# Plexuses A **plexus** is a full app — the vocabulary has always said so (*"full app with backend, frontend and DB"*). What was missing is that a plexus is **exported, not served**. It is compiled to a distributable file the way vite builds for production, and that compile is the whole point of the format. ```bash make dist # compile the plexus UIs for standalone make dist sample # for a named room ``` Output is one `index.html` per plexus under `gen//plexuses//`, carrying its theme, its data and its diagrams inline. No server, no node, no network. Zip it, mail it, double-click it. `make build` runs the same step as part of a room build. `make dist` exists for the loop where the UI is what you are working on — rebuilding a whole room to see a CSS change is a slow way to iterate. ## The constraint that shapes it It has to open from a **double-clicked file on a machine with no egress**. That is the state a regulated Windows box is usually in, and it rules out three things a normal web app does: | Ruled out | Because | | --- | --- | | `fetch("bundle.json")` | `file://` treats every sibling file as cross-origin | | `` | an absolute path assumes a server at the root | | a webfont `@import` | a blocked stylesheet is a stall, not a fallback | So the data is a JS object, the theme is inlined at compile time, and the fonts are stacks. The test that matters is opening the output with the network off and seeing zero failed requests — everything else is cosmetic. ## Declaring one A room opts in through `cfg//data/plexuses.json`, the same shape and the same place as its sibling `data/*.json` files: ```json { "items": [ { "name": "bundle" } ] } ``` A room may override anything the plexus declares — most usefully the theme: ```json { "items": [ { "name": "bundle", "theme": "mcrn" } ] } ``` ## Writing one ``` soleprint/artery/plexuses// plexus.json identity, theme, the data the page renders app/index.html the template ``` `build.py` fills these placeholders and writes one file: | Placeholder | Becomes | | --- | --- | | `%%THEME_CSS%%` | tokens plus every theme, so the switcher has something to switch to | | `%%BUNDLE%%` | `plexus.json` as a JS object | | `%%GRAPH%%` | a rendered SVG from `docs/graphs/`, inlined | | `%%TITLE%%` `%%DESCRIPTION%%` `%%DEFAULT_THEME%%` `%%BUILT%%` | from the manifest | Anything else in `app/` is copied alongside, for a plexus that outgrows one file. ## The bundle plexus The one that ships. It answers "what does a rig installation have at its disposal" — tools, cabinets, veins, themes — and embeds the system diagram. Because the SVG is **inlined** rather than ``-linked, the theme switch recolours the diagram too: graphviz writes `class="node accent"` into the SVG, and CSS outranks the presentation attributes it bakes in. Switching to `lucid` turns both the page and the diagram into something printable, which is the demonstration the format exists for. ## Not the same as rig's bundle Two artifacts, both called bundle, generated by different repos: | | soleprint | rig | | --- | --- | --- | | Command | `make dist` | `make manifest` in `sample-rig` | | Artifact | `plexuses//index.html` | `generated/.yaml` | | Needs | nothing | kind + MetalLB | | Answers | what shipped, on any machine | whether this cluster install is sound | Complementary. One proves the environment, the other travels.