import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils"; /** * Site-wide typography scale optimized for Persian (RTL) readability. * Use via `typography({ variant })`, `type.*` shorthand, or ``. */ export const typographyVariants = cva("tracking-normal", { variants: { variant: { /** Large marketing hero titles */ display: "text-3xl font-semibold leading-relaxed text-balance sm:text-4xl lg:text-5xl", /** Main page titles */ h1: "text-3xl font-bold leading-snug text-balance md:text-4xl lg:text-5xl", /** Major section headings */ h2: "text-2xl font-semibold leading-snug text-balance md:text-3xl lg:text-4xl", /** Subsection / feature block headings */ h3: "text-lg font-semibold leading-snug md:text-xl", /** Compact block headings, mini sections */ h4: "text-base font-semibold leading-snug md:text-lg", /** Prominent intro paragraphs */ "body-lg": "text-lg leading-relaxed md:text-xl", /** Standard paragraphs */ body: "text-base leading-relaxed", /** Secondary / denser copy */ "body-sm": "text-sm leading-relaxed", /** Metadata, timestamps, footnotes */ caption: "text-xs leading-normal text-muted-foreground", /** Section eyebrow / badge labels */ eyebrow: "text-sm font-medium leading-normal text-muted-foreground", /** Form labels, settings labels */ label: "text-sm font-medium leading-none", /** Header / menu items (desktop) */ nav: "text-sm font-medium", /** Mobile navigation items */ "nav-mobile": "text-base font-medium", /** Titles inside cards and panels */ "card-title": "text-base font-semibold leading-snug", /** Supporting copy inside cards */ "card-desc": "text-sm leading-relaxed text-muted-foreground", /** Chat message bubbles */ chat: "text-sm leading-relaxed", /** Log panels, JSON, technical output */ code: "font-mono text-xs leading-relaxed", /** Large stat numbers */ stat: "text-4xl font-bold leading-none text-primary md:text-5xl", /** Inline nav / footer links */ link: "text-sm text-muted-foreground", /** Section intro paragraphs (muted) */ "section-intro": "text-lg leading-relaxed text-muted-foreground", /** Pull quotes / emphasis blocks */ emphasis: "text-base font-medium leading-relaxed text-foreground", /** Accordion / list item titles */ "list-title": "text-base font-medium leading-snug", /** CTA section headings (slightly larger than h2) */ "cta-title": "text-2xl font-semibold leading-snug text-balance md:text-3xl lg:text-4xl", /** Decorative error page numbers */ "display-mono": "text-[5rem] font-black leading-none sm:text-[6rem] md:text-[8rem]", }, }, defaultVariants: { variant: "body", }, }); export type TypographyVariant = NonNullable< VariantProps["variant"] >; /** Shorthand class strings for inline use: `className={type.h2}` */ export const type: Record = { display: "text-3xl font-semibold leading-relaxed tracking-normal text-balance sm:text-4xl lg:text-5xl", h1: "text-3xl font-bold leading-snug tracking-normal text-balance md:text-4xl lg:text-5xl", h2: "text-2xl font-semibold leading-snug tracking-normal text-balance md:text-3xl lg:text-4xl", h3: "text-lg font-semibold leading-snug tracking-normal md:text-xl", h4: "text-base font-semibold leading-snug tracking-normal md:text-lg", "body-lg": "text-lg leading-relaxed tracking-normal md:text-xl", body: "text-base leading-relaxed tracking-normal", "body-sm": "text-sm leading-relaxed tracking-normal", caption: "text-xs leading-normal tracking-normal text-muted-foreground", eyebrow: "text-sm font-medium leading-normal tracking-normal text-muted-foreground", label: "text-sm font-medium leading-none tracking-normal", nav: "text-sm font-medium tracking-normal", "nav-mobile": "text-base font-medium tracking-normal", "card-title": "text-base font-semibold leading-snug tracking-normal", "card-desc": "text-sm leading-relaxed tracking-normal text-muted-foreground", chat: "text-sm leading-relaxed tracking-normal", code: "font-mono text-xs leading-relaxed tracking-normal", stat: "text-4xl font-bold leading-none tracking-normal text-primary md:text-5xl", link: "text-sm tracking-normal text-muted-foreground", "section-intro": "text-lg leading-relaxed tracking-normal text-muted-foreground", emphasis: "text-base font-medium leading-relaxed tracking-normal text-foreground", "list-title": "text-base font-medium leading-snug tracking-normal", "cta-title": "text-2xl font-semibold leading-snug tracking-normal text-balance md:text-3xl lg:text-4xl", "display-mono": "text-[5rem] font-black leading-none tracking-tighter sm:text-[6rem] md:text-[8rem]", }; /** Text-related spacing tied to typography hierarchy */ export const typeSpacing = { /** Eyebrow → heading */ eyebrowToHeading: "mt-2", /** Heading → supporting paragraph */ headingToBody: "mt-3", /** Section title block */ sectionStack: "space-y-4", /** Page hero block */ heroStack: "space-y-6", /** Card title → description */ cardStack: "gap-1.5", /** Stacked paragraphs */ paragraphStack: "space-y-4", /** Label → input */ labelToControl: "gap-1.5", /** Message → timestamp in chat */ chatMeta: "space-y-1", } as const; export function typography( variant: TypographyVariant, className?: string ): string { return cn(typographyVariants({ variant }), className); }