mirror of
https://github.com/phranck/TUIkit.git
synced 2026-06-20 09:54:37 +00:00
Performance & memory: - HeroTerminal: fix setInterval one-time random (now recursive setTimeout), reuse single Howl for seeks, track all timers via pendingTimersRef - RainOverlay: cap at 30fps, skip on prefers-reduced-motion - SpinnerLights: pre-compute boxShadow at spawn, nextId in useRef - Remove eager audio preloads from <head> (Howler loads lazily) - CloudBackground: remove unnecessary 'use client' (now Server Component) Type safety & correctness: - Import BootStep/SchoolStep/JoshuaStep/TerminalEntry from terminal-parser instead of duplicating interfaces; typed terminal-data.ts export - ThemeProvider: isTheme() type guard replaces unsafe 'as Theme' casts, instanceof guard for event.target, try/catch on localStorage.setItem - useCopyToClipboard: cancel previous timer on rapid clicks, try/catch around clipboard API, cleanup on unmount - TerminalScreen: use config.initialCursorDelay instead of magic 18000, type predicate for filter(), track glitch reset timer for cleanup Accessibility (WCAG): - prefers-reduced-motion: global CSS rule + JS skip in Rain/Spinner/Glitch - aria-hidden on decorative elements (Rain, Spinner, Clouds) - focus-visible ring on ThemeSwitcher, CodePreview, PackageBadge buttons - aria-pressed on active theme button, nav aria-label, main tabIndex Code quality: - Extract useCopyToClipboard hook (CodePreview + PackageBadge) - bg-frosted-glass CSS utility replaces 3x inline color-mix - hover:bg-white/* → hover:bg-foreground/* for theme consistency - Remove dead zoomed prop, stale eslint-disable, move lineRefsRef up - import type for ReactNode in FeatureCard
29 lines
886 B
TypeScript
29 lines
886 B
TypeScript
import type { ReactNode } from "react";
|
|
|
|
interface FeatureCardProps {
|
|
icon: ReactNode;
|
|
title: string;
|
|
description: string;
|
|
}
|
|
|
|
/** A feature highlight card with icon, title, and description. */
|
|
export default function FeatureCard({
|
|
icon,
|
|
title,
|
|
description,
|
|
}: FeatureCardProps) {
|
|
return (
|
|
<div
|
|
className="group rounded-xl border border-border bg-frosted-glass p-6 backdrop-blur-xl transition-all duration-300 hover:border-accent/30"
|
|
>
|
|
<div className="mb-3 flex items-center gap-3">
|
|
<div className="flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-accent/10 text-accent transition-colors group-hover:bg-accent/15">
|
|
{icon}
|
|
</div>
|
|
<h3 className="text-2xl font-semibold text-foreground">{title}</h3>
|
|
</div>
|
|
<p className="text-xl leading-relaxed text-muted">{description}</p>
|
|
</div>
|
|
);
|
|
}
|