Commit Graph

600 Commits

Author SHA1 Message Date
Jeff Emmett 1dcc3ff0a1 Fix SVG dataset crash and 403 on intent API
- Remove `dataset = {}` assignment on SVG circle element (read-only
  property on SVGElement, causes TypeError crash on every render)
- Add authHeaders() helper using encryptid-token from localStorage
- Include Authorization header on all mutating intent API calls
  (create, solver/run, accept, reject)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 23:17:14 -07:00
Jeff Emmett 2907935c50 fix(rtime): use getApiBase() for subdomain-compatible URL routing
Replace all hardcoded /${space}/rtime paths with getApiBase() which
derives the correct API base from window.location.pathname. This
supports both subdomain routing (demo.rspace.online/rtime) and
path-based fallback (/demo/rtime).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 22:46:33 -07:00
Jeff Emmett 08cae267fe feat(rtime): add intent-routed resource-backed commitments
Integrate Anoma-style intent routing into rTime so that commitments
become resource-backed intents that a solver can compose into multi-party
collaboration recommendations.

New modules:
- schemas-intent.ts: Intent, SolverResult, SkillCurve, Reputation types + 4 CRDT doc schemas
- solver.ts: Mycelium Clustering algorithm (bipartite graph matching, VP filtering, scoring)
- settlement.ts: Atomic settlement via saga pattern with escrow confirm/rollback
- skill-curve.ts: Per-skill bonding curve (demand/supply pricing)
- reputation.ts: Per-skill reputation scoring with time-based decay
- intent-routes.ts: 10 Hono API routes (intent CRUD, solver, settlement, curves, reputation)

Modified:
- schemas.ts: Added intentId/status fields to Commitment
- mod.ts: Registered 4 new docSchemas, mounted intent routes, added Collaborate output path
- folk-timebank-app.ts: Added Collaborate tab with intent cards, solver results panel,
  accept/reject buttons, create intent modal, skill price display, and status rings on pool orbs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 22:36:06 -07:00
Jeff Emmett 16fe8f7626 Fix rSheet: remove space slug from URL paths
Space context comes from subdomain routing, not URL path segments.
Fix appUrl, externalApp.url, and onboardingActions.href to use
subdomain-compatible paths without {space} prefix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 20:19:17 -07:00
Jeff Emmett 9a45b19435 Add rSheet module — collaborative spreadsheets via dSheet
- New module at modules/rsheet/mod.ts using externalApp pattern
- Embedded Y.js-backed spreadsheet grid with real-time sync
- Connects to shared y-websocket server for collaboration
- Registered in server/index.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 19:25:36 -07:00
Jeff Emmett 0a4ee86976 fix(rpubs): move format selector from toolbar to write step bottom bar
Remove "Digest" format dropdown from the editor toolbar header. Move format
selector into the write step bottom bar as a clickable badge with dropdown.
Fix CSS bug where dropdown panels with display:flex overrode the HTML hidden
attribute, causing a visible rectangle artifact.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 18:44:09 -07:00
Jeff Emmett 1ee14b7520 fix(rcal): consistent viewport sizing + touch pinch-zoom fix
Make calendar views fill a consistent ~60vh area across all zoom levels
(month/season/year/multi-year) using flex stretching. Fix touch pinch-zoom
by removing pinch-zoom from touch-action so our pointer handler fires
instead of native page zoom.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 18:26:52 -07:00
Jeff Emmett eec88ac661 fix(flipbook): use <img> elements instead of background-image for page rendering
background-image data URLs on divs can fail silently in StPageFlip's
shadow DOM context, producing white pages. Switch to <img> elements
with explicit pixel dimensions and object-fit:cover for reliable
rendering. Add white background to .stf__item as a safety net.
Applies to both folk-pubs-flipbook and folk-book-reader.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 13:02:28 -07:00
Jeff Emmett 6ce8ede568 fix(rmeets): bump JS cache version to bypass stale CF 301 redirect
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 12:48:05 -07:00
Jeff Emmett 0519e113b6 refactor(rmeets): remove /room/ prefix from meeting URLs
/rmeets/jeff now opens a room directly instead of requiring /rmeets/room/jeff.
Catch-all /:room route registered last so /meet, /recordings, /search still work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 11:17:42 -07:00
Jeff Emmett 5bc64a5b4e fix(touch): pointer event parity for slash commands, collab overlay, canvas, and wallet charts
Convert remaining mouse-only event listeners to Pointer Events so touch
and pen inputs work identically to mouse across rApps and canvas:

