Commit Graph
918 Commits
Author SHA1 Message Date
eomsangdon 4e1cdafab7 Merge remote-tracking branch 'origin/main_desktop_1' into sub_desktop_1 2026-09-04 19:17:59 +09:00
eomsangdonandClaude Opus 5 9019ca28ef feat(B03): 파일 카드 미리보기 확대 — 전폭·고정 높이, 라이다 점 그림·GeoTIFF 썸네일
- 미리보기를 카드 한 행 전폭·높이 120px 고정으로 키움.
- 라이다: 분류 통계를 훑는 그 길에 XY 를 성기게 주워 탑뷰 점 그림(상한 5천 점,
  파일 재열람 없음). 분류가 없는 파일은 앞 3청크만 봄.
- GeoTIFF: 오버뷰가 있을 때만 128px 흑백 썸네일(2~98 백분위 대비), 없으면 종전 범위 사각형.
- 부속 파일(.shx·.dbf·.cpg·.prj·.tfw)은 그림 대신 구분되는 값 표시 — 머리글만 읽는
  가벼운 분석기 추가.
- 값이 없는 완료 카드는 「보여 줄 값이 없음」 한 줄.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 19:17:00 +09:00
eomsangdonandClaude Opus 5 02bd45bf3c feat(B07): 표준 횡단면도 — 치수·측구 확대도·암반선 2단
빈 도각이던 표준 횡단면도를 실제 도면으로 만듦.

- 본 그림: B06 좌측 패널 모식도와 같은 배치를 실치수로 그림(1/50). 노폭·노견·
  측구 상단폭·노면 전폭에 치수선(눈금+치수값)을 붙이고, 절토·성토 경사비와
  횡단경사를 표기. 값은 B06 표준 횡단면 설정을 그대로 읽고 없으면 config 기본값.
- 측구 부분 확대도(1/10): 상단폭·저폭·깊이 치수 + 확대 축척 표기.
- 암반 2단 절토: 아래는 암반 경사(1:0.4), 위는 토사 경사(1:1), 갈리는 높이에
  암반선을 파선으로 긋고 각도를 함께 적음.
- 암 L형 측구·포장 횡단경사는 주기(※)로 적음 — 본 그림은 토사 기준.

곁들여: Router_Support 가 700줄을 넘어 재수출 import 를 한 문장으로 합쳐 681줄로
줄임(기능 변화 없음).

검증: 치수값이 STANDARD_CROSS_SECTION 과 일치(500·3000·500·900·4000), 확대도
900·300·300 + S=1/10, 2단 절토선 꺾임점 1개, 콘텐츠 358.2x172.6 mm ≤ A1 작도영역.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 19:09:06 +09:00
eomsangdonandClaude Opus 5 4e4bfa2354 feat(B02/B03/B04/B05): 계획노선 사용 범위 · 절단 여유 3m · 배수유역도 줌·측점 표기
- 계획노선 사용 범위: B02 등록에 시작·종료 누가거리 두 칸 추가, B01 수정 모달에서도
  변경. projects.route_start_m·route_end_m 신설(015_route_range.sql).
  load_design_route 가 범위 절단 → 서피스 트림 순서로 적용. 시작 >= 종료는 화면·서버
  양쪽에서 차단. 비우면 전 구간으로 종전과 같음.
- 서피스 절단 여유 기본값 30m → 3m (SURFACE_ROUTE_EDGE_TRIM_M).
- B04 지도·B05 배수유역도 줌 상한을 「화면 폭 20m」 기준으로 계산(고정 8배·16배 폐지).
  4배를 넘으면 배경 그림 흐림 보간 해제.
- 계획선 위 측점 눈금·번호 표기(측점번호+잔여거리). 관 마커와 겹치면 반대쪽으로 밀고,
  되꺾임 구간에서 라벨이 겹치면 건너뜀. 그리기 코드는 두 화면 공용.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 19:08:11 +09:00
eomsangdonandClaude Opus 5 18c174036b feat(B07): 계획평면도(라이다) — 지표면 음영기복 배경 1차 배치
빈 도각이던 라이다 계획평면도에 지표면 탑뷰 그림을 얹음.

- 확정 DTM 격자를 도곽 범위로 잘라 음영기복 PNG 를 만들고 Image 엔티티로 실음
  (북서 315도·고도 45도, 한 변 최대 1,600 px). 점구름 4,900만 점을 그대로
  그리지 않음.
- 어느 지표면을 쓸지는 1단계 확정값을 따름 — DrainageContext 에 surface_params
  를 실어 전달.
- 축척·도곽·장 나눔은 계획평면도와 같음(1/1,200) — 노선이 같은 자리에 섬.
- entities_bbox 가 꼭짓점 배열(points)을 세도록 고침. 세지 않으면 그림이 도곽
  계산에서 통째로 빠짐.

검증(용화_LAS): 콘텐츠 726.1x487.2 mm ≤ A1 작도영역, 그림 범위 안에 노선이
완전히 들어감, 음영기복 준비 0.4초·자료 214 KB. 능선·계곡이 눈으로 구분됨.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 19:00:38 +09:00
eomsangdonandClaude Opus 5 d662b0725d feat(B07): 용지도 — 등고선 배경 + 연속지적도·행정구역·범례
빈 도각이던 용지도를 실제 도면으로 만듦. 축척·도곽·장 나눔은 계획평면도와
같고(1/1,200) 배경도 같은 창구(map_background)를 씀.

- 연속지적도 필지 경계 + 지번(jibun) 표기. 작은 필지는 솎고(종이 6x3 mm 미만),
  도곽을 통째로 감싸는 임야 대필지는 도곽 중심에 지번만 적음 — 그러지 않으면
  노선이 대필지 안에 들어앉을 때 지번이 통째로 사라짐.
- 시군구·읍면동/리 경계를 파선·일점쇄선으로 구분. 지적·행정 경계는 도곽 범위로
  절취 — 자르지 않으면 산지 대필지 하나가 도면을 10 km 로 벌림(실측 8,368 mm).
