World Hub Page

World Hub Page is VySol's default frontend landing surface for committed worlds and the current Create World entrypoint. It renders the cinematic app frame, loads committed-world data in recent-use order, shows a branded startup splash while committed-world data is loading, uses the latest or last-hovered committed world for the hero area when one exists, displays each committed world as a stable image card with recent-use context, offers a dedicated Create World card at the start of the card row, and routes users into draft or committed World Detail through explicit card controls.

This page is for developers, power users, and AI coding agents that need to understand the World Hub contract before changing committed-world visibility, card layout, asset delivery, launcher startup, or the Create World entrypoint.

Why It Exists

VySol needs a recognizable first screen that can show committed worlds and provide the first action for opening a new draft world without making the frontend responsible for ingestion, commit, or durable world storage. The hub is the user-facing bridge between committed-world index records, the visual world list, and backend-owned draft opening.

The boundary matters because the hub sits near several systems that should remain separate: committed-world storage, asset delivery, draft-world opening, recent-world ordering, and World Detail routing.

Ownership Boundary

World Hub Page owns:

  • Rendering the default frontend landing page frame.
  • Showing the VySol logo mark and wordmark as non-clickable branding.
  • Showing a centered Worlds navbar with no search or settings controls.
  • Showing the default Create World hero area when there are no committed worlds.
  • Showing a branded startup splash while committed-world records are loading.
  • Loading committed-world records from the backend in most-recent-use order.
  • Using the latest committed world's saved name, optional description, background, and font for the initial loaded hero area.
  • Switching the hero title, hero description, hero font, and page background when a committed-world card is hovered.
  • Keeping the last hovered committed world as the active hero when no committed-world card is hovered.
  • Crossfading hero title/description changes and using a slightly slower crossfade for background changes.
  • Rendering the dedicated Create World card as the first card-row item.
  • Showing the current committed-world count on the Create World card.
  • Initiating backend-owned draft creation when the Create World card is clicked.
  • Rendering each committed world as a cinematic card with its background image, display name, and relative Last Used text.
  • Applying committed-world card hover styling that lifts the card, strengthens the connected card outline/glow, and reveals a subtle Manage World icon button for opening committed World Detail.
  • Routing from a committed-world Manage World icon button to committed World Detail using the clicked world ID.
  • Keeping card dimensions stable without horizontal hover expansion or text baseline drift.
  • Truncating long committed-world card titles with an ellipsis.
  • Applying the selected/default world font only to the hero title and description.
  • Keeping card text on the normal app font even when a world has a selected font.
  • Keeping the hero, navbar, and cards responsive without creating vertical page scroll on narrow browser heights.
  • Surfacing committed-world load failure in the UI without adding browser console noise.

World Hub Page does not own:

  • Creating draft setup state directly or inventing frontend-only draft IDs.
  • Creating committed worlds.
  • Running ingestion, parsing, splitting, or commit orchestration.
  • Uploading, selecting, deleting, or editing assets.
  • Marking committed worlds as used.
  • Showing chunk counts, chronicle counts, chat stats, graph stats, search, filters, or settings.
  • Loading committed-world detail data after navigation.
  • Implementing committed-world management actions.
  • Switching the hero from the Create World card, manual selection controls, search, settings, or any non-card route.
  • Customize, Ingestion, chat, retrieval, graph extraction, or provider behavior.
  • App logging or console diagnostics.

Normal Flow

The frontend entrypoint renders World Hub as the default page when no world-detail route query is present. The page imports the app's built-in logo, default background image, default font, Create World card image, local tab primitives, committed-world API client, and draft-world creation flow helper.

On mount, the page requests committed-world records from the backend and shows a branded splash instead of the default hero so a non-empty world list does not briefly flash the Create World state. The backend reads committed worlds from app.sqlite, sorts them by last_used_at with the most recent world first, and returns browser-safe background and font asset URLs. Empty results leave the Create World card as the only card-row item and keep the default Create World hero.

The Create World card always renders before committed-world cards. It uses the app's default background behavior for the page, but its own card image is the dedicated Create World artwork. Clicking the card calls the draft-world flow helper, which creates a backend draft and updates the app route to draft World Detail without a full document reload.

When committed worlds exist, the first returned world controls the initial loaded hero background, title, description, and hero font. Committed-world cards render in the same backend order using their background image, saved world name, and a relative Last Used label derived from last_used_at. Hovering a committed-world card immediately selects that world as the active hero, while the hero copy crossfades and the background crossfades slightly more slowly. When the pointer leaves the card, the last hovered world remains active. Hovering the Create World card does not change the active hero. Hovering a committed-world card or focusing its Manage World icon button still lifts the card slightly, strengthens the connected outline/glow, and reveals the icon. Clicking or keyboard-activating that icon routes to committed World Detail with the card's world ID. The card surface itself does not open the world, mutate state, mark the world as used, or display source/chunk/chat/graph stats.

