import { cn } from "@/lib/utils";
/**
* Building blocks for the detail / settings rhythm system. All spacing
* resolves to CSS tokens declared in `app/globals.css` under @theme:
* --spacing-card → p-card (card interior padding)
* --spacing-card-gap → gap-card-gap (gap between sibling cards)
* --spacing-section → gap-section / pt-section (intra-card section gap)
* --spacing-chip → gap-chip (chip clusters, pill grids, button bars)
* --spacing-label → mb-label (label header → content)
* --spacing-stat → mb-stat (hero-stat label → big number)
* --spacing-stat-gap → gap-stat-gap (horizontal between hero-stat cols)
*
* Use these instead of raw `p-[15px]` / `gap-[9px]` so a single token
* change ripples across every page.
*/
/** Outer card frame. Glass surface, rounded corners, uniform padding. */
export function Panel({
children,
className,
as: Tag = "div",
}: {
children: React.ReactNode;
className?: string;
/** Render as a different tag if needed (e.g. "section", "aside"). */
as?: keyof React.JSX.IntrinsicElements;
}) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const T = Tag as any;
return (
{children}
);
}
/**
* Vertical container for sibling Panels. Replaces ad-hoc `space-y-N` on
* an aside or column wrapper — picks up the panel-to-panel rhythm.
*/
export function PanelStack({
children,
className,
as: Tag = "div",
}: {
children: React.ReactNode;
className?: string;
as?: keyof React.JSX.IntrinsicElements;
}) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const T = Tag as any;
return (
{children}
);
}
/**
* Vertical flow inside a Panel — pulls children apart by the
* intra-card section gap. Use for stacked blocks (header → flag pills
* → meta strip → hero stats), NOT for label→content (use PanelHeader for that).
*/
export function PanelSection({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
{children}
);
}
/**
* Mono caps label, e.g. "ACTRESSES" / "TAGS". Renders the label and
* applies the standard label→content margin to whatever sits beneath.
* Pair with the chip cluster or any other content block.
*/
export function PanelHeader({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
{children}
);
}
/**
* Horizontal flex-wrap chip strip used for actresses / genres / tags /
* collections / flag pill rows. Spacing is the unified `gap-chip` token.
*/
export function ChipCluster({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) {
return (
{children}
);
}
/**
* Equal-column button row that sits OUTSIDE any Panel (Edit Metadata /
* Import / Delete pattern). Lives in the same vertical rhythm as
* Panels via PanelStack's gap-card-gap.
*/
export function ActionBar({
children,
cols = 3,
className,
}: {
children: React.ReactNode;
cols?: 2 | 3 | 4;
className?: string;
}) {
const colClass =
cols === 2 ? "grid-cols-2" : cols === 4 ? "grid-cols-4" : "grid-cols-3";
return (
{children}
);
}