- rnotes slash-command: mousedown/mouseenter → pointerdown/pointerenter
- collab overlay: mousemove → pointermove for cursor broadcast, click → pointerdown for collab-id tracking
- canvas.html: toolbar label reveal gated behind @media (hover: hover), :active fallbacks on 12 button selectors, JS mouseenter/mouseleave → pointerenter/pointerleave
- wallet-viz D3 charts: all mouseover/mousemove/mouseout → pointerenter/pointermove/pointerleave on transaction paths, balance area, Sankey links, and reset button

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 11:06:44 -07:00
Jeff Emmett 690e4dedb4 refactor: consolidate space settings — both gear icons open same tabbed modal
Remove rstack-space-settings slide-out panel. Enhance the existing tabbed
modal in rstack-space-switcher with add-member (username search + email
invite) and pending email invites (with revoke). Header gear now calls
openSettingsModal() on the space switcher instead of toggling the old panel.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:58:30 -07:00
Jeff Emmett 2cbff8925d fix(layout): viewport-filling rApp layout — eliminate body scroll
Make #app a flex column with height:100vh so all rApps fill the viewport
exactly. Wrap module body in .rapp-content flex child. Replace all
hardcoded calc(100vh - Npx) with height:100% across 20+ components.
Remove sticky positioning from subnav/tabbar (now flex items).
Generalize mobile body-flex to all pages (not just canvas-layout).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:57:09 -07:00
Jeff Emmett 7d5209021a feat(rnotes): web clipper download, URL/file note creation from sidebar
- Copy browser extension into repo so /extension/download works in Docker
- Add "Web Clipper" button to sidebar footer
- Replace simple "+" with context menu: New Note / From URL / Upload File
- BOOKMARK notes from URL, IMAGE/AUDIO/FILE notes from uploaded files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:37:13 -07:00
Jeff Emmett f6767ca841 fix(rnotes): add /transcripts route for sub-tab navigation
The Transcripts sub-tab pill in the rNotes header linked to
/{space}/rnotes/transcripts but no route existed. Add the route
serving the voice recorder/transcription app.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:21:57 -07:00
Jeff Emmett 34f0387c88 fix(rmaps): bump JS cache version + add demo debug logs
Bump folk-map-viewer.js?v=6 → v=7 to bust Cloudflare cache.
Add console logs to trace demo marker creation flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 10:00:16 -07:00
Jeff Emmett 81d8102f69 feat(tours): add guided tour links to 7 landing pages and startTour() to 5 components
Landing pages now consistently include "Start Guided Tour →" in the
hero CTA area. Components that already had internal tours (rbnb, rvnb,
rsplat) get a public startTour() wrapper; rtime and rmeets get full
TourEngine integration with contextual steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 09:33:11 -07:00
Jeff Emmett 636360ce5f fix(rpubs): fix flipbook white screen and align flow with /press landing
- Flipbook: wrap async initFlipbook in try-catch with scroll fallback,
  add 500ms verification timeout for silent StPageFlip failures, quote
  data URLs in background-image, expand shadow DOM CSS coverage
- Flow: rename steps Create/Preview/Publish → Write/Press/Print to
  match rpubs.online/press landing page description
- Routes: add /press editor route, bump script cache to v=3
- Publish panel: fix getEditorContent() reading from cached content
  instead of missing textarea (not rendered during print step)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 23:52:24 -07:00
Jeff Emmett 1cc083a655 feat(rmaps): replace SVG demo with real MapLibre GL festival meetup
The demo previously showed a static SVG world map with 6 hardcoded print
providers — completely different from the real app. Now shows a real
MapLibre GL map with 5 animated participants, 4 waypoint pins, a route
line, and the full app UI (header, sidebar, controls, mobile bottom sheet).
Visitors see exactly what the product looks like.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 23:47:02 -07:00
Jeff Emmett b5c6477f47 feat(rtime): add timebank commitment pool & weaving dashboard rApp
Port hcc-mem-staging SPA into rSpace as the rTime module. Canvas-based
commitment pool with physics orbs, SVG weaving editor with hex nodes
and bezier wires, execution panel, and optional Cyclos timebank proxy.
Automerge CRDT persistence, demo seeding, and full landing page
explaining community-based ledgers and emergent collaboration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 23:42:49 -07:00
Jeff Emmett d865da32a7 fix(rsocials): campaign wizard timeout + faster content generation
- Add 120s AbortController timeout to apiFetch so wizard can't hang
  forever on slow networks (shows "Request timed out" instead of stuck)
