<script module lang="ts">
	import { tv, type VariantProps } from "tailwind-variants";
	import type { SvelteHTMLElements } from "svelte/elements";

	// Scale sourced from Figma "Font Styles" (node 1:134): Heading 1-4 map to
	// h1-h4, the "Paragraph Regular" size maps to body/body-strong (weight
	// axis only), "Paragraph Small"/"Paragraph Mini" map to small/caption, and
	// the monospace specimen maps to mono.
	export const typography = tv({
		base: "font-sans text-foreground-default",
		variants: {
			variant: {
				h1: "text-2xl font-bold leading-tight",
				h2: "text-xl font-bold leading-tight",
				h3: "text-lg font-semibold leading-snug",
				h4: "text-base font-semibold leading-snug",
				body: "text-base font-normal leading-normal",
				"body-strong": "text-base font-semibold leading-normal",
				small: "text-sm font-normal leading-normal text-foreground-muted",
				caption: "text-xs font-normal leading-normal text-foreground-subtle",
				mono: "font-mono text-sm font-normal leading-normal"
			}
		},
		defaultVariants: {
			variant: "body"
		}
	});

	export type TypographyVariants = VariantProps<typeof typography>;

	const defaultTag = {
		h1: "h1",
		h2: "h2",
		h3: "h3",
		h4: "h4",
		body: "p",
		"body-strong": "p",
		small: "span",
		caption: "span",
		mono: "code"
	} as const satisfies Record<NonNullable<TypographyVariants["variant"]>, keyof SvelteHTMLElements>;
</script>

<script lang="ts">
	import type { Snippet } from "svelte";

	interface Props {
		variant?: TypographyVariants["variant"];
		as?: keyof SvelteHTMLElements;
		class?: string;
		children: Snippet;
	}

	let { variant = "body", as, class: className, children }: Props = $props();

	const tag = $derived(as ?? defaultTag[variant ?? "body"]);
	const classes = $derived(typography({ variant, class: className }));
</script>

<svelte:element this={tag} class={classes}>
	{@render children()}
</svelte:element>
