import * as React from "react"; import { cn } from "@/lib/utils"; export type TypographyVariant = | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption"; const sizeClasses: Record = { h1: "text-5xl md:text-6xl lg:text-7xl font-semibold tracking-tight leading-[1.05]", h2: "text-4xl md:text-5xl font-semibold tracking-tight leading-[1.1]", h3: "text-3xl md:text-4xl font-semibold tracking-tight leading-tight", h4: "text-2xl md:text-3xl font-semibold tracking-tight leading-snug", h5: "text-xl md:text-2xl font-semibold leading-snug", h6: "text-lg md:text-xl font-semibold leading-snug", subtitle1: "text-lg md:text-xl leading-relaxed text-muted-foreground", subtitle2: "text-base md:text-lg leading-relaxed text-muted-foreground", body1: "text-lg leading-relaxed", body2: "text-base leading-relaxed", caption: "text-sm leading-relaxed text-muted-foreground", }; // Inline-style fallbacks so headings size correctly even when Tailwind // preflight resets

..

to font-size: inherit and the iframe CDN // hasn't compiled utility classes yet. The Tailwind classes above still // apply on top once available (responsive breakpoints, leading, etc.). const sizeStyles: Record = { h1: { fontSize: "clamp(2.5rem, 6vw, 4.5rem)", lineHeight: 1.05, fontWeight: 600, letterSpacing: "-0.02em" }, h2: { fontSize: "clamp(2rem, 4vw, 3rem)", lineHeight: 1.1, fontWeight: 600, letterSpacing: "-0.02em" }, h3: { fontSize: "clamp(1.75rem, 3.5vw, 2.25rem)", lineHeight: 1.15, fontWeight: 600, letterSpacing: "-0.015em" }, h4: { fontSize: "clamp(1.5rem, 3vw, 1.875rem)", lineHeight: 1.2, fontWeight: 600, letterSpacing: "-0.01em" }, h5: { fontSize: "1.5rem", lineHeight: 1.25, fontWeight: 600 }, h6: { fontSize: "1.25rem", lineHeight: 1.3, fontWeight: 600 }, subtitle1: { fontSize: "1.125rem", lineHeight: 1.6 }, subtitle2: { fontSize: "1rem", lineHeight: 1.6 }, body1: { fontSize: "1.125rem", lineHeight: 1.6 }, body2: { fontSize: "1rem", lineHeight: 1.6 }, caption: { fontSize: "0.875rem", lineHeight: 1.5 }, }; const defaultTag: Record = { h1: "h1", h2: "h2", h3: "h3", h4: "h4", h5: "h5", h6: "h6", subtitle1: "p", subtitle2: "p", body1: "p", body2: "p", caption: "p", }; type Props = { variant: TypographyVariant; as?: C; className?: string; style?: React.CSSProperties; children?: React.ReactNode; } & Omit, "className" | "children" | "style">; export function Typography({ variant, as, className, style, children, ...rest }: Props) { const Tag = (as ?? defaultTag[variant]) as keyof JSX.IntrinsicElements; const isHeading = variant.startsWith("h"); const fontClass = isHeading ? "font-heading" : "font-body"; return React.createElement( Tag, { className: cn(fontClass, sizeClasses[variant], className), style: { ...sizeStyles[variant], ...style }, ...rest, }, children, ); } export default Typography;