{
  "schema": "leumas.docs.page/1",
  "id": "pkg:@leumas/touchdesign-web",
  "slug": "products/touchdesign-web",
  "kind": "capabilities",
  "bucket": "product",
  "title": "@leumas/touchdesign-web — Leumas Touchdesign at touchdesign.leumas.tech",
  "name": "@leumas/touchdesign-web",
  "eyebrow": "Leumas Touchdesign at touchdesign.leumas.tech",
  "chip": null,
  "summary": "Leumas Touchdesign at touchdesign.leumas.tech — node graphs that draw. Build generative visuals in the browser and export them anywhere: embed, subdomain, Infinity Display, video.",
  "keywords": [
    "touchdesign",
    "node graph",
    "generative visuals",
    "shader editor online",
    "animated background"
  ],
  "audience": "both",
  "funnel": {
    "product": null,
    "cta": null
  },
  "body": "# @leumas/touchdesign-web — Leumas Touchdesign at `touchdesign.leumas.tech`\n\nNode graphs that draw — build generative visuals in the browser and export them anywhere: embed,\nsubdomain, Infinity Display, video.\n\n**Status: built.** Blueprint: [`products/TODOS/touchdesign.leumas.tech.md`](../TODOS/touchdesign.leumas.tech.md)\n(§6a records the decisions made while building).\n\n## What is where\n\n| Piece | Lives in |\n|---|---|\n| The runtime, the 43 nodes, the 19 demos, the frame loop, the player | `@leumas/touchdesign` (`shared/packages/touchdesign`) |\n| The xyflow editor and the Studio workspace | `@leumas/touchdesign/editor` · `@leumas/touchdesign/workspace` |\n| The Imperium render mode and the HUD widget | `@leumas/touchdesign/register` · `@leumas/touchdesign/hud-widget` |\n| The API | `products/leumas-api/src/{controllers,routes}/touchdesign.js` → `/api/touchdesign/*` (dynamic `td_designs`, `td_renders`) |\n| The render runner (headless Chrome + ffmpeg) | `products/leumas-api/src/jobs/touchdesignRender.js` |\n| The money | `policy.js` `touchdesign.*` (floor: run, export, 10s watermarked renders; tiers: saves, publish, render seconds) |\n| The Studio app | `shared/apps/touchdesign` · `/admin/touchdesign` |\n| The SDK | `@leumas/touchdesign-sdk` |\n| This site | `src/content/pages.js` (the prose as data) · `src/content/nodes.generated.js` (from the engine at build) · `src/screens/*` |\n| Guards | `pnpm check:touchdesign-public` · `pnpm smoke:touchdesign-site` |\n\n## Why this can read a visitor's session with no configuration\n\n`touchdesign.leumas.tech` is a platform-owned Imperium site row\n(`shared/services/index/src/touchdesignSite.js`), served by the Imperium worker behind the IIS\n`*.leumas.tech` wildcard. That worker forwards `/api` and the auth prefixes to leumas-api\n**preserving the visitor's Host header and their cookies**, so every API call is same-origin.\n\n[warning] **Never set `VITE_API_BASE`.** The session cookie is httpOnly and same-origin; an absolute API\norigin turns every authenticated call cross-origin and the page renders as permanently signed out.\n\n## Running it\n\n```bash\npnpm dev:api                                    # :3000\npnpm dev:touchdesign                            # :5079\npnpm --filter @leumas/touchdesign-web build\npnpm check:touchdesign-public && pnpm smoke:touchdesign-site\n```\n\n[warning] `pnpm deploy:touchdesign` copies files but carries **no release stamp**. Only `pnpm ship` applies.\n\n## The two lists that must never disagree\n\n`src/pages.js` holds `PAGES` and `NOINDEX`, derived from `src/content/pages.js`. Every route the\nrouter renders is in one of them; a route in neither is what `check:touchdesign-public` exists to\ncatch. The sitemap, llms.txt, robots.txt and the guard all read that one file.\n",
  "source": {
    "path": "products/leumas-touchdesign/README.md",
    "blobSha": "",
    "commit": "",
    "committedAt": "",
    "provenance": "no-git",
    "bytes": 2899,
    "hash": "5f3a63d4be11275c1a026678fc8e16d280c66e9d"
  },
  "urls": {
    "html": "/p/products/touchdesign-web",
    "json": "/docs/products/touchdesign-web.json",
    "md": "/docs/products/touchdesign-web.md"
  },
  "links": {
    "composes": [
      "pkg:@leumas/theme",
      "pkg:@leumas/ui"
    ],
    "usedBy": [],
    "product": [],
    "howTo": [],
    "skills": []
  },
  "exports": null
}
