Files
Anelia-Wolf/src/components/ui/Marginalia.tsx
T
2026-09-06 17:21:52 +02:00

67 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { cn } from "@/lib/utils";
export interface MarginaliaItem {
/** Optional mono label, e.g. „Praxis“ → „Praxis: B2B-Außendienst“. */
label?: string;
value: string;
href?: string;
/** `target="_blank"` + ↗ */
external?: boolean;
}
export interface MarginaliaProps {
items: readonly MarginaliaItem[];
/** Optional caps heading above the list, e.g. „Was du bekommst“. */
title?: string;
/** `lg:sticky lg:top-[30vh]` */
sticky?: boolean;
className?: string;
}
/** Shared mono meta style (DM Mono 12 px, ls .06em, tabular). */
export const MONO = "font-mono text-xs tracking-[0.06em] tabular-nums";
/**
* Verifiable facts in the outer column: DM Mono 12 px, muted, one gold tick
* per line. Links get the growing accent underline; external ones ↗.
*/
export function Marginalia({ items, title, sticky = false, className }: MarginaliaProps) {
return (
<aside className={cn(MONO, "text-fg-muted", sticky && "lg:sticky lg:top-[30vh]", className)}>
{title && <p className="mb-4 uppercase tracking-[0.12em] text-accent">{title}</p>}
<ul className="flex flex-col gap-3">
{items.map((item, i) => {
const text = item.label ? `${item.label}: ${item.value}` : item.value;
return (
<li key={`${item.value}-${i}`} className="flex items-start gap-3">
<span aria-hidden="true" className="mt-[0.55em] h-px w-6 shrink-0 bg-accent" />
{item.href ? (
<a
href={item.href}
target={item.external ? "_blank" : undefined}
rel={item.external ? "noopener noreferrer" : undefined}
/* Tap target via ::before – padding + negative margin on the flex child
collapsed the <li> box and broke the 12 px tick rhythm of the list. */
className="relative inline-block text-fg before:absolute before:inset-x-0 before:-inset-y-3 before:content-[''] bg-[linear-gradient(currentColor,currentColor)] bg-[length:0%_1px] bg-left-bottom bg-no-repeat pb-px transition-[background-size] duration-[400ms] ease-[var(--ease-out-quart)] hover:bg-[length:100%_1px] focus-visible:bg-[length:100%_1px]"
>
{text}
{item.external && (
<>
{" "}
<span aria-hidden="true">↗</span>
</>
)}
</a>
) : (
<span>{text}</span>
)}
</li>
);
})}
</ul>
</aside>
);
}
export default Marginalia;