Commit Graph

233 Commits

Author SHA1 Message Date
Jeff Emmett 22b5c00a13 fix(routing): prevent domain stacking and remove Try Demo button
- Fix server-side redirect to always use canonical rspace.online as base
  domain instead of deriving from hostClean (prevents demo.rspace.rspace.online)
- Fix bare-domain check to exact match instead of .includes() (prevents
  stacked subdomains from triggering bare-domain routing)
- Fix client-side rspaceNavUrl to guard against reserved subdomain names
  being used as space subdomains (e.g. rspace.rspace.online)
- Fix identity component _navUrl with same canonical domain guards
- Remove "Try Demo" header button from all shell rendering functions
- Remove demo-btn CSS styles
- Fix pre-existing SchemaType error in Gemini tool declarations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 11:16:46 -07:00
Jeff Emmett 3596bb9d7c fix(ui): raise MI search z-index and unclip header overflow
Search dropdown was rendering behind overlays and getting clipped by
the header's overflow:hidden. Bump z-index to 10001 and set overflow
to visible.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 19:02:04 -07:00
Jeff Emmett 1eb4e1cb66 feat(rmaps): UX parity with rmaps-online — route overlay, ping cooldown, session persistence
Phase 1: Route double-layer outline, ScaleControl, route instruction summary,
Enter key in meeting search, select-all toggle in import preview, fitToParticipants FAB.
Phase 2: Ping All sidebar button, push vibrate+requireInteraction, 30s ping cooldown,
bundled QR code (qrcode package with external API fallback), ping toast with vibration.
Phase 3: Location persistence across sessions (<30min restore), auto-start sharing preference.
Also fix pre-existing TS error in community-sync.ts (bulkForget changes array typing).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:25:46 -07:00
Jeff Emmett 496dff3c7f feat(rtrips): add in-module AI planner with split-view chat + canvas export
"Plan with AI" now opens a split-view within rTrips instead of redirecting
to the canvas. Left panel: chat with model selector. Right panel: generated
trip cards (destinations, itineraries, budgets, packing lists) with
accept/discard flow. Demo mode provides realistic mock responses for Japan,
Europe, and beach queries. Accepted items export to canvas via sessionStorage
+ #trip-import hash handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 18:21:40 -07:00
Jeff Emmett 3f496d9fc6 feat(rnotes,canvas): comments in demo mode, emoji reactions, reminders + inline picker modal
- rNotes comments now work in demo mode via in-memory thread storage
- Added emoji reactions (7-emoji palette) and date reminders on comment threads
- Reminders integrate with rSchedule API for persistent notifications
- Canvas toolbar: split Note into "Blank Note" (always available) and "From rNotes" (picker)
- Replaced browser prompt()-based pickFromList with showPickerModal (dark-themed, searchable, keyboard nav)
- Updated pickTrip, destination, and booking handlers to use the new modal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:53:06 -07:00
Jeff Emmett 1ae0609f14 perf(canvas): batch bulk forget into single Automerge transaction
The bulk forget dialog was freezing because each shape triggered a
separate Automerge change, IndexedDB write, and WebSocket sync. New
bulkForget() method batches all shapes into one transaction with DOM
updates applied immediately for responsiveness.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:52:11 -07:00
Jeff Emmett cefc1aa5b7 fix(collab): rename Solo/Share to Online/Offline, use EncryptID usernames
Swap toggle labels to Online/Offline (more intuitive). Resolve canvas
peer usernames from encryptid_session instead of rspace-username fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:45:55 -07:00
Jeff Emmett 1cbee3e4d1 fix(canvas): absolute drag positioning + remove Move Here drop ghosts
Replace movementX/Y delta accumulation with absolute mouse-to-shape offset
tracking for drift-free drag. Remove drop suggestion overlay system entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:42:50 -07:00
Jeff Emmett eea3443cba feat(canvas): collective forgetting UX + memory graph view
Rename all "Delete" labels to "Forget permanently" to align with the
three-state memory model (present → forgotten → deleted). Add explainer
blurb in memory panel. New Collective Memory graph view — force-directed
bubble chart showing shape remembrance scores sized by how many members
still remember each shape, with click-to-navigate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 17:31:46 -07:00
Jeff Emmett cd6d979b5a feat(shell): connect CommunitySync for cross-browser tab sync on all pages
Tab list sync via Automerge previously only worked on canvas pages.
Init CommunitySync + OfflineStore in the shell entry point so
community-sync-ready fires on every non-demo shell page, enabling
real-time tab sync across all browsers via the existing inline handler.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 16:14:12 -07:00
Jeff Emmett 8f1ad52557 feat(collab): unify header & tab-row — shared people-panel across all rApps
Canvas now uses the same rstack-collab-overlay component as all other
rApps instead of its own custom #people-online-badge. Header restructured
to match renderShell() layout (history/settings in dropdown-wraps on left).
Bridge API (updatePeer/removePeer/setConnState/clearPeers) lets canvas
feed CommunitySync peers into the shared component.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 11:46:26 -07:00
Jeff Emmett 79f16925aa fix(canvas): remove TS cast from inline script (Vite builds as JS)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 19:25:18 -07:00
Jeff Emmett aa4a200f32 feat(history): add "Revert to this point" button in Time Machine panel
Forward Automerge change that overwrites content fields with snapshot data,
preserving meta and full history. Also fixes pre-existing TS errors in
folk-flow-river (undefined exitX) and test-full-loop (StepResult type).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 19:08:15 -07:00
Jeff Emmett 6bda676680 fix(canvas): add missing comment-bell HTML tag to canvas header
The JS import and define() were added but the actual
<rstack-comment-bell> element was missing from canvas.html's
header HTML (which is separate from server/shell.ts).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:21:38 -07:00
Jeff Emmett 30f037c2a0 feat(dashboard): redesign space dashboard with members, activity, votes
Replace the global "Your Spaces" grid with a space-centric dashboard showing
members, previously open tools, recent activity, active votes, and quick
actions. Fix layout cut-off by positioning dashboard fixed below header+tab
row (top: 92px) with sidebar-push support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:57:54 -07:00
Jeff Emmett 6cb82f3098 fix(canvas): register rstack-comment-bell in canvas.html imports
Canvas.html has its own component import list separate from shell.js.
The comment bell was missing, so the custom element never initialized.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:32:24 -07:00
Jeff Emmett 6ec9f5ec61 fix(canvas): prevent drag/snap/selection on shape content interactions
FolkShape now uses stopImmediatePropagation for pointerdown on non-drag
targets (scrollable content, inputs, buttons) so canvas selection and
snap listeners don't fire. Canvas capture-phase listener now checks
composedPath to only track actual drag targets (host, handles, headers).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:15:43 -07:00
Jeff Emmett afd2a5a40b fix(canvas): persistent drawing tools + online/offline label + drag fixes
Drawing/shape tools (pencil, line, rect, circle) now stay active for
multiple strokes instead of resetting to selector after each use.
Renamed collab overlay badge from "Solo/Share" to "Offline/Online".
Prevent canvas drag when interacting with image-gen and prompt content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:03:15 -07:00
Jeff Emmett cb92a7f6d8 feat(rtrips): AI trip planner — canvas tools + "Plan with AI" button
Register 5 trip-specific tools (destination, itinerary, booking, budget,
packing list) in canvas-tools.ts so Gemini can create trip shapes.
Add public toolsEnabled/systemPrompt properties to folk-prompt with
persistence. Add #trip-planner hash handler to canvas.html that auto-
creates a pre-configured AI prompt. Add "Plan with AI" gradient button
to rTrips list and detail views.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 14:32:28 -07:00
Jeff Emmett f5de97c60c feat(ux): move comment button to header bar with unresolved badge
Move the "Leave Comment" button from the bottom canvas toolbar to the
top header bar as <rstack-comment-bell>, positioned left of the
notification bell. Shows a red badge with unresolved comment pin count.
Wires canvas via comment-pin-activate/comment-pins-changed custom events.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 14:02:27 -07:00
Jeff Emmett 38053eee34 fix(notes): prevent deletion while editing, fix layout, add semantic zoom
- Fix Delete/Backspace deleting the note shape when editing text inside
  it. The canvas keydown handler now uses composedPath() to detect
  inputs inside Shadow DOM (textarea, title input). Also fixes Space
  key and Ctrl+Z being intercepted by canvas while typing.
