release: 2026-04-17 (320건 커밋) #190

병합
dnlee develop 에서 main 로 21 commits 를 머지했습니다 2026-04-17 13:42:37 +09:00
3개의 변경된 파일113개의 추가작업 그리고 133개의 파일을 삭제
Showing only changes of commit d07bd3e0f1 - Show all commits

파일 보기

@ -127,47 +127,6 @@ wing/
- API 인터페이스 변경 시 `memory/api-types.md` 갱신 - API 인터페이스 변경 시 `memory/api-types.md` 갱신
- 개별 탭 개발자는 공통 가이드를 참조하여 연동 구현 - 개별 탭 개발자는 공통 가이드를 참조하여 연동 구현
## 진행 중 작업 (완료 후 삭제)
### 폰트 크기 업스케일 작업 (진행 중)
반드시 `memory/font-upscale-plan.md`를 읽고 Phase 진행 상황을 확인할 것.
**토큰 변경 매핑 (이름 유지, 값만 변경):**
- `caption`/`label-2`/`title-6`: 11px → **12px** (0.75rem)
- `label-1`/`title-5`: 12px → **13px** (0.8125rem)
- `body-2`/`title-4`: 13px → **14px** (0.875rem)
- `body-1`/`title-3`: 14px → **16px** (1rem)
**네비게이션 클래스 교체:**
- TopBar 메인탭: `text-title-4``text-title-2` (16px)
- SubMenuBar 서브탭: `text-title-5``text-title-4` (14px)
**작업 범위:**
- Phase 1: tailwind.config.js + base.css 토큰 값 수정
- Phase 2: components.css 하드코딩(27곳) + wing.css `.wing-tab` text-xs→text-caption
- Phase 3: TopBar.tsx + SubMenuBar.tsx 클래스 교체
- Phase 4: text-xs→text-caption, text-sm→text-body-2 스크립트 교체 (design 페이지 제외, 608건)
- Phase 5: prediction 탭 인라인 fontSize 수정
- Phase 6 (보류): wing-header-bar 패딩 — 폰트 변경 후 유저 확인 후 진행
### 디자인 시스템 폰트+색상 통일 작업
compact 후 반드시 `memory/design-system-work.md`를 읽고 작업 상태(완료/미완료 컴포넌트)를 확인할 것.
**색상 규칙:**
- 하드코딩 색상(`#ef4444`, `#a855f7` 등) → CSS 변수 전환
- `rgba(59,130,246,...)` 등 비-accent 계열 → `rgba(6,182,212,...)` (accent cyan)
- 시맨틱 컬러(`color-accent`, `color-info`, `color-caution` 등)는 다양하게 사용 가능하되, 강조 색상은 **최대 2가지**로 제한
- `linear-gradient` → 단색으로 단순화
- 장식용 `border-top`, `border-left` → 제거 여부를 유저에게 확인 후 진행
**폰트 규칙:**
- 하드코딩 `fontSize`/`fontWeight` → Tailwind 토큰 (`text-title-2`, `text-caption` 등)
- `fontFamily: monospace``var(--font-mono)`
- `fontFamily: sans-serif` / `'Noto Sans KR'``var(--font-korean)`
- 인라인 `style={{ fontSize, padding }}` → Tailwind 클래스 전환 (가능한 범위)
## 환경 설정 ## 환경 설정
- Node.js 20 (`.node-version`, fnm 사용) - Node.js 20 (`.node-version`, fnm 사용)

파일 보기

