# CBMC LINK Foundation Specification v0.2

기준일: 2026-09-22  
권위 결정: `DECISIONS.md`  
기계 토큰 원본: `tokens.dtcg.json`

## 1. 적용 범위

- 주요 사용자: 기존 한국CBMC 회원
- 주요 행동: 기사 읽기
- Canonical 콘텐츠 경험: V2
- V3: 같은 콘텐츠를 소비하는 특집 Paper Reader
- 검색·필터·아카이브: MVP 제외
- 제목·요약: 하드 문자 수 제한과 강제 말줄임 없음
- 영문 kicker: 선택
- 공개 `/admin`: 제거

## 2. Token authority

```text
DESIGN.md             디자인 원칙과 사용 규칙
DECISIONS.md          승인·가역 결정
Tokens DTCG JSON      단일 기계 원본
Figma Variables       DTCG 소비본
CSS Custom Properties DTCG 소비본
```

변경 순서:

1. 결정이 필요한 변경은 `DECISIONS.md`에 기록한다.
2. 실제 값은 `tokens.dtcg.json`에서 변경한다.
3. Figma와 CSS를 같은 변경 묶음에서 갱신한다.
4. 값이 충돌하면 DTCG를 정본으로 간주한다.
5. 페이지와 컴포넌트에 임의 원시 값을 추가하지 않는다.

## 3. Responsive grid

### 3.1 Breakpoints

| 구간 | 범위 | Columns | Gap | Outer gutter | Container |
|---|---:|---:|---:|---:|---:|
| Mobile | 320–639px | 4 | 16px | 16px | fluid |
| Large mobile | 640–767px | 4 | 20px | 20px | fluid |
| Tablet | 768–1023px | 8 | 20px | 24px | max 960px |
| Desktop | 1024–1279px | 12 | 24px | 28px | max 1200px |
| Wide | 1280px+ | 12 | 24px | 32px | max 1320px |

모든 미디어 쿼리는 mobile-first로 작성한다. 브레이크포인트는 특정 기기 모델이 아니라 콘텐츠가 안정적으로 재배치되는 지점이다.

### 3.2 Grid anatomy

```css
.cbmc-grid {
  display: grid;
  grid-template-columns: repeat(var(--cbmc-grid-columns), minmax(0, 1fr));
  gap: var(--cbmc-grid-gap);
}
```

### 3.3 Standard spans

| Pattern | Mobile | Tablet | Desktop |
|---|---:|---:|---:|
| Featured story | 4/4 | 8/8 | 8/12 |
| Featured support | 4/4 | 4/8 | 4/12 |
| Standard story | 4/4 | 4/8 | 4/12 |
| Horizontal story | 4/4 | 8/8 | 6/12 |
| Article body | 4/4 | 6/8 | 7/12, max 720px |
| Article aside | 본문 아래 | 본문 아래 | 3/12 |
| Full-bleed media | 4/4 | 8/8 | 12/12 |

카드 높이는 콘텐츠에 따라 달라질 수 있다. 제목을 자르기 위해 고정 높이를 적용하지 않는다.

## 4. Spacing

### 4.1 Primitive scale

```text
0   0px
1   4px
2   8px
3  12px
4  16px
5  24px
6  32px
7  48px
8  64px
9  96px
10 128px
```

### 4.2 Semantic spacing

| Token | Value | Use |
|---|---:|---|
| inline-xs | 4px | 아이콘 내부·미세 정렬 |
| inline-sm | 8px | 아이콘과 라벨 |
| inline-md | 12px | 메타 항목 사이 |
| stack-xs | 8px | 라벨과 값 |
| stack-sm | 16px | 제목과 보조 정보 |
| stack-md | 24px | 카드 내부 주요 블록 |
| stack-lg | 32px | 컴포넌트 내부 큰 구획 |
| component | 24px | 기본 카드 padding |
| section-sm | 48px | 작은 섹션 |
| section-md | 64px | 기본 섹션 |
| section-lg | 96px | 주요 편집 섹션 |

### 4.3 Margin and padding rules

- 브라우저 기본 제목·문단 margin을 제거하고 Stack 규칙으로 재구성한다.
- 카드 기본 padding은 24px, 모바일 밀집형은 16px까지 허용한다.
- 버튼 높이는 최소 44px, 좌우 padding은 16–24px다.
- 기사 문단 간격은 16–24px 범위에서 본문 타입에 맞춘다.
- 본문 heading은 이전 문단과 48–64px, 다음 문단과 16–24px 간격을 둔다.
- 이미지와 캡션은 8–12px, 캡션과 다음 본문은 24–32px 간격을 둔다.
- 섹션 외곽 margin과 컴포넌트 내부 padding을 같은 요소에서 혼합하지 않는다.

## 5. Typography

### 5.1 Font roles

- Pretendard: 내비게이션, 본문, 메타데이터, 버튼, UI
- Noto Serif KR: Issue 커버, 장 도입, 편집 인용, 선택적 디스플레이 제목
- 시스템 폴백에서도 줄바꿈과 정보 계층이 유지되어야 한다.

### 5.2 Text styles