- Stop all keydown propagation from the editor/title inputs to prevent
  arrow keys from moving the shape while editing.
- Fix layout: replace calc(100%-36px) with proper flex layout. Header,
  toolbar, footer are flex-shrink:0; editor fills remaining space.
  Fixes headers being cut off and weird sizing.
- Add semantic zoom: icon-only (<0.3x), summary (0.3-0.7x), full
  editor (>0.7x). Reads --canvas-scale CSS custom property set by
  updateCanvasTransform().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:48:08 -07:00
Jeff Emmett 83fa874147 fix(ux): show offline only on actual disconnection, add resync tooltip
- Badge now reflects real connection state: "N online", "Reconnecting…", or "Offline"
- Removed manual online/offline toggle (was confusing — showed both states)
- Panel Solo/Share toggle remains for cursor visibility preference
- Hover tooltip on badge when offline: "changes saved locally, will resync"
- Panel shows offline/reconnecting notice banner when disconnected
- Removed unused #people-conn-status element and CSS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:39:08 -07:00
Jeff Emmett b91233092b fix(ux): move people-online badge into sub-tab header bar
- Move people badge + panel from fixed position to inline in .rstack-tab-row
- Badge sits right of the layer toggle icon with a subtle separator
- Panel drops down from badge position instead of floating fixed
- Online/Offline toggle replaces Solo/Multi labels for clarity
- Badge shows "Offline" with gray dot when in offline mode
- Mobile: hide text label, show dots only
- Tab bar gets flex:1 + min-width:0 to share row space

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:29:45 -07:00
Jeff Emmett d458a00550 fix(ux): instant bulk-delete dialog + post-login space routing
Bulk delete dialog: switch from click to pointerdown for instant
touch response, raise z-index above all overlays, add hover/active
feedback and keyboard support.

