# POP 기술 스펙 **버전: v5 (CSS Grid 기반)** --- ## v5 핵심 규칙 ### 1. 그리드 시스템 | 모드 | 화면 너비 | 칸 수 | 대상 | |------|----------|-------|------| | mobile_portrait | ~599px | 4칸 | 4~6인치 | | mobile_landscape | 600~839px | 6칸 | 7인치 | | tablet_portrait | 840~1023px | 8칸 | 8~10인치 | | tablet_landscape | 1024px~ | 12칸 | 10~14인치 (기본) | ### 2. 위치 지정 ```typescript interface PopGridPosition { col: number; // 시작 열 (1부터) row: number; // 시작 행 (1부터) colSpan: number; // 열 크기 (1~12) rowSpan: number; // 행 크기 (1~) } ``` ### 3. 브레이크포인트 설정 ```typescript const GRID_BREAKPOINTS = { mobile_portrait: { columns: 4, rowHeight: 48, gap: 8, padding: 12 }, mobile_landscape: { columns: 6, rowHeight: 44, gap: 8, padding: 16 }, tablet_portrait: { columns: 8, rowHeight: 52, gap: 12, padding: 20 }, tablet_landscape: { columns: 12, rowHeight: 56, gap: 12, padding: 24 }, }; ``` --- ## 데이터 구조 ### v5 레이아웃 ```typescript interface PopLayoutDataV5 { version: "pop-5.0"; metadata: { screenId: number; createdAt: string; updatedAt: string; }; gridConfig: { defaultMode: GridMode; maxRows: number; }; components: PopComponentDefinitionV5[]; globalSettings: { backgroundColor: string; padding: number; }; } ``` ### v5 컴포넌트 ```typescript interface PopComponentDefinitionV5 { id: string; type: PopComponentType; // "pop-label" | "pop-button" | ... label: string; gridPosition: PopGridPosition; config: PopComponentConfig; visibility: Record; // 모드별 표시/숨김 modeOverrides?: Record; // 모드별 오버라이드 } ``` ### 컴포넌트 타입 ```typescript type PopComponentType = | "pop-label" // 텍스트 라벨 | "pop-button" // 버튼 | "pop-input" // 입력 필드 | "pop-select" // 선택 박스 | "pop-grid" // 데이터 그리드 | "pop-container"; // 컨테이너 ``` --- ## 크기 프리셋 ### 터치 요소 | 요소 | 일반 | 산업용 | |------|-----|-------| | 버튼 높이 | 48px | 60px | | 입력창 높이 | 48px | 56px | | 터치 영역 | 48px | 60px | ### 폰트 (clamp) | 용도 | 범위 | CSS | |------|-----|-----| | 본문 | 14-18px | `clamp(14px, 1.5vw, 18px)` | | 제목 | 18-28px | `clamp(18px, 2.5vw, 28px)` | ### 간격 | 이름 | 값 | 용도 | |------|---|-----| | sm | 8px | 요소 내부 | | md | 16px | 컴포넌트 간 | | lg | 24px | 섹션 간 | --- ## 반응형 원칙 ``` 누르는 것 → 고정 (48px) - 버튼, 터치 영역 읽는 것 → 범위 (clamp) - 텍스트 담는 것 → 칸 (colSpan) - 컨테이너 ``` --- ## 위치 변환 12칸 기준으로 설계 → 다른 모드에서 자동 변환 ```typescript // 12칸 → 4칸 변환 예시 const ratio = 4 / 12; // = 0.333 original: { col: 1, colSpan: 6 } // 12칸에서 절반 converted: { col: 1, colSpan: 2 } // 4칸에서 절반 ``` --- ## Troubleshooting ### 컴포넌트가 얇게 보임 - **증상**: rowSpan이 적용 안됨 - **원인**: gridTemplateRows 고정 px - **해결**: `1fr` 사용 ### 모드 전환 안 됨 - **증상**: 화면 크기 변경해도 레이아웃 유지 - **해결**: `detectGridMode()` 사용 ### 겹침 발생 - **증상**: 컴포넌트끼리 겹침 - **해결**: `resolveOverlaps()` 호출 --- ## 타입 가드 ```typescript // v5 레이아웃 판별 function isV5Layout(data: any): data is PopLayoutDataV5 { return data?.version === "pop-5.0"; } // 사용 예시 if (isV5Layout(savedData)) { setLayout(savedData); } else { setLayout(createEmptyPopLayoutV5()); } ``` --- *상세 아키텍처: [ARCHITECTURE.md](./ARCHITECTURE.md)* *파일 목록: [FILES.md](./FILES.md)*