# Threads Cardnews

> Use when the user gives a topic, a draft, or a rough note and wants it turned into a Korean Threads(스레드) post, square card news images, or both — "스레드에 올릴 글", "스레드 말투로", "카드뉴스 만들어줘", "1080 카드 뽑아줘".

- Skill: `ebs-onboarding-2026/threads-cardnews` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add ebs-onboarding-2026/threads-cardnews`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ebs-onboarding-2026/threads-cardnews/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ebs-onboarding-2026 (https://skillmd.com/u/ebs-onboarding-2026)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/ebs-onboarding-2026/threads-cardnews

---


# Threads 글 + 카드뉴스

주제를 받아 ① 스레드 말투 본문과 ② 1080×1080 카드뉴스 PNG를 만든다.
둘 중 하나만 요청받아도 나머지를 제안한다 — 스레드 게시물은 보통 본문 + 이미지가 한 세트다.

## 1. 본문 쓰기

`tone.md`를 **읽고** 쓴다. 기억으로 쓰지 말 것 — 어미 분포, `;;` 용법, 호칭이 전부 거기 있다.

핵심만: 반말(해체)이 기본, 정보·평가 부분만 음슴체, 한 문장 한 줄, **마지막은 반드시 질문**.

## 2. cards.json 작성

카드는 3~5장. 기본 4장 구성: 커버 → 무슨 일 → 후기/요점 → 다음 액션 + 질문.

```json
{
  "theme": "ink",
  "cards": [
    { "kicker": "신규직원 연수 · DAY 1", "display": ["바이브코딩", "배우고 옴"],
      "accentFrom": 1, "foot": "재밌었고, 유익했고, 어려웠음.", "footsub": "첫날 후기 4장 요약 →" },
    { "kicker": "솔직 후기", "items": ["재밌었음", "유익했음", "근데 어렵기도 함"],
      "foot": "쉽다길래 만만하게 봤는데 아니더라" },
    { "kicker": "내일은", "display": ["해커톤", "나가볼까?"], "accentFrom": 1,
      "body": "연수는 내일도 이어지고,\n사내에서 해커톤 한다니까\n참여해보고 싶음.",
      "cta": "먼저 해본 스친이 있어?\n뭐부터 준비하면 되는지 알려줘" }
  ]
}
```

| 필드 | 뜻 |
|---|---|
| `theme` | `"ink"`(기본, 잉크블랙+라임) 또는 `"paper"`(크림+오렌지) |
| `kicker` | 상단 라벨. 모노 대문자 느낌으로 짧게 |
| `display` | 대제목 줄 배열. `accentFrom`부터 액센트 컬러 |
| `items` | 숫자 리스트 행. `display` 대신 씀 |
| `body` | 대제목 아래 본문. `\n`으로 줄바꿈 |
| `cta` | 하단 액센트 박스. 질문을 넣는다 |
| `foot` / `footsub` | 하단 한 줄 + 부연 |

페이지 번호(`01 / 04`)는 자동이다. 글자 크기도 자동으로 맞춰지니 지정하지 않는다.

카드 문구는 본문을 그대로 옮기지 말고 짧게 다시 쓴다. **원문에 없는 사실을 만들지 말고**,
카피를 지어냈으면 마지막에 어느 문장인지 말해준다.

## 3. 렌더링 — 기본 경로

```bash
python .claude/skills/threads-cardnews/build_cards.py cards.json --out cardnews/
python .claude/skills/threads-cardnews/shoot.py cardnews/
```

`shoot.py`가 로컬 서버를 띄우고 헤드리스 Chrome으로 카드마다 PNG를 뽑는다.
1080×1080이 아니면 스스로 실패하므로 크기 검증은 따로 필요 없다.
**브라우저 MCP가 없어도 된다. 이 경로를 먼저 쓴다.**

결과는 `cardnews/threads-card-01.png` … 순번대로. `SendUserFile`로 보낸다.

문구가 안전영역을 넘는지 보려면 `--serve`로 띄워 `window.__check()`를 부른다.
`[]`가 아니면 그 번호 카드의 문구를 줄이고 다시 빌드한다. (넘쳐도 글자는 자동으로
줄어드니, 너무 작아졌을 때만 손대면 된다.)

## 브라우저 MCP로 찍어야 할 때

Chrome이 없는 환경에서만. `--serve`를 백그라운드로 띄워 URL을 읽고:

1. 뷰포트를 **1080×1080**으로 리사이즈
2. `await window.__ready` — 폰트 로드 + 자동 크기 조절 완료
3. 카드마다 `window.__show(i)` (0-based) → **뷰포트 전체** 스크린샷, `scale: "css"`

끝나면 서버 태스크를 중지한다.

## 반드시 지킬 것

- **`file://`는 브라우저 도구가 거부한다.** 항상 HTTP로 띄운다.
- **요소 스크린샷(`target`/`element`)을 쓰지 말 것.** 호스트 DPR이 1이 아니면 확대·잘림이
  발생한다. 뷰포트를 1080×1080으로 맞추고 뷰포트 스크린샷을 찍는다.
- **`window.__ready`를 기다리지 않으면** 웹폰트 적용 전 상태가 찍힌다.
- 카드 이미지에는 이모지를 넣지 않는다. 이모지는 본문용.
- **모르는 사실은 지어내지 않는다.** 신제품·뉴스·수치가 주제면 먼저 웹 검색으로
  확인하고, 확인 안 된 건 카드에 넣지 않는다.

