diff --git a/.gitignore b/.gitignore index d8f911e..2f8271f 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,7 @@ next-env.d.ts # editor .cursor + +# development principles +DEVELOPMENT_PRINCIPLES.md +GIT_COMMIT_CONVENTION.md diff --git a/src/app/(main)/color-palette/page.tsx b/src/app/(main)/color-palette/page.tsx new file mode 100644 index 0000000..399c321 --- /dev/null +++ b/src/app/(main)/color-palette/page.tsx @@ -0,0 +1,97 @@ +import { themeColors, colorCategories } from '@/lib/theme'; + +export default function ColorPalettePage() { + return ( +
+

프로젝트 테마 색상

+ +
+ {/* 기본 색상 */} +
+

기본 색상

+
+ {Object.entries(colorCategories.neutral).map(([name, color]) => ( +
+
+

{name}

+

{color}

+
+ ))} +
+
+ + {/* 주요 색상 */} +
+

주요 색상

+
+ {Object.entries(colorCategories.primary).map(([name, color]) => ( +
+
+

{name}

+

{color}

+
+ ))} +
+
+ + {/* 확장 색상 */} +
+

확장 색상

+
+ {Object.entries(colorCategories.accent).map(([name, color]) => ( +
+
+

{name}

+

{color}

+
+ ))} +
+
+ + {/* 사용 방법 */} +
+

사용 방법

+
+
+

CSS 클래스

+
+ + <div className="text-theme-blue bg-theme-red"> + +
+
+ +
+

CSS 변수

+
+ + color: var(--color-blue);
+ background-color: var(--color-red); +
+
+
+ +
+

TypeScript

