feat(ui): add timeline component; complete terminal-noir design system

- introduce Timeline component with scroll-in animation and type-colored
  spine dots (career/edu/cert/project/homelab)
- swap terminal-noir palette for macOS Classic dark/light with matching
  timeline color tokens in globals.css
- add light mode overrides, cursor blink keyframe, font-size 14px base
- update Widget header: prefix/name split, bracket badge, no divider rule
- align archive and homelab page headers to ❯ prompt style
- convert all font-sans prose in homelab/archive to font-mono
- rename widget titles to namespaced paths (homelab/network, etc.)
- skills label: uppercase tracking → plain text-sm; remove row borders
This commit is contained in:
lerko96
2026-04-16 18:03:33 -04:00
parent 6d0b4e29d8
commit c36cc94437
6 changed files with 158 additions and 64 deletions

View File

@@ -27,16 +27,14 @@ const totalCount = skillGroups.reduce((n, g) => n + g.skills.length, 0);
export default function Skills() {
return (
<Widget title="skills" badge={totalCount} as="section">
<Widget title="tyler/skills" badge={totalCount} as="section">
<div className="flex flex-col">
{skillGroups.map(({ label, skills }, i) => (
{skillGroups.map(({ label, skills }) => (
<div
key={label}
className={`flex flex-col xs:flex-row gap-1 xs:gap-6 py-4 ${
i < skillGroups.length - 1 ? "border-b border-[var(--color-border)]" : ""
}`}
className="flex flex-col xs:flex-row gap-1 xs:gap-6 py-3"
>
<span className="font-mono text-xs text-[var(--color-text-dim)] w-28 shrink-0 uppercase tracking-wider">
<span className="font-mono text-sm text-[var(--color-text-dim)] w-28 shrink-0">
{label}
</span>
<span className="font-mono text-sm text-[var(--color-text)]">

View File

@@ -15,22 +15,22 @@ export default function Widget({
className,
children,
}: WidgetProps) {
const slashIdx = title.lastIndexOf("/");
const prefix = slashIdx >= 0 ? title.slice(0, slashIdx + 1) : null;
const name = slashIdx >= 0 ? title.slice(slashIdx + 1) : title;
return (
<Tag className={`mb-16 ${className ?? ""}`}>
<div className="flex items-center gap-3 mb-8">
<span className="font-mono text-xs text-[var(--color-text-label)] tracking-widest uppercase whitespace-nowrap">
{title}
</span>
{meta && (
<span className="font-mono text-xs text-[var(--color-text-dim)] whitespace-nowrap">
{meta}
</span>
<div className="flex items-center gap-2 mb-8">
{prefix && (
<span className="font-mono text-sm text-[var(--color-text-dim)] select-none">{prefix}</span>
)}
<div className="flex-1 h-px bg-[var(--color-border)]" aria-hidden="true" />
<span className="font-mono text-sm font-semibold text-[var(--color-text)]">{name}</span>
{badge !== undefined && (
<span className="font-mono text-xs text-[var(--color-text-dim)] whitespace-nowrap">
{badge}
</span>
<span className="font-mono text-xs text-[var(--color-text-dim)]">[{badge}]</span>
)}
{meta && (
<span className="font-mono text-xs text-[var(--color-text-dim)] ml-1"> {meta}</span>
)}
</div>
{children}