- Add theme-raw.ts (no MUI/DOM deps) as the one source of theme values. Each theme declares only surfaces, 3-tier text, borders, accent and overlay shadow; legacy glass/gradient/glow/crt keys are derived as flat values so existing call sites lose effects without edits. - Tertiary text now clears 4.5:1 on every surface in all six themes (label/inactive/dimLabel/muted alias it). Filled buttons use accent.solid + accent.ink (5.17:1 on dark/light, was 3.68:1). - theme-vars.ts derives popup CSS from the same raw values instead of a hand copy, and defines the previously undefined --d3-overlay-strong and --d3-accent-glow-dim. - MUI: no ripple, global focus-visible ring and reduced-motion rule, flat Card, status colors per theme, shape radius 16 -> 6. - DS: flatten MetalCard/DoubleBezelCard/ScreenPanel/TiltCard, tone-based PhysicalButton (500 weight, no lift), TactileBadge with zero tracking and keyboard support, glow-free Led/StatRing, idle wave amplitude 0. - PhosphorText drops mono/uppercase variants: mono has no Hangul glyphs, which spaced out Korean labels. - design.md: record the 2026-09-28 redesign brief, audit, IA and tokens.
74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
'use client'
|
|
|
|
// packages/ui/src/components/ds/PhosphorText.tsx
|
|
// v4 "조용한 계기": 타이포 변형 13종 — 전부 산세리프(Pretendard), 대문자 변환 없음.
|
|
// 위계는 크기와 명도(text 3단)로 만든다. 한글 라벨에 모노·양수 자간을 쓰지 않는다
|
|
// (모노 폰트에 한글 글리프가 없어 "누 름 유 지"처럼 벌어졌다 — 2026-09-28 실측).
|
|
// 수치는 tabular-nums 로 흔들리지 않게.
|
|
|
|
import { Typography, type TypographyProps } from '@mui/material'
|
|
import { d3roPalette, d3roFontSans, d3roTypo } from '../../theme'
|
|
|
|
type PhosphorVariant =
|
|
| 'hero' | 'title' | 'value' | 'heading'
|
|
| 'body' | 'compact' | 'small'
|
|
| 'meta' | 'label' | 'dim'
|
|
| 'engrave' | 'micro' | 'nano'
|
|
|
|
interface VariantDef {
|
|
fontSize: string
|
|
color: string
|
|
fontWeight: number
|
|
letterSpacing: string
|
|
lineHeight: number
|
|
}
|
|
|
|
const def = (key: keyof typeof d3roTypo, color: string): VariantDef => ({
|
|
fontSize: d3roTypo[key].size,
|
|
fontWeight: d3roTypo[key].weight,
|
|
letterSpacing: d3roTypo[key].spacing,
|
|
lineHeight: d3roTypo[key].line,
|
|
color,
|
|
})
|
|
|
|
const VARIANTS: Record<PhosphorVariant, VariantDef> = {
|
|
hero: def('hero', d3roPalette.text.primary),
|
|
title: def('title', d3roPalette.text.primary),
|
|
value: def('value', d3roPalette.text.primary),
|
|
heading: def('heading', d3roPalette.text.primary),
|
|
body: def('body', d3roPalette.text.secondary),
|
|
compact: def('compact', d3roPalette.text.primary),
|
|
small: def('small', d3roPalette.text.tertiary),
|
|
meta: def('meta', d3roPalette.text.tertiary),
|
|
label: def('label', d3roPalette.text.tertiary),
|
|
dim: { ...def('label', d3roPalette.text.tertiary), fontWeight: d3roTypo.body.weight },
|
|
engrave: def('engrave', d3roPalette.text.tertiary),
|
|
micro: def('micro', d3roPalette.text.tertiary),
|
|
nano: def('nano', d3roPalette.text.tertiary),
|
|
}
|
|
|
|
interface PhosphorTextProps extends Omit<TypographyProps, 'variant'> {
|
|
variant?: PhosphorVariant
|
|
}
|
|
|
|
export function PhosphorText({ variant = 'value', component = 'span', sx, ...props }: PhosphorTextProps): React.ReactElement {
|
|
const v = VARIANTS[variant]
|
|
|
|
return (
|
|
<Typography
|
|
component={component}
|
|
{...props}
|
|
sx={{
|
|
fontFamily: d3roFontSans,
|
|
fontSize: v.fontSize,
|
|
fontWeight: v.fontWeight,
|
|
color: v.color,
|
|
letterSpacing: v.letterSpacing,
|
|
lineHeight: v.lineHeight,
|
|
fontVariantNumeric: 'tabular-nums',
|
|
textTransform: 'none',
|
|
...sx,
|
|
}}
|
|
/>
|
|
)
|
|
}
|