feat(space): 사운드 시트와 몰입 모드 크롬 정리 적용

맥락:

- /space 하단 사운드 바를 제거하고 도구를 우측 도크에 수납해 배경 몰입을 강화하며, 몰입 모드 ON 체감을 높이기 위해

변경사항:

- 하단 사운드 프리셋 바를 제거하고 도크에 🎧 Sound 패널을 추가

- features/sound-preset + widgets/sound-sheet를 추가해 프리셋 선택/믹서 UI(더미) 구성

- features/immersion-mode + shared/ui/Toggle을 추가하고 Quick 시트 토글과 연결

- 몰입 모드 ON 시 상단 Current Room 숨김, 허브 버튼 소형화, 레일 미니화, HUD 저대비, 비네팅/그레인 강화

- widgets/space-chrome를 신설해 /space 상단 크롬 렌더링을 분리

- docs/90_current_state.md, docs/session_brief.md 최신 상태로 갱신

검증:

- npx tsc --noEmit

세션-상태: /space는 사운드 시트 기반 도크 구조와 몰입 모드 UI를 제공함

세션-다음: RoomSheetWidget 인원수 기반 정보를 큐레이션 표현으로 전환

세션-리스크: 터치 환경에서 미니 레일 발견성이 낮을 수 있어 보조 힌트가 필요할 수 있음
This commit is contained in:
2026-02-27 14:14:12 +09:00
parent f0efd74af3
commit ce1664f472
19 changed files with 640 additions and 114 deletions

View File

@@ -1,13 +1,20 @@
'use client';
import { useState } from 'react';
import { ImmersionModeToggle } from '@/features/immersion-mode';
import { Toggle } from '@/shared/ui';
interface QuickSheetWidgetProps {
onClose: () => void;
isImmersionMode: boolean;
onToggleImmersionMode: () => void;
}
export const QuickSheetWidget = ({ onClose }: QuickSheetWidgetProps) => {
const [immersionMode, setImmersionMode] = useState(false);
export const QuickSheetWidget = ({
onClose,
isImmersionMode,
onToggleImmersionMode,
}: QuickSheetWidgetProps) => {
const [minimalNotice, setMinimalNotice] = useState(false);
return (
@@ -25,27 +32,19 @@ export const QuickSheetWidget = ({ onClose }: QuickSheetWidgetProps) => {
</header>
<div className="space-y-3 px-4 py-4">
<button
type="button"
role="switch"
aria-checked={immersionMode}
onClick={() => setImmersionMode((current) => !current)}
className="flex w-full items-center justify-between rounded-xl border border-white/16 bg-white/6 px-3 py-2 text-sm text-white/86"
>
<span> </span>
<span>{immersionMode ? 'ON' : 'OFF'}</span>
</button>
<ImmersionModeToggle
enabled={isImmersionMode}
onToggle={onToggleImmersionMode}
/>
<button
type="button"
role="switch"
aria-checked={minimalNotice}
onClick={() => setMinimalNotice((current) => !current)}
className="flex w-full items-center justify-between rounded-xl border border-white/16 bg-white/6 px-3 py-2 text-sm text-white/86"
>
<span> </span>
<span>{minimalNotice ? 'ON' : 'OFF'}</span>
</button>
<div className="flex items-center justify-between rounded-xl border border-white/16 bg-white/6 px-3 py-2">
<span className="text-sm text-white/90"> </span>
<Toggle
checked={minimalNotice}
onChange={setMinimalNotice}
ariaLabel="알림 최소화 토글"
/>
</div>
<p className="text-xs text-white/58">
UI . .