diff --git a/docs/swarm/ui.md b/docs/swarm/ui.md index 81934037..b80b3232 100644 --- a/docs/swarm/ui.md +++ b/docs/swarm/ui.md @@ -20,16 +20,16 @@ the highlighted one. **Escape**, **Tab** or a press elsewhere shut the list with changing anything. Typing the start of an option's name picks it, also with the list shut. A dropdown inside a dialog opens above the dialog and the dialog doesn't cut it off. -| route | what | -| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `/` | the start page: the swarm's name over a digital-rain backdrop, plus a paperclip offering to set up an agent while no `ruth` exists, or her hive declares her destroyed (it opens the create form with `ruth` filled in); the swarm name in the header links here | -| `/agents` | every agent as a card that opens in place (status, config PR, wanted state, inference settings, resource caps, permissions, accounts, terminal), under a folded **hives** card with the hive directory and each hive's last reported status; create agents (with their permissions, optionally from an [archetype](archetypes.md)), link forge, matrix and GitHub accounts | -| `/agents//terminal` | one agent's live terminal | -| `/agents//subagents//terminal` | one of that agent's subagents' live terminal | -| `/reports` | two folded cards, each read only once opened: the **alerts** the swarm's Grafana holds now, the firing ones, with a button for the pending, no-data and error ones and a link to Grafana's own alert list; read through the controller with a Viewer service-account token, and a cross-repo **issue report** | -| `/jobs` | the controller's job graph, where agent creation and credential mints show progress, and under it the swarm builder's recent builds (agent config PRs, and agents built from `internal/meta` before a deploy), with what nix printed when one failed, and the review classifier's recent runs, a try-out on a real PR, and its settings | -| `/messages` | the swarm-wide message feed: every message between agents, and to them from the operator, reminders and compaction, with a history window and a filter on sender or recipient; a folded **broadcast** card above the feed sends one message to more than one agent at once, and a folded **schedules** card holds the scheduled prompts: add, edit, pause, resume and remove | -| `/notifications` | the notification router's flows: a switch for each built-in, every flow drawn as a graph, and an editor for custom flows | +| route | what | +| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `/` | the start page: the swarm's name over a digital-rain backdrop with the slug (`hyperhive / we are the wired`, its shaded gradients pulsing in a wave unless reduced motion is on) at the foot, plus a paperclip offering to set up an agent while no `ruth` exists, or her hive declares her destroyed (it opens the create form with `ruth` filled in); the swarm name in the header links here | +| `/agents` | every agent as a card that opens in place (status, config PR, wanted state, inference settings, resource caps, permissions, accounts, terminal), under a folded **hives** card with the hive directory and each hive's last reported status; create agents (with their permissions, optionally from an [archetype](archetypes.md)), link forge, matrix and GitHub accounts | +| `/agents//terminal` | one agent's live terminal | +| `/agents//subagents//terminal` | one of that agent's subagents' live terminal | +| `/reports` | two folded cards, each read only once opened: the **alerts** the swarm's Grafana holds now, the firing ones, with a button for the pending, no-data and error ones and a link to Grafana's own alert list; read through the controller with a Viewer service-account token, and a cross-repo **issue report** | +| `/jobs` | the controller's job graph, where agent creation and credential mints show progress, and under it the swarm builder's recent builds (agent config PRs, and agents built from `internal/meta` before a deploy), with what nix printed when one failed, and the review classifier's recent runs, a try-out on a real PR, and its settings | +| `/messages` | the swarm-wide message feed: every message between agents, and to them from the operator, reminders and compaction, with a history window and a filter on sender or recipient; a folded **broadcast** card above the feed sends one message to more than one agent at once, and a folded **schedules** card holds the scheduled prompts: add, edit, pause, resume and remove | +| `/notifications` | the notification router's flows: a switch for each built-in, every flow drawn as a graph, and an editor for custom flows | Everything it shows comes from [`swarm-controller`](../../swarm-controller/README.md). Pages that refresh on a timer share one polling rule: the page sends no new diff --git a/frontend/packages/swarm-ui/src/pages/StartPage.css b/frontend/packages/swarm-ui/src/pages/StartPage.css index d7d045cd..9d28393d 100644 --- a/frontend/packages/swarm-ui/src/pages/StartPage.css +++ b/frontend/packages/swarm-ui/src/pages/StartPage.css @@ -21,3 +21,11 @@ 0 0 0.4em color-mix(in srgb, var(--purple) 55%, transparent), 0 0 1.2em var(--bg); } +/* The slug sits at the foot of the page, over the rain. It stays under 2em + * from the bottom edge, where the setup assistant starts (bottom-right, + * `SetupAssistant.css`), so the two never overlap, however narrow the window. */ +.start-page .ui-slug { + position: absolute; + inset: auto 0 0; + margin: 0 0 0.4em; +} diff --git a/frontend/packages/swarm-ui/src/pages/StartPage.tsx b/frontend/packages/swarm-ui/src/pages/StartPage.tsx index ff5f9b38..c72595f9 100644 --- a/frontend/packages/swarm-ui/src/pages/StartPage.tsx +++ b/frontend/packages/swarm-ui/src/pages/StartPage.tsx @@ -1,7 +1,8 @@ // — `/`, the swarm's landing page: the swarm's name over the // digital-rain backdrop, plus the setup assistant while the swarm has no -// `ruth`. The header's swarm name links here. The hive roster is a card on the agents page. +// `ruth`, and the slug at the foot. The header's swarm name links here. The hive roster is a card on the agents page. import { MatrixRain } from "../shell/MatrixRain.js"; +import { Slug } from "../ui/slug/Slug.js"; import { useSwarmName } from "../shell/useSwarmName.js"; import { SetupAssistant } from "./SetupAssistant.js"; import "./StartPage.css"; @@ -17,6 +18,7 @@ export function StartPage() {