- 도면용 색을 화면용과 따로 정함(등고선을 가장 옅게, 행정 경계를 굵고 진하게).
- 범례를 유역도 정보표 자리(오른쪽 칸 방위표 아래)에 넣음.
- _geometry_lines 가 MultiPolygon 을 편다 — 지적·행정구역이 그 형식임.

검증(용화_LAS): 콘텐츠 734.3x489.2 mm ≤ A1 작도영역, 지번 「산77-15임」이 지적
속성과 일치, 도면 목록에 landuse 가 실림. 이 노선은 임야 대필지 한 곳에 통째로
들어가 경계선이 도곽 안에 없음 — 자료대로의 정상 결과.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 18:51:23 +09:00
eomsangdonandClaude Opus 5 6dd0dec93a feat(B07): 계획평면도 3종 — 수치등고선 배경 위 노선·측점·구조물
빈 도각이던 계획평면도(지형·노선배치도·배치도)를 실제 도면으로 만듦.

- 배경 공용화: map_background() 한 창구로 도엽 등고선·세류선 읽기·좌표 환산·
  도곽 절취를 모음. 유역도와 계획평면도가 같은 것을 부르고, 환산 결과는
  파일 mtime 을 키로 캐시(_metric_lines_cached).
- 축척 1/1,200 고정(DRAWING_SCALE_PLAN) — 지식DB 「설계제원_총괄」 측량·도면
  기준. 횡단면도와 같은 원칙으로 줄이지 않고 안 들어가면 장을 나눔(plan_chunks,
  종단 측점 기준·경계 측점 1개 중복).
- 세 장이 같은 배경·같은 도곽 배치를 쓰고 주제만 다름. 측점 눈금은 종단 측점
  좌표로 찍고, 구조물은 pipe_points.json 정본을 읽어 마름모+이름으로 표기.
- 도면 목록·단건 조회에 kind="plan" 추가. 화면 목록은 id 접두어로 묶어 장이
  나뉘어도 한 그룹으로 보임.

검증(용화_LAS): 콘텐츠 734.3x489.2 mm ≤ A1 작도영역 739.2x499.2, 노선 실거리
630.1x214.2 m → 종이 525.12x178.46 mm(실측 0.83333 mm/m = 1/1,200 일치),
배경 등고선 180줄이 세 장 동일, 유역도 8.5초 → 계획평면도 1.3초(캐시 적중,
파일 재읽기 없음).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 18:38:43 +09:00
eomsangdonandClaude Opus 5 cc15a83f67 feat(B03~B08): 제목 줄 프로젝트 이름 + 계획노선 CSV 문구 정리
- 워크플로 상태 응답에 project_name 추가. 좌측 제목 패널 같은 행 오른쪽 끝에
  프로젝트 이름 표기(길면 말줄임, 전체는 툴팁). 이름표를 오버레이 쪽에 두어
  레이아웃을 직접 조립하는 B03 까지 여섯 화면이 한 곳으로 반영됨.
- fetchProjectWorkflowState 가 {status, workflow_state} 껍데기를 벗기도록 수정.
- 계획노선을 「업로드한 CSV」로 적은 주석을 「계획노선(정본)」으로 정리.
  업로드 판정이 .csv 개수만 세어 shapefile 을 막던 것도 .shp 포함으로 맞춤.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 18:26:17 +09:00
eomsangdonandClaude Opus 5 022908abed fix(B07): 횡단면도 칸 크기 통일 — 축척 1/100 유지
실측 결과 축척은 문제가 아니었음. 실거리 3 m 가 모든 단면에서 30.0 mm
(mm/m = 10.0 단일값). 뒤죽박죽으로 보인 원인은 칸 크기 — 한 장 안에서
폭 116~218 mm, 높이 29~178 mm 로 제각각이었음.

- 장별 완전 통일: 한 장 안 모든 칸을 그 장 최대 블록 크기로 통일(_grid_for).
  테두리는 build_cross_drawing(cell_frame=...) 로 칸에 맞춰 그림.
- 장 경계는 전체 최소 장수가 되도록 동적계획으로 선택(_sheet_breaks).
  앞에서부터 채우면 바로 뒤의 큰 단면이 칸을 키워 6칸짜리 장에 1개만
  실리는 낭비가 있었음.
- 축척은 지식DB 「설계제원_총괄」 기준 1/100 고정 — 어떤 경우에도 줄이지 않고
  안 들어가면 장을 나눔. 장수는 세트마다 달라짐(2026-09-04 사용자 확정).

검증(용화_LAS): 장 21개 전부 칸 크기 단일값, mm/m = 10 단일, 측점 65개
누락 0, 칸 밖 이탈 0.000 mm. 실서버 API 로도 동일 확인.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 18:12:54 +09:00
eomsangdonandClaude Opus 5 149920f3b5 feat(B01): 모달 바깥 클릭 닫기 + 회사 로고 기본 연결
- 모달 닫기 규칙 일원화 — 바깥 클릭·Esc·[취소] 모두 같은 경로(attachModalDismiss).
  고친 게 있으면 공용 showConfirmDialog 로 한 번 묻고, 없으면 바로 닫음.
  껍데기 세 곳(Modals·AssetPicker·TempModal) 모두 적용.
- 확인창 z-index 토큰 --z-confirm(1050) 신설 — 모달(1000) 뒤에 깔리던 문제 해소.
- 프로젝트 로고 칸에 회사 기본 연결 표시 — 프로젝트 값이 비면 회사 로고를
  「회사 기본 로고 · <자산명>」으로 보이되 저장값은 계속 null(연결 유지).
  [기본으로] 로 전용 로고 해제. 남의 회사 프로젝트에는 기본을 내밀지 않음.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 18:05:23 +09:00