- Switch content generation from gemini-2.5-pro to gemini-2.5-flash
  to avoid Cloudflare/Traefik proxy timeouts (pro model took 30-60s+)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 22:48:57 -07:00
Jeff Emmett 231f5c6e59 chore(rinbox): bump folk-inbox-client.js cache version to v=3
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 20:46:04 -07:00
Jeff Emmett 58e319b8c8 feat(rinbox): add markdown rendering + TipTap collaborative editing
- Extract markdown-tiptap.ts and yjs-ws-provider.ts to shared/ for reuse
- Thread bodies render as formatted markdown via marked
- Replace compose textarea with TipTap rich-text editor + Yjs collab
- Add formatting toolbar (bold, italic, lists, code, links, etc.)
- Add TipTap comment editor with tiptap-json storage format
- Server accepts content_format on comment API
- Full ProseMirror + collab cursor CSS scoped to shadow DOM
- Editors cleaned up on navigation and disconnect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 20:40:49 -07:00
Jeff Emmett 15f5c58214 fix(rnotes): sidebar drag-drop reorder now works
- Add sort_order to Note interface and map from Automerge sortOrder
- Add sortNotes() method (pinned first, sort_order asc, updated_at fallback)
- Add CSS indicators (box-shadow) for drag-above/drag-below
- Add dragend cleanup for opacity + stale indicator classes
- Apply sortNotes in renderFromDoc, loadNotebookREST, fetchNotebookNotes
- Bump folk-notes-app.js cache to v=13

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 20:19:46 -07:00
Jeff Emmett 12499d62b5 chore(rnotes): bump folk-notes-app.js cache version to v=12
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 12:45:39 -07:00
Jeff Emmett 9266a6155f feat(rnotes): debounce suggestion panel + drag-drop notes between notebooks
Batch consecutive keystrokes into single suggestions via session tracker,
debounce panel sync (400ms) to prevent letter-by-letter flicker, and add
HTML5 drag-and-drop to move notes between notebooks in the sidebar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 12:43:40 -07:00
Jeff Emmett abc855f34e fix(rnotes): position sidebar collapse button at right edge, vertically centered
Move < button from inside search header to absolute-positioned on the
sidebar border at vertical midpoint. Matches the > reopen tab style.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:43:21 -07:00
Jeff Emmett e8d88cd10e fix(rnotes): resolve anonymous identity in comments, suggestions, and cursors
Session was stored as { claims: { username, sub } } but getSessionInfo()
read sess.username (top-level) instead of sess.claims.username — always
falling back to "Anonymous". Fixed in all 3 locations: folk-notes-app,
comment-panel, collab-presence.

Also fixed awareness race: Yjs provider broadcast initial awareness before
user field was set, creating a ghost "anonymous" peer. Now identity is set
on awareness before provider connects, and the duplicate set is removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:34:08 -07:00
Jeff Emmett 99fa59c8df feat(rnotes): suggestions in sidebar panel with per-item accept/reject
- Suggestions now appear as cards in the right-hand comment sidebar
  with author, type (Added/Deleted), text preview, and Accept/Reject
- Clicking a suggestion card scrolls the editor to the marked text
- Removed "Accept All" and "Reject All" from the review bar — too blunt
- Review bar now directs users to the sidebar for granular review
- Sidebar auto-opens when suggestions exist
- Inline popover accept/reject still works for quick actions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:28:42 -07:00
Jeff Emmett 0ec5edd1ee feat(rnotes): collapsible document sidebar with < / > toggle
Add collapse button (<) in sidebar header top-right and reopen tab (>)
on left edge when collapsed. CSS grid transition for smooth animation.
Hidden on mobile where slide navigation handles sidebar state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:28:01 -07:00
Jeff Emmett 9084de7adb feat(rsocials): wire social shapes into all cross-rApp systems
- Add GET /api/threads, /api/threads/:id, /api/campaigns, /api/campaigns/:id
  REST endpoints so other rApps can fetch rsocials data
