Files
viberoom-web/docs/90_current_state.md

498 lines
35 KiB
Markdown

# 90. Current State
Last Updated: 2026-03-16
## DONE
- `/app` session gate 제거:
- `/app`은 더 이상 running / paused / takeover UI를 보여주지 않는다
- current session이 있으면 상태와 상관없이 즉시 `/space`로 이동한다
- no-session일 때만 atmosphere entry shell이 열린다
- `/app` Atmosphere Entry Shell 1차 구현:
- no-session `/app``goal + duration + atmosphere` 중심의 premium entry shell로 교체했다
- `microStep` 입력은 entry에서 제거했고, `예상 시간(분)` 입력과 12개 dummy atmosphere grid를 추가했다
- atmosphere는 `scene + sound`가 함께 묶인 선택 단위로 동작하며, 선택한 atmosphere가 `/app` 배경과 `/space` start payload에 같이 반영된다
- custom duration server contract 전까지는 입력한 분 값을 가장 가까운 기본 리듬(`25/5`, `50/10`, `90/20`)으로 매핑한다
- weekly review entry는 main CTA를 먹지 않도록 no-session shell의 quiet secondary dock 위치로 이동했다
- `/app` Atmosphere Entry Shell visual premium polish:
- no-session shell을 `decision rail + selected atmosphere stage + curated atmosphere library` 구조로 다시 짰다
- 좌측은 입력과 시작 결정을 담당하고, 우측은 선택한 atmosphere의 immersive preview를 크게 보여준다
- review entry는 start stage 아래 quiet dock로 내려 main CTA와 경쟁하지 않게 정리했다
- current session direct start 차단:
- silent abandon을 막기 위해 server `startSession()`은 current session 존재 시 direct start를 거절한다
- `/app` 기존 single-goal commitment gate는 legacy로 내려갔다:
- 2-step `goal -> ritual` flow를 제거하고, current session이 있으면 `Resume` UI를 우선 노출하도록 정리했다
- 현재 source-of-truth는 `goal + duration + atmosphere` 중심의 새 entry shell spec이다
- `/space` Refocus System slice 1 구현:
- HUD recovery layer를 `paused / refocus / next-beat / complete` 단일 overlay 상태로 정리
- pause 직후 바로 편집 시트를 열지 않고, 작은 recovery prompt를 먼저 노출
- `한 조각 다시 잡기`로 refocus에 들어가고, paused 상태에서는 `적용하고 이어가기`로 바로 resume 연결
- microStep 완료 후 `다음 한 조각이 있나요?` next-beat prompt로만 이어지게 정리
- 한 번에 하나의 recovery tray만 열리도록 hierarchy를 고정
- `/space` Refocus System slice 2 구현:
- pause prompt의 `이대로 이어가기`가 실제 resume 동작으로 연결
- goal complete tray에 `여기서 마무리하기` 경로 추가
- 현재 세션을 다음 목표 입력 없이도 정상 완료 처리할 수 있게 연결
- goal complete / rest / next-goal의 세 분기가 UI와 동작 모두에서 분리됨
- `/space` Refocus System slice 3 구현:
- goal complete tray가 초기부터 input form을 강요하지 않도록 progressive disclosure 구조로 변경
- `여기서 마무리하기 / 잠시 비우기 / 다음 목표 이어가기`를 먼저 제안하고, 다음 목표 입력은 선택 시에만 펼쳐지게 정리
- next-beat prompt에 현재 goal 문맥을 함께 보여주도록 보강
- `/space` Refocus System slice 4 구현:
- pause / next-beat / complete / refocus tray의 glass material, hairline, spacing을 공통 규칙으로 정리
- 선택 액션을 단순 inline 링크에서 quiet option row로 바꿔 recovery decision hierarchy를 선명하게 만듦
- `goal complete`의 세 분기를 같은 tray 안의 선택 행으로 통합해 planner/form 느낌을 약화
- `refocus` form field와 footer action 톤을 다른 recovery tray와 같은 제품군으로 맞춤
- `/space` Away / Return Recovery slice 구현:
- `visibilitychange`, `pagehide`, sleep/wake gap 기반 AwayCandidate 감지 추가
- 짧은 탭 전환에는 반응하지 않도록 hidden threshold를 둠
- 돌아왔을 때 focus가 아직 running이면 `Return` tray에서 `이어서 하기 / 한 조각 다시 잡기`를 제안
- 자리를 비운 사이 focus가 끝나 break phase가 되었으면 standard break 대신 `Return` tray를 먼저 띄움
- 이 경우 `쉬기 이어가기 / 다음 목표 이어가기 / 한 조각 다시 잡기`를 선택할 수 있음
- `다음 목표 이어가기``Goal Complete` next view로 바로 연결됨
- `/space` Pause tray premium polish:
- tray 폭과 열림 높이를 키워 긴 한국어 카피가 잘리지 않게 조정
- eyebrow / title / body의 typography hierarchy와 line-height를 재정렬
- option row spacing, radius, chevron 위치를 보정해 급조된 버튼 묶음 느낌을 완화
- `/space` Pause / Break / Return tone 분리 1차 구현:
- `Return(focus)``Return(break)`가 같은 tray처럼 보이지 않도록 break tray에 emerald tint release tone 도입
- `Goal Complete``잠시 비우기` 선택도 같은 break 계열 material로 연결
- timer HUD는 break phase에서 더 가벼운 emerald 계열 glass로 보정해 focus/pause와 구분되게 조정
- `/space` Pause / Break / Return copy + interaction polish:
- `Pause``멈춘 이유` 대신 `다시 시작할 한 줄`을 중심으로 카피를 다시 정리
- `Return(focus)``멈춘 자리에서 이어가기`, `Return(break)``쉬기 이어가기 / 다음 블록 이어가기` 중심으로 재서술
- `Goal Complete``다음 블록 이어가기 / 잠시 비우기 / 여기서 마무리하기` 순의 선택 tray를 먼저 보여주고, 다음 블록 입력은 이후 단계에서만 열리게 정리
- choice/next view의 헤더와 설명도 각각 다른 감정 상태에 맞춰 분리
- `/space` Pause / Break / Return motion polish 1차 구현:
- `Pause` tray는 빠르게 다시 붙잡는 recovery reveal로 조정
- `Return(focus)`는 짧은 re-entry settle motion으로, `Return(break)`는 더 느슨한 release reveal로 분리
- `Goal Complete`도 같은 recovery family 안에서 가장 느린 closure motion을 가지도록 조정
- `/space` goal closure CTA matrix 정렬:
- `break` phase에서도 expanded intent card 안에 `이번 목표 완료`를 유지하도록 수정
- base card가 잠기는 recovery overlay(`pause / return / next-beat`) 안에서도 low-emphasis `여기서 마무리하기` 경로를 추가
- 이제 active session 상태에서는 `계속 / 다시 잡기 / 마무리` 중 최소 한 경로가 항상 보이도록 정리
- `/space` intent HUD collapsed / expanded 재설계:
- 상시 큰 goal 카드 대신 idle에서는 goal 1줄만 남는 collapsed glass rail 구조로 변경
- hover / focus / rail tap에서만 expanded card로 열리며, 이때만 microStep과 `이번 목표 완료` 액션이 노출됨
- recovery tray(`pause / return / next-beat / complete / refocus`)가 열릴 때는 base card가 강제로 collapsed 상태를 유지하도록 정리
- expanded rail은 outside click으로 접히지만, recovery tray는 outside click으로 닫히지 않고 명시적 액션으로만 닫힘
- rail 클릭은 expand/collapse만 담당하고, refocus는 expanded 상태의 `수정` 액션으로만 진입
- Focus Entry Surface / Execution Surface 재정의:
- `/app`을 planning home이 아니라 hero-first focus entry surface로 재구성
- 상단 카피를 `Planning Home` 톤에서 `지금 시작할 첫 블록` 진입 톤으로 교체
- 메인 hero에 one-line goal input + 단일 primary CTA `지금 시작`만 남기고, 첫 진입의 주 행동을 고정
- empty state에서는 starter draft를 자동 주입하지 않고 placeholder 입력으로 시작한다
- suggestion chip으로 draft를 빠르게 교체할 수 있게 하고, 직접 타이핑 시에는 ad-hoc start를 허용
- 이후 `/app`은 current session이 있으면 `Resume`, 없으면 single-goal direct start만 남기는 commitment gate로 더 줄였다
- block CRUD, preview row, list-first 구조는 메인 진입 경로에서 제거했다
- `/space`는 planning overview 없이 goal/scene/sound/timer + HUD 실행 화면으로 정리
- focus-plan / focus-session 서버 계약 연결:
- `GET /api/v1/focus-plan/today`
- `POST /api/v1/focus-plan/items`
- `PATCH /api/v1/focus-plan/items/:id`
- `DELETE /api/v1/focus-plan/items/:id`
- `POST /api/v1/focus-plan/items/:id/complete`
- `POST /api/v1/focus-sessions/current/advance-goal`
- frontend에서 plan item id와 today plan 응답을 backend contract 기준으로 정규화
- `GET /today`는 current 이후 pending item 전체를 `nextItems`로 반환
- 목표 완료 후 다음 목표 즉시 실행 흐름 구현:
- GoalCompleteSheet에서 다음 목표를 입력하면 현재 세션 완료 + 새 planning item 생성 + 다음 세션 즉시 시작
- 같은 scene / sound / timer를 유지한 채 `/space` focus 화면에서 그대로 이어감
- 실패 시 시트를 닫지 않고 HUD 토스트로 에러만 노출
- `/stats` factual summary 정리:
- weekly insight / quiet accountability mock 제거
- today / last7Days / trend만 남기고 factual card 구조로 단순화
- Calm Session OS 유료화 축 구현:
- Free는 기본 시작, Pro는 더 잘 이어가기를 파는 구조로 재정의
- old `Scene Packs / Sound Packs / Profiles` 중심 copy를 `Daily Focus Plan / Rituals / Weekly Review` 중심으로 교체
- `/app` route를 focus entry surface로 복구:
- `/app` route가 `/space` redirect 대신 `FocusDashboardWidget`을 렌더링
- current/next summary card와 list-first 구조를 제거했다
- 현재는 `Resume` gate가 구현되어 있고, no-session entry shell은 다음 slice에서 `goal + duration + atmosphere` 구조로 교체될 예정이다
- 플랜 tier 공유 store 추가:
- `entities/plan/model/usePlanTier.ts` 추가
- localStorage 기반 Free/Pro 상태를 `/app`, `/space`, `/stats`, dock paywall에서 공통 사용
- Session OS 도메인 mock 추가:
- `FocusPlanItem`
- `SessionTemplate`
- `SessionOutcome`
- `WeeklyReview`
- `AsyncCheckIn`
- `entities/session/model/focusSystem.ts`에 mock/헬퍼 집약
- `/space` planning overview 제거:
- setup drawer에서 Daily Plan / Ritual Library 진입 섹션 제거
- `/app`에서 넘긴 goal + `planItemId`를 받아 execution-only surface로 집중
- `/stats` factual summary 정착:
- factual card 반복 중심의 구조를 해체하고 `Weekly Review` 1차 IA로 전환
- `snapshot + start quality + recovery quality + completion quality + carry forward` 구조를 반영
- 기존 `focus-summary` 응답을 주간 review view model로 변환해서 사용
- recovery는 서버의 `pause 뒤 복귀` 집계를 사용하고, `자리 비움 뒤 복귀`만 limited note로 남긴다
- `/app -> /stats` primary entry의 1차 연결:
- current session이 없고 최근 7일 데이터가 충분할 때 `/app`의 quiet secondary review dock에서 `Weekly Review` entry를 노출한다
- current session이 있으면 `/app` 자체가 `/space`로 이동하므로, `/app` review entry는 no-session entry shell 안에서만 다룬다
- `/stats -> /app` handoff의 2차 연결:
- `/stats` 마지막 CTA는 `/app?review=weekly&carryHint=...&entryPreset=forest-50-10`으로 연결된다
- `/app`은 이 query를 받아 entry stage 위의 review-aware return hint를 노출한다
- goal과 duration은 자동 입력하지 않고, 방향만 가볍게 제안한다
- Pro personalized handoff 3차 연결:
- Pro에서는 `/stats` carry-forward 섹션에 추천 ritual을 함께 보여준다
- `/stats` 마지막 CTA 카피가 generic start가 아니라 `가장 잘 맞은 ritual로 /app 돌아가기`로 바뀐다
- `/app` teaser와 review return hint도 Pro에서 더 구체적인 next-session handoff 톤으로 표시된다
- `/space` secondary review teaser 4차 연결:
- goal complete로 setup 상태로 돌아왔을 때만 setup drawer 아래에 low-emphasis review teaser가 보인다
- teaser는 `주간 review 보기``/stats`를 열고, 방금 끝낸 흐름 반영을 과장하지 않는 카피만 사용한다
- 다시 시작하거나 dismiss하면 사라지며, live execution 중에는 보이지 않는다
- `Weekly Review` recovery의 서버 연결:
- server `focus-summary` 응답에 `recovery`가 추가됐다
- `pause_count / resume_count` 기반 `pause 뒤 복귀`를 실제 수치로 보여준다
- 현재는 `away recovery` 이벤트 스키마가 없어 partial/limited 상태로 남긴다
- paywall / plan / landing 메시지 재정렬:
- paywall 가치 포인트를 multi-queue, rituals, weekly review 중심으로 재작성
- landing pricing에서 구현되지 않은 1:1 매칭 / 오픈 코워킹 / 팀 대시보드를 메인 판매 포인트에서 제거
- Teams는 후순위 준비중 톤으로 약화
- Gemini 분리본 재점검:
- `SpaceWorkspaceWidget`, `SpaceToolsDockWidget`, `admin/page.tsx`, `shared/i18n/ko.ts` 분리 상태를 다시 확인
- 현재 기준 500줄 초과 파일 없음
- 최대 파일은 `src/widgets/admin-console/ui/AdminDashboardView.tsx` 482줄
- `/admin` 업로드 콘솔 회귀 복구:
- widget 분리 이후 로그인 후 placeholder만 보이던 상태 제거
- `AdminConsoleWidget`은 조합만 담당하고, 실제 scene/sound 업로드 UI는 `AdminDashboardView`로 분리 복원
- 인증 전역 상태 위치 정리:
- `src/store/useAuthStore.ts` 제거
- `entities/auth/model/useAuthStore.ts`로 이동해 auth feature가 루트 store를 직접 참조하지 않도록 정리
- auth 타입 참조 정리:
- `features/admin/api/adminApi.ts``features/auth/types` 대신 `entities/auth`를 직접 사용
- `features/auth/types/index.ts`는 중복 선언을 제거하고 `entities/auth` 재export만 담당
- `/space` stage 배경 overscan 보정:
- pan 애니메이션 중 가장자리 빈틈이 드러나지 않도록 stage background layer를 `-inset-8`로 확장
- `/space` 배경 asset 해석 안정화:
- media manifest scene key를 scene alias까지 정규화해 `green-forest``forest`를 동일 asset으로 해석
- scene/sound asset에 `source(fallback|remote)` 메타를 추가해 실제 fallback 사용 여부를 구분 가능하게 정리
- remote manifest load 실패 시 error 상태를 노출하고, `/space`에서 manifest 실패/scene fallback 사용을 진단 로그로 남기도록 보강
- Focus 피드백 채널 단일화:
- HUD 내부 status line을 제거하고 상단 중앙 고정 토스트로 통합
- Notes 저장/Undo, Goal 전환, 잠금 안내 피드백이 동일 위치에서 노출
- Free 코어 루프 개방:
- Quick Controls Time의 `90/20` 잠금을 제거
- 기본 Sound 잠금 제거로 Free에서도 기본 3~6 프리셋 선택 가능
- Pro 가치 재배치:
- Pro 잠금 대상을 `Daily Focus Plan / Rituals / Weekly Review`로 재정의
- 기본 Scene/Time/Sound는 잠금 없이 선택 중심으로 정리
- Control Center UI 재구성:
- Scene/Time/Sound 중심 구조 유지
- 추천 조합을 정보 1줄로 축소(비인터랙션)
- 하단에 Session OS 요약 카드(작은 🔒 배지) 추가
- Paywall 의도 기반 트리거 적용:
- 잠금 카드 클릭 시에만 Paywall Sheet 오픈
- Plan Pill(NORMAL) 클릭은 즉시 결제창 대신 상태 안내만 표시
- Paywall Sheet를 3개 가치 포인트 + 2개 CTA로 간결화
- Focus-First 전환:
- Quick Controls의 `기본/몰입` 토글 제거
- HUD를 외부 모드 상태 없이 기본 몰입 톤으로 고정
- 컨트롤 노출은 패널 열림 상태에서만 보이도록 단순화
- 표시 정책 옵션 추가:
- Quick Controls 패널 하단에 `컨트롤 자동 숨김` 옵션 추가
- 옵션 ON 상태에서 Control Center 8초 무입력 시 자동 닫힘 처리
- Quick Controls 모드 전환 UI 재정렬:
- 헤더에서 모드 토글 UI를 제거하고 `Plan + 닫기`만 유지
- 패널 바디 첫 섹션에 `기본/몰입` segmented pill 배치
- 모드 설명 1줄(기본: 모든 컨트롤 표시, 몰입: 필수만 남기고 숨김) 추가
- 모드 상태를 workspace -> tools-dock -> focus-hud 경로로 연결해 HUD 톤 반영 유지
- `/space` Scene 기반 자동 추천 적용:
- `RoomTheme``recommendedSoundPresetId`, `recommendedTimerPresetId` 필드 추가
- 첫 진입/시작 시 Scene 추천 타이머/사운드가 자동 반영되도록 초기화 로직 정리
- Scene 변경 시 `override.sound/timer``false`인 항목만 자동 동기화
- `/space` 사용자 override 존중 규칙 도입:
- `override.sound`, `override.timer` UI 상태 추가
- 사용자가 직접 고른 항목은 이후 Scene 변경에도 자동 덮어쓰기되지 않도록 반영
- `추천으로 되돌리기(더미)` 액션으로 override 초기화 + 추천값 즉시 복원 지원
- `Control Center`를 Scene/Time 중심으로 단순화:
- Sound/Preset Packs 섹션 제거
- 비인터랙션 추천 정보 1줄(`추천: 사운드 · 타이머`) 추가
- 하단 tertiary 액션 `추천으로 되돌리기` 추가
- 우하단 Sound Quick 경로를 override 적용의 명시적 경로로 분리:
- `onQuickSoundSelect` 콜백으로 연결해 `override.sound` 규칙을 코드 레벨에서 고정
- 세션 상태 더미 저장/복원 추가:
- `sceneId`, `timerPresetId`, `soundPresetId`, `goal`, `override(sound/timer)`를 localStorage에 저장
- 복원 우선순위: 쿼리 파라미터 > 저장 상태 > Scene 추천
- `/space` 진입 Resume CTA 추가:
- 저장된 목표가 있고 쿼리 오버라이드가 없을 때 `지난 한 조각 이어서` 블록 1회 노출
- `이어서 시작`: 저장 목표로 즉시 Focus 진입
- `새로 시작`: 목표를 비워 새 세션 입력 흐름으로 전환
- 세션 복구 운영 문서 추가:
- `docs/foundation/06_commit_convention.md`
- `docs/ops/07_session_recovery.md`
- 워크플로우 토큰 절약 모드 추가:
- `docs/context_core.md` 신설
- `docs/ops/workFlow.md`를 기본 3문서 + 조건부 로드로 변경
- 워크플로우 기본 로드를 2파일로 축소:
- `docs/work.md`
- `docs/session_brief.md`
- 복구 스크립트 추가:
- `scripts/session/recover-context.sh`
- `npm run session:recover` 명령 추가
- `/app` Start Ritual에서 절차감을 높이던 `건너뛰기` 제거
- `/app`에서 `다시 시작(30초)` 제거
- `/space` HUD에 `features/restart-30s` 기반 `↻ 다시 시작 + 30초 배지` 추가
- `/space` 하단 사운드 프리셋 바 제거, 오른쪽 `🎧 Sound` 시트로 이동
- `features/sound-preset` + `widgets/sound-sheet` 추가
- `features/immersion-mode` 추가, Quick 시트에서 몰입 모드 토글 연결
- `/space` 상단 헤더 크롬 최소화:
- 헤더 프레임(border/강한 배경) 제거
- 패딩 축소로 배경 노출 증가
- 타이머 HUD 하단 위치를 safe-area 기반 최소 여백으로 조정
- 몰입 모드 ON 시 상단 액션을 `나가기` 버튼으로 전환
- 클릭 시 토스트 `나가기(더미)` 노출 + 몰입 모드 OFF
- `/space` 상단 우측 나가기 액션을 롱프레스(1초)로 변경
- 0.05초에 진행률 20%까지 빠르게 상승
- 1초 유지 시 `나가기(더미)` 토스트 + 몰입 모드 OFF
- 몰입 OFF: 좌→우 fill(bar), 몰입 ON: 원형 ring 진행 표시
- 롱프레스 bar 진행 표시 버그 수정:
- 눌렀을 때 즉시 fill이 보이도록 CSS keyframes 기반으로 교체
- 완료 후 fill이 0으로 역방향 축소되는 현상 제거(짧은 유지 후 언마운트)
- fill 끝단을 직선 형태로 정리(rounded 캡 제거)
- 30초 복귀 액션 카피를 감성 라운지 톤으로 리브랜딩:
- 버튼 라벨: `숨 고르기 30초`
- 진입 시 HUD 모드 라벨: `BREATHE`
- 클릭 시 저자극 안내 문구 노출(2초 이내 미니 안내 + 토스트)
- `/landing` 이후 앱 플로우 배경 톤을 밝은 무드로 조정:
- `/app` 허브 배경 오버레이를 밝게 조정하고 룸 카드 어두운 마스크 강도 완화
- `/space` 배경 오버레이/비네팅 강도를 낮춰 배경 노출 증가
- `/stats`, `/settings` 배경/패널을 라이트 팔레트로 전환
- `/app` 룸 카드 hydration 에러 수정:
- `RoomPreviewCard`의 중첩 `<button>` 구조 제거
- 카드 내부 칩을 비인터랙티브 `span`으로 변경해 HTML 규칙 위반 해소
- `/app` 허브 배경/카드 가시성 안정화 패치:
- 허브 배경에 blur + 밝기 보정 + 저채도 필터를 적용해 배경 복잡도 완화
- 허브 전역 오버레이를 밝은 워시 중심으로 조정하고 그레인 강도 축소
- `RoomPreviewCard` 내부 콘텐츠 영역에 반투명 패널을 추가해 배경 변동과 텍스트 대비를 분리
- `GlassCard` 표면을 조금 더 밝고 가벼운 글래스 톤으로 보정
- 커스텀 입장 모달 톤/레이아웃 안정화:
- 모달 표면/오버레이를 허브 밝은 톤과 유사한 저대비 글래스로 전환
- `공간/사운드/타이머` 탭 콘텐츠 영역을 고정 높이로 통일해 전환 시 모달 크기 흔들림 제거
- 탭/옵션 버튼과 입력 필드를 밝은 팔레트로 정리해 가독성 개선
- `/app` 핵심 카드(시작/공간) 라이트 카드 전환:
- `지금, 몰입을 시작해요` / `오늘의 공간` 컨테이너를 흰 표면 + 어두운 텍스트 톤으로 조정
- 입력/칩/보조 버튼 색상도 라이트 카드 기준으로 재정렬
- 허브 배경은 가상 공간 이미지를 더 강한 blur로 노출해 카드 외곽 배경으로 유지
- `/app` 오늘의 공간 카드/배경을 룸별 단색 팔레트로 전환:
- `entities/room`에 룸별 `hubColor`를 추가하고 색이 서로 겹치지 않도록 분리
- 오늘의 공간 카드는 이미지 대신 룸 고유 단색 배경으로 렌더링
- 허브 페이지 배경도 선택된 룸의 동일 색으로 전환되도록 연결
- `/app` 오늘의 공간 카드에 실제 사진(외부 URL) 적용:
- `entities/room``cardPhotoUrl`, `googleImageSearchUrl`, `managedCardPhotoUrl` 필드 추가
- 카드 배경은 실제 사진을 사용하고, Google 이미지 검색 링크를 룸별로 보관
- 추후 `managedCardPhotoUrl`만 채우면 자가 관리 이미지로 전환되도록 fallback helper 추가
- `/app` 배경을 카드 사진 기반 블러로 전환:
- 허브 배경이 선택된 카드의 실제 사진을 블러 처리해 표시되도록 변경
- 앱 첫 진입 시 `ROOM_THEMES[0]`를 초기 선택으로 명시해 배경/선택 테두리 기준을 고정
- `/app` 헤더/프로필/공간 카드 디테일 조정:
- AppTopBar 배경 제거 및 로고 왼쪽 원형 `V` 배지 제거
- 프로필 트리거의 이름 왼쪽에 멤버십 등급(`PRO`/`NORMAL`/`TEAM`) 배지 노출
- 공간 카드 높이를 고정해 카드 사진 사이즈를 통일
- 배경 사진 전환 시 resize처럼 보이던 `transition-all` 제거
- `/app` 헤더/프로필 시각 위계 재정렬:
- 헤더 배경/보더/텍스트를 Start Ritual 카드와 동일한 라이트 톤(`bg-white/78`, `text-brand-dark`)으로 통일
- 멤버십 등급 뱃지를 프로필 드롭다운 트리거 외부로 분리해, 프로필 왼쪽 독립 뷰로 배치
- 프로필 드롭다운 트리거는 아바타+이름만 유지하도록 단순화
- `/app` 멤버십 등급 배지의 프리미엄 톤 강화:
- 배지 타이포를 `text-xs` 이상으로 상향하고 칩 높이/패딩을 키워 가독성과 존재감을 개선
- `PRO MEMBER` 라벨과 저채도 그라데이션/내부 하이라이트/부드러운 그림자로 유료 멤버 위계를 강화
- `NORMAL`/`TEAM`도 등급별 표면 톤과 마커를 분리해 동일 구조 안에서 차분한 구분을 제공
- `/app` 멤버십 배지 고급화 2차 적용:
- 등급 칩 높이를 `h-9`, 최소폭을 부여해 헤더 내에서 배지가 독립된 프리미엄 토큰처럼 보이도록 정렬
- `PRO`는 모바일 축약 라벨, 데스크톱 `PRO MEMBER` 라벨을 분리해 밀집을 완화
- 헤더 우측 그룹 간격을 `gap-3`으로 조정해 배지와 프로필 트리거의 시각 충돌을 완화
- 몰입 모드 ON 시 `/space` 크롬 정리:
- 상단 `Current Room` 블록 숨김
- 우상단 허브 버튼 소형 아이콘화
- 오른쪽 아이콘 레일 기본 미니화(hover/click 시 확장)
- HUD 대비/불투명도 완화
- 비네팅/그레인 강화
- `/app` 룸 카드의 인원수 기반 정보 제거
- `entities/room`에 분위기/추천 필드 추가:
- `recommendedSound`
- `recommendedTime`
- `vibeLabel`
- 룸 카드 정보 표현을 큐레이션 중심으로 전환
## NEXT
1. `/app` atmosphere entry shell 구현
2. custom duration contract 정리
3. weekly review dock 위치 재설계
## RISKS
- Free/Pro 제한은 클라이언트 local tier 기준이므로 서버에서 직접 막지 않는다
- Free/Pro gating은 localStorage mock tier 기반이라 실제 구독 상태와 연결되지 않았다
- `advance-goal`은 atomic endpoint 기준으로 동작하지만, 네트워크 실패 시 사용자는 현재 시트에서 재시도해야 한다
- Session OS 도메인은 mock 기반이므로 실제 저장/복구 API 없이도 화면만 먼저 완성된 상태다
- empty state에서 CTA는 살아 있지만 실제 시작 전에 입력 포커스가 먼저 필요하므로, 첫 진입 사용성은 브라우저 확인이 필요하다
- `/space` paywall 전환 진입점은 `/app` / `/stats` 중심이라 execution 화면만 본 사용자에게는 업그레이드 맥락이 약할 수 있다
- `/admin` 업로드 콘솔은 구조 복구가 끝났지만, 실제 파일 업로드 경로는 브라우저 수동 검증 전까지 확정할 수 없다
- stage background overscan으로 좁은 화면에서 배경 crop이 조금 더 강하게 느껴질 수 있어 실기기 확인이 필요하다
- remote manifest 실패 시 원인 진단은 가능해졌지만, 사용자용 복구 액션 UI는 아직 없다
- alias 목록에 없는 legacy scene id가 추가되면 같은 fallback 문제가 재발할 수 있다
- `npm run build`는 네트워크 제한 시 Google Font fetch 실패 가능
- localStorage 포맷 변경 시 이전 세션 저장값과의 호환성 이슈 가능
- Scene 추천값과 실제 사용자 선호가 어긋나면 자동 적용 체감 품질이 낮아질 수 있음
- 터치 기기에서 레일 미니 상태가 발견성 낮을 수 있어 추가 힌트가 필요할 수 있음
- 일부 시트(예: Room)는 아직 인원수 중심 문구가 남아 있어 톤 불일치 가능성 존재
- safe-area 값이 작은 기기에서는 HUD가 너무 낮게 느껴질 수 있어 세부 조정 여지 존재
- 롱프레스 인터랙션은 첫 사용자에게 즉시 인지되지 않을 수 있어 시각적 힌트 필요 가능성 있음
- bar/ring 진행 표시는 서로 다른 구현(JS/CSS)이라 동기화 규칙 변경 시 회귀 점검이 필요
- 안내 카피가 HUD 목표 문구와 교체 표시되므로 정보 밀도 균형 점검 필요
- 밝아진 배경 구간에서 일부 white 텍스트의 대비가 환경(디스플레이 밝기)에 따라 약해질 수 있음
- 배경 필터/블러 적용으로 저사양 환경에서 스크롤 시 미세한 페인팅 비용 증가 가능성 존재
- 모달 본문 고정 높이 적용으로 작은 화면에서 내부 스크롤 의존도가 이전보다 높아질 수 있음
- 룸 프리뷰 카드 내부는 이미지 기반 다크 텍스트 체계라 컨테이너와 톤 차이가 남아 추가 톤 정리가 필요할 수 있음
- 단색 팔레트가 일부 기기 색감에서 유사하게 보일 수 있어 실제 디스플레이 기준 재점검 필요
- 외부 이미지 URL(임시) 의존이라 소스 만료/속도 이슈 가능성이 있어 자가 호스팅 전환 필요
- 전체 배경 블러 강도 증가로 저사양 환경에서 GPU 부담이 늘 수 있어 실기기 체감 점검 필요
- 밝은 배경 사진과 라이트 헤더 조합에서 상단 경계 인지가 약해질 수 있어 대비 점검 필요
- 등급 칩 최소폭 증가로 초소형 화면에서 헤더 가로 여유가 줄어들 수 있어 간격 점검 필요
- Plan Pill에서 바로 결제창이 열리지 않도록 바뀌어, 일부 사용자는 업그레이드 진입 경로를 늦게 인지할 수 있음
- Packs 카드가 더미 상태이므로 Pro 가치 설명 카피가 약하면 클릭 동기가 낮아질 수 있음
## CHANGED FILES
- (이번 구조 재점검)
- `src/widgets/admin-console/ui/AdminConsoleWidget.tsx`
- `src/widgets/admin-console/ui/AdminDashboardView.tsx`
- `src/features/admin/api/adminApi.ts`
- `src/features/auth/types/index.ts`
- `src/entities/auth/index.ts`
- `src/entities/auth/model/useAuthStore.ts`
- `src/features/auth/hooks/useSocialLogin.ts`
- `src/features/auth/components/AuthRedirectButton.tsx`
- `docs/foundation/02_arch_fsd_rules.md`
- `docs/work.md`
- `docs/90_current_state.md`
- `docs/session_brief.md`
- (이번 세션)
- `src/app/(app)/app/page.tsx`
- `src/widgets/focus-dashboard/ui/FocusDashboardWidget.tsx`
- `src/widgets/focus-dashboard/ui/FocusPlanManageSheet.tsx`
- `src/widgets/focus-dashboard/ui/FocusPlanListRow.tsx`
- `src/entities/focus-plan/model/useFocusPlan.ts`
- `src/widgets/focus-dashboard/index.ts`
- `src/entities/plan/model/usePlanTier.ts`
- `src/entities/session/model/focusSystem.ts`
- `src/widgets/space-setup-drawer/ui/SpaceSetupDrawerWidget.tsx`
- `src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx`
- `src/widgets/stats-overview/ui/StatsOverviewWidget.tsx`
- `src/shared/i18n/messages/core.ts`
- `src/shared/i18n/messages/app.ts`
- `src/shared/i18n/messages/product.ts`
- `src/shared/i18n/messages/space.ts`
- `src/entities/media/model/types.ts`
- `src/entities/media/model/resolveMediaAsset.ts`
- `src/entities/media/model/useMediaCatalog.ts`
- `docs/work.md`
- `docs/90_current_state.md`
- `docs/session_brief.md`
- (최근 workflow 반영)
- `src/widgets/space-workspace/ui/FocusTopToast.tsx`
- `src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx`
- `src/widgets/space-focus-hud/ui/SpaceFocusHudWidget.tsx`
- `src/widgets/space-timer-hud/ui/SpaceTimerHudWidget.tsx`
- `src/entities/plan/model/mockPlan.ts`
- `src/entities/plan/model/types.ts`
- `src/widgets/control-center-sheet/ui/ControlCenterSheetWidget.tsx`
- `src/widgets/space-tools-dock/ui/SpaceToolsDockWidget.tsx`
- `src/features/paywall-sheet/ui/PaywallSheetContent.tsx`
- `src/widgets/space-focus-hud/ui/SpaceFocusHudWidget.tsx`
- `src/widgets/space-tools-dock/ui/SpaceToolsDockWidget.tsx`
- `src/widgets/space-workspace/ui/SpaceWorkspaceWidget.tsx`
- `src/widgets/control-center-sheet/ui/ControlCenterSheetWidget.tsx`
- `src/entities/room/model/types.ts`
- `src/entities/room/model/rooms.ts`
- `src/widgets/space-tools-dock/model/applyQuickPack.ts` (삭제)
- `docs/foundation/06_commit_convention.md`
- `docs/ops/07_session_recovery.md`
- `docs/context_core.md`
- `docs/session_brief.md`
- `docs/ops/workFlow.md`
- `docs/README.md`
- `.gitmessage-session.txt`
- `scripts/session/recover-context.sh`
- `package.json`
- `src/widgets/start-ritual-widget/ui/StartRitualWidget.tsx`
- `src/widgets/app-hub/ui/AppHubWidget.tsx`
- `src/entities/room/model/types.ts`
- `src/entities/room/model/rooms.ts`
- `src/features/room-select/ui/RoomPreviewCard.tsx`
- `src/widgets/app-hub/ui/AppHubWidget.tsx`
- `src/widgets/app-top-bar/ui/AppTopBar.tsx`
- `src/entities/user/model/types.ts`
- `src/entities/user/model/mockUser.ts`
- `src/entities/user/ui/MembershipTierBadge.tsx`
- `src/features/profile-menu/ui/ProfileMenu.tsx`
- `src/features/restart-30s/index.ts`
- `src/features/restart-30s/model/useRestart30s.ts`
- `src/features/restart-30s/ui/Restart30sAction.tsx`
- `src/features/immersion-mode/index.ts`
- `src/features/immersion-mode/model/useImmersionMode.ts`
- `src/features/immersion-mode/ui/ImmersionModeToggle.tsx`
- `src/features/sound-preset/index.ts`
- `src/features/sound-preset/model/useSoundPresetSelection.ts`
- `src/features/sound-preset/ui/SoundPresetControls.tsx`
- `src/shared/ui/Toggle.tsx`
- `src/widgets/sound-sheet/index.ts`
- `src/widgets/sound-sheet/ui/SoundSheetWidget.tsx`
- `src/widgets/space-chrome/index.ts`
- `src/widgets/space-chrome/ui/SpaceChromeWidget.tsx`
- `src/widgets/quick-sheet/ui/QuickSheetWidget.tsx`
- `src/widgets/space-shell/ui/SpaceSkeletonWidget.tsx`
- `src/widgets/space-tools-dock/model/useSpaceToolsDock.ts`
- `src/widgets/space-tools-dock/ui/SpaceToolsDockWidget.tsx`
- `src/widgets/space-timer-hud/ui/SpaceTimerHudWidget.tsx`
- `src/widgets/space-chrome/ui/SpaceChromeWidget.tsx`
- `src/features/immersion-mode/model/useImmersionMode.ts`
- `src/features/exit-hold/index.ts`
- `src/features/exit-hold/model/useHoldToConfirm.ts`
- `src/features/exit-hold/ui/ExitHoldButton.tsx`
- `src/app/globals.css`
- `src/features/restart-30s/model/copy.ts`
- `src/features/restart-30s/model/useRestart30s.ts`
- `src/features/restart-30s/ui/Restart30sAction.tsx`
- `src/features/restart-30s/index.ts`
- `src/widgets/space-timer-hud/ui/SpaceTimerHudWidget.tsx`
- `src/widgets/app-hub/ui/AppHubWidget.tsx`
- `src/features/room-select/ui/RoomPreviewCard.tsx`
- `src/app/(app)/space/page.tsx`
- `src/widgets/space-shell/ui/SpaceSkeletonWidget.tsx`
- `src/widgets/stats-overview/ui/StatsOverviewWidget.tsx`
- `src/widgets/settings-panel/ui/SettingsPanelWidget.tsx`
- `src/shared/ui/GlassCard.tsx`
- `src/widgets/app-hub/ui/AppHubWidget.tsx`
- `src/features/room-select/ui/RoomPreviewCard.tsx`
- `src/shared/ui/Modal.tsx`
- `src/shared/ui/Tabs.tsx`
- `src/features/custom-entry-modal/ui/CustomEntryModal.tsx`
- `src/widgets/start-ritual-widget/ui/StartRitualWidget.tsx`
- `src/widgets/rooms-gallery-widget/ui/RoomsGalleryWidget.tsx`
- `src/widgets/app-hub/ui/AppHubWidget.tsx`
- `src/entities/room/model/types.ts`
- `src/entities/room/model/rooms.ts`
- `src/features/room-select/ui/RoomPreviewCard.tsx`
## QUICK VERIFY
1. `/app`: 건너뛰기/다시 시작 노출 없음
2. `/app`: 룸 카드에 사람 수 문구 없음, 추천 정보 노출
3. `/space`: 하단 사운드 바 없음, 오른쪽 `🎧 Sound` 시트에서 프리셋 선택 가능
4. `/space`: 몰입 모드 ON 시 상단 룸 블록 숨김 + 레일 미니화 + HUD 저대비 적용
5. `/app`: 콘솔에 `button cannot be a descendant of button` hydration 에러가 재발하지 않음
6. `/app`: 숲/벽난로처럼 텍스처가 많은 룸 선택 시에도 카드 내부 텍스트 시인성이 유지됨
7. 커스텀 입장 모달 탭 전환(공간/사운드/타이머) 시 외곽 모달 크기가 유지됨
8. `/app`: 시작 카드/공간 카드가 흰 표면 + 어두운 텍스트로 표시되고, 카드 밖 배경은 블러된 가상 공간으로 노출됨
9. `/app`: 오늘의 공간 카드가 룸별 단색으로 표시되고, 허브 배경도 선택 카드 색으로 동기화됨
10. `/app`: 오늘의 공간 카드가 실제 사진으로 표시되고, room 데이터에 Google 검색 링크/자가 이미지 전환 필드가 포함됨
11. `/app`: 첫 진입 시 첫 카드가 선택된 상태로 보이며, 배경도 해당 카드 사진 블러로 시작됨
12. `/app`: 헤더가 시작 카드와 같은 라이트 톤으로 표시되고, 등급 배지가 프로필 왼쪽 독립 뷰로 노출됨
13. `/app`: 공간 카드가 동일 높이로 맞춰지고 카드 전환 시 배경 resize 느낌이 완화됨