diff --git a/CLAUDE.md b/CLAUDE.md
index 20f2e0e..d3c76c9 100755
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -23,13 +23,14 @@
```markdown
**소요 시간**: X분
-**Context 사용량**: input Xk / output Xk tokens
+**Context 사용량**: 작업분 input Xk / output Xk tokens · 누적 input Xk / output Xk tokens
```
- 날짜는 오늘 날짜(YYYY-MM-DD), 시간은 작업 완료 시각 24시간제(HHMM), 작업명은 작업 내용을 한글 또는 영문으로 간략히
- 같은 날 여러 작업이면 각각 별도 파일 (예: `2026-04-01_1430_StationOverlay-분석.md`)
-- 소요 시간: 대화 시작부터 작업 완료까지의 실제 경과 시간
-- Context 사용량: 이 대화의 토큰 사용량 (모를 경우 추정값 기재)
+- 소요 시간: 해당 작업(요청 접수 → 완료)의 실제 경과 시간
+- Context 사용량: **작업분(그 작업을 처리하며 사용된 토큰)과 누적(대화 전체) 둘 다 기록**
+ (정확한 값을 모르면 추정값 기재)
---
diff --git a/docs/history/2026-07-14_2043_전체-커밋-4차.md b/docs/history/2026-07-14_2043_전체-커밋-4차.md
new file mode 100644
index 0000000..0a5c3da
--- /dev/null
+++ b/docs/history/2026-07-14_2043_전체-커밋-4차.md
@@ -0,0 +1,20 @@
+# 2026-07-14 전체 커밋 (4차) — 스테이션바 시선 연동·팬 지연 보정
+
+**소요 시간**: 2분
+**Context 사용량**: input 13600k / output 1k tokens
+
+## 커밋
+
+- **ca591ce** `스테이션바 시선 연동(station_lookahead)·팬 지연 보정·1km 측점 마크`
+- 20개 파일, +639 / −43 (코드 5개 + docs/history 15건)
+
+## 주요 내용
+
+station_lookahead 옵션(연직/고정N/auto, 연속 모델), 노선밖 시선 기준 전환,
+시점·시설물 마크 배지 기준 통일(구간 밖 미표시), 1km 단위 측점 마크,
+양끝 시작/끝 스테이션, 팬 지연 보정(POI EMA 우회 + 자세 선행 attLeadSec),
+sen H 최대 100. 데이터 작업(경로별 camera/display.json 산출·복원)은 이력 문서로 기록.
+
+## 다음
+
+- push 는 사용자 요청 시
diff --git a/docs/history/2026-07-15_0906_포터블-로컬실행-패키지.md b/docs/history/2026-07-15_0906_포터블-로컬실행-패키지.md
new file mode 100644
index 0000000..e6bfe78
--- /dev/null
+++ b/docs/history/2026-07-15_0906_포터블-로컬실행-패키지.md
@@ -0,0 +1,31 @@
+# 2026-07-15 포터블(로컬 단독 실행) 패키지 — 웹서버 없이 더블클릭 실행
+
+**소요 시간**: 15분
+**Context 사용량**: input 14400k / output 4k tokens
+
+## 요청
+
+웹서버로 돌던 버전을 로컬에서 바로 실행할 수 있게.
+
+## 구현
+
+- **server/src/demo.ts** (신규): 경량 서버 엔트리 — 정적 클라이언트 + SPA 폴백 +
+ 클라이언트 필수 API 2종(/api/elevation DEM 프록시, /api/tile 지도 타일 프록시)만.
+ 영상은 브라우저 폴더 선택(로컬 파일)이라 업로드/HLS/DB(네이티브 모듈) 불필요
+- **scripts/build-portable.sh** (신규): 클라이언트 빌드 → esbuild 단일 번들(server.cjs)
+ → client/ 복사 → 호스트 node.exe 복사 → GhiVideo.bat/README.txt(CRLF) 생성
+- 산출물 `dist-portable/GhiVideo-Portable/` (약 103MB, gitignore 등록):
+ node.exe + server.cjs(1.2MB) + client/ + GhiVideo.bat + README.txt
+- **D:\GhiVideo-Portable** 로 복사 완료 — USB/다른 PC 에 폴더째 복사해 사용
+
+## 사용법
+
+1. 폴더째 복사 (설치 불필요 — Node 런타임 포함)
+2. `GhiVideo.bat` 더블클릭 → 브라우저 자동 오픈(http://localhost:54000)
+3. 폴더 선택으로 영상 데이터 로드. 종료 = 콘솔 창 닫기
+
+## 검증
+
+- server.cjs 단독 실행 ✓, /api/health ✓, DEM 프록시(33.41,126.29→52m) ✓,
+ index.html 서빙 ✓, 타일 프록시 200 image/png ✓
+- 재빌드: `nvm use 20 && bash scripts/build-portable.sh`
diff --git a/docs/history/2026-07-15_0910_포터블-소스비공개-강화.md b/docs/history/2026-07-15_0910_포터블-소스비공개-강화.md
new file mode 100644
index 0000000..e1a148e
--- /dev/null
+++ b/docs/history/2026-07-15_0910_포터블-소스비공개-강화.md
@@ -0,0 +1,28 @@
+# 2026-07-15 포터블 고객 배포 — 소스 비공개 확인·강화
+
+**소요 시간**: 4분
+**Context 사용량**: input 14800k / output 2k tokens
+
+## 요청
+
+고객 배포용 — 소스가 오픈되지 않게.
+
+## 점검·조치
+
+- 클라이언트(client/): Vite 프로덕션 빌드 — 압축(minify) + **소스맵 0개** 확인 ✓
+ (원본 TS/TSX/주석 미포함)
+- 서버(server.cjs): 미압축 상태였음 → **esbuild --minify** 추가(식별자·공백 압축),
+ 빌드 스크립트 반영
+- 원본 소스는 패키지에 전혀 포함되지 않음(빌드 산출물만)
+- D:\GhiVideo-Portable 에 server.cjs·client 교체 반영
+ (node.exe 는 실행 중 잠김 — 동일 파일이라 교체 불필요)
+
+## 참고 (한계 고지)
+
+- JS 특성상 압축 해제(beautify)로 코드 '구조'까지 숨길 수는 없음 —
+ 변수명·주석·원본 구성은 제거된 일반적 상용 배포 수준.
+ 더 강한 보호(난독화 도구, 바이너리화)는 필요 시 별도 검토.
+
+## 검증
+
+- 압축 번들 단독 실행 + /api/health 정상 응답 확인
diff --git a/docs/history/2026-07-15_1043_측점검색-lookahead-적용.md b/docs/history/2026-07-15_1043_측점검색-lookahead-적용.md
new file mode 100644
index 0000000..5864d8b
--- /dev/null
+++ b/docs/history/2026-07-15_1043_측점검색-lookahead-적용.md
@@ -0,0 +1,24 @@
+# 2026-07-15 측점 검색에 station_lookahead 적용 — 검색 오차 제거
+
+**소요 시간**: 5분
+**Context 사용량**: input 15200k / output 2k tokens
+
+## 제보
+
+측점 검색 시 station_lookahead 값만큼 오차 — 검색은 드론 연직(chain) 기준이라
+이동 후 배지가 '검색값 + 오프셋'을 표시.
+
+## 수정 — StationBar.tsx handleJumpToMileage
+
+- 오프셋 활성(lookActive: viewChain≠chain 감지) 시 검색 매칭·범위 판정을
+ **viewChain(배지와 동일 기준)** 으로 전환 — 검색한 측점이 '화면이 비추는 지점'이
+ 되는 시각으로 이동, 이동 직후 배지 = 검색값
+- 노선밖(viewOffM>60) 프레임은 매칭 제외(접근/이탈 구간 오검색 방지)
+- 미설정 데이터셋은 기존 동작 그대로(chain 기준, 필터 없음)
+- 순환 이동(같은 값 연속 Enter)·허용오차(stationTolerance) 로직은 유지
+
+## 검증
+
+- tsc+vite 빌드 통과, 새 번들(index-DSBYNc0I.js, 빌드 07.15 10:43) 서빙
+- 적용: F5 새로고침(빌드 시각 10:43) → 폴더 재선택 → 측점 검색 후 배지 = 검색값 확인
+- 포터블 배포본에 반영하려면 `bash scripts/build-portable.sh` 재실행 필요
diff --git a/docs/history/2026-07-15_1102_타이틀-StationPlayer-변경.md b/docs/history/2026-07-15_1102_타이틀-StationPlayer-변경.md
new file mode 100644
index 0000000..958c6d2
--- /dev/null
+++ b/docs/history/2026-07-15_1102_타이틀-StationPlayer-변경.md
@@ -0,0 +1,18 @@
+# 2026-07-15 타이틀 StationPlayer 변경 — 재빌드·포터블·zip 갱신
+
+**소요 시간**: 5분
+**Context 사용량**: input 15800k / output 2k tokens
+
+## 작업
+
+- 사용자: App.tsx 좌측 패널(숨김) 제목을 StationPlayer / 스테이션 기반 동영상
+ 플레이어로 변경
+- 보완: 실제 브라우저 탭 제목인 **client/index.html `
`** 도 동일하게 변경
+ (App.tsx 쪽은 SHOW_LEFT_PANEL=false 라 화면에 안 보임)
+- 웹 서버 빌드 + 포터블 재빌드 + D:\GhiVideo-Portable(client·server.cjs) 갱신 +
+ GhiVideo-Portable.zip 재생성(48.9MB)
+
+## 검증
+
+- 서빙 확인: `StationPlayer — 스테이션 기반 동영상 플레이어` ✓
+- 적용: F5 새로고침으로 탭 제목 확인
diff --git a/docs/history/2026-07-15_1109_팬-지연-포즈평활-완전제거.md b/docs/history/2026-07-15_1109_팬-지연-포즈평활-완전제거.md
new file mode 100644
index 0000000..66dfd39
--- /dev/null
+++ b/docs/history/2026-07-15_1109_팬-지연-포즈평활-완전제거.md
@@ -0,0 +1,31 @@
+# 2026-07-15 팬(회전) 시 라벨 지연·늦은 정렬 — 포즈 평활 완전 제거
+
+**소요 시간**: 8분
+**Context 사용량**: input 16400k / output 3k tokens
+
+## 제보 (재발)
+
+좌우 회전 시 측점·라벨이 여전히 뒤늦게 따라오고 뒤늦게 정렬됨.
+
+## 원인 (단위 착오 발견)
+
+- 포즈 평활 상한 POSE_SMOOTH_SYNCED_MAX=5 를 '±5 영상프레임(83ms)'로 잡았으나
+ smoothFrame 의 halfWin 단위는 **프레임 배열 행(CSV 10Hz 행)** → 실제 **±0.5초 이동평균**
+- 대칭 창이라 등속 회전 중에는 지연이 없지만, **팬 시작·종료(각가속) 구간**에서
+ 평균이 실제 자세를 못 따라가 "늦게 출발·늦게 정렬" 발생
+
+## 수정 — StationOverlay.tsx
+
+- POSE_SMOOTH_SYNCED_MAX **5 → 0** (프레임 동기 데이터는 평활 완전 끔)
+ - 위치 = djmd(프레임 동기, 잡음 없음), 자세 = 10Hz 선형보간 — 둘 다 이미 매끄러움
+ - smoothFrame(h=0) = 해당 행 그대로 + poseAt 의 행간 선형보간만 수행
+- 비동기(CSV 지터) 데이터셋은 기존 smoothHalf 그대로
+
+## 잔여 지연 시
+
+- 남는 '일정한' 지연(등속 회전 중에도 밀림) = 짐벌 로그 기록 지연 →
+ 카메라 파라미터 '자세 선행' +0.1~0.3s 튜닝 후 PC 저장 (어제 추가한 기능)
+
+## 반영
+
+- 웹(index-vsJQCQXN.js, 07.15 11:09) + 포터블(D:\GhiVideo-Portable) + zip 갱신 완료
diff --git a/docs/history/2026-07-15_1113_작업기록-토큰-형식-규칙화.md b/docs/history/2026-07-15_1113_작업기록-토큰-형식-규칙화.md
new file mode 100644
index 0000000..59ea46d
--- /dev/null
+++ b/docs/history/2026-07-15_1113_작업기록-토큰-형식-규칙화.md
@@ -0,0 +1,21 @@
+# 2026-07-15 작업 기록 형식 규칙화 — 작업분·누적 토큰 병기 (영구 적용)
+
+**소요 시간**: 5분
+**Context 사용량**: 작업분 input 90k / output 2k tokens · 누적 input 16600k / output 220k tokens
+
+## 요청
+
+작업 기록 md: 파일명 앞 날짜·시간 + 내용에 처리 토큰량 기록.
+사용된 토큰량(작업분)과 누적 토큰량 **모두** 기록. 앞으로 모든 작업에 영구 적용.
+
+## 조치
+
+- **CLAUDE.md** 히스토리 규칙 갱신 — Context 사용량 형식을
+ `작업분 input Xk / output Xk · 누적 input Xk / output Xk` 로 확정
+ (기존 파일명 규칙 YYYY-MM-DD_HHMM_작업명.md 은 그대로)
+- **개인 메모리** 등록(work-history-md-format) — 다른 프로젝트/새 세션에도 적용
+- 이 파일부터 새 형식 적용 (작업분 = 해당 요청 처리에 사용된 추정 토큰)
+
+## 참고
+
+- 토큰값은 추정치 기준(정확한 계측값이 없을 때) — CLAUDE.md 에 명시
diff --git a/docs/history/2026-07-15_1116_직진-라벨떨림-자세필터.md b/docs/history/2026-07-15_1116_직진-라벨떨림-자세필터.md
new file mode 100644
index 0000000..ed9b555
--- /dev/null
+++ b/docs/history/2026-07-15_1116_직진-라벨떨림-자세필터.md
@@ -0,0 +1,29 @@
+# 2026-07-15 직진 시 원거리 라벨 떨림 — 자세 속도적응 필터(One Euro)
+
+**소요 시간**: 7분
+**Context 사용량**: 작업분 input 120k / output 3k tokens · 누적 input 16800k / output 226k tokens
+
+## 제보
+
+회전 추종은 좋아졌는데, 직진 시 전방 측점·라벨이 흔들려 보임.
+
+## 원인
+
+포즈 평활 완전 제거(11:09) 후 비행로그 자세의 미세 잡음이 그대로 노출 —
+특히 짐벌 피치가 **정수 단위 양자화**로 기록되어 행 사이 ±1° 계단이 생기고,
+원거리 라벨은 각도 잡음이 증폭(0.5°≈수십 px)되어 떨림으로 보임.
+
+## 수정 — StationOverlay.tsx
+
+- **자세 속도적응 필터(One Euro)** 를 RAF 의 dronePose 에 적용 (frameSynced 전용):
+ - 컷오프 = MIN_CUT(0.8Hz) + BETA(0.5)×|각속도| — 변화가 느리면(직진 미세 잡음)
+ 강하게 평활, 팬처럼 빠르면 컷오프 상승 → **지연 없이 떨림만 제거**
+ - yaw(최단각)/pitch/roll 에 적용, 위치·고도(djmd, 잡음 없음)는 미적용
+ - 시크·세그먼트 전환(급점프)·0.5s 이상 정지 시 필터 리셋
+- 선형·측점·POI 라벨이 같은 dronePose 를 쓰므로 한 몸으로 움직임(상호 분리 없음)
+
+## 반영
+
+- 웹(index-3vQazFsG.js, 07.15 11:16) + 포터블(D:\GhiVideo-Portable) + zip 갱신
+- 확인: F5 → 직진 구간 떨림 감소 + 회전 추종 유지. 떨림이 남으면 MIN_CUT 하향(0.5),
+ 회전이 다시 늦으면 BETA 상향(0.8) 여지 있음
diff --git a/docs/history/2026-07-15_1124_자세필터-route옵션화.md b/docs/history/2026-07-15_1124_자세필터-route옵션화.md
new file mode 100644
index 0000000..fc8a7ac
--- /dev/null
+++ b/docs/history/2026-07-15_1124_자세필터-route옵션화.md
@@ -0,0 +1,30 @@
+# 2026-07-15 자세 필터 강도 route.json 옵션화 — att_min_cut / att_beta
+
+**소요 시간**: 6분
+**Context 사용량**: 작업분 input 100k / output 2k tokens · 누적 input 16900k / output 228k tokens
+
+## 요청
+
+자세 필터(One Euro) 값을 route.json 옵션으로 사용자 조정 가능하게.
+
+## 구현 — StationOverlay.tsx, types/geo.ts
+
+route.json `routeInfo` 에 추가(폴더별, 숫자·숫자문자열 허용):
+
+| 키 | 기본 | 의미 |
+|----|------|------|
+| `att_min_cut` | 0.8 | 저속 컷오프(Hz) — **작을수록 직진 떨림 억제 강함** (0.1~3 권장) |
+| `att_beta` | 0.5 | 각속도당 컷오프 증가 — **클수록 팬(회전) 추종 민감** |
+
+- routeMeta 변경 시 자동 반영, 설정 존재하면 콘솔 로그
+ `[오버레이] 자세 필터: min_cut …Hz, beta … (route.json)` 로 확인 가능
+- RouteMeta 타입 문서화
+
+## 튜닝 가이드
+
+- 직진 떨림 남음 → att_min_cut 0.8 → 0.5 → 0.3 낮추기
+- 회전 추종 둔함 → att_beta 0.5 → 0.8 → 1.0 올리기
+
+## 반영
+
+- 웹(index-DZfP1Yr_.js, 07.15 11:24) + 포터블 + zip 갱신 완료
diff --git a/docs/history/2026-07-15_1244_StationPlayer-Portable-경로생성.md b/docs/history/2026-07-15_1244_StationPlayer-Portable-경로생성.md
new file mode 100644
index 0000000..bcbe56e
--- /dev/null
+++ b/docs/history/2026-07-15_1244_StationPlayer-Portable-경로생성.md
@@ -0,0 +1,21 @@
+# 2026-07-15 StationPlayer-Portable — 지정 경로에 로컬 버전 생성·개명
+
+**소요 시간**: 6분
+**Context 사용량**: 작업분 input 80k / output 2k tokens · 누적 input 17100k / output 233k tokens
+
+## 요청
+
+D:\GhiVideo-Portable 대신 **D:\_project\20260612_abcvideo\StationPlayer-Portable** 에 로컬 버전.
+
+## 작업
+
+- 최신 포터블(자세 필터 옵션 포함, 11:24 빌드)을 지정 경로에 배치
+ - 대상 폴더가 빈 폴더로 이미 존재 → 중첩 복사를 평탄화로 정리
+- 제품명 변경 반영: **GhiVideo.bat → StationPlayer.bat**, README 제목/안내문 StationPlayer 로
+- scripts/build-portable.sh 도 동일 이름 체계로 갱신
+ (산출물 dist-portable/StationPlayer-Portable, StationPlayer.bat)
+- 기존 D:\GhiVideo-Portable / GhiVideo-Portable.zip 은 그대로 둠(구버전 이름 배포본)
+
+## 구성 (D:\_project\20260612_abcvideo\StationPlayer-Portable)
+
+StationPlayer.bat / README.txt / client\ / node.exe / server.cjs — 실행은 bat 더블클릭
diff --git a/docs/history/2026-07-15_1250_선형-커튼면-입체표시.md b/docs/history/2026-07-15_1250_선형-커튼면-입체표시.md
new file mode 100644
index 0000000..318a58a
--- /dev/null
+++ b/docs/history/2026-07-15_1250_선형-커튼면-입체표시.md
@@ -0,0 +1,23 @@
+# 2026-07-15 선형 입체 표시 — 아래로 내려 그리는 커튼 면
+
+**소요 시간**: 12분
+**Context 사용량**: 작업분 input 150k / output 4k tokens · 누적 input 17400k / output 240k tokens
+
+## 요청
+
+선형을 선만이 아니라, 아래쪽으로 일정 두께의 면(커튼)이 있는 입체 형태로.
+
+## 구현 — StationOverlay.tsx
+
+- buildLines: 각 선형 세그먼트에서 윗변(기존 선 z)과 아랫변(z − 커튼높이)을 각각
+ 투영해 화면 사각형(curtainQuads) 생성 — 원 클립(표시 측점까지)·드론높이 모드 평면
+ 규칙 동일 적용, 근평면 뒤 꼭짓점 있으면 면 생략(선은 유지)
+- RAF: 커튼 면을 반투명 빨강(0.22)으로 채우고 하단 윤곽선(0.35) 추가 → 그 위에
+ 기존 선(0.85) — 벽처럼 서 있는 입체감
+- **화면표시 옵션 '커튼 높이'** 슬라이더(0~20m, 0.5 스텝, 기본 3m, 0=선만):
+ display.json `clCurtainM` 로 저장/로드/초기화 연동 (PC 저장 payload 포함)
+
+## 반영
+
+- 웹(index-CIAoq9c5.js, 07.15 12:50) + 포터블(D:\_project\...\StationPlayer-Portable) 갱신
+- 확인: F5 → 폴더 재선택 → 화면표시 옵션에서 '커튼 높이' 조절
diff --git a/docs/history/2026-07-15_1256_선형-홀로그램-입체효과-토글.md b/docs/history/2026-07-15_1256_선형-홀로그램-입체효과-토글.md
new file mode 100644
index 0000000..8ef5fc3
--- /dev/null
+++ b/docs/history/2026-07-15_1256_선형-홀로그램-입체효과-토글.md
@@ -0,0 +1,27 @@
+# 2026-07-15 선형 입체 표현 '홀로그램 펜스' + 표시 토글 옵션
+
+**소요 시간**: 14분
+**Context 사용량**: 작업분 input 180k / output 6k tokens · 누적 input 17700k / output 248k tokens
+
+## 요청
+
+선형을 참신하게 입체적으로 + 보일지 말지 사용자 옵션.
+
+## 구현 — '홀로그램 펜스' (StationOverlay.tsx)
+
+1. **그라데이션 커튼**: 세그먼트를 ~15m 분할, 위(0.38)→아래(0.02) 소멸 그라데이션 면
+2. **수직살(스트럿)**: 분할 경계마다 세로선 — 원근 수렴(멀수록 촘촘·짧음)이 핵심 입체 큐,
+ 거리 페이드(450m 기준)로 깊이감
+3. **상단 레일 글로우**: 넓고 옅은 글로우(8px, 0.22) 위에 본선(2.5px, 0.9) — 네온 레일
+4. **유동 대시**: 밝은 점(5/27 대시)이 레일을 따라 흐르는 애니메이션 — 방향/생동감
+
+## 옵션 (display.json)
+
+- **clFx**(기본 true): 화면표시 패널 '선형 입체 효과' 토글 버튼 — 끄면 종전 단순 선
+- **clCurtainM**(기본 3m): 커튼 높이 (입체 효과 켠 상태에서만 노출, 0=면 없이 레일만)
+- PC 저장/자동 적용/초기화(파일 복원) 모두 연동
+
+## 반영
+
+- 웹(index-DqFz4LF6.js, 07.15 12:56) + 포터블(StationPlayer-Portable) 갱신
+- 확인: F5 → 폴더 재선택 → 화면표시 옵션 '선형 입체 효과' 토글
diff --git a/docs/history/2026-07-15_1302_대시방향-튜브레일.md b/docs/history/2026-07-15_1302_대시방향-튜브레일.md
new file mode 100644
index 0000000..85bbab3
--- /dev/null
+++ b/docs/history/2026-07-15_1302_대시방향-튜브레일.md
@@ -0,0 +1,31 @@
+# 2026-07-15 유동 대시 진행방향 정렬 + 선형 튜브(지름 있는 원형 단면) 레일
+
+**소요 시간**: 13분
+**Context 사용량**: 작업분 input 200k / output 7k tokens · 누적 input 18000k / output 255k tokens
+
+## 요청
+
+1. 선형 애니메이션(유동 대시)이 '가는 방향'으로 흐르게
+2. 선형을 지름 있는 입체 원형(튜브)으로
+
+## 구현 — StationOverlay.tsx
+
+### ① 대시 진행방향 정렬
+
+- 선형 배열이 체이니지 감소 순(7k→0k)이라 대시가 역방향으로 흐르던 문제
+- 드론 **실제 이동 벡터**(±3행 GPS 변위, 호버 시 yaw 폴백)와 세그먼트 방향의
+ 내적으로 각 세그먼트를 '뒤→앞'으로 정렬 → 역방향 비행에서도 항상 진행방향 흐름
+
+### ② 튜브 레일 (원형 단면)
+
+- 분할점(~15m) 사이 구간마다 화면 폭 = **지름(m) ÷ 거리 × 픽셀/라디안** —
+ 가까울수록 굵고 멀수록 가는 원근 지름 표현 (하한 1.5px, 상한 40px)
+- **3중 스트로크 원통 음영**: 외곽(어두운 적, 1.0w) → 본체(적, 0.6w) →
+ 하이라이트(밝은 살구, 0.26w) — 둥근 파이프 질감. 라운드 캡으로 이음새 없음
+- 옵션 **'선형 지름'**(display.json clTubeD, 기본 1.2m, 0.2~5m) — 입체 효과 켠
+ 상태에서 커튼 높이 아래 슬라이더. 입체 효과 끄면 종전 단순 선
+
+## 반영
+
+- 웹(index-L2DHv7Ep.js, 07.15 13:02) + 포터블(StationPlayer-Portable) 갱신
+- 확인: F5 → 대시가 진행방향으로 흐르는지, 튜브가 가까울수록 굵어지는지
diff --git a/docs/history/2026-07-15_1307_진한코어-반투명원통.md b/docs/history/2026-07-15_1307_진한코어-반투명원통.md
new file mode 100644
index 0000000..e5ee962
--- /dev/null
+++ b/docs/history/2026-07-15_1307_진한코어-반투명원통.md
@@ -0,0 +1,20 @@
+# 2026-07-15 선형 렌더링 — 진한 중심선 + 반투명 원통 셸
+
+**소요 시간**: 4분
+**Context 사용량**: 작업분 input 60k / output 2k tokens · 누적 input 18100k / output 258k tokens
+
+## 요청
+
+선형의 선은 진하게, 그 선을 중심으로 감싸는 원통은 입체감 + 투명도.
+
+## 수정 — StationOverlay.tsx (RAF 렌더)
+
+- **중심선(코어)**: 항상 진한 실선 rgba(205,25,25,0.95) / 2.5px — 튜브 유무와 무관
+- **원통 셸**: 불투명 3중 파이프 → **반투명 다층 셸**(알파 0.10~0.13, 3층)로 교체
+ - 폭 = 지름/거리 원근 환산(상한 44px), 안쪽 층일수록 은은히 밝음 — 유리관 볼륨감
+ - 셸이 코어를 감싸는 구조(셸 먼저 → 코어 → 유동 대시)
+- 유동 대시·커튼·수직살·'선형 지름' 옵션은 그대로
+
+## 반영
+
+- 웹(index-CgJSMixD.js, 07.15 13:07) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1309_커튼제거-기본형입체형-토글.md b/docs/history/2026-07-15_1309_커튼제거-기본형입체형-토글.md
new file mode 100644
index 0000000..029a2c2
--- /dev/null
+++ b/docs/history/2026-07-15_1309_커튼제거-기본형입체형-토글.md
@@ -0,0 +1,23 @@
+# 2026-07-15 커튼 제거 + 선형 기본형/입체형 사용자 선택
+
+**소요 시간**: 4분
+**Context 사용량**: 작업분 input 70k / output 3k tokens · 누적 input 18200k / output 262k tokens
+
+## 요청
+
+커튼 표현 제거. 선형을 기본형/입체형으로 사용자 옵션 선택.
+
+## 수정 — StationOverlay.tsx
+
+- **커튼 완전 제거**: 그라데이션 면·수직살 렌더링, 생성 로직, clCurtainM
+ 옵션(상태/저장/로드/초기화/슬라이더) 모두 삭제
+- **표시 형태 토글**(display.json `clFx`):
+ - **입체형**(기본): 반투명 원통 셸 + 진한 중심선 + 유동 대시 + 원근 지름
+ - **기본형**: 종전 단순 빨간 선
+ - 버튼 문구: '■ 선형 입체형 (원통 + 유동 대시)' ↔ '▶ 선형 기본형 (단순 선)'
+- '선형 지름'(clTubeD) 슬라이더는 입체형에서만 노출
+- 기존 display.json 에 남은 clCurtainM 키는 무시됨(무해)
+
+## 반영
+
+- 웹(index-Kjiwq3q1.js, 07.15 13:09) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1312_유동점-월드고정-전환.md b/docs/history/2026-07-15_1312_유동점-월드고정-전환.md
new file mode 100644
index 0000000..cc1499d
--- /dev/null
+++ b/docs/history/2026-07-15_1312_유동점-월드고정-전환.md
@@ -0,0 +1,28 @@
+# 2026-07-15 유동 점 근거리 역행 — 월드(체이니지) 고정 펄스로 전환
+
+**소요 시간**: 8분
+**Context 사용량**: 작업분 input 130k / output 5k tokens · 누적 input 18400k / output 268k tokens
+
+## 제보
+
+유동 점이 화면 위쪽(원거리)은 앞으로 흐르는데, 드론에 가까울수록 뒤(드론 쪽)로
+흐르는 것처럼 보임 — 모두 앞으로 흐르게.
+
+## 원인
+
+대시가 **화면(픽셀) 좌표 기준**으로 이동 — 근거리에서는 지면이 화면 아래로
+흘러내리는 속도(수백 px/s)가 대시 상승 속도(36px/s)보다 훨씬 빨라,
+지면 기준으로는 뒤로 가는 것처럼 보이는 상대운동 착시.
+
+## 수정 — StationOverlay.tsx
+
+- 화면 대시 제거 → **월드 고정 펄스**: 체이니지에 고정된 점(30m 간격)이
+ 노선을 따라 **실속도 12m/s** 로 전진 — 원근 투영을 매 프레임 다시 하므로
+ 어느 거리에서든 지면 기준 항상 진행방향으로 흐름
+- 진행방향: 드론 이동 벡터와 중심선 배열 방향의 투표(dot) 부호로 결정
+ (역방향 비행도 정상), 중심선 누적거리(clCumRef) 사전 계산
+- 펄스 크기도 원근(지름 연동 rWorld/거리) — 가까울수록 큼 (1.6~9px)
+
+## 반영
+
+- 웹(index-oyd_KyNG.js, 07.15 13:12) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1321_전구간-측점검색-궤적방식-점.md b/docs/history/2026-07-15_1321_전구간-측점검색-궤적방식-점.md
new file mode 100644
index 0000000..ba03550
--- /dev/null
+++ b/docs/history/2026-07-15_1321_전구간-측점검색-궤적방식-점.md
@@ -0,0 +1,36 @@
+# 2026-07-15 측점 검색 전 구간(모든 세그먼트) 순환 + 선형 점 궤적 방식 전환
+
+**소요 시간**: 25분
+**Context 사용량**: 작업분 input 350k / output 12k tokens · 누적 input 18900k / output 282k tokens
+
+## 요청
+
+1. 측점 검색(예: 1355)이 한 군데만 찾음 — 여러 통과가 있으면 현재 위치에서
+ 진행방향으로 찾고, 끝까지 가면 처음부터 현재까지 순환해야 함
+2. 선형 애니메이션을 드론 궤적 표현과 동일한 방식으로
+
+## 구현
+
+### ① 측점 검색 — 전 구간(모든 세그먼트) 순환
+
+- 종전: 검색 범위가 **현재 영상(세그먼트) 프레임**뿐 → 다른 영상에 있는 통과는
+ 못 찾고, 현재 영상에 1곳이면 1곳만 순환
+- geoData/geoStore: **fullFrames**(전체 비행 프레임, datum·초점 보정 동일 적용) 추가
+- StationBar: 전 구간 검색 인덱스(globalSearch — 배지와 동일한 viewChain 규칙,
+ 0.2s 표본) 생성 → 통과 그룹핑 → **전역 시간축에서 현재 위치 기준 진행방향 순환**
+ (같은 값 연속 Enter = 다음 통과, 마지막 넘으면 처음으로 랩어라운드)
+- 다른 세그먼트의 통과로 점프: useVideoPlayer.loadLocalFile 에 **startAtSec** 추가,
+ VideoPlayer.handleSeekSegment(세그먼트 전환 + 해당 시각 시크, 재생 상태 유지),
+ StationBar 에 onSeekSegment prop 배선
+- 세그먼트 길이 미측정(null) 등 전역 인덱스 불가 시 기존 세그먼트 내 검색 폴백
+
+### ② 선형 점 — 궤적(측정점)과 동일 방식
+
+- 이동 애니메이션(12m/s 위상) 제거 → **체이니지 20m 간격 월드 고정점**
+- 스타일도 궤적 측정점과 동일(노란 점 1.8px 고정 크기) — 화면 이동만으로
+ 자연스럽게 흐르는 궤적과 같은 질감
+
+## 반영
+
+- 웹(index-BCV4opt2.js, 07.15 13:21) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 측점 입력 후 Enter 반복 — 전 구간 통과를 순환하며 세그먼트가 자동 전환되는지
diff --git a/docs/history/2026-07-15_1327_선형점-측점10등분-분할옵션.md b/docs/history/2026-07-15_1327_선형점-측점10등분-분할옵션.md
new file mode 100644
index 0000000..94d70c2
--- /dev/null
+++ b/docs/history/2026-07-15_1327_선형점-측점10등분-분할옵션.md
@@ -0,0 +1,23 @@
+# 2026-07-15 선형 점을 측점 사이 등분점으로 + 분할 수 옵션
+
+**소요 시간**: 8분
+**Context 사용량**: 작업분 input 130k / output 6k tokens · 누적 input 19200k / output 290k tokens
+
+## 요청
+
+1. 노란 점을 측점(100m) 사이 십등분 위치에 — 10m 단위 검토용
+2. 몇 등분할지 사용자 옵션으로
+
+## 구현 — StationOverlay.tsx
+
+- 중심선 로드 시 **측점 체이니지 ↔ 폴리라인 누적거리 앵커** 구축
+ (측점 정점이 선형에 삽입되어 있어 최근접 5m 이내 = 그 측점 위치)
+- 선형 점을 임의 등간격(20m) → **인접 측점 구간의 N등분점**으로 변경:
+ 측점 자체 위치(눈금 존재)는 제외, **중간(½) 지점은 크게(2.8px)** 표시
+- **'측점 분할' 옵션**(display.json `clDotDiv`, 기본 10 = 10m 단위, 1~20, 1=점 없음):
+ 입체형 상태의 화면표시 패널 슬라이더, PC 저장/자동 적용/초기화 연동
+- 측점 앵커가 없는 데이터셋은 20m 등간격 폴백
+
+## 반영
+
+- 웹(index-DX-VwDm-.js, 07.15 13:27) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1330_선형-곡선평활.md b/docs/history/2026-07-15_1330_선형-곡선평활.md
new file mode 100644
index 0000000..fa7e2e7
--- /dev/null
+++ b/docs/history/2026-07-15_1330_선형-곡선평활.md
@@ -0,0 +1,28 @@
+# 2026-07-15 선형 각짐 — Catmull-Rom 곡선 평활 + 튜브 렌더 배치 최적화
+
+**소요 시간**: 7분
+**Context 사용량**: 작업분 input 120k / output 5k tokens · 누적 input 19400k / output 296k tokens
+
+## 제보 (스크린샷: 2+000~2+100 곡선)
+
+선형(튜브)이 곡선부에서 각져 보임 — 정점(~20m 간격) 사이 직선 연결이 원인.
+
+## 수정
+
+### geoData.ts — 곡선 평활 (로드 시 1회)
+
+- **Centripetal Catmull-Rom** 보간으로 정점 사이를 세분(세그먼트당 2~6분할, ~6m 간격)
+- **모든 원 정점을 정확히 통과** → 측점 삽입 정점 유지 = 선형-측점 정합 그대로,
+ z 도 곡선 보간(수직 각짐도 완화)
+- 60m 이상 장대 세그먼트(직선)·양끝 세그먼트·중복 정점은 세분 제외(불필요·경계 안정)
+- 측점 z 재정렬·정점 삽입이 끝난 최종 선형에 적용, 콘솔 로그로 정점 수 확인 가능
+
+### StationOverlay.tsx — 튜브 스트로크 배치
+
+- 세그먼트 수 증가(213 → 수백)에 대비해 폭 버킷(0.5px) 단위로 묶어
+ 스트로크 횟수를 세그먼트 수 → 버킷 수(~20)로 절감
+
+## 반영
+
+- 웹(index-BnZPSKzv.js, 07.15 13:30) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 곡선 구간(예: 2+000~2+100)에서 튜브가 매끄러운 호로 보이는지
diff --git a/docs/history/2026-07-15_1334_원통-이음매-오프스크린합성.md b/docs/history/2026-07-15_1334_원통-이음매-오프스크린합성.md
new file mode 100644
index 0000000..9d43514
--- /dev/null
+++ b/docs/history/2026-07-15_1334_원통-이음매-오프스크린합성.md
@@ -0,0 +1,25 @@
+# 2026-07-15 원통 셸 이음매 잘림/중첩 — 오프스크린 불투명 합성으로 해소
+
+**소요 시간**: 5분
+**Context 사용량**: 작업분 input 90k / output 3k tokens · 누적 input 19600k / output 300k tokens
+
+## 제보 (스크린샷)
+
+중심선을 감싸는 반투명 원통이 중간중간 잘려 보이고 중첩 부분이 진하게 보임 — 정확한 관찰.
+
+## 원인
+
+원통 셸을 짧은 세그먼트 '반투명' 스트로크로 이어 그려서:
+- 세그먼트 이음매(라운드 캡 겹침)마다 알파가 중첩 → 진한 띠
+- 폭 버킷이 바뀌는 지점은 다른 패스로 그려져 단차(잘림)처럼 보임
+
+## 수정 — StationOverlay.tsx
+
+- **오프스크린 캔버스에 '불투명'으로 셸 3층을 그린 뒤, 메인 캔버스에 전체를
+ 한 번(globalAlpha 0.32)에 합성** — 불투명 겹침은 흔적이 없으므로 이음매·단차가
+ 원천 제거되고, 투명도는 화면 합성 단계에서 균일하게 적용됨
+- 폭 버킷 배치 최적화 유지(불투명이라 겹침 무해), 캔버스 크기 변경 시 오프스크린 재생성
+
+## 반영
+
+- 웹(index-D3J3-0ig.js, 07.15 13:34) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1339_측점검색-정밀화.md b/docs/history/2026-07-15_1339_측점검색-정밀화.md
new file mode 100644
index 0000000..de27a8c
--- /dev/null
+++ b/docs/history/2026-07-15_1339_측점검색-정밀화.md
@@ -0,0 +1,31 @@
+# 2026-07-15 측점 검색 오차(2000→1+991) — 시간축·표본 보정
+
+**소요 시간**: 10분
+**Context 사용량**: 작업분 input 160k / output 5k tokens · 누적 input 19800k / output 305k tokens
+
+## 제보 (스크린샷)
+
+2000 검색 시 1+991 로 이동 — 해당 측점으로 정확히 안 감.
+
+## 원인 (실측)
+
+1. **전역 시간축 스케일 오차**: 전 구간 검색의 fps 를 '마지막 프레임 ÷ 영상 길이 합'으로
+ 환산 — CSV 로그가 영상보다 길어(착륙 꼬리, 경로 1-1 +0.9s/0.14%) 시간축이 압축되어
+ 검색 지점이 최대 ~7m 어긋남 (ffprobe 실측: 1-1 671.7s vs CSV 672.6s)
+2. **표본 이산화**: 검색 인덱스가 0.2s 표본이라 ±0.8m 추가 오차
+
+## 수정 — StationBar.tsx (+ geoData DJI_VIRTUAL_FPS export)
+
+- 시간기반(DJI) 로그는 frame = 경과초×59.94 가 정확한 환산 → **가상 fps 상수 사용**
+ (프레임 간격 >1 로 자동 감지, 프레임 기반 데이터는 기존 방식 유지)
+- 통과 시각을 이웃 표본과 **선형보간**해 vc == 검색값 지점으로 정밀화
+
+## 잔여 한계 (참고)
+
+- 마지막 세그먼트 끝부분은 CSV 꼬리 때문에 세그먼트 내부 배지 시간축이 미세 압축 —
+ 끝 수 초 구간에서 수 m 오차 가능(통상 검토 구간 밖)
+
+## 반영
+
+- 웹(index-BcIFwOAf.js, 07.15 13:39) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 2000 검색 → 배지 2+000(±2m 이내) 도착
diff --git a/docs/history/2026-07-15_1355_측점검색-강한통과-우선.md b/docs/history/2026-07-15_1355_측점검색-강한통과-우선.md
new file mode 100644
index 0000000..3d895b7
--- /dev/null
+++ b/docs/history/2026-07-15_1355_측점검색-강한통과-우선.md
@@ -0,0 +1,30 @@
+# 2026-07-15 측점 검색 불일치(1370→1+360) — '도달 통과' 우선 선택
+
+**소요 시간**: 12분
+**Context 사용량**: 작업분 input 180k / output 6k tokens · 누적 input 20100k / output 311k tokens
+
+## 제보 (스크린샷)
+
+1370 검색 시 배지 1+360 지점으로 이동 — 검색값과 불일치.
+
+## 원인 (실데이터 재현)
+
+- 경로 1-1, lookahead 240. t≈252s 구간에서 **드론이 약 2분 호버**하며 배지값(vc)이
+ 1360 에 정체 + 호버 중 카메라 회전으로 vc 가 검색 창을 들락거림
+- 그 결과 "1360 까지만 접근하는" **약한 통과 창**(최소 오차 9.9m)이 생기고,
+ 검색이 이 창을 첫 통과로 채택 → 실제 1370 도달 지점(t=336.9s)을 지나침
+
+## 수정 — StationBar.tsx
+
+- 통과 창을 **강한 통과**(창 안에서 vc 가 검색값을 실제로 가로지름: min≤km≤max,
+ 또는 최소 오차 ≤5m)와 **약한 통과**(근접만)로 분류
+- 순환 이동은 강한 통과들로만 — 강한 통과가 하나도 없을 때만 약한 통과 폴백
+
+## 검증 (경로 1-1, km=1370)
+
+- 강한 통과: t=336.9s, vc=**1370.0** (오차 0) ✓
+- 약한 통과(후순위): t=252.3s, vc=1360.1 — 종전에 잘못 착지하던 곳
+
+## 반영
+
+- 웹(index-CngDBzBa.js, 07.15 13:55) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1359_연속Enter-순환-보강.md b/docs/history/2026-07-15_1359_연속Enter-순환-보강.md
new file mode 100644
index 0000000..368d24b
--- /dev/null
+++ b/docs/history/2026-07-15_1359_연속Enter-순환-보강.md
@@ -0,0 +1,27 @@
+# 2026-07-15 측점 2개 이상 시 Enter 순환 — 시크 지연에도 다음 통과로
+
+**소요 시간**: 6분
+**Context 사용량**: 작업분 input 90k / output 3k tokens · 누적 input 20300k / output 315k tokens
+
+## 요청
+
+측점이 2개 이상 존재하면 Enter 를 칠 때마다 다음 검색 측점으로 이동.
+
+## 원인 (기존 순환이 멈추던 조건)
+
+- 순환 로직은 있었으나 '같은 검색' 판정이 **현재 시각 ≈ 직전 목표(0.1s)** 일 때만 성립 —
+ 4K 시크·세그먼트 전환은 정착에 수백 ms~수 초 걸려, 그 전에 Enter 를 다시 치면
+ 현재 시각이 직전 목표에 못 미쳐 '새 검색'으로 오인 → **같은 통과를 다시 잡음**
+
+## 수정 — StationBar.tsx (전 구간·세그먼트 폴백 양쪽)
+
+- 같은 값 재Enter 는 시각 근접 여부와 무관하게 **무조건 다음 통과**:
+ 기준시각 = max(직전 목표, 현재 시각 − 0.25s)
+ - 시크 미정착(현재 < 직전 목표) → 직전 목표 기준으로 다음 통과 ✓
+ - 재생으로 이미 지나감 → 현재 시각 기준 다음 통과 ✓
+ - 마지막 통과 이후 → 처음으로 랩어라운드(기존 유지)
+
+## 반영
+
+- 웹(index-C_8WNL38.js, 07.15 13:59) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 같은 값 Enter 연타 — 시크가 끝나기 전에 쳐도 통과 지점들을 차례로 순환
diff --git a/docs/history/2026-07-15_1404_측점검색-교차방식-재설계.md b/docs/history/2026-07-15_1404_측점검색-교차방식-재설계.md
new file mode 100644
index 0000000..4de5f4f
--- /dev/null
+++ b/docs/history/2026-07-15_1404_측점검색-교차방식-재설계.md
@@ -0,0 +1,40 @@
+# 2026-07-15 측점 검색 재설계 — 부호 교차(zero-crossing) 방식
+
+**소요 시간**: 15분
+**Context 사용량**: 작업분 input 250k / output 8k tokens · 누적 input 20600k / output 324k tokens
+
+## 제보
+
+1355 검색이 계속 오차 발생 + 두 번째 1355 지점으로 순환이 안 됨.
+
+## 원인 (실데이터 재현으로 확정)
+
+±20m '허용 창' 그룹핑 방식의 구조적 한계:
+- 호버·저속 구간에서 창이 128초까지 늘어나며 **서로 다른 통과들이 한 창으로 병합**
+ (1355 실제 통과 3곳 — 201.0s/327.2s/334.5s — 이 1곳으로 뭉개짐 → 순환 불가)
+- 창 안 '최적점' 선택이 흔들리며 착지 오차 유발
+
+## 수정 — StationBar.tsx (전 구간 검색)
+
+- **부호 교차 방식**: 배지값(vc)이 검색값을 가로지르는 모든 순간을 각각의 통과로
+ (교차 시각 = 선형보간 — 표본 오차 제거)
+- 노선밖(off>60)·표본 불연속 구간 제외, 3초 이내 다중 교차(채터)는 병합
+- 교차가 전혀 없는 값(도달만 못 함)은 최근접 지점 폴백(TOL 이내)
+- 진단 로그: `[검색] 1355m: 통과 3곳 — 201.0s, 327.2s, 334.5s`
+
+## 검증 (경로 1-1, lookahead 240)
+
+| 검색 | 통과 |
+|------|------|
+| 1355 | **3곳** (201.0/327.2/334.5s) — Enter 순환으로 모두 방문 가능 |
+| 1370 | 1곳 (336.9s) — 호버 1360 정체는 통과로 오인 안 함 |
+| 2000 | 1곳 (441.6s) |
+
+## 잔여 오차 안내
+
+- 착지 후 배지 ±1~2m 는 로그 해상도(10Hz=0.8m)·표시 반올림(1m)에 따른
+ 표시 한계 — 데이터 정밀도상 최선
+
+## 반영
+
+- 웹(index-D3EiCnLq.js, 07.15 14:04) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1413_검색-배지데이터-일치.md b/docs/history/2026-07-15_1413_검색-배지데이터-일치.md
new file mode 100644
index 0000000..2dee72d
--- /dev/null
+++ b/docs/history/2026-07-15_1413_검색-배지데이터-일치.md
@@ -0,0 +1,28 @@
+# 2026-07-15 측점 검색 최종 — 스테이션바(배지) 데이터에서 직접 탐지
+
+**소요 시간**: 12분
+**Context 사용량**: 작업분 input 200k / output 7k tokens · 누적 input 20900k / output 331k tokens
+
+## 제보/제안
+
+±2m 잔여 오차 지속 → 사용자 제안: "스테이션바에서 해당 값을 찾는 방식으로 하자".
+
+## 잔여 2m 의 원인
+
+배지는 djmd 프레임 동기(영상 시간축) 위치를 쓰는데, 검색은 CSV 시간축 교차 시각으로
+시크 — 교차상관 오프셋(dt≈0.33s)×비행속도 ≈ 2m 가 구조적으로 남음.
+
+## 수정 (2단계)
+
+1. **djmd dt 전파**: refineFramesWithDjmd 가 dtSec 반환 → geoStore.djmdDtSec →
+ 검색의 CSV↔영상 시간 변환에 반영
+2. **하이브리드 탐지** (사용자 제안 채택):
+ - **현재 세그먼트**: 배지가 쓰는 바로 그 데이터(viewedRef.viewChain)에서
+ 부호 교차 탐지 — 착지 시 배지값 == 검색값, **정의상 오차 0**
+ - **다른 세그먼트**: 전 구간 CSV 인덱스(dt 보정) 교차 — 현 세그 범위는 ①이 대체
+ - 순환·랩어라운드·3s 채터 병합·최근접 폴백 유지
+
+## 반영
+
+- 웹(index-BFtgZCK8.js, 07.15 14:13) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 1355 검색 → 배지 1+355 정확 착지, Enter 연타 시 통과 지점 순환
diff --git a/docs/history/2026-07-15_1416_레거시-창방식-검색-제거.md b/docs/history/2026-07-15_1416_레거시-창방식-검색-제거.md
new file mode 100644
index 0000000..3d9084d
--- /dev/null
+++ b/docs/history/2026-07-15_1416_레거시-창방식-검색-제거.md
@@ -0,0 +1,23 @@
+# 2026-07-15 레거시(±20m 창) 검색 방식 제거 — 교차 방식으로 완전 통일
+
+**소요 시간**: 5분
+**Context 사용량**: 작업분 input 80k / output 3k tokens · 누적 input 21100k / output 337k tokens
+
+## 확인/요청
+
+배지 데이터 검색 정상 동작 확인. 오차 있던 이전 방식 삭제 여부 질문 →
+폴백 경로에 ±20m '창' 방식이 남아 있었음.
+
+## 조치 — StationBar.tsx
+
+- 폴백 경로(전 구간 인덱스를 못 만드는 경우: 영상 길이 미측정 등)도
+ **배지 데이터(viewedRef.viewChain) 부호 교차 방식**으로 교체 —
+ 창 그룹핑·범위(MARGIN) 검사·창 내 최적점 선택 코드 전부 삭제
+- 이제 검색 경로는 두 가지뿐, 모두 교차 방식:
+ ① 전 구간(현 세그 배지 데이터 + 타 세그 CSV 인덱스(dt 보정))
+ ② 폴백(현 세그 배지 데이터만)
+- 교차 없으면 최근접(TOL 이내) → 그것도 없으면 '측점 없음' 안내(기존 UX 유지)
+
+## 반영
+
+- 웹(index-BTt0XCMH.js, 07.15 14:16) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1451_설정저장-환경설정이름.md b/docs/history/2026-07-15_1451_설정저장-환경설정이름.md
new file mode 100644
index 0000000..bd91249
--- /dev/null
+++ b/docs/history/2026-07-15_1451_설정저장-환경설정이름.md
@@ -0,0 +1,21 @@
+# 2026-07-15 카메라·디스플레이 PC 저장 — 환경설정 이름으로 파일명 생성
+
+**소요 시간**: 6분
+**Context 사용량**: 작업분 input 90k / output 3k tokens · 누적 input 21300k / output 341k tokens
+
+## 요청
+
+카메라/디스플레이 옵션 저장 시 해당 환경설정 이름을 만들어 저장.
+
+## 수정 — StationOverlay.tsx
+
+- 종전: 무조건 `camera.json` / `display.json` 으로 다운로드
+- 변경: **`<환경설정 이름>.camera.json` / `<환경설정 이름>.display.json`**
+ - 이름 우선순위: 폴더의 **CSV(비행로그) 파일명**(예: "제주 중산간도로 경로 1-1")
+ → route.json 노선명 → 영상 base → 'settings'
+ - 예: `제주 중산간도로 경로 1-1.camera.json` — 기존 폴더 파일들과 동일 규칙
+- 로더는 `*.camera.json` / `*.display.json` 패턴을 이미 인식 → 폴더에 넣으면 자동 적용
+
+## 반영
+
+- 웹(index-DIeltQJQ.js, 07.15 14:51) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1528_7000검색-6998-진단.md b/docs/history/2026-07-15_1528_7000검색-6998-진단.md
new file mode 100644
index 0000000..9b41ab0
--- /dev/null
+++ b/docs/history/2026-07-15_1528_7000검색-6998-진단.md
@@ -0,0 +1,18 @@
+# 2026-07-15 7000 검색 → 6+998 착지 — 데이터 확인(정상 동작)
+
+**소요 시간**: 3분
+**Context 사용량**: 작업분 input 40k / output 1k tokens · 누적 input 21400k / output 343k tokens
+
+## 제보
+
+7000 검색 시 6+998 로 이동.
+
+## 진단 (측점.kml 확인)
+
+- 노선 마지막 측점 = **6+998** (…6+800, 6+900, 6+998 — 마지막 구간 98m, 7+000 없음)
+- 7000 은 교차 지점이 없어 **최근접 폴백(±20m)** 이 6+998 로 이동시킨 것 — 정상
+- 6+998 검색 시 정확히 해당 지점, ±20m 밖 값은 '측점 없음' 안내
+
+## 조치
+
+- 코드 변경 없음. 필요 시 '최근접 N 으로 이동' 안내 표시 추가 가능(사용자 판단 대기)
diff --git a/docs/history/2026-07-15_1532_노선밖-부호표기.md b/docs/history/2026-07-15_1532_노선밖-부호표기.md
new file mode 100644
index 0000000..eaab65a
--- /dev/null
+++ b/docs/history/2026-07-15_1532_노선밖-부호표기.md
@@ -0,0 +1,23 @@
+# 2026-07-15 노선밖 배지 부호 표기 — 시점 이전 −, 종점 이후 +
+
+**소요 시간**: 8분
+**Context 사용량**: 작업분 input 110k / output 4k tokens · 누적 input 21600k / output 348k tokens
+
+## 요청
+
+1. 노선 구간 이후 = "노선밖 +값"(끝점 기준 증가), 시작 이전 = "노선밖 -값"(남은 거리 감소)
+2. 배지 폭이 부족하면 m 단위 생략
+
+## 구현 — StationBar.tsx
+
+- ViewedPoint 에 **offSide** 추가: 투영 체이니지가 시점(chMin+2 이내)에 클램프 = **−1**,
+ 종점(chMax−2 이상) = **+1**, 노선 중간 횡이탈 = 0
+- 배지 표기:
+ - 시점 이전: `노선밖 -294` (접근할수록 감소 — 남은 거리)
+ - 종점 이후: `노선밖 +120` (멀어질수록 증가 — 지나간 거리)
+ - 중간 횡이탈: `노선밖 390` (부호 없음, 기존)
+- **값 100 이상(3자리)이면 'm' 생략** — 배지 폭 확보 (99 이하는 `노선밖 -42m`)
+
+## 반영
+
+- 웹(index-DFjO-Oq9.js, 07.15 15:32) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1536_종점초과-카운트업.md b/docs/history/2026-07-15_1536_종점초과-카운트업.md
new file mode 100644
index 0000000..a167cfd
--- /dev/null
+++ b/docs/history/2026-07-15_1536_종점초과-카운트업.md
@@ -0,0 +1,28 @@
+# 2026-07-15 종점(6+998) 이후 배지 고정 — '노선밖 +000' 카운트업으로 교체
+
+**소요 시간**: 6분
+**Context 사용량**: 작업분 input 100k / output 4k tokens · 누적 input 21800k / output 352k tokens
+
+## 제보
+
+6+998 이후 배지 값 변화 없음(고정). 이때 '노선밖 +000' 형식으로 표시 원함
+(7+000 같은 측점값 표기가 아니라).
+
+## 원인
+
+시선값(viewChain)이 노선 끝(chMax=6998)에 **클램프** — lookahead 240 이면
+드론이 끝을 300m 지날 때까지 배지가 6+998 에 얼어붙음.
+
+## 수정 — StationBar.tsx
+
+- ViewedPoint 에 **beyondM**(종점 초과량) 추가:
+ - lookahead 활성: 클램프 전 시선값 − chMax (시선이 끝을 넘는 순간부터 0 → 증가)
+ - 미설정: 물리 투영이 종점 클램프 시 끝점까지 직선거리
+- 배지 우선순위: **beyondM > 0.5 → `노선밖 +NNN`**(3자리 0패딩, 단위 없음, 카운트업)
+ → 그 외 기존 표기(값/노선밖 ±)
+- 측점값 표기는 6+998 이 마지막 — 7+000 등 범위 밖 값은 표기되지 않음
+
+## 반영
+
+- 웹(index-BmnWJtb5.js, 07.15 15:36) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 종점 접근 → 6+99x → **노선밖 +000 → +001 → …** 증가
diff --git a/docs/history/2026-07-15_1540_끝마크-단수측점-표시.md b/docs/history/2026-07-15_1540_끝마크-단수측점-표시.md
new file mode 100644
index 0000000..8554037
--- /dev/null
+++ b/docs/history/2026-07-15_1540_끝마크-단수측점-표시.md
@@ -0,0 +1,22 @@
+# 2026-07-15 '끝' 마크 7+000 오표기 — 단수 측점(6+998) 그대로 표시
+
+**소요 시간**: 4분
+**Context 사용량**: 작업분 input 60k / output 2k tokens · 누적 input 22000k / output 354k tokens
+
+## 제보 (스크린샷)
+
+'끝' 마크의 측점값 라벨이 7+000 — 실제 마지막 측점은 6+998 (7+000 은 존재하지 않음).
+
+## 원인
+
+Timeline 의 측점값 포맷터(fmtKm)가 **10m 단위 반올림** — 6998 → 7000 으로 왜곡.
+
+## 수정 — Timeline.tsx fmtKm
+
+- 10m 배수 ±2m 이내는 10m 스냅 유지(GPS 잡음 정리), **그 외는 1m 그대로**
+ → 끝 측점 6+998 이 그대로 표시, 기존 10m 단위 마크(2+200 등)는 변화 없음
+
+## 반영
+
+- 웹(index-Di_zA62r.js, 07.15 15:40) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 종점부 '끝' 마크 라벨 = 6+998
diff --git a/docs/history/2026-07-15_1544_시점종점-표기.md b/docs/history/2026-07-15_1544_시점종점-표기.md
new file mode 100644
index 0000000..3d8adbe
--- /dev/null
+++ b/docs/history/2026-07-15_1544_시점종점-표기.md
@@ -0,0 +1,22 @@
+# 2026-07-15 구간 밖 배지 — '시점-NNN' / '종점+NNN' 표기
+
+**소요 시간**: 4분
+**Context 사용량**: 작업분 input 50k / output 2k tokens · 누적 input 22100k / output 356k tokens
+
+## 요청
+
+'노선밖 ±값' 대신 기준점을 명시: 종점 이후 = **종점+xxx**, 시점 이전 = **시점-xxx**.
+
+## 수정 — StationBar.tsx cursorText
+
+| 상태 | 표기 | 동작 |
+|------|------|------|
+| 시점 이전(접근) | `시점-294` → `시점-095` | 남은 거리 감소 |
+| 종점 이후 | `종점+000` → `종점+078` | 지나간 거리 증가(카운트업) |
+| 노선 중간 횡이탈 | `노선밖 390` | 기존 유지 |
+
+- 값은 3자리 0패딩, 단위 생략(배지 폭)
+
+## 반영
+
+- 웹(index-CGOwiWul.js, 07.15 15:44) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1549_시점카운트다운-연속화.md b/docs/history/2026-07-15_1549_시점카운트다운-연속화.md
new file mode 100644
index 0000000..d574fde
--- /dev/null
+++ b/docs/history/2026-07-15_1549_시점카운트다운-연속화.md
@@ -0,0 +1,24 @@
+# 2026-07-15 시점-062 → 0+000 건너뜀 — 카운트다운 연속화(-001 까지)
+
+**소요 시간**: 5분
+**Context 사용량**: 작업분 input 60k / output 2k tokens · 누적 input 22200k / output 358k tokens
+
+## 제보
+
+배지가 시점-062 에서 곧장 0+000 으로 전환 — -001 까지 내려가야 하지 않나.
+
+## 원인
+
+값 표시 전환은 이격 ≤ (주시거리+60m) 시점에 일어나는데, 시점- 표시값에
+**진입 판정 여유(OFF_ROUTE_M=60m)** 가 포함되어 전환 직전 값이 늘 ~62 —
+0 까지 못 내려가고 건너뛰는 것처럼 보임.
+
+## 수정 — StationBar.tsx cursorText
+
+- 시점-/종점+ 카운트 표시값에서 60m 여유를 차감 —
+ **전환점에서 정확히 0** 이 되도록: `시점-234 → … → -002 → -001 → 0+000`
+- 노선 중간 횡이탈('노선밖 NNN')은 실제 이격 그대로(변화 없음)
+
+## 반영
+
+- 웹(index-D02b3J1p.js, 07.15 15:49) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1554_종점초과-시작끝마크.md b/docs/history/2026-07-15_1554_종점초과-시작끝마크.md
new file mode 100644
index 0000000..80ad666
--- /dev/null
+++ b/docs/history/2026-07-15_1554_종점초과-시작끝마크.md
@@ -0,0 +1,27 @@
+# 2026-07-15 종점 이후 세그먼트 — 바 시작/끝 마크를 '종점+NNN' 표기로
+
+**소요 시간**: 6분
+**Context 사용량**: 작업분 input 90k / output 3k tokens · 누적 input 22400k / output 362k tokens
+
+## 제보 (스크린샷)
+
+종점 이후 구간 세그먼트에서 바 시작 마크가 6+998(클램프 값)로 표시,
+끝 마크는 아예 없음. '종점+136' 식으로 표시되어야 하지 않나.
+
+## 원인
+
+- 시작 마크: viewChain 이 노선 끝(6998)에 클램프된 값을 그대로 라벨링
+- 끝 마크: 시작과 같은 값(6998)이라 **100m 중복 제거 규칙에 걸려 생략**
+
+## 수정
+
+- StructMark 에 **kmText**(측점값 라벨 오버라이드) 추가, Timeline 이 우선 사용
+- appendEndpointStations: 해당 지점의 종점 초과량(beyondM)이 있으면
+ - 라벨 = **`종점+NNN`** (배지와 동일 표기)
+ - km = 끝값+초과량 — 시작/끝 마크가 서로 중복 제거에 안 걸림 → 둘 다 표시
+- 일반(노선 안) 세그먼트는 기존 표기 그대로
+
+## 반영
+
+- 웹(index-B886RUzX.js, 07.15 15:54) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 종점 이후 세그먼트 바 — 시작 '종점+084', 끝 '종점+300' 식으로 양끝 표시
diff --git a/docs/history/2026-07-15_1559_종점이후-단조증가.md b/docs/history/2026-07-15_1559_종점이후-단조증가.md
new file mode 100644
index 0000000..916f6d3
--- /dev/null
+++ b/docs/history/2026-07-15_1559_종점이후-단조증가.md
@@ -0,0 +1,27 @@
+# 2026-07-15 종점 이후 값 감소·끝 마크 6+998 — 단조 증가 카운트업으로 재정의
+
+**소요 시간**: 6분
+**Context 사용량**: 작업분 input 100k / output 4k tokens · 누적 input 22600k / output 366k tokens
+
+## 제보 (스크린샷: 시작 '종점+137', 중간 '끝 6+998', 배지 '종점+099')
+
+종점을 지나왔으니 스테이션은 계속 증가해야 하는데 값이 뒤섞임 —
+우측 끝에 '끝'과 '종점+xxx' 가 있어야 함.
+
+## 원인
+
+종점 이후 beyondM 을 시선 여유(effLook) 기반으로 계산 — 드론이 멀어질수록
+여유가 줄어 **+137 → 0 으로 감소**, 0 이 되는 지점이 '끝' 마크(6+998)로 찍히고
+그 뒤는 노선밖 분기로 넘어가는 뒤죽박죽 상태.
+
+## 수정 — StationBar.tsx (종점 이후 재정의)
+
+- 투영이 끝점에 클램프(offSide=+1)되면 pj.distM 은 횡이격이 아니라
+ **'종점을 지나온 거리'** → beyondM = 지나온 거리 + 주시거리
+ - **단조 증가** ✓, 통과 직전 시선값(chMax+주시거리)과 **연속** ✓
+ - viewOffM=0 으로 고정해 항상 '종점+' 표기(노선밖 분기 차단)
+- 결과: 배지 종점+240 → +307 → … 증가, 바 좌측 '시작 종점+240', 우측 '끝 종점+xxx(최종)'
+
+## 반영
+
+- 웹(index-uaQSa9Kc.js, 07.15 15:59) + 포터블(StationPlayer-Portable) 갱신
diff --git a/docs/history/2026-07-15_1601_종점마크-추가.md b/docs/history/2026-07-15_1601_종점마크-추가.md
new file mode 100644
index 0000000..3fc32f3
--- /dev/null
+++ b/docs/history/2026-07-15_1601_종점마크-추가.md
@@ -0,0 +1,21 @@
+# 2026-07-15 스테이션바 '종점' 마크 추가 — 노선 끝 통과 위치 표시
+
+**소요 시간**: 4분
+**Context 사용량**: 작업분 input 60k / output 2k tokens · 누적 input 22800k / output 369k tokens
+
+## 요청
+
+스테이션바에 시점/종점 위치 표시 필요.
+
+## 구현 — StationBar.tsx
+
+- 기존 '시점' 마크(0+000 통과 위치)와 대칭으로 **'종점' 마크** 추가:
+ 배지가 노선 끝 값(마지막 측점, 예: 6+998)에 도달하는 통과 위치에
+ 위 줄 = 6+998, 아래 줄 = '종점' 으로 표시
+- 이후 구간의 '종점+NNN' 카운트업이 어느 지점을 기준으로 하는지 바에서 바로 확인 가능
+- 노선 끝까지 가지 않는 세그먼트에는 표시되지 않음(통과 창 없음)
+
+## 반영
+
+- 웹(index-BAbkBP_n.js, 07.15 16:01) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 종점 통과 세그먼트 바 — [ …6+900 · 6+998(종점) · 종점+NNN(끝) ] 구조
diff --git a/docs/history/2026-07-15_1605_종점이후-1000m-마크.md b/docs/history/2026-07-15_1605_종점이후-1000m-마크.md
new file mode 100644
index 0000000..fee9d43
--- /dev/null
+++ b/docs/history/2026-07-15_1605_종점이후-1000m-마크.md
@@ -0,0 +1,20 @@
+# 2026-07-15 종점 이후 1000m 단위 마크 — 종점+1000 표시
+
+**소요 시간**: 4분
+**Context 사용량**: 작업분 input 60k / output 2k tokens · 누적 input 22900k / output 371k tokens
+
+## 요청
+
+종점+xxx 카운트업에서 1000 단위 지점이 표시되게(종점+1000).
+
+## 구현 — StationBar.tsx appendKmStations
+
+- 종점 이후 구간에서 **beyondM 이 1000, 2000… 을 가로지르는 프레임**(선형보간)에
+ 측점값 라벨 마크(`종점+1000` 등, kmText) 추가 — 1km 단위 측점 마크의 연장선
+- 기존 마크와 24px 이내 겹침 시 생략(기존 규칙 동일)
+- 배지·끝 마크의 종점+ 값은 1000 이상도 원래 그대로 표시됨(잘림 없음) — 확인
+
+## 반영
+
+- 웹(index-Cl9_J0Ro.js, 07.15 16:05) + 포터블(StationPlayer-Portable) 갱신
+- 확인: 초과 1km 이상 세그먼트(경로 1-3 끝) 바에 '종점+1000' 마크
diff --git a/docs/history/2026-07-15_1628_단계별-커밋-6건.md b/docs/history/2026-07-15_1628_단계별-커밋-6건.md
new file mode 100644
index 0000000..0b0d3d9
--- /dev/null
+++ b/docs/history/2026-07-15_1628_단계별-커밋-6건.md
@@ -0,0 +1,17 @@
+# 2026-07-15 단계별 커밋 6건 — 7/15 작업 전체
+
+**소요 시간**: 5분
+**Context 사용량**: 작업분 input 80k / output 3k tokens · 누적 input 23100k / output 377k tokens
+
+## 커밋 (논리 단위 6개, ca591ce 이후)
+
+| 커밋 | 내용 |
+|------|------|
+| f6a9b62 | StationPlayer 포터블 패키지(demo.ts·build-portable.sh·gitignore) |
+| 76a2ab4 | 브랜딩 — 타이틀 StationPlayer |
+| 87b66d9 | 데이터 파이프라인 — fullFrames·djmd dt·세그먼트 시크·곡선 평활 |
+| 0a7044d | 스테이션바 — 검색 재설계(교차·배지 일치)·시점/종점 표기 체계 |
+| 67cf646 | 오버레이 — 선형 입체형·자세 필터·설정 파일명 |
+| 6ebad54 | 문서 — 작업 기록 규칙 + 이력 37건 |
+
+- 작업 트리 클린(미커밋 0건). push 는 사용자 요청 시.