feat: implement unified schema mapper, enhance UI/UX with responsive design, and optimize asset log logic

This commit is contained in:
2026-04-23 18:00:10 +09:00
parent bb1cc36d01
commit 9365af4522
21 changed files with 1129 additions and 892 deletions

View File

@@ -1,7 +1,67 @@
:root {
--primary-color: #1E5149;
--primary-hover: #153c36;
--primary-light: #edf2f1;
/* --- System Colors (Added) --- */
--color-red: #F21D0D;
--color-pink: #E8175E;
--color-magenta: #B92ED1;
--color-purple: #6D3DC2;
--color-navy: #4255bd;
--color-blue: #0D8DF2;
--color-cyan: #03AEFC;
--color-green: #4DB251;
--color-yellow: #FFBF00;
--color-orange: #FF9800;
--color-dahong: #FF3D00;
--color-brown: #A0705F;
--color-iron: #7F7F7F;
--color-steel: #688897;
--color-red-light: #FEE9E7;
--color-pink-light: #FDE8EF;
--color-magenta-light: #F8EBFB;
--color-purple-light: #F1ECF9;
--color-navy-light: #EDEEF9;
--color-blue-light: #E7F4FE;
--color-cyan-light: #E6F7FF;
--color-green-light: #EEF8EE;
--color-yellow-light: #FFF9E6;
--color-orange-light: #FFF5E6;
--color-dahong-light: #FFECE6;
--color-brown-light: #F6F1EF;
--color-iron-light: #F3F3F3;
--color-steel-light: #F0F4F5;
--color-red-medium: #FAA59E;
--color-pink-medium: #F6A2BF;
--color-magenta-medium: #E3ABEC;
--color-purple-medium: #C5B1E7;
--color-navy-medium: #B3BBE5;
--color-blue-medium: #9ED1FA;
--color-cyan-medium: #9ADFFE;
--color-green-medium: #B8E0B9;
--color-yellow-medium: #FFE599;
--color-orange-medium: #FFD699;
--color-dahong-medium: #FFB199;
--color-brown-medium: #D9C6BF;
--color-iron-medium: #CCCCCC;
--color-steel-medium: #C3CFD5;
/* --- Primary Brand Levels --- */
--primary-lv-0: #E9EEED;
--primary-lv-1: #D2DCDB;
--primary-lv-2: #A5B9B6;
--primary-lv-3: #789792;
--primary-lv-4: #4B746D;
--primary-lv-5: #35635C;
--primary-lv-6: #1E5149;
--primary-lv-7: #1B443D;
--primary-lv-8: #193833;
--primary-lv-9: #162A27;
/* --- Legacy Aliases (Maintained for compatibility) --- */
--primary-color: var(--primary-lv-6);
--primary-hover: var(--primary-lv-5);
--primary-light: var(--primary-lv-0);
--text-main: #111827;
--text-muted: #6B7280;
--border-color: #E5E7EB;
@@ -9,7 +69,7 @@
--bg-light: #FAFAFA;
--sidebar-bg: #ffffff;
--white: #FFFFFF;
--danger: #dc2626;
--danger: var(--color-red);
--dash-primary: #6cc020;
--dash-light: #f2f9ec;
@@ -22,14 +82,15 @@
box-sizing: border-box;
margin: 0;
padding: 0;
letter-spacing: -0.02em;
/* 모든 요소에 자간 규칙 일괄 적용 */
}
body {
font-family: 'Pretendard Variable', Pretendard, sans-serif;
font-family: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, system-ui, Roboto, 'Helvetica Neue', 'Segoe UI', 'Apple SD Gothic Neo', 'Noto Sans KR', 'Malgun Gothic', sans-serif;
color: var(--text-main);
background-color: var(--bg-color);
line-height: 1.5;
letter-spacing: -0.02em;
font-size: 14px;
overflow: hidden;
}
@@ -57,14 +118,32 @@ body {
gap: 1.5rem;
}
.brand {
display: flex;
align-items: center;
gap: 0.75rem;
}
.main-logo {
height: 34px;
width: auto;
}
.brand h1 {
font-size: 1.2rem;
font-size: 1.1rem;
/* 전체적으로 살짝 축소 */
font-weight: 800;
color: var(--text-main);
white-space: nowrap;
margin-right: 1rem;
}
.brand h1 span { color: var(--primary-color); }
.brand h1 .sub-title {
font-size: 0.85rem;
/* 영문 제목은 더 작게 */
color: var(--primary-color);
font-weight: 600;
margin-left: 0.25rem;
}
.integrated-nav {
flex: 1;
@@ -93,7 +172,7 @@ body {
}
.lnb-shelf {
display: none;
display: none;
align-items: center;
gap: 0.25rem;
padding: 0 0.75rem;
@@ -118,7 +197,11 @@ body {
white-space: nowrap;
}
.lnb-item:hover { color: var(--primary-color); background-color: var(--bg-color); }
.lnb-item:hover {
color: var(--primary-color);
background-color: var(--bg-color);
}
.lnb-item.active {
color: var(--primary-color);
background-color: var(--primary-light);
@@ -126,12 +209,23 @@ body {
}
@keyframes fadeIn {
from { opacity: 0; transform: translateX(-5px); }
to { opacity: 1; transform: translateX(0); }
from {
opacity: 0;
transform: translateX(-5px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* --- Global Actions & Buttons --- */
.header-actions { display: flex; gap: 0.3rem; align-items: center; }
.header-actions {
display: flex;
gap: 0.3rem;
align-items: center;
}
.btn {
display: inline-flex;
@@ -145,30 +239,87 @@ body {
cursor: pointer;
height: 28px;
line-height: 1;
white-space: nowrap; /* 텍스트 줄바꿈 방지 */
flex-shrink: 0; /* 크기 찌그러짐 방지 */
}
.btn i, .btn svg { width: 12px !important; height: 12px !important; }
.btn i,
.btn svg {
width: 12px !important;
height: 12px !important;
}
.btn-primary { background-color: var(--primary-color); color: var(--white); border: 1px solid var(--primary-color); }
.btn-outline { background-color: transparent; color: var(--text-muted); border: 1px solid var(--border-color); }
.btn-danger { color: var(--danger) !important; border-color: var(--danger) !important; }
.btn-primary {
background-color: var(--primary-color);
color: var(--white);
border: 1px solid var(--primary-color);
}
.btn-outline {
background-color: transparent;
color: var(--text-muted);
border: 1px solid var(--border-color);
}
.btn-danger {
color: var(--danger) !important;
border-color: var(--danger) !important;
}
/* --- Layout Frame --- */
.content-area {
flex: 1;
padding: 2rem;
overflow-y: auto;
padding: 0 2rem;
/* 좌우 여백만 유지 */
overflow: hidden;
/* 전체 스크롤 차단 */
display: flex;
flex-direction: column;
}
.view-container {
flex: 1;
width: 100%;
display: flex;
flex-direction: column;
gap: 1.5rem;
overflow: hidden;
/* 내부 스크롤을 유도하기 위해 설정 */
}
.hidden { display: none !important; }
.text-nowrap { white-space: nowrap; }
/* --- Footer --- */
.main-footer {
height: 40px;
background-color: var(--white);
border-top: 1px solid var(--border-color);
display: flex;
align-items: center;
justify-content: flex-end;
padding: 0 1.5rem;
flex-shrink: 0;
}
.main-footer p {
font-family: 'Pretendard Variable', Pretendard, sans-serif;
font-size: 0.75rem;
font-weight: 300;
line-height: 1.25rem;
letter-spacing: -0.0175rem;
color: #777777;
user-select: none;
pointer-events: all;
-webkit-user-drag: none;
margin: 0;
padding: 0;
box-sizing: border-box;
}
.hidden {
display: none !important;
}
.text-nowrap {
white-space: nowrap;
}
/* --- Utility Styles --- */
.badge {
@@ -178,8 +329,16 @@ body {
font-weight: 700;
white-space: nowrap;
}
.badge-primary { background-color: var(--primary-color); color: white; }
.badge-muted { background-color: #9CA3AF; color: white; }
.badge-primary {
background-color: var(--primary-color);
color: white;
}
.badge-muted {
background-color: #9CA3AF;
color: white;
}
.text-tag {
color: var(--text-muted);
@@ -190,4 +349,27 @@ body {
background-color: var(--bg-light);
}
.font-bold { font-weight: 700; }
.font-bold {
font-weight: 700;
}
/* --- Responsive Design (Tablet & Mobile) --- */
@media (max-width: 1200px) {
.header-container { gap: 0.75rem; padding: 0 1rem; }
.brand h1 { font-size: 1rem; }
.brand h1 .sub-title { font-size: 0.75rem; }
}
@media (max-width: 992px) {
.main-header { height: auto; padding: 0.5rem 0; }
.header-container { flex-direction: column; align-items: flex-start; gap: 0.5rem; }
.integrated-nav { width: 100%; justify-content: flex-start; border-top: 1px solid var(--border-color); padding-top: 0.5rem; }
.header-actions { width: 100%; justify-content: flex-end; padding-top: 0.5rem; }
.content-area { padding: 0 1rem; }
}
@media (max-width: 768px) {
.brand h1 .sub-title { display: none; } /* 아주 좁은 화면에선 영문명 숨김 */
.header-actions .btn span { display: none; } /* 버튼 텍스트 숨기고 아이콘만 표시 */
.header-actions .btn { padding: 0 0.5rem; }
}

View File

@@ -1,112 +1,24 @@
/* ITAM Guide Modal Styles */
:root {
--guide-modal-width: 1060px;
--guide-modal-height: 92vh;
--guide-primary: #1E5149;
--guide-accent: #6cc020;
}
/* ITAM Guide Modal Styles - Updated to match common modal style */
/* Floating Trigger Button - REMOVED (now in header) */
.guide-trigger {
display: none;
}
/* Modal Overlay */
.guide-overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(4px);
z-index: 2000;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
}
.guide-overlay.active {
opacity: 1;
visibility: visible;
}
/* Guide Modal */
.guide-modal {
width: var(--guide-modal-width);
max-width: 94vw;
height: var(--guide-modal-height);
background-color: #ffffff;
border-radius: 14px;
overflow: hidden;
box-shadow: 0 24px 60px rgba(0,0,0,0.3);
display: flex;
flex-direction: column;
transform: translateY(20px) scale(0.97);
opacity: 0;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.guide-overlay.active .guide-modal {
transform: translateY(0) scale(1);
opacity: 1;
}
/* Header */
.guide-header {
padding: 1.1rem 1.5rem;
/* Tab Container (below header) */
.guide-tabs-container {
background: #FAFAFA;
border-bottom: 1px solid var(--border-color);
display: flex;
justify-content: space-between;
align-items: center;
background: linear-gradient(135deg, var(--guide-primary), #2a6d63);
color: white;
flex-shrink: 0;
}
.guide-header h2 {
font-size: 1.15rem;
font-weight: 700;
display: flex;
align-items: center;
gap: 10px;
margin: 0;
}
.btn-close-guide {
background: rgba(255, 255, 255, 0.12);
border: none;
color: white;
cursor: pointer;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.2s;
}
.btn-close-guide:hover {
background: rgba(255, 255, 255, 0.3);
}
/* ===== Tab Navigation ===== */
.guide-tabs {
display: flex;
border-bottom: 1px solid var(--border-color);
background: #f8faf9;
padding: 0 1.5rem;
flex-shrink: 0;
gap: 2px;
overflow-x: auto;
}
.guide-tabs {
display: flex;
gap: 2px;
overflow-x: auto;
scrollbar-width: none;
}
.guide-tabs::-webkit-scrollbar { display: none; }
.guide-tab {
padding: 0.7rem 1rem;
padding: 0.75rem 1.25rem;
font-size: 13px;
font-weight: 600;
color: var(--text-muted);
@@ -114,37 +26,27 @@
border-bottom: 2px solid transparent;
transition: all 0.2s ease;
white-space: nowrap;
position: relative;
top: 1px;
}
.guide-tab:hover {
color: var(--guide-primary);
color: var(--primary-color);
background: rgba(30, 81, 73, 0.04);
}
.guide-tab.active {
color: var(--guide-primary);
border-bottom-color: var(--guide-primary);
color: var(--primary-color);
border-bottom-color: var(--primary-color);
background: white;
}
/* ===== Content Area ===== */
/* Content Area */
.guide-body {
flex: 1;
overflow-y: auto;
padding: 0;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE/Edge */
}
.guide-body::-webkit-scrollbar {
display: none; /* Chrome/Safari */
padding-bottom: 2rem;
}
.guide-tab-panel {
display: none;
padding: 1.5rem 2rem 2rem;
padding: 1.5rem 0;
animation: guideFadeIn 0.3s ease;
}
@@ -157,12 +59,12 @@
to { opacity: 1; transform: translateY(0); }
}
/* ===== Section Styles ===== */
/* Section Styles */
.guide-section {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1.5rem;
margin-bottom: 2rem;
}
.guide-section:last-child {
@@ -171,84 +73,66 @@
.guide-section h3 {
font-size: 1rem;
padding-bottom: 0.4rem;
border-bottom: 2px solid var(--guide-primary);
color: var(--guide-primary);
padding-bottom: 0.5rem;
border-bottom: 2px solid var(--primary-color);
color: var(--primary-color);
margin: 0;
display: flex;
align-items: center;
gap: 8px;
}
.guide-section h4 {
font-size: 0.9rem;
color: var(--text-main);
margin: 0.6rem 0 0.2rem;
font-weight: 700;
}
.guide-text {
font-size: 13px;
color: var(--text-muted);
color: var(--text-main);
line-height: 1.7;
margin: 0;
}
.guide-text strong {
color: var(--text-main);
}
/* ===== Flowchart ===== */
/* Flowchart Styles */
.flow-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
padding: 1.25rem;
background-color: #f8faf9;
border-radius: 12px;
border: 1px dashed #d0d7d5;
gap: 0.75rem;
padding: 1.5rem;
background-color: #f9fafb;
border-radius: 8px;
border: 1px solid var(--border-color);
}
.flow-row {
display: flex;
width: 100%;
gap: 0.75rem;
align-items: stretch;
gap: 1rem;
align-items: center;
}
.flow-step {
flex: 1;
background: white;
padding: 0.65rem 0.9rem;
border-radius: 8px;
padding: 1rem;
border-radius: 6px;
border: 1px solid var(--border-color);
display: flex;
align-items: flex-start;
gap: 10px;
transition: transform 0.2s, box-shadow 0.2s;
}
.flow-step:hover {
transform: translateY(-2px);
box-shadow: 0 4px 14px rgba(0,0,0,0.06);
border-color: var(--guide-primary);
gap: 12px;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.flow-step .step-number {
width: 22px;
height: 22px;
min-width: 22px;
width: 24px;
height: 24px;
min-width: 24px;
border-radius: 50%;
background-color: var(--guide-primary);
background-color: var(--primary-color);
color: white;
font-size: 11px;
font-size: 12px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 1px;
}
.flow-step .step-label {
@@ -259,91 +143,46 @@
}
.flow-step .step-desc {
font-size: 11.5px;
font-size: 12px;
color: var(--text-muted);
line-height: 1.5;
margin-top: 2px;
}
.flow-arrow {
color: #b5c4c0;
width: 16px !important;
height: 16px !important;
margin-top: 4px;
}
.flow-arrow-right {
color: #b5c4c0;
width: 16px !important;
height: 16px !important;
color: var(--text-muted);
display: flex;
align-items: center;
flex-shrink: 0;
}
/* ===== Info Table ===== */
/* Info Table Style */
.guide-info-table {
width: 100%;
border-collapse: collapse;
font-size: 12.5px;
margin-top: 0.5rem;
font-size: 13px;
}
.guide-info-table th {
background: #f0f4f3;
color: var(--guide-primary);
background: #f8faf9;
color: var(--primary-color);
font-weight: 700;
padding: 0.5rem 0.75rem;
padding: 0.75rem;
text-align: left;
border-bottom: 2px solid var(--guide-primary);
border-bottom: 1px solid var(--border-color);
}
.guide-info-table td {
padding: 0.45rem 0.75rem;
border-bottom: 1px solid var(--border-color);
padding: 0.75rem;
border-bottom: 1px solid #f3f4f6;
color: var(--text-main);
line-height: 1.5;
}
.guide-info-table tr:hover td {
background: #f8faf9;
}
/* ===== Tip Box ===== */
/* Tip Box Style */
.guide-tip {
background: linear-gradient(135deg, #f0f9eb, #e8f5e0);
border-left: 4px solid var(--guide-accent);
border-radius: 0 8px 8px 0;
padding: 0.75rem 1rem;
font-size: 12.5px;
color: #2d5016;
background: var(--primary-light);
border-left: 4px solid var(--primary-color);
padding: 1rem;
font-size: 13px;
color: var(--primary-color);
line-height: 1.6;
}
.guide-tip strong {
color: #1a3a0a;
}
/* ===== Warning Box ===== */
.guide-warn {
background: linear-gradient(135deg, #fff8ed, #fff3e0);
border-left: 4px solid #ff9800;
border-radius: 0 8px 8px 0;
padding: 0.75rem 1rem;
font-size: 12.5px;
color: #7a4a00;
line-height: 1.6;
}
/* ===== Badge ===== */
.guide-badge {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: 700;
}
.guide-badge.green { background: #e6f4ea; color: #137333; }
.guide-badge.orange { background: #fff4e5; color: #b45309; }
.guide-badge.blue { background: #e8f0fe; color: #1a56db; }
.guide-badge.red { background: #fce8e6; color: #c5221f; }

View File

@@ -4,11 +4,10 @@
display: flex;
flex-wrap: wrap;
gap: 1.25rem;
background-color: var(--white);
padding: 1.5rem;
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 1.5rem 0; /* 좌우 패딩 제거, 상하 여백 유지 */
border-bottom: 1px solid var(--border-color); /* 하단 구분선만 남김 */
align-items: flex-end;
margin-bottom: 0.5rem;
}
.search-item {
@@ -23,7 +22,7 @@
.search-item label {
font-size: 11px;
font-weight: 800;
font-weight: 700;
color: var(--text-muted);
}
@@ -35,70 +34,92 @@
border-radius: 4px;
font-size: 14px;
outline: none;
background-color: var(--white);
}
/* 셀렉트 박스 화살표 여백 절대 고정 (수정 금지) */
.search-item select {
padding-right: 2.5rem;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-9'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 0.75rem center;
padding-right: 2.5rem !important;
cursor: pointer;
}
.search-item input:focus,
.search-item select:focus {
border-color: var(--primary-color);
}
/* 필터 초기화 버튼 크기 조정 (입력창 높이 38px에 맞춤) */
.btn-reset {
margin-left: auto;
height: 38px !important;
padding: 0 0.8rem !important;
font-size: 12px !important;
display: inline-flex !important;
align-items: center !important;
gap: 0.35rem !important;
border-radius: 4px !important;
color: var(--text-muted) !important;
padding: 0 1.2rem !important;
display: inline-flex;
align-items: center;
justify-content: center;
}
.table-container {
flex: 1;
background-color: var(--white);
border-top: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-color);
border-left: none;
border-right: none;
overflow: auto;
max-height: calc(100vh - 240px);
}
table {
width: 100%;
border-collapse: collapse;
table-layout: auto;
}
th, td {
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--border-color);
text-align: left;
padding: 0.8rem 1.2rem;
border-bottom: 1px solid #F3F4F6;
text-align: left; /* 기본은 좌측 정렬 */
white-space: nowrap;
}
th {
background-color: #FAFAFA;
font-weight: 700;
font-size: 13px;
font-weight: 600;
color: var(--text-muted);
font-size: 12px;
position: sticky;
top: 0;
z-index: 10;
box-shadow: inset 0 -1px 0 var(--border-color);
text-transform: uppercase;
text-transform: none;
}
td {
font-size: 14px;
font-size: 13px;
color: var(--text-main);
font-weight: 400;
}
tbody tr:hover {
background-color: #F9FAFB;
}
.btn-sm {
padding: 0.25rem 0.5rem;
font-size: 11px;
height: 24px;
/* 정렬 클래스 강제 적용 */
.text-center { text-align: center !important; }
.text-right { text-align: right !important; }
.text-left { text-align: left !important; }
.btn-icon {
padding: 0.25rem;
border: none;
background: none;
cursor: pointer;
color: var(--text-muted);
transition: color 0.2s;
}
.btn-icon:hover {
color: var(--primary-color);
}
.btn-icon svg {
width: 16px;
height: 16px;
}