docs(docs): 문서를 화면과 용도별 폴더로 재구성

This commit is contained in:
2026-03-16 11:31:03 +09:00
parent acfa8f4f48
commit 38a9d1e762
25 changed files with 112 additions and 112 deletions

View File

@@ -0,0 +1,487 @@
# 10. Refocus System Spec
Last Updated: 2026-03-15
이 문서는 VibeRoom의 `Refocus System`을 제품 대표 경험으로 설계하기 위한 상세 기준 문서다.
관련 상위 문서:
- `../../product_principles.md`
- `../../current_context.md`
- `../app/19_app_atmosphere_entry_spec.md`
---
## 1. 왜 Refocus가 핵심인가
VibeRoom의 차별점은 `더 오래 계획하게 만드는 것`이 아니라,
`흔들린 뒤에도 다시 집중 위에 올라타게 만드는 것`이어야 한다.
ADHD 성향 사용자와 프리랜서에게 진짜 어려운 순간은 대개 아래 셋 중 하나다.
- 시작 직전
- 잠깐 멈췄다가 다시 붙잡아야 할 때
- 한 조각을 끝냈는데 다음 동작이 흐려졌을 때
`/app`이 시작 마찰을 줄이는 화면이라면,
`Refocus System`은 **세션 도중 무너진 흐름을 다시 복구하는 핵심 시스템**이다.
---
## 2. 레퍼런스에서 가져올 것 / 버릴 것
이 문서는 2026-03-14 기준 공식 사이트를 기준으로 아래 레퍼런스를 참고했다.
- [Portal](https://portal.app/)
- [LifeAt Pricing](https://lifeat.io/pricing)
- [Focusmate Pricing](https://www.focusmate.com/pricing/)
- [Focusmate Getting Started](https://support.focusmate.com/en/articles/9110188-getting-started)
- [Focusmate Focus Now](https://support.focusmate.com/en/articles/9994509-focus-now)
### Portal에서 가져올 것
- 배경이 주인공이고 인터페이스는 조용히 뒤로 물러나야 한다
- 감각 품질 자체가 제품 가치가 된다
- “아름답다”가 장식이 아니라 사용 지속 이유가 된다
### Focusmate에서 가져올 것
- 행동을 시작시키는 명확한 구조
- 사용자가 망설이지 않게 하는 단일 흐름
- `지금 바로 들어간다`는 즉시성
### LifeAt에서 가져올 것
- 가볍게 시작할 수 있는 친화성
- 공간과 집중을 연결하는 감성
### LifeAt에서 가져오면 안 되는 것
- planner / todo / calendar 중심 구조
- 목표를 많이 다루게 하는 흐름
- “집중 앱”보다 “정리 앱”처럼 읽히는 경험
---
## 3. 한 줄 정의
> Refocus는 사용자가 흔들렸을 때 죄책감 없이 다시 한 조각 위에 올라타게 만드는 조용한 복귀 의식이다.
중요한 점:
- `수정 기능`이 아니다
- `체크리스트`가 아니다
- `왜 못 했는지 묻는 평가 시스템`이 아니다
---
## 4. 제품 목표
Refocus System은 아래 4가지를 만족해야 한다.
1. 사용자가 세션을 포기하지 않게 한다
2. pause 이후 복귀 마찰을 줄인다
3. microStep을 다시 잡아 실행을 재개하게 한다
4. UI가 배경과 몰입을 방해하지 않는다
---
## 5. 시스템 원칙
### 1. Refocus는 한 번에 한 질문만 한다
질문을 여러 개 던지면 planner처럼 느껴진다.
항상 다음 하나만 물어야 한다.
- 계속할까?
- 지금 할 한 조각은 무엇일까?
- 이 목표를 끝낼까?
### 2. 사용자를 평가하지 않는다
금지:
- 왜 못 했어요?
- 얼마나 산만했나요?
- 다시 집중하세요
허용:
- 다음 한 조각이 있나요?
- 지금 다시 시작할 수 있게 한 줄만 남겨볼까요?
- 여기까지로 충분한가요?
### 3. goal은 1개, microStep도 1개
Refocus는 절대 리스트 관리 UI가 되면 안 된다.
- multi-step 금지
- queue 금지
- subtask list 금지
### 4. 배경은 항상 주인공이다
Refocus UI는 강한 모달이 아니라 **배경 위에 잠깐 생겼다가 사라지는 얇은 recovery layer**여야 한다.
### 5. Premium은 절제에서 온다
좋은 Refocus는 화려한 카드나 모션이 아니라 아래에서 온다.
- 올바른 정보 밀도
- 1개의 명확한 행동
- 자연스러운 등장과 퇴장
- 배경과 어우러지는 재질감
---
## 6. Refocus가 필요한 순간들
Refocus는 아래 4개 진입점으로 고정한다.
### A. Pause 직후
사용자가 세션을 멈춘 뒤 다시 돌아와야 하는 순간.
### B. MicroStep 완료 직후
현재 한 조각은 끝났지만 다음 행동이 아직 흐린 순간.
### C. 사용자가 의도를 직접 수정하고 싶을 때
goal이나 microStep을 다시 정리하고 싶은 수동 진입.
### D. 세션에서 멀어졌다가 복귀했을 때
탭을 바꾸거나 잠깐 이탈한 후 다시 `/space`로 돌아온 상황.
---
## 7. 화면 상태 모델
Refocus는 아래 5개 상태만 가진다.
1. `Focused`
2. `Paused`
3. `Refocus`
4. `Next Beat`
5. `Complete`
한 번에 활성화되는 확장 상태는 하나만 허용한다.
- `Refocus`
- `Next Beat`
- `Complete`
이 셋은 동시에 보이면 안 된다.
---
## 8. 상태별 상세 UX
### CTA Matrix
Refocus family에서 중요한 원칙은 하나다.
> 세션이 아직 살아 있는 상태라면, 사용자는 언제든 `계속 / 다시 잡기 / 마무리` 중 하나로 갈 수 있어야 한다.
상태별 CTA는 아래처럼 고정한다.
| 상태 | 보여야 하는 주 행동 | goal complete 접근 |
| --- | --- | --- |
| `Focused` | `수정`, `microStep 완료`, `이번 목표 완료`, timer `pause/reset` | base intent card에서 직접 노출 |
| `Paused` | `한 조각 다시 잡기`, `바로 이어가기` | pause tray의 low-emphasis `여기서 마무리하기` |
| `Return (focus)` | `멈춘 자리에서 이어가기`, `한 조각 다시 잡기` | return tray의 low-emphasis `여기서 마무리하기` |
| `Break` | break 유지, 다음 블록으로 이어가기, goal closure | base intent card에서 직접 노출 |
| `Return (break)` | `쉬기 이어가기`, `다음 블록 이어가기`, `한 조각 다시 잡기` | return tray의 low-emphasis `여기서 마무리하기` |
| `Next Beat` | `목표만 두고 계속하기`, `다음 단계 적기` | next-beat tray의 low-emphasis `이 목표는 여기서 마무리하기` |
`Refocus` 편집 시트 자체는 편집에만 집중하고, complete 액션은 별도 decision tray나 base intent card에서 수행한다.
### 8.1 Focused
목표:
- 사용자가 UI를 거의 의식하지 않고 일하는 상태
보여야 하는 것:
- goal
- optional microStep
- timer HUD
- minimal controls
보이면 안 되는 것:
- 질문
- 복구 유도 문구
- task-like affordance
### 8.2 Paused
목표:
- 세션이 끊긴 느낌이 아니라 잠시 호흡을 고르는 느낌
행동:
- 바로 큰 sheet를 띄우지 않는다
- HUD 상태가 paused로 바뀌고,
- `다시 시작할 준비가 되면 한 조각만 다시 잡는다`는 감각을 준다
### 8.3 Refocus
목표:
- 목표를 버리지 않고 다시 시작점을 만든다
UI:
- anchored tray 또는 compact sheet
- 필드 2개
- 이번 세션 목표
- 지금 할 한 조각
- CTA 2개
- 적용
- 취소
중요:
- `다시 방향 잡기`는 메인 액션이 아니라 recovery action이어야 한다
- button cluster처럼 보이면 안 된다
### 8.4 Next Beat
목표:
- microStep 완료 후 checklist가 아니라 “다음 한 조각”으로 연결
질문:
> 다음 한 조각이 있나요?
행동:
- `한 조각 정하기`
- `없이 계속`
금지:
- 다음 step list 펼치기
- 여러 개 제안
- 정리형 UI
### 8.5 Complete
목표:
- 목표가 끝났을 때 닫음과 다음 시작을 모두 부드럽게 연결
질문:
- 여기까지 끝났나요?
행동:
- 여기서 마무리하기
- 다음 블록 이어가기
- 잠시 비우기
완료는 celebration보다 **closure quality**가 중요하다.
---
## 9. 상세 플로우
### Flow A. Pause -> Refocus -> Resume
1. 사용자가 pause 한다
2. UI는 즉시 평가하지 않는다
3. 사용자가 resume을 누르거나 intent를 누르면 Refocus로 들어갈 수 있다
4. 사용자는 goal / microStep 중 필요한 것만 조정한다
5. `적용 후 이어가기` 또는 `적용` 뒤 resume
목표:
- pause 이후 바로 복귀하는 것이 아니라,
- 한 번 숨을 고르고 다시 붙잡게 만든다
### Flow B. MicroStep Complete -> Next Beat
1. 사용자가 microStep completion mark를 누른다
2. 기존 microStep은 조용히 처리된다
3. `다음 한 조각이 있나요?`가 나타난다
4. 사용자는
- 새 microStep을 적거나
- 없이 계속 간다
목표:
- planner처럼 다음 목록을 만드는 것이 아니라
- 지금 하나만 다시 붙잡게 한다
### Flow C. Manual Refocus
1. 사용자가 goal 영역을 눌러 의도 수정 진입
2. goal / microStep 수정
3. 적용
4. 조용히 복귀
목표:
- 세션을 깨지 않는 범위에서 intent만 조정
### Flow D. Goal Complete -> Next Goal or Close
1. 사용자가 goal complete 진입
2. 현재 목표를 닫을지, 다음 목표로 이어갈지 선택
3. 다음 목표는 여전히 1개만 다룬다
목표:
- checklist가 아니라 clean transition
---
## 10. UI 구조
### 레이어 구조
#### Layer 1. Background
- 배경 이미지/영상
- 주인공
#### Layer 2. Core HUD
- timer
- sound / scene controls
- intent card
#### Layer 3. Recovery Layer
- refocus tray
- next beat prompt
- complete tray
Recovery Layer는 Core HUD와 같은 material family를 가져야 한다.
다만 더 조용하고 얇아야 한다.
### Material 방향
- iOS 계열의 refined glass 참고
- 강한 탁도보다 `투명 + blur + 얕은 경계`를 우선
- glow, heavy shadow, thick border 금지
- chip 남발 금지
### 모션 방향
- 빠르게 튀어나오지 않는다
- appear 220~280ms
- disappear 180~220ms
- scale보다는 opacity + position shift 위주
---
## 11. 카피라이팅 방향
### tone
- 짧다
- 저압력이다
- 평가하지 않는다
- 다시 시작할 수 있게 한다
### 좋은 예
- `지금 할 한 조각`
- `다음 한 조각이 있나요?`
- `한 줄만 다듬고 다시 시작해요.`
- `여기까지로 충분한가요?`
### 피해야 할 예
- `할 일`
- `리스트`
- `관리`
- `다음 단계들`
- `왜 못 했나요?`
---
## 12. Free / Pro에서의 역할
### Free
- 기본 refocus 진입
- goal / microStep 재설정
- next beat prompt
- goal complete 기본 흐름
### Pro
- 더 정교한 refocus guidance
- 세션 패턴 기반 microStep 제안
- 어떤 ritual에서 복귀율이 높은지 review에 반영
중요:
Pro는 `더 많은 목표`가 아니라 `더 높은 복귀 성공률`을 파는 쪽으로 가야 한다.
---
## 13. 성공 지표
Refocus System은 아래 지표로 판단한다.
- Pause 후 Resume 비율
- Pause 후 Refocus 진입 비율
- Refocus 후 2분 이상 유지 비율
- MicroStep 완료 후 Next Beat 입력 비율
- Goal complete 후 다음 세션 전환 비율
- 세션 중 abandon 비율 감소
---
## 14. 구현 우선순위
### Slice 1
- pause 이후 Refocus 진입 구조 정리
- goal / microStep 수정 tray 정교화
- 한 번에 하나의 overlay만 뜨도록 상태 정리
### Slice 2
- microStep 완료 -> Next Beat 흐름 정리
- checklist 느낌 제거
### Slice 3
- goal complete tray의 완성도 향상
- closure / next goal / break 분기 정리
### Slice 4
- Pro용 adaptive refocus 기획
- review와 refocus 연결
---
## 15. 절대 피해야 할 방향
- pause를 실패처럼 느끼게 하는 UX
- checklist UI
- multi-step planner화
- 과한 그래프 / 통계 immediate 노출
- 배경보다 더 앞에 나오는 recovery UI
- action chip 남발
- 한 번에 여러 질문을 던지는 sheet
---
## 16. 이 문서를 기준으로 다음 구현에서 꼭 지켜야 할 것
- Refocus는 `편집 기능`이 아니라 `recovery ritual`처럼 느껴져야 한다
- 사용자는 한 번에 하나의 행동만 선택해야 한다
- 배경은 절대 희생시키지 않는다
- premium quality는 더 많은 glass가 아니라 더 적은 friction에서 나온다

View File

@@ -0,0 +1,441 @@
# 11. Away / Return Recovery Spec
Last Updated: 2026-03-14
이 문서는 사용자가 `pause`를 누르지 않고 그냥 자리를 떠난 경우를 VibeRoom이 어떻게 감지하고, 어떻게 맞이하고, 어떻게 다시 복귀시킬지를 정의하는 상세 기준 문서다.
관련 문서:
- `../../product_principles.md`
- `../../current_context.md`
- `./10_refocus_system_spec.md`
---
## 1. 왜 이 기획이 중요한가
ADHD 성향 사용자와 프리랜서는 자주 아래처럼 이탈한다.
- `pause`를 누를 생각도 못 한 채 자리에서 일어남
- 잠깐 딴 탭을 보다가 세션 흐름을 잃음
- focus가 끝났는지도 모른 채 돌아옴
이 상황을 제품이 다루지 않으면 아래 문제가 생긴다.
- Refocus가 “사용자가 pause를 눌렀을 때만 작동하는 기능”으로 축소된다
- 세션이 실제 흐름보다 더 기계적으로 느껴진다
- `pause``break`가 같은 “멈춘 상태”처럼 읽힌다
- 돌아온 사용자를 잘못된 상태로 맞이하게 된다
VibeRoom은 감시 앱이 되어서는 안 되지만,
**돌아왔을 때의 복귀 품질**은 반드시 설계해야 한다.
---
## 2. 한 줄 정의
> Away / Return은 사용자의 무의식적 이탈을 실패로 다루지 않고, 돌아왔을 때 가장 자연스럽게 다시 몰입 위에 올려놓는 복귀 레이어다.
중요한 점:
- 사용자를 통제하거나 막는 기능이 아니다
- “왜 떠났는가”를 추궁하지 않는다
- 핵심은 detection보다 **return UX**다
---
## 3. 이 시스템이 해결해야 하는 문제
### 문제 A. 사용자는 `pause`를 누르지 않는다
사용자는 실제로는 쉬고 싶어서 일어난 것이어도,
제품 안에서는 아무 액션도 하지 않은 채 세션이 흘러간다.
### 문제 B. focus가 끝났는데 break처럼 보인다
사용자가 없던 사이 focus가 끝났다면, 돌아왔을 때 단순 `Break`로 맞이하면 안 된다.
그건 제품이 사용자의 실제 맥락을 오해한 것이다.
### 문제 C. pause와 break가 겹쳐 보인다
현재 감정적으로는 이렇게 읽히기 쉽다.
- `Pause`: 내가 멈춤
- `Break`: focus가 끝나서 쉬는 중
둘은 의미가 다른데, UI와 상태가 충분히 분리되지 않으면 같은 “멈춤”처럼 느껴진다.
---
## 4. 핵심 원칙
### 1. 감시는 하지 않는다
아래는 금지한다.
- webcam / face tracking
- 키보드/마우스 무입력만으로 강제 이탈 판정
- 사용자를 혼내는 알림
- “집중하지 않았네요” 류의 카피
### 2. 확실한 신호만 사용한다
웹에서 “자리 비움”은 정확히 알 수 없다.
따라서 v1은 아래처럼 비교적 강한 신호만 쓴다.
- `visibilitychange`
- `pagehide`
- 브라우저/기기 sleep 이후 큰 시간 점프
- 창 복귀 시점
### 3. detection보다 return이 중요하다
중요한 것은 “네가 떠났다는 걸 알아냈다”가 아니라,
**“돌아온 지금 무엇을 제안할 것인가”**다.
### 4. Pause와 Break는 명확히 다르게 느껴져야 한다
- `Pause`는 recovery tone
- `Break`는 release / reset tone
- `Return`은 re-entry tone
### 5. focus ended while away는 Break가 아니라 Return이다
사용자가 없는 동안 focus가 끝났다면,
돌아온 순간의 경험은 `쉬는 중`이 아니라 `복귀 결정`이어야 한다.
---
## 5. 상태 모델
VibeRoom의 세션 상태를 제품적으로는 아래처럼 다룬다.
### Core States
- `Focus`
- `Pause`
- `Break`
### Recovery States
- `AwayCandidate`
- `Return`
### 의미
#### Focus
사용자가 현재 세션 안에서 일하고 있음
#### Pause
사용자가 의도적으로 멈춤
#### Break
focus 블록을 끝내고 의도적으로 쉬는 상태
#### AwayCandidate
사용자가 실제로 자리를 떴을 가능성이 높은 내부 판단 상태
#### Return
이탈 후 다시 돌아온 순간, 제품이 복귀를 제안하는 상태
---
## 6. 웹에서의 감지 전략
### v1에서 사용하는 신호
#### 1. visibility hidden
- 사용자가 탭을 떠남
- 브라우저가 background로 감
#### 2. pagehide / tab background
- 페이지가 전환되거나 숨겨짐
#### 3. sleep / wake 시간 점프
- 사용자가 기기를 잠그거나 화면이 꺼졌다가 돌아왔을 가능성
- `Date.now()` 기준 큰 delta로 감지
### v1에서 사용하지 않는 신호
#### blur / focus 단독
너무 오탐이 많다.
#### 무입력 시간만으로 Away 판단
읽고 생각하는 사용자를 잘못 판정할 수 있다.
#### pointer / keyboard tracking 강제화
감시처럼 느껴질 수 있어 금지
---
## 7. 판단 규칙
### Rule 1. focus 중 hidden/wake gap 발생
상태:
- `Focus`
- `visibility hidden` 또는 `sleep/wake delta` 발생
처리:
- 내부적으로 `AwayCandidate`
### Rule 2. 돌아왔을 때 focus가 아직 안 끝남
상태:
- 사용자가 복귀
- 남은 focus 시간이 남아 있음
처리:
- `Return` tray 노출
- 질문:
- `이어서 할까요?`
- `한 조각 다시 잡을까요?`
### Rule 3. 돌아왔을 때 focus가 이미 끝남
상태:
- 사용자가 복귀
- focus phase는 끝났음
- 하지만 사용자는 그 종료를 경험하지 못했음
처리:
- `Break` 직접 진입 금지
- `Return` tray 노출
- 질문:
- `자리를 비운 사이 이 블록이 끝났어요. 지금 어떻게 이어갈까요?`
행동:
- `지금부터 쉬기`
- `다음 목표로 이어가기`
- `한 조각 다시 잡기`
### Rule 4. pause 상태에서 복귀
상태:
- 이미 사용자가 직접 `Pause`한 상태
처리:
- 이건 Away보다 Pause 흐름이 우선
- 기존 pause recovery prompt 유지
즉, `Away / Return`은 manual pause를 덮어쓰지 않는다.
---
## 8. Return UX 설계
### Return의 목적
- 죄책감 없이 다시 올려놓기
- `지금 어떤 상태인지`를 간단히 알려주기
- 선택지를 2~3개만 제시하기
### Return의 기본 구조
- eyebrow: `다시 돌아왔어요`
- 짧은 현재 맥락 설명
- primary action 1개
- secondary action 1개
- tertiary는 최대 1개
### Case A. focus still running
카피 예:
- 제목: `이어서 갈까요?`
- 설명: `흐름은 그대로 남아 있어요. 바로 이어가거나 한 조각만 다시 잡을 수 있어요.`
행동:
- primary: `이어서 하기`
- secondary: `한 조각 다시 잡기`
### Case B. focus ended while away
카피 예:
- 제목: `자리를 비운 사이 이 블록이 끝났어요.`
- 설명: `지금부터 쉬거나, 다음으로 이어갈 수 있어요.`
행동:
- primary: `지금부터 쉬기`
- secondary: `다음 목표 이어가기`
- tertiary: `한 조각 다시 잡기`
### Case C. break ended while away
이건 v1에서는 단순화한다.
- break가 끝났고 사용자가 돌아왔다면
- `다음 블록으로 이어갈까요?` 정도의 단순 return prompt만 둔다
- 이 상태는 후속 slice에서 다룬다
---
## 9. Pause / Break / Return의 차이
### Pause
- 사용자가 직접 멈춘 상태
- 톤: recovery
- 질문:
- `한 조각 다시 잡기`
- `이대로 이어가기`
### Break
- 사용자가 focus 블록을 끝낸 뒤 쉬는 상태
- 톤: release / reset
- 질문:
- `쉬기 계속`
- `다음으로 가기`
### Return
- 사용자가 떠났다가 돌아온 상태
- 톤: re-entry
- 질문:
- `지금 어디서 다시 시작할까?`
핵심:
`Pause``Return`은 비슷하지만 다르다.
- Pause는 사용자가 멈춘 것
- Return은 제품이 사용자의 이탈을 감지하고 다시 맞이하는 것
---
## 10. UI / Layer 구조
### Layer 원칙
- Away / Return도 기존 recovery family 안에 들어간다
- 한 번에 하나의 recovery layer만 열 수 있다
우선순위:
1. `Complete`
2. `Return`
3. `Pause`
4. `Refocus`
5. `Next Beat`
### 이유
- Complete는 가장 명시적이고 종료 의미가 강함
- Return은 환경 변화에 대한 복귀 진입점
- Pause는 사용자의 수동 멈춤
- Refocus와 Next Beat는 더 세부적인 recovery 단계
---
## 11. 카피 원칙
### 좋은 톤
- `다시 돌아왔어요`
- `흐름은 그대로 남아 있어요`
- `한 조각만 다시 잡을까요?`
- `지금부터 쉬거나, 다음으로 이어갈 수 있어요`
### 금지 톤
- `집중을 놓쳤네요`
- `왜 자리를 비우셨나요`
- `세션이 중단되었습니다`
- `복귀하세요`
---
## 12. 구현 우선순위
### Slice A. Spec 정리
- 상태 모델 확정
- detection 전략 확정
- Return UX 문구 확정
### Slice B. Detection 도입
- `visibilitychange`
- `pagehide`
- sleep/wake delta
### Slice C. Return Tray 구현
- focus still running case
- focus ended while away case
### Slice D. Pause / Break 분리 강화
- copy
- visual tone
- action hierarchy
---
## 13. 측정 지표
- hidden -> return 이후 resume 비율
- away detected 후 abandon 비율
- focus ended while away 후 다음 행동 선택률
- return tray에서 primary 선택 비율
- return 후 2분 이상 유지 비율
---
## 14. 이번 기획이 기존 계획과 어떻게 연결되는가
이 문서는 `중간에 끼어든 기획`이 맞지만, 방향을 흐리는 끼어듦이 아니다.
오히려 `Refocus System`을 완성하기 위해 필요한 핵심 보강이다.
따라서 순서는 이렇게 재정렬한다.
1. `Refocus System` 구현
2. `Away / Return Recovery` 구현
3. 그 다음에 originally planned visual polish
4. 그 다음에 Break 품질과 Review 확장
즉, 원래 예정했던 다음 기획은 사라지지 않는다.
**Away / Return이 먼저 들어오고, visual polish와 break refinement가 그 뒤로 밀리는 것**이다.
---
## 15. 절대 피해야 할 방향
- 감시처럼 느껴지는 detection
- 무입력 시간을 벌점처럼 해석하는 것
- hidden -> 자동 pause 강제
- 돌아왔을 때 죄책감 유발 카피
- focus ended while away인데 그냥 break로 보내는 것
---
## 16. 다음 구현에서 꼭 지켜야 할 것
- detection은 조심스럽게, return UX는 분명하게
- pause와 return을 섞지 말 것
- break는 reward / reset tone으로 유지할 것
- away는 “실패”가 아니라 “복귀가 필요한 순간”으로 다룰 것

View File

@@ -0,0 +1,273 @@
# 13. `/space` Intent Card Collapsed / Expanded Spec
Last Updated: 2026-03-15
이 문서는 `/space` 좌상단 목표 카드의 **collapsed / expanded 구조**를 정의한다.
목적은 단순하다.
- goal은 항상 보여야 한다
- 하지만 배경을 계속 크게 가리면 안 된다
- 평소에는 조용한 `anchor`처럼 남고, 필요할 때만 `card`처럼 확장돼야 한다
관련 문서:
- `./10_refocus_system_spec.md`
- `./11_away_return_recovery_spec.md`
- `../../product/12_core_loop_execution_roadmap.md`
- `../../current_context.md`
---
## 1. 왜 바꾸는가
현재 구조의 문제는 이것이다.
- goal, microStep, 액션이 항상 한 카드 안에 모두 보인다
- 읽힘은 확보하지만, 배경의 존재감을 과하게 가져간다
- `/space`의 주인공이 scene이어야 하는데, 좌상단 카드가 먼저 읽힌다
즉 문제는 glass material 자체보다 **항상 큰 상태로 떠 있는 면적**이다.
premium ambient UI에서는:
- 정보는 항상 남아야 하지만
- 존재감은 항상 같을 필요가 없다
그래서 목표 카드는 `persistent presence`는 유지하고, `persistent emphasis`는 버려야 한다.
---
## 2. 한 줄 정의
> `/space`의 목표 카드는 평소에는 얇은 glass rail로 남고, 사용자가 실제로 결정을 내려야 할 때만 확장된다.
---
## 3. 상태 정의
Intent Card는 아래 2개 상태만 가진다.
### 3.1 Collapsed
기본 상태.
보이는 것:
- goal 1줄
보이지 않는 것:
- microStep 상세
- 완료 액션
- recovery footer
역할:
- 지금 어떤 일 위에 있는지 잃지 않게 하는 기준점
감정:
- panel이 아니라 anchor
### 3.2 Expanded
필요할 때만 열리는 상태.
보이는 것:
- goal
- microStep 또는 비어 있을 때의 조용한 helper line
- `이번 목표 완료`
- microStep 완료 체크
역할:
- 지금 이 세션을 어떻게 계속할지 결정하게 하는 짧은 제어 면
감정:
- 툴바가 아니라, 잠깐 열리는 soft control surface
---
## 4. 상태 전환 규칙
### Expanded로 전환되는 경우
- desktop에서 hover
- focus 진입
- rail 전체 클릭/tap
### Collapsed로 돌아가는 경우
- pointer leave
- focus out
- expand affordance 재클릭
- expanded 상태에서 card 바깥 pointer down
- recovery tray가 열릴 때
중요:
- `pause / return / next-beat / complete / refocus` tray가 열려 있는 동안에는 목표 카드는 강제로 collapsed 상태를 유지한다
- tray가 이미 의사결정 레이어이기 때문에, base card까지 expanded 상태면 배경을 이중으로 가리게 된다
### dismissal rule
- expanded goal card는 `outside click / outside tap`으로 접혀도 된다
- 이 동작은 base card의 ephemeral expansion에만 적용한다
- `refocus / next-beat / return / complete`처럼 의사결정을 요구하는 tray는 outside click으로 닫히면 안 된다
- decision tray는 반드시 명시적 액션으로만 닫는다
- `취소`
- `적용`
- `여기서 마무리하기`
- `잠시 비우기`
- `다음 블록 이어가기`
- 즉, `/space`에서 가볍게 접히는 것은 `expanded rail`뿐이고, 실질적인 state change layer는 dismissible popover로 취급하지 않는다
---
## 5. 시각 구조
### Collapsed rail
- 폭: 약 `18rem ~ 19rem`
- 높이: 약 `48px ~ 52px`
- radius: `18px` 전후
- glass:
- 더 얇고 더 투명
- large panel처럼 보이면 안 된다
- goal:
- 1줄 truncate
- medium weight
- affordance:
- 별도 chevron / dropdown button은 두지 않는다
- rail 자체가 expand trigger로 동작한다
- desktop에서는 hover로, mobile에서는 tap으로 자연스럽게 열린다
### Expanded card
- 폭: 약 `21rem ~ 23rem`
- 높이: 내용에 따라 자연스럽게
- radius: `22px ~ 24px`
- glass:
- collapsed보다 한 단계 더 선명한 재질
- 하지만 tray만큼 무겁지는 않다
- 내부 구조:
1. goal row
2. microStep row
3. quiet footer action
---
## 6. 정보 구조
### Goal row
- 좌측: goal 1줄
- 우측: expanded 상태에서만 보이는 `수정` 액션
- collapsed 상태에서는 rail 전체가 expand trigger로만 동작한다
- expanded 상태에서도 goal 텍스트 자체는 edit trigger가 아니다
- refocus는 expanded 상태의 명시적 `수정` 액션으로만 진입한다
### MicroStep row
- expanded 상태에서만 노출
- 왼쪽: completion glyph
- 오른쪽: microStep text
- microStep이 없으면:
- helper 1줄만 노출
- planner-like placeholder 금지
### Footer action
- expanded 상태에서만 노출
- 우측 정렬된 quiet text action 1개
- `이번 목표 완료`
- `다시 방향` 상시 버튼은 두지 않는다
- refocus는 expanded 상태의 명시적 `수정` 액션으로만 진입한다
---
## 7. interaction 원칙
### Goal 수정
- expanded 상태의 `수정` 액션 클릭 -> refocus
- collapsed 상태의 rail 클릭은 절대 refocus를 열지 않는다
- 핵심은 `expand``edit`의 역할이 섞이지 않게 하는 것이다
### microStep 완료
- expanded 상태에서만 완료 glyph가 노출된다
- collapsed 상태에서는 실수 클릭을 막기 위해 숨긴다
### 목표 완료
- expanded 상태에서만 footer action 노출
- collapsed 상태에서는 보이지 않는다
---
## 8. motion 원칙
### Collapsed -> Expanded
- 넓어짐 + 내부 row fade-in
- card가 “튀어나오는” 느낌보다, rail이 조용히 열리는 느낌이어야 한다
- duration은 짧고 부드럽게
### Expanded -> Collapsed
- 내부 row가 먼저 약해지고
- 폭이 줄어든다
- 닫힘은 더 조용해야 한다
### tray open 시
- intent card는 먼저 collapsed
- 그 아래 tray가 열림
-`card 확장``tray 확장`은 동시에 크게 보이면 안 된다
---
## 9. 금지사항
- 상시 expanded 금지
- goal + microStep + footer action 항상 노출 금지
- Now chip 재도입 금지
- toolbar/pill/button cluster처럼 보이게 만들기 금지
- 배경보다 card가 먼저 읽히게 만들기 금지
- rail 클릭과 edit 진입을 같은 액션으로 섞기 금지
- 별도 chevron/dropdown button을 상시 노출하기 금지
---
## 10. 구현 기준
필수 변경 파일:
- `src/widgets/space-focus-hud/ui/IntentCapsule.tsx`
- `src/widgets/space-focus-hud/ui/SpaceFocusHudWidget.tsx`
가능한 보조 변경:
- `src/shared/i18n/messages/space.ts`
- `src/widgets/space-focus-hud/ui/overlayStyles.ts`
구현 포인트:
- `IntentCapsule` 내부에 local expanded state 추가
- hover / focus / toggle button 기반 전환
- `showActions === false` 또는 overlay open 상태에서는 강제 collapsed
- microStep / footer action은 expanded에서만 렌더
---
## 11. 완료 기준
- idle 상태에서 상단 goal UI가 배경을 덜 가린다
- expanded 상태에서만 microStep과 완료 액션이 보인다
- recovery tray가 열릴 때 base card는 과하게 커져 있지 않다
- bright / dark scene 모두에서 읽히지만 scene이 먼저 읽힌다
- `/space`가 productivity dashboard처럼 보이지 않는다