Post-login routing: reload page when logging in on a non-demo space
so access gates clear and CRDT sync reconnects with auth. Silently
provisions personal space in background.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 13:21:03 -07:00
Jeff Emmett 34a7a4e37e fix(canvas): mobile toolbar to right, persistent lock badge, reminder auth
- Move mobile toolbar to right side to avoid zoom bar overlap
- Toolbar panel opens leftward, bottom toolbar offsets flipped
- Add [locked] attribute reflection on folk-shape for external CSS
- Persistent 🔒 badge on locked shapes visible when unselected
- Add Authorization header to calendar reminder POST request

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 20:13:15 -07:00
Jeff Emmett e2c6275308 fix(canvas): comment pin tool state management + shape detection bug
- Fix elementFromPoint using canvas-relative coords instead of viewport
  coords for shape detection during pin placement
- Use shape data from Automerge doc for offset calculation (more reliable)
- Add exitCommentMode() to deactivate pin placement when switching tools
- Integrate comment mode into syncBottomToolbar active state
- Escape key closes popover and exits comment mode
- Mutual exclusion between comment/draw/connect/pending tool modes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 19:28:51 -07:00
Jeff Emmett 07e3c7348c feat(canvas): add Figma-style comment pin system
Overlay markers at canvas or shape-relative coords with threaded
comments, @mention notifications, and rSchedule reminder integration.
Toolbar "Leave Comment" button (/) next to Note tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 18:47:03 -07:00
Jeff Emmett 2c0fbb76ac fix(canvas): add auth headers to API fetches + deduplicate sync events
- Add Authorization header to fetchTripData, fetchTripDetail, and
  fetchNotesData to prevent 401 errors on private spaces
- Add #initialSyncFired flag to CommunitySync so the "synced" event
  only fires once per connection cycle instead of on every debounce gap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 16:28:58 -07:00
