Files
anthonyrawlins 7774d7ec98 feat(brand-system): Implement comprehensive CHORUS brand system with typography and design tokens
This commit implements a complete brand system overhaul including:

TYPOGRAPHY SYSTEM:
- Add Exo font family (Thin, Light, Regular, ExtraLight) as primary brand font
- Implement SF Pro Display/Text hierarchy for UI components
- Create comprehensive Typography component with all brand variants
- Update all components to use new typography tokens

DESIGN TOKEN SYSTEM:
- Create complete design token system in theme/designTokens.ts
- Define Carbon Black (#1a1a1a), Walnut Brown (#8B4513), Brushed Aluminum (#A8A8A8) palette
- Implement CSS custom properties for consistent theming
- Update Ant Design theme integration

COMPONENT UPDATES:
- Enhance Hero section with Exo Thin typography and improved layout
- Update navigation with SF Pro font hierarchy
- Redesign Button component with new variants and accessibility
- Apply brand colors and typography across all showcase sections
- Improve Footer with consistent brand application

PERFORMANCE & ACCESSIBILITY:
- Self-host Exo fonts for optimal loading performance
- Implement proper font-display strategies
- Add comprehensive accessibility audit documentation
- Include responsive testing verification

DOCUMENTATION:
- Add brand system demo and implementation guides
- Include QA testing reports and accessibility audits
- Document design token usage and component patterns

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-02 22:12:42 +10:00

423 lines
11 KiB
TypeScript

'use client';
import React from 'react';
import { Typography as AntTypography } from 'antd';
import { designTokens } from '../../theme/designTokens';
const { Title, Paragraph, Text } = AntTypography;
// =============================================================================
// TYPOGRAPHY COMPONENT INTERFACES
// =============================================================================
interface BaseTypographyProps {
children: React.ReactNode;
className?: string;
style?: React.CSSProperties;
id?: string;
}
interface HeadingProps extends BaseTypographyProps {
level?: 1 | 2 | 3 | 4 | 5;
color?: 'primary' | 'secondary' | 'tertiary' | 'inverse';
gradient?: boolean;
}
interface BodyTextProps extends BaseTypographyProps {
size?: 'large' | 'regular' | 'small';
color?: 'primary' | 'secondary' | 'tertiary' | 'disabled' | 'inverse';
weight?: 'light' | 'regular' | 'medium' | 'semibold' | 'bold';
}
interface CodeTextProps extends BaseTypographyProps {
inline?: boolean;
language?: string;
}
interface ButtonTextProps extends BaseTypographyProps {
size?: 'small' | 'regular' | 'large';
}
// =============================================================================
// HERO DISPLAY TYPOGRAPHY
// =============================================================================
export const HeroDisplay: React.FC<HeadingProps> = ({
children,
className = '',
style = {},
color = 'primary',
gradient = false,
...props
}) => {
const colorMap = {
primary: 'var(--text-primary)',
secondary: 'var(--text-secondary)',
tertiary: 'var(--text-tertiary)',
inverse: 'var(--text-inverse)',
};
const heroStyles: React.CSSProperties = {
fontFamily: 'var(--font-display)',
fontSize: 'var(--text-hero)',
fontWeight: 100, // Exo Thin
lineHeight: 'var(--leading-tight)',
letterSpacing: 'var(--tracking-tight)',
color: gradient ? 'transparent' : colorMap[color],
background: gradient ? 'linear-gradient(135deg, var(--color-primary) 0%, var(--color-success) 100%)' : 'none',
WebkitBackgroundClip: gradient ? 'text' : 'initial',
backgroundClip: gradient ? 'text' : 'initial',
margin: 0,
...style,
};
return (
<h1
className={`text-hero ${gradient ? 'text-gradient' : ''} ${className}`}
style={heroStyles}
{...props}
>
{children}
</h1>
);
};
// =============================================================================
// DISPLAY TYPOGRAPHY HIERARCHY
// =============================================================================
export const DisplayHeading: React.FC<HeadingProps> = ({
children,
level = 1,
className = '',
style = {},
color = 'primary',
gradient = false,
...props
}) => {
const colorMap = {
primary: 'var(--text-primary)',
secondary: 'var(--text-secondary)',
tertiary: 'var(--text-tertiary)',
inverse: 'var(--text-inverse)',
};
const levelStyles = {
1: {
fontSize: 'var(--text-display-1)',
fontWeight: 200, // Exo ExtraLight
lineHeight: 'var(--leading-snug)',
},
2: {
fontSize: 'var(--text-display-2)',
fontWeight: 300, // Exo Light
lineHeight: 'var(--leading-normal)',
},
3: {
fontSize: 'clamp(20px, 3vw, 28px)',
fontWeight: 400, // Exo Regular
lineHeight: 'var(--leading-normal)',
},
4: {
fontSize: 'clamp(18px, 2.5vw, 24px)',
fontWeight: 400,
lineHeight: 'var(--leading-normal)',
},
5: {
fontSize: 'clamp(16px, 2vw, 20px)',
fontWeight: 500,
lineHeight: 'var(--leading-normal)',
},
};
const displayStyles: React.CSSProperties = {
fontFamily: 'var(--font-display)',
color: gradient ? 'transparent' : colorMap[color],
background: gradient ? 'linear-gradient(135deg, var(--color-primary) 0%, var(--color-success) 100%)' : 'none',
WebkitBackgroundClip: gradient ? 'text' : 'initial',
backgroundClip: gradient ? 'text' : 'initial',
letterSpacing: 'var(--tracking-snug)',
margin: 0,
...levelStyles[level],
...style,
};
const Tag = `h${level}` as keyof JSX.IntrinsicElements;
return (
<Tag
className={`text-display-${level} ${gradient ? 'text-gradient' : ''} ${className}`}
style={displayStyles}
{...props}
>
{children}
</Tag>
);
};
// =============================================================================
// INTERFACE TYPOGRAPHY
// =============================================================================
export const InterfaceText: React.FC<BodyTextProps> = ({
children,
size = 'regular',
className = '',
style = {},
color = 'primary',
weight = 'medium',
...props
}) => {
const colorMap = {
primary: 'var(--text-primary)',
secondary: 'var(--text-secondary)',
tertiary: 'var(--text-tertiary)',
disabled: 'var(--text-disabled)',
inverse: 'var(--text-inverse)',
};
const sizeMap = {
small: 'var(--text-interface-small)',
regular: 'var(--text-interface)',
large: 'var(--text-interface)',
};
const weightMap = {
light: 300,
regular: 400,
medium: 500,
semibold: 600,
bold: 700,
};
const interfaceStyles: React.CSSProperties = {
fontFamily: 'var(--font-interface)',
fontSize: sizeMap[size],
fontWeight: weightMap[weight],
lineHeight: 'var(--leading-normal)',
letterSpacing: size === 'small' ? 'var(--tracking-wider)' : 'var(--tracking-wide)',
color: colorMap[color],
margin: 0,
...style,
};
return (
<span
className={`text-interface ${className}`}
style={interfaceStyles}
{...props}
>
{children}
</span>
);
};
// =============================================================================
// BODY TYPOGRAPHY
// =============================================================================
export const BodyText: React.FC<BodyTextProps> = ({
children,
size = 'regular',
className = '',
style = {},
color = 'primary',
weight = 'regular',
...props
}) => {
const colorMap = {
primary: 'var(--text-primary)',
secondary: 'var(--text-secondary)',
tertiary: 'var(--text-tertiary)',
disabled: 'var(--text-disabled)',
inverse: 'var(--text-inverse)',
};
const sizeMap = {
large: 'var(--text-body-large)',
regular: 'var(--text-body)',
small: 'var(--text-body-small)',
};
const weightMap = {
light: 300,
regular: 400,
medium: 500,
semibold: 600,
bold: 700,
};
const lineHeightMap = {
large: 'var(--leading-reading)',
regular: 'var(--leading-loose)',
small: 'var(--leading-relaxed)',
};
const bodyStyles: React.CSSProperties = {
fontFamily: 'var(--font-body)',
fontSize: sizeMap[size],
fontWeight: weightMap[weight],
lineHeight: lineHeightMap[size],
letterSpacing: size === 'small' ? 'var(--tracking-wide)' : 'var(--tracking-normal)',
color: colorMap[color],
margin: 0,
...style,
};
return (
<p
className={`text-body text-body-${size} ${className}`}
style={bodyStyles}
{...props}
>
{children}
</p>
);
};
// =============================================================================
// CODE TYPOGRAPHY
// =============================================================================
export const CodeText: React.FC<CodeTextProps> = ({
children,
inline = false,
className = '',
style = {},
language,
...props
}) => {
const codeStyles: React.CSSProperties = {
fontFamily: 'var(--font-mono)',
fontSize: inline ? '0.9em' : 'var(--text-code)',
lineHeight: 'var(--leading-relaxed)',
letterSpacing: 'var(--tracking-normal)',
color: 'var(--text-primary)',
backgroundColor: inline ? 'var(--bg-tertiary)' : 'var(--bg-secondary)',
padding: inline ? '2px 6px' : 'var(--space-md)',
borderRadius: inline ? '4px' : 'var(--radius-md)',
border: inline ? '1px solid var(--border-secondary)' : 'none',
margin: 0,
...style,
};
if (inline) {
return (
<code
className={`text-code ${className}`}
style={codeStyles}
{...props}
>
{children}
</code>
);
}
return (
<pre
className={`text-code ${className}`}
style={{
...codeStyles,
display: 'block',
overflow: 'auto',
whiteSpace: 'pre-wrap',
}}
{...props}
>
<code>{children}</code>
</pre>
);
};
// =============================================================================
// BUTTON TYPOGRAPHY
// =============================================================================
export const ButtonText: React.FC<ButtonTextProps> = ({
children,
size = 'regular',
className = '',
style = {},
...props
}) => {
const sizeMap = {
small: 'var(--text-interface-small)',
regular: 'var(--text-interface)',
large: 'var(--text-interface)',
};
const buttonStyles: React.CSSProperties = {
fontFamily: 'var(--font-body)',
fontSize: sizeMap[size],
fontWeight: 600,
lineHeight: 'var(--leading-tight)',
letterSpacing: 'var(--tracking-wider)',
margin: 0,
...style,
};
return (
<span
className={`text-button ${className}`}
style={buttonStyles}
{...props}
>
{children}
</span>
);
};
// =============================================================================
// UTILITY COMPONENTS
// =============================================================================
export const Gradient: React.FC<BaseTypographyProps> = ({
children,
className = '',
style = {},
...props
}) => {
const gradientStyles: React.CSSProperties = {
background: 'linear-gradient(135deg, var(--color-primary) 0%, var(--color-success) 100%)',
WebkitBackgroundClip: 'text',
backgroundClip: 'text',
color: 'transparent',
backgroundSize: '200% 200%',
animation: 'gradient-shift 5s ease-in-out infinite',
...style,
};
return (
<span
className={`text-gradient ${className}`}
style={gradientStyles}
{...props}
>
{children}
</span>
);
};
// =============================================================================
// COMPOUND COMPONENTS
// =============================================================================
export const Typography = {
Hero: HeroDisplay,
Display: DisplayHeading,
Interface: InterfaceText,
Body: BodyText,
Code: CodeText,
Button: ButtonText,
Gradient,
// Legacy compatibility with existing components
H1: (props: HeadingProps) => <DisplayHeading level={1} {...props} />,
H2: (props: HeadingProps) => <DisplayHeading level={2} {...props} />,
H3: (props: HeadingProps) => <DisplayHeading level={3} {...props} />,
H4: (props: HeadingProps) => <DisplayHeading level={4} {...props} />,
H5: (props: HeadingProps) => <DisplayHeading level={5} {...props} />,
P: (props: BodyTextProps) => <BodyText {...props} />,
};
export default Typography;