eomsangdonandClaude Opus 5 92441eb8c9 fix(B05): 초기화 후 계획선이 원지반과 어긋나던 문제
브라우저 세션에 남은 계획선 편집 초안이 초기값 위에 다시 얹혀,
초기화 직후에는 멀쩡하다가 새로고침 한 번에 계획선이 측점에서 떨어짐
(실측: 측점 66개 중 25개가 10cm 초과, 최대 6.0m).

- [초기화]가 `b05-profile-alignment-draft:*` 세션 초안을 전부 제거
- 노선번호 없는 초안 키(`:none`) 폐지 — 어느 노선에나 되붙어 초기화로도
  떨어지지 않던 구멍

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 17:02:07 +09:00
eomsangdonandClaude Fable 5 738e09e7b1 feat(B05/B06): 구조물 선택 화면 전체 활성화 + 세션 상시 공유
- 바깥 선택이 폼에 실릴 때 접힌 좌측 패널 자동 펼침(onReveal 창구)
- 계곡 통과 시설 목록 행도 보이는 자리로 스크롤(rAF)
- 종단 테이블 구조물 구간 판정을 허용오차 비교로 교체 + 병합 측점 포함(강조 0건→6건)
- 구조물 선택 세션을 소비형에서 유지형으로 — B06 카드·목록·부재 선택도 같은 칸에 기록,
  양쪽 진입 시 복원(목록 지연 로드 대비 이중 복원)
- 조정창 닫기가 세션 선택까지 지우던 결함 수정(부재 해제와 측점 해제 분리)
- B05 페이지 700줄 유지 위해 상단측 세션 보관을 Page_Helpers로 이동(동작 불변)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-04 16:27:35 +09:00
eomsangdonandClaude Opus 5 ebef874e5f feat(B05): 부재키 일원화 — 세월교·BOX암거까지
- 이름표를 횡단도 이름으로 통일 — 세월교 유입·유출, BOX 좌·우, 본체는 body
- 조정창 하나가 여러 부재를 다루므로 `측이름:부재` 꼴 — 강조는 전체 키, 조정창은 앞칸만
- B06 갈래 태우기 신규 모듈 — 세월교/BOX/기슭막이 조정창으로 각각 보냄
- 저장 코리도 만료(BUILD_VERSION 91→92) — 재계산 비용 실측 차이 없음(5.1초 vs 4.7초)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 15:32:10 +09:00
eomsangdonandClaude Opus 5 2878ab9617 feat(B05): 3D 코리도 구조물 개별 선택
- 구조물 솔리드에 부재키(key) 부여 — B06과 같은 이름(inlet·outlet·extra{i}·bextra{i}·own·basin·pipe)
- 구조물 메쉬에 신원표(userData) — 이름 규칙은 그대로 유지
- 신규 모듈 두 개 — 3D 클릭·강조(Viewer_Structure_Pick), 좌측 패널 연결·B06 넘김(Structure_Pick_Session)
- 좌측 패널·종단에서 고른 것도 3D가 따라오도록 선택 동기화에 포트 추가
- B06 진입 시 세션 넘김값으로 그 측점 카드 선택·스크롤 + 기슭막이 조정창 열기
- 저장 코리도 만료(BUILD_VERSION 90→91) — 옛 저장본엔 부재키가 없음
- 뷰어 700줄 여유 — 검증용 요약을 Viewer_Debug로 분리(동작 불변)
- 검증 수단 — __corridorScene에 camera·project 추가

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 15:04:38 +09:00
eomsangdonandClaude Opus 5 e0e9d819c4 fix(A06): 인증 코드 단계가 새로고침에 사라지던 문제
휴대폰에서 코드를 보러 메일 앱에 다녀오면 브라우저가 탭을 버려 페이지가 다시 뜨는데,
단계 상태가 메모리에만 있어 이메일/비밀번호 화면으로 되돌아갔다(2026-09-04 사용자 보고).
받은 코드가 무용지물이 되고, 다시 로그인하면 새 코드가 발급돼 앞 코드는 폐기됐다.

- 코드를 보낸 시점에 이메일과 발송 시각만 sessionStorage 에 남기고(비밀번호는 저장 안 함),
  화면이 다시 뜨면 그 단계로 되돌린다 — 이메일 채움·잠금, 코드 입력칸 노출, 재발송 대기도
  발송 시각 기준으로 이어 센다.
- 서버 유효시간(5분)이 지난 값은 되살리지 않고 지운다. [이메일/비밀번호 다시 입력]·로그인
  성공 시에도 지운다. 세션 저장이 막힌 브라우저면 예전처럼 메모리로만 동작한다.
- 서버는 손대지 않았다 — 코드는 이미 DB 에 5분간 있고 검증에 이메일+코드만 쓴다.

검증(공용 브라우저 5174): 대기 상태를 심고 새로고침 → 코드 입력칸 노출·이메일 잠금 채움·
버튼 "인증하고 로그인"·"43초 후 재발송" 복원. [이메일/비밀번호 다시 입력] 누르면 대기 상태
삭제되고 비밀번호 화면 복귀. 발송 6분 전 값은 복원하지 않고 삭제.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 12:56:50 +09:00
eomsangdonandClaude Opus 5 5df79d2dff fix(B05): 저장 전 구조물 [삭제] 무동작 — 조각이 옛 배열을 고치던 문제
증상: 방금 [추가]한(아직 저장 전) 항목을 목록에서 고른 뒤 [삭제]를 눌러도 목록에
그대로 남음. 저장 뒤에는 정상.

원인: 700줄 분리(2026-09-04)로 `_Commit`·`_Events` 조각이 `structures` 배열을
**참조로** 받아 두는데, `setStructures()` 가 `structures = next.map(...)` 로 배열을
갈아끼움. 화면 목록은 새 배열로 그려지고 조각은 옛 배열을 splice 해 사라지지 않았음.
같은 이유로 `renderOptionFields()` 의 `optionInputs = []` 도 조각이 옛 칸 목록을
읽을 수 있어 저장값이 어긋날 자리였음.

