First panel no longer sticks to the left edge. Left padding set to
calc(50vw - 240px) so the carousel starts with generous breathing room.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Break out of the layout's max-w-7xl px-4 container using negative
margins so the workbench carousel fills the entire viewport width.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Page reorder drag now only starts from the drag-handle icon, not from
anywhere in the page. This allows dragSource on list items (tasks,
events, contacts) to work without being intercepted by page reorder.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Making guestMode reactive with $state() triggered an infinite effect
cascade: guestMode.notifications being accessed in the template created
a reactive dependency that, combined with 8+ AppPages each running
$effect for module loading, exceeded Svelte's effect update depth limit.
Root cause: GuestMode object has reactive getters that return new
references on each access. Wrapping it in $state() made every template
access trigger a re-render, which triggered more effects, creating an
unbounded cascade.
Fix: Keep guestMode as plain variable (non-reactive). The warning about
non_reactive_update is acceptable — guestMode is set once during init
and its properties are accessed imperatively, not reactively.
Also:
- Remove debug console.logs from AppPage, +page, +layout
- Keep onMount for workbench state loading (replaces $effect)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Delete all 25 apps/*/apps/web-archived/ directories (superseded by unified ManaCore app)
- Remove stale +page.server.ts stubs from teams, organizations, settings (always returned empty data)
- Simplify teams and organizations pages to static empty-state (no server load dependency)
- Delete empty apps/context/apps/mobile/components/variants/index.ts
- Remove commented-out apps-archived entries from pnpm-workspace.yaml
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Make entity registration lazy (ensureEntitiesRegistered) to avoid
circular imports at module load time
- Re-enable cross-module drop target in AppPage
- Fix Component type in app-registry to accept any props (AnyComponent)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduce EntityDescriptor pattern: each module declares how its items
can be displayed, dragged, dropped, and created from other modules.
- Entity types + registry with executeDrop orchestration
- Entity descriptors for todo, calendar, contacts
- List items are now draggable (dragSource) across pages
- Pages accept cross-module drops (event→todo, contact→calendar, etc.)
- Drops create new items + bidirectional manaLinks via shared-links
- LinkedItems component shows cross-module links in DetailViews
- Visual feedback: page glows purple on valid hover, green on success
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
$derived cannot reference variables declared later in the script.
Moved the calculation below the isTagStripVisible $state declaration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dev env vars (_CLIENT suffixed) are empty, so localhost:3001 (auth),
localhost:3050 (sync), localhost:3060 (api) were blocked by CSP.
Added http://localhost:* and ws://localhost:* to connect-src when
NODE_ENV !== 'production'.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
bind:clientHeight + $effect setting CSS variable caused infinite reflow
loop: height change → CSS var → padding change → height change.
Now using $derived calculation from state (isCollapsed, isTagStripVisible)
instead of DOM measurement. No reflow loop possible.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Per-app SSE connections exhaust the browser's 6-connection-per-origin
limit, causing the app to hang on load. Reverted to HTTP polling for
both eager and lazy apps.
SSE server endpoint remains available for future use as a single unified
stream (one connection for all apps, similar to the old unified WebSocket).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Times ListView: inline timer with start/stop, name input, live elapsed display
- Times DetailView: editable entry with duration (h/m/s), project, billable, delete
- Zitare ListView: tap-to-cycle quotes, inline fav button, tag drag-and-drop support
- Zitare DetailView: full quote view with category, author bio, share, favorite
- Homepage: remove tag bar (available via PillNav), carousel uses full width
- Register both DetailViews in app-registry
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These are secondary pages accessible via settings/profile, not primary navigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Display assigned tags as colored pills in todo, calendar, contacts
DetailViews. Clicking a tag pill removes it from the item. Hover turns
the X icon red for clear affordance.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace tiny 6px tag dots with readable pills showing colored dot +
tag name. Uses color-mix for subtle tinted background per tag color.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
useAllTags() returns a Svelte 5 runes object with .value, not an
Observable with .subscribe(). Also fix getTagsByIds() calls to pass
the allTags array as first argument.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add rightAction snippet prop to QuickInputBar (InputBar.svelte)
- Move toggle from leftAction to rightAction (renders after submit button)
- Increase toggle size from 28px to 36px for better tap target
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Mount DragPreview + draggable tag bar on workbench homepage
- Add dropTarget on list items in todo, calendar, contacts ListViews
- Show assigned tags as colored dots on list items
- Tags can be dragged from the tag bar onto any item to assign them
- Drop target highlights with module-colored outline on hover
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Toggle button now renders inside the InputBar pill (left side) instead of
as a separate element next to it. Uses the existing leftAction snippet prop.
- Button is 28px circle, subtle background, no border/shadow (lives inside pill)
- Remove bottom-stack-row wrapper (no longer needed)
- Cleaner visual: toggle is part of the input bar, not floating beside it
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Tags pill moved to first position in nav items (leftmost)
- Toggle button: 44px round (matches InputBar height), same border-radius
(9999px), same backdrop-filter blur, same box-shadow, theme-aware colors
- Button sits directly next to QuickInputBar with no gap, vertically centered
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The bottom-stack container now exports its height as --bottom-chrome-height
CSS custom property (via bind:clientHeight + $effect on :root). All elements
that need to position above the bottom chrome read this variable:
- PageCarousel minimized-tabs: bottom: var(--bottom-chrome-height)
- NotificationBar: bottom: var(--bottom-chrome-height)
- Main content padding: calc(var(--bottom-chrome-height) + 2rem)
This ensures tabs, notifications, and content never overlap with the
bottom stack regardless of PillNav collapse state or TagStrip visibility.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace 4 independent position:fixed elements with one flex container that
stacks them naturally from bottom to top. Elements push each other
automatically — no more hardcoded offsets or z-index conflicts.
Stack order (bottom → top):
1. PillNavigation (collapsible)
2. TagStrip (togglable)
3. QuickInputBar + toggle button row
Shared-UI changes:
- PillNavigation: add positioning='fixed'|'static' prop
- QuickInputBar: add positioning='fixed'|'static' prop
- TagStrip: add positioning='fixed'|'static' prop
- All default to 'fixed' for backward compatibility
Layout changes:
- Wrap all bottom elements in .bottom-stack (position:fixed, flex-column)
- Remove hardcoded bottomOffset calculations
- Toggle button is now inline next to QuickInputBar (not separately positioned)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When heightPx is not yet set, use the element's actual offsetHeight
instead of 0 so the first drag correctly adjusts height.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend PageShell resize handle to support diagonal drag for both
width and height. Height is persisted per page in workbench settings.
Resize cursor changed from ew-resize to nwse-resize.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Small floating button (▼/▲) at the bottom-right that toggles PillNav
visibility. QuickInputBar's bottomOffset adjusts dynamically when nav
is collapsed (70px → 12px), reclaiming vertical space.
- Button uses existing handleCollapsedChange() with localStorage persistence
- Smooth transitions on position and rotation
- Glass-morphism style (blur + semi-transparent background)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consistent naming: ListView.svelte + DetailView.svelte as a pair.
Update app-registry.ts and splitscreen/registry.ts imports.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add inline-editable DetailViews with auto-save for:
- cards: deck details with color, description, public toggle
- storage: file details with rename, favorite, size/type info
- presi: presentation deck details with slide count
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add inline-editable DetailViews with auto-save for:
planta, inventar, skilltree, memoro, questions, uload, mukke, citycorners
Wire AppView list items to open overlay via navigate() with sibling
navigation support. Fix citycorners table names (cityLocations→ccLocations).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove /dashboard (redundant), merge /home into / (app root)
- Update all redirects and navigation references accordingly
- Add panel navigation stack with overlay detail views for workbench
- Implement inline-editable DetailViews for todo, calendar, contacts
- Auto-save on blur, prev/next navigation with sibling arrows
- Fix minimized tabs z-index behind quick input bar
- Fix showNewEvent undefined error in calendar AppView
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Client now connects to GET /sync/{appId}/stream via fetch + ReadableStream
instead of WebSocket + HTTP pull. Each app gets its own SSE connection that
delivers initial sync data + live updates in one persistent stream.
Changes:
- Remove WebSocket connection (connectUnifiedWs)
- Add connectSSE() per app using fetch + ReadableStream
- Parse SSE events (changes, heartbeat) from streamed response
- Auto-reconnect on disconnect with WS_RECONNECT_DELAY
- Fallback to polling if SSE endpoint not available
- ensureAppSynced() connects SSE for lazy apps on first visit
- handleOnline() reconnects all active SSE streams
- handleOffline() aborts all SSE connections
Benefits: 1 connection instead of 2 (WS + HTTP), data delivered instantly
without notification → pull round-trip, works through HTTP proxies/CDN.
Push (POST /sync/{appId}) remains unchanged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Only sync eager apps at startup (manacore, todo, calendar, contacts,
tags, links — needed for dashboard widgets). All other apps are lazy:
their collections sync on first module route visit.
Reduces startup pull requests from ~108 to ~20-30. Lazy apps get
synced when the user navigates to their module via ensureAppSynced().
- Add EAGER_APPS config set in sync.ts
- startAll() only starts pull for eager apps
- ensureAppSynced() starts pull + periodic sync for lazy apps
- Route-based trigger in +layout.svelte $effect
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Server now returns hasMore: true when there are more than 1000 changes
pending for a collection. Client continues pulling in a loop until
hasMore is false, using the last row's timestamp as cursor.
Prevents data loss after long offline periods where >1000 changes
accumulated for a single collection.
Server changes (Go):
- GetChangesSince() accepts limit parameter
- HandlePull() fetches limit+1, trims, sets hasMore
- SyncedUntil uses last row's timestamp when paginating
Client changes (TypeScript):
- Pull loop: while (hasMore) { fetch → apply → advance cursor }
- Cursor only persisted after all pages fetched
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merge the auth store factories (createManaAuthStore, createAuthStore) from
@manacore/shared-auth-stores into @manacore/shared-auth-ui, reducing
from 3 auth packages to 2.
- Copy store files into shared-auth-ui/src/stores/
- Re-export store factories and types from shared-auth-ui
- Update imports in manacore/web and arcade/web
- Remove shared-auth-stores from active package.json dependencies
Result: @manacore/shared-auth (core, platform-agnostic) +
@manacore/shared-auth-ui (Svelte components + stores)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ensureSelfContact now works without profile data — creates a minimal
"Ich" contact in guest/local mode, syncs with profile when authenticated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auto-create a self-contact (fixed ID) from the user's auth profile
on first visit to /contacts, synced on each load
- Pin self-contact to top of all contact lists with "Du" badge
- Add "Mein Profil" carousel page showing a profile card view
- Add page option to ContactPagePicker
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All app compute servers have been consolidated into apps/api/ (unified
Hono/Bun server). Old servers moved to apps/*/apps/server-archived/.
Archived: cards, chat, contacts, context, calendar, guides, moodlit,
mukke, news, nutriphi, picture, planta, presi, questions, storage, todo, traces
Still active: uload (separate domain), memoro (Supabase-based)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete consolidation of all 15 app servers into one Hono/Bun process.
Modules added: chat, context, picture, storage, todo, planta, nutriphi,
guides, moodlit, news, traces, presi
Total: 15 modules, one server, one port (3050), ~2400 LOC.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add ContactPage and ContactPagePicker components using the shared
PageCarousel/PageShell system. Available pages: Alle Kontakte,
Favoriten, Bald Geburtstag, Mit E-Mail, Mit Telefon, Mit Unternehmen,
Mit Adresse, Kürzlich hinzugefügt. Default opens "Alle" + "Favoriten".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New consolidated Hono/Bun API server at apps/api/ that replaces individual
app servers. One process, one port, one auth middleware, one container.
Modules ported:
- calendar: RRULE expansion, ICS import, Google Calendar (stub)
- contacts: avatar upload (S3), vCard import/parsing
- mukke: audio upload/download presigned URLs, batch cover art
Architecture: each module registers routes under /api/v1/{module}/*
using the shared-hono middleware stack (auth, rate limit, error handler).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All standalone SvelteKit web apps have been superseded by the unified
ManaCore app (apps/manacore/apps/web). Moved to web-archived/ within
each project to preserve history while removing from active workspace.
Archived: calc, cards, chat, citycorners, contacts, context, guides,
inventar, moodlit, mukke, news, nutriphi, photos, picture, planta,
presi, questions, skilltree, storage, times, zitare, todo, calendar,
uload, memoro
Moved to apps-archived/: wisekeep (not integrated, inactive)
Kept active: manacore (unified), matrix, manavoxel, arcade (separate containers)
Server, landing, and package directories remain active for each project.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded isDE ternaries in help/index.ts with svelte-i18n lookups.
FAQ questions, answers (HTML), features, highlights, and contact info are
now in locales/help/{de,en,es,fr,it}.json — supporting all 5 languages
instead of only German and English.
32 locale modules registered, 160 JSON files total.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Port i18n strings from 22 standalone apps into unified per-module locale
structure. Each module now has 5 language files (de, en, es, fr, it).
Modules added: calendar, contacts, memoro, citycorners, times, zitare,
inventar, photos, skilltree, questions, uload, chat, cards, picture,
moodlit, storage, context, presi, nutriphi, planta, calc, matrix, guides
Total: 31 locale modules, 155 JSON files, all 5 languages complete.
German and English ported from standalone apps, ES/FR/IT generated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Start createReminderScheduler with todoReminderSource on auth ready.
Request notification permission on app mount. Stop scheduler on destroy.
Todo reminders now fire browser notifications when dueDate - minutesBefore
is reached.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>