src/components/heading.tsximport React from 'react'import { clsx } from 'clsx'import type { HTMLAttributes } from 'react'import { generateIdFromChildren } from '@/tools/generate-id-from-children'type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {children?: React.ReactNodeclassName?: string/** Custom ID for the heading. If not provided, will be auto-generated from children content */id?: string/** The HTML heading tag to render (h1, h2, h3, h4, h5, h6) */as?: HeadingLevel/** The heading level to use for styling (independent of the HTML tag) */styleAs?: HeadingLevel/** Font size override */fontSize?: string/** Font weight override */fontWeight?: string/** Letter spacing override */letterSpacing?: string/** Line height override */lineHeight?: string/** Text wrap behavior */textWrap?: string/** Font family override */fontFamily?: string/** Text color override */color?: string | undefined/** Margin override */margin?: string/** Text alignment override */textAlign?: string/** Disable automatic ID generation */disableId?: boolean}export function Heading({children = '',className,id,as: Element = 'h1',styleAs,fontSize = '',fontWeight = '',letterSpacing = '',lineHeight = '',textWrap = '',fontFamily = '',color = '',margin = '',textAlign = '',disableId = false,...props}: HeadingProps) {// Define base styles for different heading levelsconst getHeadingDefaults = (level: HeadingLevel) => {switch (level) {// h1 is title case and Forge Navy: uppercase is reserved for eyebrows,// categories, and spec labels, and orange stays a restrained accent// rather than carrying page headlines.case 'h1':return {fontSize: 'text-4xl sm:text-6xl md:text-7xl',fontWeight: 'font-bold',letterSpacing: 'tracking-tight',lineHeight: 'leading-tight',textWrap: 'text-balance',textTransform: 'uppercase',fontFamily: 'font-heading',color: 'text-contrast',margin: 'mb-8',}case 'h2':return {fontSize: 'text-base',fontWeight: 'font-bold',letterSpacing: 'tracking-wide',lineHeight: 'leading-normal',textWrap: '',textTransform: 'uppercase',fontFamily: 'font-heading',color: 'text-accent',margin: 'mb-4',}case 'h3':return {fontSize: 'text-4xl sm:text-5xl',fontWeight: 'font-bold',letterSpacing: 'tracking-tight',lineHeight: 'leading-normal',textWrap: '',textTransform: 'uppercase',fontFamily: 'font-heading',color: 'text-contrast',margin: 'mb-6',}case 'h4':return {fontSize: 'text-xl md:text-xl',fontWeight: 'font-semibold',letterSpacing: 'tracking-normal',lineHeight: 'leading-tight',textWrap: '',textTransform: '',fontFamily: 'font-heading',color: 'text-contrast-dark',margin: 'mb-8',}case 'h5':return {fontSize: 'text-xl sm:text-2xl',fontWeight: 'font-semibold',letterSpacing: 'tracking-tight',lineHeight: 'leading-tight',textWrap: '',textTransform: '',fontFamily: 'font-heading',color: 'text-contrast',margin: 'mb-8',}case 'h6':return {fontSize: 'text-lg sm:text-xl',fontWeight: 'font-semibold',letterSpacing: 'tracking-tight',lineHeight: 'leading-tight',textWrap: '',textTransform: '',fontFamily: 'font-heading',color: 'text-contrast',margin: 'mb-8',}default:return {fontSize: 'text-4xl sm:text-5xl md:text-6xl',fontWeight: 'font-bold',letterSpacing: 'tracking-tight',lineHeight: 'leading-tight sm:leading-tight md:leading-tight',textWrap: '',textTransform: '',fontFamily: 'font-heading',color: 'text-contrast',margin: 'mb-8',}}}// Use styleAs for visual styling, fallback to Element (as prop) if styleAs not providedconst styleLevel = styleAs || Elementconst defaults = getHeadingDefaults(styleLevel)// Use user-defined values if provided, otherwise use defaultsconst finalFontSize = fontSize || defaults.fontSizeconst finalFontWeight = fontWeight || defaults.fontWeightconst finalLetterSpacing = letterSpacing || defaults.letterSpacingconst finalLineHeight = lineHeight || defaults.lineHeightconst finalTextWrap = textWrap || defaults.textWrapconst finalTextTransform = defaults.textTransformconst finalFontFamily = fontFamily || defaults.fontFamilyconst finalColor = color || defaults.colorconst finalMargin = margin || defaults.marginconst finalTextAlign = textAlign// Generate ID from children if not provided (unless disabled)const headingId = disableId? undefined: id || generateIdFromChildren(children)return (<Elementid={headingId}className={clsx('content-wrapper',// Apply final styles (user-defined or defaults)finalFontSize,finalFontWeight,finalLetterSpacing,finalLineHeight,finalTextWrap,finalTextTransform,finalFontFamily,finalColor,finalMargin,finalTextAlign,// Custom className can override or extend default stylesclassName)}{...props}>{children}</Element>)}