조치: 두 배열 모두 **자체를 바꾸지 않고 내용만 갈아끼움**(`splice` · `length = 0`)하고
`const` 로 못박아 다시 갈아끼우지 못하게 함. 데이터 흐름은 그대로 — 삭제는 캐시만
바꾸고, 영구저장은 [저장]에서만 나감(5장 데이터 3층).

검증(시험 프로젝트 8cd2e635, 공용 브라우저 실조작):
- 저장 전: [추가] → 목록 12건 → 고르고 [삭제] → **11건으로 사라짐**, 서버는
  revision 4·0건 그대로(쓰기 없음), 세션 캐시도 빈 목록
- 저장 경로: [추가] → [저장] revision 5·1건 → [삭제](서버 5·1건 유지) → [저장]
  revision 6·0건
- 저장값: 옹벽 옵션 `height_m 2.5 · length_m 10 · before_m 5 · after_m 5`,
  기준 5+0(100m) → 구간 95~105m 정상
- 시험 프로젝트는 구조물 0건으로 되돌려 둠. `tsc --noEmit` 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 12:50:17 +09:00
eomsangdon 02fb075916 Merge remote-tracking branch 'origin/sub_laptop_1' into main_laptop_1 2026-09-04 11:38:36 +09:00
eomsangdonandClaude Opus 5 7500f37acd refactor(B05): 구조물 배치 패널 700줄 분리 (동작 불변)
B05_Profile_UI_Structures_Panel.ts 1024 -> 669줄. 조각 셋 모두 700줄 이하.
- _Structures_Panel_Types.ts(94줄) — GROUP_LABELS · PipeFacilityItem · StructuresSection ·
  StructuresCallbacks · 기본 구간 길이 상수. 패널이 다시 export 해 옛 임포트 경로 유지.
- _Structures_Panel_Commit.ts(312줄) — 폼 불러오기(구조물·계곡 통과 시설)와 [추가]/[수정]
  저장, 목록 알림. 검증 순서·분기·수치는 그대로이고 패널 클로저 값만 ctx 로 받음.
- _Structures_Panel_Events.ts(146줄) — 드롭다운·버튼·측점 입력 배선. 리스너 본문 그대로.
  StructuresEventContext 가 StructuresCommitContext 를 상속해 패널은 컨텍스트 하나만 만듦.
  가변 상태 4개(editingId · selectedPipeChainage · tempPipeChainage · positionConfirmed)의
  주인은 그대로 패널이고, 읽기 함수 + set* 로만 넘김.

검증: 분리 전 export 4개가 진입 파일에서 그대로 보임, tsc --noEmit 통과, prettier 적용,
tmp/tests 183 passed. 공용 브라우저(5174)에서 실제 조작으로 저장 경로까지 확인 —
C 사면안정/옹벽을 기준측점 5+0 에 [추가] -> 목록 반영, [저장] -> 서버 정본 2건(revision 0->1),
새로고침 후 목록에서 골라 [삭제] -> [저장] -> 서버 0건(revision 4). 시험 프로젝트는 원래
상태(구조물 0건)로 되돌려 둠.

참고(분리와 무관한 기존 동작): 방금 [추가]해 아직 저장 전인 항목은 structure_id 가 없어
[삭제]가 듣지 않음. 저장 뒤에는 정상 삭제됨. 분리 전 코드와 같은 분기라 이번 변경과 무관.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:37:46 +09:00
eomsangdon 0c02a8876f Merge remote-tracking branch 'origin/sub_laptop_1' into main_laptop_1 2026-09-04 11:34:14 +09:00
eomsangdonandClaude Opus 5 907cfc144b refactor(B07): 상세 설계 화면 700줄 초과 분리 — 좌측 패널
732줄 한 파일을 둘로 나눔 (동작 불변, 순수 이동).
- `B07_DesignDetail_UI_Page.ts` 517줄 — CAD 임베드·postMessage 교신·저장/확정 흐름
- `B07_DesignDetail_UI_Panels.ts` 234줄 — 도면 목록 12분류(`DRAWING_GROUPS`)와
  측점 설계 정보 카드. DOM 만 만들고 고르기 동작은 콜백으로 받음

검증: 공용 브라우저 B07 화면 실측 — 도면 목록 패널 1개·항목 54개(「설계 도면 49건」),
CAD iframe 1개 로드, 콘솔 오류 0. `tsc --noEmit` 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:33:51 +09:00
eomsangdonandClaude Opus 5 887444fe7c refactor(common_util): 횡단 설계 계산 700줄 초과 분리 — 단면 기하
728줄 한 파일을 둘로 나눔 (계산 불변, 순수 이동).
- `common_util_cross_design.ts` 405줄 — 표준단면 해석·설계선 조립·면적 산출
- `common_util_cross_design_geometry.ts` 333줄 — `SectionGeometry`(노면·측구·사면 설계고)
  와 그것만 쓰는 상수(행진 간격·최대 거리)·`sideRole`·`ResolvedGroup`

파이썬 짝 파일(`B06_Section_Engine_Design.py`)은 손대지 않음 — 미러 관계 유지.

검증: 공용 브라우저 B06 횡단 카드 실측과 서버 계산값 대조 — 측점 0에서
절토 화면 2.50㎡ / 서버 2.4985㎡, 성토 화면 1.85㎡ / 서버 1.8521㎡ 로 일치
(카드 273장 렌더, 콘솔 오류 0). `tsc --noEmit` 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:30:22 +09:00
eomsangdonandClaude Opus 5 f541ab4480 refactor(B03): 파일 입력 화면 700줄 초과 분리 — 판정 규칙·업로드 흐름
925줄 한 파일을 셋으로 나눔 (동작 불변).
- `B03_FileInput_UI_Page.ts` 692줄 — 화면 조립·카드 렌더·현황 표시
- `B03_FileInput_UI_Page_Flow.ts` 262줄 — 중단 세션 이어올리기·보관함 이관·청크 업로드·
  초기 계산 중 재잠금·서비스워커. 화면 상태는 `UploadFlowContext` 창구로만 받음
