Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 947837fe40 | |||
| 5ef833fde5 | |||
| 67e192b0e1 | |||
| 8ef011bfc8 | |||
| 9403e3698d |
@@ -1,5 +1,25 @@
|
|||||||
# 의사결정 이력
|
# 의사결정 이력
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.76
|
||||||
|
- 프리뷰용 `viewerSidebar__section`은 데스크톱 오른쪽 레일에서 하단 액션 카드처럼 보이게 하려고 `margin-top: auto`를 갖고 있었지만, 모바일 전체 화면 overlay에서는 이 규칙이 카드를 바닥으로 밀어 과도하게 붙은 인상을 만들 수 있다고 판단했다.
|
||||||
|
- 게다가 `localRightRailRoot`가 최소 높이 100%를 유지한 채 상위 콘텐츠 컨테이너도 flex 남은 높이를 채우면, 하단 footer 영역과 Teleport 콘텐츠의 시각적 쌓임이 어색해질 수 있으므로 모바일 overlay에서는 콘텐츠 컨테이너를 내용 높이 기준으로 풀어 footer가 자연스럽게 아래로 따라오게 정리했다.
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.75
|
||||||
|
- 데스크톱/태블릿에서는 오른쪽 레일을 폭이 정해진 서랍 패널처럼 여는 게 맞지만, 모바일에서는 같은 폭 규칙을 유지하면 오히려 “오른쪽에서 덜 열린 반쪽 패널”처럼 보여 하단 공간까지 어색해질 수 있다고 판단했다.
|
||||||
|
- 그래서 모바일 한정으로 오른쪽 레일 overlay를 전체 화면 패널로 바꾸고, 공유/복사 같은 하단 액션이 기기 하단 UI나 safe-area에 붙어 잘리지 않도록 내부 바디 패딩을 더 넉넉하게 두는 쪽으로 정리했다.
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.74
|
||||||
|
- 모바일에서는 `workspaceBody` 자체가 카드처럼 배경색을 가지는 것보다, 바깥 앱 셸 배경 위에 각 화면의 실제 카드/섹션만 떠 있는 편이 시각 구조가 더 명확하다고 판단했다.
|
||||||
|
- 특히 `workspaceBody`가 좌우 마진을 가진 상태로 별도 배경색을 칠하면 “내용과 무관한 중간 레이어 박스”처럼 보일 수 있으므로, 모바일 한정으로 공통 워크스페이스 배경을 투명 처리해 불필요한 레이어감을 줄이는 쪽으로 정리했다.
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.73
|
||||||
|
- 모바일 `appShell`은 PC처럼 좌우 3열이 아니라 위쪽 레일과 아래쪽 본문이 세로로 쌓이는 2행 구조이므로, 열 정의만 1fr로 바꾸고 행 정의를 비워두면 암묵 그리드 행이 남는 높이를 늘려 본문이 아래로 밀려 보일 수 있다고 판단했다.
|
||||||
|
- 이 문제는 각 화면 본문을 개별 조정하기보다 모바일 셸 컨테이너에서 첫 행은 `auto`, 본문 행은 `minmax(0, 1fr)`로 고정하고 전체 콘텐츠 정렬을 위쪽으로 붙이는 편이 공통 회귀를 가장 작게 되돌리는 방법이라고 정리했다.
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.72
|
||||||
|
- 모바일 상단 레일은 왼쪽 유저 카드 영역과 오른쪽 패널 토글 버튼이 같은 시각적 간격 체계를 가져야 전체 셸이 덜 비뚤어져 보이므로, 모바일에서만 `railHeader` 좌우 패딩을 본문 카드 여백보다 조금 넓은 `20px`로 맞추는 편이 낫다고 판단했다.
|
||||||
|
- 오른쪽 레일 토글 아이콘이 모바일에서 테두리 없는 아이콘만 보이면 왼쪽 네비 토글 버튼과 컴포넌트 문법이 달라 보이므로, 모바일 한정으로 같은 버튼형 배경/테두리/라운드를 적용해 조작 가능한 컨트롤처럼 통일하는 쪽으로 정리했다.
|
||||||
|
|
||||||
## 2026-04-03 v1.4.71
|
## 2026-04-03 v1.4.71
|
||||||
- 모바일에서 공통 본문 하단이 딱 붙어 보이는 문제는 로그인 화면 하나만 고치는 것보다 `workspaceBody` 공통 하단 여백을 safe-area까지 포함해 보강하는 편이 이후 모든 본문 화면에 일괄 적용되어 유지보수상 낫다고 판단했다.
|
- 모바일에서 공통 본문 하단이 딱 붙어 보이는 문제는 로그인 화면 하나만 고치는 것보다 `workspaceBody` 공통 하단 여백을 safe-area까지 포함해 보강하는 편이 이후 모든 본문 화면에 일괄 적용되어 유지보수상 낫다고 판단했다.
|
||||||
- 모바일 왼쪽 네비게이션은 데스크톱의 폭 축소형 접기와 목적이 다르므로, 기존 `leftRailCollapsed`를 억지로 재사용하기보다 `mobileLeftNavOpen` 상태를 분리하고 유저 카드 우측 버튼으로 검색/메뉴 묶음만 접는 방식이 더 자연스럽다고 정리했다.
|
- 모바일 왼쪽 네비게이션은 데스크톱의 폭 축소형 접기와 목적이 다르므로, 기존 `leftRailCollapsed`를 억지로 재사용하기보다 `mobileLeftNavOpen` 상태를 분리하고 유저 카드 우측 버튼으로 검색/메뉴 묶음만 접는 방식이 더 자연스럽다고 정리했다.
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
# 업데이트 로그
|
# 업데이트 로그
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.76
|
||||||
|
- 모바일 티어표 프리뷰에서 오른쪽 레일의 `VIEWER MODE` 카드가 패널 바닥에 딱 붙고, 카피라이트 문구가 카드 뒤쪽 중간 높이에 겹쳐 보일 수 있던 배치를 보정했다.
|
||||||
|
- 모바일 오른쪽 overlay 레일에서는 `rightRail__content`가 남는 높이를 억지로 채우지 않도록 `flex: 0 0 auto`로 풀고, `localRightRailRoot`의 최소 높이도 `auto`로 낮춰 footer와 콘텐츠가 자연스럽게 순서대로 쌓이게 했다.
|
||||||
|
- 프리뷰 전용 `viewerSidebar__section`의 `margin-top: auto`는 모바일에서만 끄고, 광고 아래에 바로 카드가 이어지도록 조정했다.
|
||||||
|
- 프런트 프로덕션 빌드(`npm run build`) 통과를 확인했다.
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.75
|
||||||
|
- 모바일에서 오른쪽 레일을 열었을 때 패널이 `calc(100vw - 20px)` 폭의 좁은 서랍처럼 떠서 화면 전체를 채우지 못하고, 아래쪽도 어색하게 비어 보이던 부분을 조정했다.
|
||||||
|
- 모바일 오른쪽 레일 overlay는 `inset: 0`, `width: 100vw`, `height: 100dvh`로 화면 전체를 덮는 패널처럼 열리게 바꾸고, 하단 액션/공유 버튼이 바닥에 붙거나 잘려 보이지 않도록 내부 패딩을 `32px + safe-area`까지 늘렸다.
|
||||||
|
- 프런트 프로덕션 빌드(`npm run build`) 통과를 확인했다.
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.74
|
||||||
|
- 모바일 본문 영역에서 `workspaceBody` 배경색이 좌우 마진 안쪽에만 칠해져 중앙에 어설픈 배경 박스가 떠 있는 것처럼 보이던 부분을 정리했다.
|
||||||
|
- 모바일에서는 공통 워크스페이스 배경을 투명하게 두고, 실제 화면별 카드/섹션 배경만 남겨 덜 미완성처럼 보이도록 조정했다.
|
||||||
|
- 프런트 프로덕션 빌드(`npm run build`) 통과를 확인했다.
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.73
|
||||||
|
- 모바일에서 왼쪽 레일 아래 메인 컨텐츠가 화면 중간부터 시작하는 것처럼 보이던 회귀를 수정했다.
|
||||||
|
- 원인은 모바일 `.appShell`이 1열 그리드로 바뀐 상태에서 세로 행 정의가 없어 `leftRail` 행과 `appMain` 행이 남는 높이를 나눠 가지며 위쪽이 불필요하게 늘어날 수 있던 점이었다. 모바일 그리드를 `auto + minmax(0, 1fr)` 행으로 고정하고 `align-content: start`를 적용해 상단 레일 바로 아래에 본문이 이어지도록 보정했다.
|
||||||
|
- 프런트 프로덕션 빌드(`npm run build`) 통과를 확인했다.
|
||||||
|
|
||||||
|
## 2026-04-03 v1.4.72
|
||||||
|
- 모바일 공통 상단 헤더(`railHeader`) 좌우 패딩을 `20px`로 넓혀, 오른쪽 레일 토글 버튼과 화면 가장자리 간격이 왼쪽 유저 카드 쪽과 더 자연스럽게 맞도록 조정했다.
|
||||||
|
- 모바일에서 오른쪽 레일 열기/닫기 아이콘도 왼쪽 네비게이션 토글과 같은 버튼형 카드 스타일로 보이도록 `42px` 크기, 테두리, 배경, 둥근 모서리를 맞췄다.
|
||||||
|
- 프런트 프로덕션 빌드(`npm run build`) 통과를 확인했다.
|
||||||
|
|
||||||
## 2026-04-03 v1.4.71
|
## 2026-04-03 v1.4.71
|
||||||
- 모바일에서 본문 페이지나 로그인 화면 하단이 카드/버튼 바로 아래에서 끊겨 보여 답답했던 부분을 줄이기 위해, 공통 워크스페이스 본문 하단에 모바일 safe-area 기반 여백을 추가했다.
|
- 모바일에서 본문 페이지나 로그인 화면 하단이 카드/버튼 바로 아래에서 끊겨 보여 답답했던 부분을 줄이기 위해, 공통 워크스페이스 본문 하단에 모바일 safe-area 기반 여백을 추가했다.
|
||||||
- 모바일 왼쪽 네비게이션은 유저 프로필 카드 오른쪽 토글 버튼으로 접고 펼칠 수 있게 바꾸고, 닫힘/열림 전환 시 검색창과 메뉴가 위아래로 부드럽게 스르륵 접히는 애니메이션을 추가했다.
|
- 모바일 왼쪽 네비게이션은 유저 프로필 카드 오른쪽 토글 버튼으로 접고 펼칠 수 있게 바꾸고, 닫힘/열림 전환 시 검색창과 메뉴가 위아래로 부드럽게 스르륵 접히는 애니메이션을 추가했다.
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ const showSettingsThemePanel = computed(() => route.name === 'profile')
|
|||||||
const showTopicViewToggle = computed(() => route.name === 'topicHub')
|
const showTopicViewToggle = computed(() => route.name === 'topicHub')
|
||||||
const topicViewMode = computed(() => (route.query.view === 'list' ? 'list' : 'grid'))
|
const topicViewMode = computed(() => (route.query.view === 'list' ? 'list' : 'grid'))
|
||||||
const showBackendFallback = computed(() => !isPreviewMode.value && ['maintenance', 'offline'].includes(backendState.value))
|
const showBackendFallback = computed(() => !isPreviewMode.value && ['maintenance', 'offline'].includes(backendState.value))
|
||||||
|
const shouldLockRightRailBodyScroll = computed(() => isRightRailOverlay.value && rightRailOpen.value && !showBackendFallback.value)
|
||||||
const leftBottomPrimaryAction = computed(() => {
|
const leftBottomPrimaryAction = computed(() => {
|
||||||
if (!authReady.value) return null
|
if (!authReady.value) return null
|
||||||
if (route.name === 'home' && auth.user) {
|
if (route.name === 'home' && auth.user) {
|
||||||
@@ -296,6 +297,11 @@ function toggleTheme() {
|
|||||||
applyTheme(isLightTheme.value ? 'dark' : 'light')
|
applyTheme(isLightTheme.value ? 'dark' : 'light')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function syncRightRailBodyScrollLock(shouldLock) {
|
||||||
|
if (typeof document === 'undefined') return
|
||||||
|
document.body.style.overflow = shouldLock ? 'hidden' : ''
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
const savedTheme = window.localStorage.getItem('tier-maker:theme')
|
const savedTheme = window.localStorage.getItem('tier-maker:theme')
|
||||||
@@ -338,6 +344,7 @@ onBeforeUnmount(() => {
|
|||||||
window.removeEventListener('resize', syncViewportWidth)
|
window.removeEventListener('resize', syncViewportWidth)
|
||||||
window.removeEventListener('keydown', handleGlobalKeydown)
|
window.removeEventListener('keydown', handleGlobalKeydown)
|
||||||
}
|
}
|
||||||
|
syncRightRailBodyScrollLock(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -383,6 +390,14 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
shouldLockRightRailBodyScroll,
|
||||||
|
(shouldLock) => {
|
||||||
|
syncRightRailBodyScrollLock(shouldLock)
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
)
|
||||||
|
|
||||||
function isRouteActive(path) {
|
function isRouteActive(path) {
|
||||||
if (path === '/') return route.path === '/'
|
if (path === '/') return route.path === '/'
|
||||||
return route.path.startsWith(path)
|
return route.path.startsWith(path)
|
||||||
@@ -2031,9 +2046,15 @@ function reloadApp() {
|
|||||||
@media (max-width: 860px) {
|
@media (max-width: 860px) {
|
||||||
.appShell {
|
.appShell {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: auto minmax(0, 1fr);
|
||||||
|
align-content: start;
|
||||||
min-height: 100dvh;
|
min-height: 100dvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.railHeader {
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.leftRail {
|
.leftRail {
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
@@ -2066,6 +2087,27 @@ function reloadApp() {
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.workspaceHead .ghostIcon--iconOnly,
|
||||||
|
.rightRail__top .ghostIcon--iconOnly {
|
||||||
|
width: 42px;
|
||||||
|
height: 42px;
|
||||||
|
min-width: 42px;
|
||||||
|
border: 1px solid var(--theme-border);
|
||||||
|
border-radius: 14px;
|
||||||
|
background: var(--theme-surface-soft);
|
||||||
|
color: var(--theme-text-soft);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightRail--overlay {
|
||||||
|
inset: 0;
|
||||||
|
width: 100vw;
|
||||||
|
min-width: 0;
|
||||||
|
height: 100dvh;
|
||||||
|
min-height: 100dvh;
|
||||||
|
border-left: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
.appMain {
|
.appMain {
|
||||||
min-height: auto;
|
min-height: auto;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
@@ -2132,12 +2174,14 @@ function reloadApp() {
|
|||||||
.workspaceBody {
|
.workspaceBody {
|
||||||
padding: 0 0 calc(28px + env(safe-area-inset-bottom));
|
padding: 0 0 calc(28px + env(safe-area-inset-bottom));
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
background: transparent;
|
||||||
margin: 14px 14px 0;
|
margin: 14px 14px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.workspaceBody--localRail {
|
.workspaceBody--localRail {
|
||||||
padding: 0 0 calc(28px + env(safe-area-inset-bottom));
|
padding: 0 0 calc(28px + env(safe-area-inset-bottom));
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
background: transparent;
|
||||||
margin: 14px 14px 0;
|
margin: 14px 14px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2154,7 +2198,16 @@ function reloadApp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rightRail--overlay .rightRail__body {
|
.rightRail--overlay .rightRail__body {
|
||||||
padding-bottom: calc(14px + env(safe-area-inset-bottom));
|
padding: 14px 20px calc(32px + env(safe-area-inset-bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightRail--overlay .rightRail__content {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rightRail--overlay .localRightRailRoot {
|
||||||
|
min-height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.collapsedSearchModal {
|
.collapsedSearchModal {
|
||||||
|
|||||||
@@ -3198,6 +3198,9 @@ onUnmounted(() => {
|
|||||||
.previewOnly {
|
.previewOnly {
|
||||||
padding: 14px;
|
padding: 14px;
|
||||||
}
|
}
|
||||||
|
.viewerSidebar__section {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
.pool {
|
.pool {
|
||||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user