-
+
+
stream-client
+
);
}
diff --git a/src/components/ui/BottomSheet.tsx b/src/components/ui/BottomSheet.tsx
index efefdc4..bff3859 100644
--- a/src/components/ui/BottomSheet.tsx
+++ b/src/components/ui/BottomSheet.tsx
@@ -47,7 +47,7 @@ function BottomSheet({ open, onClose, children }: BottomSheetProps) {
하나 더 붙는데, 실제 @wanteddev/wds의 ActionArea 컴포넌트에는 이 14px이 없어서
여기서 더해준다. */}
{/* 앱 WebView에서는 네이티브 세이프에어리어와 중복이라 데스크톱 컬럼에서만 남긴다(BottomNav와 같은 규칙). */}
-
+
,
portalEl,
diff --git a/src/components/ui/ScreenLayout.tsx b/src/components/ui/ScreenLayout.tsx
index 0453b1e..3c3d277 100644
--- a/src/components/ui/ScreenLayout.tsx
+++ b/src/components/ui/ScreenLayout.tsx
@@ -52,7 +52,11 @@ interface ScreenLayoutProps {
// 같이 움직여야 하는 고정 px는 FeedbacksQaCard(캐러셀 카드)와 BililgeReturnConfirmModal
// 둘뿐이다. 화면과 같은 배경 위에 서는 컬럼이라 그림자로 경계를 표시한다
// — App.tsx가 같은 브레이크포인트로 이 컬럼을 가운데 세운다.
-// 세이프에어리어는 앱 셸이 담당하므로 여기서 env(safe-area-inset-*)를 더하지 않는다(중복 여백이 된다).
+// 세이프에어리어는 env(safe-area-inset-*)로 확보한다(index.html의 viewport-fit=cover와 한 쌍).
+// 고정 px를 더하면 앱에서 네이티브 인셋과 겹쳐 두 번 들어가지만, env()는 환경이 채우는 값이라
+// 앱 WebView에서는 0이 되어 중복이 생기지 않는다 — 폰 브라우저·PWA(standalone)에서만 실제 인셋이 잡힌다.
+// 상단은 이 루트 div가 배경을 갖고 있어 여기서 패딩으로 받고, 하단은 Bottom Nav·Action Area가
+// 각자 자기 배경을 그 자리까지 연장해야 해서 컴포넌트마다 h-safe-bottom으로 처리한다.
// 배경도 같은 방식으로 라우트 handle에서 받는다 — 헤더 슬롯까지 이 루트 div가 덮기 때문에,
// 화면이 헤더와 본문에 따로 배경을 깔 필요가 없다.
function ScreenLayout({
@@ -71,7 +75,7 @@ function ScreenLayout({
{header}
{/* 스크롤 처리는 각 화면이 스스로 결정한다(예: 상단 토글/필터는 고정하고 목록만 스크롤).
diff --git a/src/features/events/EventsApplicationClosedScreen.tsx b/src/features/events/EventsApplicationClosedScreen.tsx
index 57dc674..975c0dd 100644
--- a/src/features/events/EventsApplicationClosedScreen.tsx
+++ b/src/features/events/EventsApplicationClosedScreen.tsx
@@ -71,7 +71,7 @@ function EventsApplicationClosedScreen() {
{/* WDS ActionArea의 아래 padding 20px + 여기 14px = Figma Bottom Safe Area 34px.
앱 WebView에서는 네이티브 세이프에어리어와 중복이라 데스크톱 프레임에서만 남긴다. */}
-
+
);
diff --git a/src/features/events/EventsApplicationCompleteScreen.tsx b/src/features/events/EventsApplicationCompleteScreen.tsx
index afc3459..3d3cd37 100644
--- a/src/features/events/EventsApplicationCompleteScreen.tsx
+++ b/src/features/events/EventsApplicationCompleteScreen.tsx
@@ -92,7 +92,7 @@ function EventsApplicationCompleteScreen() {
{/* 신청 폼과 같은 이유의 14px — WDS ActionArea의 아래 padding 20px에 iOS Home Bar 여백을 더해 34px.
앱 WebView에서는 네이티브 세이프에어리어와 중복이라 데스크톱 프레임에서만 남긴다. */}
-
+
);
diff --git a/src/features/events/EventsApplicationScreen.tsx b/src/features/events/EventsApplicationScreen.tsx
index 6477343..188aeab 100644
--- a/src/features/events/EventsApplicationScreen.tsx
+++ b/src/features/events/EventsApplicationScreen.tsx
@@ -155,7 +155,7 @@ function EventsApplicationScreen() {
WDS ActionArea는 아래 padding 20px만 준다 — 모자란 14px을 여기서 더한다(BottomSheet와 같은 이유).
Bottom Nav가 있는 화면은 BottomNav가 이 여백을 준다.
앱 WebView에서는 네이티브 세이프에어리어와 중복이라 데스크톱 컬럼에서만 남긴다(BottomNav와 같은 규칙). */}
-
+
+
);
diff --git a/src/index.css b/src/index.css
index 81be834..4dd2296 100644
--- a/src/index.css
+++ b/src/index.css
@@ -45,6 +45,25 @@
--color-thumbnail-placeholder: #d9d9d9;
}
+/* iOS 노치·홈 인디케이터 자리. index.html의 viewport-fit=cover와 한 쌍이다.
+ 값은 우리가 정하지 않고 플랫폼이 채운다 — 앱 WebView는 네이티브 SafeAreaView가 이미
+ 인셋해서 0, 폰 브라우저·PWA(standalone)는 실제 인셋, 데스크톱·구형 기기는 0이다.
+ 그래서 기기·실행 환경 분기를 코드에서 하지 않아도 된다.
+ 데스크톱 프레임(sm 이상)에서 Figma 스펙대로 자리를 흉내 내려면 sm: 유틸로 따로 덮는다. */
+@utility pt-safe-top {
+ padding-top: env(safe-area-inset-top, 0px);
+}
+
+@utility h-safe-bottom {
+ height: env(safe-area-inset-bottom, 0px);
+}
+
+/* WDS ActionArea가 이미 아래 padding 20px을 주는 자리 — 모자란 만큼만 더한다.
+ 노치 기기(34px)면 14px, 홈 인디케이터가 없는 기기(0)면 0이 된다. */
+@utility h-safe-bottom-extra {
+ height: max(0px, calc(env(safe-area-inset-bottom, 0px) - 20px));
+}
+
/* 무한 스크롤 목록 등 스크롤은 동작하되 스크롤바는 안 보이게 할 때 쓰는 재사용 유틸리티 */
@utility scrollbar-hidden {
scrollbar-width: none;