Jeff Emmett 2de61cd7ad feat(rcal): move zoom/legend below calendar, add multi-day event spans
- Reorder layout: nav → calendar → legend → zoom bars → bottom bar
- Add "Calendar Legend" heading above source badges
- Fix getEventsForDate() to support multi-day range checking
- Render colored span bars across day cells for multi-day events
- Make showAccountModal/isSignedIn public on rstack-identity
- Tour final step triggers identity setup flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 15:10:39 -07:00
Jeff Emmett ac402c29e9 feat(canvas): replace repulsion with snap guides + drop suggestion
Remove ambient repulsion loop (shapes drifting apart at 60fps). Add
Figma-style snap alignment guides during drag with magnetic stickiness,
and ghost drop suggestion when shapes overlap after drop.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:28:32 -07:00
Jeff Emmett 4b08a02851 fix(seed): prevent demo data re-seeding after user deletes content
Added a `seeded` flag to Automerge doc metadata across 6 modules
(rcal, rnotes, rtasks, rvote, rbnb, rvnb). Once demo data is seeded,
deleting all content no longer triggers re-seeding on next page load.

Also removed rcal's per-request seedDemoIfEmpty() call from the route
handler — onInit + seedTemplate already handle initial seeding.

fix(canvas): prevent bulk delete dialog from stacking

The Delete key repeat was creating multiple overlays, making the dialog
appear unclosable. Added a guard to prevent duplicate dialogs, and
Escape key support to dismiss.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:24:51 -07:00
Jeff Emmett fe7157ffe1 fix(shell): position settings/history panels below their buttons
Both panels now use position:fixed with JS-computed coordinates from
getBoundingClientRect(), ensuring they open directly below their
respective header buttons and right-aligned to the button edge.
History panel clamps left edge to prevent off-screen overflow.

Also adds missing click handlers for settings-btn and history-btn
in canvas.html (previously only wired in shell.ts module pages).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:59:44 -07:00
Jeff Emmett e0f0426e59 fix(canvas): limit separation dynamics to rApps/embeds, not drawings/slides
- Add folk-shape to pushExemptTags so wb drawings (pencil, rect, circle,
  line) are exempt from repulsion and can overlap other shapes freely
- Skip wb-drawing elements in repulsion loop and free-position placement
- Locked shapes are not pushed by repulsion (full push goes to unlocked neighbor)
- getExistingShapeRects uses pushExemptTags instead of hardcoded arrow check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:25:27 -07:00
Jeff Emmett 842ac4d67e feat(canvas): eraser works on all shapes, add lock icon for shapes
- Eraser now targets any folk-shape (not just wb-drawing), erasing whatever it touches
- Added lock property to folk-shape: locked shapes can't be moved, resized, or erased
- Lock state persisted via Automerge sync (toJSON/applyData/fromData)
- Lock icon appears beside calendar icon when shape(s) selected, toggles lock on click

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:19:54 -07:00
Jeff Emmett 63c1b7c1e7 refactor(shell): convert settings & history panels to dropdown menus
Replace full-height slide-in panels with compact dropdowns that appear
beneath header icons. Both icons now grouped in header-right with
mutual exclusion and click-outside-to-close behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 23:17:17 -07:00
Jeff Emmett e56b4fe89c fix(canvas): hide feed toggle on mobile corner tools
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:31:58 -07:00
Jeff Emmett 9b0a672c7b feat(canvas): add Ctrl+Z undo / Ctrl+Shift+Z redo for shape operations
Local inverse-change stack that records before-snapshots of each mutation
and applies forward Automerge changes to restore state on undo. Batches
rapid same-shape changes (<500ms) so drags produce a single undo entry.
Supports create, move/resize, forget, remember, and hard-delete operations.
Max 50 entries, redo stack clears on new changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 22:31:22 -07:00
Jeff Emmett 15f7e759d1 fix(canvas): map shape interaction + reminder widget dismissal
Map viewer: disable MapLibre interactions when inside a folk-shape
until editing mode (double-click). Prevents map panning when trying
to select/move the shape on canvas.