- `B03_FileInput_UI_Page_Rules.ts` 107줄 — 필수 카드 판정·파일 적합성·업로드 가능 판정·
  서버 파일의 카드 매핑 (상태를 가두지 않는 순수 함수)

검증: 공용 브라우저에서 새 프로젝트 만들어 노선 5종 실제 선택·업로드 —
카드 5장 선택 후 [파일 업로드] 비활성, [LAS 없이 설계] 켜면 활성(판정 규칙 정상),
업로드 후 4장 완료 표시(20초). 남은 `route_prj` 오류·400 은 지형 자료가 없어
분리 전에도 같던 것. `tsc --noEmit` 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:19:04 +09:00
eomsangdonandClaude Opus 5 41cfab22e9 refactor(ui_template): 공통 컴포넌트 700줄 초과 분리 — 차트·기본 스타일
917줄 한 파일을 넷으로 나눔 (동작 불변, 순수 이동).
- `ui_template_elements.ts` 363줄 — 버튼·입력·선택·카드·태그·토스트·확인창·셸
- `ui_template_elements_styles.ts` 369줄 — `injectBaseStyles()` 와 규칙 문자열
- `ui_template_elements_chart.ts` 185줄 — 공통 라인 차트
- `ui_template_elements_base.ts` 33줄 — 요소 생성 헬퍼 `el` (셋이 함께 써 순환 방지)

본체가 `export *` 로 다시 내보내 호출부의 import 경로는 불변.

검증: 분리 전 `export` 25개 전부 유지(+`el` 공개 1개 추가), `tsc --noEmit` 통과,
tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:19:04 +09:00
eomsangdonandClaude Opus 5 37fc63ba4c refactor(B04): 지표면 3D 뷰어 700줄 분리 (동작 불변)
B04_PreProcess_UI_TerrainViewer.ts 958 -> 698줄.
- _TerrainViewer_Chrome.ts(209줄) — 상태줄·표시 토글·등고선 간격 폼·뷰포트·축척·컴파스·
  표고 범례·로딩 서클 DOM 생성. 만드는 순서·클래스·인라인 스타일 그대로.
- _TerrainViewer_Contours.ts(189줄) — 등고선 적재(fetch·라인 생성·라벨·범례). 뷰어
  클로저가 쥐던 값만 ctx 로 받고 본문 수치·로직은 그대로. 호출부는 얇은 래퍼로 유지.

검증: export 2개(SurfaceTerrainViewer · createSurfaceTerrainViewer) 분리 전과 동일,
tsc --noEmit 통과, prettier 적용. 공용 브라우저(5174) B04 실조작 — 뷰어 2개·캔버스 2개
렌더, 상태줄 CLASSIFICATION · DTM · 등고선 1m, 등고 라벨 40개(상한), 범례 940m/760m,
등고선 토글을 끄면 라벨 0 → 켜면 40 복귀, 간격 5m 적용 시 상태가 5m 로 바뀌고
1m 로 되돌리면 원상 복귀.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:18:22 +09:00
eomsangdonandClaude Opus 5 9c141ac717 refactor(B05): 종단 패널 콜백 타입 분리 (726 -> 688줄)
RouteProfilePanelCallbacks 인터페이스만 B05_Profile_UI_Profile_Panel_Types.ts(52줄)로
그대로 옮기고, 진입 파일에서 다시 export 해 옛 임포트 경로(_Profile_Render 등)를 유지.
런타임 코드는 한 줄도 건드리지 않음.

검증: 분리 전 export 2개(RouteProfilePanelCallbacks · createRouteProfilePanel)가 진입
파일에서 그대로 보임, tsc --noEmit 통과, prettier 유지. 공용 브라우저(5174) 실조작 —
종단 패널 측점 66개·표 12행·줌 버튼 7개·유역 11개 정상, 측점 선택 후 방향키 862.99->863.09m,
Ctrl+Z 로 862.99m 복귀.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 11:12:05 +09:00
eomsangdonandClaude Opus 5 fbbedc7230 fix(700줄분리): 진입 파일에서 분리 전 이름 전부 재노출
laptop-sub 가 쓴 AST 대조법(분리 전 커밋의 모듈 정의 이름 ↔ 지금 모듈 `dir()`)을
내 4개에도 적용해 누락 26개를 찾아 되살림.

- `B03_FileInput_Router.py` 누락 17 → 0 (헬퍼 13 + 청크 엔드포인트 4)
- `B03_FileInput_Router_Temp.py` 누락 5 → 0 (`_total_chunks` + 청크 엔드포인트 4)
- `B07_DesignDetail_Router_Support.py` 누락 3 → 0 (`_BASIN_MAX_DISTANCE_M` ·
  `_clip_segment` · `_geometry_lines`)
- `config/config_system.py` 누락 1 → 0 (`_SCS_SOIL` — `import *` 가 밑줄 이름을 안 실음)

검증: 네 파일 모두 **정의 이름 누락 0**(28·19·36·246개 대조), 라우트 수 유지
(B03 7 · temp 9+attach 1 · B07 7), ruff check 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:53:37 +09:00
eomsangdonandClaude Opus 5 322a2f1f13 fix(B04): 분리로 사라진 이름을 진입 라우터에서 재노출
700줄 분리 때 _Router_Progress · _Router_Status 로 옮겨 진입 파일에서 안 보이게 된
PROGRESS_FILE_RELATIVE · _progress_file_path · read_surface_progress ·
get_wf1_analysis_status · get_surface_model_preview 를 as 재노출로 되살림.
옛 경로를 보던 호출부·테스트가 그대로 동작하게 하려는 것(laptop-main 의 B07 사례와 같은 사고 예방).

