/* ===== 서명용 손글씨 폰트 (완전한 한글 지원 폰트) ===== */ @import url("https://fonts.googleapis.com/css2?family=Allura&family=Dancing+Script:wght@700&family=Great+Vibes&family=Pacifico&family=Satisfy&family=Caveat:wght@700&family=Permanent+Marker&family=Shadows+Into+Light&family=Kalam:wght@700&family=Patrick+Hand&family=Indie+Flower&family=Amatic+SC:wght@700&family=Covered+By+Your+Grace&family=Nanum+Brush+Script&family=Nanum+Pen+Script&family=Gaegu:wght@700&family=Hi+Melody&family=Gamja+Flower&family=Poor+Story&family=Do+Hyeon&family=Jua&display=swap"); /* ===== Tailwind CSS & Animations ===== */ @import "tailwindcss"; @import "tw-animate-css"; /* ===== Dark Mode Variant ===== */ @custom-variant dark (&:is(.dark *)); /* ===== Tailwind Theme Extensions ===== */ @theme { /* Color System - HSL Format (shadcn/ui Standard) */ --color-background: hsl(var(--background)); --color-foreground: hsl(var(--foreground)); --color-card: hsl(var(--card)); --color-card-foreground: hsl(var(--card-foreground)); --color-popover: hsl(var(--popover)); --color-popover-foreground: hsl(var(--popover-foreground)); --color-primary: hsl(var(--primary)); --color-primary-foreground: hsl(var(--primary-foreground)); --color-secondary: hsl(var(--secondary)); --color-secondary-foreground: hsl(var(--secondary-foreground)); --color-muted: hsl(var(--muted)); --color-muted-foreground: hsl(var(--muted-foreground)); --color-accent: hsl(var(--accent)); --color-accent-foreground: hsl(var(--accent-foreground)); --color-destructive: hsl(var(--destructive)); --color-destructive-foreground: hsl(var(--destructive-foreground)); --color-border: hsl(var(--border)); --color-input: hsl(var(--input)); --color-ring: hsl(var(--ring)); /* Success, Warning, Info Colors */ --color-success: hsl(var(--success)); --color-success-foreground: hsl(var(--success-foreground)); --color-warning: hsl(var(--warning)); --color-warning-foreground: hsl(var(--warning-foreground)); --color-info: hsl(var(--info)); --color-info-foreground: hsl(var(--info-foreground)); /* Chart Colors */ --color-chart-1: hsl(var(--chart-1)); --color-chart-2: hsl(var(--chart-2)); --color-chart-3: hsl(var(--chart-3)); --color-chart-4: hsl(var(--chart-4)); --color-chart-5: hsl(var(--chart-5)); /* Sidebar Colors */ --color-sidebar: hsl(var(--sidebar-background)); --color-sidebar-foreground: hsl(var(--sidebar-foreground)); --color-sidebar-primary: hsl(var(--sidebar-primary)); --color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground)); --color-sidebar-accent: hsl(var(--sidebar-accent)); --color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground)); --color-sidebar-border: hsl(var(--sidebar-border)); --color-sidebar-ring: hsl(var(--sidebar-ring)); /* Font Families */ --font-sans: var(--font-inter); --font-mono: var(--font-jetbrains-mono); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); } /* ===== CSS Variables (Vivid Blue Theme) ===== */ :root { /* Light Theme Colors - HSL Format */ --background: 0 0% 100%; --foreground: 224 71% 4%; --card: 0 0% 100%; --card-foreground: 224 71% 4%; --popover: 0 0% 100%; --popover-foreground: 224 71% 4%; --primary: 217.2 91.2% 59.8%; --primary-foreground: 0 0% 100%; --secondary: 220 14.3% 95.9%; --secondary-foreground: 220.9 39.3% 11%; --muted: 220 14.3% 95.9%; --muted-foreground: 220 8.9% 46.1%; --accent: 220 14.3% 95.9%; --accent-foreground: 220.9 39.3% 11%; --destructive: 0 84.2% 60.2%; --destructive-foreground: 0 0% 100%; --border: 220 13% 88%; --input: 220 13% 88%; --ring: 217.2 91.2% 59.8%; /* Success Colors (Emerald) */ --success: 142 76% 36%; --success-foreground: 0 0% 100%; /* Warning Colors (Amber) */ --warning: 38 92% 50%; --warning-foreground: 0 0% 100%; /* Info Colors (Cyan) */ --info: 188 94% 43%; --info-foreground: 0 0% 100%; /* Chart Colors */ --chart-1: 12 76% 61%; --chart-2: 173 58% 39%; --chart-3: 197 37% 24%; --chart-4: 43 74% 66%; --chart-5: 27 87% 67%; /* Border Radius */ --radius: 0.5rem; /* Sidebar Colors */ --sidebar-background: 220 20% 97%; --sidebar-foreground: 224 71% 4%; --sidebar-primary: 217.2 91.2% 59.8%; --sidebar-primary-foreground: 0 0% 100%; --sidebar-accent: 220 14.3% 95.9%; --sidebar-accent-foreground: 220.9 39.3% 11%; --sidebar-border: 220 13% 91%; --sidebar-ring: 217.2 91.2% 59.8%; } /* ===== Dark Theme (Palantir-Inspired) ===== */ .dark { /* 배경: 팔란티어 스타일 깊은 네이비 */ --background: 222 47% 6%; --foreground: 210 20% 95%; /* 카드: 배경보다 약간 밝게 (레이어 구분) */ --card: 220 40% 9%; --card-foreground: 210 20% 95%; /* 팝오버: 카드와 동일 */ --popover: 220 40% 9%; --popover-foreground: 210 20% 95%; /* Primary: 다크 배경에서 약간 더 밝은 블루 */ --primary: 217 91% 65%; --primary-foreground: 0 0% 100%; /* Secondary: 어두운 슬레이트 */ --secondary: 220 25% 14%; --secondary-foreground: 210 20% 90%; /* Muted: 차분한 회색-네이비 */ --muted: 220 20% 13%; --muted-foreground: 215 15% 58%; /* Accent: secondary와 유사 */ --accent: 220 25% 16%; --accent-foreground: 210 20% 90%; /* Destructive: 다크에서 더 밝은 레드 */ --destructive: 0 72% 51%; --destructive-foreground: 0 0% 100%; /* Border: 팔란티어 스타일 - 보더가 더 잘 보임 */ --border: 220 20% 18%; --input: 220 20% 18%; --ring: 217 91% 65%; /* Success (Emerald) - 다크 배경용 밝기 조정 */ --success: 142 70% 42%; --success-foreground: 0 0% 100%; /* Warning (Amber) - 다크 배경용 밝기 조정 */ --warning: 38 92% 55%; --warning-foreground: 0 0% 10%; /* Info (Cyan) - 다크 배경용 밝기 조정 */ --info: 188 90% 48%; --info-foreground: 0 0% 100%; /* Chart Colors - 다크 배경에서 선명한 컬러 */ --chart-1: 220 70% 55%; --chart-2: 160 60% 48%; --chart-3: 30 80% 58%; --chart-4: 280 65% 63%; --chart-5: 340 75% 58%; /* Sidebar - 메인 배경보다 약간 어둡게 */ --sidebar-background: 222 47% 5%; --sidebar-foreground: 210 20% 90%; --sidebar-primary: 217 91% 65%; --sidebar-primary-foreground: 0 0% 100%; --sidebar-accent: 220 25% 14%; --sidebar-accent-foreground: 210 20% 90%; --sidebar-border: 220 20% 16%; --sidebar-ring: 217 91% 65%; } /* ===== Base Styles ===== */ * { border-color: hsl(var(--border)); } body { color: hsl(var(--foreground)); background: hsl(var(--background)); } /* Button 기본 커서 스타일 */ button { cursor: pointer; } button:disabled { cursor: not-allowed; } /* ===== Dialog/Modal Overlay ===== */ /* Radix UI Dialog Overlay - 60% 불투명도 배경 */ [data-radix-dialog-overlay], .fixed.inset-0.z-50.bg-black { background-color: rgba(0, 0, 0, 0.6) !important; backdrop-filter: none !important; } /* DialogPrimitive.Overlay 클래스 오버라이드 */ .fixed.inset-0.z-50 { background-color: rgba(0, 0, 0, 0.6) !important; backdrop-filter: none !important; } /* ===== Accessibility - Focus Styles ===== */ /* 모든 인터랙티브 요소에 대한 포커스 스타일 */ button:focus-visible, a:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; } /* TableSearchWidget의 SelectTrigger 포커스 스타일 제거 */ [role="combobox"]:focus-visible { outline: none !important; box-shadow: none !important; } button[role="combobox"]:focus-visible { outline: none !important; box-shadow: none !important; border-color: hsl(var(--input)) !important; } /* ===== Scrollbar Styles (Optional) ===== */ /* Webkit 기반 브라우저 (Chrome, Safari, Edge) */ ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: hsl(var(--muted)); } ::-webkit-scrollbar-thumb { background: hsl(var(--muted-foreground) / 0.3); border-radius: 5px; } ::-webkit-scrollbar-thumb:hover { background: hsl(var(--muted-foreground) / 0.5); } /* Firefox */ * { scrollbar-width: thin; scrollbar-color: hsl(var(--muted-foreground) / 0.3) hsl(var(--muted)); } /* ===== Animation Utilities ===== */ /* Smooth transitions for interactive elements */ button, a, input, textarea, select { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, filter, backdrop-filter; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; } /* 런타임 화면에서 컴포넌트 위치 변경 시 모든 애니메이션/트랜지션 완전 제거 */ [data-screen-runtime] [id^="component-"] { transition: none !important; } [data-screen-runtime] [data-conditional-layer] { transition: none !important; } /* Disable animations for users who prefer reduced motion */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } /* ===== Sonner 토스트 애니메이션 완전 제거 ===== */ [data-sonner-toaster] [data-sonner-toast] { animation: none !important; transition: none !important; opacity: 1 !important; transform: none !important; } [data-sonner-toaster] [data-sonner-toast][data-mounted="true"] { animation: none !important; } [data-sonner-toaster] [data-sonner-toast][data-removed="true"] { animation: none !important; } /* ===== Print Styles ===== */ @media print { * { background: transparent !important; color: black !important; box-shadow: none !important; text-shadow: none !important; } a, a:visited { text-decoration: underline; } a[href]::after { content: " (" attr(href) ")"; } img { max-width: 100% !important; } @page { margin: 2cm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } } /* ===== Custom Utilities (Project-Specific) ===== */ /* 손글씨 폰트 클래스 */ .font-handwriting { font-family: "Allura", cursive; } .font-dancing-script { font-family: "Dancing Script", cursive; } .font-great-vibes { font-family: "Great Vibes", cursive; } .font-pacifico { font-family: "Pacifico", cursive; } .font-satisfy { font-family: "Satisfy", cursive; } .font-caveat { font-family: "Caveat", cursive; } /* 한글 손글씨 폰트 */ .font-nanum-brush { font-family: "Nanum Brush Script", cursive; } .font-nanum-pen { font-family: "Nanum Pen Script", cursive; } .font-gaegu { font-family: "Gaegu", cursive; } /* ===== Component-Specific Overrides ===== */ /* 필요시 특정 컴포넌트에 대한 스타일 오버라이드를 여기에 추가 */ /* 예: Calendar, Table 등의 미세 조정 */ /* 모바일에서 테이블 레이아웃 고정 (화면 밖으로 넘어가지 않도록) */ @media (max-width: 639px) { .table-mobile-fixed { table-layout: fixed; } } /* 데스크톱에서 테이블 레이아웃 자동 (기본값이지만 명시적으로 설정) */ @media (min-width: 640px) { .table-mobile-fixed { table-layout: auto; } } /* 그리드선 숨기기 */ .hide-grid td, .hide-grid th { border: none !important; } .hide-grid { border-collapse: separate !important; border-spacing: 0 !important; } /* ===== 저장 테이블 막대기 애니메이션 ===== */ @keyframes saveBarDrop { 0% { transform: scaleY(0); transform-origin: top; opacity: 0; } 100% { transform: scaleY(1); transform-origin: top; opacity: 1; } } /* ===== End of Global Styles ===== */ /* ===== Dark Mode Compatibility Layer ===== */ /* 하드코딩된 Tailwind 색상 → 다크 모드 자동 변환 */ /* 개별 컴포넌트 수정 없이, 이 한 곳에서 전체 프로젝트 커버 */ /* --- 1. 배경색: white/gray → 시맨틱 토큰 --- */ .dark .bg-white { background-color: hsl(var(--card)) !important; } .dark .bg-gray-50 { background-color: hsl(var(--muted)) !important; } .dark .bg-gray-100 { background-color: hsl(var(--muted)) !important; } .dark .bg-gray-200 { background-color: hsl(var(--accent)) !important; } /* --- 2. 텍스트: gray → 시맨틱 토큰 --- */ .dark .text-gray-400 { color: hsl(var(--muted-foreground)) !important; } .dark .text-gray-500 { color: hsl(var(--muted-foreground)) !important; } .dark .text-gray-600 { color: hsl(var(--foreground) / 0.7) !important; } .dark .text-gray-700 { color: hsl(var(--foreground) / 0.8) !important; } .dark .text-gray-800 { color: hsl(var(--foreground) / 0.9) !important; } .dark .text-gray-900 { color: hsl(var(--foreground)) !important; } /* --- 3. 보더: gray → 시맨틱 토큰 --- */ .dark .border-gray-100 { border-color: hsl(var(--border)) !important; } .dark .border-gray-200 { border-color: hsl(var(--border)) !important; } .dark .border-gray-300 { border-color: hsl(var(--border)) !important; } .dark .divide-gray-200 > * + * { border-color: hsl(var(--border)) !important; } /* --- 4. 호버: gray → 시맨틱 토큰 --- */ .dark .hover\:bg-gray-50:hover { background-color: hsl(var(--muted)) !important; } .dark .hover\:bg-gray-100:hover { background-color: hsl(var(--accent)) !important; } .dark .hover\:bg-gray-200:hover { background-color: hsl(var(--accent)) !important; } /* --- 5. Emerald (성공/완료 상태) --- */ .dark .bg-emerald-50 { background-color: hsl(142 40% 12%) !important; } .dark .bg-emerald-100 { background-color: hsl(142 40% 15%) !important; } .dark .text-emerald-600 { color: hsl(142 70% 55%) !important; } .dark .text-emerald-700 { color: hsl(142 70% 50%) !important; } .dark .text-emerald-800 { color: hsl(142 70% 60%) !important; } .dark .text-emerald-900 { color: hsl(142 70% 65%) !important; } .dark .border-emerald-200 { border-color: hsl(142 40% 25%) !important; } .dark .border-emerald-300 { border-color: hsl(142 40% 30%) !important; } .dark .ring-emerald-200 { --tw-ring-color: hsl(142 40% 25%) !important; } /* --- 6. Amber/Yellow (경고/주의 상태) --- */ .dark .bg-amber-50 { background-color: hsl(38 40% 12%) !important; } .dark .bg-amber-100 { background-color: hsl(38 40% 15%) !important; } .dark .bg-yellow-50 { background-color: hsl(48 40% 12%) !important; } .dark .bg-yellow-100 { background-color: hsl(48 40% 15%) !important; } .dark .text-amber-600 { color: hsl(38 90% 58%) !important; } .dark .text-amber-700 { color: hsl(38 90% 55%) !important; } .dark .text-amber-800 { color: hsl(38 90% 60%) !important; } .dark .text-amber-900 { color: hsl(38 90% 65%) !important; } .dark .text-yellow-600 { color: hsl(48 90% 55%) !important; } .dark .text-yellow-700 { color: hsl(48 90% 50%) !important; } .dark .text-yellow-800 { color: hsl(48 90% 60%) !important; } .dark .border-amber-200 { border-color: hsl(38 40% 25%) !important; } .dark .border-amber-300 { border-color: hsl(38 40% 30%) !important; } .dark .border-yellow-200 { border-color: hsl(48 40% 25%) !important; } .dark .ring-amber-200 { --tw-ring-color: hsl(38 40% 25%) !important; } /* --- 7. Blue (정보/프라이머리 상태) --- */ .dark .bg-blue-50 { background-color: hsl(217 40% 12%) !important; } .dark .bg-blue-100 { background-color: hsl(217 40% 15%) !important; } .dark .text-blue-600 { color: hsl(217 90% 65%) !important; } .dark .text-blue-700 { color: hsl(217 90% 60%) !important; } .dark .text-blue-800 { color: hsl(217 90% 65%) !important; } .dark .border-blue-200 { border-color: hsl(217 40% 25%) !important; } .dark .ring-blue-200 { --tw-ring-color: hsl(217 40% 25%) !important; } /* --- 8. Red (에러/삭제 상태) --- */ .dark .bg-red-50 { background-color: hsl(0 40% 12%) !important; } .dark .bg-red-100 { background-color: hsl(0 40% 15%) !important; } .dark .text-red-600 { color: hsl(0 75% 60%) !important; } .dark .text-red-700 { color: hsl(0 75% 55%) !important; } .dark .text-red-800 { color: hsl(0 75% 60%) !important; } .dark .border-red-200 { border-color: hsl(0 40% 25%) !important; } .dark .ring-red-200 { --tw-ring-color: hsl(0 40% 25%) !important; } /* --- 9. Green (성공 - emerald 변형) --- */ .dark .bg-green-50 { background-color: hsl(142 40% 12%) !important; } .dark .bg-green-100 { background-color: hsl(142 40% 15%) !important; } .dark .text-green-600 { color: hsl(142 70% 55%) !important; } .dark .text-green-700 { color: hsl(142 70% 50%) !important; } .dark .border-green-200 { border-color: hsl(142 40% 25%) !important; } /* --- 10. Slate (gray 변형) --- */ .dark .bg-slate-50 { background-color: hsl(var(--muted)) !important; } .dark .bg-slate-100 { background-color: hsl(var(--muted)) !important; } .dark .text-slate-500 { color: hsl(var(--muted-foreground)) !important; } .dark .text-slate-600 { color: hsl(var(--foreground) / 0.7) !important; } .dark .text-slate-700 { color: hsl(var(--foreground) / 0.8) !important; } .dark .border-slate-200 { border-color: hsl(var(--border)) !important; } /* --- 11. bg-white opacity 변형 --- */ .dark .bg-white\/30 { background-color: hsl(var(--card) / 0.3) !important; } .dark .bg-white\/50 { background-color: hsl(var(--card) / 0.5) !important; } .dark .bg-white\/80 { background-color: hsl(var(--card) / 0.8) !important; } .dark .bg-white\/90 { background-color: hsl(var(--card) / 0.9) !important; } .dark .hover\:bg-white:hover { background-color: hsl(var(--card)) !important; } /* --- 12. text-black → foreground --- */ .dark .text-black { color: hsl(var(--foreground)) !important; } /* --- 13. bg/text/border - purple (관리 UI) --- */ .dark .bg-purple-50 { background-color: hsl(270 40% 12%) !important; } .dark .bg-purple-100 { background-color: hsl(270 40% 15%) !important; } .dark .bg-purple-200 { background-color: hsl(270 40% 20%) !important; } .dark .text-purple-500 { color: hsl(270 70% 60%) !important; } .dark .text-purple-600 { color: hsl(270 70% 55%) !important; } .dark .text-purple-700 { color: hsl(270 70% 50%) !important; } .dark .border-purple-200 { border-color: hsl(270 40% 25%) !important; } .dark .border-purple-300 { border-color: hsl(270 40% 30%) !important; } /* --- 14. bg/text/border - indigo --- */ .dark .bg-indigo-50 { background-color: hsl(231 40% 12%) !important; } .dark .bg-indigo-100 { background-color: hsl(231 40% 15%) !important; } .dark .text-indigo-600 { color: hsl(231 70% 60%) !important; } .dark .text-indigo-700 { color: hsl(231 70% 55%) !important; } .dark .border-indigo-200 { border-color: hsl(231 40% 25%) !important; } /* --- 15. bg/text - pink/rose (상태 뱃지) --- */ .dark .bg-pink-50 { background-color: hsl(330 40% 12%) !important; } .dark .bg-pink-100 { background-color: hsl(330 40% 15%) !important; } .dark .text-pink-600 { color: hsl(330 70% 60%) !important; } .dark .text-pink-700 { color: hsl(330 70% 55%) !important; } .dark .bg-rose-50 { background-color: hsl(350 40% 12%) !important; } .dark .bg-rose-100 { background-color: hsl(350 40% 15%) !important; } .dark .text-rose-600 { color: hsl(350 70% 60%) !important; } .dark .text-rose-700 { color: hsl(350 70% 55%) !important; } /* --- 16. bg/text - cyan/teal (정보/상태) --- */ .dark .bg-cyan-50 { background-color: hsl(187 40% 12%) !important; } .dark .bg-cyan-100 { background-color: hsl(187 40% 15%) !important; } .dark .text-cyan-600 { color: hsl(187 70% 55%) !important; } .dark .text-cyan-700 { color: hsl(187 70% 50%) !important; } .dark .bg-teal-50 { background-color: hsl(162 40% 12%) !important; } .dark .bg-teal-100 { background-color: hsl(162 40% 15%) !important; } .dark .text-teal-600 { color: hsl(162 70% 55%) !important; } .dark .text-teal-700 { color: hsl(162 70% 50%) !important; } /* --- 17. bg/text - orange (경고 변형) --- */ .dark .bg-orange-50 { background-color: hsl(25 40% 12%) !important; } .dark .bg-orange-100 { background-color: hsl(25 40% 15%) !important; } .dark .bg-orange-200 { background-color: hsl(25 40% 20%) !important; } .dark .text-orange-600 { color: hsl(25 90% 65%) !important; } .dark .text-orange-700 { color: hsl(25 90% 70%) !important; } .dark .border-orange-200 { border-color: hsl(25 40% 25%) !important; } .dark .border-orange-300 { border-color: hsl(25 40% 30%) !important; } /* --- 18. bg/text/border - violet (필터/관계 표시) --- */ .dark .bg-violet-50 { background-color: hsl(263 40% 12%) !important; } .dark .bg-violet-100 { background-color: hsl(263 40% 18%) !important; } .dark .bg-violet-200 { background-color: hsl(263 40% 22%) !important; } .dark .text-violet-500 { color: hsl(263 80% 70%) !important; } .dark .text-violet-600 { color: hsl(263 80% 65%) !important; } .dark .text-violet-700 { color: hsl(263 80% 72%) !important; } .dark .border-violet-200 { border-color: hsl(263 40% 30%) !important; } .dark .border-violet-300 { border-color: hsl(263 40% 35%) !important; } /* --- 19. bg/text/border - amber (조인/경고) --- */ .dark .bg-amber-200 { background-color: hsl(38 40% 20%) !important; } .dark .text-amber-500 { color: hsl(38 90% 60%) !important; } .dark .text-amber-600 { color: hsl(38 90% 65%) !important; } /* ===== End Dark Mode Compatibility Layer ===== */