3008 lines
100 KiB
TypeScript
3008 lines
100 KiB
TypeScript
import {
|
|
AppstoreOutlined,
|
|
AppstoreAddOutlined,
|
|
BellOutlined,
|
|
CheckCircleOutlined,
|
|
CompassOutlined,
|
|
LogoutOutlined,
|
|
CloseOutlined,
|
|
LeftOutlined,
|
|
SettingOutlined,
|
|
RightOutlined,
|
|
ThunderboltOutlined,
|
|
} from '@ant-design/icons';
|
|
import {
|
|
useEffect,
|
|
useMemo,
|
|
useState,
|
|
type CSSProperties,
|
|
type PointerEvent as ReactPointerEvent,
|
|
type ReactNode,
|
|
} from 'react';
|
|
import './Template1PlayAppView.css';
|
|
|
|
type Template1PlayAppViewProps = {
|
|
onBack: () => void;
|
|
launchContext?: 'direct' | 'embedded';
|
|
};
|
|
|
|
type Template1SectionId = 'home' | 'projects' | 'resources' | 'automation';
|
|
|
|
type Template1Section = {
|
|
id: Template1SectionId;
|
|
label: string;
|
|
description: string;
|
|
chips: string[];
|
|
};
|
|
|
|
type Template1MenuItem = {
|
|
title: string;
|
|
description: string;
|
|
icon: ReactNode;
|
|
screen?: Template1SectionId;
|
|
actionLabel?: string;
|
|
actionType?: 'navigate' | 'exit' | 'local';
|
|
settingAction?: 'theme' | 'notifications' | 'reset-state';
|
|
};
|
|
|
|
type Template1ThemeId =
|
|
| 'theme-default'
|
|
| 'theme-sky'
|
|
| 'theme-citrus'
|
|
| 'theme-forest'
|
|
| 'theme-violet'
|
|
| 'theme-graphite'
|
|
| 'theme-sunset'
|
|
| 'theme-coral'
|
|
| 'theme-olive'
|
|
| 'theme-mint'
|
|
| 'theme-ocean'
|
|
| 'theme-berry'
|
|
| 'theme-latte'
|
|
| 'theme-choco'
|
|
| 'theme-aurora'
|
|
| 'theme-electric'
|
|
| 'theme-tide'
|
|
| 'theme-peach-night'
|
|
| 'theme-graphite-cool'
|
|
| 'theme-ember'
|
|
| 'theme-small-text'
|
|
| 'theme-base-text'
|
|
| 'theme-large-text'
|
|
| 'theme-xsmall-text'
|
|
| 'theme-reading-text'
|
|
| 'theme-comfort-text'
|
|
| 'theme-comfortable-readable-text'
|
|
| 'theme-micro-text'
|
|
| 'theme-cursor-text'
|
|
| 'theme-compact-structure'
|
|
| 'theme-wide-structure'
|
|
| 'theme-list-structure'
|
|
| 'theme-focus-structure'
|
|
| 'theme-dense-grid-structure'
|
|
| 'theme-stagger-structure'
|
|
| 'theme-split-card-structure'
|
|
| 'theme-stats-column-structure'
|
|
| 'theme-mosaic-structure'
|
|
| 'theme-timeline-structure'
|
|
| 'theme-dashboard-structure'
|
|
| 'theme-kanban-structure'
|
|
| 'theme-glass-accent'
|
|
| 'theme-soft-glass'
|
|
| 'theme-glass-ink'
|
|
| 'theme-sunrise-glow'
|
|
| 'theme-slate-readability'
|
|
| 'theme-ocean-office'
|
|
| 'theme-sunset-contrast'
|
|
| 'theme-berry-focus'
|
|
| 'theme-aurora-clean'
|
|
| 'theme-micro-precision'
|
|
| 'theme-warm-glass'
|
|
| 'theme-citrus-minimal';
|
|
|
|
type Template1ThemeCategory = '색상' | '폰트' | '구조' | '혼합';
|
|
type Template1ThemePanelClass = 'color' | 'font' | 'layout' | 'mix';
|
|
type Template1LayoutPattern =
|
|
| 'compact'
|
|
| 'wide'
|
|
| 'list'
|
|
| 'focus'
|
|
| 'dense-grid'
|
|
| 'stagger'
|
|
| 'split'
|
|
| 'stats'
|
|
| 'mosaic'
|
|
| 'timeline'
|
|
| 'dashboard'
|
|
| 'kanban';
|
|
type Template1LayoutVisualKind =
|
|
| 'table-tight'
|
|
| 'table-card'
|
|
| 'list'
|
|
| 'focus'
|
|
| 'stagger'
|
|
| 'split'
|
|
| 'chess'
|
|
| 'timeline'
|
|
| 'board';
|
|
type Template1LayoutVisual = {
|
|
label: string;
|
|
kind: Template1LayoutVisualKind;
|
|
tileCount: number;
|
|
};
|
|
|
|
type Template1ThemePreset = {
|
|
id: Template1ThemeId;
|
|
title: string;
|
|
category: Template1ThemeCategory;
|
|
description: string;
|
|
fontScale: number;
|
|
cardColumns: number;
|
|
homeColumns: number;
|
|
gap: string;
|
|
padding: string;
|
|
shellRadius: string;
|
|
cardRadius: string;
|
|
cardMinHeight: string;
|
|
cardIconSize: string;
|
|
chipGap: string;
|
|
cssVars: Record<string, string>;
|
|
};
|
|
|
|
const TEMPLATE1_DEFAULT_THEME_VARIABLES: Record<string, string> = {
|
|
'--template1-background-start': '#f8fafc',
|
|
'--template1-background-end': '#f4f7fe',
|
|
'--template1-surface': '#ffffff',
|
|
'--template1-text': '#0f172a',
|
|
'--template1-subtext': '#64748b',
|
|
'--template1-muted': '#94a3b8',
|
|
'--template1-border': 'rgba(15, 23, 42, 0.1)',
|
|
'--template1-theme-item-min-width': '196px',
|
|
'--template1-theme-item-height': '56px',
|
|
'--template1-theme-item-max-width': '256px',
|
|
'--template1-theme-item-max-height': '74px',
|
|
'--template1-theme-window-width': '272px',
|
|
'--template1-theme-window-height': '302px',
|
|
'--template1-card-grid-template': 'auto 1fr auto',
|
|
'--template1-card-action-column': 'auto',
|
|
'--template1-card-action-justify': 'end',
|
|
'--template1-home-item-layout': 'auto minmax(0, 1fr) auto',
|
|
'--template1-home-item-gap': '14px',
|
|
'--template1-home-item-padding': '16px',
|
|
'--template1-home-item-padding-inline': '18px',
|
|
'--template1-card-max-height': 'none',
|
|
'--template1-topbar-start': 'rgba(248, 250, 252, 0.96)',
|
|
'--template1-topbar-end': 'rgba(248, 250, 252, 0.75)',
|
|
'--template1-topbar-text': '#0c4a9e',
|
|
'--template1-badge-bg': '#dbeafe',
|
|
'--template1-badge-text': '#0c4a9e',
|
|
'--template1-button-bg': '#dbeafe',
|
|
'--template1-button-text': '#0c4a9e',
|
|
'--template1-button-hover': 'rgba(37, 99, 235, 0.2)',
|
|
'--template1-settings-bg': '#ffffff',
|
|
'--template1-settings-border': '#e2e8f0',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#dbe4f2',
|
|
'--template1-card-text': '#0f172a',
|
|
'--template1-card-subtext': '#475569',
|
|
'--template1-card-icon-bg': '#e2e8f0',
|
|
'--template1-card-action': '#3b82f6',
|
|
'--template1-danger-bg': '#fff1f2',
|
|
'--template1-danger-border': '#fecaca',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(15, 23, 42, 0.12)',
|
|
};
|
|
|
|
const THEME_PRESETS: Template1ThemePreset[] = [
|
|
{
|
|
id: 'theme-default',
|
|
title: '기본 라이트',
|
|
category: '색상',
|
|
description: '기존 느낌의 안정적인 블루 계열',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#f8fafc',
|
|
'--template1-background-end': '#f4f7fe',
|
|
'--template1-surface': '#ffffff',
|
|
'--template1-text': '#0f172a',
|
|
'--template1-subtext': '#64748b',
|
|
'--template1-muted': '#94a3b8',
|
|
'--template1-border': 'rgba(15, 23, 42, 0.1)',
|
|
'--template1-topbar-start': 'rgba(248, 250, 252, 0.96)',
|
|
'--template1-topbar-end': 'rgba(248, 250, 252, 0.75)',
|
|
'--template1-topbar-text': '#0c4a9e',
|
|
'--template1-badge-bg': '#dbeafe',
|
|
'--template1-badge-text': '#0c4a9e',
|
|
'--template1-button-bg': '#dbeafe',
|
|
'--template1-button-text': '#0c4a9e',
|
|
'--template1-button-hover': 'rgba(37, 99, 235, 0.2)',
|
|
'--template1-settings-bg': '#ffffff',
|
|
'--template1-settings-border': '#e2e8f0',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#dbe4f2',
|
|
'--template1-card-text': '#0f172a',
|
|
'--template1-card-subtext': '#475569',
|
|
'--template1-card-icon-bg': '#e2e8f0',
|
|
'--template1-card-action': '#3b82f6',
|
|
'--template1-danger-bg': '#fff1f2',
|
|
'--template1-danger-border': '#fecaca',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(15, 23, 42, 0.12)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-sky',
|
|
title: '스카이 라이트',
|
|
category: '색상',
|
|
description: '푸른 그라데이션과 선명한 포인트',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '24px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#f0f9ff',
|
|
'--template1-background-end': '#e0f2fe',
|
|
'--template1-surface': '#f8fdff',
|
|
'--template1-text': '#0f172a',
|
|
'--template1-subtext': '#0f3f5f',
|
|
'--template1-muted': '#1d5a83',
|
|
'--template1-border': 'rgba(12, 74, 158, 0.16)',
|
|
'--template1-topbar-start': 'rgba(238, 250, 255, 0.96)',
|
|
'--template1-topbar-end': 'rgba(238, 250, 255, 0.7)',
|
|
'--template1-topbar-text': '#075985',
|
|
'--template1-badge-bg': '#bae6fd',
|
|
'--template1-badge-text': '#0c4a6e',
|
|
'--template1-button-bg': '#bae6fd',
|
|
'--template1-button-text': '#075985',
|
|
'--template1-button-hover': 'rgba(14, 165, 233, 0.2)',
|
|
'--template1-settings-bg': '#ecfeff',
|
|
'--template1-settings-border': '#bae6fd',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#bae6fd',
|
|
'--template1-card-text': '#0f172a',
|
|
'--template1-card-subtext': '#075985',
|
|
'--template1-card-icon-bg': '#bae6fd',
|
|
'--template1-card-action': '#0284c7',
|
|
'--template1-danger-bg': '#e0f2fe',
|
|
'--template1-danger-border': '#7dd3fc',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(2, 132, 199, 0.12)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-citrus',
|
|
title: '시트러스',
|
|
category: '색상',
|
|
description: '온건한 오렌지톤과 고명도 카드',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '20px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#fffbeb',
|
|
'--template1-background-end': '#fff7ed',
|
|
'--template1-surface': '#fffdf7',
|
|
'--template1-text': '#431407',
|
|
'--template1-subtext': '#854d0e',
|
|
'--template1-muted': '#b45309',
|
|
'--template1-border': 'rgba(180, 83, 9, 0.25)',
|
|
'--template1-topbar-start': 'rgba(255, 247, 237, 0.96)',
|
|
'--template1-topbar-end': 'rgba(255, 247, 237, 0.74)',
|
|
'--template1-topbar-text': '#92400e',
|
|
'--template1-badge-bg': '#fde68a',
|
|
'--template1-badge-text': '#92400e',
|
|
'--template1-button-bg': '#fde68a',
|
|
'--template1-button-text': '#92400e',
|
|
'--template1-button-hover': 'rgba(202, 138, 4, 0.2)',
|
|
'--template1-settings-bg': '#fffbeb',
|
|
'--template1-settings-border': '#fde68a',
|
|
'--template1-card-bg': '#fffdf7',
|
|
'--template1-card-border': '#fdba74',
|
|
'--template1-card-text': '#431407',
|
|
'--template1-card-subtext': '#7c2d12',
|
|
'--template1-card-icon-bg': '#fde68a',
|
|
'--template1-card-action': '#d97706',
|
|
'--template1-danger-bg': '#fff7ed',
|
|
'--template1-danger-border': '#fed7aa',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(180, 83, 9, 0.12)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-forest',
|
|
title: '포레스트',
|
|
category: '색상',
|
|
description: '그린 포인트와 무광 카드',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#f0fdf4',
|
|
'--template1-background-end': '#ecfccb',
|
|
'--template1-surface': '#f0fdf4',
|
|
'--template1-text': '#052e16',
|
|
'--template1-subtext': '#166534',
|
|
'--template1-muted': '#14532d',
|
|
'--template1-border': 'rgba(34, 197, 94, 0.25)',
|
|
'--template1-topbar-start': 'rgba(240, 253, 244, 0.96)',
|
|
'--template1-topbar-end': 'rgba(236, 252, 203, 0.72)',
|
|
'--template1-topbar-text': '#166534',
|
|
'--template1-badge-bg': '#bbf7d0',
|
|
'--template1-badge-text': '#166534',
|
|
'--template1-button-bg': '#bbf7d0',
|
|
'--template1-button-text': '#166534',
|
|
'--template1-button-hover': 'rgba(22, 163, 74, 0.2)',
|
|
'--template1-settings-bg': '#f0fdf4',
|
|
'--template1-settings-border': '#bbf7d0',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#86efac',
|
|
'--template1-card-text': '#052e16',
|
|
'--template1-card-subtext': '#166534',
|
|
'--template1-card-icon-bg': '#dcfce7',
|
|
'--template1-card-action': '#16a34a',
|
|
'--template1-danger-bg': '#ecfccb',
|
|
'--template1-danger-border': '#a3e635',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(21, 128, 61, 0.12)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-violet',
|
|
title: '바이올렛',
|
|
category: '색상',
|
|
description: '보라 기조의 고대비 강조형',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '24px',
|
|
cardRadius: '20px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#faf5ff',
|
|
'--template1-background-end': '#ede9fe',
|
|
'--template1-surface': '#fcfaff',
|
|
'--template1-text': '#312e81',
|
|
'--template1-subtext': '#5b21b6',
|
|
'--template1-muted': '#6d28d9',
|
|
'--template1-border': 'rgba(109, 40, 217, 0.25)',
|
|
'--template1-topbar-start': 'rgba(250, 245, 255, 0.96)',
|
|
'--template1-topbar-end': 'rgba(237, 233, 254, 0.7)',
|
|
'--template1-topbar-text': '#5b21b6',
|
|
'--template1-badge-bg': '#ddd6fe',
|
|
'--template1-badge-text': '#5b21b6',
|
|
'--template1-button-bg': '#ddd6fe',
|
|
'--template1-button-text': '#4c1d95',
|
|
'--template1-button-hover': 'rgba(109, 40, 217, 0.2)',
|
|
'--template1-settings-bg': '#faf5ff',
|
|
'--template1-settings-border': '#ddd6fe',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#c4b5fd',
|
|
'--template1-card-text': '#312e81',
|
|
'--template1-card-subtext': '#4c1d95',
|
|
'--template1-card-icon-bg': '#ddd6fe',
|
|
'--template1-card-action': '#6d28d9',
|
|
'--template1-danger-bg': '#f3e8ff',
|
|
'--template1-danger-border': '#c4b5fd',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(91, 33, 182, 0.12)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-graphite',
|
|
title: '그래파이트',
|
|
category: '색상',
|
|
description: '차분한 다크 모노톤',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '20px',
|
|
cardRadius: '12px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#f8fafc',
|
|
'--template1-background-end': '#e2e8f0',
|
|
'--template1-surface': '#f1f5f9',
|
|
'--template1-text': '#0f172a',
|
|
'--template1-subtext': '#334155',
|
|
'--template1-muted': '#475569',
|
|
'--template1-border': 'rgba(71, 85, 105, 0.28)',
|
|
'--template1-topbar-start': 'rgba(241, 245, 249, 0.96)',
|
|
'--template1-topbar-end': 'rgba(226, 232, 240, 0.72)',
|
|
'--template1-topbar-text': '#0f172a',
|
|
'--template1-badge-bg': '#cbd5e1',
|
|
'--template1-badge-text': '#0f172a',
|
|
'--template1-button-bg': '#cbd5e1',
|
|
'--template1-button-text': '#0f172a',
|
|
'--template1-button-hover': 'rgba(71, 85, 105, 0.2)',
|
|
'--template1-settings-bg': '#f8fafc',
|
|
'--template1-settings-border': '#cbd5e1',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#cbd5e1',
|
|
'--template1-card-text': '#0f172a',
|
|
'--template1-card-subtext': '#334155',
|
|
'--template1-card-icon-bg': '#e2e8f0',
|
|
'--template1-card-action': '#334155',
|
|
'--template1-danger-bg': '#e2e8f0',
|
|
'--template1-danger-border': '#94a3b8',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(15, 23, 42, 0.16)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-sunset',
|
|
title: '썬셋',
|
|
category: '색상',
|
|
description: '붉은 톤과 따뜻한 대비',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '20px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#fff1f2',
|
|
'--template1-background-end': '#ffe4e6',
|
|
'--template1-surface': '#fff7f8',
|
|
'--template1-text': '#7f1d1d',
|
|
'--template1-subtext': '#9f1239',
|
|
'--template1-muted': '#be123c',
|
|
'--template1-border': 'rgba(190, 18, 60, 0.28)',
|
|
'--template1-topbar-start': 'rgba(255, 241, 242, 0.96)',
|
|
'--template1-topbar-end': 'rgba(254, 205, 211, 0.75)',
|
|
'--template1-topbar-text': '#9f1239',
|
|
'--template1-badge-bg': '#fecdd3',
|
|
'--template1-badge-text': '#9f1239',
|
|
'--template1-button-bg': '#fecdd3',
|
|
'--template1-button-text': '#9f1239',
|
|
'--template1-button-hover': 'rgba(190, 18, 60, 0.18)',
|
|
'--template1-settings-bg': '#fff7f8',
|
|
'--template1-settings-border': '#fecdd3',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#fda4af',
|
|
'--template1-card-text': '#7f1d1d',
|
|
'--template1-card-subtext': '#9f1239',
|
|
'--template1-card-icon-bg': '#fee2e2',
|
|
'--template1-card-action': '#be123c',
|
|
'--template1-danger-bg': '#fecdd3',
|
|
'--template1-danger-border': '#fda4af',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(190, 18, 60, 0.14)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-coral',
|
|
title: '코랄',
|
|
category: '색상',
|
|
description: '밝은 톤에 강한 액션 포인트',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#fff5f5',
|
|
'--template1-background-end': '#fce7f3',
|
|
'--template1-surface': '#fff8fb',
|
|
'--template1-text': '#831843',
|
|
'--template1-subtext': '#9d174d',
|
|
'--template1-muted': '#be185d',
|
|
'--template1-border': 'rgba(219, 39, 119, 0.25)',
|
|
'--template1-topbar-start': 'rgba(255, 245, 245, 0.96)',
|
|
'--template1-topbar-end': 'rgba(252, 231, 243, 0.72)',
|
|
'--template1-topbar-text': '#9d174d',
|
|
'--template1-badge-bg': '#f9a8d4',
|
|
'--template1-badge-text': '#9d174d',
|
|
'--template1-button-bg': '#f9a8d4',
|
|
'--template1-button-text': '#9d174d',
|
|
'--template1-button-hover': 'rgba(236, 72, 153, 0.2)',
|
|
'--template1-settings-bg': '#fff8fb',
|
|
'--template1-settings-border': '#f9a8d4',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#f9a8d4',
|
|
'--template1-card-text': '#831843',
|
|
'--template1-card-subtext': '#9d174d',
|
|
'--template1-card-icon-bg': '#fbcfe8',
|
|
'--template1-card-action': '#be185d',
|
|
'--template1-danger-bg': '#f9a8d4',
|
|
'--template1-danger-border': '#f472b6',
|
|
'--template1-danger-icon': '#be123c',
|
|
'--template1-danger-text': '#be123c',
|
|
'--template1-shadow': 'rgba(190, 24, 93, 0.15)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-olive',
|
|
title: '올리브',
|
|
category: '색상',
|
|
description: '차분한 올리브 + 브라운의 조합',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '20px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#f7fee7',
|
|
'--template1-background-end': '#ecfccb',
|
|
'--template1-surface': '#f7fee7',
|
|
'--template1-text': '#365314',
|
|
'--template1-subtext': '#365314',
|
|
'--template1-muted': '#4d7c0f',
|
|
'--template1-border': 'rgba(77, 124, 15, 0.24)',
|
|
'--template1-topbar-start': 'rgba(247, 254, 231, 0.96)',
|
|
'--template1-topbar-end': 'rgba(236, 252, 203, 0.72)',
|
|
'--template1-topbar-text': '#365314',
|
|
'--template1-badge-bg': '#d9f99d',
|
|
'--template1-badge-text': '#365314',
|
|
'--template1-button-bg': '#d9f99d',
|
|
'--template1-button-text': '#365314',
|
|
'--template1-button-hover': 'rgba(101, 163, 13, 0.2)',
|
|
'--template1-settings-bg': '#ecfccb',
|
|
'--template1-settings-border': '#d9f99d',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#bef264',
|
|
'--template1-card-text': '#365314',
|
|
'--template1-card-subtext': '#4d7c0f',
|
|
'--template1-card-icon-bg': '#dcfce7',
|
|
'--template1-card-action': '#65a30d',
|
|
'--template1-danger-bg': '#fef9c3',
|
|
'--template1-danger-border': '#facc15',
|
|
'--template1-danger-icon': '#713f12',
|
|
'--template1-danger-text': '#713f12',
|
|
'--template1-shadow': 'rgba(101, 163, 13, 0.14)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-mint',
|
|
title: '민트',
|
|
category: '색상',
|
|
description: '초록빛이 얇은 차트와 함께하는 쿨 톤',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#f0fdfa',
|
|
'--template1-background-end': '#ccfbf1',
|
|
'--template1-surface': '#f0fdf4',
|
|
'--template1-text': '#115e59',
|
|
'--template1-subtext': '#115e59',
|
|
'--template1-muted': '#0f766e',
|
|
'--template1-border': 'rgba(13, 148, 136, 0.26)',
|
|
'--template1-topbar-start': 'rgba(240, 253, 250, 0.96)',
|
|
'--template1-topbar-end': 'rgba(204, 251, 241, 0.72)',
|
|
'--template1-topbar-text': '#115e59',
|
|
'--template1-badge-bg': '#99f6e4',
|
|
'--template1-badge-text': '#115e59',
|
|
'--template1-button-bg': '#99f6e4',
|
|
'--template1-button-text': '#115e59',
|
|
'--template1-button-hover': 'rgba(13, 148, 136, 0.2)',
|
|
'--template1-settings-bg': '#f0fdfa',
|
|
'--template1-settings-border': '#99f6e4',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#5eead4',
|
|
'--template1-card-text': '#115e59',
|
|
'--template1-card-subtext': '#0f766e',
|
|
'--template1-card-icon-bg': '#99f6e4',
|
|
'--template1-card-action': '#0f766e',
|
|
'--template1-danger-bg': '#ccfbf1',
|
|
'--template1-danger-border': '#5eead4',
|
|
'--template1-danger-icon': '#115e59',
|
|
'--template1-danger-text': '#115e59',
|
|
'--template1-shadow': 'rgba(13, 148, 136, 0.13)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-ocean',
|
|
title: '오션',
|
|
category: '색상',
|
|
description: '진한 블루와 선명한 대비 포인트',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '20px',
|
|
cardRadius: '17px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#eff6ff',
|
|
'--template1-background-end': '#dbeafe',
|
|
'--template1-surface': '#f1f5ff',
|
|
'--template1-text': '#1e3a8a',
|
|
'--template1-subtext': '#1d4ed8',
|
|
'--template1-muted': '#312e81',
|
|
'--template1-border': 'rgba(30, 64, 175, 0.22)',
|
|
'--template1-topbar-start': 'rgba(219, 234, 254, 0.96)',
|
|
'--template1-topbar-end': 'rgba(191, 219, 254, 0.72)',
|
|
'--template1-topbar-text': '#1d4ed8',
|
|
'--template1-badge-bg': '#dbeafe',
|
|
'--template1-badge-text': '#1d4ed8',
|
|
'--template1-button-bg': '#dbeafe',
|
|
'--template1-button-text': '#1d4ed8',
|
|
'--template1-button-hover': 'rgba(37, 99, 235, 0.16)',
|
|
'--template1-settings-bg': '#eff6ff',
|
|
'--template1-settings-border': '#bfdbfe',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#93c5fd',
|
|
'--template1-card-text': '#1e3a8a',
|
|
'--template1-card-subtext': '#1e40af',
|
|
'--template1-card-icon-bg': '#dbeafe',
|
|
'--template1-card-action': '#2563eb',
|
|
'--template1-danger-bg': '#dbeafe',
|
|
'--template1-danger-border': '#93c5fd',
|
|
'--template1-danger-icon': '#1d4ed8',
|
|
'--template1-danger-text': '#1d4ed8',
|
|
'--template1-shadow': 'rgba(30, 64, 175, 0.12)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-berry',
|
|
title: '버리',
|
|
category: '색상',
|
|
description: '보라 계열과 높은 대비로 강조',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '11px',
|
|
padding: '14px',
|
|
shellRadius: '21px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#faf5ff',
|
|
'--template1-background-end': '#f5d0fe',
|
|
'--template1-surface': '#fdf2ff',
|
|
'--template1-text': '#4c1d95',
|
|
'--template1-subtext': '#6b21a8',
|
|
'--template1-muted': '#7e22ce',
|
|
'--template1-border': 'rgba(109, 40, 217, 0.24)',
|
|
'--template1-topbar-start': 'rgba(250, 245, 255, 0.96)',
|
|
'--template1-topbar-end': 'rgba(245, 208, 254, 0.72)',
|
|
'--template1-topbar-text': '#6b21a8',
|
|
'--template1-badge-bg': '#e9d5ff',
|
|
'--template1-badge-text': '#5b21b6',
|
|
'--template1-button-bg': '#e9d5ff',
|
|
'--template1-button-text': '#5b21b6',
|
|
'--template1-button-hover': 'rgba(124, 58, 237, 0.18)',
|
|
'--template1-settings-bg': '#faf5ff',
|
|
'--template1-settings-border': '#e9d5ff',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#ddd6fe',
|
|
'--template1-card-text': '#4c1d95',
|
|
'--template1-card-subtext': '#6d28d9',
|
|
'--template1-card-icon-bg': '#e9d5ff',
|
|
'--template1-card-action': '#6d28d9',
|
|
'--template1-danger-bg': '#f5d0fe',
|
|
'--template1-danger-border': '#f0abfc',
|
|
'--template1-danger-icon': '#6b21a8',
|
|
'--template1-danger-text': '#6b21a8',
|
|
'--template1-shadow': 'rgba(109, 40, 217, 0.14)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-latte',
|
|
title: '라떼',
|
|
category: '색상',
|
|
description: '따뜻한 라이트 톤과 부드러운 대비',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '11px',
|
|
padding: '14px',
|
|
shellRadius: '20px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#fff7ed',
|
|
'--template1-background-end': '#ffedd5',
|
|
'--template1-surface': '#fffbeb',
|
|
'--template1-text': '#7c2d12',
|
|
'--template1-subtext': '#9a3412',
|
|
'--template1-muted': '#c2410c',
|
|
'--template1-border': 'rgba(194, 65, 12, 0.2)',
|
|
'--template1-topbar-start': 'rgba(255, 247, 237, 0.96)',
|
|
'--template1-topbar-end': 'rgba(254, 215, 170, 0.7)',
|
|
'--template1-topbar-text': '#9a3412',
|
|
'--template1-badge-bg': '#fed7aa',
|
|
'--template1-badge-text': '#9a3412',
|
|
'--template1-button-bg': '#fed7aa',
|
|
'--template1-button-text': '#9a3412',
|
|
'--template1-button-hover': 'rgba(234, 88, 12, 0.22)',
|
|
'--template1-settings-bg': '#fff7ed',
|
|
'--template1-settings-border': '#fdba74',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#fdba74',
|
|
'--template1-card-text': '#7c2d12',
|
|
'--template1-card-subtext': '#9a3412',
|
|
'--template1-card-icon-bg': '#fed7aa',
|
|
'--template1-card-action': '#ea580c',
|
|
'--template1-danger-bg': '#ffedd5',
|
|
'--template1-danger-border': '#fdba74',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(234, 88, 12, 0.14)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-choco',
|
|
title: '초코',
|
|
category: '색상',
|
|
description: '다크 베이스에 단단한 하이라이트',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '11px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#262626',
|
|
'--template1-background-end': '#3f3f46',
|
|
'--template1-surface': '#1f2937',
|
|
'--template1-text': '#f8fafc',
|
|
'--template1-subtext': '#cbd5e1',
|
|
'--template1-muted': '#94a3b8',
|
|
'--template1-border': 'rgba(148, 163, 184, 0.35)',
|
|
'--template1-topbar-start': 'rgba(31, 41, 55, 0.96)',
|
|
'--template1-topbar-end': 'rgba(55, 65, 81, 0.75)',
|
|
'--template1-topbar-text': '#f8fafc',
|
|
'--template1-badge-bg': '#334155',
|
|
'--template1-badge-text': '#f8fafc',
|
|
'--template1-button-bg': '#334155',
|
|
'--template1-button-text': '#f8fafc',
|
|
'--template1-button-hover': 'rgba(148, 163, 184, 0.24)',
|
|
'--template1-settings-bg': '#262626',
|
|
'--template1-settings-border': '#475569',
|
|
'--template1-card-bg': '#1e293b',
|
|
'--template1-card-border': '#64748b',
|
|
'--template1-card-text': '#f8fafc',
|
|
'--template1-card-subtext': '#cbd5e1',
|
|
'--template1-card-icon-bg': '#334155',
|
|
'--template1-card-action': '#93c5fd',
|
|
'--template1-danger-bg': 'rgba(148, 163, 184, 0.18)',
|
|
'--template1-danger-border': '#64748b',
|
|
'--template1-danger-icon': '#fca5a5',
|
|
'--template1-danger-text': '#fca5a5',
|
|
'--template1-shadow': 'rgba(15, 23, 42, 0.45)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-aurora',
|
|
title: '오로라',
|
|
category: '색상',
|
|
description: '차갑고 선명한 푸른 계열',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#eff6ff',
|
|
'--template1-background-end': '#dbeafe',
|
|
'--template1-surface': '#eef2ff',
|
|
'--template1-text': '#312e81',
|
|
'--template1-subtext': '#1d4ed8',
|
|
'--template1-muted': '#4338ca',
|
|
'--template1-border': 'rgba(59, 130, 246, 0.28)',
|
|
'--template1-topbar-start': 'rgba(238, 242, 255, 0.96)',
|
|
'--template1-topbar-end': 'rgba(224, 242, 254, 0.76)',
|
|
'--template1-topbar-text': '#312e81',
|
|
'--template1-badge-bg': '#bfdbfe',
|
|
'--template1-badge-text': '#312e81',
|
|
'--template1-button-bg': '#bfdbfe',
|
|
'--template1-button-text': '#312e81',
|
|
'--template1-button-hover': 'rgba(59, 130, 246, 0.2)',
|
|
'--template1-settings-bg': '#eff6ff',
|
|
'--template1-settings-border': '#bfdbfe',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#93c5fd',
|
|
'--template1-card-text': '#312e81',
|
|
'--template1-card-subtext': '#1e40af',
|
|
'--template1-card-icon-bg': '#dbeafe',
|
|
'--template1-card-action': '#2563eb',
|
|
'--template1-danger-bg': '#dbeafe',
|
|
'--template1-danger-border': '#93c5fd',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(30, 64, 175, 0.18)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-electric',
|
|
title: '일렉트릭',
|
|
category: '색상',
|
|
description: '강한 대비의 보라·청록 조합',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '20px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#312e81',
|
|
'--template1-background-end': '#0f172a',
|
|
'--template1-surface': '#1e1b4b',
|
|
'--template1-text': '#f8fafc',
|
|
'--template1-subtext': '#cbd5e1',
|
|
'--template1-muted': '#a5b4fc',
|
|
'--template1-border': 'rgba(168, 85, 247, 0.36)',
|
|
'--template1-topbar-start': 'rgba(30, 27, 75, 0.96)',
|
|
'--template1-topbar-end': 'rgba(15, 23, 42, 0.78)',
|
|
'--template1-topbar-text': '#f8fafc',
|
|
'--template1-badge-bg': '#5b21b6',
|
|
'--template1-badge-text': '#f8fafc',
|
|
'--template1-button-bg': '#5b21b6',
|
|
'--template1-button-text': '#f8fafc',
|
|
'--template1-button-hover': 'rgba(147, 51, 234, 0.24)',
|
|
'--template1-settings-bg': '#312e81',
|
|
'--template1-settings-border': '#7c3aed',
|
|
'--template1-card-bg': '#0f172a',
|
|
'--template1-card-border': '#6d28d9',
|
|
'--template1-card-text': '#f8fafc',
|
|
'--template1-card-subtext': '#c7d2fe',
|
|
'--template1-card-icon-bg': '#312e81',
|
|
'--template1-card-action': '#22d3ee',
|
|
'--template1-danger-bg': '#1e293b',
|
|
'--template1-danger-border': '#7c3aed',
|
|
'--template1-danger-icon': '#fca5a5',
|
|
'--template1-danger-text': '#fca5a5',
|
|
'--template1-shadow': 'rgba(17, 24, 39, 0.58)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-tide',
|
|
title: '타이드',
|
|
category: '색상',
|
|
description: '청록 바다 톤의 부드러운 잔향',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#f0fdfa',
|
|
'--template1-background-end': '#cffafe',
|
|
'--template1-surface': '#ecfeff',
|
|
'--template1-text': '#0f766e',
|
|
'--template1-subtext': '#0f766e',
|
|
'--template1-muted': '#115e59',
|
|
'--template1-border': 'rgba(13, 148, 136, 0.24)',
|
|
'--template1-topbar-start': 'rgba(236, 254, 255, 0.96)',
|
|
'--template1-topbar-end': 'rgba(207, 250, 254, 0.72)',
|
|
'--template1-topbar-text': '#0f766e',
|
|
'--template1-badge-bg': '#99f6e4',
|
|
'--template1-badge-text': '#134e4a',
|
|
'--template1-button-bg': '#99f6e4',
|
|
'--template1-button-text': '#134e4a',
|
|
'--template1-button-hover': 'rgba(13, 148, 136, 0.2)',
|
|
'--template1-settings-bg': '#ecfeff',
|
|
'--template1-settings-border': '#5eead4',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#2dd4bf',
|
|
'--template1-card-text': '#0f766e',
|
|
'--template1-card-subtext': '#115e59',
|
|
'--template1-card-icon-bg': '#a7f3d0',
|
|
'--template1-card-action': '#0d9488',
|
|
'--template1-danger-bg': '#cffafe',
|
|
'--template1-danger-border': '#2dd4bf',
|
|
'--template1-danger-icon': '#b91c1c',
|
|
'--template1-danger-text': '#b91c1c',
|
|
'--template1-shadow': 'rgba(13, 148, 136, 0.14)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-peach-night',
|
|
title: '피치 나이트',
|
|
category: '색상',
|
|
description: '핑크와 다크 브라운의 조용한 대비',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '11px',
|
|
padding: '14px',
|
|
shellRadius: '21px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#2d1a33',
|
|
'--template1-background-end': '#4c1d95',
|
|
'--template1-surface': '#2e1065',
|
|
'--template1-text': '#fdf2f8',
|
|
'--template1-subtext': '#f5d0fe',
|
|
'--template1-muted': '#e9d5ff',
|
|
'--template1-border': 'rgba(232, 121, 249, 0.3)',
|
|
'--template1-topbar-start': 'rgba(46, 16, 101, 0.96)',
|
|
'--template1-topbar-end': 'rgba(124, 58, 237, 0.74)',
|
|
'--template1-topbar-text': '#fdf2f8',
|
|
'--template1-badge-bg': '#c026d3',
|
|
'--template1-badge-text': '#fdf2f8',
|
|
'--template1-button-bg': '#c026d3',
|
|
'--template1-button-text': '#fdf2f8',
|
|
'--template1-button-hover': 'rgba(236, 72, 153, 0.24)',
|
|
'--template1-settings-bg': '#312e81',
|
|
'--template1-settings-border': '#a855f7',
|
|
'--template1-card-bg': '#1e1b4b',
|
|
'--template1-card-border': '#c026d3',
|
|
'--template1-card-text': '#fdf2f8',
|
|
'--template1-card-subtext': '#ddd6fe',
|
|
'--template1-card-icon-bg': '#4c1d95',
|
|
'--template1-card-action': '#fb7185',
|
|
'--template1-danger-bg': '#2e1065',
|
|
'--template1-danger-border': '#c026d3',
|
|
'--template1-danger-icon': '#fca5a5',
|
|
'--template1-danger-text': '#fca5a5',
|
|
'--template1-shadow': 'rgba(30, 27, 75, 0.52)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-graphite-cool',
|
|
title: '쿨 그래파이트',
|
|
category: '색상',
|
|
description: '은은한 회색계열에 청색 포인트',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '11px',
|
|
padding: '14px',
|
|
shellRadius: '20px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#111827',
|
|
'--template1-background-end': '#1f2937',
|
|
'--template1-surface': '#0f172a',
|
|
'--template1-text': '#e2e8f0',
|
|
'--template1-subtext': '#cbd5e1',
|
|
'--template1-muted': '#94a3b8',
|
|
'--template1-border': 'rgba(148, 163, 184, 0.3)',
|
|
'--template1-topbar-start': 'rgba(15, 23, 42, 0.96)',
|
|
'--template1-topbar-end': 'rgba(30, 41, 59, 0.76)',
|
|
'--template1-topbar-text': '#f8fafc',
|
|
'--template1-badge-bg': '#334155',
|
|
'--template1-badge-text': '#f8fafc',
|
|
'--template1-button-bg': '#334155',
|
|
'--template1-button-text': '#f8fafc',
|
|
'--template1-button-hover': 'rgba(148, 163, 184, 0.24)',
|
|
'--template1-settings-bg': '#111827',
|
|
'--template1-settings-border': '#475569',
|
|
'--template1-card-bg': '#1e293b',
|
|
'--template1-card-border': '#64748b',
|
|
'--template1-card-text': '#e2e8f0',
|
|
'--template1-card-subtext': '#d1d5db',
|
|
'--template1-card-icon-bg': '#334155',
|
|
'--template1-card-action': '#67e8f9',
|
|
'--template1-danger-bg': '#334155',
|
|
'--template1-danger-border': '#64748b',
|
|
'--template1-danger-icon': '#fda4af',
|
|
'--template1-danger-text': '#fda4af',
|
|
'--template1-shadow': 'rgba(15, 23, 42, 0.58)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-ember',
|
|
title: '엠버',
|
|
category: '색상',
|
|
description: '따뜻한 주황과 카카오 브라운',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#431407',
|
|
'--template1-background-end': '#7c2d12',
|
|
'--template1-surface': '#3b1905',
|
|
'--template1-text': '#fef3c7',
|
|
'--template1-subtext': '#fed7aa',
|
|
'--template1-muted': '#fdba74',
|
|
'--template1-border': 'rgba(180, 83, 9, 0.32)',
|
|
'--template1-topbar-start': 'rgba(59, 25, 5, 0.96)',
|
|
'--template1-topbar-end': 'rgba(124, 45, 18, 0.75)',
|
|
'--template1-topbar-text': '#fef3c7',
|
|
'--template1-badge-bg': '#b45309',
|
|
'--template1-badge-text': '#fef3c7',
|
|
'--template1-button-bg': '#b45309',
|
|
'--template1-button-text': '#fef3c7',
|
|
'--template1-button-hover': 'rgba(217, 119, 6, 0.24)',
|
|
'--template1-settings-bg': '#431407',
|
|
'--template1-settings-border': '#d97706',
|
|
'--template1-card-bg': '#7c2d12',
|
|
'--template1-card-border': '#f59e0b',
|
|
'--template1-card-text': '#fef3c7',
|
|
'--template1-card-subtext': '#fed7aa',
|
|
'--template1-card-icon-bg': '#92400e',
|
|
'--template1-card-action': '#fcd34d',
|
|
'--template1-danger-bg': '#3b1905',
|
|
'--template1-danger-border': '#d97706',
|
|
'--template1-danger-icon': '#fca5a5',
|
|
'--template1-danger-text': '#fca5a5',
|
|
'--template1-shadow': 'rgba(69, 26, 3, 0.52)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-small-text',
|
|
title: '폰트 소형',
|
|
category: '폰트',
|
|
description: '요소 간 간격은 유지, 텍스트만 축소',
|
|
fontScale: 0.88,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '11px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '80px',
|
|
cardIconSize: '36px',
|
|
chipGap: '4px',
|
|
cssVars: TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
},
|
|
{
|
|
id: 'theme-base-text',
|
|
title: '폰트 기본',
|
|
category: '폰트',
|
|
description: '기본 텍스트 스케일 유지',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
},
|
|
{
|
|
id: 'theme-large-text',
|
|
title: '폰트 대형',
|
|
category: '폰트',
|
|
description: '가독성 중심 대형 타이포',
|
|
fontScale: 1.18,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '13px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '86px',
|
|
cardIconSize: '40px',
|
|
chipGap: '4px',
|
|
cssVars: TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
},
|
|
{
|
|
id: 'theme-xsmall-text',
|
|
title: '폰트 초소형',
|
|
category: '폰트',
|
|
description: '많은 항목을 한 화면에 넣고 싶을 때',
|
|
fontScale: 0.75,
|
|
cardColumns: 4,
|
|
homeColumns: 1,
|
|
gap: '10px',
|
|
padding: '12px',
|
|
shellRadius: '18px',
|
|
cardRadius: '14px',
|
|
cardMinHeight: '72px',
|
|
cardIconSize: '30px',
|
|
chipGap: '3px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-grid-template': 'auto 1fr auto',
|
|
'--template1-card-max-height': '86px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-reading-text',
|
|
title: '폰트 리딩',
|
|
category: '폰트',
|
|
description: '긴 문장을 안정적으로 읽기 좋은 배율',
|
|
fontScale: 1.12,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '13px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '20px',
|
|
cardMinHeight: '88px',
|
|
cardIconSize: '40px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-max-height': '122px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-comfort-text',
|
|
title: '폰트 편안',
|
|
category: '폰트',
|
|
description: '장문 콘텐츠 위주의 완만한 가독성',
|
|
fontScale: 1.04,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '86px',
|
|
cardIconSize: '39px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-home-item-padding': '15px',
|
|
'--template1-home-item-padding-inline': '16px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-comfortable-readable-text',
|
|
title: '폰트 라운드',
|
|
category: '폰트',
|
|
description: '긴 문장을 위해 라운드 라벨/여백 강화',
|
|
fontScale: 1.06,
|
|
cardColumns: 3,
|
|
homeColumns: 2,
|
|
gap: '11px',
|
|
padding: '12px',
|
|
shellRadius: '20px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '78px',
|
|
cardIconSize: '35px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-max-height': '112px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-micro-text',
|
|
title: '폰트 마이크로',
|
|
category: '폰트',
|
|
description: '컴팩트한 인터페이스에서 정보 밀도 강화',
|
|
fontScale: 0.84,
|
|
cardColumns: 4,
|
|
homeColumns: 1,
|
|
gap: '9px',
|
|
padding: '11px',
|
|
shellRadius: '16px',
|
|
cardRadius: '14px',
|
|
cardMinHeight: '70px',
|
|
cardIconSize: '30px',
|
|
chipGap: '3px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-max-height': '88px',
|
|
'--template1-card-grid-template': 'auto 1fr auto',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-cursor-text',
|
|
title: '폰트 리듬',
|
|
category: '폰트',
|
|
description: '제목과 본문의 대비를 더 분명하게',
|
|
fontScale: 1.1,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '13px',
|
|
shellRadius: '20px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '86px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-max-height': '118px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-compact-structure',
|
|
title: '구조 컴팩트',
|
|
category: '구조',
|
|
description: '카드 폭은 줄이고 여백을 촘촘히',
|
|
fontScale: 1,
|
|
cardColumns: 2,
|
|
homeColumns: 2,
|
|
gap: '9px',
|
|
padding: '10px',
|
|
shellRadius: '16px',
|
|
cardRadius: '12px',
|
|
cardMinHeight: '72px',
|
|
cardIconSize: '32px',
|
|
chipGap: '3px',
|
|
cssVars: TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
},
|
|
{
|
|
id: 'theme-wide-structure',
|
|
title: '구조 와이드',
|
|
category: '구조',
|
|
description: '큰 카드와 넓은 패딩으로 시인성 강화',
|
|
fontScale: 1,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '14px',
|
|
padding: '16px',
|
|
shellRadius: '26px',
|
|
cardRadius: '20px',
|
|
cardMinHeight: '92px',
|
|
cardIconSize: '42px',
|
|
chipGap: '5px',
|
|
cssVars: TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
},
|
|
{
|
|
id: 'theme-list-structure',
|
|
title: '구조 리스트',
|
|
category: '구조',
|
|
description: '목록형 단일 카드를 우선 노출',
|
|
fontScale: 1,
|
|
cardColumns: 1,
|
|
homeColumns: 1,
|
|
gap: '10px',
|
|
padding: '12px',
|
|
shellRadius: '18px',
|
|
cardRadius: '14px',
|
|
cardMinHeight: '78px',
|
|
cardIconSize: '34px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-bg': '#f8fafc',
|
|
'--template1-card-border': '#cbd5e1',
|
|
'--template1-topbar-text': '#475569',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-focus-structure',
|
|
title: '구조 포커스',
|
|
category: '구조',
|
|
description: '중요 항목의 우선순위를 카드 크기로 표현',
|
|
fontScale: 1,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '96px',
|
|
cardIconSize: '40px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#c7d2fe',
|
|
'--template1-card-action': '#4f46e5',
|
|
'--template1-card-icon-bg': '#e0e7ff',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-dense-grid-structure',
|
|
title: '구조 더블그리드',
|
|
category: '구조',
|
|
description: '카드 수를 급증시키는 촘촘한 4열 배치',
|
|
fontScale: 1,
|
|
cardColumns: 4,
|
|
homeColumns: 2,
|
|
gap: '8px',
|
|
padding: '10px',
|
|
shellRadius: '14px',
|
|
cardRadius: '12px',
|
|
cardMinHeight: '64px',
|
|
cardIconSize: '30px',
|
|
chipGap: '3px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-max-height': '84px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-stagger-structure',
|
|
title: '구조 스태거',
|
|
category: '구조',
|
|
description: '텍스트 길이 우선 배열과 액션 하단 배치',
|
|
fontScale: 1,
|
|
cardColumns: 2,
|
|
homeColumns: 2,
|
|
gap: '12px',
|
|
padding: '12px',
|
|
shellRadius: '20px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '94px',
|
|
cardIconSize: '36px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-grid-template': '1fr',
|
|
'--template1-card-action-column': '1 / -1',
|
|
'--template1-card-action-justify': 'stretch',
|
|
'--template1-card-max-height': '130px',
|
|
'--template1-home-item-layout': 'auto minmax(0, 1fr)',
|
|
'--template1-home-item-gap': '10px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-split-card-structure',
|
|
title: '구조 카드분할',
|
|
category: '구조',
|
|
description: '상세는 크게, 아이콘은 작게 배치',
|
|
fontScale: 1,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '13px',
|
|
padding: '12px',
|
|
shellRadius: '24px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '96px',
|
|
cardIconSize: '42px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-grid-template': 'auto 1fr',
|
|
'--template1-card-action-column': '1 / -1',
|
|
'--template1-card-action-justify': 'flex-end',
|
|
'--template1-home-item-padding': '14px',
|
|
'--template1-home-item-padding-inline': '16px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-stats-column-structure',
|
|
title: '구조 통계열',
|
|
category: '구조',
|
|
description: '항목 수가 많을 때 가독성을 위한 넓은 좌우 여백',
|
|
fontScale: 1,
|
|
cardColumns: 1,
|
|
homeColumns: 2,
|
|
gap: '14px',
|
|
padding: '16px',
|
|
shellRadius: '18px',
|
|
cardRadius: '14px',
|
|
cardMinHeight: '82px',
|
|
cardIconSize: '36px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-grid-template': 'auto 1fr auto',
|
|
'--template1-card-action-column': '3 / 3',
|
|
'--template1-home-item-layout': 'auto minmax(0, 1fr) auto',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-mosaic-structure',
|
|
title: '구조 모자이크',
|
|
category: '구조',
|
|
description: '작은 카드와 넓은 화면에서 분산 배치',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 2,
|
|
gap: '8px',
|
|
padding: '10px',
|
|
shellRadius: '16px',
|
|
cardRadius: '12px',
|
|
cardMinHeight: '68px',
|
|
cardIconSize: '30px',
|
|
chipGap: '3px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-grid-template': 'auto 1fr',
|
|
'--template1-card-action-column': '1 / -1',
|
|
'--template1-card-action-justify': 'start',
|
|
'--template1-card-max-height': '98px',
|
|
'--template1-home-item-layout': 'auto minmax(0, 1fr)',
|
|
'--template1-home-item-gap': '8px',
|
|
'--template1-home-item-padding': '11px',
|
|
'--template1-home-item-padding-inline': '12px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-timeline-structure',
|
|
title: '구조 타임라인',
|
|
category: '구조',
|
|
description: '목록처럼 수직이 강조되는 정렬',
|
|
fontScale: 1,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '13px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '17px',
|
|
cardMinHeight: '90px',
|
|
cardIconSize: '37px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-grid-template': '1fr',
|
|
'--template1-card-action-column': '1 / -1',
|
|
'--template1-card-action-justify': 'flex-start',
|
|
'--template1-card-max-height': '118px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-dashboard-structure',
|
|
title: '구조 대시보드',
|
|
category: '구조',
|
|
description: '카드 간격을 크게 잡아 분석 레이아웃에 최적화',
|
|
fontScale: 1,
|
|
cardColumns: 3,
|
|
homeColumns: 2,
|
|
gap: '10px',
|
|
padding: '12px',
|
|
shellRadius: '20px',
|
|
cardRadius: '14px',
|
|
cardMinHeight: '76px',
|
|
cardIconSize: '33px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-grid-template': 'auto minmax(0, 1.2fr) auto',
|
|
'--template1-card-action-column': '3 / 3',
|
|
'--template1-card-action-justify': 'end',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': '#bfdbfe',
|
|
'--template1-card-max-height': '104px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-kanban-structure',
|
|
title: '구조 칸반',
|
|
category: '구조',
|
|
description: '작업 보드형 배치에서 항목 구분이 뚜렷',
|
|
fontScale: 1,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '12px',
|
|
shellRadius: '22px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '88px',
|
|
cardIconSize: '36px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
...TEMPLATE1_DEFAULT_THEME_VARIABLES,
|
|
'--template1-card-grid-template': 'minmax(0, 1.2fr) auto',
|
|
'--template1-card-action-column': '1 / -1',
|
|
'--template1-card-action-justify': 'stretch',
|
|
'--template1-home-item-layout': 'auto minmax(0, 1fr)',
|
|
'--template1-home-item-gap': '10px',
|
|
'--template1-card-max-height': '124px',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-glass-accent',
|
|
title: '글래스 믹스',
|
|
category: '혼합',
|
|
description: '잔잔한 색상과 폰트 강조를 함께 적용',
|
|
fontScale: 1.06,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '13px',
|
|
padding: '15px',
|
|
shellRadius: '24px',
|
|
cardRadius: '17px',
|
|
cardMinHeight: '86px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#111827',
|
|
'--template1-background-end': '#0b1220',
|
|
'--template1-surface': '#1f2937',
|
|
'--template1-text': '#f8fafc',
|
|
'--template1-subtext': '#cbd5e1',
|
|
'--template1-muted': '#94a3b8',
|
|
'--template1-border': 'rgba(148, 163, 184, 0.36)',
|
|
'--template1-topbar-start': '#334155',
|
|
'--template1-topbar-end': '#1f2937',
|
|
'--template1-topbar-text': '#f8fafc',
|
|
'--template1-badge-bg': 'rgba(148, 163, 184, 0.28)',
|
|
'--template1-badge-text': '#e2e8f0',
|
|
'--template1-button-bg': 'rgba(148, 163, 184, 0.3)',
|
|
'--template1-button-text': '#f8fafc',
|
|
'--template1-button-hover': 'rgba(148, 163, 184, 0.5)',
|
|
'--template1-settings-bg': '#111827',
|
|
'--template1-settings-border': 'rgba(148, 163, 184, 0.5)',
|
|
'--template1-card-bg': '#111827',
|
|
'--template1-card-border': 'rgba(148, 163, 184, 0.42)',
|
|
'--template1-card-text': '#f8fafc',
|
|
'--template1-card-subtext': '#cbd5e1',
|
|
'--template1-card-icon-bg': 'rgba(148, 163, 184, 0.28)',
|
|
'--template1-card-action': '#93c5fd',
|
|
'--template1-danger-bg': 'rgba(220, 38, 38, 0.18)',
|
|
'--template1-danger-border': 'rgba(220, 38, 38, 0.38)',
|
|
'--template1-danger-icon': '#fca5a5',
|
|
'--template1-danger-text': '#fecdd3',
|
|
'--template1-shadow': 'rgba(2, 6, 23, 0.4)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-soft-glass',
|
|
title: '글래스 라이트',
|
|
category: '혼합',
|
|
description: '차분한 블루 톤의 부드러운 글래스 텍스처',
|
|
fontScale: 1.02,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#f8fafc',
|
|
'--template1-background-end': '#dbeafe',
|
|
'--template1-surface': '#eef2ff',
|
|
'--template1-text': '#1e3a8a',
|
|
'--template1-subtext': '#334155',
|
|
'--template1-muted': '#64748b',
|
|
'--template1-border': 'rgba(96, 165, 250, 0.36)',
|
|
'--template1-topbar-start': '#dbeafe',
|
|
'--template1-topbar-end': '#bfdbfe',
|
|
'--template1-topbar-text': '#1e3a8a',
|
|
'--template1-badge-bg': 'rgba(96, 165, 250, 0.2)',
|
|
'--template1-badge-text': '#1d4ed8',
|
|
'--template1-button-bg': 'rgba(96, 165, 250, 0.28)',
|
|
'--template1-button-text': '#1d4ed8',
|
|
'--template1-button-hover': 'rgba(59, 130, 246, 0.25)',
|
|
'--template1-settings-bg': '#eef2ff',
|
|
'--template1-settings-border': 'rgba(96, 165, 250, 0.45)',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': 'rgba(147, 197, 253, 0.6)',
|
|
'--template1-card-text': '#1e3a8a',
|
|
'--template1-card-subtext': '#334155',
|
|
'--template1-card-icon-bg': 'rgba(191, 219, 254, 0.65)',
|
|
'--template1-card-action': '#2563eb',
|
|
'--template1-danger-bg': 'rgba(96, 165, 250, 0.12)',
|
|
'--template1-danger-border': 'rgba(96, 165, 250, 0.45)',
|
|
'--template1-danger-icon': '#1d4ed8',
|
|
'--template1-danger-text': '#1d4ed8',
|
|
'--template1-shadow': 'rgba(30, 58, 138, 0.16)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-glass-ink',
|
|
title: '글래스 인크',
|
|
category: '혼합',
|
|
description: '연한 잉크톤과 다크 텍스트 강조',
|
|
fontScale: 1.02,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#020617',
|
|
'--template1-background-end': '#0f172a',
|
|
'--template1-surface': '#111827',
|
|
'--template1-text': '#e2e8f0',
|
|
'--template1-subtext': '#94a3b8',
|
|
'--template1-muted': '#cbd5e1',
|
|
'--template1-border': 'rgba(148, 163, 184, 0.3)',
|
|
'--template1-topbar-start': '#0b1120',
|
|
'--template1-topbar-end': '#1e293b',
|
|
'--template1-topbar-text': '#e2e8f0',
|
|
'--template1-badge-bg': 'rgba(148, 163, 184, 0.18)',
|
|
'--template1-badge-text': '#e2e8f0',
|
|
'--template1-button-bg': 'rgba(148, 163, 184, 0.2)',
|
|
'--template1-button-text': '#e2e8f0',
|
|
'--template1-button-hover': 'rgba(148, 163, 184, 0.38)',
|
|
'--template1-settings-bg': '#020617',
|
|
'--template1-settings-border': 'rgba(148, 163, 184, 0.34)',
|
|
'--template1-card-bg': '#111827',
|
|
'--template1-card-border': 'rgba(148, 163, 184, 0.4)',
|
|
'--template1-card-text': '#e2e8f0',
|
|
'--template1-card-subtext': '#cbd5e1',
|
|
'--template1-card-icon-bg': 'rgba(148, 163, 184, 0.25)',
|
|
'--template1-card-action': '#93c5fd',
|
|
'--template1-danger-bg': 'rgba(248, 113, 113, 0.16)',
|
|
'--template1-danger-border': 'rgba(248, 113, 113, 0.36)',
|
|
'--template1-danger-icon': '#fca5a5',
|
|
'--template1-danger-text': '#fecdd3',
|
|
'--template1-shadow': 'rgba(2, 6, 23, 0.45)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-sunrise-glow',
|
|
title: '새벽 네온',
|
|
category: '혼합',
|
|
description: '라이트/다크 대비를 넘나드는 글래스 하이라이트',
|
|
fontScale: 1.08,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '13px',
|
|
shellRadius: '24px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '88px',
|
|
cardIconSize: '39px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#0f172a',
|
|
'--template1-background-end': '#1e1b4b',
|
|
'--template1-surface': '#1e293b',
|
|
'--template1-text': '#f8fafc',
|
|
'--template1-subtext': '#93c5fd',
|
|
'--template1-muted': '#c7d2fe',
|
|
'--template1-border': 'rgba(167, 139, 250, 0.34)',
|
|
'--template1-topbar-start': '#1f2937',
|
|
'--template1-topbar-end': '#312e81',
|
|
'--template1-topbar-text': '#f8fafc',
|
|
'--template1-badge-bg': 'rgba(129, 140, 248, 0.22)',
|
|
'--template1-badge-text': '#ddd6fe',
|
|
'--template1-button-bg': 'rgba(129, 140, 248, 0.22)',
|
|
'--template1-button-text': '#ddd6fe',
|
|
'--template1-button-hover': 'rgba(129, 140, 248, 0.32)',
|
|
'--template1-settings-bg': '#0f172a',
|
|
'--template1-settings-border': 'rgba(129, 140, 248, 0.34)',
|
|
'--template1-card-bg': '#1e293b',
|
|
'--template1-card-border': 'rgba(165, 180, 252, 0.42)',
|
|
'--template1-card-text': '#f8fafc',
|
|
'--template1-card-subtext': '#c7d2fe',
|
|
'--template1-card-icon-bg': 'rgba(129, 140, 248, 0.2)',
|
|
'--template1-card-action': '#c4b5fd',
|
|
'--template1-danger-bg': 'rgba(129, 140, 248, 0.15)',
|
|
'--template1-danger-border': 'rgba(129, 140, 248, 0.34)',
|
|
'--template1-danger-icon': '#fda4af',
|
|
'--template1-danger-text': '#fda4af',
|
|
'--template1-shadow': 'rgba(30, 27, 75, 0.45)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-slate-readability',
|
|
title: '슬레이트 가독성',
|
|
category: '혼합',
|
|
description: '차분한 다크톤에 중간 글꼴 스케일을 결합한 실사용형',
|
|
fontScale: 1.01,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '13px',
|
|
padding: '14px',
|
|
shellRadius: '22px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '86px',
|
|
cardIconSize: '37px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#0f172a',
|
|
'--template1-background-end': '#0b1326',
|
|
'--template1-surface': '#1f2937',
|
|
'--template1-text': '#e2e8f0',
|
|
'--template1-subtext': '#94a3b8',
|
|
'--template1-muted': '#cbd5e1',
|
|
'--template1-border': 'rgba(148, 163, 184, 0.36)',
|
|
'--template1-topbar-start': '#1f2937',
|
|
'--template1-topbar-end': '#0f172a',
|
|
'--template1-topbar-text': '#e2e8f0',
|
|
'--template1-badge-bg': 'rgba(148, 163, 184, 0.25)',
|
|
'--template1-badge-text': '#f8fafc',
|
|
'--template1-button-bg': 'rgba(148, 163, 184, 0.24)',
|
|
'--template1-button-text': '#f8fafc',
|
|
'--template1-button-hover': 'rgba(148, 163, 184, 0.45)',
|
|
'--template1-settings-bg': '#111827',
|
|
'--template1-settings-border': 'rgba(148, 163, 184, 0.5)',
|
|
'--template1-card-bg': '#1f2937',
|
|
'--template1-card-border': 'rgba(148, 163, 184, 0.38)',
|
|
'--template1-card-text': '#e2e8f0',
|
|
'--template1-card-subtext': '#cbd5e1',
|
|
'--template1-card-icon-bg': 'rgba(148, 163, 184, 0.22)',
|
|
'--template1-card-action': '#93c5fd',
|
|
'--template1-danger-bg': 'rgba(248, 113, 113, 0.16)',
|
|
'--template1-danger-border': 'rgba(248, 113, 113, 0.36)',
|
|
'--template1-danger-icon': '#fca5a5',
|
|
'--template1-danger-text': '#fecdd3',
|
|
'--template1-shadow': 'rgba(2, 6, 23, 0.44)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-ocean-office',
|
|
title: '오션 오피스',
|
|
category: '혼합',
|
|
description: '차분한 시안 계열에 넓은 카드 텍스트 정렬을 추가한 업무형',
|
|
fontScale: 1.03,
|
|
cardColumns: 2,
|
|
homeColumns: 2,
|
|
gap: '12px',
|
|
padding: '13px',
|
|
shellRadius: '24px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '88px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#e0f2fe',
|
|
'--template1-background-end': '#bae6fd',
|
|
'--template1-surface': '#f1f5f9',
|
|
'--template1-text': '#0f172a',
|
|
'--template1-subtext': '#334155',
|
|
'--template1-muted': '#475569',
|
|
'--template1-border': 'rgba(14, 116, 144, 0.28)',
|
|
'--template1-topbar-start': '#e0f2fe',
|
|
'--template1-topbar-end': '#bae6fd',
|
|
'--template1-topbar-text': '#0c4a6e',
|
|
'--template1-badge-bg': 'rgba(14, 116, 144, 0.22)',
|
|
'--template1-badge-text': '#0c4a6e',
|
|
'--template1-button-bg': 'rgba(14, 116, 144, 0.24)',
|
|
'--template1-button-text': '#0c4a6e',
|
|
'--template1-button-hover': 'rgba(14, 116, 144, 0.3)',
|
|
'--template1-settings-bg': '#f8fafc',
|
|
'--template1-settings-border': 'rgba(14, 116, 144, 0.45)',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': 'rgba(14, 165, 233, 0.35)',
|
|
'--template1-card-text': '#0f172a',
|
|
'--template1-card-subtext': '#334155',
|
|
'--template1-card-icon-bg': 'rgba(14, 165, 233, 0.2)',
|
|
'--template1-card-action': '#0284c7',
|
|
'--template1-danger-bg': 'rgba(14, 116, 144, 0.12)',
|
|
'--template1-danger-border': 'rgba(14, 116, 144, 0.35)',
|
|
'--template1-danger-icon': '#0369a1',
|
|
'--template1-danger-text': '#0369a1',
|
|
'--template1-shadow': 'rgba(14, 116, 144, 0.18)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-sunset-contrast',
|
|
title: '선셋 강세',
|
|
category: '혼합',
|
|
description: '낮은 채도의 주황/네온 대비를 통한 즉시 인지형 구성',
|
|
fontScale: 1.04,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '11px',
|
|
padding: '13px',
|
|
shellRadius: '22px',
|
|
cardRadius: '18px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '37px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#fde68a',
|
|
'--template1-background-end': '#ffedd5',
|
|
'--template1-surface': '#fff7ed',
|
|
'--template1-text': '#7c2d12',
|
|
'--template1-subtext': '#9a3412',
|
|
'--template1-muted': '#c2410c',
|
|
'--template1-border': 'rgba(217, 119, 6, 0.34)',
|
|
'--template1-topbar-start': '#fef3c7',
|
|
'--template1-topbar-end': '#fed7aa',
|
|
'--template1-topbar-text': '#7c2d12',
|
|
'--template1-badge-bg': 'rgba(217, 119, 6, 0.24)',
|
|
'--template1-badge-text': '#7c2d12',
|
|
'--template1-button-bg': 'rgba(217, 119, 6, 0.24)',
|
|
'--template1-button-text': '#7c2d12',
|
|
'--template1-button-hover': 'rgba(217, 119, 6, 0.3)',
|
|
'--template1-settings-bg': '#fef3c7',
|
|
'--template1-settings-border': 'rgba(217, 119, 6, 0.45)',
|
|
'--template1-card-bg': '#fff7ed',
|
|
'--template1-card-border': 'rgba(245, 158, 11, 0.4)',
|
|
'--template1-card-text': '#7c2d12',
|
|
'--template1-card-subtext': '#9a3412',
|
|
'--template1-card-icon-bg': 'rgba(245, 158, 11, 0.24)',
|
|
'--template1-card-action': '#ea580c',
|
|
'--template1-danger-bg': 'rgba(251, 146, 60, 0.18)',
|
|
'--template1-danger-border': 'rgba(251, 146, 60, 0.45)',
|
|
'--template1-danger-icon': '#dc2626',
|
|
'--template1-danger-text': '#dc2626',
|
|
'--template1-shadow': 'rgba(120, 53, 15, 0.24)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-berry-focus',
|
|
title: '베리 포커스',
|
|
category: '혼합',
|
|
description: '강한 보조색과 집중형 가독성을 함께 조율한 구성',
|
|
fontScale: 1.06,
|
|
cardColumns: 2,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '13px',
|
|
shellRadius: '20px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '90px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#111827',
|
|
'--template1-background-end': '#1e1b4b',
|
|
'--template1-surface': '#312e81',
|
|
'--template1-text': '#f8fafc',
|
|
'--template1-subtext': '#c7d2fe',
|
|
'--template1-muted': '#ddd6fe',
|
|
'--template1-border': 'rgba(167, 139, 250, 0.38)',
|
|
'--template1-topbar-start': '#312e81',
|
|
'--template1-topbar-end': '#4c1d95',
|
|
'--template1-topbar-text': '#f5d0fe',
|
|
'--template1-badge-bg': 'rgba(216, 180, 254, 0.24)',
|
|
'--template1-badge-text': '#ddd6fe',
|
|
'--template1-button-bg': 'rgba(216, 180, 254, 0.24)',
|
|
'--template1-button-text': '#ddd6fe',
|
|
'--template1-button-hover': 'rgba(216, 180, 254, 0.32)',
|
|
'--template1-settings-bg': '#312e81',
|
|
'--template1-settings-border': 'rgba(216, 180, 254, 0.35)',
|
|
'--template1-card-bg': '#4338ca',
|
|
'--template1-card-border': 'rgba(216, 180, 254, 0.42)',
|
|
'--template1-card-text': '#f8fafc',
|
|
'--template1-card-subtext': '#ddd6fe',
|
|
'--template1-card-icon-bg': 'rgba(216, 180, 254, 0.2)',
|
|
'--template1-card-action': '#f472b6',
|
|
'--template1-danger-bg': 'rgba(244, 114, 182, 0.2)',
|
|
'--template1-danger-border': 'rgba(244, 114, 182, 0.4)',
|
|
'--template1-danger-icon': '#f9a8d4',
|
|
'--template1-danger-text': '#fce7f3',
|
|
'--template1-shadow': 'rgba(76, 29, 149, 0.33)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-aurora-clean',
|
|
title: '오로라 클래린',
|
|
category: '혼합',
|
|
description: '차가운 블루그레이 베이스에 깔끔한 타이포우선 배치',
|
|
fontScale: 0.98,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '14px',
|
|
shellRadius: '24px',
|
|
cardRadius: '14px',
|
|
cardMinHeight: '82px',
|
|
cardIconSize: '36px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#e2e8f0',
|
|
'--template1-background-end': '#f1f5f9',
|
|
'--template1-surface': '#ffffff',
|
|
'--template1-text': '#1e293b',
|
|
'--template1-subtext': '#334155',
|
|
'--template1-muted': '#475569',
|
|
'--template1-border': 'rgba(71, 85, 105, 0.34)',
|
|
'--template1-topbar-start': '#f8fafc',
|
|
'--template1-topbar-end': '#e2e8f0',
|
|
'--template1-topbar-text': '#0f172a',
|
|
'--template1-badge-bg': 'rgba(148, 163, 184, 0.25)',
|
|
'--template1-badge-text': '#334155',
|
|
'--template1-button-bg': 'rgba(71, 85, 105, 0.24)',
|
|
'--template1-button-text': '#1e293b',
|
|
'--template1-button-hover': 'rgba(71, 85, 105, 0.28)',
|
|
'--template1-settings-bg': '#ffffff',
|
|
'--template1-settings-border': 'rgba(71, 85, 105, 0.4)',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': 'rgba(148, 163, 184, 0.5)',
|
|
'--template1-card-text': '#1e293b',
|
|
'--template1-card-subtext': '#334155',
|
|
'--template1-card-icon-bg': 'rgba(148, 163, 184, 0.25)',
|
|
'--template1-card-action': '#334155',
|
|
'--template1-danger-bg': 'rgba(71, 85, 105, 0.14)',
|
|
'--template1-danger-border': 'rgba(71, 85, 105, 0.4)',
|
|
'--template1-danger-icon': '#475569',
|
|
'--template1-danger-text': '#475569',
|
|
'--template1-shadow': 'rgba(30, 41, 59, 0.2)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-micro-precision',
|
|
title: '마이크로 정밀',
|
|
category: '혼합',
|
|
description: '작고 촘촘한 정보뷰를 위한 고밀도 조합',
|
|
fontScale: 0.92,
|
|
cardColumns: 4,
|
|
homeColumns: 2,
|
|
gap: '9px',
|
|
padding: '11px',
|
|
shellRadius: '18px',
|
|
cardRadius: '12px',
|
|
cardMinHeight: '72px',
|
|
cardIconSize: '28px',
|
|
chipGap: '3px',
|
|
cssVars: {
|
|
'--template1-background-start': '#0f172a',
|
|
'--template1-background-end': '#020617',
|
|
'--template1-surface': '#111827',
|
|
'--template1-text': '#e2e8f0',
|
|
'--template1-subtext': '#94a3b8',
|
|
'--template1-muted': '#cbd5e1',
|
|
'--template1-border': 'rgba(148, 163, 184, 0.32)',
|
|
'--template1-topbar-start': '#1e293b',
|
|
'--template1-topbar-end': '#0f172a',
|
|
'--template1-topbar-text': '#e2e8f0',
|
|
'--template1-badge-bg': 'rgba(148, 163, 184, 0.24)',
|
|
'--template1-badge-text': '#e2e8f0',
|
|
'--template1-button-bg': 'rgba(148, 163, 184, 0.24)',
|
|
'--template1-button-text': '#e2e8f0',
|
|
'--template1-button-hover': 'rgba(148, 163, 184, 0.32)',
|
|
'--template1-settings-bg': '#020617',
|
|
'--template1-settings-border': 'rgba(148, 163, 184, 0.4)',
|
|
'--template1-card-bg': '#0f172a',
|
|
'--template1-card-border': 'rgba(148, 163, 184, 0.4)',
|
|
'--template1-card-text': '#e2e8f0',
|
|
'--template1-card-subtext': '#94a3b8',
|
|
'--template1-card-icon-bg': 'rgba(148, 163, 184, 0.22)',
|
|
'--template1-card-action': '#38bdf8',
|
|
'--template1-danger-bg': 'rgba(59, 130, 246, 0.16)',
|
|
'--template1-danger-border': 'rgba(59, 130, 246, 0.36)',
|
|
'--template1-danger-icon': '#7dd3fc',
|
|
'--template1-danger-text': '#bfdbfe',
|
|
'--template1-shadow': 'rgba(2, 6, 23, 0.45)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-warm-glass',
|
|
title: '웜 글래스',
|
|
category: '혼합',
|
|
description: '따뜻한 톤의 글래스와 중립 텍스트를 조합한 대화형 스타일',
|
|
fontScale: 1.02,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '12px',
|
|
padding: '13px',
|
|
shellRadius: '23px',
|
|
cardRadius: '16px',
|
|
cardMinHeight: '86px',
|
|
cardIconSize: '38px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#ffedd5',
|
|
'--template1-background-end': '#fde68a',
|
|
'--template1-surface': '#fef3c7',
|
|
'--template1-text': '#431407',
|
|
'--template1-subtext': '#9a3412',
|
|
'--template1-muted': '#b45309',
|
|
'--template1-border': 'rgba(217, 119, 6, 0.3)',
|
|
'--template1-topbar-start': '#ffedd5',
|
|
'--template1-topbar-end': '#fde68a',
|
|
'--template1-topbar-text': '#7c2d12',
|
|
'--template1-badge-bg': 'rgba(217, 119, 6, 0.24)',
|
|
'--template1-badge-text': '#7c2d12',
|
|
'--template1-button-bg': 'rgba(217, 119, 6, 0.22)',
|
|
'--template1-button-text': '#7c2d12',
|
|
'--template1-button-hover': 'rgba(217, 119, 6, 0.3)',
|
|
'--template1-settings-bg': '#ffedd5',
|
|
'--template1-settings-border': 'rgba(217, 119, 6, 0.45)',
|
|
'--template1-card-bg': '#fefce8',
|
|
'--template1-card-border': 'rgba(217, 119, 6, 0.5)',
|
|
'--template1-card-text': '#7c2d12',
|
|
'--template1-card-subtext': '#9a3412',
|
|
'--template1-card-icon-bg': 'rgba(217, 119, 6, 0.2)',
|
|
'--template1-card-action': '#ea580c',
|
|
'--template1-danger-bg': 'rgba(249, 115, 22, 0.18)',
|
|
'--template1-danger-border': 'rgba(249, 115, 22, 0.46)',
|
|
'--template1-danger-icon': '#c2410c',
|
|
'--template1-danger-text': '#c2410c',
|
|
'--template1-shadow': 'rgba(120, 53, 15, 0.3)',
|
|
},
|
|
},
|
|
{
|
|
id: 'theme-citrus-minimal',
|
|
title: '시트러스 미니멀',
|
|
category: '혼합',
|
|
description: '밝은 크림베이스에 선명 텍스트 스케일로 정돈한 조합',
|
|
fontScale: 0.99,
|
|
cardColumns: 3,
|
|
homeColumns: 1,
|
|
gap: '11px',
|
|
padding: '12px',
|
|
shellRadius: '21px',
|
|
cardRadius: '15px',
|
|
cardMinHeight: '84px',
|
|
cardIconSize: '35px',
|
|
chipGap: '4px',
|
|
cssVars: {
|
|
'--template1-background-start': '#fffbeb',
|
|
'--template1-background-end': '#fef3c7',
|
|
'--template1-surface': '#fffbeb',
|
|
'--template1-text': '#3f3f46',
|
|
'--template1-subtext': '#44403c',
|
|
'--template1-muted': '#57534e',
|
|
'--template1-border': 'rgba(180, 83, 9, 0.25)',
|
|
'--template1-topbar-start': '#fff7ed',
|
|
'--template1-topbar-end': '#fde68a',
|
|
'--template1-topbar-text': '#7c2d12',
|
|
'--template1-badge-bg': 'rgba(180, 83, 9, 0.18)',
|
|
'--template1-badge-text': '#7c2d12',
|
|
'--template1-button-bg': 'rgba(180, 83, 9, 0.2)',
|
|
'--template1-button-text': '#7c2d12',
|
|
'--template1-button-hover': 'rgba(180, 83, 9, 0.28)',
|
|
'--template1-settings-bg': '#fffbeb',
|
|
'--template1-settings-border': 'rgba(180, 83, 9, 0.35)',
|
|
'--template1-card-bg': '#ffffff',
|
|
'--template1-card-border': 'rgba(180, 83, 9, 0.38)',
|
|
'--template1-card-text': '#3f3f46',
|
|
'--template1-card-subtext': '#57534e',
|
|
'--template1-card-icon-bg': 'rgba(245, 158, 11, 0.2)',
|
|
'--template1-card-action': '#ca8a04',
|
|
'--template1-danger-bg': 'rgba(146, 64, 14, 0.12)',
|
|
'--template1-danger-border': 'rgba(146, 64, 14, 0.35)',
|
|
'--template1-danger-icon': '#a16207',
|
|
'--template1-danger-text': '#a16207',
|
|
'--template1-shadow': 'rgba(120, 53, 15, 0.22)',
|
|
},
|
|
},
|
|
];
|
|
|
|
const THEME_PRESET_BY_ID = Object.fromEntries(THEME_PRESETS.map((item) => [item.id, item]));
|
|
const THEME_LAYOUT_PATTERN: Record<Template1ThemeId, Template1LayoutPattern> = {
|
|
'theme-default': 'mosaic',
|
|
'theme-sky': 'mosaic',
|
|
'theme-citrus': 'mosaic',
|
|
'theme-forest': 'mosaic',
|
|
'theme-violet': 'mosaic',
|
|
'theme-graphite': 'mosaic',
|
|
'theme-sunset': 'mosaic',
|
|
'theme-coral': 'mosaic',
|
|
'theme-olive': 'mosaic',
|
|
'theme-mint': 'mosaic',
|
|
'theme-ocean': 'mosaic',
|
|
'theme-berry': 'mosaic',
|
|
'theme-choco': 'mosaic',
|
|
'theme-aurora': 'mosaic',
|
|
'theme-electric': 'mosaic',
|
|
'theme-tide': 'mosaic',
|
|
'theme-peach-night': 'mosaic',
|
|
'theme-graphite-cool': 'mosaic',
|
|
'theme-ember': 'mosaic',
|
|
'theme-small-text': 'mosaic',
|
|
'theme-base-text': 'mosaic',
|
|
'theme-large-text': 'mosaic',
|
|
'theme-xsmall-text': 'mosaic',
|
|
'theme-reading-text': 'mosaic',
|
|
'theme-comfort-text': 'mosaic',
|
|
'theme-comfortable-readable-text': 'mosaic',
|
|
'theme-micro-text': 'mosaic',
|
|
'theme-cursor-text': 'mosaic',
|
|
'theme-compact-structure': 'compact',
|
|
'theme-wide-structure': 'wide',
|
|
'theme-list-structure': 'list',
|
|
'theme-focus-structure': 'focus',
|
|
'theme-dense-grid-structure': 'dense-grid',
|
|
'theme-stagger-structure': 'stagger',
|
|
'theme-split-card-structure': 'split',
|
|
'theme-stats-column-structure': 'stats',
|
|
'theme-mosaic-structure': 'mosaic',
|
|
'theme-timeline-structure': 'timeline',
|
|
'theme-dashboard-structure': 'dashboard',
|
|
'theme-kanban-structure': 'kanban',
|
|
'theme-glass-accent': 'mosaic',
|
|
'theme-soft-glass': 'mosaic',
|
|
'theme-glass-ink': 'mosaic',
|
|
'theme-sunrise-glow': 'mosaic',
|
|
'theme-slate-readability': 'mosaic',
|
|
'theme-ocean-office': 'dashboard',
|
|
'theme-sunset-contrast': 'split',
|
|
'theme-berry-focus': 'kanban',
|
|
'theme-aurora-clean': 'mosaic',
|
|
'theme-micro-precision': 'dense-grid',
|
|
'theme-warm-glass': 'wide',
|
|
'theme-citrus-minimal': 'compact',
|
|
};
|
|
|
|
const THEME_LAYOUT_VISUALS: Record<Template1LayoutPattern, Template1LayoutVisual> = {
|
|
compact: { label: '테이블형(저패딩)', kind: 'table-tight', tileCount: 8 },
|
|
wide: { label: '카드형(저패딩)', kind: 'table-card', tileCount: 6 },
|
|
list: { label: '리스트형', kind: 'list', tileCount: 4 },
|
|
focus: { label: '포커스형', kind: 'focus', tileCount: 6 },
|
|
'dense-grid': { label: '바둑판형', kind: 'chess', tileCount: 12 },
|
|
stagger: { label: '스태거형', kind: 'stagger', tileCount: 8 },
|
|
split: { label: '분할형', kind: 'split', tileCount: 10 },
|
|
stats: { label: '통계형', kind: 'split', tileCount: 9 },
|
|
mosaic: { label: '바둑판형', kind: 'chess', tileCount: 14 },
|
|
timeline: { label: '타임라인형', kind: 'timeline', tileCount: 7 },
|
|
dashboard: { label: '대시보드형', kind: 'board', tileCount: 10 },
|
|
kanban: { label: '칸반형', kind: 'board', tileCount: 8 },
|
|
};
|
|
|
|
const THEME_CATEGORIES: Template1ThemeCategory[] = ['색상', '폰트', '혼합'];
|
|
const THEME_TAB_CLASS_BY_CATEGORY: Record<Template1ThemeCategory, Template1ThemePanelClass> = {
|
|
색상: 'color',
|
|
폰트: 'font',
|
|
구조: 'layout',
|
|
혼합: 'mix',
|
|
};
|
|
const THEME_CATEGORY_BY_ID = Object.fromEntries(THEME_PRESETS.map((theme) => [theme.id, theme.category])) as Record<
|
|
Template1ThemeId,
|
|
Template1ThemeCategory
|
|
>;
|
|
const THEME_WINDOW_DRAG_PADDING = 8;
|
|
const THEME_WINDOW_HALF_SIZE = {
|
|
width: 272,
|
|
height: 302,
|
|
};
|
|
|
|
const SETTINGS: Template1MenuItem[] = [
|
|
{
|
|
title: '테마',
|
|
description: '배경/카드 스타일을 선택',
|
|
icon: <AppstoreOutlined />,
|
|
actionType: 'local',
|
|
settingAction: 'theme',
|
|
},
|
|
{
|
|
title: '알림',
|
|
description: '알림 영역 설정 진입점',
|
|
icon: <BellOutlined />,
|
|
actionType: 'local',
|
|
settingAction: 'notifications',
|
|
},
|
|
{
|
|
title: '상태 초기화',
|
|
description: '현재 화면을 홈 상태로 복원',
|
|
icon: <CheckCircleOutlined />,
|
|
actionType: 'local',
|
|
settingAction: 'reset-state',
|
|
},
|
|
{
|
|
title: '앱 종료',
|
|
description: '설정을 닫고 앱 화면을 종료합니다.',
|
|
icon: <LogoutOutlined />,
|
|
actionType: 'exit',
|
|
},
|
|
];
|
|
|
|
const THEME_STYLE_KEY = '--template1-background-start';
|
|
const DEFAULT_THEME_ID: Template1ThemeId = 'theme-default';
|
|
|
|
const TEMPLATE1_SECTIONS: Template1Section[] = [
|
|
{
|
|
id: 'home',
|
|
label: '홈',
|
|
description: '빠른 네비게이션으로 주요 기능으로 이동',
|
|
chips: ['요약', '최근 작업', '바로가기'],
|
|
},
|
|
{
|
|
id: 'projects',
|
|
label: '작업',
|
|
description: '프로젝트 관리나 문맥 전환 진입점',
|
|
chips: ['레이아웃', '요청', '검수'],
|
|
},
|
|
{
|
|
id: 'resources',
|
|
label: '리소스',
|
|
description: '문서/데이터/관리 화면 모음',
|
|
chips: ['문서', '리소스', '로그'],
|
|
},
|
|
{
|
|
id: 'automation',
|
|
label: '자동화',
|
|
description: '자동화와 상태 확인 흐름',
|
|
chips: ['플랜', '체크리스트', '실행 이력'],
|
|
},
|
|
];
|
|
|
|
const TEMPLATE1_MENUS: Record<Template1SectionId, Template1MenuItem[]> = {
|
|
home: [
|
|
{
|
|
title: '오늘 개요',
|
|
description: '최근 작업 수와 진행 상태를 한 화면에서 확인',
|
|
icon: <CompassOutlined />,
|
|
screen: 'home',
|
|
actionLabel: '열기',
|
|
actionType: 'navigate',
|
|
},
|
|
{
|
|
title: '요청 보드',
|
|
description: '채팅/플랜 타입의 빠른 이동',
|
|
icon: <ThunderboltOutlined />,
|
|
screen: 'projects',
|
|
actionLabel: '이동',
|
|
actionType: 'navigate',
|
|
},
|
|
{
|
|
title: '앱 바코드',
|
|
description: '새 앱 연결 전에 기본 레이아웃 점검',
|
|
icon: <AppstoreAddOutlined />,
|
|
screen: 'projects',
|
|
actionLabel: '확인',
|
|
actionType: 'navigate',
|
|
},
|
|
],
|
|
projects: [
|
|
{
|
|
title: 'Layout Editor',
|
|
description: '레이아웃 편집 흐름 컴포넌트',
|
|
icon: <CompassOutlined />,
|
|
screen: 'projects',
|
|
actionLabel: '열기',
|
|
actionType: 'navigate',
|
|
},
|
|
{
|
|
title: 'Layout Draw',
|
|
description: '컴포넌트 샘플 배치 화면',
|
|
icon: <ThunderboltOutlined />,
|
|
screen: 'projects',
|
|
actionLabel: '열기',
|
|
actionType: 'navigate',
|
|
},
|
|
{
|
|
title: '저장된 레이아웃',
|
|
description: '저장 기록과 재열기 진입점',
|
|
icon: <CheckCircleOutlined />,
|
|
screen: 'projects',
|
|
actionLabel: '열기',
|
|
actionType: 'navigate',
|
|
},
|
|
],
|
|
resources: [
|
|
{
|
|
title: '문서',
|
|
description: '문서 목록과 상세 진입 구성',
|
|
icon: <CompassOutlined />,
|
|
screen: 'resources',
|
|
actionLabel: '열기',
|
|
actionType: 'navigate',
|
|
},
|
|
{
|
|
title: '리소스 관리',
|
|
description: '공유 리소스 목록과 승인 상태',
|
|
icon: <AppstoreAddOutlined />,
|
|
screen: 'resources',
|
|
actionLabel: '열기',
|
|
actionType: 'navigate',
|
|
},
|
|
{
|
|
title: '활동 로그',
|
|
description: '최근 변경 이력 요약',
|
|
icon: <BellOutlined />,
|
|
screen: 'automation',
|
|
actionLabel: '열기',
|
|
actionType: 'navigate',
|
|
},
|
|
],
|
|
automation: [
|
|
{
|
|
title: '자동화',
|
|
description: 'Plan/작업 진행 목록',
|
|
icon: <AppstoreAddOutlined />,
|
|
screen: 'automation',
|
|
actionLabel: '열기',
|
|
actionType: 'navigate',
|
|
},
|
|
{
|
|
title: '체크리스트',
|
|
description: '요청 단계 추적',
|
|
icon: <CheckCircleOutlined />,
|
|
screen: 'automation',
|
|
actionLabel: '확인',
|
|
actionType: 'navigate',
|
|
},
|
|
{
|
|
title: '에러 로그',
|
|
description: '실패/경고 대응 화면',
|
|
icon: <CloseOutlined />,
|
|
screen: 'automation',
|
|
actionLabel: '확인',
|
|
actionType: 'navigate',
|
|
},
|
|
],
|
|
};
|
|
|
|
type Template1ActiveScreen = Template1SectionId;
|
|
|
|
type ThemeWindowPosition = {
|
|
left: number;
|
|
top: number;
|
|
};
|
|
|
|
type Template1HomeScreenProps = {
|
|
items: Pick<Template1MenuItem, 'title' | 'description' | 'icon' | 'actionLabel'> & {
|
|
chips: string[];
|
|
screen: Template1SectionId;
|
|
}[];
|
|
onItemSelect: (item: Template1MenuItem) => void;
|
|
};
|
|
|
|
type Template1SectionScreenProps = {
|
|
title: string;
|
|
chips: string[];
|
|
cards: Template1MenuItem[];
|
|
onItemSelect: (item: Template1MenuItem) => void;
|
|
};
|
|
|
|
function Template1HomeScreen({ items, onItemSelect }: Template1HomeScreenProps) {
|
|
return (
|
|
<>
|
|
<header className="template1-app__section-head">
|
|
<h2>콘텐츠 목록</h2>
|
|
</header>
|
|
<div className="template1-app__home-list" aria-label="콘텐츠 목록">
|
|
{items.map((item) => (
|
|
<button
|
|
type="button"
|
|
key={item.title}
|
|
className="template1-app__home-item"
|
|
onClick={() => onItemSelect({ ...item, screen: item.screen, actionType: 'navigate' })}
|
|
>
|
|
<span className="template1-app__card-icon">{item.icon}</span>
|
|
<div>
|
|
<strong>{item.title}</strong>
|
|
<span>{item.description}</span>
|
|
<small>{item.chips.join(' · ')}</small>
|
|
</div>
|
|
<span className="template1-app__card-action">{item.actionLabel ?? '열기'}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function Template1SectionScreen({ title, chips, cards, onItemSelect }: Template1SectionScreenProps) {
|
|
return (
|
|
<>
|
|
<div className="template1-app__chips-text">{chips.join(' · ')}</div>
|
|
<div className="template1-app__cards" aria-label={title}>
|
|
<div className="template1-app__title-row">
|
|
<h2>{title}</h2>
|
|
</div>
|
|
{cards.map((item) => (
|
|
<button
|
|
type="button"
|
|
key={item.title}
|
|
className="template1-app__card"
|
|
onClick={() => onItemSelect(item)}
|
|
>
|
|
<span className="template1-app__card-icon">{item.icon}</span>
|
|
<div>
|
|
<strong>{item.title}</strong>
|
|
<span>{item.description}</span>
|
|
</div>
|
|
<span className="template1-app__card-action">{item.actionLabel ?? '열기'}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function Template1SettingsDropdown({
|
|
onItemSelect,
|
|
onThemeOpen,
|
|
}: {
|
|
onItemSelect: (item: Template1MenuItem) => void;
|
|
onThemeOpen: () => void;
|
|
}) {
|
|
return (
|
|
<div className="template1-app__settings-dropdown" role="menu" aria-label="설정 메뉴">
|
|
<div className="template1-app__settings-list">
|
|
{SETTINGS.map((item) => (
|
|
<button
|
|
type="button"
|
|
key={item.title}
|
|
className={`template1-app__settings-item${item.actionType === 'exit' ? ' template1-app__settings-item--danger' : ''}`}
|
|
onClick={() => {
|
|
if (item.settingAction === 'theme') {
|
|
onThemeOpen();
|
|
return;
|
|
}
|
|
onItemSelect(item);
|
|
}}
|
|
>
|
|
<span
|
|
className={`template1-app__card-icon template1-app__settings-item-icon${item.actionType === 'exit' ? ' template1-app__settings-item-icon--danger' : ''}`}
|
|
>
|
|
{item.icon}
|
|
</span>
|
|
<div className="template1-app__settings-item-content">
|
|
<strong>{item.title}</strong>
|
|
<span
|
|
className={item.actionType === 'exit' ? 'template1-app__settings-item-description--muted' : undefined}
|
|
>
|
|
{item.description}
|
|
</span>
|
|
</div>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function Template1ThemeSettingsPanel({
|
|
activeThemeId,
|
|
onClose,
|
|
onThemeSelect,
|
|
onWindowMoveStart,
|
|
style,
|
|
isDragging,
|
|
}: {
|
|
activeThemeId: Template1ThemeId;
|
|
onClose: () => void;
|
|
onThemeSelect: (themeId: Template1ThemeId) => void;
|
|
onWindowMoveStart: (event: ReactPointerEvent<HTMLDivElement>) => void;
|
|
style: CSSProperties;
|
|
isDragging: boolean;
|
|
}) {
|
|
const activeThemeCategory = THEME_CATEGORY_BY_ID[activeThemeId] ?? '색상';
|
|
const [activeTab, setActiveTab] = useState<Template1ThemeCategory>(
|
|
THEME_CATEGORIES.includes(activeThemeCategory) ? activeThemeCategory : '색상',
|
|
);
|
|
const [themePage, setThemePage] = useState(0);
|
|
useEffect(() => {
|
|
setActiveTab(THEME_CATEGORIES.includes(activeThemeCategory) ? activeThemeCategory : '색상');
|
|
setThemePage(0);
|
|
}, [activeThemeCategory]);
|
|
useEffect(() => {
|
|
setThemePage(0);
|
|
}, [activeTab]);
|
|
|
|
const renderThemePreview = (tabClass: Template1ThemePanelClass, theme: Template1ThemePreset) => {
|
|
if (tabClass === 'font') {
|
|
return (
|
|
<span className="template1-app__theme-item-preview__font" style={{ color: theme.cssVars['--template1-card-text'] }}>
|
|
<span
|
|
className="template1-app__theme-item-preview__font-glyph"
|
|
style={{ fontSize: `${Math.max(12, Math.round(16 * theme.fontScale))}px` }}
|
|
>
|
|
Aa
|
|
</span>
|
|
<span className="template1-app__theme-item-preview__font-line" />
|
|
</span>
|
|
);
|
|
}
|
|
|
|
if (tabClass === 'layout') {
|
|
const layoutPattern = THEME_LAYOUT_PATTERN[theme.id];
|
|
const layoutVisual = THEME_LAYOUT_VISUALS[layoutPattern];
|
|
|
|
return (
|
|
<span className="template1-app__theme-item-preview__layout-shell">
|
|
<span className="template1-app__theme-item-preview__layout-shell-title">
|
|
구조 방식: {layoutVisual.label}
|
|
</span>
|
|
<span
|
|
className={`template1-app__theme-item-preview__layout template1-app__theme-item-preview__layout--${layoutVisual.kind}`}
|
|
aria-label={`${layoutVisual.label} 미리보기`}
|
|
>
|
|
{Array.from({ length: layoutVisual.tileCount }, (_, index) => (
|
|
<span
|
|
key={`${theme.id}-${index}`}
|
|
className="template1-app__theme-item-preview__layout-tile"
|
|
/>
|
|
))}
|
|
</span>
|
|
<span className="template1-app__theme-item-preview__text-row">
|
|
<span>카드열: {theme.cardColumns}</span>
|
|
<span>홈열: {theme.homeColumns}</span>
|
|
<span>여백: {theme.gap}</span>
|
|
<span>패딩: {theme.padding}</span>
|
|
</span>
|
|
</span>
|
|
);
|
|
}
|
|
|
|
if (tabClass === 'mix') {
|
|
const mixColor = theme.cssVars['--template1-background-start'];
|
|
const mixSurface = theme.cssVars['--template1-surface'];
|
|
const mixAction = theme.cssVars['--template1-card-action'];
|
|
const mixText = theme.cssVars['--template1-card-text'];
|
|
return (
|
|
<span className="template1-app__theme-item-preview__mix-combo">
|
|
<span className="template1-app__theme-item-preview__mix-colors" aria-hidden="true">
|
|
<span
|
|
className="template1-app__theme-item-preview__mix-swatch template1-app__theme-item-preview__mix-swatch--start"
|
|
style={{ background: mixColor, borderColor: theme.cssVars['--template1-card-border'] }}
|
|
/>
|
|
<span
|
|
className="template1-app__theme-item-preview__mix-swatch template1-app__theme-item-preview__mix-swatch--surface"
|
|
style={{ background: mixSurface, borderColor: theme.cssVars['--template1-card-border'] }}
|
|
/>
|
|
<span
|
|
className="template1-app__theme-item-preview__mix-swatch template1-app__theme-item-preview__mix-swatch--action"
|
|
style={{ background: mixAction, borderColor: theme.cssVars['--template1-card-border'] }}
|
|
/>
|
|
</span>
|
|
<span className="template1-app__theme-item-preview__text-card">
|
|
<span className="template1-app__theme-item-preview__text-title" style={{ color: mixText }}>
|
|
혼합 구성
|
|
</span>
|
|
<span className="template1-app__theme-item-preview__text-row">
|
|
<span>글자: {Math.round(theme.fontScale * 100)}%</span>
|
|
<span>아이콘: {theme.cardIconSize}</span>
|
|
</span>
|
|
<span className="template1-app__theme-item-preview__text-row">
|
|
<span>컬러: {theme.title.includes('글래스') ? '글래스' : '강조형'}</span>
|
|
<span>칩 간격: {theme.chipGap}</span>
|
|
</span>
|
|
</span>
|
|
</span>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<span className="template1-app__theme-item-preview--color">
|
|
<span className="template1-app__theme-item-preview__swatch">
|
|
<span
|
|
className="template1-app__theme-item-preview__swatch-main"
|
|
style={{ background: theme.cssVars[THEME_STYLE_KEY], borderColor: theme.cssVars['--template1-card-border'] }}
|
|
/>
|
|
<span style={{ background: theme.cssVars['--template1-card-action'], opacity: 0.8 }} />
|
|
<span style={{ background: theme.cssVars['--template1-card-text'], opacity: 0.25 }} />
|
|
</span>
|
|
</span>
|
|
);
|
|
};
|
|
|
|
const groupedThemes = useMemo(() => {
|
|
const map: Record<Template1ThemeCategory, Template1ThemePreset[]> = {
|
|
색상: [],
|
|
폰트: [],
|
|
구조: [],
|
|
혼합: [],
|
|
};
|
|
|
|
THEME_PRESETS.forEach((theme) => {
|
|
map[theme.category].push(theme);
|
|
});
|
|
|
|
return map;
|
|
}, []);
|
|
const activeThemes = groupedThemes[activeTab];
|
|
const activeTabClass = THEME_TAB_CLASS_BY_CATEGORY[activeTab];
|
|
const isPagingTab = activeTab === '혼합';
|
|
const themePageSize = isPagingTab ? 1 : activeThemes.length;
|
|
const themePageCount = Math.max(1, Math.ceil(activeThemes.length / themePageSize));
|
|
const clampThemePage = Math.min(themePage, themePageCount - 1);
|
|
const safeThemePage = clampThemePage < 0 ? 0 : clampThemePage;
|
|
const visibleThemes = isPagingTab
|
|
? activeThemes.slice(safeThemePage * themePageSize, (safeThemePage + 1) * themePageSize)
|
|
: activeThemes;
|
|
const canPrevThemePage = isPagingTab && safeThemePage > 0;
|
|
const canNextThemePage = isPagingTab && safeThemePage < themePageCount - 1;
|
|
|
|
return (
|
|
<section
|
|
className={`template1-app__theme-window${isDragging ? ' template1-app__theme-window--dragging' : ''}`}
|
|
role="region"
|
|
aria-label="테마 설정 창"
|
|
style={style}
|
|
>
|
|
<header
|
|
className="template1-app__theme-window-head"
|
|
onPointerDown={onWindowMoveStart}
|
|
>
|
|
<div className="template1-app__theme-window-title">
|
|
<p>테마</p>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
className="template1-app__theme-window-close"
|
|
aria-label="테마 창 닫기"
|
|
onClick={onClose}
|
|
>
|
|
<CloseOutlined />
|
|
</button>
|
|
</header>
|
|
<div className="template1-app__theme-page">
|
|
<div
|
|
className="template1-app__theme-tabs"
|
|
role="tablist"
|
|
aria-label="테마 그룹"
|
|
>
|
|
{THEME_CATEGORIES.map((category) => (
|
|
<button
|
|
key={category}
|
|
type="button"
|
|
role="tab"
|
|
aria-selected={activeTab === category}
|
|
className={`template1-app__theme-tab${activeTab === category ? ' template1-app__theme-tab--active' : ''}`}
|
|
onClick={() => setActiveTab(category)}
|
|
>
|
|
{category}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
<div className={`template1-app__theme-page-body template1-app__theme-page-body--${activeTabClass}`}>
|
|
{visibleThemes.map((theme, index) => {
|
|
const isActive = theme.id === activeThemeId;
|
|
const tabClass = activeTabClass;
|
|
const tabBadge = activeTab === '폰트'
|
|
? `${Math.round(theme.fontScale * 100)}%`
|
|
: activeTab === '혼합'
|
|
? '구성형'
|
|
: '톤';
|
|
const tabSummary = activeTab === '혼합'
|
|
? `${theme.title} / 폰트 ${Math.round(theme.fontScale * 100)}%`
|
|
: '';
|
|
const tabDescription = activeTab === '색상' || activeTab === '폰트' || activeTab === '혼합' ? theme.description : '';
|
|
|
|
return (
|
|
<button
|
|
key={theme.id}
|
|
type="button"
|
|
aria-pressed={isActive}
|
|
className={`template1-app__theme-item${isActive ? ' template1-app__theme-item--active' : ''} template1-app__theme-item--${THEME_TAB_CLASS_BY_CATEGORY[activeTab]}`}
|
|
onClick={() => onThemeSelect(theme.id)}
|
|
>
|
|
<span className={`template1-app__theme-item-preview template1-app__theme-item-preview--${tabClass}`}>
|
|
{renderThemePreview(tabClass, theme)}
|
|
</span>
|
|
<span className={`template1-app__theme-info template1-app__theme-info--${tabClass}`}>
|
|
<strong title={theme.description}>{theme.title}</strong>
|
|
{tabSummary ? <span className="template1-app__theme-item-summary">{tabSummary}</span> : null}
|
|
{tabDescription ? <span className="template1-app__theme-info-desc">{tabDescription}</span> : null}
|
|
<span className="template1-app__theme-info-chip">
|
|
<em>{tabBadge}</em>
|
|
{isActive ? (
|
|
<span className="template1-app__theme-active-check">
|
|
<CheckCircleOutlined />
|
|
적용
|
|
</span>
|
|
) : null}
|
|
</span>
|
|
</span>
|
|
</button>
|
|
);
|
|
})}
|
|
{isPagingTab && themePageCount > 1 ? (
|
|
<div className="template1-app__theme-pager">
|
|
<button
|
|
type="button"
|
|
className="template1-app__theme-pager-btn"
|
|
onClick={() => setThemePage((value) => Math.max(0, value - 1))}
|
|
disabled={!canPrevThemePage}
|
|
>
|
|
<LeftOutlined />
|
|
이전
|
|
</button>
|
|
<span className="template1-app__theme-pager-label">
|
|
{safeThemePage + 1} / {themePageCount}
|
|
</span>
|
|
<button
|
|
type="button"
|
|
className="template1-app__theme-pager-btn"
|
|
onClick={() => setThemePage((value) => Math.min(themePageCount - 1, value + 1))}
|
|
disabled={!canNextThemePage}
|
|
>
|
|
다음
|
|
<RightOutlined />
|
|
</button>
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
function buildThemeStyle(theme: Template1ThemePreset): CSSProperties {
|
|
return {
|
|
'--template1-font-scale': `${theme.fontScale}`,
|
|
'--template1-card-columns': `${theme.cardColumns}`,
|
|
'--template1-home-columns': `${theme.homeColumns}`,
|
|
'--template1-gap': theme.gap,
|
|
'--template1-padding': theme.padding,
|
|
'--template1-shell-radius': theme.shellRadius,
|
|
'--template1-card-radius': theme.cardRadius,
|
|
'--template1-card-min-height': theme.cardMinHeight,
|
|
'--template1-card-icon-size': theme.cardIconSize,
|
|
'--template1-chip-gap': theme.chipGap,
|
|
...theme.cssVars,
|
|
} as CSSProperties;
|
|
}
|
|
|
|
export function Template1PlayAppView({ onBack, launchContext = 'direct' }: Template1PlayAppViewProps) {
|
|
const [activeScreen, setActiveScreen] = useState<Template1ActiveScreen>('home');
|
|
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
|
|
const [activeThemeId, setActiveThemeId] = useState<Template1ThemeId>(DEFAULT_THEME_ID);
|
|
const [isThemeWindowOpen, setIsThemeWindowOpen] = useState(false);
|
|
const [themeWindowPos, setThemeWindowPos] = useState<ThemeWindowPosition>({ left: 40, top: 88 });
|
|
const [themeWindowDragStart, setThemeWindowDragStart] = useState({ x: 0, y: 0 });
|
|
const [isThemeWindowDragging, setIsThemeWindowDragging] = useState(false);
|
|
void launchContext;
|
|
|
|
const activeSectionItem = useMemo(
|
|
() => TEMPLATE1_SECTIONS.find((item) => item.id === activeScreen) ?? TEMPLATE1_SECTIONS[0],
|
|
[activeScreen],
|
|
);
|
|
|
|
const menuItems = TEMPLATE1_MENUS[activeScreen] ?? [];
|
|
|
|
const homeMenuItems = useMemo(
|
|
() =>
|
|
TEMPLATE1_SECTIONS.filter((item) => item.id !== 'home')
|
|
.map((item) => ({
|
|
title: item.label,
|
|
description: item.description,
|
|
icon:
|
|
item.id === 'projects' ? <ThunderboltOutlined /> :
|
|
item.id === 'resources' ? <AppstoreAddOutlined /> :
|
|
<BellOutlined />,
|
|
screen: item.id,
|
|
actionLabel: '열기',
|
|
chips: item.chips,
|
|
actionType: 'navigate',
|
|
})),
|
|
[],
|
|
);
|
|
|
|
const goSection = (section: Template1SectionId) => {
|
|
setActiveScreen(section);
|
|
setIsThemeWindowOpen(false);
|
|
setIsSettingsOpen(false);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!isThemeWindowDragging) {
|
|
return;
|
|
}
|
|
|
|
const stopWindowDrag = () => setIsThemeWindowDragging(false);
|
|
|
|
const moveWindow = (event: PointerEvent) => {
|
|
const nextLeft = event.clientX - themeWindowDragStart.x;
|
|
const nextTop = event.clientY - themeWindowDragStart.y;
|
|
const dragAreaWidth = Math.max(120, window.innerWidth - 20);
|
|
const dragAreaHeight = Math.max(120, window.innerHeight - 20);
|
|
const windowWidth = Math.min(THEME_WINDOW_HALF_SIZE.width, dragAreaWidth);
|
|
const windowHeight = Math.min(THEME_WINDOW_HALF_SIZE.height, dragAreaHeight);
|
|
const maxLeft = Math.max(THEME_WINDOW_DRAG_PADDING, window.innerWidth - windowWidth - THEME_WINDOW_DRAG_PADDING);
|
|
const maxTop = Math.max(THEME_WINDOW_DRAG_PADDING, window.innerHeight - windowHeight - THEME_WINDOW_DRAG_PADDING);
|
|
|
|
setThemeWindowPos({
|
|
left: Math.max(THEME_WINDOW_DRAG_PADDING, Math.min(nextLeft, maxLeft)),
|
|
top: Math.max(THEME_WINDOW_DRAG_PADDING, Math.min(nextTop, maxTop)),
|
|
});
|
|
};
|
|
|
|
window.addEventListener('pointermove', moveWindow);
|
|
window.addEventListener('pointerup', stopWindowDrag);
|
|
return () => {
|
|
window.removeEventListener('pointermove', moveWindow);
|
|
window.removeEventListener('pointerup', stopWindowDrag);
|
|
};
|
|
}, [isThemeWindowDragging, themeWindowDragStart]);
|
|
|
|
const goThemeScreen = () => {
|
|
setIsThemeWindowOpen(true);
|
|
setIsSettingsOpen(false);
|
|
};
|
|
|
|
const closeThemeWindow = () => {
|
|
setIsThemeWindowOpen(false);
|
|
};
|
|
|
|
const openItem = (item: Template1MenuItem) => {
|
|
if (item.actionType === 'exit') {
|
|
onBack();
|
|
setIsSettingsOpen(false);
|
|
return;
|
|
}
|
|
|
|
if (item.settingAction === 'reset-state') {
|
|
goSection('home');
|
|
setIsSettingsOpen(false);
|
|
return;
|
|
}
|
|
|
|
if (item.actionType === 'local') {
|
|
if (item.settingAction === 'theme') {
|
|
goThemeScreen();
|
|
return;
|
|
}
|
|
|
|
setIsSettingsOpen(false);
|
|
return;
|
|
}
|
|
|
|
if (item.screen) {
|
|
goSection(item.screen);
|
|
}
|
|
};
|
|
|
|
const handleHomeIconClick = () => {
|
|
setIsThemeWindowOpen(false);
|
|
goSection('home');
|
|
};
|
|
|
|
const renderActiveScreen = () => {
|
|
if (activeScreen === 'home') {
|
|
return <Template1HomeScreen items={homeMenuItems} onItemSelect={openItem} />;
|
|
}
|
|
|
|
return (
|
|
<Template1SectionScreen
|
|
title={activeSectionItem.label}
|
|
chips={activeSectionItem.chips}
|
|
cards={menuItems}
|
|
onItemSelect={openItem}
|
|
/>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<section
|
|
className="template1-app"
|
|
style={buildThemeStyle(THEME_PRESET_BY_ID[activeThemeId] ?? THEME_PRESET_BY_ID[DEFAULT_THEME_ID])}
|
|
>
|
|
<header className="template1-app__topbar">
|
|
<div className="template1-app__brand">
|
|
<button
|
|
type="button"
|
|
className="template1-app__badge"
|
|
aria-label="Template1 홈으로 이동"
|
|
onClick={handleHomeIconClick}
|
|
onKeyDown={(event) => {
|
|
if (event.key === 'Enter' || event.key === ' ') {
|
|
event.preventDefault();
|
|
handleHomeIconClick();
|
|
}
|
|
}}
|
|
>
|
|
<AppstoreOutlined />
|
|
</button>
|
|
<div>
|
|
<h1>Template1 앱 레이아웃</h1>
|
|
<p>다음 앱에 바로 적용 가능한 기본 배치 예시</p>
|
|
</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
className="template1-app__topbar-action"
|
|
aria-label="Template1 설정 열기"
|
|
aria-expanded={isSettingsOpen}
|
|
onClick={() => {
|
|
if (isSettingsOpen) {
|
|
setIsSettingsOpen(false);
|
|
return;
|
|
}
|
|
|
|
setIsSettingsOpen(true);
|
|
}}
|
|
title="설정"
|
|
>
|
|
<SettingOutlined />
|
|
</button>
|
|
</header>
|
|
|
|
{isSettingsOpen ? (
|
|
<Template1SettingsDropdown
|
|
onItemSelect={(item) => {
|
|
if (item.settingAction === 'theme') {
|
|
goThemeScreen();
|
|
return;
|
|
}
|
|
|
|
openItem(item);
|
|
}}
|
|
onThemeOpen={() => {
|
|
goThemeScreen();
|
|
}}
|
|
/>
|
|
) : null}
|
|
|
|
<main className="template1-app__main">
|
|
<div className="template1-app__scroll-area">
|
|
<div key={`template1-screen-${activeScreen}-${isSettingsOpen ? 'settings' : 'screen'}`} className="template1-app__screen-transition">
|
|
{renderActiveScreen()}
|
|
</div>
|
|
</div>
|
|
</main>
|
|
{isThemeWindowOpen ? (
|
|
<Template1ThemeSettingsPanel
|
|
activeThemeId={activeThemeId}
|
|
onClose={closeThemeWindow}
|
|
onThemeSelect={(themeId) => {
|
|
setActiveThemeId(themeId);
|
|
}}
|
|
isDragging={isThemeWindowDragging}
|
|
onWindowMoveStart={(event) => {
|
|
const clickedTarget = event.target as Element | null;
|
|
|
|
if (
|
|
event.button !== 0 ||
|
|
!(clickedTarget instanceof Element) ||
|
|
clickedTarget.closest('.template1-app__theme-window-close')
|
|
) {
|
|
return;
|
|
}
|
|
|
|
setThemeWindowDragStart({
|
|
x: event.clientX - Number(themeWindowPos.left),
|
|
y: event.clientY - Number(themeWindowPos.top),
|
|
});
|
|
setIsThemeWindowDragging(true);
|
|
event.preventDefault();
|
|
}}
|
|
style={{
|
|
left: themeWindowPos.left,
|
|
top: themeWindowPos.top,
|
|
}}
|
|
/>
|
|
) : null}
|
|
</section>
|
|
);
|
|
}
|