{name}

+ ); } diff --git a/frontend/packages/swarm-ui/src/ui/slug/Slug.css b/frontend/packages/swarm-ui/src/ui/slug/Slug.css new file mode 100644 index 00000000..d2c9d2b0 --- /dev/null +++ b/frontend/packages/swarm-ui/src/ui/slug/Slug.css @@ -0,0 +1,43 @@ +/* The slug: the signature line at the foot of a page. The shaded blocks pulse + in a wave, each glyph delayed by its index (`--i`). Motion is gated the way + `shell/Shell.css` gates its own: stilled under the OS preference and the + `data-motion` override, back on with `allow`. */ +.ui-slug { + display: flex; + align-items: center; + justify-content: center; + gap: 1em; + margin: 2em 0 1em; + color: var(--purple-dim); + font-size: 0.8em; + letter-spacing: 0.15em; +} +.ui-slug-gradient { + white-space: pre; +} +.ui-slug-glyph { + display: inline-block; + animation: ui-slug-wave 2.4s ease-in-out infinite; + animation-delay: calc(var(--i) * 0.18s); +} +@keyframes ui-slug-wave { + 0%, + 100% { + opacity: 0.3; + } + 50% { + opacity: 1; + } +} +@media (prefers-reduced-motion: reduce) { + .ui-slug-glyph { + animation: none; + } +} +:root[data-motion="reduce"] .ui-slug-glyph { + animation: none; +} +:root[data-motion="allow"] .ui-slug-glyph { + animation: ui-slug-wave 2.4s ease-in-out infinite; + animation-delay: calc(var(--i) * 0.18s); +} diff --git a/frontend/packages/swarm-ui/src/ui/slug/Slug.tsx b/frontend/packages/swarm-ui/src/ui/slug/Slug.tsx new file mode 100644 index 00000000..18153c57 --- /dev/null +++ b/frontend/packages/swarm-ui/src/ui/slug/Slug.tsx @@ -0,0 +1,30 @@ +// — the signature line, `░▒▓█▓▒░ hyperhive / we are the wired ░▒▓█▓▒░`, +// the hive dashboard's footer line without its hive-c0re part. The +// shaded blocks at each end are the gradients: each glyph pulses a beat after +// its neighbour, so a wave runs along them (stilled under reduced motion, see +// `Slug.css`). +import "./Slug.css"; + +const GRADIENT = ["░", "▒", "▓", "█", "▓", "▒", "░"]; + +function Gradient() { + return ( + + ); +} + +export function Slug() { + return ( +

+ + hyperhive / we are the wired + +

+ ); +}