diff --git a/docs/90_current_state.md b/docs/90_current_state.md index f5fa242..719a567 100644 --- a/docs/90_current_state.md +++ b/docs/90_current_state.md @@ -43,6 +43,10 @@ Last Updated: 2026-03-14 - 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와 구분되게 조정 - Focus Entry Surface / Execution Surface 재정의: - `/app`을 planning home이 아니라 hero-first focus entry surface로 재구성 diff --git a/docs/session_brief.md b/docs/session_brief.md index 8804aed..3aff7fc 100644 --- a/docs/session_brief.md +++ b/docs/session_brief.md @@ -48,6 +48,10 @@ Last Updated: 2026-03-14 - tray 폭과 max-height를 늘려 한국어 제목/설명 잘림을 줄였다. - title/body line-height와 spacing을 다시 잡아 임시 패널 느낌을 줄였다. - option row의 radius, padding, chevron 정렬을 보정해 더 차분한 recovery panel처럼 읽히게 했다. +- `Pause / Break / Return`의 감정 톤 분리를 시작했다. + - `Return(break)`은 focus 복귀 tray와 같은 재질을 쓰지 않고, 더 부드러운 emerald tint release tone으로 분리했다. + - `Goal Complete`의 `잠깐 쉬기` 선택도 같은 release tone으로 연결했다. + - timer HUD도 break phase에서는 더 가벼운 emerald 계열 material로 바뀌어 pause/focus와 다르게 읽히도록 정리 중이다. - `/app`을 single-goal commitment gate로 다시 줄였다. - 2-step ritual setup을 제거했다. - current session이 있으면 `Resume` UI만 보여주고, `/space`로 이어가기만 제안한다. diff --git a/src/widgets/space-focus-hud/ui/GoalCompleteSheet.tsx b/src/widgets/space-focus-hud/ui/GoalCompleteSheet.tsx index f5150de..feee62d 100644 --- a/src/widgets/space-focus-hud/ui/GoalCompleteSheet.tsx +++ b/src/widgets/space-focus-hud/ui/GoalCompleteSheet.tsx @@ -8,6 +8,7 @@ import { HUD_FIELD, HUD_OPTION_CHEVRON, HUD_OPTION_ROW, + HUD_OPTION_ROW_BREAK, HUD_OPTION_ROW_PRIMARY, HUD_TEXT_LINK, HUD_TEXT_LINK_STRONG, @@ -190,17 +191,17 @@ export const GoalCompleteSheet = ({ type="button" onClick={onRest} disabled={isSubmitting} - className={HUD_OPTION_ROW} + className={cn(HUD_OPTION_ROW, HUD_OPTION_ROW_BREAK)} >

{copy.space.goalComplete.restButton}

-

+

{copy.space.goalComplete.restDescription}

- + ) : ( @@ -121,15 +130,15 @@ export const ReturnPrompt = ({ disabled={isBusy} className={cn(HUD_OPTION_ROW, HUD_OPTION_ROW_PRIMARY)} > -
-

+

+

{copy.space.focusHud.returnPromptContinue}

-

+

{copy.space.focusHud.returnPromptContinueHint}

- + )} diff --git a/src/widgets/space-focus-hud/ui/overlayStyles.ts b/src/widgets/space-focus-hud/ui/overlayStyles.ts index 964c3e0..7760adf 100644 --- a/src/widgets/space-focus-hud/ui/overlayStyles.ts +++ b/src/widgets/space-focus-hud/ui/overlayStyles.ts @@ -1,11 +1,19 @@ export const HUD_TRAY_SHELL = 'pointer-events-auto relative mt-3 w-full overflow-hidden rounded-[22px] border border-white/10 bg-[#101318]/30 text-white shadow-[0_12px_28px_rgba(2,6,23,0.14)] backdrop-blur-[8px] backdrop-saturate-125'; +export const HUD_TRAY_SHELL_BREAK = + 'pointer-events-auto relative mt-3 w-full overflow-hidden rounded-[22px] border border-emerald-200/14 bg-[rgba(10,20,18,0.34)] text-white shadow-[0_12px_28px_rgba(2,6,23,0.12)] backdrop-blur-[8px] backdrop-saturate-125'; + export const HUD_TRAY_LAYER = 'pointer-events-none absolute inset-0 rounded-[22px] bg-[linear-gradient(180deg,rgba(255,255,255,0.08)_0%,rgba(255,255,255,0.025)_24%,rgba(255,255,255,0.01)_100%)]'; +export const HUD_TRAY_LAYER_BREAK = + 'pointer-events-none absolute inset-0 rounded-[22px] bg-[linear-gradient(180deg,rgba(110,231,183,0.10)_0%,rgba(255,255,255,0.025)_22%,rgba(255,255,255,0.01)_100%)]'; + export const HUD_TRAY_HAIRLINE = 'pointer-events-none absolute inset-x-0 top-0 h-px bg-white/16'; +export const HUD_TRAY_HAIRLINE_BREAK = 'pointer-events-none absolute inset-x-0 top-0 h-px bg-emerald-200/18'; + export const HUD_FIELD = 'h-11 w-full rounded-[18px] border border-white/10 bg-black/14 px-3.5 text-[0.98rem] tracking-tight text-white placeholder:text-white/30 focus:border-white/20 focus:bg-black/20 focus:outline-none focus:ring-2 focus:ring-white/8'; @@ -15,6 +23,9 @@ export const HUD_OPTION_ROW = export const HUD_OPTION_ROW_PRIMARY = 'border-white/12 bg-black/14 hover:border-white/18 hover:bg-black/18'; +export const HUD_OPTION_ROW_BREAK = + 'border-emerald-200/12 bg-[rgba(16,38,31,0.28)] hover:border-emerald-200/18 hover:bg-[rgba(16,38,31,0.38)]'; + export const HUD_OPTION_CHEVRON = 'mt-0.5 shrink-0 text-[13px] text-white/28 transition-colors duration-200 group-hover:text-white/52'; @@ -27,6 +38,12 @@ export const HUD_PAUSE_TITLE = export const HUD_PAUSE_BODY = 'mt-2 max-w-[23rem] text-[13px] leading-[1.6] text-white/58 md:text-[13.5px]'; +export const HUD_RETURN_TITLE = + 'mt-2 max-w-[24rem] text-[1.08rem] font-medium leading-[1.36] tracking-[-0.02em] text-white/95 md:text-[1.14rem]'; + +export const HUD_RETURN_BODY = + 'mt-2 max-w-[23rem] text-[13px] leading-[1.58] text-white/58'; + export const HUD_TEXT_LINK = 'text-[12px] font-medium tracking-[0.08em] text-white/62 underline decoration-white/16 underline-offset-4 transition-all duration-200 hover:text-white/84 hover:decoration-white/28 disabled:cursor-default disabled:text-white/26 disabled:no-underline'; diff --git a/src/widgets/space-timer-hud/ui/SpaceTimerHudWidget.tsx b/src/widgets/space-timer-hud/ui/SpaceTimerHudWidget.tsx index b347a49..d9874d7 100644 --- a/src/widgets/space-timer-hud/ui/SpaceTimerHudWidget.tsx +++ b/src/widgets/space-timer-hud/ui/SpaceTimerHudWidget.tsx @@ -42,6 +42,7 @@ export const SpaceTimerHudWidget = ({ onResetClick, }: SpaceTimerHudWidgetProps) => { const { isBreatheMode, triggerRestart } = useRestart30s(); + const isBreakPhase = hasActiveSession && sessionPhase === 'break'; const modeLabel = isBreatheMode ? RECOVERY_30S_MODE_LABEL : !hasActiveSession @@ -63,15 +64,19 @@ export const SpaceTimerHudWidget = ({ className={cn( 'relative z-10 flex h-[3.5rem] items-center justify-between gap-6 overflow-hidden rounded-full px-5 transition-colors', isImmersionMode - ? 'border border-white/10 bg-black/20 backdrop-blur-2xl shadow-[0_8px_32px_rgba(0,0,0,0.12)]' - : 'border border-white/15 bg-black/30 backdrop-blur-2xl shadow-[0_8px_32px_rgba(0,0,0,0.16)]', + ? isBreakPhase + ? 'border border-emerald-200/14 bg-[rgba(10,20,18,0.26)] backdrop-blur-2xl shadow-[0_8px_32px_rgba(0,0,0,0.10)]' + : 'border border-white/10 bg-black/20 backdrop-blur-2xl shadow-[0_8px_32px_rgba(0,0,0,0.12)]' + : isBreakPhase + ? 'border border-emerald-200/16 bg-[rgba(10,20,18,0.32)] backdrop-blur-2xl shadow-[0_8px_32px_rgba(0,0,0,0.14)]' + : 'border border-white/15 bg-black/30 backdrop-blur-2xl shadow-[0_8px_32px_rgba(0,0,0,0.16)]', )} >
{modeLabel} @@ -114,13 +119,21 @@ export const SpaceTimerHudWidget = ({ className={cn( 'inline-flex h-8 w-8 items-center justify-center rounded-full text-sm transition-all duration-150 ease-out focus-visible:outline-none focus-visible:ring-2 active:scale-95 disabled:cursor-not-allowed disabled:opacity-30', isImmersionMode - ? 'text-white/70 hover:bg-white/10 hover:text-white' - : 'text-white/80 hover:bg-white/15 hover:text-white', + ? isBreakPhase + ? 'text-white/74 hover:bg-emerald-100/10 hover:text-white' + : 'text-white/70 hover:bg-white/10 hover:text-white' + : isBreakPhase + ? 'text-white/82 hover:bg-emerald-100/12 hover:text-white' + : 'text-white/80 hover:bg-white/15 hover:text-white', isStartAction && isHighlighted - ? 'bg-white/10 text-white shadow-sm' + ? isBreakPhase + ? 'bg-emerald-100/10 text-white shadow-sm' + : 'bg-white/10 text-white shadow-sm' : '', isPauseAction && isHighlighted - ? 'bg-white/10 text-white shadow-sm' + ? isBreakPhase + ? 'bg-emerald-100/10 text-white shadow-sm' + : 'bg-white/10 text-white shadow-sm' : '', )} >