Files
portfolio/src/components/Widget.tsx
lerko96 088a06a51c feat: terminal-noir redesign — widget system + design token overhaul
Replace cyan-green modern theme with terminal-noir aesthetic aligned to
style-guide.md. Hard edges, monospace-first, linear transitions, no gradients.

Introduce Widget component as the single repeatable section primitive:
title bar with horizontal rule, optional badge/meta — all pages and
sections now use this pattern (Glance-inspired data-driven layout).

Design system changes (globals.css):
- Palette: #0a0a0a bg, #111111 surface, #00cc44 status green, #cc2200 alert red
- Drop Montserrat; Source Code Pro primary, system sans for prose only
- Transitions: linear 120ms; no eased animations, no border-radius

Component changes:
- Nav: flat, border-bottom only, lowercase links
- Hero: 56px square photo, status dot, @ email glyph
- ProjectCard: flat bordered card, 2-col grid, no gradient tile
- Skills: key-value rows with dot-separated values
- Footer: minimal text links

Pages: all sections wrapped in Widget; homelab uses gap-px grid for
at-a-glance, services, and ADRs sections. Archive uses flat list layout.

Data: remove gradient field from Project type; add optional year field
2026-04-12 19:23:50 -04:00

40 lines
1.0 KiB
TypeScript

type WidgetProps = {
title: string;
badge?: string | number;
meta?: string;
as?: "section" | "div" | "article";
className?: string;
children: React.ReactNode;
};
export default function Widget({
title,
badge,
meta,
as: Tag = "section",
className,
children,
}: WidgetProps) {
return (
<Tag className={`mb-12 ${className ?? ""}`}>
<div className="flex items-center gap-3 mb-6">
<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-1 h-px bg-[var(--color-border)]" aria-hidden="true" />
{badge !== undefined && (
<span className="font-mono text-xs text-[var(--color-text-dim)] whitespace-nowrap">
{badge}
</span>
)}
</div>
{children}
</Tag>
);
}