From 78a65fa15b26f46248904e752e5ff73e95caa969 Mon Sep 17 00:00:00 2001 From: corpi Date: Mon, 2 Mar 2026 15:12:03 +0900 Subject: [PATCH] =?UTF-8?q?style(space):=20=EC=8A=A4=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=A4=91=EC=8B=AC=20=EC=B2=AB=20=EC=9D=B8=EC=83=81?= =?UTF-8?q?=EA=B3=BC=20Setup/Focus=20=ED=86=A4=EC=9D=84=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 맥락: - /space 첫 화면이 그라데이션 안내 화면처럼 보이며 공간 서비스의 무대감이 약했습니다. - Setup 안내 카드/상단 크롬/도크 존재감이 커서 몰입형 인상(Portal/LifeAt 톤)을 해치고 있었습니다. 변경사항: - 배경을 실제 공간 프리뷰 이미지 우선 렌더로 전환하고, 실패 시 그라데이션 fallback만 남기도록 조정했습니다. - 배경 오버레이를 과한 비네팅 대신 단일 규칙(얕은 읽기용 필터 + 고정 그레인)으로 정리했습니다. - Setup 상태의 중앙 안내 카드를 제거하고, 진입 시 Setup Drawer 자동 오픈 흐름만 남겼습니다. - Setup Drawer 헤더 안내 문구를 1줄로 축약하고 섹션을 3단(Space/Goal/Sound) 번호 체계로 고정했습니다. - Setup 상태에서는 Drawer 닫기를 막아 설명 박스 없이도 자연스러운 입력 흐름을 유지했습니다. - 상단 크롬을 최소화하고 Focus 상태의 Setup 열기 버튼을 약한 보조 액션으로 낮췄습니다. - 오른쪽 도크 레일의 폭/간격/아이콘 박스를 정돈하고 Focus 기본 opacity를 낮춰 몰입 방해를 줄였습니다. 검증: - npx tsc --noEmit - npm run build 세션-상태: /space 첫 진입이 장면+드로어 중심으로 정리되어 설명 없이도 시작 흐름이 읽힙니다. 세션-다음: 필요 시 Setup Drawer 내부 타이포 스케일과 칩 밀도를 추가 미세 조정합니다. 세션-리스크: 외부 이미지 소스 품질 편차에 따라 장면 밝기 체감이 달라질 수 있습니다. --- src/entities/room/model/rooms.ts | 3 +- .../ui/SpaceSetupDrawerWidget.tsx | 20 +++--- .../space-sheet-shell/ui/SpaceSideSheet.tsx | 38 +++++++----- .../ui/SpaceToolsDockWidget.tsx | 16 ++--- .../ui/SpaceWorkspaceWidget.tsx | 62 +++++++------------ 5 files changed, 64 insertions(+), 75 deletions(-) diff --git a/src/entities/room/model/rooms.ts b/src/entities/room/model/rooms.ts index c754b95..3d1c8ba 100644 --- a/src/entities/room/model/rooms.ts +++ b/src/entities/room/model/rooms.ts @@ -233,9 +233,10 @@ export const getRoomCardBackgroundStyle = (room: RoomTheme): CSSProperties => { export const getRoomBackgroundStyle = (room: RoomTheme): CSSProperties => { return { - backgroundImage: `${room.previewGradient}, url('${room.previewImage}')`, + backgroundImage: `url('${getRoomCardPhotoUrl(room)}'), linear-gradient(160deg, #1e293b 0%, #0f172a 100%)`, backgroundSize: 'cover, cover', backgroundPosition: 'center, center', + backgroundRepeat: 'no-repeat, no-repeat', }; }; diff --git a/src/widgets/space-setup-drawer/ui/SpaceSetupDrawerWidget.tsx b/src/widgets/space-setup-drawer/ui/SpaceSetupDrawerWidget.tsx index eeb0d67..c7f15fd 100644 --- a/src/widgets/space-setup-drawer/ui/SpaceSetupDrawerWidget.tsx +++ b/src/widgets/space-setup-drawer/ui/SpaceSetupDrawerWidget.tsx @@ -8,6 +8,7 @@ import { SpaceSideSheet } from '@/widgets/space-sheet-shell'; interface SpaceSetupDrawerWidgetProps { open: boolean; + dismissible?: boolean; rooms: RoomTheme[]; selectedRoomId: string; goalInput: string; @@ -26,6 +27,7 @@ interface SpaceSetupDrawerWidgetProps { export const SpaceSetupDrawerWidget = ({ open, + dismissible = true, rooms, selectedRoomId, goalInput, @@ -45,8 +47,9 @@ export const SpaceSetupDrawerWidget = ({
-
+
-

Space

-

오늘 머물 공간을 하나 고르세요.

+

1) Space

-
+
-

Goal

-

스킵 없이 한 줄 목표를 남겨주세요.

+

2) Goal

-
+
-

Sound

-

선택 항목이에요. 필요 없으면 그대로 시작해도 됩니다.

+

3) Sound

diff --git a/src/widgets/space-sheet-shell/ui/SpaceSideSheet.tsx b/src/widgets/space-sheet-shell/ui/SpaceSideSheet.tsx index c690e30..70226d9 100644 --- a/src/widgets/space-sheet-shell/ui/SpaceSideSheet.tsx +++ b/src/widgets/space-sheet-shell/ui/SpaceSideSheet.tsx @@ -11,6 +11,7 @@ interface SpaceSideSheetProps { children: ReactNode; footer?: ReactNode; widthClassName?: string; + dismissible?: boolean; } export const SpaceSideSheet = ({ @@ -21,6 +22,7 @@ export const SpaceSideSheet = ({ children, footer, widthClassName, + dismissible = true, }: SpaceSideSheetProps) => { useEffect(() => { if (!open) { @@ -46,12 +48,16 @@ export const SpaceSideSheet = ({ return ( <> - + {dismissible ? ( + + ) : null}
{children}
diff --git a/src/widgets/space-tools-dock/ui/SpaceToolsDockWidget.tsx b/src/widgets/space-tools-dock/ui/SpaceToolsDockWidget.tsx index 16d8ffd..3d59336 100644 --- a/src/widgets/space-tools-dock/ui/SpaceToolsDockWidget.tsx +++ b/src/widgets/space-tools-dock/ui/SpaceToolsDockWidget.tsx @@ -75,13 +75,13 @@ export const SpaceToolsDockWidget = ({ return ( <> -
+
{TOOL_ITEMS.map((item) => { @@ -95,15 +95,15 @@ export const SpaceToolsDockWidget = ({ aria-label={item.label} onClick={() => setActivePanel(item.id)} className={cn( - 'relative inline-flex h-9 w-9 items-center justify-center rounded-xl border text-base transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-300/75', + 'relative inline-flex h-8 w-8 items-center justify-center rounded-[10px] border text-[15px] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-300/75', selected - ? 'border-sky-200/64 bg-sky-200/22' - : 'border-white/18 bg-white/8 hover:bg-white/14', + ? 'border-sky-200/58 bg-sky-200/18 shadow-[0_0_0_1px_rgba(186,230,253,0.28)]' + : 'border-white/14 bg-white/7 hover:bg-white/13', )} > {item.icon} {item.id === 'inbox' && thoughtCount > 0 ? ( - + {thoughtCount > 99 ? '99+' : `${thoughtCount}`} ) : null} diff --git a/src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx b/src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx index 9437c0c..5030c40 100644 --- a/src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx +++ b/src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx @@ -14,7 +14,6 @@ import { type GoalChip, } from '@/entities/session'; import { useSoundPresetSelection } from '@/features/sound-preset'; -import { cn } from '@/shared/lib/cn'; import { useToast } from '@/shared/ui'; import { SpaceFocusHudWidget } from '@/widgets/space-focus-hud'; import { SpaceSetupDrawerWidget } from '@/widgets/space-setup-drawer'; @@ -102,7 +101,6 @@ export const SpaceWorkspaceWidget = () => { }; const handleOpenSetup = () => { - setWorkspaceMode('setup'); setSetupDrawerOpen(true); }; @@ -111,70 +109,48 @@ export const SpaceWorkspaceWidget = () => {
-
-
-
-

VibeRoom

-

- {selectedRoom.name} · {selectedRoom.vibeLabel} -

-
+
+ {!isFocusMode ? ( +
+

VibeRoom

+
+ ) : ( +
+ )} - {!isSetupDrawerOpen ? ( + {isFocusMode && !isSetupDrawerOpen ? ( ) : null}
-
- {isFocusMode ? null : ( -
-
-

Workspace

-

- 공간을 고르고 시작하세요 -

-

- 오른쪽 Setup에서 목표를 입력하면 바로 몰입 화면으로 전환됩니다. -

-
-
- )} -
+
{ goalChips={GOAL_CHIPS} soundPresets={SOUND_PRESETS} canStart={canStart} - onClose={() => setSetupDrawerOpen(false)} + onClose={() => { + if (isFocusMode) { + setSetupDrawerOpen(false); + } + }} onRoomSelect={setSelectedRoomId} onGoalChange={handleGoalChange} onGoalChipSelect={handleGoalChipSelect}