PC로 시작한 지도 앱, 모바일이 주가 되기까지
PC 먼저 개발의 대가
Pet-Pass는 지도 기반 서비스다. 반려동물 동반 가능한 장소를 지도 위에 핀으로 찍고, 필터로 걸러서 찾아가는 앱. 처음 만들 때 나는 당연하다는 듯이 PC 웹 브라우저를 기준으로 레이아웃을 잡았다. 넓은 화면에서 지도가 크게 펼쳐지고, 왼쪽 사이드바에 필터 패널이 붙어 있는 구조. 보기엔 그럴듯했다.
문제는 실제 서비스를 쓸 사람들이 어디서 쓰느냐를 생각하지 않았다는 거다. 반려동물 동반 장소를 검색하는 사람은 외출 중에, 산책하다가, 카페 앞에서 스마트폰으로 찾는다. PC 앞에 앉아서 검색하는 사람은 거의 없다.
모바일로 처음 열었을 때 화면이 깨졌다. 사이드바는 화면 절반을 잡아먹고, 지도는 좁아터진 오른쪽에 쪼그라들어 있었다. 핀을 탭하면 팝업이 화면 밖으로 튀어나갔다. 필터 버튼들은 한 줄에 다 들어오지 않아서 가로 스크롤이 생겼다.
구조를 뒤집어야 했다. 지도를 전체 화면으로 펼치고, 필터와 상세 정보는 아래에서 올라오는 바텀시트 형태로 바꿨다. AI에게 레이아웃 재설계를 지시할 때 "모바일 퍼스트로 작성하고, PC는 미디어 쿼리로 확장"이라는 가이드라인을 명시적으로 넣기 시작했다. 이 한 줄을 처음부터 넣었더라면 리팩토링 시간이 없었을 것이다.
교훈: 지도 기반 서비스는 처음부터 모바일 퍼스트여야 한다. PC 레이아웃을 모바일로 축소하는 것보다, 모바일 레이아웃을 PC로 확장하는 게 훨씬 쉽다.
AI와 작업할 때 "모바일 퍼스트" 같은 설계 원칙은 매 지시마다 명시해야 한다. 한 번 말한 것을 기억하지 못한다.
검은 화면에서 베이지로
개발 초기 Pet-Pass의 화면은 검은색이었다. 정확히는 어두운 회색과 남색이 섞인 다크 테마. 딱히 의도한 게 아니라 AI가 생성한 초기 CSS가 그랬고, 나도 특별한 의견이 없어서 그냥 두었다. 지도 앱이니까 어두운 톤도 나쁘지 않다고 생각했다.
한참 개발하다가 Claude에게 UI 리뷰를 부탁했다. 질문은 간단했다: "지금 디자인이 서비스 컨셉에 맞나?"
돌아온 피드백이 날카로웠다. 반려동물 동반 장소를 찾는 서비스는 따뜻하고, 친근하고, 산책하는 기분이어야 하는데, 지금 화면은 사이버펑크 게임 같다고. 강아지랑 카페 가려고 앱 켰더니 헬스케어 앱 같은 분위기가 나온다면 뭔가 어긋난다고.
그 말이 맞았다. 서비스의 페르소나를 생각했다 — 강아지 목줄 잡고 동네 산책하는 사람, 반려묘와 동반 입장 가능한 카페를 찾는 사람. 이들이 편하게 느낄 색은 검은색이 아니었다.
베이지로 방향을 틀었다. 흙길 느낌, 가을 햇살, 따뜻한 나무. #c8b89a를 프라이머리로 잡고, 배경은 크림색 계열로 채웠다. 폰트는 Pretendard — 한국어에서 가장 자연스럽게 읽히는 선택이었다.
Pet-Pass Theme System
베이지가 기본이 되고 나서, 화이트와 다크는 자연스럽게 따라왔다. 사람마다 선호하는 화면 밝기가 다르고, 밤에 쓰는 사람도 있으니까. 테마 시스템을 localStorage로 연결해서 새로고침해도 유지되게 했고, 모든 페이지에서 공유되게 theme.js 하나로 통합했다.
결과적으로 이 색 전환이 서비스의 정체성을 만들었다. Pet-Pass는 따뜻한 베이지가 기본인 서비스가 됐다. AI가 UI 컨셉을 제안하고, 사람이 "맞다, 그게 맞다"고 결정하는 — 바이브 코딩에서 협업이 가장 잘 작동한 순간 중 하나였다.
필터명 전쟁
지도에 표시되는 장소 데이터는 공공데이터포털에서 온다. 업종 분류가 정부 기준으로 되어 있어서 실제 서비스에서 보여주기엔 이름이 낯설다. 대표적인 게 휴게음식점이다.
카페를 찾으려는 사람이 "휴게음식점"이라는 필터를 보면 뭔지 알까? 법적 정의로는 주류를 팔지 않는 음식점이 휴게음식점이고, 카페 대부분이 여기 속한다. 하지만 사용자 입장에서 "카페 찾기" 버튼이 "휴게음식점 필터"일 거라고 생각하는 사람은 없다.
해결책은 간단했다: 데이터를 화면에 표시할 때 변환 테이블을 적용한다. 휴게음식점 → 카페·음료, 일반음식점 → 식당·레스토랑, 문화시설 → 문화·공원.
문제는 이 변환 규칙이 자꾸 사라진다는 것이었다. 데이터를 새로 내려받거나, AI가 관련 코드를 수정하거나, 다른 기능을 추가할 때마다 변환 로직이 덮어써지거나 빠졌다. 화면을 열면 "카페·음료"가 다시 "휴게음식점"으로 돌아와 있었다.
AI 협업에서 반복적으로 발생한 패턴: AI는 기존 코드를 수정할 때 "핵심 기능"만 보존하려 한다. 데이터 변환 테이블처럼 비즈니스 로직처럼 보이지 않는 코드는 정리 대상이 된다.
해결책은 변환 규칙을 별도 파일로 분리하고, 수정 지시마다 "이 파일은 건드리지 말 것"을 명시하는 것이었다. 규칙이 코드에 인라인으로 박혀 있으면 언제든 사라진다.
지금은 data/category-map.js라는 파일 하나에 모든 변환 규칙이 들어 있고, AI에게 작업을 지시할 때 이 파일을 언급하면서 "변환 테이블은 유지해야 한다"고 매번 강조한다. 귀찮지만 이 한 줄이 없으면 다음 작업에서 또 원복된다.
이 경험이 가르쳐준 건, AI와 협업할 때 "이건 당연히 유지되겠지"라는 가정을 하면 안 된다는 것이다. 사람이 보기에 자명한 규칙도, AI에게는 그냥 코드 한 덩어리다. 중요한 제약 조건은 항상 명시적으로 지시에 포함시켜야 한다.
이 경험에서 배운 것
지도 기반 모바일 서비스는 처음부터 모바일 퍼스트로 설계해야 한다. PC 레이아웃을 모바일로 줄이는 건 반대 방향보다 훨씬 고통스럽다.
서비스 컬러는 기능이 아닌 컨셉에서 결정해야 한다. AI가 초안을 만들어도, 그게 서비스의 페르소나에 맞는지 판단하는 건 사람이 해야 한다.
AI와 장기 협업할 때는 커스텀 변환 규칙, 네이밍 컨벤션, 비즈니스 로직을 별도 파일로 분리하고, 매 작업 지시에 "유지 대상"으로 명시해야 한다. 그렇지 않으면 다음 작업에서 사라진다.