Redesign UI with new token system, primitives, and motion
Restraint-first design language: neutral gray surfaces + one blue accent (cyan/amber/red reserved for state), 8pt spacing, softer radii, one ambient + one raised shadow, standardized motion tokens. Alfa Slab One demoted to BrandMark only; Inter carries all page copy. New primitives (Button, Card, Badge, Stat, SectionHeader, Skeleton, EmptyState, Tabs, Breadcrumbs, StatusPip, Field, Input, Select, Textarea) plus motion utilities (tweenNumber, viewTransition) and a global toast system. All eight route surfaces rewritten on top: Fleet gains an overview hero, Server detail restructures into tabs, Deployments gets a collapsible drift summary + per-server pipeline visual, and the scripts/configs/plugins/betas flows adopt the new form primitives. Sticky translucent nav with backdrop blur, view-transition cross-fades between routes, staggered card entrance on Fleet, breathing status pip halo, tabular-numeric player counts. Gmail-style g-key nav shortcuts. Mobile stacks below 720px; prefers-reduced-motion neutralizes durations. Legacy tokens preserved as aliases so any un-migrated code still renders.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
<script lang="ts">
|
||||
import type { Health } from '$ui/stores/servers.js';
|
||||
|
||||
interface Props {
|
||||
health?: Health;
|
||||
size?: 'sm' | 'md';
|
||||
label?: string | null;
|
||||
}
|
||||
|
||||
let { health = 'offline', size = 'md', label = null }: Props = $props();
|
||||
|
||||
let toneClass = $derived(
|
||||
health === 'online' ? 't-online' :
|
||||
health === 'stale' ? 't-warning' :
|
||||
't-danger'
|
||||
);
|
||||
|
||||
let announceLabel = $derived(
|
||||
label ?? (
|
||||
health === 'online' ? 'online' :
|
||||
health === 'stale' ? 'stale' :
|
||||
'offline'
|
||||
)
|
||||
);
|
||||
</script>
|
||||
|
||||
<span class="pip s-{size} {toneClass}" role="status" aria-label={announceLabel}>
|
||||
<span class="halo" aria-hidden="true"></span>
|
||||
<span class="dot" aria-hidden="true"></span>
|
||||
</span>
|
||||
|
||||
<style>
|
||||
.pip {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.s-sm { width: 8px; height: 8px; }
|
||||
.s-md { width: 10px; height: 10px; }
|
||||
|
||||
.dot {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* Halo — opacity+scale only, GPU-cheap, no box-shadow ring. */
|
||||
.halo {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.t-online .dot { background: var(--state-online); box-shadow: 0 0 4px rgba(124, 212, 255, 0.55); }
|
||||
.t-online .halo { background: var(--state-online); animation: pip-breathe 2.4s var(--ease-standard) infinite; }
|
||||
|
||||
.t-warning .dot { background: var(--state-warning); }
|
||||
.t-danger .dot { background: var(--state-danger); opacity: 0.7; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user