- Register folk-social-thread/campaign/newsletter in MI triage panel,
  tool schema, system prompt, and KNOWN_TRIAGE_SHAPES
- Add rsocials MODULE_PORTS (threads-out, campaigns-out, post-published,
  campaign-data) and WIDGET_API to folk-rapp for embed/widget mode
- Add rsocials to folk-feed FEED_ENDPOINTS (threads, campaigns, newsletter)
  and normalize response arrays (threads, campaigns, drafts)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:25:26 -07:00
Jeff Emmett 63a3f9b6c3 fix(rcart): add missing getTransakEnv import
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:08:23 -07:00
Jeff Emmett 9edb6cccde fix(rcart): Transak staging payment — popup instead of blocked iframe
Transak staging sets X-Frame-Options: sameorigin, blocking iframe embedding.
Server now uses x-forwarded-host header for correct referrerDomain behind
Traefik, and returns env (STAGING/PRODUCTION) in transak-session response.
Client opens a popup window for staging instead of iframe.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 16:01:57 -07:00
Jeff Emmett bbbe14246c feat(rinbox): space agent mailbox system — per-space MI email identity
Each space gets {space}-agent@rspace.online as a real Mailcow mailbox
(auto-provisioned with generated password). Inbound emails are IMAP-polled
and processed by MI (Gemini Flash) for auto-reply. All outbound emails
(approvals, notifications) set reply-to to the agent address so replies
route back through MI.

- mailcow.ts: createMailbox/deleteMailbox/mailboxExists API
- schema.sql + db.ts: agent_mailboxes table for per-space IMAP creds
- space-alias-service.ts: provisionAgentMailbox/deprovisionAgentMailbox
- server.ts: internal routes for agent mailbox CRUD + member-emails
- rinbox/mod.ts: initAgentMailbox, per-space IMAP sync, processAgentMI
- rinbox/agent-notify.ts: sendSpaceNotification (BCC members)
- rcal/rtasks/rvote: notification hooks on create

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 08:59:52 -07:00
Jeff Emmett e31c905d7c feat(rnotes): add tiptap-markdown for inline markdown shortcuts + paste
Type **bold**, _italic_, ~~strike~~, `code`, etc. and they auto-convert
to rich text. Pasting markdown also converts to formatted content.
Added to all 4 editor instances (Yjs, legacy, bookmark, image, audio).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:56:22 -07:00
Jeff Emmett 219a5f434b fix(rnotes): mobile collab UX — bottom-sheet comments, toolbar reorder
- Comment sidebar → full-width bottom sheet at ≤768px (was ≤480px)
- Toolbar: collab tools (comment, suggest) reordered first on mobile
  via CSS order so they're visible without scrolling
- Suggestion review bar wraps at mobile widths
- Toolbar scroll + larger touch targets promoted to ≤768px breakpoint

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:26:30 -07:00
Jeff Emmett 8f9d507440 fix(rinbox): clean up sub-tab header — mailboxes + approvals only, info icon, space mailbox primary
Remove Personal, Agents, Tour from nav header. Move Guide/About behind
info icon (ⓘ). Space mailbox ({space}@rspace.online) shown first with
highlighted card spanning full width. Add demo threads for space mailbox.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:21:50 -07:00
Jeff Emmett 25abb0266b feat(rsocials): newsletter drafts tab + remove Listmonk setup wall
Drafts tab shown by default with Automerge-backed CRUD. Listmonk tabs
conditionally appear when configured. Info banner for unconfigured state.
Draft editor with HTML preview, status dropdown, subscriber management.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:15:46 -07:00
Jeff Emmett db25d65c43 chore(rnotes): bump JS cache version to v=9
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:14:22 -07:00
Jeff Emmett 77ac0c1e32 feat(rsocials): newsletter drafts, subscribers + MI route updates
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:11:31 -07:00
Jeff Emmett 2eac542e19 feat(rnotes): mobile stack navigation — Notion-style two-screen slide
Replace overlay sidebar with horizontal flex stack: full-width doc list
slides to full-width editor with back bar on note tap. Resize-aware.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:11:26 -07:00
Jeff Emmett 3add66b5ef chore(rsocials): add NewsletterDraft and NewsletterSubscriber types
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:04:15 -07:00
Jeff Emmett f966f02909 feat(spaces,rsocials): invite-based member adds + clickable campaign content
Space invites: Convert both username-add and email-invite (existing user)
paths from direct-add to invite flow — creates space_invite via EncryptID,
sends invite email with Accept button, dispatches space_invite notification
with Accept/Decline buttons in the notification bell. No one gets forcefully
added to a space anymore.

