From 61822345bf5102ce40135a84155aedcb06798e46 Mon Sep 17 00:00:00 2001 From: caadiq Date: Tue, 14 Apr 2026 13:35:39 +0900 Subject: [PATCH] =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83/=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=EB=B0=94=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Layout 배경 그라디언트를 body fixed 배경으로 이동 (스크롤 시 하단 배경 일관성) - 해방 계산기 데스티니 탭 placeholder에 최소 높이 부여 - overlayscrollbars 도입: 메인 스크롤바가 콘텐츠를 밀지 않고 오버레이로 표시 - 내부 스크롤 영역은 얇은 커스텀 스크롤바 유지 Co-Authored-By: Claude Opus 4.6 (1M context) --- frontend/package-lock.json | 18 ++++++++++ frontend/package.json | 2 ++ frontend/src/components/Layout.jsx | 2 +- .../src/features/liberation/Liberation.jsx | 4 +-- frontend/src/index.css | 35 +++++++++++++------ frontend/src/main.jsx | 9 +++++ 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 0a03a0c..fcd56ef 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,6 +14,8 @@ "@tanstack/react-query": "^5.91.0", "dayjs": "^1.11.20", "framer-motion": "^12.23.22", + "overlayscrollbars": "^2.15.1", + "overlayscrollbars-react": "^0.5.6", "react": "^19.2.4", "react-dom": "^19.2.4", "react-router-dom": "^7.14.0" @@ -2552,6 +2554,22 @@ "node": ">= 0.8.0" } }, + "node_modules/overlayscrollbars": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-2.15.1.tgz", + "integrity": "sha512-glX26JwjL+Tkzv0JNOWdW4VozP5dGXO+Wx8+TPrdTEJTSYT/8eJS8yXM+fewjU0nFq/JeCa+X+BqABNjC4YZSA==", + "license": "MIT" + }, + "node_modules/overlayscrollbars-react": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/overlayscrollbars-react/-/overlayscrollbars-react-0.5.6.tgz", + "integrity": "sha512-E5To04bL5brn9GVCZ36SnfGanxa2I2MDkWoa4Cjo5wol7l+diAgi4DBc983V7l2nOk/OLJ6Feg4kySspQEGDBw==", + "license": "MIT", + "peerDependencies": { + "overlayscrollbars": "^2.0.0", + "react": ">=16.8.0" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index ad3957c..c6606a8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,6 +16,8 @@ "@tanstack/react-query": "^5.91.0", "dayjs": "^1.11.20", "framer-motion": "^12.23.22", + "overlayscrollbars": "^2.15.1", + "overlayscrollbars-react": "^0.5.6", "react": "^19.2.4", "react-dom": "^19.2.4", "react-router-dom": "^7.14.0" diff --git a/frontend/src/components/Layout.jsx b/frontend/src/components/Layout.jsx index ef1f26e..244049e 100644 --- a/frontend/src/components/Layout.jsx +++ b/frontend/src/components/Layout.jsx @@ -57,7 +57,7 @@ export default function Layout() { return ( -
diff --git a/frontend/src/features/liberation/Liberation.jsx b/frontend/src/features/liberation/Liberation.jsx index 11fcfd4..dbe9a9a 100644 --- a/frontend/src/features/liberation/Liberation.jsx +++ b/frontend/src/features/liberation/Liberation.jsx @@ -286,7 +286,7 @@ export default function Liberation() { const overallProgress = Math.min((totalCumulative / GENESIS_TOTAL) * 100, 100) return ( -
+
{/* 해방 종류 탭 */}
{[ @@ -310,7 +310,7 @@ export default function Liberation() {
{liberationType === 'destiny' ? ( -
+
구현 예정
데스티니 해방 계산기는 준비 중입니다.
diff --git a/frontend/src/index.css b/frontend/src/index.css index 5cce142..017d67c 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -1,4 +1,5 @@ @import "tailwindcss"; +@import "overlayscrollbars/overlayscrollbars.css"; @theme { --font-sans: "Maplestory", "Noto Sans KR", system-ui, -apple-system, sans-serif; @@ -6,8 +7,19 @@ } html, body, #root { - height: 100%; - background: #030712; + min-height: 100%; + background: linear-gradient(to bottom right, #030712, #030712, #0f172a); + background-attachment: fixed; +} + +/* OverlayScrollbars body 오버레이 테마 */ +.os-theme-maple.os-theme-dark { + --os-handle-bg: rgba(255, 255, 255, 0.25); + --os-handle-bg-hover: rgba(255, 255, 255, 0.4); + --os-handle-bg-active: rgba(255, 255, 255, 0.5); + --os-size: 12px; + --os-padding-perpendicular: 2px; + --os-padding-axis: 2px; } html { @@ -46,26 +58,27 @@ input[type="number"] { to { opacity: 1; transform: translateY(0); } } -/* 커스텀 스크롤바 */ -* { + +/* 내부 스크롤 영역만 얇은 커스텀 스크롤바 (메인 페이지 스크롤은 기본) */ +*:not(html):not(body) { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.1) transparent; } -*::-webkit-scrollbar { +*:not(html):not(body)::-webkit-scrollbar { width: 8px; height: 8px; } -*::-webkit-scrollbar-track { +*:not(html):not(body)::-webkit-scrollbar-track { background: transparent; } -*::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.08); +*:not(html):not(body)::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.12); border-radius: 4px; transition: background 0.2s; } -*::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.18); +*:not(html):not(body)::-webkit-scrollbar-thumb:hover { + background: rgba(255, 255, 255, 0.22); } -*::-webkit-scrollbar-corner { +*:not(html):not(body)::-webkit-scrollbar-corner { background: transparent; } diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index 1aaee6d..c1204e4 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -2,9 +2,18 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import { BrowserRouter } from 'react-router-dom' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { OverlayScrollbars } from 'overlayscrollbars' import './index.css' import App from './App.jsx' +// body 전체에 오버레이 스크롤바 적용 (화면을 밀지 않음) +OverlayScrollbars( + { target: document.body, cancel: { nativeScrollbarsOverlaid: true } }, + { + scrollbars: { theme: 'os-theme-maple os-theme-dark', autoHide: 'leave', autoHideDelay: 800 }, + } +) + const queryClient = new QueryClient({ defaultOptions: { queries: {