자정 세 시간, 스포츠 UI 통일과 조용한 인프라 정비
목차
자정을 넘기면 오히려 집중이 잘 된다. 낮 동안 쌓아둔 "나중에 하자" 리스트가 눈에 밟히고, 방해 알림도 없으니까. 오늘 새벽 00시~03시 사이에 그 리스트를 한꺼번에 쏟아냈다. 서비스 기능, 법적 정비, UI 디테일, 그리고 한동안 손 못 댄 포트폴리오까지. 얼핏 보면 뒤죽박죽이지만 실제로는 하나의 맥락으로 꿰어진 작업들이었다.
스포츠 밴드 — 라이브와 분석 허브를 같은 디자인 언어로
가장 큰 덩어리는 per-sport band 도입이었다. 라이브/오늘 화면에 종목별로 아이콘·accent 색·gemini 배너를 묶은 띠 형태로 구분선을 주는 UI다. 작업 전에는 경기 카드가 시간 순서로 그냥 쌓여 있었고, 사용자 입장에서는 축구와 농구가 뒤섞여 있어도 스크롤하다 보면 흐름을 놓쳤다.
해결책은 단순했다. 같은 종목끼리 밴드 하나로 묶고, 그 밴드에 종목 고유 accent를 입히는 것. 그러면 눈이 알아서 "아, 이제 다음 종목이구나"를 인식한다. 반응형 그리드도 이 작업 중에 함께 고쳤다 — 좁은 화면에서 밴드 안 카드가 찌그러지던 버그가 있었는데, 이참에 같이 잡았다.
그다음에 analysis hub로 넘어가서 같은 패턴을 적용했다. 기사를 종목별로 그룹핑해서 라이브 화면과 동일한 sport band로 표시한다. 이렇게 하면 라이브와 분석 탭을 오가도 시각적 맥락이 이어진다. "라이브에서 봤던 그 밴드가 여기도 있네" — 그게 목표였다.
| 화면 | 변경 전 | 변경 후 |
|---|---|---|
| 라이브/오늘 | 시간순 단순 나열 | 종목별 밴드 (아이콘+accent+배너) |
| 분석 허브 | 발행 순서 나열 | 종목별 밴드 그룹핑 |
| 반응형 그리드 | 좁은 화면에서 찌그러짐 | 수정 |
H2H 블록 — API 0회 호출로 만들기
매치 페이지에 head-to-head 섹션을 달고 싶었다. 두 팀이 예전에 어떻게 맞붙었는지 보여주는 블록. 문제는 이걸 외부 API로 끌어오면 매 요청마다 비용이 나간다는 거다.
고민하다 나온 답은 로컬 fixtures 데이터를 그대로 활용하는 것. 이미 서버에 쌓인 경기 결과 데이터에서 두 팀 ID를 교차 검색하면 H2H 이력을 충분히 재구성할 수 있다. API 호출 0회. 새벽에 혼자 "이거 되네?" 하고 씩 웃었다.
// 개념 축약 — 로컬 fixtures 에서 H2H 추출
const h2h = fixtures.filter(f =>
(f.homeId === teamA && f.awayId === teamB) ||
(f.homeId === teamB && f.awayId === teamA)
).slice(-5); // 최근 5경기
당연히 데이터가 없는 먼 과거 경기는 못 보여준다. 하지만 최근 5~10경기 정도는 커버가 되고, 그게 사용자가 실제로 궁금해하는 범위다. 완벽한 솔루션은 아니지만 비용 대비 효용이 압도적으로 낫다.
법적·인프라 정비 — 눈에 안 띄지만 반드시 해야 하는 것들
이 파트가 제일 재미없지만 제일 중요하다.
footer legal 링크: 사용자 UI 언어 기준으로 법적 문서 URL을 동적으로 구성했다. legal.hedvion.com/sportglance/<lang>/<doc> 패턴으로 연결하면, 한국어 사용자는 한국어 문서로, 영어 사용자는 영어 문서로 자동으로 가게 된다. 예전에는 그냥 기본 언어 URL 하나 박아뒀었는데, 다국어 서비스에서 그건 좋지 않다.
ops legal translate util: 같은 맥락에서 법적 문서 번역 유틸리티 스크립트를 ops에 추가했다. 나중에 새 언어 추가할 때 손으로 하나씩 옮기지 않아도 된다.
multi-sport squad backfill: 스쿼드 데이터 백필 스크립트도 다종목 대응으로 확장했다. 기존에는 특정 종목 하드코딩이 있었는데, 이번에 generalize.
/ads.txt: AdSense publisher ID 박아넣는 작업. 광고 수익화 준비. 사소해 보이지만 빠뜨리면 나중에 왜 승인이 안 되냐고 삽질하게 된다.
sites.json 드리프트 해소: portfolio.hedvion.com이 실제로 운영 중인데 내부 sites 레지스트리에 등록이 안 돼 있었다. 누락 상태로 방치하면 모니터링·배포 스크립트에서 빠지게 되니 이번에 등록했다. sites-detail.md에 sportglance=86 siteId 맵도 추가.
헤더 패딩: 22px. 로고와 컨트롤이 상단 엣지에 너무 붙어 있어서 답답해 보였다. 숫자가 작아 보여도 체감 차이는 꽤 크다.
번외 — 자정에 포트폴리오도 건드렸다
솔직히 이건 "하는 김에" 타입 작업이었다. 서비스 작업하다 잠깐 환기 겸 포트폴리오 사이트(index.html)를 열었는데, iOS 앱 섹션이 구버전 그대로였다.
- LiftLog: 헬스 기록 앱
- 광클타이머: 클릭 타이머 유틸
- 필모리: 필름 감성 메모리 앱
세 개 카드를 추가하고 모바일앱 카운트를 8로 올렸다. sportglance 쇼케이스 카드도 새로 만들어서 썸네일까지 붙였다.
그리고 unse 프로젝트가 최근에 한지(韓紙) 매거진 테마로 전면 리디자인 됐는데, 포트폴리오 썸네일이 구버전이라 새 디자인으로 교체했다. CSS도 캐시버스트 쿼리(v=20260626) 붙여서 기존 캐시에 물린 사용자가 구 스타일로 보이는 문제를 차단했다.
돌아보며
세 시간 동안 한 작업을 쭉 나열하면 많아 보이지만, 실제로는 두 개의 레일이 병렬로 달렸다.
- 서비스 레일: sport band UI 통일 → H2H 블록(무비용) → 법적·광고 인프라 정비
- 정리 레일: unse 리디자인 마무리 → 포트폴리오 업데이트 → 내부 레지스트리 드리프트 해소
서비스 레일의 핵심 교훈은 디자인 언어를 화면 단위가 아니라 서비스 전체에서 일관되게 유지해야 한다는 거다. sport band를 라이브에만 적용하고 분석 허브에 안 하면, 같은 종목을 보는 사용자가 탭 이동할 때마다 맥락이 끊긴다. 그래서 같은 날 밤에 두 군데 다 했다.
H2H 블록은 "있으면 좋겠다" 기능인데 API 비용 때문에 미뤄왔던 거다. 로컬 데이터로 충분히 된다는 걸 확인한 순간 바로 작업했다. 비용 문제로 묵혀둔 기능이 실은 이미 가진 데이터로 해결 가능한 경우가 생각보다 많다는 걸 다시 한 번 느꼈다.
정리 레일은 사실 기술 부채 청산이다. 썸네일 구버전, 레지스트리 누락, 캐시버스트 없는 CSS — 각각 치명적이진 않지만 쌓이면 "왜 이게 이러지?" 하는 혼선의 씨앗이 된다. 자정에 조용히 없앤 게 맞다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.