rSocials content linking: All generated campaign content now links through
to actual editable content. Draft post cards in thread gallery are clickable
(thread editor or campaign view). Campaign manager post cards expand on click
and thread badges link to thread editor. Wizard success screen shows
individual thread links. CampaignPost schema gains threadId field, stored on
commit so posts maintain their thread association.

Also includes canvas social media tools, social shape components
(folk-social-thread, folk-social-campaign, folk-social-newsletter),
and MI context-aware suggestion registry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 20:03:52 -07:00
Jeff Emmett 358965cb61 fix(rmaps): join form overlay + authenticated user auto-join
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:04:24 -07:00
Jeff Emmett c4972079dd fix(cad): CSS containment + Scribus image gen for all CAD shapes
- KiCad, FreeCAD, Blender, Scribus: add .wrapper flex container with
  height:100% + min-height:0 so content stays within element bounds
- KiCad assembler: regex fallback for non-JSON tool results (SVG, Gerber, PDF)
- Scribus image gen: actually write downloaded fal.ai images to disk
  (was creating imagePath but never saving bytes)
- Mount rspace-files volume in scribus-novnc so generated images are
  accessible from both containers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:53:42 -07:00
Jeff Emmett 8ea537525a fix(rwallet): align timeline inflows/outflows with balance changes
- Use curveStepAfter for the balance river so step transitions happen
  exactly at transaction dates (curveBasis didn't pass through data points,
  causing waterfall shapes to disconnect from the river edges)
- Update hardcoded USD estimates to current CoinGecko prices (2026-03-25)
- Add SAFE, COW, ENS, LDO, BAL to the price estimate table
- Fix BigInt→Number precision for large token balances (>2^53 wei) in
  both price-feed enrichment and transfer value parsing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:36:10 -07:00
Jeff Emmett f3094f5f88 fix(rwallet): chain filter now updates all displayed data + chain proportion bar
- Stats, balance table, and DeFi positions all filter by selected chain
- Added proportional color bar showing each chain's share of total value
- Chain buttons show USD value + percentage on hover
- Bumped JS cache version to v=21

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:32:02 -07:00
Jeff Emmett ba56697e23 fix(rcal): show calendar event locations on map in all spaces, not just demo
REST API events use location_lat/location_lng while the map panel
filters on latitude/longitude. Demo events set both, but non-demo
events only had location_lat/location_lng — so the map was always
empty outside demo.

Normalize both REST and Automerge event data to include latitude/
longitude aliases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:10:44 -07:00
Jeff Emmett 44a69e665e perf(rmaps): preload MapLibre GL, switch CDN from unpkg to jsDelivr
Add <link rel="preload"> hints for MapLibre JS+CSS in the module HTML
so the browser starts fetching them in parallel with the main bundle,
instead of waiting until joinRoom() calls loadMapLibre().

Switch from unpkg (slow, no HTTP/2) to jsDelivr (faster edge caching).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:03:21 -07:00
Jeff Emmett 355d33768a fix(mobile): responsive parity — touch targets, iOS zoom, viewport clamping
rNotes: always-visible add button on touch, 36px toolbar buttons with horizontal
scroll, URL popover as bottom sheet on mobile, improved comment sidebar bottom
panel with drag handle, larger footer buttons, slash menu viewport clamping and
mobile-friendly item sizes, reduced code-textarea/image-preview heights.

rTasks/rFiles: font-size 16px on inputs to prevent iOS Safari auto-zoom.

Shell: .hover-reveal touch utility, 36px min-height on rapp-nav buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:59:04 -07:00