@@ -170,14 +177,25 @@ function showActivityDetails(status) {
modal.style.display = 'flex';
}
-function closeActivityModal() { document.getElementById('activityDetailModal').style.display = 'none'; }
+function closeActivityModal() {
+ const modal = document.getElementById('activityDetailModal');
+ if (modal) modal.style.display = 'none';
+}
+
+function closeAuthModal() {
+ const modal = document.getElementById('authModal');
+ if (modal) modal.style.display = 'none';
+}
function scrollToProject(name) {
closeActivityModal();
const target = Array.from(document.querySelectorAll('.repo-title')).find(t => t.innerText.trim() === name.trim())?.closest('.accordion-header');
if (target) {
let p = target.parentElement;
- while (p && p !== document.body) { if (p.classList.contains('continent-group') || p.classList.contains('country-group')) p.classList.add('active'); p = p.parentElement; }
+ while (p && p !== document.body) {
+ if (p.classList.contains('continent-group') || p.classList.contains('country-group')) p.classList.add('active');
+ p = p.parentElement;
+ }
target.parentElement.classList.add('active');
const pos = target.getBoundingClientRect().top + window.pageYOffset - 220;
window.scrollTo({ top: pos, behavior: 'smooth' });
diff --git a/style/common.css b/style/common.css
index 090f80c..3ccba6a 100644
--- a/style/common.css
+++ b/style/common.css
@@ -1,80 +1,70 @@
:root {
- /* Design Tokens */
+ /* 1. Core Colors */
--primary-color: #1E5149;
- --primary-lv-0: #e9eeed;
- --primary-lv-1: #D2DCDB;
+ --primary-hover: #163b36;
+ --primary-lv-0: #f0f7f4;
+ --primary-lv-1: #e1eee9;
--primary-lv-8: #193833;
+
--bg-default: #FFFFFF;
--bg-muted: #F9FAFB;
- --text-main: #2D3748;
- --text-sub: #718096;
- --border-color: #E2E8F0;
--hover-bg: #F7FAFC;
+
+ --text-main: #111827;
+ --text-sub: #6B7280;
+ --error-color: #F21D0D;
+ --border-color: #E2E8F0;
+
+ /* 2. Gradients */
--header-gradient: linear-gradient(90deg, #193833 0%, #1e5149 100%);
--ai-gradient: linear-gradient(180deg, #da8cf1 0%, #8bb1f2 100%);
+
+ /* 3. Spacing & Radius */
--space-xs: 4px;
--space-sm: 8px;
--space-md: 16px;
--space-lg: 32px;
- --space-xl: 64px;
--radius-sm: 4px;
+ --radius-md: 6px;
--radius-lg: 8px;
+ --radius-xl: 12px;
+
+ /* 4. Typography */
--fz-h1: 20px;
--fz-h2: 16px;
--fz-body: 13px;
- --box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
+ --fz-small: 11px;
+
+ /* 5. Shadows */
+ --box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
--box-shadow-lg: 0 10px 20px rgba(0, 0, 0, 0.1);
+ --box-shadow-modal: 0 25px 50px -12px rgba(0,0,0,0.5);
+
+ /* 6. Layout Constants */
+ --topbar-h: 36px;
}
/* Base Reset */
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
+* { margin: 0; padding: 0; box-sizing: border-box; }
body {
- font-family: 'Pretendard', sans-serif;
+ font-family: 'Pretendard', -apple-system, sans-serif;
font-size: var(--fz-body);
color: var(--text-main);
background: var(--bg-default);
min-height: 100vh;
}
-/* 메일 관리자 전용: 전체 스크롤 방지 */
-body:has(.mail-wrapper) {
- height: 100vh;
- overflow: hidden;
-}
+/* Page Specific Overrides */
+body:has(.mail-wrapper) { height: 100vh; overflow: hidden; }
-input, select, textarea, button {
- font-family: 'Pretendard', sans-serif;
-}
+input, select, textarea, button { font-family: inherit; }
+a { text-decoration: none; color: inherit; }
+button { cursor: pointer; border: none; transition: all 0.2s ease; }
-a {
- text-decoration: none;
- color: inherit;
-}
-
-button {
- cursor: pointer;
- border: none;
- font-family: inherit;
- transition: all 0.2s ease;
-}
-
-/* Layout Utilities */
-.flex-center {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.flex-between {
- display: flex;
- align-items: center;
- justify-content: space-between;
-}
+/* Utilities */
+.flex-center { display: flex; align-items: center; justify-content: center; }
+.flex-between { display: flex; align-items: center; justify-content: space-between; }
+.text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Components: Topbar */
.topbar {
@@ -84,198 +74,97 @@ button {
padding: 0 var(--space-lg);
position: fixed;
top: 0;
- height: 36px;
+ height: var(--topbar-h);
display: flex;
align-items: center;
- z-index: 1000;
-}
-
-.topbar-header {
- margin-right: 60px;
- font-weight: 700;
-}
-
-.topbar-header h2 {
- font-size: 16px;
- color: white;
-}
-
-.nav-list {
- display: flex;
- list-style: none;
- gap: var(--space-sm);
-}
-
-.nav-item {
- padding: 4px 8px;
- border-radius: 4px;
- color: rgba(255, 255, 255, 0.8);
- transition: 0.2s;
- font-size: 14px;
- cursor: pointer;
-}
-
-.nav-item:hover {
- background: var(--primary-lv-1);
- color: #fff;
-}
-
-.nav-item.active {
- background: var(--primary-lv-0);
- color: var(--primary-color) !important;
- font-weight: 700;
-}
-
-/* Modals */
-.modal-overlay {
- display: none;
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.6);
z-index: 2000;
- justify-content: center;
- align-items: center;
}
+.topbar-header h2 { font-size: 16px; color: white; margin-right: 60px; font-weight: 700; }
+.nav-list { display: flex; list-style: none; gap: var(--space-sm); }
+.nav-item {
+ padding: 4px 12px; border-radius: var(--radius-sm);
+ color: rgba(255, 255, 255, 0.8); font-size: 14px;
+}
+.nav-item:hover { background: var(--primary-lv-8); color: #fff; }
+.nav-item.active { background: var(--primary-lv-0); color: var(--primary-color) !important; font-weight: 700; }
+/* Components: Modals */
+.modal-overlay {
+ display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
+ background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(4px);
+ z-index: 3000; justify-content: center; align-items: center;
+}
.modal-content {
- background: white;
- padding: 24px;
- border-radius: 12px;
- width: 90%;
- max-width: 500px;
- box-shadow: var(--box-shadow-lg);
+ background: white; padding: 24px; border-radius: var(--radius-xl);
+ width: 90%; max-width: 500px; box-shadow: var(--box-shadow-modal);
}
-
.modal-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
- border-bottom: 1px solid var(--border-color);
- padding-bottom: 12px;
+ display: flex; justify-content: space-between; align-items: center;
+ margin-bottom: 20px; border-bottom: 1px solid var(--border-color); padding-bottom: 12px;
}
+.modal-header h3 { margin: 0; font-size: 16px; color: var(--primary-color); font-weight: 700; }
+.modal-close { cursor: pointer; font-size: 24px; color: var(--text-sub); line-height: 1; }
+.modal-close:hover { color: var(--text-main); }
-.modal-header h3 {
- margin: 0;
- font-size: 16px;
-}
+/* Components: Data Tables */
+.data-table { width: 100%; border-collapse: collapse; font-size: 12px; }
+.data-table th, .data-table td { padding: 10px 8px; border-bottom: 1px solid var(--border-color); text-align: left; }
+.data-table th { color: var(--text-sub); font-weight: 600; background: var(--bg-muted); }
+.data-table tr:hover { background: var(--hover-bg); }
-.modal-close {
- cursor: pointer;
- font-size: 20px;
+/* Components: Buttons (Unified) */
+.btn {
+ display: inline-flex; align-items: center; justify-content: center; gap: 8px;
+ padding: 8px 16px; border-radius: var(--radius-lg); font-weight: 600; font-size: 13px;
}
+.btn-primary { background: var(--primary-color); color: #fff; }
+.btn-primary:hover { background: var(--primary-hover); transform: translateY(-1px); }
+.btn-secondary { background: #f1f3f5; color: #495057; }
+.btn-secondary:hover { background: #e9ecef; }
+.btn-danger { background: #fee2e2; color: #dc2626; }
+.btn-danger:hover { background: #fecaca; }
-/* Modal Form Elements */
-.select-group {
- margin-bottom: 16px;
- text-align: left;
-}
+/* Existing Utils - Compatibility */
+._button-small { @extend .btn; padding: 6px 14px; font-size: 12px; background: var(--primary-color); color: #fff; border-radius: 6px; }
+._button-medium { @extend .btn; padding: 10px 20px; background: var(--primary-color); color: #fff; border-radius: 6px; font-weight: 700; }
+.sync-btn { background: var(--primary-color); color: #fff; padding: 8px 16px; border-radius: 8px; font-size: 13px; font-weight: 600; }
-.select-group label {
- display: block;
- font-size: 12px;
- font-weight: 700;
- color: var(--text-sub);
- margin-bottom: 6px;
-}
+/* Badges */
+.badge { padding: 2px 8px; border-radius: 20px; font-size: 11px; font-weight: 700; display: inline-block; background: #eee; }
-.modal-select {
- width: 100%;
- padding: 10px;
- border: 1px solid var(--border-color);
- border-radius: 6px;
- font-size: 14px;
- background: #fff;
- outline: none;
-}
+/* Status Colors (Common) */
+.bg-success { background: #e8f5e9; color: #2e7d32; }
+.bg-warning { background: #fff8e1; color: #FFBF00; }
+.bg-danger { background: #ffebee; color: #dc2626; }
+.bg-info { background: #e3f2fd; color: #1565c0; }
-.modal-select:focus {
- border-color: var(--primary-color);
-}
+.status-error { background: #fee9e7; }
+.status-warning { background: #fff9e6; }
-/* Data Tables inside Modals */
-.data-table {
- width: 100%;
- border-collapse: collapse;
- font-size: 12px;
-}
-
-.data-table th,
-.data-table td {
- padding: 10px 8px;
- border-bottom: 1px solid var(--border-color);
- text-align: left;
-}
-
-.data-table th {
- color: var(--text-sub);
- font-weight: 600;
- background: var(--bg-muted);
-}
-
-.data-table tr:hover {
- background: var(--hover-bg);
-}
-
-/* Utils: Buttons */
-._button-xsmall {
- padding: 2px 8px;
- font-size: 11px;
- border-radius: 4px;
- background: var(--bg-muted);
- border: 1px solid var(--border-color);
-}
-
-._button-small {
- padding: 6px 14px;
- font-size: 12px;
- border-radius: 6px;
- background: var(--primary-color);
- color: #fff;
- font-weight: 600;
-}
-
-._button-medium {
- padding: 10px 20px;
- background: var(--primary-color);
- color: #fff;
- border-radius: 6px;
- font-weight: 700;
-}
-
-.btn-confirm {
- width: 100%;
- padding: 12px;
- background: var(--primary-color);
- color: white;
- border: none;
- border-radius: 8px;
- font-weight: 700;
- cursor: pointer;
- margin-top: 10px;
-}
+.warning-text { color: #FFBF00; font-weight: 600; }
+.error-text { color: #F21D0D !important; font-weight: 700; }
/* Spinner */
.spinner {
- display: none;
- width: 16px;
- height: 16px;
- border: 2px solid rgba(255, 255, 255, .3);
- border-radius: 50%;
- border-top-color: #fff;
- animation: spin 1s ease-in-out infinite;
+ display: none; width: 16px; height: 16px; border: 2px solid rgba(255, 255, 255, .3);
+ border-radius: 50%; border-top-color: #fff; animation: spin 1s ease-in-out infinite;
}
+@keyframes spin { to { transform: rotate(360deg); } }
-@keyframes spin {
- to { transform: rotate(360deg); }
+/* Modals (Refined) */
+.modal-overlay {
+ display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
+ background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(4px);
+ z-index: 3000; justify-content: center; align-items: center;
}
-
-.badge {
- background: #eee;
- padding: 2px 6px;
- border-radius: 4px;
- font-size: 11px;
+.modal-content {
+ background: white; padding: 24px; border-radius: var(--radius-xl);
+ width: 90%; max-width: 500px; box-shadow: var(--box-shadow-modal);
}
+.modal-header {
+ display: flex; justify-content: space-between; align-items: center;
+ margin-bottom: 20px; border-bottom: 1px solid var(--border-color); padding-bottom: 12px;
+}
+.modal-header h3 { margin: 0; font-size: 16px; color: var(--primary-color); font-weight: 700; }
+.modal-close { cursor: pointer; font-size: 24px; color: var(--text-sub); line-height: 1; transition: 0.2s; }
+.modal-close:hover { color: var(--text-main); }