Reminder widget: dismiss on Escape key and when clicking elsewhere
on canvas (deselecting shapes). Clean up schedule icon when shape
is deleted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:44:28 -07:00
Jeff Emmett d5e822ec7c fix(canvas): remove duplicate settings/history button handlers
Canvas.html had its own addEventListener calls for settings-btn and
history-btn, but the shell script already wires these. Both handlers
fired on click, causing double-toggle (open then immediately close).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:39:32 -07:00
Jeff Emmett 355b53ee17 fix(canvas): hide toolbar items for disabled modules
Inject enabledModules into client, tag 25 module-specific toolbar buttons
with data-requires-module, and filter out disabled items (plus empty groups)
at page init. Spaces with all modules enabled are unaffected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 20:36:10 -07:00
Jeff Emmett ee1a791aea fix(canvas): move offline status to people badge, toolbar minimize to bottom, zoom to bottom-right
- Offline/reconnecting indicator now shows inside the "N online" people
  badge instead of the shell header (hidden on canvas via CSS override)
- Toolbar collapse/minimize button moved from top to bottom of toolbar
  stack so it sits where the last tool icon was
- Zoom controls moved from bottom-left to bottom-right; on mobile they
  sit above the bottom toolbar to avoid overlap

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:22:39 -07:00
Jeff Emmett 36e76449fa fix(canvas): prevent horizontal overflow on mobile
- Add overflow:hidden on html element for canvas-layout pages
- Bottom toolbar: constrain to viewport with right:8px, horizontal
  scroll for overflow buttons, flex-shrink:0 on items
- Context menu: clamp position to viewport bounds
- Modal panels: use min() for min-width to respect small screens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:17:27 -07:00
Jeff Emmett 0067369af1 fix(canvas): prevent mobile scroll by using flex layout for canvas page
On mobile, header/tab-row switch from fixed to sticky (in-flow), but
#app.canvas-layout still had height:100vh — total content exceeded
viewport causing unwanted scroll. Fix: body becomes a flex column
(100dvh, overflow hidden), header/tab-row flex-shrink:0, #app fills
remaining space with flex:1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:50:10 -07:00
Jeff Emmett 448b68eb62 feat(tour): replace static welcome popup with guided feature tour
Replaces the "Welcome to rSpace" popup with a 6-step interactive tour
that spotlights key UI features (app switcher, MI bar, spaces, identity,
canvas, tabs/tools). Skippable at any time via button, Escape, or
clicking the backdrop. Navigable with Back/Next buttons and arrow keys.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:42:20 -07:00
Jeff Emmett fec0149f55 fix(shell): ensure header settings/history buttons are clickable
Add z-index stacking contexts to header left/right sections so buttons
render above center content and backdrop-filter pseudo-element. Add
overflow:hidden on center to prevent search bar overflow into button areas.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 16:13:38 -07:00
Jeff Emmett 77f2e9ae56 fix(rpubs): allow public PDF generation + fix zine auto-spawn
- Add publicWrite to rpubs module (PDF gen is computational, not a write)
- Fix zine auto-spawn: wait for community-sync-ready event instead of
  fragile 800ms timeout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 22:20:08 -07:00
Jeff Emmett c23d7eb65b fix(canvas): reminder widget expands from schedule icon position
Instead of popping up at fixed top-right, the reminder mini-calendar
now appears at the 📅 icon's location and scales out from it.
Icon hides while widget is open, reappears on close.
Viewport-clamped to prevent off-screen overflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 21:54:50 -07:00
Jeff Emmett 4f1eab3104 fix(spaces): redirect to subdomain URL after space creation
Create-space form redirected to /{slug}/rspace which 404s on subdomain
hosts (jeff.rspace.online/mycofi/rspace → rewritten to /jeff/mycofi/rspace).
Now redirects to https://{slug}.rspace.online/rspace.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 16:45:35 -07:00
Jeff Emmett 92df7d332d fix(canvas): only show reminder calendar on icon click, not on shape select/drag
Remove the auto-opening calendar on shape selection and the drag-to-calendar
compact mode. The 📅 icon on selected shapes remains as the entry point.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:15:18 -07:00
Jeff Emmett 73ad020812 fix(spaces): fix space creation routing and use /rspace URLs
Space creation was broken because the canvas module has id "rspace" but
all navigation URLs used "/canvas". On production subdomain routing this
resulted in 404s after creating a space.

- Switch create-space form from deprecated /api/communities to /api/spaces
- Replace all /canvas navigation URLs with /rspace to match module ID
- Fix DID matching in space listing to check both sub and did:key formats
- Add proper client DID support in EncryptID registration flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 11:07:01 -07:00