+
+ + import {'{'} themeColors {'}'} from '@/lib/theme';
+ const buttonColor = themeColors.blue; +
+
+
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/app/globals.css b/src/app/globals.css index 6a05a2f..665e1ad 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -76,6 +76,21 @@ --sidebar-accent-foreground: oklch(0.205 0 0); --sidebar-border: oklch(0.922 0 0); --sidebar-ring: oklch(0.708 0 0); + --color-white: #FFFFFF; + --color-black: #000000; + --color-blue: #0000C0; + --color-red: #C00000; + --color-yellow: #FFFF00; + --color-light-gray: #D3D3D3; + --color-dark-gray: #282828; + --color-cobalt-blue: #3678F1; + --color-bright-red: #CF1414; + --color-banana-yellow: #FFE062; + --color-ivory-ice: #DEBA86; + --color-hydran-pink: #FFBFCA; + --color-choco-brown: #4E2E28; + --color-delegate-green: #7DDCC4; + --color-purple: #800080; } .dark { @@ -138,3 +153,53 @@ -ms-overflow-style: none; } } + +/* 다크 모드 지원 (선택사항) */ +@media (prefers-color-scheme: dark) { + :root { + /* 다크 모드에서 색상 조정이 필요한 경우 여기에 추가 */ + } +} + +/* 기본 스타일 */ +body { + color: var(--color-black); + background: var(--color-white); +} + +/* 유틸리티 클래스 */ +.text-theme-blue { color: var(--color-blue); } +.text-theme-red { color: var(--color-red); } +.text-theme-yellow { color: var(--color-yellow); } +.text-theme-cobalt-blue { color: var(--color-cobalt-blue); } +.text-theme-bright-red { color: var(--color-bright-red); } +.text-theme-banana-yellow { color: var(--color-banana-yellow); } +.text-theme-ivory-ice { color: var(--color-ivory-ice); } +.text-theme-hydran-pink { color: var(--color-hydran-pink); } +.text-theme-choco-brown { color: var(--color-choco-brown); } +.text-theme-delegate-green { color: var(--color-delegate-green); } +.text-theme-purple { color: var(--color-purple); } + +.bg-theme-blue { background-color: var(--color-blue); } +.bg-theme-red { background-color: var(--color-red); } +.bg-theme-yellow { background-color: var(--color-yellow); } +.bg-theme-cobalt-blue { background-color: var(--color-cobalt-blue); } +.bg-theme-bright-red { background-color: var(--color-bright-red); } +.bg-theme-banana-yellow { background-color: var(--color-banana-yellow); } +.bg-theme-ivory-ice { background-color: var(--color-ivory-ice); } +.bg-theme-hydran-pink { background-color: var(--color-hydran-pink); } +.bg-theme-choco-brown { background-color: var(--color-choco-brown); } +.bg-theme-delegate-green { background-color: var(--color-delegate-green); } +.bg-theme-purple { background-color: var(--color-purple); } + +.border-theme-blue { border-color: var(--color-blue); } +.border-theme-red { border-color: var(--color-red); } +.border-theme-yellow { border-color: var(--color-yellow); } +.border-theme-cobalt-blue { border-color: var(--color-cobalt-blue); } +.border-theme-bright-red { border-color: var(--color-bright-red); } +.border-theme-banana-yellow { border-color: var(--color-banana-yellow); } +.border-theme-ivory-ice { border-color: var(--color-ivory-ice); } +.border-theme-hydran-pink { border-color: var(--color-hydran-pink); } +.border-theme-choco-brown { border-color: var(--color-choco-brown); } +.border-theme-delegate-green { border-color: var(--color-delegate-green); } +.border-theme-purple { border-color: var(--color-purple); } diff --git a/src/lib/theme.ts b/src/lib/theme.ts new file mode 100644 index 0000000..648f509 --- /dev/null +++ b/src/lib/theme.ts @@ -0,0 +1,80 @@ +// 프로젝트 테마 색상 정의 +export const themeColors = { + // 기본 색상 + white: '#FFFFFF', + black: '#000000', + + // 주요 색상 + blue: '#0000C0', + red: '#C00000', + yellow: '#FFFF00', + + // 그레이 톤 + lightGray: '#D3D3D3', + darkGray: '#282828', + + // 확장 색상 + cobaltBlue: '#3678F1', + brightRed: '#CF1414', + bananaYellow: '#FFE062', + ivoryIce: '#DEBA86', + hydranPink: '#FFBFCA', + chocoBrown: '#4E2E28', + delegateGreen: '#7DDCC4', + purple: '#800080', +} as const; + +// 색상 타입 정의 +export type ThemeColor = keyof typeof themeColors; +export type ThemeColorValue = typeof themeColors[ThemeColor]; + +// 색상 카테고리별 그룹화 +export const colorCategories = { + primary: { + blue: themeColors.blue, + red: themeColors.red, + yellow: themeColors.yellow, + }, + neutral: { + white: themeColors.white, + black: themeColors.black, + lightGray: themeColors.lightGray, + darkGray: themeColors.darkGray, + }, + accent: { + cobaltBlue: themeColors.cobaltBlue, + brightRed: themeColors.brightRed, + bananaYellow: themeColors.bananaYellow, + ivoryIce: themeColors.ivoryIce, + hydranPink: themeColors.hydranPink, + chocoBrown: themeColors.chocoBrown, + delegateGreen: themeColors.delegateGreen, + purple: themeColors.purple, + }, +} as const; + +// CSS 변수 이름 생성 함수 +export const getCssVariableName = (colorName: ThemeColor): string => { + return `--color-${colorName.replace(/([A-Z])/g, '-$1').toLowerCase()}`; +}; + +// 색상 값 가져오기 함수 +export const getThemeColor = (colorName: ThemeColor): ThemeColorValue => { + return themeColors[colorName]; +}; + +// CSS 변수로 색상 가져오기 함수 +export const getCssVariableColor = (colorName: ThemeColor): string => { + return `var(${getCssVariableName(colorName)})`; +}; + +// 색상 유효성 검사 함수 +export const isValidThemeColor = (color: string): color is ThemeColorValue => { + return Object.values(themeColors).includes(color as ThemeColorValue); +}; + +// 색상 이름으로 색상 찾기 함수 +export const findColorByName = (colorValue: string): ThemeColor | null => { + const entry = Object.entries(themeColors).find(([_, value]) => value === colorValue); + return entry ? (entry[0] as ThemeColor) : null; +}; \ No newline at end of file