Inputs

World Hub Page receives imported frontend defaults, the Create World card image, browser click actions, committed-world hover/focus UI state, and backend committed-world responses. Responses include committed-world identity, display name, optional description, background asset identity and URL, font asset identity and URL, and last_used_at.

It does not receive raw local file paths, source text, chunk records, graph state, chat state, provider responses, draft IDs, uploaded file handles, or draft-world metadata.

Outputs

The system produces visible frontend UI state: startup splash, brand, navbar, hero presentation, background presentation, Create World card, committed-world cards, committed-card hover/focus presentation, empty-list state, and load-failure state. On Create World click it asks the Draft World Detail API to create a draft and then updates the app route to draft World Detail. On committed-world icon click it updates the app route to committed World Detail for the selected world ID. It does not write files, create database rows directly, create committed worlds, mutate committed-world metadata, persist UI state, mark committed worlds as used, or emit app logs.

User-Facing Behavior

Users first see a dark VySol-themed startup splash with the centered butterfly mark and a spinner while committed-world data loads. After loading, they see a cinematic World Hub with VySol branding, one content-sized Worlds nav item, a hero area, and a row that starts with the Create World card.

If at least one committed world exists, the most recently used world appears first and supplies the initial loaded hero background, name, optional description, and hero font. Hovering another committed-world card changes the hero and full-page background to that world. The card hover effect is immediate, the hero title and description crossfade quickly, and the background crossfades a little more slowly. If the description is missing, the description space remains blank instead of falling back to default copy. If no committed world exists, users see the default Create World hero with the default background and font after loading completes.

The Create World card shows its dedicated image, Create World, and the current committed-world count such as 5 Worlds. Hovering it does not change the active hero; it keeps the latest committed-world hero when worlds exist. Clicking the Create World card creates backend-owned draft setup and opens draft World Detail. Each committed-world card shows the selected/default background image, world name, and relative Last Used label. Hovering a committed-world card gives it a connected blue/purple outline, soft glow, slight lift, and a subtle sliders-style Manage World icon button for opening committed World Detail. Keyboard focus on the icon keeps the Manage World action visible for activation. The committed-world card surface itself does not navigate. Current committed-world cards do not show descriptions, counts, source stats, chat stats, or graph stats. Hero title, hero description, and long committed-world card titles clamp inside their reserved areas instead of expanding the layout.

If committed-world loading fails, the card row shows a quiet Unable to load worlds. surface while the browser console stays free of repeated frontend error spam.

System Interactions

World Hub Page currently interacts with:

  • Committed World Card API, which lists committed worlds for card rendering.
  • Draft World Detail API, which creates backend-owned draft setup when the Create World card is clicked.
  • World Detail Page Shell, which renders after the frontend route changes to draft or committed mode and owns committed detail loading after navigation.
  • Asset File Delivery, which serves card background images and hero fonts by asset ID.
  • Committed World Index Storage, which owns the committed-world metadata behind the card API.
  • Asset Metadata Storage and Safe Asset File Storage indirectly through backend asset resolution.
  • Built-in default assets, which provide the logo, page background image, and default font.
  • The local tab wrapper, which provides the static navbar structure.
  • The frontend and backend launcher services used during normal startup.

It must stay separate from draft-world registry internals, source staging internals, ingestion attempts, parser systems, graph systems, retrieval, and chat behavior.

Current Edge Cases

Internal edge cases:

  • Empty committed-world lists render the Create World card without fake committed-world cards.
  • Failed card loading shows a quiet row-level message without adding noisy console logs.
  • The startup splash prevents the default Create World hero from flashing before a non-empty world list resolves.
  • The latest committed world controls the initial loaded hero only after the committed-world list loads successfully.
  • Hovering a committed-world card changes the active hero without marking the world as used.
  • Leaving a committed-world card keeps the last hovered committed world active.
  • Hovering the Create World card does not replace the active committed-world hero.
  • Hero copy and background changes crossfade without delaying the card hover effect.
  • Missing world descriptions render as blank hero descriptions, not default Create World descriptions.
  • Hero title text is constrained to avoid resizing the overall page layout.
  • Hero description text is constrained to avoid resizing the overall page layout.
  • Long committed-world card titles truncate with an ellipsis instead of wrapping or resizing cards.
  • The Create World card count is always visible and does not depend on hover or focus.
  • The committed-world Last Used label is always visible and stays aligned with the Create World count row.
  • Committed-world hover styling must not clip card text, hard-cut glow at the card row edge, or shift text baselines after hover ends.
  • The committed-world open icon appears only during committed-card hover or focus.
  • The committed-world card surface remains presentation-only and does not navigate.
  • The Create World card uses its dedicated image while the page background remains driven by default, latest committed-world, or last-hovered committed-world hero behavior.
  • Card layout uses fixed dimensions and does not depend on hover expansion.
  • Card text uses the default app font even when the committed world has a selected font asset.
  • Hero title and description use the active committed world's selected/default font when committed worlds exist.
  • Narrow browser layouts keep the app surface locked to the viewport so cards do not create vertical page scroll.
  • The hero and navbar text remain visible and non-selectable.
  • The brand area is not an anchor or button, so clicking it does not navigate.

