From 15c03835efef36a727a8da41c3d4c6f04d16342f Mon Sep 17 00:00:00 2001 From: zenn Date: Thu, 2 Apr 2026 23:16:28 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A6=B4=EB=A6=AC=EC=8A=A4:=20v1.4.34=20?= =?UTF-8?q?=EB=9D=BC=EC=9D=B4=ED=8A=B8=EB=AA=A8=EB=93=9C=20=EC=83=89?= =?UTF-8?q?=EC=83=81=20=EC=B2=B4=EA=B3=84=20=EC=9E=AC=EC=A0=95=EB=B9=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/history.md | 4 ++ docs/todo.md | 1 + docs/update.md | 7 ++ frontend/src/App.vue | 8 +-- frontend/src/style.css | 68 +++++++++++++------- frontend/src/views/FavoriteTierListsView.vue | 1 + frontend/src/views/HomeView.vue | 14 ++-- frontend/src/views/MyTierListsView.vue | 2 +- frontend/src/views/SearchResultsView.vue | 1 + frontend/src/views/TopicHubView.vue | 2 +- 10 files changed, 72 insertions(+), 36 deletions(-) diff --git a/docs/history.md b/docs/history.md index 976dd08..1a6e8c0 100644 --- a/docs/history.md +++ b/docs/history.md @@ -612,6 +612,10 @@ - 게임 이미지 경로는 저장 시 상대 경로(`/uploads/...`)를 유지하는 방향으로 정리했다. - 현재 단계에서는 구조 변경 비용을 고려해 DB를 유지하되, 운영/확장성 요구가 커지기 전 RDB 이관 판단이 필요하다고 기록했다. +## 2026-04-02 v1.4.34 +- 라이트모드는 단순 토글 존재만으로 충분하지 않고, 셸/카드/버튼/오버레이가 같은 색 문법을 공유해야 품질이 안정된다고 판단해 공통 토큰을 다시 정리했다. +- 홈 카드 즐겨찾기 버튼처럼 다크 전용 하드코딩이 남아 있으면 전체 인상이 쉽게 무너지므로, 이후 테마 보정은 공통 변수 우선 원칙으로 계속 가져가기로 했다. + ## 2026-03-19 - 초기 저장소는 빠른 구현을 위해 `lowdb(JSON 파일)`를 채택했다. - 인증은 JWT 대신 서버 세션(`express-session` + `session-file-store`)을 사용했다. diff --git a/docs/todo.md b/docs/todo.md index 98e9ab0..c8ddd4c 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -113,6 +113,7 @@ - 관리자 게임 아이템 순서 저장은 추가됐으므로, 다음 단계에서는 새 아이템 추가 직후 `자동 맨 앞 배치`와 `관리자 수동 고정 순서`의 우선순위를 실제 운영 흐름 기준으로 한 번 더 QA한다. - 관리자 템플릿 요청 미리보기는 실제 완성본 iframe 방식과의 체감 차이를 마지막으로 한 번 더 QA한다. - 라이트모드/다크모드 2차 보정까지 반영했으므로, 남은 작업은 전체 화면을 실제 사용 흐름으로 돌려 보며 대비·명도·아이콘 가독성을 미세하게 QA하는 최종 테마 점검 단계로 가져간다. +- 라이트모드 공통 토큰 재정비와 카드/아바타/즐겨찾기 버튼 보정까지 반영했으므로, 다음 QA에서는 로그인/홈/주제 허브/에디터/관리자 순으로 실제 플로우를 돌리며 남은 하드코딩 색과 과한 대비가 없는지 확인한다. - 관리자용 티어표 승인/숨김 처리, 아이템 정렬 UI를 추가한다. - 회원 일괄 작업(다중 선택, 일괄 비밀번호 초기화, 활동 저조 계정 정리) 같은 관리 보조 기능을 추가한다. - 티어 행 프리셋 저장, 색상 관리, 행 복제 같은 고급 편집 기능을 추가한다. diff --git a/docs/update.md b/docs/update.md index dffc9e3..0ffadfc 100644 --- a/docs/update.md +++ b/docs/update.md @@ -1104,6 +1104,13 @@ - **티어표 데이터 정규화**: 게임 이미지 경로가 절대 로컬 URL로 저장되지 않도록 저장/조회 시 `/uploads/...` 상대 경로로 정규화 - **프로젝트 점검 결과 문서화**: DB 구조, 화면-파일 매핑, 코딩 규칙, 기술 명세, 남은 위험 요소를 `docs/`에 신규 정리 +## 2026-04-02 v1.4.34 +- **라이트모드 팔레트 재정비**: 공통 라이트 테마 색상을 회색 위주에서 더 정돈된 청회색 계열로 다시 잡고, 셸/레일/메인/카드 표면 대비를 처음부터 재조정 +- **공통 토큰 확장**: 강조색 강도, 강조 배경, 오버레이 스크림, 아바타 테두리, 즐겨찾기 버튼 상태색을 공통 변수로 분리해 화면별 하드코딩을 줄임 +- **홈 카드 보정**: 주제 카드 즐겨찾기 버튼이 라이트모드에서 검은 플로팅 버튼처럼 뜨던 문제를 테마 변수 기반으로 수정 +- **목록 카드 통일**: 주제 허브/나의 티어표/즐겨찾기/검색 결과 카드의 아바타 테두리를 공통 토큰으로 맞춰 라이트모드에서 카드 밀도가 덜 어색하게 보이도록 정리 +- **전역 셸 보정**: 백엔드 점검 안내 버튼과 가이드 모달 오버레이도 라이트모드에 맞는 공통 색상 체계로 통일 + ## 2026-03-19 v0.1.2 - **로그인 UI 개선**: 로그인 카드 중앙 배치, 중복 타이틀 제거, 입력 overflow 수정, 엔터로 로그인/회원가입 제출 - **안내문 조건화**: “첫 회원가입 계정은 admin” 문구는 유저가 0명일 때만 표시(`/api/auth/meta`) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index a0e2f44..f86f232 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -748,8 +748,8 @@ function reloadApp() { min-width: 128px; padding: 12px 18px; border-radius: 999px; - border: 1px solid rgba(98, 170, 255, 0.32); - background: rgba(98, 170, 255, 0.18); + border: 1px solid var(--theme-accent-soft-strong); + background: var(--theme-accent-soft); color: var(--theme-text-strong); font-weight: 700; cursor: pointer; @@ -929,7 +929,7 @@ function reloadApp() { border-radius: 999px; object-fit: cover; flex: 0 0 auto; - border: 1px solid rgba(255, 255, 255, 0.14); + border: 1px solid var(--theme-avatar-border); background: var(--theme-surface-soft-3); } @@ -1453,7 +1453,7 @@ function reloadApp() { align-items: center; justify-content: center; padding: 32px 20px; - background: rgba(0, 0, 0, 0.62); + background: var(--theme-overlay-scrim); backdrop-filter: blur(10px); } diff --git a/frontend/src/style.css b/frontend/src/style.css index 6821ad6..a1dd68c 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -33,37 +33,59 @@ --theme-danger-bg: rgba(239, 68, 68, 0.1); --theme-danger-border: rgba(239, 68, 68, 0.18); --theme-accent-bg: rgba(76, 133, 245, 0.92); + --theme-accent-strong: rgba(137, 183, 255, 0.96); + --theme-accent-soft: rgba(76, 133, 245, 0.18); + --theme-accent-soft-strong: rgba(76, 133, 245, 0.3); --theme-accent-text: #fff; + --theme-overlay-scrim: rgba(0, 0, 0, 0.62); + --theme-avatar-border: rgba(255, 255, 255, 0.14); + --theme-favorite-bg: rgba(12, 14, 18, 0.72); + --theme-favorite-border: rgba(255, 255, 255, 0.14); + --theme-favorite-icon: rgba(255, 255, 255, 0.94); + --theme-favorite-active-bg: rgba(54, 45, 10, 0.92); + --theme-favorite-active-border: rgba(255, 216, 107, 0.28); + --theme-favorite-active-icon: #ffd86b; --theme-icon-filter: brightness(0) saturate(100%) invert(94%) sepia(6%) saturate(207%) hue-rotate(186deg) brightness(96%) contrast(92%); } :root[data-theme='light'] { - --theme-body-bg: #e7ebf2; - --theme-shell-bg: rgba(237, 241, 247, 0.98); - --theme-rail-bg: rgba(243, 246, 251, 0.97); - --theme-main-bg: rgba(232, 236, 243, 0.98); - --theme-workspace-bg: rgba(247, 249, 252, 0.96); - --theme-card-bg: rgba(252, 253, 255, 0.98); - --theme-card-bg-hover: rgba(244, 247, 251, 0.98); - --theme-card-border: rgba(31, 41, 55, 0.11); - --theme-card-shadow: 0 18px 34px rgba(31, 41, 55, 0.07); - --theme-surface-soft: rgba(30, 41, 59, 0.055); - --theme-surface-soft-2: rgba(30, 41, 59, 0.075); - --theme-surface-soft-3: rgba(30, 41, 59, 0.105); - --theme-pill-bg: rgba(30, 41, 59, 0.045); - --theme-border: rgba(30, 41, 59, 0.11); - --theme-border-strong: rgba(30, 41, 59, 0.16); - --theme-text: rgba(20, 27, 40, 0.92); - --theme-text-strong: rgba(10, 15, 28, 0.98); - --theme-text-muted: rgba(55, 65, 81, 0.76); - --theme-text-soft: rgba(75, 85, 99, 0.72); - --theme-text-faint: rgba(100, 116, 139, 0.88); - --theme-thumb-fallback-bg: #f6f8fb; - --theme-select-arrow: rgba(55, 65, 81, 0.74); + --theme-body-bg: #eef2f8; + --theme-shell-bg: rgba(241, 245, 251, 0.98); + --theme-rail-bg: rgba(248, 250, 253, 0.98); + --theme-main-bg: rgba(234, 239, 247, 0.98); + --theme-workspace-bg: rgba(250, 252, 255, 0.97); + --theme-card-bg: rgba(255, 255, 255, 0.96); + --theme-card-bg-hover: rgba(246, 249, 253, 0.98); + --theme-card-border: rgba(71, 85, 105, 0.12); + --theme-card-shadow: 0 14px 30px rgba(57, 72, 92, 0.08); + --theme-surface-soft: rgba(75, 85, 99, 0.052); + --theme-surface-soft-2: rgba(75, 85, 99, 0.078); + --theme-surface-soft-3: rgba(75, 85, 99, 0.11); + --theme-pill-bg: rgba(75, 85, 99, 0.048); + --theme-border: rgba(71, 85, 105, 0.12); + --theme-border-strong: rgba(71, 85, 105, 0.18); + --theme-text: rgba(24, 33, 48, 0.93); + --theme-text-strong: rgba(11, 18, 32, 0.98); + --theme-text-muted: rgba(51, 65, 85, 0.78); + --theme-text-soft: rgba(71, 85, 105, 0.76); + --theme-text-faint: rgba(100, 116, 139, 0.9); + --theme-thumb-fallback-bg: #f3f6fb; + --theme-select-arrow: rgba(51, 65, 85, 0.72); --theme-danger-bg: rgba(239, 68, 68, 0.1); --theme-danger-border: rgba(239, 68, 68, 0.22); - --theme-accent-bg: rgba(64, 110, 226, 0.94); + --theme-accent-bg: rgba(56, 105, 226, 0.94); + --theme-accent-strong: rgba(47, 87, 194, 0.96); + --theme-accent-soft: rgba(56, 105, 226, 0.12); + --theme-accent-soft-strong: rgba(56, 105, 226, 0.22); --theme-accent-text: #fff; + --theme-overlay-scrim: rgba(17, 24, 39, 0.28); + --theme-avatar-border: rgba(71, 85, 105, 0.16); + --theme-favorite-bg: rgba(255, 255, 255, 0.9); + --theme-favorite-border: rgba(71, 85, 105, 0.16); + --theme-favorite-icon: rgba(51, 65, 85, 0.92); + --theme-favorite-active-bg: rgba(255, 243, 199, 0.96); + --theme-favorite-active-border: rgba(217, 119, 6, 0.22); + --theme-favorite-active-icon: #b45309; --theme-icon-filter: brightness(0) saturate(100%) invert(14%) sepia(14%) saturate(652%) hue-rotate(182deg) brightness(95%) contrast(91%); } diff --git a/frontend/src/views/FavoriteTierListsView.vue b/frontend/src/views/FavoriteTierListsView.vue index c7958b4..2fb65f8 100644 --- a/frontend/src/views/FavoriteTierListsView.vue +++ b/frontend/src/views/FavoriteTierListsView.vue @@ -223,6 +223,7 @@ onMounted(loadFavorites) height: 22px; border-radius: 9999px; object-fit: cover; + border: 1px solid var(--theme-avatar-border); background: var(--theme-border); flex: 0 0 auto; } diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue index b579dd1..895049b 100644 --- a/frontend/src/views/HomeView.vue +++ b/frontend/src/views/HomeView.vue @@ -165,9 +165,9 @@ function templateThumbUrl(template) { width: 34px; height: 34px; border-radius: 999px; - border: 1px solid rgba(255, 255, 255, 0.14); - background: rgba(15, 15, 15, 0.72); - color: rgba(255, 255, 255, 0.82); + border: 1px solid var(--theme-favorite-border); + background: var(--theme-favorite-bg); + color: var(--theme-favorite-icon); font-size: 17px; line-height: 1; cursor: pointer; @@ -177,16 +177,16 @@ function templateThumbUrl(template) { justify-content: center; } .libraryCard__favorite--active { - background: rgba(54, 45, 10, 0.92); - border-color: rgba(255, 216, 107, 0.28); + background: var(--theme-favorite-active-bg); + border-color: var(--theme-favorite-active-border); } .libraryCard__favoriteIcon { opacity: 0.76; - color: rgba(255, 255, 255, 0.94); + color: var(--theme-favorite-icon); } .libraryCard__favorite--active .libraryCard__favoriteIcon { opacity: 1; - color: #ffd86b; + color: var(--theme-favorite-active-icon); } .libraryCard__thumbWrap { width: 100%; diff --git a/frontend/src/views/MyTierListsView.vue b/frontend/src/views/MyTierListsView.vue index f4ac7a1..2b2e276 100644 --- a/frontend/src/views/MyTierListsView.vue +++ b/frontend/src/views/MyTierListsView.vue @@ -229,7 +229,7 @@ function openList(t) { height: 22px; border-radius: 9999px; object-fit: cover; - border: 1px solid rgba(255, 255, 255, 0.12); + border: 1px solid var(--theme-avatar-border); background: var(--theme-border); flex: 0 0 auto; } diff --git a/frontend/src/views/SearchResultsView.vue b/frontend/src/views/SearchResultsView.vue index de8583b..1f23a05 100644 --- a/frontend/src/views/SearchResultsView.vue +++ b/frontend/src/views/SearchResultsView.vue @@ -215,6 +215,7 @@ watch( height: 22px; border-radius: 9999px; object-fit: cover; + border: 1px solid var(--theme-avatar-border); background: var(--theme-border); flex: 0 0 auto; } diff --git a/frontend/src/views/TopicHubView.vue b/frontend/src/views/TopicHubView.vue index 2709c83..3f6385a 100644 --- a/frontend/src/views/TopicHubView.vue +++ b/frontend/src/views/TopicHubView.vue @@ -319,7 +319,7 @@ watch( height: 22px; border-radius: 9999px; object-fit: cover; - border: 1px solid rgba(255, 255, 255, 0.12); + border: 1px solid var(--theme-avatar-border); background: var(--theme-border); flex: 0 0 auto; }