| Style | Responsive size | Family | Weight | Line height |
|---|---:|---|---:|---:|
| Display XL | 48–72px | Serif | 600 | 1.06 |
| Display LG | 40–56px | Serif | 600 | 1.10 |
| Display MD | 34–44px | Serif | 600 | 1.16 |
| Heading XL | 28–36px | Sans | 700 | 1.25 |
| Heading LG | 24–28px | Sans | 700 | 1.30 |
| Heading MD | 20–22px | Sans | 700 | 1.35 |
| Heading SM | 18px | Sans | 700 | 1.40 |
| Lead | 18–20px | Sans | 400 | 1.70 |
| Body LG | 18px | Sans | 400 | 1.75 |
| Body MD | 16px | Sans | 400 | 1.70 |
| Body SM | 14px | Sans | 400 | 1.60 |
| Meta | 13px | Sans | 600 | 1.45 |
| Caption | 12px | Sans | 400 | 1.55 |
| Label | 12px | Sans | 800 | 1.35 |
| Button | 14px | Sans | 700 | 1.40 |

정보성 텍스트는 12px 미만으로 내려가지 않는다. 본문은 16px 미만으로 내려가지 않는다.

### 5.3 Unlimited-title policy

CMS에는 제목 문자 수 제한을 두지 않는다.

```css
.cbmc-title {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  word-break: keep-all;
  overflow-wrap: anywhere;
}
```

- 기본 카드에 `line-clamp`와 ellipsis를 사용하지 않는다.
- 제목 영역과 카드 높이를 고정하지 않는다.
- 긴 제목이 이미지나 CTA 위에 겹치지 않아야 한다.
- 접근 가능한 전체 제목과 화면 제목은 동일해야 한다.
- 영문·URL처럼 긴 단위만 `overflow-wrap:anywhere`로 안전하게 나눈다.

## 6. Color roles

- Brand primitive를 컴포넌트에서 직접 사용하지 않고 semantic token을 사용한다.
- Cyan과 Orange 배경 위 흰색 일반 텍스트를 사용하지 않는다.
- visited 링크는 기본 링크와 구분하되 브랜드 CTA에는 visited 스타일을 적용하지 않는다.
- success, warning, error, info는 아이콘·라벨을 동반한다.
- disabled는 낮은 opacity만으로 표현하지 않고 조작 불가 상태를 semantic HTML로 제공한다.

## 7. Media

### 7.1 Ratios

| Token | Ratio | Use |
|---|---:|---|
| hero | 16:9 | Issue/Article 대표 이미지 |
| cover | 4:5 | Issue cover |
| card | 3:2 | StoryCard |
| portrait | 4:5 | 인물 중심 기사 |
| square | 1:1 | author·thumbnail |
| wide | 21:9 | full-bleed 특집 |

### 7.2 Missing image

- 이미지가 선택 정보이면 미디어 영역을 제거하고 텍스트 중심 레이아웃으로 전환한다.
- 이미지가 내용 이해에 필수이면 발행을 차단한다.
- 공개 화면에는 “이미지 준비 중”, 깨진 아이콘, 랜덤 대체 이미지를 표시하지 않는다.
- 편집 Preview에서만 중립 missing-media 상태를 표시한다.
- 이미지 권리 만료와 동의 미승인은 missing 상태와 동일하게 처리한다.

### 7.3 Loading and crop

- 첫 화면 핵심 이미지는 eager/high priority를 선택할 수 있다.
- 나머지 이미지는 lazy loading한다.
- CMS에 focal point를 저장하고 기본값은 center다.
- `srcset`과 `sizes`를 제공한다.
- alt, caption, credit는 서로 다른 필드다.
- AI 생성 여부와 권리·동의 상태는 콘텐츠 데이터로 관리한다.

## 8. Motion

```text
micro       120ms  아이콘·짧은 피드백
fast        160ms  hover·focus visual
standard    240ms  메뉴·시트
editorial   420ms  콘텐츠 전환
page-turn   780ms  V3 전용
```

- 자동 재생 모션은 사용하지 않는다.
- V3 전환 중 이전/다음 버튼은 입력 잠금 상태를 명확히 표시한다.
- `prefers-reduced-motion`에서는 페이지 회전을 즉시 교체 전환으로 바꾼다.
- 모션 없이도 현재 페이지와 진행 상태를 이해할 수 있어야 한다.

## 9. Elevation and layering

```text
z-base      0
z-sticky  100
z-overlay 400
z-modal   500
z-toast   600
```

- 일반 카드: border 우선, 필요한 경우 `shadow.card` 한 단계만 사용
- Sheet/Dialog: `shadow.overlay`
- V3 책: `shadow.book`
- 그림자로 클릭 가능성을 표현하지 않는다.

## 10. Verification

- 320/375/390/430/768/1024/1280px에서 검수한다.
- 모든 폭에서 가로 overflow가 없어야 한다.
- 긴 한국어 제목을 사용해 카드와 헤더를 검수한다.
- 200% 확대에서 주요 행동이 유지되어야 한다.
- DTCG, CSS, Figma 값이 일치해야 한다.
- 새로운 임의 간격과 색상값이 컴포넌트에 추가되지 않아야 한다.