@ -31,25 +31,25 @@
@layer base { @layer base {
:root { :root {
/* bg — Background */ /* bg — Background */
--bg-base: #0a0e1a; --bg-base: #121418;
--bg-surface: #0f1524; --bg-surface: #1B1E23;
--bg-elevated: #121929; --bg-elevated: #24272D;
--bg-card: #1a2236; --bg-card: #24272D;
--bg-surface-hover: #1e2844; --bg-surface-hover: #3A3F49;
/* stroke — Border */ /* stroke — Border */
--stroke-default: #1e2a42; --stroke-default: #24272D;
--stroke-light: #2a3a5c; --stroke-light: #1B1E23;
/* fg — Foreground */ /* fg — Foreground */
--fg-default: #edf0f7; --fg-default: #F8F9FC;
--fg-sub: #c0c8dc; --fg-sub: #B9C1C9;
--fg-disabled: #9ba3b8; --fg-disabled: #808892;
/* color — Palette */ /* color — Palette */
--color-info: #3b82f6; --color-info: #0099DD;
--color-accent: #06b6d4; --color-accent: #0099DD;
--color-accent-muted: #0e7490; --color-accent-muted: #007AB1;
--color-danger: #ef4444; --color-danger: #D61111;
--color-warning: #f97316; --color-warning: #f97316;
--color-caution: #eab308; --color-caution: #FEDA4A;
--color-success: #22c55e; --color-success: #22c55e;
--color-tertiary: #a855f7; --color-tertiary: #a855f7;
--color-boom: #f59e0b; --color-boom: #f59e0b;
@ -111,29 +111,34 @@
--static-black: #131415; --static-black: #131415;
--static-white: #ffffff; --static-white: #ffffff;
/* Gray */ /* Gray (Definition cool-tone, 15 steps) */
--gray-100: #f1f5f9; --gray-0: #FFFFFF;
--gray-200: #e2e8f0; --gray-50: #F8F9FC;
--gray-300: #cbd5e1; --gray-100: #F3F6FB;
--gray-400: #94a3b8; --gray-200: #EBEFF5;
--gray-500: #64748b; --gray-250: #E1E6EC;
--gray-600: #475569; --gray-300: #D6DBE1;
--gray-700: #334155; --gray-400: #B9C1C9;
--gray-800: #1e293b; --gray-500: #808892;
--gray-900: #0f172a; --gray-550: #6C747E;
--gray-1000: #020617; --gray-600: #565B64;
--gray-700: #3A3F49;
--gray-800: #24272D;
--gray-850: #1B1E23;
--gray-900: #121418;
--gray-1000: #000000;
/* Blue */ /* Blue (Primary Blue-Cyan, hue ~200°) */
--blue-100: #dbeafe; --blue-100: #E6F4FB;
--blue-200: #bfdbfe; --blue-200: #B3E0F5;
--blue-300: #93c5fd; --blue-300: #80CCEE;
--blue-400: #60a5fa; --blue-400: #4DB8E8;
--blue-500: #3b82f6; --blue-500: #0099DD;
--blue-600: #2563eb; --blue-600: #007AB1;
--blue-700: #1d4ed8; --blue-700: #005C85;
--blue-800: #1e40af; --blue-800: #003D59;
--blue-900: #1e3a8a; --blue-900: #001F2D;
--blue-1000: #172554; --blue-1000: #001520;
/* Green */ /* Green */
--green-100: #dcfce7; --green-100: #dcfce7;
@ -152,7 +157,7 @@
--yellow-200: #fef08a; --yellow-200: #fef08a;
--yellow-300: #fde047; --yellow-300: #fde047;
--yellow-400: #facc15; --yellow-400: #facc15;
--yellow-500: #eab308; --yellow-500: #FEDA4A;
--yellow-600: #ca8a04; --yellow-600: #ca8a04;
--yellow-700: #a16207; --yellow-700: #a16207;
--yellow-800: #854d0e; --yellow-800: #854d0e;
@ -160,12 +165,12 @@
--yellow-1000: #422006; --yellow-1000: #422006;
/* Red */ /* Red */
--red-100: #fee2e2; --red-100: #7A2D2D;
--red-200: #fecaca; --red-200: #fecaca;
--red-300: #fca5a5; --red-300: #fca5a5;
--red-400: #f87171; --red-400: #f87171;
--red-500: #ef4444; --red-500: #DE4141;
--red-600: #dc2626; --red-600: #D61111;
--red-700: #b91c1c; --red-700: #b91c1c;
--red-800: #991b1b; --red-800: #991b1b;
--red-900: #7f1d1d; --red-900: #7f1d1d;
@ -189,19 +194,19 @@
/* ── Light theme overrides ── */ /* ── Light theme overrides ── */
[data-theme='light'] { [data-theme='light'] {
--bg-base: #f8fafc; --bg-base: #FFFFFF;
--bg-surface: #ffffff; --bg-surface: #FFFFFF;
--bg-elevated: #f1f5f9; --bg-elevated: #F3F6FB;
--bg-card: #ffffff; --bg-card: #FFFFFF;
--bg-surface-hover: #e2e8f0; --bg-surface-hover: #EBEFF5;
--stroke-default: #cbd5e1; --stroke-default: #B9C1C9;
--stroke-light: #e2e8f0; --stroke-light: #E1E6EC;
--fg-default: #0f172a; --fg-default: #121418;
--fg-sub: #475569; --fg-sub: #24272D;
--fg-disabled: #94a3b8; --fg-disabled: #808892;
--hover-overlay: rgba(0, 0, 0, 0.04); --hover-overlay: rgba(0, 0, 0, 0.04);
--dropdown-bg: rgba(255, 255, 255, 0.97); --dropdown-bg: rgba(255, 255, 255, 0.97);
--color-accent-muted: #0891b2; --color-accent-muted: #007AB1;
--color-navy: #1d4ed8; --color-navy: #1d4ed8;
--color-navy-hover: #2563eb; --color-navy-hover: #2563eb;
} }

파일 보기

@ -108,7 +108,7 @@ interface SemanticColor {
const SEMANTIC_COLORS: SemanticColor[] = [ const SEMANTIC_COLORS: SemanticColor[] = [
{ name: 'Primary 500', hex: '#0099DD', usages: ['긍정의 의미', '주요 액션 버튼', '링크, 선택 상태'] }, { name: 'Primary 500', hex: '#0099DD', usages: ['긍정의 의미', '주요 액션 버튼', '링크, 선택 상태'] },
{ name: 'Red 600', hex: '#D61111', usages: ['부정 컬러로 사용', '공지 배지의 Text로 사용'] }, { name: 'Red 600', hex: '#D61111', usages: ['부정 컬러로 사용', '공지 배지의 Text로 사용'] },
{ name: 'Red 100', hex: '#FBD8DC', usages: ['공지 배지의 bg 컬러'] }, { name: 'Red 100', hex: '#7A2D2D', usages: ['공지 배지의 bg 컬러'] },
{ name: 'Yellow 500', hex: '#FEDA4A', usages: ['즐겨찾기/북마크 의미로 사용'] }, { name: 'Yellow 500', hex: '#FEDA4A', usages: ['즐겨찾기/북마크 의미로 사용'] },
]; ];
@ -144,31 +144,36 @@ const COLOR_TOKEN_GROUPS: ColorTokenGroup[] = [
{ {
title: 'Gray', title: 'Gray',
tokens: [ tokens: [
{ name: 'gray.100', hex: '#f1f5f9' }, { name: 'gray.0', hex: '#FFFFFF' },
{ name: 'gray.200', hex: '#e2e8f0' }, { name: 'gray.50', hex: '#F8F9FC' },
{ name: 'gray.300', hex: '#cbd5e1' }, { name: 'gray.100', hex: '#F3F6FB' },
{ name: 'gray.400', hex: '#94a3b8' }, { name: 'gray.200', hex: '#EBEFF5' },
{ name: 'gray.500', hex: '#64748b' }, { name: 'gray.250', hex: '#E1E6EC' },
{ name: 'gray.600', hex: '#475569' }, { name: 'gray.300', hex: '#D6DBE1' },
{ name: 'gray.700', hex: '#334155' }, { name: 'gray.400', hex: '#B9C1C9' },
{ name: 'gray.800', hex: '#1e293b' }, { name: 'gray.500', hex: '#808892' },
{ name: 'gray.900', hex: '#0f172a' }, { name: 'gray.550', hex: '#6C747E' },
{ name: 'gray.1000', hex: '#020617' }, { name: 'gray.600', hex: '#565B64' },
{ name: 'gray.700', hex: '#3A3F49' },
{ name: 'gray.800', hex: '#24272D' },
{ name: 'gray.850', hex: '#1B1E23' },
{ name: 'gray.900', hex: '#121418' },
{ name: 'gray.1000', hex: '#000000' },
], ],
}, },
{ {
title: 'Blue', title: 'Blue (Primary)',
tokens: [ tokens: [
{ name: 'blue.100', hex: '#dbeafe' }, { name: 'blue.100', hex: '#E6F4FB' },
{ name: 'blue.200', hex: '#bfdbfe' }, { name: 'blue.200', hex: '#B3E0F5' },
{ name: 'blue.300', hex: '#93c5fd' }, { name: 'blue.300', hex: '#80CCEE' },
{ name: 'blue.400', hex: '#60a5fa' }, { name: 'blue.400', hex: '#4DB8E8' },
{ name: 'blue.500', hex: '#3b82f6' }, { name: 'blue.500', hex: '#0099DD' },
{ name: 'blue.600', hex: '#2563eb' }, { name: 'blue.600', hex: '#007AB1' },
{ name: 'blue.700', hex: '#1d4ed8' }, { name: 'blue.700', hex: '#005C85' },
{ name: 'blue.800', hex: '#1e40af' }, { name: 'blue.800', hex: '#003D59' },
{ name: 'blue.900', hex: '#1e3a8a' }, { name: 'blue.900', hex: '#001F2D' },
{ name: 'blue.1000', hex: '#172554' }, { name: 'blue.1000', hex: '#001520' },
], ],
}, },
{ {
@ -193,7 +198,7 @@ const COLOR_TOKEN_GROUPS: ColorTokenGroup[] = [
{ name: 'yellow.200', hex: '#fef08a' }, { name: 'yellow.200', hex: '#fef08a' },
{ name: 'yellow.300', hex: '#fde047' }, { name: 'yellow.300', hex: '#fde047' },
{ name: 'yellow.400', hex: '#facc15' }, { name: 'yellow.400', hex: '#facc15' },
{ name: 'yellow.500', hex: '#eab308' }, { name: 'yellow.500', hex: '#FEDA4A' },
{ name: 'yellow.600', hex: '#ca8a04' }, { name: 'yellow.600', hex: '#ca8a04' },
{ name: 'yellow.700', hex: '#a16207' }, { name: 'yellow.700', hex: '#a16207' },
{ name: 'yellow.800', hex: '#854d0e' }, { name: 'yellow.800', hex: '#854d0e' },
@ -204,12 +209,12 @@ const COLOR_TOKEN_GROUPS: ColorTokenGroup[] = [
{ {
title: 'Red', title: 'Red',
tokens: [ tokens: [
{ name: 'red.100', hex: '#fee2e2' }, { name: 'red.100', hex: '#7A2D2D' },
{ name: 'red.200', hex: '#fecaca' }, { name: 'red.200', hex: '#fecaca' },
{ name: 'red.300', hex: '#fca5a5' }, { name: 'red.300', hex: '#fca5a5' },
{ name: 'red.400', hex: '#f87171' }, { name: 'red.400', hex: '#f87171' },
{ name: 'red.500', hex: '#ef4444' }, { name: 'red.500', hex: '#DE4141' },
{ name: 'red.600', hex: '#dc2626' }, { name: 'red.600', hex: '#D61111' },
{ name: 'red.700', hex: '#b91c1c' }, { name: 'red.700', hex: '#b91c1c' },
{ name: 'red.800', hex: '#991b1b' }, { name: 'red.800', hex: '#991b1b' },
{ name: 'red.900', hex: '#7f1d1d' }, { name: 'red.900', hex: '#7f1d1d' },
@ -771,27 +776,27 @@ export const ColorPaletteContent = ({ theme }: ColorPaletteContentProps) => {
tokens: [ tokens: [
{ {
name: '--bg-base', name: '--bg-base',
value: '#0a0e1a', value: '#121418',
desc: '페이지 최하단 배경', desc: '페이지 최하단 배경',
}, },
{ {
name: '--bg-surface', name: '--bg-surface',
value: '#0f1524', value: '#1B1E23',
desc: '패널, 사이드바', desc: '패널, 사이드바',
}, },
{ {
name: '--bg-elevated', name: '--bg-elevated',
value: '#121929', value: '#24272D',
desc: '테이블 헤더, 섹션', desc: '테이블 헤더, 섹션',
}, },
{ {
name: '--bg-card', name: '--bg-card',
value: '#1a2236', value: '#24272D',
desc: '카드, 플로팅 요소', desc: '카드, 플로팅 요소',
}, },
{ {
name: '--bg-surface-hover', name: '--bg-surface-hover',
value: '#1e2844', value: '#3A3F49',
desc: '호버 인터랙션', desc: '호버 인터랙션',
}, },
], ],
@ -799,11 +804,11 @@ export const ColorPaletteContent = ({ theme }: ColorPaletteContentProps) => {
{ {
title: 'fg — Foreground', title: 'fg — Foreground',
tokens: [ tokens: [
{ name: '--fg-default', value: '#edf0f7', desc: '기본 텍스트' }, { name: '--fg-default', value: '#F8F9FC', desc: '기본 텍스트' },
{ name: '--fg-sub', value: '#c0c8dc', desc: '보조 텍스트' }, { name: '--fg-sub', value: '#B9C1C9', desc: '보조 텍스트' },
{ {
name: '--fg-disabled', name: '--fg-disabled',
value: '#9ba3b8', value: '#808892',
desc: '비활성, 플레이스홀더', desc: '비활성, 플레이스홀더',
}, },
], ],
@ -813,12 +818,12 @@ export const ColorPaletteContent = ({ theme }: ColorPaletteContentProps) => {
tokens: [ tokens: [
{ {
name: '--stroke-default', name: '--stroke-default',
value: '#1e2a42', value: '#24272D',
desc: '기본 구분선', desc: '기본 구분선',
}, },
{ {
name: '--stroke-light', name: '--stroke-light',
value: '#2a3a5c', value: '#1B1E23',
desc: '연한 구분선', desc: '연한 구분선',
}, },
], ],
@ -921,11 +926,12 @@ export const ColorPaletteContent = ({ theme }: ColorPaletteContentProps) => {
<span></span> <span></span>
</div> </div>
{[ {[
{ name: '--color-accent', value: '#06b6d4', desc: '주요 강조' }, { name: '--color-accent', value: '#0099DD', desc: '주요 강조' },
{ name: '--color-info', value: '#3b82f6', desc: '정보' }, { name: '--color-accent-muted', value: '#007AB1', desc: '차분한 강조' },
{ name: '--color-danger', value: '#ef4444', desc: '위험' }, { name: '--color-info', value: '#0099DD', desc: '정보' },
{ name: '--color-danger', value: '#D61111', desc: '위험' },
{ name: '--color-warning', value: '#f97316', desc: '주의' }, { name: '--color-warning', value: '#f97316', desc: '주의' },
{ name: '--color-caution', value: '#eab308', desc: '경고' }, { name: '--color-caution', value: '#FEDA4A', desc: '경고' },
{ name: '--color-success', value: '#22c55e', desc: '성공' }, { name: '--color-success', value: '#22c55e', desc: '성공' },
{ {
name: '--color-tertiary', name: '--color-tertiary',
@ -942,6 +948,16 @@ export const ColorPaletteContent = ({ theme }: ColorPaletteContentProps) => {
value: '#fbbf24', value: '#fbbf24',
desc: '오일붐 호버', desc: '오일붐 호버',
}, },
{
name: '--color-navy',
value: '#1e40af',
desc: 'Navy 강조',
},
{
name: '--color-navy-hover',
value: '#1d4ed8',
desc: 'Navy 호버',
},
].map((tk) => ( ].map((tk) => (
<div <div
key={tk.name} key={tk.name}