| name | slide-audit |
| description | Render HTML slide decks to per-slide PNGs and verify layout by (1) deterministic Playwright bounding-rect diagnostic and (2) parallel subagents that visually review the screenshots. Catches text overlap, clipping, overflow, layout bugs. Triggers - ๊ธ์ ๊ฒน์นจ, ์ฌ๋ผ์ด๋ ์คํฌ๋ฆฐ์ท, ์ฌ๋ผ์ด๋ ๊ฒ์, ์ฌ๋ผ์ด๋ ๊ฒ์ฆ, deck ๋ฆฌ๋ทฐ, slide audit, slide overlap, slide verify, HTML ์ฌ๋ผ์ด๋ ์ ๊ฒ. |
slide-audit
HTML ์ฌ๋ผ์ด๋ ๋ฑ (1920ร1080, .slide + .is-active ํ ๊ธ ๋ฐฉ์)์ ๋ ์ด์์์ ๋ ๋จ๊ณ๋ก ๊ฒ์ฆ:
- Rect diagnostic (deterministic) โ Playwright ๋ก
.slide-content, .card, .two-col > .col, .hero, .timeline ์ getBoundingClientRect() ๋ฅผ ์ธก์ ํด content ๊ฒฝ๊ณ/์บ๋ฒ์ค ์ด๊ณผ๋ฅผ ํ์ง. ์๋ธ์์ด์ ํธ๋ณด๋ค ์ ํํ๊ณ ์ฌํ์ฑ ์์.
- Visual audit (subagent) โ ๊ฐ ์ฌ๋ผ์ด๋ PNG ๋ฅผ ๋ณ๋ ฌ ์๋ธ์์ด์ ํธ๊ฐ ์ด๋ฏธ์ง๋ก ์ด์ด ํ
์คํธ ๊ฒน์นจยท์๋ฆผ์ ํ์ธ.
๋ฉ์ธ ์์ด์ ํธ๋ ์ ๋ PNG ๋ฅผ ์ง์ Read ํ์ง ๋ง ๊ฒ. ์ปจํ
์คํธ ๋ญ๋น. ๋ชจ๋ ์ด๋ฏธ์ง ํ๋
์ ์๋ธ์์ด์ ํธ๋ก ์์.
ํต์ฌ ์์น โ ์์ ์์
1. measure.mjs โ rect ๋ก ๊ตฌ์กฐ ๋ฒ๊ทธ๋ถํฐ ์ก๋๋ค (๋ฑ 1ํ ์คํ, ~10์ด)
2. screenshot.mjs โ PNG ์์ฑ
3. ์๋ธ์์ด์ ํธ dispatch (๋ณ๋ ฌ) โ ์๊ฐ ํ์ง ํ์ธ
2025-04-14 ๊ตํ (์คํฌ ์กด์ฌ ์ด์ ): ์๋ธ์์ด์ ํธ๊ฐ "์นด๋ ํ๋จ์ด footer ์ ๊ฒน์น๋ค" ๋ฅผ persistently ๋ณด๊ณ ํ๋๋ฐ, ํ๋ฉด ์ฒ๋ฆฌ (padding ์กฐ์ ) ๋ก 2๋ผ์ด๋ ์คํจ. Rect ์ธก์ ์ผ๋ก ์นด๋๊ฐ ์ค์ ๋ก 1033~1213px ๊น์ง ๋ถํ์ด ์บ๋ฒ์ค ๋ฐ๊น์ง ํ์ด๋์๋ค๋ ๊ฑธ ํ์ธ โ ๊ตฌ์กฐ CSS ๋ฒ๊ทธ (grid auto-row + aspect-ratio + min-height ๋ฏธ์ค์ ) โ ์ ํํ ์์ . ์๋ธ์์ด์ ํธ๋ ์ฆ์์ ๋ณด๊ณ , measure.mjs ๋ ์์ธ์ ๋ณด์ฌ์ค๋ค. ๋ ๋ค ๋๋ ค๋ผ.
ํธ๋ฆฌ๊ฑฐ
- ์ฌ์ฉ์๊ฐ ์ฌ๋ผ์ด๋/๋ฑ/HTML ํ๋ ์ ํ
์ด์
์ ๊ธ์ ๊ฒน์นจยท๋ ์ด์์ ์ด์ยท๊ฒ์ฆ์ ์์ฒญํ ๋
- ์: "์ฌ๋ผ์ด๋ ๊ฒน์นจ ํ์ธ", "deck ๊ฒ์ฆ", "HTML ์ฌ๋ผ์ด๋ ์ ๊ฒ", "14ํ์ด์ง ์๋ฆฐ๋ค"
์ ์ ์กฐ๊ฑด
๋์ HTML ๊ท์ฝ:
- ์ฌ๋ผ์ด๋๋
<section class="slide" data-index="NN"> ๊ตฌ์กฐ
.slide { opacity: 0 }, .slide.is-active { opacity: 1 }
- 1920ร1080 ์บ๋ฒ์ค, center-anchored
์ค์น (์ต์ด 1ํ)
cd ~/.claude/skills/slide-audit
[ -d node_modules/playwright ] || npm install
npx playwright install chromium
์ค์ (Claude Code ํ๊ฒฝ): Bash ์๋๋ฐ์ค๊ฐ Chromium ์๋ธํ๋ก์ธ์ค๋ฅผ killEPERM ์ผ๋ก ์ฃฝ์
๋๋ค. Playwright ์คํ Bash ํธ์ถ์ dangerouslyDisableSandbox: true ๋ก.
์ํฌํ๋ก
1. Rect diagnostic
node ~/.claude/skills/slide-audit/measure.mjs <html-path>
์ถ๋ ฅ:
โ slide 01 ok
โ slide 14 col[0] bottom=1041 exceeds content bottom=860 by 181
...
30/30 slides clean, 0 with issues
- ๋ฌธ์ ์๋ ์ฌ๋ผ์ด๋ ์์ผ๋ฉด exit 2
- ISSUE ๋ฐ๊ฒฌ ์ ์ฆ์ CSS ์์ ํ ์ฌ์ธก์ . ๋ค์ ๋จ๊ณ๋ก ๋์ด๊ฐ์ง ๋ง ๊ฒ.
- rect ๊ฐ ๋ชจ๋ clean ์ด๋ฉด ๊ตฌ์กฐ๋ ์์ . ๋ค์์ผ๋ก.
2. Screenshot ์์ฑ
node ~/.claude/skills/slide-audit/screenshot.mjs <html-path> [outdir]
outdir ์๋ต ์ <html๋๋ ํ ๋ฆฌ>/_screenshots/<ํ์ผ๋ช
>/ ์ ์ ์ฅ
- ๊ฐ ์ฌ๋ผ์ด๋ โ
slide_NN.png
manifest.json ์ ๋ชฉ๋ก ๊ธฐ๋ก
.progress ์ค๋ฒ๋ ์ด๋ ์๋ ์จ๊น (์คํฌ๋ฆฐ์ท์ "keys to navigate" ํํธ ์ ๋ค์ด๊ฐ)
3. ์๋ธ์์ด์ ํธ ๋ณ๋ ฌ dispatch (ํ์)
์ฌ๋ผ์ด๋๋ฅผ 8์ฅ ์ดํ์ฉ ๋ฐฐ์น๋ก ๋๋ ์ ๋ณ๋ ฌ ํธ์ถ. ๋จ์ผ ๋ฉ์์ง์ multi Agent tool_use.
๋ฐฐ์น ํฌ๊ธฐ ๊ท์น:
- 30์ฅ โ 4 ๋ฐฐ์น (8+8+7+7)
- 20์ฅ โ 3 ๋ฐฐ์น (7+7+6)
- 10์ฅ ์ดํ โ 1 ๋ฐฐ์น
๊ฐ ์๋ธ์์ด์ ํธ์ ๋ค์ ํ๋กฌํํธ ํ
ํ๋ฆฟ์ ๊ทธ๋๋ก ์ ๋ฌ (๊ฒฝ๋ก๋ง ์นํ):
You are visually auditing screenshots of N slides from an HTML presentation deck.
Each PNG is a 1920ร1080 render of one slide. Read each image using the Read tool
(it handles PNGs as images) and inspect it visually.
Target files:
1. <abs path>/slide_NN.png
...
Background: <1-2 lines about the deck โ palette, structure, layout components>.
For EVERY slide, apply this checklist:
- Does the h1 title overlap or touch the pagenum on the right?
- Does text inside any card/container overflow its boundary (visible cut or extending past edge)?
- In 2-column or 3-column grids, do left/right contents encroach on each other?
- In hero layouts, does text overlap the image?
- Timeline nodes: do connector lines align with nodes?
- Does the slide-footer overlap any body content above it?
- Any element extending past the 1920ร1080 canvas (clipped at edges)?
- Bullet lists visibly cut at card bottom?
RESPOND in this exact Markdown format, ONE SECTION PER SLIDE, no prose outside:
## Slide NN
- status: OK | ISSUE
- issues:
- <short description โ suspected cause>
- suggested-fix: <one-line CSS hint, or "none">
Rules:
- If OK, write `- status: OK`, `- issues:` (empty), `- suggested-fix: none`.
- Keep each issue to one line.
- Do NOT open any file other than the N PNGs listed.
- Do NOT provide a summary at the end.
- Do NOT echo the checklist.
4. ๋ฆฌํฌํธ ์ทจํฉ + ์์ฌ์ค๋ฌ์ฐ๋ฉด rect ์ฌ์ธก์
์๋ธ์์ด์ ํธ ์๋ต์ ๋ณํฉํด ์ฌ์ฉ์์๊ฒ ์ ์. ์ด์๊ฐ ๋ณด๊ณ ๋๋๋ฐ ์์ ํ๋๋ฐ๋ "persistent" ๊ฐ ๋ฐ๋ณต๋๋ฉด measure.mjs ๋ก ๋์๊ฐ์ ์ค์ bounding rect ํ์ธ. ์๋ธ์์ด์ ํธ vision ํ๋จ์ hallucination ๊ฐ๋ฅ (์๋ ํ
์คํธ "์์/์ฐจ์" ์ ๋ณด๊ณ ํ ์ค์ ์ฌ๋ก ์์). Rect ๋ ๊ฑฐ์ง๋ง ์ ํ๋ค.
ํ์ผ
screenshot.mjs โ ์ฌ๋ผ์ด๋ PNG ๋ ๋๋ฌ
measure.mjs โ rect diagnostic
package.json โ Playwright ์์กด์ฑ
SKILL.md โ ์ด ๋ฌธ์
๊ณตํต CSS ๋ฒ๊ทธ ์นดํ๋ก๊ทธ (๊ฒฝํ ์ถ์ )
์ด ์นดํ๋ก๊ทธ๋ rect diagnostic ์ด ์คํจํ์ ๋ ์ฒดํฌํ ๊ตฌ์กฐ์ ์์ธ.
| ์ฆ์ (rect) | ์์ธ | ์์ |
|---|
card bottom > content bottom | .slide-content grid auto-row + .card-img { aspect-ratio } | .slide-content { grid-auto-rows: 100%; overflow: hidden } + .card { min-height: 0 } + .card-img { flex: 1 1 auto; min-height: 0; } (aspect-ratio ์ ๊ฑฐ) + .card-body { flex: 0 0 auto } |
col bottom > content bottom | .two-col > .col { flex column } ์ min-height ์์, ๋ด๋ถ img intrinsic size | .two-col { min-height: 0 } + .two-col > .col { min-height: 0; overflow: hidden } + .two-col > .col > img { flex: 0 1 auto; min-height: 0; max-height: 50%; object-fit: contain } |
timeline::before ์ ์ด ๋ node ๋ฐ์ผ๋ก | ๋
ธ๋ ๊ฐ์ โ 5 (๊ธฐ๋ณธ ์ค๊ณ) | ๋
ธ๋ ๊ฐ์๋ณ left/right % ์ฌ์ค์ (4๋
ธ๋ = 12.5%, 3๋
ธ๋ = 16.6%) |
| footer overlap | --content-h ๊ฐ ๊ฐ์ฉ ๋์ด ์ด๊ณผ | 240 (content-top) + content-h + gap + 60 (footer) + 80 (safe-y) โค 1080 ๋ง์กฑํ๋ content-h. 80px gap ๊ถ์ฅ โ content-h: 620 |
์ฃผ์
- ์์ ์ ํญ์ ๋ณ๋ ํด์์ ์ฌ์ฉ์ ์น์ธ ํ (๊ฒ์๋ง ์ด ์คํฌ์ ์ญํ )
- ์ธ๋ถ ๋ฆฌ์์ค (ํฐํธยท์ด๋ฏธ์ง CDN) ์์กด ์
networkidle ๋๊ธฐ๋ก ์ถฉ๋ถ
- measure.mjs ๋ 30 ์ฌ๋ผ์ด๋ โ 8์ด, screenshot.mjs ๋ โ 12์ด. ๊ฒ์ 1ํ 1๋ถ ์ด๋ด์ ์๋ฃ๋จ