/** * Loading skeletons for route-level loading.tsx files. Neutral blocks only (no fake numbers, no * placeholder text that could be mistaken for data — CLAUDE.md §281). `aria-busy` + a visually * hidden status line announce the loading state to assistive technology. */ export function Skeleton({ className = '', w, h = 14 }: { className?: string; w?: string | number; h?: number }) { return ; } export function SkeletonText({ lines = 3, className = '' }: { lines?: number; className?: string }) { return (
{Array.from({ length: lines }, (_, i) => ( ))}
); } export function SkeletonTable({ rows = 8, cols = 6, className = '' }: { rows?: number; cols?: number; className?: string }) { return (
{Array.from({ length: cols }, (_, i) => ( ))} {Array.from({ length: rows * cols }, (_, i) => ( ))}
); } export function PageSkeleton({ title = 'Loading', tabs = 0, table = true }: { title?: string; tabs?: number; table?: boolean }) { return (

{title}…

{tabs > 0 ? (
{Array.from({ length: tabs }, (_, i) => ( ))}
) : null} {table ? : null}
); }