Watch
0
0
Fork
You've already forked hyperhive
0

swarm ui: the start page ends with the slug, its gradients animated

hyperhive / we are the wired between two shaded gradients that pulse in a
wave, still under reduced motion. It sits under 2em from the bottom edge,
clear of the setup assistant.
This commit is contained in:
iris 2026-11-01 13:31:34 +01:00 • committed by mara
commit 0e840bd34b
4 changed files with 94 additions and 11 deletions

View file

@ -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;
}

View file

@ -1,7 +1,8 @@
// <StartPage> — `/`, 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() {
<MatrixRain />
<h1 class="start-page-name">{name}</h1>
<SetupAssistant />
<Slug />
</div>
);
}

View file

@ -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);
}

View file

@ -0,0 +1,30 @@
// <Slug> — 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 (
<span class="ui-slug-gradient" aria-hidden="true">
{GRADIENT.map((glyph, i) => (
<span key={i} class="ui-slug-glyph" style={{ "--i": i }}>
{glyph}
</span>
))}
</span>
);
}
export function Slug() {
return (
<p class="ui-slug">
<Gradient />
<span class="ui-slug-text">hyperhive / we are the wired</span>
<Gradient />
</p>
);
}