검증: 분리 전 모듈 정의 이름을 전수 대조해 누락 0개(_Router 16개 · _Router_Watershed 30개),
라우트 9개 유지, ruff check/format 통과, tmp/tests 183 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:51:39 +09:00
eomsangdonandClaude Opus 5 0b16a1240c fix(B07): 분리한 유역도 이름을 진입 파일에서 재노출
`_Support_Basin.py` 로 옮긴 뒤 `CONTOUR_FILE` · `STREAM_FILE` · `_basins_crs` ·
`_geojson_payload` · `_geojson_features` · `_too_far_from_route` 가 진입 파일에서
사라져, 옛 이름을 참조하던 다른 워크트리의 테스트가 ImportError·AttributeError 로
깨졌음(laptop-sub 보고 2건). 프로덕션 호출부는 새 모듈을 직접 봐 동작에는 영향 없었음.

`as` 형태로 다시 내보내 분리 전 이름 14개가 진입 파일에서 모두 보이게 함.

검증: 진입 파일 속성 14개 전부 확인, 라우트 7개 유지, ruff check 통과,
tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:49:06 +09:00
eomsangdon cea803b281 Merge remote-tracking branch 'origin/sub_laptop_1' into main_laptop_1 2026-09-04 10:34:30 +09:00
eomsangdonandClaude Opus 5 472a6f7849 refactor(config): 시스템 설정 700줄 초과 분리 — 지형·설계 파라미터
937줄 한 파일을 셋으로 나눔 (값·이름 불변).
- `config_system.py` 255줄 — 서버·로깅·DB·업로드·저장소·인증·CORS
- `config_system_terrain.py` 186줄 — 5장·5-2장 지형 분석·지표면 모델 파라미터
- `config_system_design.py` 520줄 — 5-3장~5-6장 경로·유역·종횡단·계획선 파라미터

본체가 두 조각을 `import *` 로 다시 내보내므로 기존
`from config.config_system import …` 호출부는 그대로임.

검증: 분리 전 원본과 대조해 **공개 상수 243개 전부 값 동일**(사라진 것은 설계 모듈
내부에서만 쓰는 `_SCS_SOIL` 하나 — 밑줄 시작이라 원래도 외부 참조 없음),
백엔드 재시작 후 기동 정상·주요 API 6종 200, ruff check 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:34:18 +09:00
eomsangdonandClaude Opus 5 8be60007e7 refactor(B07): 도면 조립 지원 700줄 초과 분리 — 유역도·입출력
808줄 한 파일을 셋으로 나눔 (동작 불변, 순수 이동).
- `B07_DesignDetail_Router_Support.py` 532줄 — 도면 목록·장 배치·확정 저장·재계산
- `B07_DesignDetail_Router_Support_Basin.py` 279줄 — 유역도 배경(GeoJSON·좌표 환산·도곽 클리핑)
- `B07_DesignDetail_Router_Support_Io.py` 88줄 — 원본 JSON·매니페스트 입출력, 측점 대응표

떼어낸 `watershed_source`·`clip_line_to_box` 는 본체에서 `as` 로 다시 내보내
호출부(`B07_DesignDetail_Router.py`)의 import 경로가 그대로임.

검증: 라우트 7개 그대로, 공용 브라우저 `design-drawings` 200 · `frame-template` 200,
ruff check 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:34:18 +09:00
eomsangdonandClaude Opus 5 3ec6527cc2 refactor(B03): 임시 보관함 라우터 700줄 초과 분리 — 청크·보조
749줄 한 파일을 셋으로 나눔 (동작 불변, 순수 이동).
- `B03_FileInput_Router_Temp.py` 478줄 — 묶음 생성·목록·삭제·파일 업로드·프로젝트 연결
- `B03_FileInput_Router_Temp_Chunks.py` 294줄 — 세션·조각·진행·마무리 (prefix 없는
  APIRouter 를 본체가 `include_router` 로 붙여 `/api/temp-uploads/...` 경로 불변)
- `B03_FileInput_Router_Temp_Support.py` 46줄 — 조각 수·묶음 폴더·상태 갱신 (순환 방지)

검증: 라우트 10개(temp 9 + attach 1) 경로·메서드 동일, 공용 브라우저에서 실제 청크 흐름
create 200 → upload-sessions 200 → chunks 200 → finalize 200 → delete 200,
ruff check 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:34:01 +09:00
eomsangdonandClaude Opus 5 07e6441d7f refactor(B04): 배수유역 라우터 700줄 분리 (동작 불변)
B04_PreProcess_Router_Watershed.py 714줄 -> 518줄. 산출물 기록(.npz·스테이지 기하)과
응답 좌표 변환 헬퍼 9개를 B04_PreProcess_Router_Watershed_Output.py(225줄)로 그대로 옮김.
공개 심볼 router · get_primary_region · CONTOUR_FILE · STREAM_FILE 유지
(main.py · B03_FileInput_Service_Chain · B07_DesignDetail_Router_Support 참조).

검증: ruff check 전체 통과·format 적용, tmp/tests 183 passed, 백엔드 재시작 후
경로 2개 유지, /drainage/rainfall 200, /drainage/primary-region 200(schema_version 3),
B05 화면 유역 11개·측점 66개 정상, 옮긴 순수 헬퍼 6개 직접 호출 스모크 통과.
분석 재실행(쓰기 경로)은 작업본 산출물을 덮어써서 돌리지 않음.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:17:34 +09:00
eomsangdonandClaude Opus 5 c4aac6f299 refactor(B03): 파일 입력 라우터 700줄 초과 분리 — 보조·청크 업로드
872줄 한 파일을 셋으로 나눔 (동작 불변, 순수 분리).
- `B03_FileInput_Router.py` 309줄 — 파일 업로드·현황·워크플로 엔드포인트
- `B03_FileInput_Router_Chunks.py` 390줄 — 세션 생성·조각 전송·마무리·진행 조회
  (자체 APIRouter 를 본체가 `include_router` 로 붙여 경로 문자열 불변)
- `B03_FileInput_Router_Helpers.py` 268줄 — 필수 파일 판정·중복 지문 판별·단계 기록·알림

