import { cn } from "@/lib/utils"; import { TransitionLink } from "@/components/motion/TransitionLink"; import { RevealGroup, RevealItem } from "@/components/motion/Reveal"; import { termine as termineDe } from "@/content/home"; import type { GoalRow, SituationRow, TermineRow, TocRow, WerdegangRow } from "@/content/home"; import { TEXT_LINK } from "./TextLink"; export type { GoalRow, SituationRow, TermineRow, TocRow, WerdegangRow }; export type LedgerRow = TocRow | WerdegangRow | TermineRow | SituationRow | GoalRow; interface LedgerBase { className?: string; /** Stagger between rows (default 0.1 s). */ stagger?: number; } export type LedgerProps = | (LedgerBase & { variant: "toc"; rows: readonly TocRow[] }) | (LedgerBase & { variant: "werdegang"; rows: readonly WerdegangRow[] }) | (LedgerBase & { variant: "termine"; rows: readonly TermineRow[]; heading?: string }) | (LedgerBase & { variant: "situations"; rows: readonly SituationRow[] }) | (LedgerBase & { variant: "goals"; rows: readonly GoalRow[] }); const MONO = "font-mono text-xs tracking-[0.06em] tabular-nums"; /* ---------------- toc ---------------- */ /** * Table-of-contents row = ONE (keyboard: one tab stop). * Hover: ground `--surface`, lower hairline turns gold (scaleX from the left, * 0.6 s), arrow +8 px. No italic flip, nothing reflows – everything is * always visible. */ function TocRowView({ row }: { row: TocRow }) { return ( {row.numeral} {row.title} {row.oneLiner} {row.keywords.join(" · ")} {row.link.label} {/* Lower hairline: recolours to gold from the left on hover. */} ); } /* ---------------- termine ---------------- */ function TermineRowView({ row }: { row: TermineRow }) { const inner = ( <> {row.date} {row.format} {row.title} {row.venue} {row.href && ( <> {" "} )} ); const cls = "grid grid-cols-1 gap-y-1 py-5 lg:grid-cols-[1fr_1fr_2fr_1fr] lg:items-baseline lg:gap-x-8"; if (row.href) { return ( {inner} ); } return
{inner}
; } /* ---------------- Ledger ---------------- */ /** * Typographic ledgers instead of cards. Rows are hairline-separated and * stagger in via ; the toc variant's rows are links. */ export function Ledger(props: LedgerProps) { const { className, stagger = 0.1 } = props; if (props.variant === "toc") { return ( {props.rows.map((row) => ( ))} ); } if (props.variant === "werdegang") { return ( {props.rows.map((row) => (
{row.keyword}
{row.text}
))}
); } if (props.variant === "termine") { const heading = props.heading ?? termineDe.heading; return (

{props.rows.map((row) => ( ))}
); } if (props.variant === "situations") { return ( {props.rows.map((row) => ( {row.numeral} {row.text} ))} ); } return ( {props.rows.map((row) => ( {row.text} ))} ); } export default Ledger;