Skip to content

[S15P11A705-377] 핀 시스템을 도입하고 Home을 개편한다 — 최근의 장소 리치 카드·지역 방사형 팝·장소 저장 버튼 - #160

Merged
TrossYou merged 6 commits into
devfrom
feature/S15P11A705-377-pin-system-home
Aug 7, 2026
Merged

[S15P11A705-377] 핀 시스템을 도입하고 Home을 개편한다 — 최근의 장소 리치 카드·지역 방사형 팝·장소 저장 버튼#160
TrossYou merged 6 commits into
devfrom
feature/S15P11A705-377-pin-system-home

Conversation

@TrossYou

@TrossYou TrossYou commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

사용자 제공 "핀 목업 v2" 1차분입니다(기반 자산 + Home). 상세·포스트잇·로딩 등은 이 PR 머지 후 후속 티켓에서 진행합니다.

A. 핀 기반 자산 (후속 티켓이 재사용)

  • src/shared/ui/PinSymbols.tsxPinStanding·PinOutline·PinTack(참조 문서 path 원본 그대로) + 카드에 박는 PinTackMount.
  • tailwind.config.js키프레임 4종(pin-stand / pin-ripple / pin-loop / pin-pull, 목업 값 그대로) + 이번 상호작용용 pin-pop-in. 조율 세션의 사전 승인 범위대로 keyframes/animation 추가만 했고 색 토큰은 손대지 않았습니다.
  • 마커 핀은 기존 color-markers/*.svg 20색 자산 그대로입니다(새 음영·광택 없음).
  • 압정의 강철 그라디언트 id는 useId로 인스턴스마다 분리했습니다 — 같은 id를 여러 번 심으면 문서 전체가 첫 정의 하나로 수렴합니다(마커 filter id에서 이미 겪은 문제).
  • 모든 핀 애니메이션은 motion-reduce에서 생략됩니다.

B. 지도 핀 연출

상세가 열리면 나머지 핀이 saturate(.32) opacity(.5)(전환 .25s)로 흐려지고, 선택 핀만 다시 꽂히며 민트 물결이 1회 퍼집니다. 371의 카드 앞장 강조와 같은 경로를 공유합니다.

  • 마커를 <img> 하나에서 래퍼 + 이미지로 바꿨습니다 — 물결은 같은 자리에 겹치는 형제 요소가 필요한데 <img>는 자식을 가질 수 없습니다.
  • 필터는 374 톤 역보정 위에 이어 붙입니다. 덮어쓰면 그 핀만 누렇게 뜹니다.
  • 이미 끝난 애니메이션은 클래스를 다시 붙여도 재생되지 않으므로, 떼고 리플로우를 읽은 뒤 다시 붙입니다(같은 핀 연속 선택).

C. "최근의 장소" (사용자 지시)

제목 변경, 3장 겹침 스택 폐기 → 엇갈려 펼친 배치. 리치 폴라로이드 카드(4:3 사진 + 폴백 일러스트 + 장소명 + 손글씨 맥락 + 키워드 칩 + 날짜)에 압정을 박았습니다 — 바늘은 종이 뒤, 받침만 위(압정 래퍼 z-0 / 종이 z-10, 종이에 받침 그림자).

  • 리치 카드가 한 장 약 290px이라 2행입니다(3행이면 보드만 뷰포트 세로를 넘습니다 — 사용자 허용 범위).
  • 맥락 지연 호출 상한이 구조로 정해집니다: 보이는 카드에만 마운트되므로 동시 요청 최대 2건, recordId별 캐시라 목록을 한 바퀴 돌아도 총 요청이 기록 수를 넘지 않습니다.
  • 카드는 별도 보드 패널이 아니라 페이지 배경 위에 직접 꽂힙니다(정정 반영). 겹침은 판을 깔아 가리는 대신 지도를 비켜 세워 해결했습니다.

D. 지역 뷰 좌우 배치 / 지도 폭 축소·페이드

지도를 좌측에 붙이고 우측을 '최근의 장소' 자리로 비웁니다. 배경 레이어를 md부터 좁히고(md 17rem / lg 21rem / xl 23rem) 오른쪽 128px을 그라데이션으로 지웁니다.

  • 마스크는 지워도 되는 것에만 겁니다(타일·톤 워시·질감, 지역 뷰는 <svg>만). 레이어 전체에 걸었더니 그 안의 줌·"내 주변" 버튼까지 사라졌던 것을 고친 부분입니다.
  • 타일과 워시·질감이 같은 폭으로 사라집니다 — 어긋나면 경계가 두 겹으로 보입니다. 하단 로고 보호 페이드와는 mask-composite: intersect로 겹쳐 둘 다 살렸습니다.
  • fitBounds·센터링·"화면 밖 N개" 배지가 페이드 띠를 가림으로 인식합니다(rightObstructionPx). 이게 없으면 동쪽 끝 마커(제주)가 보이지 않는 띠 안으로 들어가고 지도가 좌측으로 치우칩니다.

E. 검색창·저장 버튼 (사용자 지시)

검색창 가로 축소(상한 26rem)·높이 축소, 장소추가 버튼 축소 + 라벨 "장소 저장" + 북마크 아이콘. ⚠️ 목업은 이 자리에 핀 아이콘을 제안했지만 사용자가 북마크로 지정했습니다 — 핀은 이미 "지도 위의 장소"를 뜻해서 저장까지 핀으로 두면 한 기호가 두 뜻을 갖습니다.

F. 지역 상호작용 재설계 + 클릭 무반응 버그 2건

좌하단 카드 패널을 폐기하고, 지역을 누르면 장소들이 누른 자리 주변으로 방사형 스태거(45ms)로 떠오릅니다(animata flower-menu 방식). 7개마다 바깥 고리로 넘겨 겹침을 막고, 대형이 화면을 벗어나면 항목을 자르지 않고 원점만 안쪽으로 밉니다(자르면 방사형이 찌그러집니다). ESC·바깥 클릭·같은 지역 재클릭으로 닫히며 motion-reduce에서는 애니메이션 없이 최종 상태로 나타납니다.

"색칠된 지역을 눌러도 아무 일이 없다"의 원인은 두 가지였고 둘 다 376부터 있던 버그입니다:

  1. 컨텐츠 레이어가 클릭을 삼켰다. z-10 + max-w-6xl 블록이라 눈에 보이는 것이 없는 여백까지 사각형 전체가 클릭을 받습니다. 한반도에서 서울이 그려지는 자리가 정확히 그 아래였습니다. → 레이어에 pointer-events-none, 실제 위젯에만 auto. 부수 효과로 그 영역에서 막혀 있던 카카오 지도 드래그도 함께 풀렸습니다.
  2. 클릭 대상이 너무 작았다. 전국 축척에서 실측하면 서울 중구 약 5.7×3.1px, 종로구 6.7×7.1px입니다. → 지역 중심에 반지름 11의 보이지 않는 클릭 원을 놓고 도형은 pointer-events:none으로 내렸습니다.

제주 인셋

제주를 우하단 인셋 박스로 분리했습니다(사용자 허용, 한국 지도의 관례). 제주까지 한 화면에 담으면 위도 5.42도인데 빼면 4.31도로 20% 줄어, 같은 높이에서 본토를 약 1.26배 크게 그릴 수 있습니다(폭 566 → 711 단위). 히어로에 가려 세로가 늘 부족한 화면이라 이득이 크고, 시군구가 커지면 클릭도 쉬워집니다. 인셋 안에서도 색칠·클릭 원 반지름이 본토와 같아 조작감이 다르지 않습니다.

보완 커밋

  1. 핀 기반 자산 도입 + Home 개편 (A~F)
  2. 최근의 장소를 보드가 아닌 배경에 꽂고 지도를 비켜 세운다 — 베이지 보드 패널 제거(정정)
  3. 지역 뷰 페이지 스크롤을 없애고 지도 폭을 카드와 분리한다 — 카드를 흐름에서 빼고 md부터 축소 + 제주 인셋
  4. 지도 우측 경계를 그라데이션으로 되돌린다 — 컨트롤은 남긴다
  5. 최근의 장소를 뷰포트 안으로 올리고 fitBounds에 페이드 가림을 반영한다
  6. 지역 방사형 팝의 조정 손잡이를 한곳에 모은다 — 동작 변화 없음(기본값이 현재 화면과 동일). 거리·간격·스태거·원점 당김·칩 크기를 한 줄로 조정할 수 있게 정리

검사

npm run build(tsc -b 포함) · npm test 439개 통과(377 신설 30) · npm run lint 0건. 빌드 산출 CSS에서 animate-pin-*·@keyframes·반응형 폭 클래스가 실제로 출력되는지 확인했습니다(Tailwind는 원시 텍스트 스캔이라 조용히 빠질 수 있습니다).

지역 클릭 동작은 컴포넌트 테스트로 고정했습니다 — jsdom에 렌더해 실제 클릭 이벤트를 보내 장소 이름이 뜨는지, 도형이 pointer-events:none인지, 클릭 원 지름이 자치구 크기보다 큰지, 제주 인셋 안에서도 같은지를 검증합니다.

확인 방법

로그인이 OAuth 뒤라 에이전트가 화면 확인을 할 수 없어 절차를 남깁니다.

  1. 검색창이 좁아지고 옆 버튼이 "장소 저장" + 북마크 아이콘(핀 아님)인지.
  2. 우측 '최근의 장소'가 보드 없이 배경 위에 있고, 카드 2장이 좌우로 어긋나며 압정이 박혀 있는지. 압정 바늘이 종이 앞으로 나오면 안 됩니다. 사진·장소명·손글씨 맥락·키워드·날짜가 모두 있는지. 화살표로 넘기면 한 칸씩 밀리는지.
  3. 페이지 스크롤이 없는지(지도 뷰·지역 뷰 모두). 카드와 넘김 버튼까지 스크롤 없이 보여야 합니다.
  4. 지도 오른쪽 끝이 카드 앞에서 부드럽게 페이드되고, 줌·"내 주변" 버튼은 선명하게 보이는지.
  5. 검색창과 카드 사이 빈 곳에서 지도를 드래그 — 예전에는 꿈쩍도 하지 않았습니다(클릭 삼킴 수정 확인).
  6. 최초 진입에서 제주 포함 모든 마커가 페이드 띠 밖에 있고 지도가 좌측으로 치우치지 않는지.
  7. 마커 클릭 → 상세가 열리며 나머지 핀이 흐려지고 선택 핀만 다시 꽂히며 물결이 퍼지는지. 닫으면 원상복구되는지.
  8. 지역 탭 → 색칠된 서울 칸 클릭 → 장소 이름 칩이 또로록 떠오르는지. 칩 클릭 → 상세, ESC·바깥 클릭 → 닫힘. 제주 인셋 안의 칸도 동일하게 동작하는지.
    • ⚠️ 존재감 확인 포인트: 옛 지역 뷰에서 "좌하단 카드가 안 보인다 / 화면 가운데에 눈에 띄게"라는 피드백이 있었습니다. 이 팝이 그 대체이므로, 화면 가장자리에 있는 지역(예: 강원 동해안, 전남 서남부)을 눌렀을 때도 칩이 충분히 눈에 띄는지 함께 봐 주세요.
    • 약하다면 조정은 한 줄입니다 — radialBurst.tsBURST_ORIGIN_CENTER_PULL_RATIO(기본 0, 0.3~0.5면 가운데로 당김) / BASE_RADIUS_PX(퍼지는 거리) / STAGGER_MS(뜨는 속도), 칩 크기·글자는 RegionMapViewREGION_BURST_CHIP_CLASS 한 줄. 어느 쪽이 좋은지 알려 주시면 반영하겠습니다.
  9. OS "동작 줄이기"를 켜고 7~8을 다시 — 애니메이션 없이 최종 상태로 바로 나타나야 합니다.
  10. 회귀: 검색 결과 갤러리, 지도↔지역 토글, 374 톤(따뜻한 지도·마커 색 정상), 376 색칠·범례·"지역 밖 기록" 배지.

🤖 Generated with Claude Code

TrossYou and others added 6 commits August 7, 2026 14:08
L3 스택 5단: 368(지도 풀블리드) → 371(최근 카드) → 374(톤 마스크) → 376(지역 뷰) → 377(이 커밋).

A. 핀 자산 — shared/ui/PinSymbols.tsx에 pin-standing·pin-outline·pin-tack(참조 문서
   path 그대로) + tailwind.config에 키프레임 4종(pin-stand/ripple/loop/pull)과 이번
   상호작용용 pin-pop-in. 색 토큰은 손대지 않았다. 압정 그라디언트 id는 useId로 인스턴스마다
   분리했다 — 같은 id를 여러 번 심으면 문서 전체가 첫 정의 하나로 수렴한다
B. 지도 — 상세가 열리면 나머지 핀은 saturate(.32) opacity(.5)로 흐려지고 선택 핀만 다시
   꽂히며 물결이 퍼진다. 마커를 <img> 하나에서 래퍼+이미지로 바꿨다(물결은 형제 요소가
   필요한데 <img>는 자식을 가질 수 없다). 필터는 톤 역보정 위에 이어 붙인다
C. 최근의 장소 — 제목 변경, 3장 겹침 폐기 → 엇갈려 펼친 배치. 리치 폴라로이드 카드에
   압정(바늘은 종이 뒤, 받침만 위)과 보드 배경면을 더했다. 리치 카드가 커서 2행이다
   (사용자 허용). 맥락 지연 호출은 보이는 카드 수(2)가 상한이고 recordId로 캐시된다
D. 지역 뷰 — 지도를 좌측에 붙이고 우측을 '최근의 장소' 보드 자리로 비웠다
E. 검색창 가로 축소, 장소 저장 버튼 축소 + 북마크 아이콘(핀 아님 — 사용자 지정)
F. 지역 상호작용 재설계 — 지역을 누르면 장소들이 누른 자리 주변으로 방사형 스태거로 뜬다
   (좌하단 카드 패널 폐기). reduced-motion에서는 애니메이션 없이 최종 상태로 나타난다

무반응 버그의 근본 원인 두 가지(376부터 있던 것):
① HomePage 컨텐츠 레이어(z-10)가 max-w-6xl 전폭·전고 블록이라 투명한 여백까지 클릭을
   삼켰다. 서울이 그려지는 자리가 정확히 그 아래였다 → 레이어에 pointer-events-none을 주고
   실제 위젯에만 auto를 되돌렸다. 지도 드래그도 같은 이유로 막혀 있었다
② 클릭 대상이 시군구 도형 자체였는데 전국 축척에서 서울 중구는 약 6x3px이라 누를 수 없었다
   → 지역 중심에 반지름 11의 보이지 않는 클릭 원을 따로 놓고 도형은 pointer-events:none으로
   내렸다. 이 동작은 컴포넌트 테스트로 고정했다(클릭 → 장소 이름 등장)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
사용자 정정 — 앞서 반영한 베이지 보드 패널은 의도가 아니었다. 카드는 별도 배경면이 아니라
**페이지 배경(paper-white) 위에** 압정으로 직접 꽂혀 있어야 한다.

- 보드 패널과 재질 상수(lib/recentBoard.ts)를 제거했다
- 대신 배경 레이어(지도·지역 뷰)를 lg 이상에서 22rem만큼 좁히고 오른쪽 6rem을 마스크로
  페이드했다. "맵과 레코드가 겹쳐 보여 정신없다"는 피드백의 해법을 판을 깔아 가리는 쪽이
  아니라 지도를 비켜 세우는 쪽으로 잡았다 — 판을 깔면 배경이 하나 더 생겨 층만 늘어난다
- 잘린 단면을 그대로 두면 "지도가 잘렸다"로 읽혀서, 마지막 6rem을 알파로 떨어뜨려 배경으로
  스며들게 했다(히어로 오버레이와 같은 mask 기법)
- 368의 음수 오른쪽 마진은 lg 이상에서 되돌린다 — 그 마진은 지도를 padding box까지 넓히려던
  것이라 폭을 줄이는 이 변경과 반대로 작동한다
- 히어로 블러 오버레이도 같은 폭으로 맞춰 지도 없는 배경 위가 흐려지지 않게 했다
- 지역 뷰의 pr 예약은 제거했다(배경 레이어가 이미 좁아져 자리를 두 번 빼게 된다)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
화면 피드백 두 건. 원인이 서로 달라 각각 다르게 고쳤다.

① 지역 뷰 페이지 스크롤 — 지도가 아니라 **컨텐츠 열**이 원인이었다. 리치 카드 2장이 컨텐츠
   열 높이를 뷰포트 예산(PAGE_MIN_HEIGHT_CLASS) 밖으로 밀어냈고, <main>이 늘어나자 그 안에
   inset-0으로 붙어 있던 배경 레이어가 함께 늘어났으며, 지역 지도는 h-full이라 같이 커져
   제주가 화면 밖으로 나갔다. 스크롤은 결과였다.
   → '최근의 장소'를 흐름에서 빼 <main> 기준 우측 띠에 붙였다(md 이상). 페이지 높이가
     토글+검색만으로 정해져 359의 "본문만 스크롤" 계약이 회복된다. 기준을 컨텐츠 열이 아니라
     <main>으로 잡은 이유는 컨텐츠 열이 max-w-6xl 가운데 정렬이라 넓은 화면에서 오른쪽 끝이
     뷰포트와 어긋나기 때문이다. 지도에는 뷰포트 기준 max-height 안전판도 뒀다.

② 지도와 카드 겹침 — 앞선 축소가 먹지 않은 이유가 두 가지였다.
   - 조건이 lg(≥1024px)뿐이라 그보다 좁은 창에서는 전폭 그대로였다 → md부터 걸고 폭에 따라
     예약 폭을 키운다(md 17rem / lg 21rem / xl 23rem, 카드 폭과 짝)
   - 오른쪽 6rem 페이드 마스크가 **그 안에 있던 줌·"내 주변" 버튼까지 지웠다**(버튼은 right-8
     자리다) → 마스크를 걷고 잘린 단면은 라운드+그림자로 마감했다. 컨트롤은 좁아진 상자를
     기준으로 배치되므로 자동으로 카드 왼쪽에 남는다. fitBounds 여유·화면 밖 배지는 컨테이너
     실측값을 쓰므로 새 폭에 자동으로 맞는다.

제주 인셋 채택 — 제주까지 한 화면에 담으면 위도 5.42도인데 빼면 4.31도로 20% 줄어, 같은
높이에서 본토를 약 1.26배 크게 그릴 수 있다(폭 566 → 711 단위). 히어로에 가려 세로가 늘
부족한 화면이라 이득이 크고, 시군구가 커지면 클릭도 쉬워진다. 인셋 안에서도 색칠·클릭 원
반지름이 본토와 같아 조작감이 다르지 않다(테스트로 고정).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
피드백 — 축소된 지도의 우측이 직선으로 딱 잘려 보인다. 배경으로 스며들어야 한다.

앞서 이 페이드를 걷어냈던 이유는 배경 레이어 **전체**에 마스크를 걸었더니 그 안의 줌·"내 주변"
버튼(오른쪽에서 32px 자리)까지 함께 사라졌기 때문이다. 그래서 이번에는 **지워도 되는 것에만**
건다 — 지도 타일과 톤 워시·질감, 지역 뷰는 <svg>에만. 컨트롤·범례·칩은 마스크 밖에 남는다.

- 페이드 폭 128px(8rem). 요청 하한 6rem보다 넉넉히 잡아 단면이 드러나지 않게 했다
- **타일과 워시·질감이 같은 폭으로 사라진다.** 폭이 어긋나면 한쪽이 먼저 끝나 경계가 두 겹으로
  보인다(374 워시와의 정합 확인 요청). 하단 로고 보호 페이드와는 mask-composite: intersect로
  겹쳐 둘 다 살렸다 — 하나만 쓰면 다른 쪽이 사라진다
- 폭은 mapToneMask.ts의 MAP_TONE_RIGHT_FADE_PX 한 곳에서 나온다. 지도 뷰와 지역 뷰가 같은 값을
  받아 두 탭의 오른쪽 경계가 같아 보인다
- 앞 커밋에서 하드 엣지를 감추려 넣었던 라운드·그림자는 제거했다(페이드가 대신한다)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
화면 피드백 2건.

① '최근의 장소'가 너무 아래에 있어 페이지 스크롤이 생겼다 — 절대 배치라도 스크롤 영역의
   overflow에는 그대로 잡힌다. top을 19~21rem에서 6.5~7rem으로 올리고 폭을 md·lg 모두
   15rem으로 통일했다. lg에서 19rem이면 4:3 사진이 커져 카드 한 장이 340px이 되고 두 장이면
   다시 예산을 넘는다. 히어로는 왼쪽 컬럼이라 카드가 위로 와도 검색창과 부딪히지 않는다.

② 지도 뷰에서 제주가 우측 페이드에 가려지고 지도가 좌측으로 치우쳤다 — 오른쪽 128px이
   그라데이션으로 지워지는데 fitBounds는 컨테이너 **전체**에 마커를 담고 있었다. 보이지 않는
   띠 안에 들어간 마커는 사라진 것처럼 보인다.
   → MapViewInsets에 rightObstructionPx·containerWidthPx를 더해 상단 오버레이와 **같은 취급**을
     한다. 세 곳이 함께 보정된다: fitBounds 여유(오른쪽에 페이드 폭을 더함), 센터링(중심을
     서쪽으로 옮겨 목표 지점을 보이는 영역 한가운데로), "화면 밖 N개" 배지가 세는 가시 영역
     (동쪽 경계를 그만큼 안으로).
   컨테이너 폭을 모를 때는 보정하지 않는다 — 0으로 나눠 NaN을 만들지 않기 위해서다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
동작은 그대로다(기본값이 현재 화면과 같다). 머지 후 "존재감이 약하다"는 피드백이 오면 한 줄로
조정할 수 있도록 손잡이만 정리했다.

- 퍼지는 거리·간격·스태거(BASE_RADIUS_PX / RING_GAP_PX / STAGGER_MS / ITEMS_PER_RING /
  START_ANGLE_DEG)를 export하고 "취향 조정 지점" 주석 블록으로 묶었다
- 칩 크기·글자는 인라인 클래스라 어디를 고쳐야 할지 드러나지 않았다 → REGION_BURST_CHIP_CLASS
  한 줄로 모았다. Tailwind가 원시 텍스트를 스캔하므로 조각을 조립하지 않고 완성된 리터럴로 둔다
- 원점을 가운데로 당기는 손잡이(BURST_ORIGIN_CENTER_PULL_RATIO)를 신설했다. 기본 0이라 지금은
  누른 자리 그대로다 — 누른 자리에서 퍼져야 "이 지역의 것"이라는 연결이 유지되기 때문이다.
  지역이 화면 가장자리에 있어 존재감이 약하면 0.3~0.5로 올린다
- 당김은 화면 밖 보정(clampBurstOrigin) **앞에** 적용한다. 순서가 바뀌면 당기다 다시 밖으로 나간다

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@TrossYou
TrossYou merged commit 4678f86 into dev Aug 7, 2026
2 checks passed
@TrossYou
TrossYou deleted the feature/S15P11A705-377-pin-system-home branch August 7, 2026 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant