286 lines
19 KiB
Markdown
286 lines
19 KiB
Markdown
# reference-method.md — 레퍼런스 해체와 합성
|
|
|
|
레퍼런스를 **원리로 분해**해서 **다른 결과물로 재조합**하는 절차다.
|
|
|
|
**원칙 한 줄**: 레퍼런스를 언어로 설명했을 때 그 설명이 여러 결과물로 구현될 수 있으면 원리다. 하나로만 이어지면 표현이다. **원리만 가져간다.**
|
|
|
|
| 가져간다 (원리) | 안 가져간다 (표현) |
|
|
|---|---|
|
|
| 그리드의 비대칭 관계 (관찰 예: 5:7) | 섹션 배치 그대로 |
|
|
| 타입 단계의 관계 (관찰 예: 1.333) | 폰트 조합 그대로 |
|
|
| 색의 역할 배분 (관찰 예: 60/30/10) | 색상값 |
|
|
| 여백의 상대 리듬 (관찰 예: 섹션 120 / 요소 24) | 섹션 순서 |
|
|
| 모션의 의도 (스크롤=시선 유도) | 애니메이션 시퀀스 |
|
|
|
|
표의 숫자는 특정 사례를 설명하는 관찰 예시일 뿐, 다른 프로젝트에 그대로 적용할 법칙이 아니다. 관계가 현재 콘텐츠·언어·과업·렌더에서도 작동하는지 확인한 뒤 값을 정한다.
|
|
|
|
---
|
|
|
|
## 1. 레퍼런스 슬롯으로 해체하기
|
|
|
|
R1·R2·R3은 구조·톤·디테일을 섞어 복제하지 않기 위한 **검토 슬롯**이다. 세 슬롯을 채웠다는 사실은 합성의 품질을 보장하지 않는다. 프로젝트에 필요한 슬롯만 채우고, 비운 슬롯은 이유와 대체 근거를 기록한다.
|
|
|
|
| 슬롯 | 가져올 것 | 어디서 |
|
|
|---|---|---|
|
|
| **R1 · 구조** | 그리드, 섹션 순서, 정보 위계, 여백 리듬 | 같은 업종·같은 목적 |
|
|
| **R2 · 톤** | 색 역할, 타입 페어링, 형태 언어, 질감 | 다른 업종 또는 웹 이외 매체를 우선 검토 |
|
|
| **R3 · 디테일** | 모션 1개, 호버 1개, 전환 1개 | Codrops / Eyecandy / Design Spells |
|
|
|
|
R2가 R1과 같은 업종이어도 브리프가 요구하는 브랜드·시장·제작 조건에 맞으면 가능하다. 같은 업종의 평균을 무비판적으로 복제하지 않도록, 가져오는 원칙·관찰·결정·검증을 분리해 기록한다.
|
|
|
|
### 목표 시장은 네 번째 레퍼런스가 아니라 경계 조건이다
|
|
|
|
목표 시장을 적지 않으면 검색 결과 상위의 서구 사례가 무의식적으로 기본값이 된다. 먼저 한 줄로 잠근다.
|
|
|
|
```md
|
|
시장: 국가/도시/생활권 · 주 사용 기기 · 단위/통화 · 문의/구매 관습 · 피해야 할 외래 문법
|
|
```
|
|
|
|
- R1은 같은 업종·목적에 더해 **같은 목표 시장을 우선**한다. 구조에 단위·용어·연락 방식이 묻어 있기 때문이다.
|
|
- R2는 다른 업종 또는 같은 문화권의 다른 매체를 먼저 검토하되, 같은 업종이 더 적합하면 그 조건과 이유를 기록한다.
|
|
- 다른 문화권 R3는 기법만 가져온다. 카피·색·상징·사진 연출까지 번지면 경계 조건 위반이다.
|
|
- 같은 시장 자료가 부족하면 빈칸을 숨기지 말고, 어떤 관습을 공식 문서·현지 서비스로 별도 검증했는지 적는다.
|
|
|
|
목표 시장 적합성은 국기·전통 문양 같은 표식이 아니다. 통화 단위, 면적 표기, 동네 탐색 축, 정보 순서, 촬영 조도, CTA 동사처럼 **사용자가 실제로 행동하는 문법**이다.
|
|
|
|
**충돌 해결 순위**
|
|
1. 가독성·접근성이 언제나 이긴다. R2의 톤이 대비를 깨면 톤을 조정한다.
|
|
2. R1 구조가 R3 모션을 이긴다. 모션 때문에 구조를 바꾸지 않는다.
|
|
3. 브리프가 모든 레퍼런스를 이긴다. 충돌하면 레퍼런스를 버린다.
|
|
4. 한 축에 여러 출처가 영향을 주면 출처별 관찰과 최종 결정을 분리한다. 출처가 섞였다는 사실이 실패는 아니며, 근거 없이 절충한 경우만 다시 검토한다.
|
|
|
|
---
|
|
|
|
## 2. 6축 해체 프레임워크
|
|
|
|
각 레퍼런스를 6축으로 뜯는다. **형용사만으로 끝내지 않는다.** 실측값, 관찰 가능한 규칙, 적용 조건을 함께 적고 실제 렌더에서 결정이 맞는지 확인한다. 아래 숫자 범위는 보편 판정이 아니라 관찰을 시작할 때 쓸 수 있는 예시다.
|
|
|
|
**R3 예외**: R3는 사이트가 아니라 기법이다. 축 5(모션 언어) 하나만 채우고 나머지는 비운다.
|
|
대신 R3에는 **구현 제약**(브라우저 지원, 성능 비용, 보간 조건)을 반드시 적는다.
|
|
|
|
### 축 1 — 레이아웃 그리드
|
|
컬럼 수·거터 / 콘텐츠 최대폭과 뷰포트 비 / 대칭·비대칭(비율) / 그리드를 깨는 요소 / 실제 본문 줄 길이와 읽기 맥락
|
|
→ *"무엇을 정렬시키고 무엇을 일부러 어긋나게 했나?"*
|
|
|
|
### 축 2 — 타입 스케일
|
|
실제 사용된 크기 목록 / 그 사이 비율 / 단계 수 / 패밀리 수 / 굵기 대비 / line-height / letter-spacing
|
|
→ *"최대 글자와 본문의 비는 몇 배이고, 이 화면의 과업·언어·읽기 폭에서 위계가 보이는가?"*
|
|
|
|
### 축 3 — 컬러 역할
|
|
색상값이 아니라 **역할**로 적는다. surface 단계 수 / text 위계 / accent 면적과 역할 / border 존재 여부 / state 색 분리 여부
|
|
→ *"강조색을 지워도 정보 위계와 조작 상태를 이해할 수 있는가?"*
|
|
|
|
### 축 4 — 여백 리듬
|
|
기본 단위 / 섹션 간 수직 여백 / 요소 간 : 섹션 간 비율 / 여백 값 종류 / 좌우 패딩
|
|
→ *"가장 큰 빈 공간은 어디이고 왜 거기인가?"*
|
|
|
|
### 축 5 — 모션 언어
|
|
트리거(로드/스크롤/호버/커서) / duration / easing / 정보 전달인가 장식인가 / reduced-motion 대응
|
|
→ *"모션을 전부 끄면 작동하는가?"* (작동해야 정상)
|
|
|
|
**어떤 CSS 속성 또는 스크롤 로직을 쓰는지 반드시 적어라.** `transform`·`opacity`는 저비용 기본이지만 다른 선택은 금지가 아니다. `stroke-dashoffset`·`height`·`clip-path`·`filter` 같은 기법은 1단계부터 비용 측정, 입력 간섭, 감소 모션, 지원 범위와 예산을 함께 기록해 `motion.md`의 계약으로 검증한다.
|
|
|
|
### 축 6 — 시선 흐름
|
|
첫 진입점 / 2·3번째 / 비즈니스 우선순위와 일치 여부 / Z·F·수직 낙하 중 무엇인가 / CTA가 경로 위에 있나
|
|
|
|
**회색조 위계 서술** (에이전트용 squint test 대체) — 자기가 만들 화면에 대해 문장으로 쓴다:
|
|
> 색을 전부 제거했을 때 가장 강한 덩어리는 ___, 두 번째는 ___, 세 번째는 ___.
|
|
> 이 순서는 비즈니스 우선순위 [1위 ___ / 2위 ___ / 3위 ___]와 일치한다 / 하지 않는다.
|
|
|
|
일치하지 않으면 크기·굵기·대비·공간·순서를 검토한다. 색만으로 해결하지 않고, 필요한 경우 색 역할도 프로젝트 토큰 안에서 조정한다.
|
|
|
|
---
|
|
|
|
## 3. 실전 절차 체크리스트
|
|
|
|
- [ ] **1. 브리프를 한 문장으로 압축한다.** `[대상]이 [행동]하게. 느낌은 [형용사 2개].` 이 문장 없이 수집을 시작하지 않는다.
|
|
- [ ] **1-b. 목표 시장 경계 조건을 쓴다.** 국가/생활권·기기·단위/통화·행동 관습·금지할 외래 문법. R1이 같은 시장인지 표시한다.
|
|
- [ ] **2. galleries.md 라우팅 표에서 필요한 레퍼런스 슬롯을 정한다.** R2의 업종·매체 선택 조건을 기록한다.
|
|
- [ ] **3. 사용한 각 슬롯에서 원본 사이트 URL을 확보한다.** 하위 페이지가 필요하면 **인덱스에서 `href`를 뽑아라. slug를 추측하지 마라** — 추측한 URL은 404가 난다.
|
|
- [ ] **3-b. 그 URL이 정본인지 검증한다.** 사용자가 특정 제품·브랜드를 지목했고 후보 도메인이 여럿이면 필수다. **HTTP 200은 살아있다는 뜻이 아니다.**
|
|
- `curl -sS -o /dev/null -w "%{url_effective} %{http_code} %{size_download}\n" -L <url>` 로 **최종 URL·본문 크기**를 본다. 본문이 **1KB 미만이면 파킹 도메인을 의심하라** — 전형적 파킹 페이지는 `/lander` 로 보내는 JS 한 줄뿐이다.
|
|
- 후보들의 본문이 **바이트 단위로 동일**하면 공통 응답일 수 있다. 파킹이라고 단정하지 말고 제목·본문 정체성·소유자·정본 링크를 확인한다.
|
|
- 정본 판정 근거는 **콘텐츠 안에서** 찾아라: 저장소 링크, 설치 명령에 적힌 패키지·스킬 이름, 소유자 계정, 문서 제목이 로컬 파일과 일치하는지.
|
|
- [ ] **4. 사용한 원본 사이트를 §4 템플릿으로 WebFetch 한다.** 갤러리 페이지가 아니라 원본이다. → 축 6·정보 위계·카피 톤을 얻는다.
|
|
- [ ] **5. §5로 computed style을 추출한다.** → 축 1·2·3·4를 얻는다. **이 단계를 건너뛰면 6축의 4개가 빈칸으로 남는다.**
|
|
- [ ] **6. 텍스트 소스로 폰트 이름·무료 대체를 확정한다.** (Typewolf / Happy Hues / Eyecandy — galleries.md §3)
|
|
- [ ] **7. 6축 해체 시트를 작성한다.** 실측값 또는 관찰 가능한 규칙과 적용 조건을 쓴다. 6축에 안 들어가는 관측은 `6축 밖의 관측`에 적는다.
|
|
- [ ] **8. 결정한다.** 출처 ID → 원칙/조건 → 관찰 → 결정 → 검증 계획을 프로젝트 `design.md` 또는 evidence 기록에 남긴다.
|
|
- [ ] **9. 필요한 변형과 이유를 적는다.** 변형 개수는 슬롯 수와 무관하다.
|
|
- [ ] **10. antipatterns.md를 훑고 발견한 후보를 프로젝트 계약과 실제 렌더로 평가한다.**
|
|
|
|
---
|
|
|
|
## 4. WebFetch 프롬프트 템플릿 (그대로 복사해서 쓴다)
|
|
|
|
### 4-A. 원본 사이트 구조 분석 — 가장 자주 쓴다
|
|
|
|
> 이 페이지의 구조를 분석해줘. 다음을 순서대로 답해라.
|
|
> 1. 상단부터 순서대로 섹션 목록. 각 섹션의 역할을 한 단어로 붙여라.
|
|
> 2. h1의 정확한 문장, 그리고 h2 전체 목록.
|
|
> 3. CTA 문구 전부와 각각이 페이지 어디에 있는지.
|
|
> 4. 내비게이션 항목 목록.
|
|
> 5. 이 페이지가 방문자에게 시키려는 우선 행동과, 있으면 보조 행동. 각각이 어디서 어떤 위계로 제시되는지.
|
|
> 6. 카피의 톤 — 평균 문장 길이, 1인칭/2인칭 사용, 전문용어 밀도.
|
|
> 7. 숫자나 지표가 사용된 위치와 그 값.
|
|
> 추측하지 말고 페이지에 실제로 있는 것만 답해라. 없으면 "없음"이라고 써라.
|
|
|
|
### 4-B. 폰트 확인 (Typewolf 등)
|
|
|
|
> 이 페이지에서 언급된 폰트 이름을 전부 나열해라. 각각에 대해 헤드라인용인지 본문용인지, 유료인지 무료인지, 제시된 무료 대체 폰트가 있으면 그 이름까지 적어라. 페이지에 없는 정보는 지어내지 마라.
|
|
|
|
### 4-C. 모션 기법 확인 (Eyecandy · Codrops)
|
|
|
|
> 이 페이지에서 설명하는 애니메이션 기법의 이름, 그 기법이 시각적으로 무엇을 하는지, 구현에 쓰인 CSS 속성이나 JS 라이브러리를 나열해라. 코드 예시가 있으면 핵심 부분을 그대로 옮겨라.
|
|
|
|
### 4-D. 디자인 시스템 토큰 확보 (DesignSystems.one · 공개 시스템 문서)
|
|
|
|
> 이 문서에서 다음을 추출해라. 값이 명시된 것만 적고 없으면 "미공개"라고 써라.
|
|
> 1. 컬러 토큰 이름과 값 (전체 스케일)
|
|
> 2. 타입 스케일 — 크기 목록, line-height, 굵기
|
|
> 3. 여백 스케일 — 기본 단위와 전체 단계
|
|
> 4. border-radius 값 목록
|
|
> 5. 그림자 정의
|
|
> 6. 모션 duration과 easing
|
|
|
|
### 4-E. 리디자인 — 현행 사이트 감사
|
|
|
|
> 이 페이지를 감사해줘. 다음을 답해라.
|
|
> 1. 섹션 순서와 각 섹션이 실제로 전달하는 정보
|
|
> 2. 정보 위계상 가장 강조된 것과, 비즈니스적으로 가장 중요해 보이는 것 — 둘이 일치하는가
|
|
> 3. 카피에서 구체적 사실(숫자, 고유명사, 조건)이 들어간 문장과 그렇지 않은 문장의 비율
|
|
> 4. 내비게이션 구조와 항목 수
|
|
> 5. 페이지에서 명백히 불필요하거나 중복인 섹션
|
|
> 추측하지 말고 페이지에 있는 것만 답해라.
|
|
|
|
---
|
|
|
|
## 5. computed style 추출 (축 1·2·3·4를 얻는 유일한 방법)
|
|
|
|
WebFetch는 마크다운으로 변환하면서 CSS를 버린다. **그리드·타입스케일·컬러·여백은 WebFetch로 절대 나오지 않는다.**
|
|
브라우저 도구(Chrome DevTools MCP / Playwright)로 원본 사이트를 열고 아래를 실행한다.
|
|
|
|
```js
|
|
() => {
|
|
const cs = (el, p) => getComputedStyle(el).getPropertyValue(p);
|
|
const vis = el => { const r = el.getBoundingClientRect(); return r.width > 0 && r.height > 0; };
|
|
const all = [...document.querySelectorAll('body *')].filter(vis);
|
|
const textEls = all.filter(el => [...el.childNodes].some(n => n.nodeType === 3 && n.textContent.trim().length > 1));
|
|
const tally = a => { const m={}; a.forEach(v=>{m[v]=(m[v]||0)+1;}); return Object.entries(m).sort((x,y)=>y[1]-x[1]).slice(0,12); };
|
|
const h1 = document.querySelector('h1');
|
|
const p = [...document.querySelectorAll('p')].filter(vis).find(el => el.innerText.trim().length > 200);
|
|
return {
|
|
// 반드시 첫 줄에 둔다. 페이지가 실행 중 이탈하면 엉뚱한 사이트의 값이 돌아온다.
|
|
url: location.href,
|
|
title: document.title,
|
|
viewport: innerWidth + 'x' + innerHeight,
|
|
heading: h1 && { size: cs(h1,'font-size'), lh: cs(h1,'line-height'), ls: cs(h1,'letter-spacing'),
|
|
weight: cs(h1,'font-weight'), family: cs(h1,'font-family').split(',')[0] },
|
|
body: p && { size: cs(p,'font-size'), lh: cs(p,'line-height'), color: cs(p,'color'),
|
|
family: cs(p,'font-family').split(',')[0], widthPx: Math.round(p.getBoundingClientRect().width) },
|
|
fontSizes: tally(textEls.map(el => cs(el,'font-size'))),
|
|
families: tally(textEls.map(el => cs(el,'font-family').split(',')[0].replace(/["']/g,''))),
|
|
textColors: tally(textEls.map(el => cs(el,'color'))),
|
|
backgrounds:tally(all.map(el => cs(el,'background-color')).filter(c => c !== 'rgba(0, 0, 0, 0)')),
|
|
radii: tally(all.map(el => cs(el,'border-radius')).filter(r => r !== '0px')),
|
|
widths: tally(all.filter(el => el.getBoundingClientRect().width > 500)
|
|
.map(el => Math.round(el.getBoundingClientRect().width) + 'px')),
|
|
sectionPadding: [...new Set([...document.querySelectorAll('section, main > div')].filter(vis).slice(0,20)
|
|
.map(el => cs(el,'padding-top') + ' / ' + cs(el,'padding-bottom')))]
|
|
};
|
|
}
|
|
```
|
|
|
|
**결과 읽는 법**
|
|
|
|
> **먼저 `url` 을 봐라. 열려고 한 사이트가 아니면 나머지 값은 전부 버려라.**
|
|
> 페이지가 실행 중 이탈하거나 리다이렉트되면 스크립트는 **다른 사이트의 값을 조용히 반환한다.**
|
|
> 실측에서 2회 연속 발생했다. 이건 실패가 아니라 **오염**이다 — 숫자가 6축 시트에 들어가고,
|
|
> 3단계 토큰의 근거가 되고, `design.md` 또는 프로젝트 evidence 기록에 출처 ID → 원칙/조건 → 관찰 → 결정 → 검증으로 남는다. `evidence-ledger.md`는 기록 형식을 안내하는 정본이다.
|
|
|
|
- `fontSizes` 상위 항목 = 타입 스케일 후보다. 실제 본문 요소와 화면 위계를 같이 확인한다.
|
|
- `textColors` 상위 항목 = 텍스트 위계 후보다. 색 수가 아니라 역할·대비·실제 렌더를 본다.
|
|
- `backgrounds` 최다값 = 지배 배경 후보다. 채도·등장 횟수만으로 강조 역할이나 면적을 단정하지 않는다.
|
|
- `radii` 종류 수 = 형태 어휘를 살필 출발점이다. 수가 아니라 토큰 역할과 화면 밀도로 평가한다.
|
|
- `widths` 최다값 = 컨테이너 폭. `body.widthPx` = 텍스트 컬럼 폭.
|
|
|
|
브라우저 도구를 못 쓰는 환경이면 **6축 중 4개가 빈칸이라는 사실을 산출물에 명시**하고 넘어간다. 채운 척하지 마라.
|
|
|
|
---
|
|
|
|
## 6. 하지 말아야 할 것
|
|
|
|
- **갤러리 홈페이지만 fetch하고 "레퍼런스를 봤다"고 말하기.** 갤러리 홈은 카드 이미지뿐이라 정보가 0이다. **반드시 원본 사이트를 연다.**
|
|
- 레퍼런스 이름만 나열하고 넘어가기. 6축 수치가 없으면 참고한 게 아니다.
|
|
- **WebFetch만 하고 6축을 채웠다고 하기.** WebFetch는 축 6과 카피 톤만 준다. 나머지는 §5가 필요하다.
|
|
- 하위 페이지 URL의 slug를 추측하기. 인덱스에서 `href`를 뽑아라.
|
|
- R1·R2·R3를 같은 갤러리에서 고르기.
|
|
- 6축 시트에 "세련됐다", "깔끔하다" 같은 형용사 적기.
|
|
|
|
---
|
|
|
|
## 6. 산출물 형식 (필수)
|
|
|
|
레퍼런스 조사 단계는 **아래 블록을 출력하기 전까지 완료되지 않는다.** 다음 단계로 넘어가지 마라.
|
|
|
|
```markdown
|
|
## 브리프
|
|
[대상]이 [행동]하게. 느낌은 [형용사 2개].
|
|
|
|
## 목표 시장
|
|
- 지역/생활권:
|
|
- 기기/단위/통화:
|
|
- 행동 관습:
|
|
- 금지할 외래 문법:
|
|
|
|
## R1 · 구조 — <출처 ID> <이름> <원본 URL>
|
|
- 가져올 축: 그리드, 여백 리듬
|
|
- 원칙/조건:
|
|
- 관찰:
|
|
- 결정:
|
|
- 검증 계획:
|
|
- 그리드: 관찰한 최대폭 / 비대칭 또는 대칭 관계 / 거터
|
|
- 여백: 관찰한 단위 / 섹션 간 / 요소 간 / 관계
|
|
- 6축 밖의 관측: (있으면) 카피 규범, 증거 제시 방식, 반복 노출 규칙 등
|
|
- 변형: 최대폭을 1120으로 축소 — 본문 한 줄이 국문 40자를 넘었기 때문
|
|
|
|
## R2 · 톤 — <출처 ID> <이름> <원본 URL> [업종/매체 선택 조건:]
|
|
- 가져올 축: 컬러 역할, 타입 스케일
|
|
- 원칙/조건:
|
|
- 관찰:
|
|
- 결정:
|
|
- 검증 계획:
|
|
- 컬러: 관찰한 역할 단계와 면적 관계
|
|
- 타입: 관찰한 서체 역할·단계 관계·최대/본문 비율
|
|
- 6축 밖의 관측: (있으면) 신뢰를 만드는 방식, 제품을 보여주는 방식
|
|
- 변형: 비율을 1.25로 조정 — 정보량이 많아 중간 단계가 필요
|
|
|
|
## R3 · 디테일 — <출처 ID> <이름> <출처 URL>
|
|
- 가져올 축: 모션 언어 (R3는 이 축만 채운다)
|
|
- 원칙/조건:
|
|
- 관찰:
|
|
- 결정:
|
|
- 검증 계획:
|
|
- 모션: 스크롤 진입 시 8px 상승 + 페이드, 320ms, ease-out
|
|
- 구현 제약: 브라우저 지원 / JS 비용 / 보간 조건
|
|
- 변형: 280ms로 단축 — 페이지가 길어 반복 노출이 잦음
|
|
|
|
## 회색조 위계
|
|
가장 강한 덩어리는 ___, 두 번째 ___, 세 번째 ___.
|
|
비즈니스 우선순위 [1 ___ / 2 ___ / 3 ___]와 일치한다.
|
|
|
|
## 안 할 것
|
|
- (antipatterns.md에서 이 브리프에 특히 위험한 후보와 그 이유)
|
|
```
|
|
|
|
**검증 조건** — 사용한 슬롯마다 다음을 채운다.
|
|
- 사용한 슬롯은 **원본 사이트 URL**이 있다 (갤러리 URL 아님)
|
|
- 목표 시장 경계 조건이 있고 R1의 시장 일치 여부가 적혀 있다
|
|
- R2의 업종 또는 매체 선택 조건이 적혀 있다
|
|
- 각 슬롯에 **가져올 축**, 출처 ID → 원칙/조건 → 관찰 → 결정 → 검증 계획이 명시되어 있다
|
|
- 필요한 변형과 그 이유가 적혀 있다
|
|
- 6축은 실측값 또는 관찰 가능한 규칙으로 채웠고, §5를 못 실행했다면 어느 축이 빈칸인지 명시했다
|
|
- R3를 썼다면 **구현 제약**(지원 범위·JS 비용)이 적혀 있다
|
|
- 회색조 위계가 비즈니스 우선순위와 일치한다
|
|
|
|
> 근거: research/references/02-methodology.md (조사일 2026-08-20)
|