(chore) init commit and add tasks

This commit is contained in:
Story Crater Bot
2026-08-18 18:33:49 -07:00
commit 6c6218ef36
61 changed files with 9851 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
import type { ReactNode } from 'react'
type Props = {
label: string
hint?: string
right?: ReactNode
children: ReactNode
className?: string
}
/** Instrument panel chrome: hairline frame, corner ticks, eyebrow label. */
export function Panel({ label, hint, right, children, className = '' }: Props) {
return (
<section className={`relative border border-wire bg-deck ${className}`}>
<span className="pointer-events-none absolute -left-px -top-px h-2 w-2 border-l border-t border-wire-lit" />
<span className="pointer-events-none absolute -right-px -top-px h-2 w-2 border-r border-t border-wire-lit" />
<span className="pointer-events-none absolute -bottom-px -left-px h-2 w-2 border-b border-l border-wire-lit" />
<span className="pointer-events-none absolute -bottom-px -right-px h-2 w-2 border-b border-r border-wire-lit" />
<header className="flex items-baseline justify-between gap-4 border-b border-wire px-4 py-2.5">
<div className="flex items-baseline gap-3">
<h2 className="font-data text-[11px] uppercase tracking-[0.18em] text-chalk">{label}</h2>
{hint && <p className="font-data text-[10px] text-dim">{hint}</p>}
</div>
{right}
</header>
<div className="p-4">{children}</div>
</section>
)
}
+43
View File
@@ -0,0 +1,43 @@
'use client'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
const SURFACES = [
{ code: 'B', href: '/cluster', label: 'Topology' },
{ code: 'E', href: '/cluster/delivery', label: 'Delivery' },
{ code: 'C', href: '/cluster/terminal', label: 'Terminal' },
{ code: 'D', href: '/cluster/chat', label: 'Chat' },
]
export function Rail() {
const pathname = usePathname()
return (
<nav
aria-label="Cluster surfaces"
className="flex shrink-0 gap-px overflow-x-auto border-b border-wire bg-void md:w-16 md:flex-col md:overflow-visible md:border-b-0 md:border-r"
>
{SURFACES.map((s) => {
const active = pathname === s.href
return (
<Link
key={s.href}
href={s.href}
aria-current={active ? 'page' : undefined}
className={[
'group flex flex-1 flex-row items-center gap-2 px-4 py-3 transition-colors md:flex-none md:flex-col md:gap-1 md:px-0 md:py-4',
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-lamp',
active ? 'bg-deck text-lamp' : 'text-dim hover:bg-riser hover:text-chalk',
].join(' ')}
>
<span className="font-signage text-lg font-semibold leading-none">{s.code}</span>
<span className="font-data text-[9px] uppercase tracking-[0.14em] md:[writing-mode:vertical-rl]">
{s.label}
</span>
</Link>
)
})}
</nav>
)
}
+54
View File
@@ -0,0 +1,54 @@
'use client'
import { useEffect, useState } from 'react'
import { cluster, nodes } from '@/lib/clusterMock'
import { SlotMeter } from './SlotMeter'
/** Fake liveness so the layout can be judged in motion. Replaced by SSE in Phase 2. */
function useDrift() {
const [age, setAge] = useState<number>(cluster.snapshotAge)
const [slots, setSlots] = useState(3)
useEffect(() => {
const tick = setInterval(() => setAge((a) => (a > 6 ? 0.4 : +(a + 0.9).toFixed(1))), 900)
const churn = setInterval(() => setSlots(() => 1 + Math.floor(Math.random() * 5)), 3400)
return () => {
clearInterval(tick)
clearInterval(churn)
}
}, [])
return { age, slots }
}
export function Ribbon() {
const { age, slots } = useDrift()
return (
<div className="flex flex-wrap items-center gap-x-6 gap-y-2 border-b border-wire bg-void px-4 py-2.5 font-data text-[11px]">
<span className="flex items-center gap-2 text-chalk">
<span className="h-1.5 w-1.5 rounded-full bg-flux" />
{cluster.distro}
</span>
<span className="text-dim">
k8s <span className="text-chalk">{cluster.kubernetes}</span>
</span>
<span className="text-dim">
nodes <span className="text-chalk">{nodes.length}</span>
</span>
<span className="text-dim">
snapshot <span className="text-chalk">{age.toFixed(1)}s</span>
</span>
<span className="ml-auto flex items-center gap-3">
<span className="uppercase tracking-[0.16em] text-dim">seq</span>
<SlotMeter used={slots} />
<span className="tabular-nums text-chalk">{slots}/8</span>
</span>
<span className="border border-lamp/40 px-1.5 py-0.5 uppercase tracking-[0.16em] text-lamp">
placeholder data
</span>
</div>
)
}
+44
View File
@@ -0,0 +1,44 @@
'use client'
import { SEQUENCE_SLOTS, PUBLIC_SLOT_CAP } from '@/lib/clusterMock'
type Props = {
used: number
size?: 'sm' | 'lg'
showCap?: boolean
}
/**
* The signature element. Eight discrete cells, one per vLLM sequence slot.
* Cells past PUBLIC_SLOT_CAP are operator headroom and read as reserved.
*/
export function SlotMeter({ used, size = 'sm', showCap = false }: Props) {
const cell = size === 'lg' ? 'h-6 w-3' : 'h-3 w-[7px]'
return (
<div className="flex items-center gap-2">
<div className="flex gap-[3px]" role="img" aria-label={`${used} of ${SEQUENCE_SLOTS} sequence slots in use`}>
{Array.from({ length: SEQUENCE_SLOTS }, (_, i) => {
const reserved = i >= PUBLIC_SLOT_CAP
const active = i < used
return (
<span
key={i}
className={[
cell,
'rounded-[1px] transition-colors duration-500',
active ? 'bg-lamp' : reserved ? 'bg-wire' : 'bg-wire-lit/40',
reserved && !active ? 'opacity-50' : '',
].join(' ')}
/>
)
})}
</div>
{showCap && (
<span className="font-data text-[10px] uppercase tracking-widest text-dim">
{used}/{PUBLIC_SLOT_CAP} public · {SEQUENCE_SLOTS} total
</span>
)}
</div>
)
}