요즘 콘텐츠를 만드는 사람의 가장 큰 병목은 글이 아니라 '보기 좋게 만드는 것'입니다. 좋은 글을 써도 小红书(샤오훙수)에 올릴 캐러셀 카드나 위챗 표지 이미지로 옮기려면 Canva·Figma를 붙잡고 한참 씨름해야 하죠. guizang-social-card-skill은 바로 이 단계를 자동화합니다. AI 에이전트(Claude Code, Codex 등)에게 "이 글로 스위스풍 샤오훙수 5장 만들어줘"라고 말하면, 글에서 핵심을 뽑아 페이지를 나누고, 정해진 레이아웃과 색표를 골라 HTML로 짠 뒤, 진짜 브라우저로 렌더링해 PNG 이미지 세트를 뽑아줍니다.
당신이 잡지사에 글 한 편을 넘겼다고 합시다. 유능한 아트 디렉터는 글을 처음부터 다시 디자인하지 않습니다. 잡지사가 수십 년에 걸쳐 다듬어 온 '하우스 스타일'(폰트 규칙, 색 팔레트, 표지 레이아웃 틀)을 꺼내, 이 글에 맞는 틀을 고르고 사진을 앉히고 제목 크기를 잡습니다. 창의력은 '틀을 고르고 채우는' 데 쓰지, '매번 새 틀을 발명하는' 데 쓰지 않죠. guizang-social-card-skill이 하는 일이 정확히 이것입니다. 이미 잘 만들어진 28개의 레이아웃 골격과 10개의 색표 중에서 AI가 고르고, 당신의 내용으로 채우고, 품질 규칙으로 검수합니다.
핵심 통찰은 "AI에게 자유를 덜 줄수록 결과가 더 좋아진다"는 역설입니다. 보통 이미지 생성은 AI에게 "예쁘게 만들어줘"라고 맡기지만, 그러면 매번 품질이 들쭉날쭉합니다. 이 스킬은 정반대로 갑니다 — 색은 10개 프리셋에서만, 레이아웃은 28개 골격에서만, hex 값 자유 입력 금지. 대신 그 안에서는 잡지 수준의 일관성이 나옵니다. README의 표현을 빌리면 "자유를 주는 것보다 미학을 지키는 게 더 중요하다(保护美学比给自由更重要)".
SKILL.md 한 파일에 "언제 발동하고, 어떤 순서로 일하라"를 적어두면, 사용자가 관련 요청을 할 때 에이전트가 자동으로 그 매뉴얼을 읽고 따릅니다. 이 프로젝트는 그 자체가 하나의 스킬입니다.2026년 TrendShift 데일리에는 유난히 #AI skills 태그가 많습니다(nature-skills, SkillOpt, GordenPPTSkill 등). AI 에이전트가 보편화되면서 "에이전트에게 무엇을 어떻게 시킬지"를 패키징한 스킬이 새로운 오픈소스 장르가 됐기 때문입니다. guizang-social-card-skill은 그중에서도 '디자인 자동화'라는, 누구나 즉시 효용을 체감하는 영역을 정조준했습니다. 공개(2026-05-27) 6일 만에 별 약 2,500개, 포크 약 250개가 붙을 만큼 빠르게 떴습니다.
둘째, 작가 op7418(歸藏, 구이짱)은 중국 AI·디자인 커뮤니티에서 손꼽히는 인플루언서(KOL)입니다. 그의 안목이 색표·레이아웃·타이포 규칙에 그대로 녹아 있어, "AI가 만들었는데 디자이너가 만든 것 같다"는 결과가 나옵니다. 자매 프로젝트 guizang-ppt-skill(PPT용)과 미학 언어를 공유하죠.
셋째, 기술적으로 가장 영리한 선택은 "이미지를 그리지 않고, HTML을 그린 뒤 스크린샷을 찍는다"는 발상입니다. AI는 그림(픽셀)을 정밀하게 못 그리지만, 텍스트(HTML/CSS)는 완벽하게 읽고 쓰고 고칠 수 있습니다. 그래서 카드를 HTML로 짠 뒤 Playwright로 PNG를 뽑으면 — 픽셀 정밀도 + AI 편집 가능성 + 무한 이미지 소스를 모두 얻습니다.
| 접근 방식 | 장점 | 한계 |
|---|---|---|
| AI 이미지 생성 (DALL·E 등) | 자유로운 그림 | 글자 깨짐, 레이아웃 부정확, 재현 불가 |
| Canva/Figma 수작업 | 정밀 제어 | 사람 노동, 느림, 자동화 불가 |
| 마크다운→이미지 변환 | 간단 | 레이아웃 표현력 빈약 |
| 이 스킬 (HTML→PNG) | 정밀+자동+검증 가능 | 렌더 파이프라인(Node/Playwright) 필요 |
넷째, 품질을 '주장'이 아니라 '측정'합니다. validate-social-deck.mjs가 Playwright로 실제 DOM을 재서 글자 넘침·폰트 과대·여백 과다 같은 결함을 자동 검출합니다(뒤에서 상세). "예뻐 보인다"가 아니라 "규칙 R1~R7을 통과했다"로 품질을 말하는 거죠.
이 프로젝트는 일반 웹앱과 스택 구성이 다릅니다. 실행 코드(.mjs)는 두 개뿐이고, 나머지 핵심 자산은 마크다운 규칙 문서(references/*.md)와 HTML 시드 템플릿입니다. AI가 읽고 따르는 '지식'이 곧 스택의 본체이기 때문입니다. GitHub 언어 통계도 HTML 73% · JavaScript 27%로, 빌드 도구·프레임워크가 없는 구성을 그대로 보여줍니다.
카드를 실제 이미지로 만드는 엔진입니다. 프레임워크 없이 Node 스크립트 + 헤드리스 브라우저만 씁니다. package.json의 의존성도 playwright ^1.60.0 단 하나뿐입니다.
| 구성 | 역할 |
|---|---|
| Node.js | validate-social-deck.mjs(품질 검증) 실행 런타임. ESM(.mjs) 사용. 렌더러는 태스크별로 생성하는 render.cjs(레포에 미포함)이며 레포 소스에는 포함되지 않음 |
| Playwright (chromium) | 헤드리스 크롬을 띄워 각 .poster 노드를 실제로 렌더하고 스크린샷. DOM을 진짜로 측정해 검증 |
| SwiftShader | --use-angle=swiftshader 플래그로 GPU 없이도 WebGL 렌더(잉크 배경) 가능하게 함 |
| WebFetch / curl | 웹에서 이미지 소스를 받아 assets/에 저장하고 SOURCES.md에 출처 기록 |
실제 '디자인'이 사는 곳. 순수 HTML/CSS이며, 빌드 도구(웹팩 등)가 전혀 없는 단일 파일 방식입니다.
| 구성 | 역할 |
|---|---|
| CSS Grid + Custom Properties | 레이아웃 골격과 테마. 모든 색은 var(--...)로 참조 → 테마 교체가 속성 한 줄(data-theme/data-accent)로 끝남 |
| 폰트 스택 | Editorial: Playfair Display + Noto Serif(세리프) · Swiss: Inter + Helvetica(산세리프) · 중국어는 Songti. 중·영문 동시 지원 |
| WebGL 잉크 배경 | assets/magazine-bg-webgl.js — 잡지풍 표지에 흐르는 먹(墨) 애니메이션. 저사양/스크린샷 시 비활성화 가능 |
| Mapbox Static Image API / OSM staticmaps | .map-block — 서버사이드 생성 정적 래스터 이미지 + HTML .map-pin 오버레이. 라이브 JS 지도 라이브러리는 사용하지 않음. 여행 공략용 |
| Lucide 아이콘 | 일관된 라인 아이콘 세트 |
| 3개 화판(board) | .poster.xhs 1080×1440(3:4) · .poster.wide 2100×900(21:9) · .poster.square 1080×1080(1:1) |
| 구성 | 역할 |
|---|---|
| Agent Skills 표준 | SKILL.md(YAML 프런트매터의 name/description) — 에이전트가 트리거 키워드로 자동 발동 |
npx skills add | 한 줄 설치 CLI. ~/.claude/skills/로 클론 |
| Progressive Disclosure | SKILL.md(요약) → references/*.md(상세)를 필요할 때만 읽어 토큰 절약 (아래 4장 참조) |
| AGPL-3.0 | 네트워크 서비스(SaaS)로 써도 소스 공개 의무. 폐쇄·유료 독점 금지 |
일반 웹앱은 "코드가 주연, 문서가 조연"입니다. 이 스킬은 정반대 — 마크다운 규칙 문서와 HTML 시드가 주연이고, 실행 코드(.mjs 2개)는 그 디자인을 사진으로 찍어주는 조연일 뿐입니다. '제품'이 곧 '잘 쓰여진 지식'인 셈이죠.
AI의 컨텍스트(읽을 수 있는 글의 양)는 한정돼 있습니다. 규칙을 전부 한 파일에 넣으면 토큰이 폭발하죠. 그래서 SKILL.md는 '목차+요약'만 담고, 상세 규칙은 references/의 15개 파일로 쪼개 둡니다. 에이전트는 "지금 테마를 고를 차례"면 theme-presets.md만, "사진 위에 글자를 얹을 차례"면 image-overlay.md만 그때그때 읽습니다. 필요한 지식만 적시에 꺼내 쓰는 구조입니다.
AI에게 "HTML을 처음부터 짜라"고 하면 매번 다른 결과가 나옵니다. 이 스킬은 그걸 막습니다. 4.5단계에서 반드시 시드 템플릿을 복사한 뒤, <!-- POSTERS_HERE --> 자리만 레시피(M01~M16 / S01~S12)로 교체하게 강제합니다. 시드에는 폰트 로딩·테마 토큰·3개 화판·배경 레이어가 이미 다 배선돼 있어, AI는 '구조'를 발명할 필요 없이 '내용'만 채웁니다.
// 스타일 모드에 따라 시드 선택 (Step 4.5) Editorial -> cp assets/template-editorial-card.html index.html Swiss -> cp assets/template-swiss-card.html index.html // 테마는 최상위 요소 속성 한 줄로 결정 (모든 CSS가 var(--..)로 읽음) <html data-theme="ink-classic | indigo-porcelain | midnight-ink ..."> // Editorial <html data-accent="ikb | lemon-yellow | lemon-green | safety-orange"> // Swiss // 페이지마다 레시피 골격을 끼움 <section class="poster xhs" data-id="01-cover"> ...레시피 M16... </section>
Editorial 레시피(세리프+레저+여백)와 Swiss 레시피(Inter+카드필+그리드)를 한 세트에 섞으면 레이아웃이 조용히 깨집니다. 또 임의의 hex 색을 넣는 것도 금지 — 반드시 10개 프리셋에서만 고릅니다. "규칙을 좁히는 것"이 곧 품질 보증 장치입니다.
사진이 없을 때 AI가 멋대로 처리하지 않도록 우선순위가 고정돼 있습니다: ① 사용자 사진 → ② AI 생성 → ③ 웹 소싱. 웹 소싱도 순서가 정해져 있습니다(Unsplash → Pexels → Flickr CC → Wallhaven → 직접 검색). 받은 이미지는 assets/에 저장하고 출처를 SOURCES.md에 한 줄씩 남긴 뒤, "출처 표기할까요?"를 사용자에게 먼저 묻습니다("일단 받고, 공개 후, 사용자가 결정").
validate-social-deck.mjs는 정적 스캔이 아니라 실제 브라우저로 렌더해 픽셀을 잰 뒤 7개 규칙으로 판정합니다. 흥미로운 점은 SKILL.md가 "렌더 후 자동으로 돌리지 말 것"을 명시한다는 것 — 매번 수십 초가 들기 때문에, 먼저 사용자에게 보여주고 요청할 때만 검사합니다. (참고: README는 규칙을 R1~R6로 다르게 번호 매기지만, 실제 스크립트는 아래 R1~R7이 정답입니다.)
| 규칙 | 무엇을 잡나 |
|---|---|
| R1 Overflow | scrollHeight > clientHeight — 내용이 카드 밖으로 넘침 (FAIL) |
| R2 Footer 충돌 | position:absolute 푸터 위로 본문이 침범 (FAIL) |
| R3 Swiss 볼드 | 72px+ 제목이 굵기 600 이상 → "클수록 가늘게" 원칙 위반 (FAIL) |
| R4 최소 폰트 | 본문/캡션이 모바일 가독 하한선 아래로 작아짐 (WARN) |
| R5 4횡대 밀도 | 3:4 카드를 4등분해 채움률 75% 미만이면 'PPT 같은 빈 카드' 경고 (WARN) |
| R6 제목 줄 수 상한 | 화판별 제목 줄/글자 수 초과 (WARN) |
| R7 figure 여백 드리프트 | 브라우저 기본 figure 40px 여백이 정렬을 틀어놓음 (WARN) |
구조를 3층으로 보면 쉽습니다. 루트의 .md 4개는 메타(진입·소개·인수인계·제품). assets/는 손에 잡히는 재료(시드 HTML, 배경 이미지). references/는 도서관 — 평소엔 닫혀 있다가 해당 작업 단계에서만 펼쳐집니다. SKILL.md가 "지금 image-overlay.md 봐"라고 가리키는 식이죠.
주목할 메타 문서가 있습니다. PRODUCT.md·HANDOFF.md의 존재는 작가의 철학("Skill은 Prompt가 아니라 Product")을 그대로 보여줍니다. 버전 번호·CHANGELOG·능력 경계(할 수 있는 것/없는 것)를 명시하는 — 즉 스킬을 '하나의 소프트웨어 제품'처럼 운영하는 흔치 않은 사례입니다. 또 모든 테스트·데모는 local-tests/에 두고 gitignore해 스킬 루트를 깨끗하게 유지합니다.
가장 값진 학습 포인트는 SKILL.md + references/ 구조 그 자체입니다. "프롬프트를 잘 쓰는 법"이 아니라 "지식을 파일 시스템으로 구조화해 토큰을 아끼는 법"을 보여줍니다. YAML 프런트매터의 description이 곧 '발동 트리거'라는 점, 메인 파일을 가볍게 유지하고 상세를 분리하는 점을 그대로 차용할 수 있습니다.
내가 자주 하는 반복 작업(예: "회의록을 액션아이템으로 정리") 하나를 골라 SKILL.md + references/ 2~3개로 쪼개 스킬을 만들어 보기. description에 트리거 키워드를 넣어 자동 발동을 테스트.
모든 색을 var(--...)로 빼고 data-theme/data-accent 한 줄로 전체 팔레트를 교체하는 기법은 실무 디자인 시스템의 정석입니다. CSS Grid로 28개 레이아웃 골격을 구성하고, "클수록 가늘게(larger=lighter)" 같은 타이포 하드룰을 코드로 강제하는 방식도 배울 점입니다.
카드 한 장(3:4)을 CSS Grid로 짜고, :root에 색 토큰 3세트를 정의한 뒤 data-theme 속성만 바꿔 다크/라이트/세피아로 전환되게 만들기.
validate-social-deck.mjs는 단순 스크린샷이 아니라 헤드리스 브라우저로 실제 픽셀을 재는 테스트 엔진입니다. getBoundingClientRect()로 요소 위치를, getComputedStyle()로 폰트 굵기를 읽어 규칙 위반을 잡습니다. 화면을 4횡대로 쪼개 채움률을 계산하는 'density bitmap' 기법(Uint8Array로 행 점유 표시)은 시각 회귀 테스트의 좋은 예시입니다.
Playwright로 임의 웹페이지를 열어 특정 요소가 화면 밖으로 넘쳤는지(scrollHeight > clientHeight)를 검사하는 10줄짜리 스크립트 작성 → exit code로 CI에 연결.
무료 라이브러리(Unsplash/Pexels/Flickr CC/Wallhaven) 우선순위와 SOURCES.md 출처 기록, 'AI는 저작권을 추측하지 말고 사용자에게 결정을 넘긴다'는 정책 설계는 실무에서 곧바로 쓸 수 있는 패턴입니다. 특히 Pexels가 중국어 키워드 검색을 지원해 국내 장면에 강하다는 식의 소스별 강점 매핑이 디테일합니다.
만(滿)이미지(전체를 덮는 사진) 위에 제목을 얹을 때, 먼저 사진을 읽어 주제(얼굴/초점)의 위치를 HTML 주석으로 기록한 뒤 안전지대에만 글자를 놓고, object-position을 인라인으로 지정해 잘림을 막는 규칙(image-overlay.md)은 멀티모달 시대의 실전 합성 노하우입니다. "썸네일 360px로 줄여도 제목이 읽히나" 테스트도 인상적입니다.
| 항목 | 요구사항 / 비고 |
|---|---|
| AI 에이전트 | 파일 읽기·쓰기 + 셸 실행이 가능한 Claude Code / Codex / Cursor. 일반 챗봇은 렌더 파이프라인이 없어 비권장 |
| Node.js | render.mjs·validate-social-deck.mjs 실행용. ESM(.mjs) 지원 버전 |
| Playwright | chromium 바이너리 다운로드 필요(수백 MB). 최초 1회 npx playwright install chromium |
| GPU | 불필요 — --use-angle=swiftshader 소프트웨어 렌더로 WebGL 잉크 배경까지 처리 |
| 인터넷 | 폰트 CDN, 지도 타일(OSM), 이미지 소스(Unsplash/Pexels 등) 접근에 필요 |
| 디스크 | chromium + 9장 WebP 배경 + 출력 PNG 저장 공간(수백 MB~) |
| OS | 경로·OS 독립. macOS/Linux/Windows 모두 가능(Node+Playwright 동작 환경이면 됨) |
"AI 이미지 생성 모델"처럼 GPU와 큰 VRAM이 필요할 것 같지만 전혀 아닙니다. 본질이 브라우저로 웹페이지를 스크린샷 찍는 것이라, 평범한 노트북에서도 돕니다. 무거운 건 chromium 다운로드(최초 1회)뿐입니다.
npx skills add https://github.com/op7418/guizang-social-card-skill로 설치한 뒤, 좋아하는 블로그 글 하나를 붙여넣고 "이 글로 스위스풍 샤오훙수 5장, IKB 블루로 만들어줘"라고 요청. 나온 PNG 세트를 살펴보며 표지/내용 페이지 구성이 어떻게 갈리는지 관찰.
똑같은 글을 한 번은 Editorial(전자잡지풍), 한 번은 Swiss로 뽑아 나란히 비교. "이 콘텐츠는 피처 기사인가, 릴리스 노트인가?"라는 SKILL.md의 판단 기준이 결과에서 어떻게 드러나는지 정리.
assets/template-swiss-card.html을 브라우저로 직접 열어 data-accent 값을 ikb→lemon-yellow로 바꿔보고, 한 색만 바꿨는데 전체 팔레트가 갈리는 CSS 변수 시스템을 체감. layout-recipes.md에서 레시피 하나(S10 H-Bar Chart 등)를 골라 <!-- POSTERS_HERE -->에 붙여 렌더.
validate-social-deck.mjs를 읽고 R1(overflow)·R5(4횡대 밀도) 로직을 따라가 본 뒤, "푸터에 항상 페이지 번호가 있어야 한다" 같은 나만의 규칙 R8을 추가해보기. Playwright의 page.evaluate()로 DOM을 측정하는 패턴을 손에 익히는 게 목표.
이 레포의 구조(SKILL.md + references/ + 시드 + 검증)를 본떠, 예를 들어 "이력서/포트폴리오 카드 생성 스킬"을 설계. 색표·레이아웃을 직접 정의하고 검증 규칙까지 붙이면 '스킬을 제품처럼 만드는' 전 과정을 경험하게 됩니다.
| 주차 | 주제 | 핵심 학습 + 산출물 |
|---|---|---|
| 1주차 | CSS 디자인 시스템 | CSS Grid, Custom Properties(var()), data-* 테마 전환, 타이포 스케일. → 3:4 카드 1장을 3개 테마로 전환 |
| 2주차 | 에이전트 스킬 구조 | Agent Skills 표준, SKILL.md 프런트매터, Progressive Disclosure. → 나만의 미니 스킬 1개(SKILL.md + references 2개) |
| 3주차 | 헤드리스 렌더링 | Playwright 설치·구동, page.screenshot(), evaluate()로 DOM 측정. → HTML→PNG 렌더 스크립트 |
| 4주차 | 시각 회귀 테스트 | getBoundingClientRect/getComputedStyle 기반 규칙, density bitmap, exit code & CI. → 품질 검증기 1개 + 규칙 3개 |
코드부터 읽으려 하면 막막합니다. 1주차 전에 스킬을 먼저 설치해 결과물을 여러 개 뽑아보세요. "이런 게 나오는구나"를 손에 익힌 뒤 시드 템플릿 → references → 검증 스크립트 순으로 역설계하면 훨씬 빨리 이해됩니다.
xhs=3:4 샤오훙수, wide=21:9 위챗 머리이미지, square=1:1 공유 카드. 같은 내용이라도 화판마다 따로 구성해야 합니다(잘라 쓰기 금지).<!-- POSTERS_HERE --> 부분만 채웁니다.