feat(service): Console_SendMail을 Windows 서비스로 변환

- MailService.cs 추가: ServiceBase 상속받는 Windows 서비스 클래스
- Program.cs 수정: 서비스/콘솔 모드 지원, 설치/제거 기능 추가
- 프로젝트 설정: System.ServiceProcess 참조 추가
- 배치 파일 추가: 서비스 설치/제거/콘솔실행 스크립트

주요 기능:
- Windows 서비스로 백그라운드 실행
- 명령행 인수로 모드 선택 (-install, -uninstall, -console)
- EventLog를 통한 서비스 로깅
- 안전한 서비스 시작/중지 처리

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ChiKyun Kim
2025-09-11 09:08:40 +09:00
parent 777fcd5d89
commit 6bd4f84192
49 changed files with 46882 additions and 102 deletions

View File

@@ -0,0 +1,490 @@
/* Tailwind CSS v3.3.0 - Custom Build for GroupWare React Components */
/*! tailwindcss v3.3.0 | MIT License | https://tailwindcss.com */
*,::after,::before{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}::after,::before{--tw-content:''}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace, SFMono-Regular, "Roboto Mono", "Courier New", monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}
/* Base Variables */
:root {
--color-white: 255 255 255;
--color-black: 0 0 0;
--color-gray-50: 249 250 251;
--color-gray-100: 243 244 246;
--color-gray-200: 229 231 235;
--color-gray-300: 209 213 219;
--color-gray-400: 156 163 175;
--color-gray-500: 107 114 128;
--color-gray-600: 75 85 99;
--color-gray-700: 55 65 81;
--color-gray-800: 31 41 55;
--color-gray-900: 17 24 39;
--color-blue-50: 239 246 255;
--color-blue-100: 219 234 254;
--color-blue-200: 191 219 254;
--color-blue-300: 147 197 253;
--color-blue-400: 96 165 250;
--color-blue-500: 59 130 246;
--color-blue-600: 37 99 235;
--color-blue-700: 29 78 216;
--color-blue-800: 30 64 175;
--color-blue-900: 30 58 138;
--color-indigo-50: 238 242 255;
--color-indigo-100: 224 231 255;
--color-indigo-200: 199 210 254;
--color-indigo-300: 165 180 252;
--color-indigo-400: 129 140 248;
--color-indigo-500: 99 102 241;
--color-indigo-600: 79 70 229;
--color-indigo-700: 67 56 202;
--color-indigo-800: 55 48 163;
--color-indigo-900: 49 46 129;
--color-purple-50: 245 243 255;
--color-purple-100: 237 233 254;
--color-purple-200: 221 214 254;
--color-purple-300: 196 181 253;
--color-purple-400: 167 139 250;
--color-purple-500: 139 92 246;
--color-purple-600: 124 58 237;
--color-purple-700: 109 40 217;
--color-purple-800: 91 33 182;
--color-purple-900: 76 29 149;
--color-green-50: 240 253 244;
--color-green-100: 220 252 231;
--color-green-200: 187 247 208;
--color-green-300: 134 239 172;
--color-green-400: 74 222 128;
--color-green-500: 34 197 94;
--color-green-600: 22 163 74;
--color-green-700: 21 128 61;
--color-green-800: 22 101 52;
--color-green-900: 20 83 45;
--color-yellow-50: 255 251 235;
--color-yellow-100: 254 243 199;
--color-yellow-200: 253 230 138;
--color-yellow-300: 252 211 77;
--color-yellow-400: 251 191 36;
--color-yellow-500: 245 158 11;
--color-yellow-600: 217 119 6;
--color-yellow-700: 180 83 9;
--color-yellow-800: 146 64 14;
--color-yellow-900: 120 53 15;
--color-red-50: 254 242 242;
--color-red-100: 254 226 226;
--color-red-200: 252 165 165;
--color-red-300: 248 113 113;
--color-red-400: 239 68 68;
--color-red-500: 239 68 68;
--color-red-600: 220 38 38;
--color-red-700: 185 28 28;
--color-red-800: 153 27 27;
--color-red-900: 127 29 29;
}
/* Utility Classes - Core */
.container { width: 100%; }
@media (min-width: 640px) { .container { max-width: 640px; } }
@media (min-width: 768px) { .container { max-width: 768px; } }
@media (min-width: 1024px) { .container { max-width: 1024px; } }
@media (min-width: 1280px) { .container { max-width: 1280px; } }
@media (min-width: 1536px) { .container { max-width: 1536px; } }
.mx-auto { margin-left: auto; margin-right: auto; }
.px-4 { padding-left: 1rem; padding-right: 1rem; }
.py-8 { padding-top: 2rem; padding-bottom: 2rem; }
/* Positioning */
.fixed { position: fixed; }
.relative { position: relative; }
.absolute { position: absolute; }
.inset-0 { inset: 0px; }
.top-4 { top: 1rem; }
.right-4 { right: 1rem; }
.top-full { top: 100%; }
.z-10 { z-index: 10; }
.z-40 { z-index: 40; }
.z-50 { z-index: 50; }
/* Display */
.block { display: block; }
.inline-block { display: inline-block; }
.inline { display: inline; }
.flex { display: flex; }
.inline-flex { display: inline-flex; }
.table { display: table; }
.table-cell { display: table-cell; }
.grid { display: grid; }
.hidden { display: none; }
/* Flexbox */
.flex-1 { flex: 1 1 0%; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.items-end { align-items: flex-end; }
.justify-center { justify-content: center; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
/* Grid */
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (min-width: 768px) {
.md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.md\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
.lg\:col-span-2 { grid-column: span 2 / span 2; }
.lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 640px) {
.sm\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Spacing */
.gap-2 { gap: 0.5rem; }
.gap-3 { gap: 0.75rem; }
.gap-4 { gap: 1rem; }
.gap-6 { gap: 1.5rem; }
.space-x-1 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(0.25rem * var(--tw-space-x-reverse)); margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse))); }
.space-x-2 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(0.5rem * var(--tw-space-x-reverse)); margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); }
.space-x-3 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(0.75rem * var(--tw-space-x-reverse)); margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); }
.space-x-4 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(1rem * var(--tw-space-x-reverse)); margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); }
.space-x-8 > :not([hidden]) ~ :not([hidden]) { --tw-space-x-reverse: 0; margin-right: calc(2rem * var(--tw-space-x-reverse)); margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse))); }
.space-y-1 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.25rem * var(--tw-space-y-reverse)); }
.space-y-3 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); }
.space-y-4 > :not([hidden]) ~ :not([hidden]) { --tw-space-y-reverse: 0; margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); margin-bottom: calc(1rem * var(--tw-space-y-reverse)); }
/* Margins */
.m-2 { margin: 0.5rem; }
.mb-1 { margin-bottom: 0.25rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.mr-1 { margin-right: 0.25rem; }
.mr-2 { margin-right: 0.5rem; }
.mr-3 { margin-right: 0.75rem; }
.ml-2 { margin-left: 0.5rem; }
.ml-4 { margin-left: 1rem; }
.ml-auto { margin-left: auto; }
.mt-6 { margin-top: 1.5rem; }
/* Padding */
.p-1 { padding: 0.25rem; }
.p-3 { padding: 0.75rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.p-8 { padding: 2rem; }
.px-2 { padding-left: 0.5rem; padding-right: 0.5rem; }
.px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
.px-4 { padding-left: 1rem; padding-right: 1rem; }
.px-6 { padding-left: 1.5rem; padding-right: 1.5rem; }
.py-0 { padding-top: 0px; padding-bottom: 0px; }
.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
.py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; }
.py-4 { padding-top: 1rem; padding-bottom: 1rem; }
.pt-0 { padding-top: 0px; }
.pb-0 { padding-bottom: 0px; }
/* Size */
.w-4 { width: 1rem; }
.w-5 { width: 1.25rem; }
.w-6 { width: 1.5rem; }
.w-8 { width: 2rem; }
.w-12 { width: 3rem; }
.w-16 { width: 4rem; }
.w-20 { width: 5rem; }
.w-24 { width: 6rem; }
.w-28 { width: 7rem; }
.w-32 { width: 8rem; }
.w-40 { width: 10rem; }
.w-48 { width: 12rem; }
.w-full { width: 100%; }
.min-w-32 { min-width: 8rem; }
.min-w-48 { min-width: 12rem; }
.max-w-xs { max-width: 20rem; }
.max-w-md { max-width: 28rem; }
.max-w-2xl { max-width: 42rem; }
.h-4 { height: 1rem; }
.h-5 { height: 1.25rem; }
.h-6 { height: 1.5rem; }
.h-8 { height: 2rem; }
.h-10 { height: 2.5rem; }
.h-16 { height: 4rem; }
.min-h-screen { min-height: 100vh; }
.max-h-40 { max-height: 10rem; }
/* Background */
.bg-white { background-color: rgb(255 255 255); }
.bg-black { background-color: rgb(0 0 0); }
.bg-gray-500 { background-color: rgb(107 114 128); }
.bg-gray-800 { background-color: rgb(31 41 55); }
.bg-blue-300 { background-color: rgb(147 197 253); }
.bg-blue-500 { background-color: rgb(59 130 246); }
.bg-green-300 { background-color: rgb(134 239 172); }
.bg-green-500 { background-color: rgb(34 197 94); }
.bg-yellow-300 { background-color: rgb(252 211 77); }
.bg-yellow-500 { background-color: rgb(245 158 11); }
.bg-red-300 { background-color: rgb(248 113 113); }
.bg-red-400 { background-color: rgb(239 68 68); }
.bg-red-500 { background-color: rgb(239 68 68); }
.bg-purple-500 { background-color: rgb(139 92 246); }
.bg-orange-500 { background-color: rgb(249 115 22); }
/* Background with opacity */
.bg-white\/5 { background-color: rgb(255 255 255 / 0.05); }
.bg-white\/10 { background-color: rgb(255 255 255 / 0.1); }
.bg-white\/20 { background-color: rgb(255 255 255 / 0.2); }
.bg-white\/30 { background-color: rgb(255 255 255 / 0.3); }
.bg-gray-500\/20 { background-color: rgb(107 114 128 / 0.2); }
.bg-blue-500\/20 { background-color: rgb(59 130 246 / 0.2); }
.bg-green-500\/20 { background-color: rgb(34 197 94 / 0.2); }
.bg-yellow-500\/20 { background-color: rgb(245 158 11 / 0.2); }
.bg-red-500\/20 { background-color: rgb(239 68 68 / 0.2); }
.bg-purple-500\/20 { background-color: rgb(139 92 246 / 0.2); }
.bg-orange-500\/90 { background-color: rgb(249 115 22 / 0.9); }
.bg-blue-500\/90 { background-color: rgb(59 130 246 / 0.9); }
.bg-green-500\/90 { background-color: rgb(34 197 94 / 0.9); }
.bg-red-500\/90 { background-color: rgb(239 68 68 / 0.9); }
/* Gradient backgrounds */
.bg-gradient-to-br { background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); }
.from-blue-900 { --tw-gradient-from: rgb(30 58 138); --tw-gradient-to: rgb(30 58 138 / 0); --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); }
.via-purple-900 { --tw-gradient-to: rgb(76 29 149 / 0); --tw-gradient-stops: var(--tw-gradient-from), rgb(76 29 149), var(--tw-gradient-to); }
.to-indigo-900 { --tw-gradient-to: rgb(49 46 129); }
/* Text Colors */
.text-white { color: rgb(255 255 255); }
.text-gray-300 { color: rgb(209 213 219); }
.text-gray-500 { color: rgb(107 114 128); }
.text-blue-300 { color: rgb(147 197 253); }
.text-green-300 { color: rgb(134 239 172); }
.text-yellow-300 { color: rgb(252 211 77); }
.text-red-300 { color: rgb(248 113 113); }
.text-red-400 { color: rgb(239 68 68); }
.text-orange-100 { color: rgb(255 237 213); }
.text-orange-900 { color: rgb(154 52 18); }
.text-primary-200 { color: rgb(147 197 253); }
.text-primary-300 { color: rgb(147 197 253); }
.text-primary-400 { color: rgb(96 165 250); }
.text-success-200 { color: rgb(187 247 208); }
.text-success-300 { color: rgb(134 239 172); }
.text-success-400 { color: rgb(74 222 128); }
.text-warning-300 { color: rgb(252 211 77); }
.text-danger-300 { color: rgb(248 113 113); }
.text-danger-400 { color: rgb(239 68 68); }
/* Text with opacity */
.text-white\/50 { color: rgb(255 255 255 / 0.5); }
.text-white\/60 { color: rgb(255 255 255 / 0.6); }
.text-white\/70 { color: rgb(255 255 255 / 0.7); }
.text-white\/80 { color: rgb(255 255 255 / 0.8); }
/* Typography */
.text-xs { font-size: 0.75rem; line-height: 1rem; }
.text-sm { font-size: 0.875rem; line-height: 1.25rem; }
.text-base { font-size: 1rem; line-height: 1.5rem; }
.text-lg { font-size: 1.125rem; line-height: 1.75rem; }
.text-xl { font-size: 1.25rem; line-height: 1.75rem; }
.text-2xl { font-size: 1.5rem; line-height: 2rem; }
.font-medium { font-weight: 500; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.uppercase { text-transform: uppercase; }
.tracking-wider { letter-spacing: 0.05em; }
.text-left { text-align: left; }
.text-center { text-align: center; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.underline { text-decoration-line: underline; }
.whitespace-nowrap { white-space: nowrap; }
/* Borders */
.border { border-width: 1px; }
.border-b { border-bottom-width: 1px; }
.border-l-4 { border-left-width: 4px; }
.border-r { border-right-width: 1px; }
.border-t { border-top-width: 1px; }
.border-white\/10 { border-color: rgb(255 255 255 / 0.1); }
.border-white\/20 { border-color: rgb(255 255 255 / 0.2); }
.border-white\/30 { border-color: rgb(255 255 255 / 0.3); }
.border-gray-500\/30 { border-color: rgb(107 114 128 / 0.3); }
.border-orange-700 { border-color: rgb(194 65 12); }
.divide-y > :not([hidden]) ~ :not([hidden]) { --tw-divide-y-reverse: 0; border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); }
.divide-white\/10 > :not([hidden]) ~ :not([hidden]) { border-color: rgb(255 255 255 / 0.1); }
.divide-white\/20 > :not([hidden]) ~ :not([hidden]) { border-color: rgb(255 255 255 / 0.2); }
/* Border Radius */
.rounded { border-radius: 0.25rem; }
.rounded-md { border-radius: 0.375rem; }
.rounded-lg { border-radius: 0.5rem; }
.rounded-2xl { border-radius: 1rem; }
.rounded-full { border-radius: 9999px; }
/* Shadows */
.shadow-sm { box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); }
.shadow-lg { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -2px rgb(0 0 0 / 0.05); }
/* Overflow */
.overflow-hidden { overflow: hidden; }
.overflow-x-auto { overflow-x: auto; }
.overflow-y-auto { overflow-y: auto; }
/* Interactivity */
.cursor-pointer { cursor: pointer; }
.cursor-not-allowed { cursor: not-allowed; }
/* Focus */
.focus\:outline-none:focus { outline: 2px solid transparent; outline-offset: 2px; }
.focus\:ring-1:focus { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); }
.focus\:ring-2:focus { --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); }
.focus\:ring-white\/50:focus { --tw-ring-color: rgb(255 255 255 / 0.5); }
.focus\:ring-primary-400:focus { --tw-ring-color: rgb(96 165 250); }
.focus\:border-transparent:focus { border-color: transparent; }
.focus\:ring-offset-0:focus { --tw-ring-offset-width: 0px; }
/* Hover Effects */
.hover\:bg-white\/10:hover { background-color: rgb(255 255 255 / 0.1); }
.hover\:bg-white\/20:hover { background-color: rgb(255 255 255 / 0.2); }
.hover\:bg-white\/30:hover { background-color: rgb(255 255 255 / 0.3); }
.hover\:bg-primary-600:hover { background-color: rgb(37 99 235); }
.hover\:bg-green-600:hover { background-color: rgb(22 163 74); }
.hover\:bg-red-600:hover { background-color: rgb(220 38 38); }
.hover\:bg-purple-600:hover { background-color: rgb(124 58 237); }
.hover\:text-white:hover { color: rgb(255 255 255); }
.hover\:text-blue-200:hover { color: rgb(191 219 254); }
.hover\:text-blue-300:hover { color: rgb(147 197 253); }
.hover\:text-primary-300:hover { color: rgb(147 197 253); }
/* Disabled */
.disabled\:opacity-50:disabled { opacity: 0.5; }
.disabled\:cursor-not-allowed:disabled { cursor: not-allowed; }
/* Transitions */
.transition-colors { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
.transition-all { transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
.transition-transform { transition-property: transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
.duration-200 { transition-duration: 200ms; }
.duration-300 { transition-duration: 300ms; }
/* Transforms */
.transform { transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); }
.translate-x-0 { --tw-translate-x: 0px; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); }
.rotate-180 { --tw-rotate: 180deg; transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); }
/* Animations */
.animate-spin { animation: spin 1s linear infinite; }
.animate-pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }
.animate-slide-up { animation: slideUp 0.3s ease-out; }
.animate-fade-in { animation: fadeIn 0.5s ease-in-out; }
@keyframes spin {
to { transform: rotate(360deg); }
}
@keyframes pulse {
50% { opacity: .5; }
}
@keyframes slideUp {
from { transform: translateY(10px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Backdrop Filter */
.backdrop-blur-sm { backdrop-filter: blur(4px); }
/* Opacity */
.opacity-0 { opacity: 0; }
.opacity-50 { opacity: 0.5; }
.opacity-100 { opacity: 1; }
/* Visibility */
.invisible { visibility: hidden; }
.visible { visibility: visible; }
/* Responsive Design Utilities */
@media (min-width: 640px) {
.sm\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 768px) {
.md\:flex { display: flex; }
.md\:hidden { display: none; }
.md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.md\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.md\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
.lg\:col-span-2 { grid-column: span 2 / span 2; }
.lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Custom Tailwind Config Extensions */
.bg-primary-500 { background-color: rgb(59 130 246); }
.bg-primary-600 { background-color: rgb(37 99 235); }
.bg-success-500 { background-color: rgb(34 197 94); }
.bg-success-600 { background-color: rgb(22 163 74); }
.bg-warning-500 { background-color: rgb(245 158 11); }
.bg-warning-600 { background-color: rgb(217 119 6); }
.bg-danger-500 { background-color: rgb(239 68 68); }
.bg-danger-600 { background-color: rgb(220 38 38); }
.bg-primary-500\/20 { background-color: rgb(59 130 246 / 0.2); }
.bg-primary-500\/30 { background-color: rgb(59 130 246 / 0.3); }
.bg-success-500\/20 { background-color: rgb(34 197 94 / 0.2); }
.bg-success-500\/30 { background-color: rgb(34 197 94 / 0.3); }
.bg-warning-500\/20 { background-color: rgb(245 158 11 / 0.2); }
.bg-warning-500\/30 { background-color: rgb(245 158 11 / 0.3); }
.bg-danger-500\/20 { background-color: rgb(239 68 68 / 0.2); }
.bg-danger-500\/30 { background-color: rgb(239 68 68 / 0.3); }
/* Custom Utilities for the project */
.glass-effect {
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.18);
}
.card-hover {
transition: all 0.3s ease;
}
.card-hover:hover {
transform: translateY(-5px);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.custom-scrollbar::-webkit-scrollbar {
width: 8px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.1);
border-radius: 8px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.3);
border-radius: 8px;
border: 2px solid rgba(255, 255, 255, 0.1);
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.5);
}
.loading {
border: 3px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top: 3px solid #fff;
width: 20px;
height: 20px;
animation: spin 1s linear infinite;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
// Tailwind CSS Configuration for GroupWare React Components
// This configuration includes all custom colors and extensions used in the React components
window.tailwind = {
config: {
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
},
success: {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e',
600: '#16a34a',
700: '#15803d',
800: '#166534',
900: '#14532d',
},
warning: {
50: '#fffbeb',
100: '#fef3c7',
200: '#fde68a',
300: '#fcd34d',
400: '#fbbf24',
500: '#f59e0b',
600: '#d97706',
700: '#b45309',
800: '#92400e',
900: '#78350f',
},
danger: {
50: '#fef2f2',
100: '#fee2e2',
200: '#fecaca',
300: '#fca5a5',
400: '#f87171',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c',
800: '#991b1b',
900: '#7f1d1d',
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-in-out',
'slide-up': 'slideUp 0.3s ease-out',
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
}
}
}
}
}
};
// Apply configuration if tailwindcss is available
if (typeof tailwindcss !== 'undefined') {
tailwindcss.config = window.tailwind.config;
}