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:
@@ -5,6 +5,7 @@ interface SpaceTimerHudWidgetProps {
|
||||
timerLabel: string;
|
||||
goal: string;
|
||||
className?: string;
|
||||
isImmersionMode?: boolean;
|
||||
}
|
||||
|
||||
const HUD_ACTIONS = [
|
||||
@@ -17,20 +18,44 @@ export const SpaceTimerHudWidget = ({
|
||||
timerLabel,
|
||||
goal,
|
||||
className,
|
||||
isImmersionMode = false,
|
||||
}: SpaceTimerHudWidgetProps) => {
|
||||
return (
|
||||
<div className={cn('pointer-events-none fixed inset-x-0 bottom-[4.7rem] z-20 px-4 pr-16 sm:px-6', className)}>
|
||||
<div className="mx-auto w-full max-w-xl pointer-events-auto">
|
||||
<section className="flex h-16 items-center justify-between gap-3 rounded-2xl border border-white/10 bg-black/25 px-3.5 backdrop-blur-sm">
|
||||
<section
|
||||
className={cn(
|
||||
'flex h-16 items-center justify-between gap-3 rounded-2xl px-3.5 transition-colors',
|
||||
isImmersionMode
|
||||
? 'border border-white/6 bg-black/16 backdrop-blur-md'
|
||||
: 'border border-white/10 bg-black/25 backdrop-blur-sm',
|
||||
)}
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-baseline gap-2">
|
||||
<span className="text-[11px] font-semibold uppercase tracking-[0.16em] text-white/62">
|
||||
<span
|
||||
className={cn(
|
||||
'text-[11px] font-semibold uppercase tracking-[0.16em]',
|
||||
isImmersionMode ? 'text-white/45' : 'text-white/62',
|
||||
)}
|
||||
>
|
||||
Focus
|
||||
</span>
|
||||
<span className="text-2xl font-semibold tracking-tight text-white">25:00</span>
|
||||
<span className="text-[11px] text-white/62">{timerLabel}</span>
|
||||
<span
|
||||
className={cn(
|
||||
'text-2xl font-semibold tracking-tight',
|
||||
isImmersionMode ? 'text-white/72' : 'text-white',
|
||||
)}
|
||||
>
|
||||
25:00
|
||||
</span>
|
||||
<span className={cn('text-[11px]', isImmersionMode ? 'text-white/42' : 'text-white/62')}>
|
||||
{timerLabel}
|
||||
</span>
|
||||
</div>
|
||||
<p className="truncate text-[11px] text-white/58">목표: {goal}</p>
|
||||
<p className={cn('truncate text-[11px]', isImmersionMode ? 'text-white/44' : 'text-white/58')}>
|
||||
목표: {goal}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2.5">
|
||||
@@ -40,7 +65,12 @@ export const SpaceTimerHudWidget = ({
|
||||
key={action.id}
|
||||
type="button"
|
||||
title={action.label}
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-full border border-white/15 bg-white/8 text-sm text-white/82 transition-colors hover:bg-white/14 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-200/80"
|
||||
className={cn(
|
||||
'inline-flex h-8 w-8 items-center justify-center rounded-full border text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-200/80',
|
||||
isImmersionMode
|
||||
? 'border-white/10 bg-white/5 text-white/64 hover:bg-white/10'
|
||||
: 'border-white/15 bg-white/8 text-white/82 hover:bg-white/14',
|
||||
)}
|
||||
>
|
||||
<span aria-hidden>{action.icon}</span>
|
||||
<span className="sr-only">{action.label}</span>
|
||||
|
||||
Reference in New Issue
Block a user