Cross-system edge cases:

  • Rendering the hub must not create drafts or committed worlds.
  • Clicking Create World must create a backend-owned draft, not a frontend-only draft record.
  • Create World navigation must update the frontend route without forcing a full document reload.
  • Rendering the hub must not mark committed worlds as used.
  • Rendering Last Used must use backend last_used_at values without refreshing or mutating them.
  • Opening committed World Detail from the card icon must route by world ID without the Hub loading committed-world detail data or refreshing last_used_at.
  • Card image URLs and hero font URLs must come from backend asset delivery instead of hardcoded local filesystem paths.
  • Stored asset paths must remain backend-owned so unsafe or missing assets are rejected before file serving.
  • Recent-use ordering must come from committed-world storage rather than client-side draft or display-name sorting.

Invariants

  • World Hub must remain the default frontend page when no world-detail route query is present.
  • The VySol brand must remain visible, top-left, and non-clickable.
  • The navbar must contain only Worlds for the current hub.
  • The navbar must use the shared content-sized app nav behavior: width follows its contents, height stays fixed, and tab text size matches other app nav tabs.
  • Search and settings must not appear in the current hub.
  • The default empty-list hero copy must remain Create World and Build a living setting for roleplay and simulation. until that default copy is intentionally changed.
  • The Create World card must remain the first card-row item.
  • The Create World card must call backend draft creation before routing to World Detail.
  • Committed-world opening must happen through the card icon button, not through the committed-world card surface.
  • When committed worlds exist, the initial loaded hero must use the most recently used committed world's saved metadata.
  • Hovering committed-world cards must update only frontend presentation, not navigation or committed-world last_used_at.
  • Card rendering must use committed-world backend data, not mock frontend-only worlds.
  • Committed-world cards must show background image, name, and Last Used for the current card behavior.
  • Committed-world icon navigation must not imply committed-world detail data is loaded by the Hub.
  • Draft and uncommitted worlds must not appear in the Hub.
  • The hub must not hardcode local machine paths, user data, secrets, or uploaded file paths.

Implementation Landmarks

  • frontend/src/world-hub-page.tsx owns the World Hub composition, card loading state, and card rendering.
  • frontend/src/world-hub-page.css owns World Hub-specific layout, viewport locking, and card styling.
  • frontend/src/committed-world-api.ts owns committed-world frontend request helpers; the Hub uses the card-list request.
  • frontend/src/draft-world-api.ts owns the Create World draft-opening helper.
  • frontend/src/app-navigation.ts owns frontend route helpers for Hub and World Detail navigation.
  • frontend/src/main.tsx owns the current route switch between Hub and World Detail.
  • app/committed_worlds owns committed-world card listing and detail routes.
  • app/storage/worlds.py owns recent-use ordering for committed-world records.
  • app/asset_files owns safe browser-facing asset file delivery.
  • frontend/vite.config.ts proxies the frontend card and asset requests during dev startup.

What AI/Coders Must Check Before Changing This System

Before editing World Hub Page, check:

  • Whether the change belongs in card rendering instead of world creation, ingestion, asset upload, search, settings, storage, or navigation work.
  • Whether the page still renders when the backend returns no committed worlds.
  • Whether rendering the hub still avoids creating drafts, committed-world rows, source state, or ingestion state.
  • Whether clicking Create World still creates draft state through the Draft World Detail API.
  • Whether committed worlds still arrive in most-recent-use order.
  • Whether draft or uncommitted worlds remain excluded.
  • Whether card images and hero fonts still load through safe backend asset delivery.
  • Whether narrow browser layouts remain non-scrollable while preserving the card row.
  • Whether hero text constraints prevent long names or descriptions from resizing the layout unexpectedly.
  • Whether generated frontend build output stays ignored and source assets remain the tracked source of truth.