# InsuWiki TOC 더블클릭/어색한 움직임 수정

## 작업 개요
TOC(목차) 클릭 시 더블클릭해야 동작하고, 스크롤 움직임이 어색한 문제를 수정한다.

## 프로젝트 경로
- InsuWiki: `/home/jay/projects/insuwiki/`
- 빌드: `cd /home/jay/projects/insuwiki/nextapp && npx next build`

## 버그 원인 분석 (4가지)

### 버그 1: ID 불일치 (핵심 원인)
**TableOfContents.tsx** (77행)는 `lines.forEach((line, index))`의 `index`로 ID 생성:
```typescript
const id = `h-${level}-${index}-${text.toLowerCase().replace(...)}`;
```

**DocumentClient.tsx** (109~123행)는 `node?.position?.start?.line - 1`로 ID 생성:
```typescript
const lineIndex = (node?.position?.start?.line || 1) - 1;
const id = `h-${level}-${lineIndex}-${text...}`;
```

**문제**: react-markdown AST의 `position.start.line`과 단순 `split('\n').forEach`의 `index`가 일치하지 않음. 코드블록, 빈 줄 등에서 어긋남.

**수정 방향**:
- 양쪽 모두 **동일한 ID 생성 로직**을 사용해야 함
- **권장 방식**: text + level 기반 ID 생성 (line index에 의존하지 않음)
- 예: `h-${level}-${text.toLowerCase().replace(/[^\wㄱ-ㅎㅏ-ㅣ가-힣]/g, '-')}`
- 동일 텍스트 heading 중복 시 suffix 추가: `h-1-제목`, `h-1-제목-1`, `h-1-제목-2`
- list item도 동일하게: `list-${level}-${text...}`
- ⚠️ **TOC와 DocumentClient 양쪽 모두** 같은 함수/로직으로 ID를 생성해야 함

### 버그 2: scroll-margin-top 부족
현재 heading에 `scroll-mt-4` (16px) 적용되어 있으나, 고정 헤더 높이가 ~100px.
```tsx
// DocumentClient.tsx 128행 등
<h1 id={id} className="...scroll-mt-4...">
```

**수정**: `scroll-mt-4` → `scroll-mt-32` (128px)로 변경. h1, h2, h3 모두.

### 버그 3: scroll-padding-top 미설정
글로벌 CSS에 `scroll-padding-top` 없음.

**수정**: `nextapp/src/app/globals.css`에 추가:
```css
html {
  scroll-padding-top: 8rem; /* 128px — 고정 헤더 높이 커버 */
}
```

### 버그 4: scrollIntoView block 파라미터
`block: 'start'`가 뷰포트 최상단으로 이동 → 헤더 뒤에 숨김.
scroll-padding-top + scroll-mt-32 적용 후에는 이 문제가 자동 해결될 수 있으나,
만약 여전히 문제가 있으면 커스텀 스크롤 로직으로 교체:
```typescript
const headerOffset = 130;
const elementPosition = element.getBoundingClientRect().top;
const offsetPosition = elementPosition + window.pageYOffset - headerOffset;
window.scrollTo({ top: offsetPosition, behavior: 'smooth' });
```

## 수정 대상 파일

### 1. `nextapp/src/components/TableOfContents.tsx`
- ID 생성 로직 변경 (67~104행): line index 기반 → text+level 기반 (중복 처리 포함)
- list item ID도 동일하게 변경 (84~104행)

### 2. `nextapp/src/app/docs/[id]/DocumentClient.tsx`
- `generateId` 함수 (109~123행): TOC와 동일한 text+level 기반 ID 생성
- heading `scroll-mt-4` → `scroll-mt-32` 변경 (128, 132, 136행)
- list item ID 생성도 동일하게 변경

### 3. `nextapp/src/app/globals.css`
- `html { scroll-padding-top: 8rem; }` 추가

## ⚠️ 핵심 제약조건
- **ID 일관성이 가장 중요**: TOC에서 생성하는 ID와 DocumentClient에서 heading에 부여하는 ID가 **100% 동일**해야 함. 하나라도 어긋나면 클릭 네비게이션이 깨짐.
- 뷰 모드 기존 동작 (IntersectionObserver 기반 스크롤 하이라이트) 깨뜨리지 말 것
- 편집 모드 (isEditing) 동작도 유지
- 다른 페이지 (daily 문서 등)에 영향 없어야 함

## 테스트 체크리스트
- [ ] TOC 클릭 시 **한 번 클릭**으로 해당 heading으로 스크롤
- [ ] 스크롤 후 heading이 고정 헤더에 가려지지 않음
- [ ] 본문 스크롤 시 TOC 하이라이트가 정확히 현재 위치 반영
- [ ] 편집 모드에서도 TOC 클릭 → 에디터 스크롤 정상 동작
- [ ] 동일 텍스트의 heading이 여러 개 있어도 각각 올바른 위치로 이동
- [ ] TypeScript 에러 0건 (`npx next build` 또는 `npx tsc --noEmit`)
- [ ] Next.js 빌드 성공