검증: 라우트 7개 경로·메서드 동일(`GET upload-overview|upload-status|workflow-state`,
`POST files|upload-sessions|chunks|finalize`), 공용 브라우저에서 노선 5종 실제 업로드 성공
(shp metadata preview_path 포함), ruff check 통과, tmp/tests 378 passed

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:15:19 +09:00
eomsangdonandClaude Opus 5 03a193af70 refactor(B04): 지표면 라우터 700줄 분리 (경로·응답 불변)
B04_PreProcess_Router.py 718줄 -> 493줄.
- B04_PreProcess_Router_Status.py(221줄) — 분석 상태 조회·모델 프리뷰 엔드포인트.
  prefix 없이 만들고 본체가 include_router 로 실어 붙임(본체 prefix 를 그대로 상속).
- B04_PreProcess_Router_Progress.py(47줄) — progress.json 읽기·쓰기 헬퍼.
  본체와 상태 라우터가 함께 써야 해 순환 임포트를 피하려고 별도 모듈로 둠.
  본체는 write_surface_progress 를 계속 재노출(B03_FileInput_Service_WF1 이 참조).

검증: ruff check/format 통과. 라우터 경로 9개가 분리 전과 동일(중복 prefix 없음 확인).
백엔드 재시작(8001) 후 openapi 에 surface 경로 12개 그대로, 브라우저에서
/surface/status 200(진행률 100·모델 3), /surface/models 200,
/surface/models/415/preview 200 model/gltf-binary 7,946,756바이트.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:13:36 +09:00
eomsangdonandClaude Opus 5 2975ea09c7 refactor(B04): 전처리 스타일시트 700줄 분리 (동작 불변)
B04_PreProcess_UI_Style.css 870줄 -> 565줄. 하단 2D 지도·도구줄·시트 툴바 규칙을
B04_PreProcess_UI_Style_Map.css(312줄)로 값·순서 그대로 옮김. 진입 TS 에서 본체 다음에
불러 캐스케이드 순서 유지.

검증: 두 파일을 다시 이으면 원본과 **경계 빈 줄 1개 외 완전 동일**(텍스트 대조).
tsc --noEmit 통과. 공용 브라우저(5174) B04 화면 실측 — 좌측 폼 flex/gap 16px,
.b04-map flex column gap 12px(896x828), 헤더·컨트롤 정상, 3D 서피스·2D 지도 렌더 정상.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:09:10 +09:00
eomsangdonandClaude Opus 5 370ff30738 refactor(B05): 종단 스타일시트 700줄 분리 (동작 불변)
B05_Profile_UI_Style.css 1379줄 -> 592줄. 규칙을 값·순서 그대로 옮겨 두 조각으로 나눔.
- B05_Profile_UI_Style_Table.css (515줄) — 도면 테이블·값 열 오버레이·우클릭 메뉴·
  계획고 편집 버튼·줌 조작구
- B05_Profile_UI_Style_Drainage.css (289줄) — 배수유역도 패널
진입 TS 두 곳(B05_Profile_UI_Page.ts, A00_Common/b_structures_section.ts)에서
본체 다음에 순서대로 불러 캐스케이드 순서 유지.

검증: tsc --noEmit 통과, prettier 서식 유지, 공용 브라우저(5174)에서 계산 스타일 확인
(표 이름표 sticky 78px, 구배 블록 absolute, 편집 버튼 21x17, 줌 22x22, 배수유역 flex).
종단 패널 캡처가 분리 전과 **바이트 단위로 동일**(md5 ee6bc8b52adb).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 10:07:17 +09:00
eomsangdonandClaude Opus 5 3b89ba4fac fix(B05): 종단표 구배 3행 상시 표기
구배 L·H·S 는 값 열을 접는 규칙에서 제외 — 구조물로 좁게 갈라진 구간도 값을 적음
(2026-09-04 사용자 확정, 「각도 행」 = 구배 3행). 그 구간만 고를 때까지 값을 감추던
옛 규칙(2026-08-03)을 걷어내고, 구조물 구간 표시·하이라이트·툴팁은 유지.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 09:31:27 +09:00
eomsangdon 997e94dddb Merge remote-tracking branch 'origin/main_laptop_1' into sub_laptop_1 2026-09-04 07:31:20 +09:00
eomsangdonandClaude Opus 5 782139732b fix(B05): 종단표 구조물 열 상시 표기·직선화 자리 곡선값 제거
- 구조물 측점 판정을 문자열 키에서 누가거리 허용 오차 0.1m 비교로 바꿈 —
  구조물 목록(85.59)과 계획선 측점(85.595)이 셋째 자리에서 어긋나 구조물 열을
  못 알아보고 값을 그대로 펼쳐 이웃 값과 겹쳐 보였음. 이제 고른 때만 값 열 오버레이로 보임
- 대수차 1e-4% 미만이면 직선으로 보고 곡선 L·R 을 빈 칸으로 둠 — 직선화하면
  대수차가 0 이 되어 R = L ÷ |대수차| 가 수억 m 로 발산했음 (표·값 열 오버레이 공통)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 07:31:08 +09:00
eomsangdon ec85e42b3e Merge remote-tracking branch 'origin/sub_laptop_1' into main_laptop_1 2026-09-04 07:24:03 +09:00
eomsangdonandClaude Opus 5 2d49c59342 feat(B05): 종단도 줌·Y 표시 표고창 조작구
- B05_Profile_UI_Profile_Zoom.ts 신규 — 배율 상태(가로 폭 배수·세로 배율·창 중심)와
  버튼 7개(+ − ⇕+ ⇕− ▲ ▼ ⤢). 자리는 요약줄 오른쪽 끝(그래프 우측 상단),
  설명은 툴팁, 클릭은 stopPropagation 으로 측점 선택에 번지지 않게 함
- X 줌은 폭 배수 — computeProfileLayout 에 zoomX 를 넘겨 측점 간격·폭맞춤 폭에 함께 곱함.
  그래프·테이블·편집 버튼층·구조물 레인이 같은 매핑을 쓰므로 넷의 x 정렬이 유지됨
