59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
import * as React from "react"
|
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
|
|
import { cn } from "@/lib/utils"
|
|
|
|
// 랜딩 텍스트 스케일 단일 소스. 페이지마다 text-[44px]/font-black/…을 직접 박지 말고
|
|
// variant 로 통일한다. 색·크기 미세조정은 className 으로 합성.
|
|
const typographyVariants = cva("", {
|
|
variants: {
|
|
variant: {
|
|
// 히어로 h1
|
|
display: "text-3xl sm:text-4xl md:text-[50px] font-black tracking-tight leading-[1.2] text-ink break-keep",
|
|
// 섹션 제목 h2
|
|
title: "text-3xl md:text-[44px] font-black tracking-tight leading-tight text-ink break-keep",
|
|
// 섹션 내 서브 제목 (데모 패널 등)
|
|
heading: "text-2xl md:text-3xl font-bold tracking-tight text-ink break-keep",
|
|
// 카드 제목
|
|
cardTitle: "text-lg font-bold text-ink break-keep",
|
|
// 섹션 상단 오버라인 라벨
|
|
eyebrow: "text-sm font-semibold text-primary tracking-wider uppercase",
|
|
// 섹션 리드 문단
|
|
lead: "text-base sm:text-lg text-ink-soft font-medium leading-relaxed break-keep",
|
|
body: "text-[15px] text-ink-soft font-medium leading-relaxed break-keep",
|
|
small: "text-sm text-ink-soft font-medium leading-relaxed break-keep",
|
|
caption: "text-xs text-ink-muted font-semibold leading-relaxed break-keep",
|
|
// 11px 트래킹 대문자 메타 라벨 (단가 패널·푸터 컬럼 제목 등)
|
|
micro: "text-[11px] font-bold text-ink-muted uppercase tracking-wider",
|
|
},
|
|
},
|
|
defaultVariants: { variant: "body" },
|
|
})
|
|
|
|
const defaultTag: Record<NonNullable<VariantProps<typeof typographyVariants>["variant"]>, React.ElementType> = {
|
|
display: "h1",
|
|
title: "h2",
|
|
heading: "h3",
|
|
cardTitle: "h3",
|
|
eyebrow: "span",
|
|
lead: "p",
|
|
body: "p",
|
|
small: "p",
|
|
caption: "p",
|
|
micro: "span",
|
|
}
|
|
|
|
type TypographyProps = React.HTMLAttributes<HTMLElement> &
|
|
VariantProps<typeof typographyVariants> & {
|
|
/** 의미상 태그를 강제로 바꾸고 싶을 때 (예: cardTitle 을 h4 로) */
|
|
as?: React.ElementType
|
|
htmlFor?: string
|
|
}
|
|
|
|
function Typography({ className, variant, as, ...props }: TypographyProps) {
|
|
const Comp = as ?? defaultTag[variant ?? "body"]
|
|
return <Comp className={cn(typographyVariants({ variant }), className)} {...props} />
|
|
}
|
|
|
|
export { Typography, typographyVariants }
|