{
  "schema": "leumas.docs.page/1",
  "id": "pkg:@leumas/web",
  "slug": "products/web",
  "kind": "capabilities",
  "bucket": "product",
  "title": "Leumas Web — @leumas/web",
  "name": "Leumas Web",
  "eyebrow": null,
  "chip": "@leumas/web",
  "summary": "Leumas Web — the public hub (Google-HUD app index, social, dashboard, account, Imperium subdomains). A thin shell over @leumas/features.",
  "keywords": [
    "web",
    "web headlock",
    "subdomains",
    "web config-registry",
    "features",
    "web api",
    "leumas web",
    "how to use web"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# Leumas Web — `@leumas/web`\n\n**The index of everything Leumas hosts, and the home of Leumas Social.**\nFind anything in Imperium, jump to it, manage your account — and use the full social network.\n\n`leumas.tech` · dev port **5173** · a thin shell over `@leumas/features`.\nArchitecture: [PLATFORM.md](../../PLATFORM.md) · [APPLIANCES.md](../../APPLIANCES.md) §3\n\n---\n\n## Core functionality\n\n1. **Index / search** — every app, tool, subdomain, page, capability, chatbot, automation and site\n   mode in the ecosystem, from `@leumas/index-service` (`/index/*`). This is the \"Google of Leumas\",\n   and it is a real page at **`/search`**: ranked, snippeted, faceted by kind, paged and linkable.\n   ⌘K and `/search` call the SAME `/index/search` so they agree on ordering; the palette's last row\n   hands the query over to the page (`AppLayout`'s `searchAllHref`). `/sitemap` redirects here.\n   `/sitemap.xml` is unaffected — that is `createSeoRouter` in `@leumas/hosting`.\n2. **Funnel pages** — `/apps/:slug` per-app pages with full SEO, screenshots, and \"open in Studio\" /\n   \"get the app\" calls to action.\n3. **Leumas Social** — the entire social product: feed, reels, watch, stories, messenger, friends,\n   groups, chatrooms, discover, marketplace, random chat, sing, profiles, notifications.\n   **Gated in production**: any `vite build` shows the `/social` teaser and redirects `/social/*` to\n   it; dev is open. Leumas staff, tenant admins and users flagged `beta` bypass it. Override with\n   `VITE_SOCIAL=full|teaser`. The default is derived from `import.meta.env.PROD` in `App.jsx` and\n   NOT from a dotfile, because `.env.*` is gitignored — see the note there.\n4. **Account & dashboard** — login/signup, membership & Stripe checkout, PassNode wallet, the\n   `/dashboard` operator deck, API keys.\n5. **Marketing & portfolio** — the public Showcase pages, company pages, gallery.\n6. **Hosted-site renderer** — when a request arrives on a hosted subdomain or custom domain, the same\n   build renders **that tenant's site** instead of the hub (`HostedSiteApp`).\n7. **The social-only bundle** — a second entry that ships social + auth only. This is what\n   `leumas-ios` loads.\n\n## What it must never do\n\n| Never | Because |\n|---|---|\n| Host sites itself | Imperium does — `@leumas/hosting` / `@leumas/imperium-server` |\n| Edit site content | Studio does. Web renders, Studio authors |\n| Re-implement social UI | it's `@leumas/features/surfaces/social` — Studio used the same code, iOS uses the same code |\n| Ship an admin surface | Studio (`/admin`) and leumas-admin own those |\n| Talk to `admin.leumas.tech` | that's staff-only infrastructure |\n\n## Composes\n\n```\n@leumas/ui  @leumas/theme          the st- kit + tokens. No bespoke components\n@leumas/features                   social · dashboard · consoles · physics · os surfaces + guards\n@leumas/api-client                 every HTTP call. credentials:'include' + Bearer fallback\n@leumas/config-registry            Imperium modes, DynamicPage, custom x- modes\n@leumas/hosting                    subdomain resolution on the client side\n@leumas/imperium-pages             the mode page components\n@leumas/cinematic                  ShowcaseHero and the splash language\n@leumas/hud  @leumas/media         hud mode · media globe mode\n@leumas/headlock                   scroll/pointer lock helpers\n```\n\n## File tree\n\n```\nproducts/leumas-web/\n├── package.json\n├── vite.config.js [done] port 5173 · proxies /auth /api /db /social /index /mcp /leviathan /library …\n├── index.html [done] hub entry\n├── social.html [todo] social-only entry (iOS)\n├── configs/ [done] local dev configs\n├── public/cinematic/ [done]\n└── src/\n ├── main.jsx [done] boots TenantBoot · registers custom x- modes\n ├── social.jsx [todo] social-only boot: socialRoutes() + auth + account\n ├── App.jsx [done] 229 lines · 37 routes + socialRoutes() + dashboardRoutes()\n ├── HostedSiteApp.jsx [done] a hosted subdomain owns the whole path space\n ├── routeComponents.js [done] route → component binding\n ├── siteHandlers.jsx [done]\n    ├── bootstrap/\n │ ├── TenantBoot.jsx [done] hub vs hosted-site decision\n │ └── tenant.js [done]\n ├── cinematic/ [done]\n └── pages/ [done] 30 .jsx — Showcase, company, dashboard, DynamicPage, LibraryApp\n ├── _shared/ [done] ecosystem.jsx · brandData.js\n └── dashboard/ [done]\n```\n\n## Roadmap\n\n### [todo] W1 · The social-only entry (roadmap B4)\n\n- Status: todo — `social.html` + `src/social.jsx` — mount `socialRoutes()` + auth + account only\n- Status: todo — Add the entry to `vite.config.js` `build.rollupOptions.input`\n- Status: todo — Verify the bundle excludes cinematic, three, media, hud\n- Status: todo — Point `products/leumas-ios/capacitor.config.json` `webDir` at it\n- Status: todo — Keep `/social` on the hub entry — desktop users and SEO\n\n### [todo] W2 · The link page (roadmap D1)\n\n- Status: todo — `/link` route — reuse the existing `<Login>`, then a consent step:\n      *\"Link your Leumas account to Studio on DESKTOP-4F2A?\"*\n- Status: todo — On approve, call `GET /auth/link/authorize`, redirect to the loopback callback\n- Status: todo — [warning] This page is on **leumas.tech**. A customer must never be sent to `admin.leumas.tech`\n\n### [partial] W3 · Index depth\n\n- Status: done — `/index/search` is the site-wide search: ranked (six fixed score bands, total ordering),\n      `limit`/`offset` paged, `kind`-faceted, snippeted, and one source-load per few seconds instead\n      of one per keystroke. Reports `search: 'lexical'`, the same field `/marketplace/listings` uses,\n      so a semantic re-rank can arrive without every caller guessing which ranker ran.\n- Status: done — `/search` page + the ⌘K \"See all results\" handover\n- Status: done — Subdomains are searchable — `sites` is a first-class index kind, `configs` is its alias\n- [~] **`plugin_listings` deliberately NOT added as an index kind.** `hydrateAppCatalogs`\n      (`shared/services/marketplace/src/hydrate.js`) is the one writer keeping `plugin_listings` and\n      `tools` in step from a single `defineLeumasApp`, so every listing already has a `tools` row the\n      `apps`/`tools` sources serve. A `listings` kind would list every app twice and re-open the\n      drift that file exists to close. The store's semantic reach instead appears on `/search` as a\n      \"You might also mean\" strip fed by `GET /marketplace/listings`.\n- Status: todo — Sitemap includes marketplace listings\n\n### [todo] W4 · Funnel quality\n\n- Status: todo — Every `/apps/:slug` page: screenshot, \"how it's made\", \"how to use\", pricing, install CTA\n- Status: todo — Per-domain scoping so a tenant's hub shows only their apps\n\n### [partial] W5 · README accuracy\n\n- Status: done — This file no longer says \"scaffold only\" — the product is live and extensive\n\n## Run\n\n```bash\npnpm --filter @leumas/web dev\n```\n\nLeave `VITE_API_BASE` **unset** in dev — the Vite proxy makes the httpOnly cookie work with no CORS.\nOnly set it for a genuinely cross-origin API.\n",
  "source": {
    "path": "products/leumas-web/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 7317,
    "hash": "a2834b4f397a3e8dc83874423efb3b338da30f3d"
  },
  "urls": {
    "html": "/p/products/web",
    "json": "/docs/products/web.json",
    "md": "/docs/products/web.md"
  },
  "links": {
    "composes": [
      "pkg:@leumas/body-3d",
      "pkg:@leumas/capability-sdk",
      "pkg:@leumas/config-registry",
      "pkg:@leumas/entrance",
      "pkg:@leumas/features",
      "pkg:@leumas/game-3d",
      "pkg:@leumas/game-kit",
      "pkg:@leumas/sound",
      "pkg:@leumas/theme",
      "pkg:@leumas/ui"
    ],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  },
  "exports": null
}