- Y 는 표시 표고창(제안 A) — createLongitudinalProfile 에 elevationOffsetRatio 인자 추가,
  창 높이 = 전범위 ÷ 배율, ▲▼ 가 창 높이의 10%씩 중심 이동. 세로 스크롤 없음
- 지반선·계획선·절성토 음영을 플롯 사각형 clipPath 안으로 옮김 — 배율을 올려도
  선이 축·측점 라벨 위로 흘러나오지 않음 (B06 은 배율 1·오프셋 0 이라 표시 불변)
- 요약줄 렌더러에 trailing 자리 추가, .b05-profile__zoom* CSS 추가

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 07:23:34 +09:00
eomsangdonandClaude Opus 5 ecb3bcb9ce feat(B05): 종단도 방향키 연속 이동·이력 한 덩어리·쉬프트 상하
- 방향키 청취를 패널 루트에서 window 로 옮김 — 그래프 클릭 뒤 포커스가 body 에
  남아 방향키가 아무 반응이 없던 결함 수정 (패널이 화면에 없으면 무시)
- 길게 누르면 편집 버튼과 같은 속도로 연속 이동 (0.5초 뒤 0.1초 간격, OS 키 반복 무시)
- 이력에 pause()/resume() 추가 — 연속 이동 전체가 되돌리기 1회로 원위치.
  구조물 이동은 서버 재계산이 뒤따르므로 키를 뗀 뒤 700ms 뒤 기록
- pause() 에서도 관 목록을 세션에 흘려 되돌리기 기준을 조작 전 값으로 고정
- 좌우 연속 이동 중에는 처음 잡은 구조물 측점·자체 누가거리 카운터 사용 —
  관 측점 id 가 누가거리 기반이라 한 번 옮기면 선택이 풀려 한 칸만 움직이던 결함 수정
- ProfileTools.nudge(delta) 노출 — [쉬프트] 모드의 상·하 방향키가 도구 ▲▼ 와
  같은 경로(onShift)로 구간 평행이동

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 07:11:41 +09:00
eomsangdonandClaude Opus 5 98db2731b9 style(B03): 미리보기 범위 사각형 옅은 점선 처리
어두운 테마에서 채움 35%가 회색 덩어리로 보여 범위인지 안 읽힘 — 채움 12% +
점선 테두리로 「범위」임이 드러나게 함(실측 스크린샷 확인).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 07:06:32 +09:00
eomsangdonandClaude Opus 5 ab16361125 feat(B03): 업로드 자료 카드 그래픽 미리보기 — 범위 사각형·노선 형상·범위 대조
- 계획노선 shapefile 분석에 `preview_path`(200점 안팎 솎은 좌표열) 추가 — 이미
  메모리에 있는 정점을 쓰므로 파일 재열람 0회(솎기 0.136ms)
- LAS·GeoTIFF 는 사용자 확정대로 **bbox 사각형만** (점구름·래스터 렌더 안 함)
- `upload-overview` 응답에 분석 `metadata` 동봉 — 재접속해도 같은 그림
- 카드에 SVG 미리보기 렌더(신규 `B03_FileInput_UI_Preview.ts`), 값 없으면 미표시
- 계획노선 카드는 지형 자료 범위와 대조 — 벗어나면 경고색·안내, 좌표계가 다르면
  대조 생략(재투영 안 함). shapefile 은 좌표계가 없어 같은 세트 `.prj` 값을 씀

검증: 공용 브라우저 실측(노선 선 121점·범위 안/밖·좌표계 상이 3갈래),
tmp/tests/test_b03_preview_path.py 2건, tsc --noEmit 통과

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 07:04:33 +09:00
eomsangdonandClaude Opus 5 af85dea714 feat(ui_template): 진행단계 패널 끌어 옮기기·열림 방향 자동 전환
- 헤더를 잡아 끌어 자리 이동, 이동 범위는 상단 헤더 아래 화면 안으로 clamp
- 아래 공간 부족 시 `is-flip-up` 으로 헤더 위로 펼침(바닥 기준 정렬)
- 자리는 sessionStorage 세션 캐시에만 보관, 접힘/펴짐 뒤 방향 재판정
- threshold 4px 초과 시에만 포인터 캡처 — pointerdown 캡처는 click 대상을
  제목에서 헤더로 바꿔 접기/펴기 토글을 죽임(실측)
- 이동은 window 에서 청취 — B07 CAD iframe 위로 커서가 나가도 안 끊김

검증: 공용 브라우저 B03·B05·B07 실측(이동 오차 1px 이내, clamp·뒤집힘·토글 정상),
tsc --noEmit 통과

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-04 06:37:57 +09:00
eomsangdon d1accfea0d Merge remote-tracking branch 'origin/sub_laptop_1' into main_laptop_1 2026-09-04 05:29:27 +09:00
eomsangdon 7c62896c14 Merge remote-tracking branch 'origin/main_laptop_1' into sub_laptop_1 2026-09-03 21:10:11 +09:00
eomsangdon ee5fa16f6a Merge remote-tracking branch 'origin/sub_laptop_1' into main_laptop_1 2026-09-03 21:10:10 +09:00
eomsangdonandClaude Opus 5 db91109b5a fix(B03): 입력 버튼 3칸 1:1:1·높이 통일, 토글 아래 빈 자리 제거
사용자 지시(2026-09-03).

- 고르는 자리를 flex 에서 **격자 3칸**으로 바꿈. flex 로는 내용 폭이 배분에 섞여
  288·254·288 로 어긋났고 버튼 높이도 달랐다. 격자는 칸을 먼저 나누므로 1:1:1 이고,
  칸을 꽉 채우게 해 세 칸 높이가 같아진다(실측 277×47 셋 다 동일).
- 빈 오류 줄이 자리를 잡아 토글 아래가 비어 보이던 것 제거 — 글자가 있을 때만 자리를
  차지한다(`:empty { display: none }`, min-height·마진 제거).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 21:06:48 +09:00