The brand market research report interactive web report with Dante Labs design tokens appliedbuild and deploy to Vercel. The goal is that following this skill as-is produces the same visual quality for Musinsa / 29CM / any brand alike.
Absolute Rules (Hard Contract)
- Build on the local SSD (
/tmp/{brand}-report-app) . Runningnpm installin an SMB/NAS-mounted workspace takes 17+ minutes and appears to hang. Copy only the build artifacts back to the workspace. - Inject VERCEL_API_TOKEN only from the container
.envor the docker-composeenvironment:block. The Secrets panel in the paperclip console iscodex_localnot propagated to the adapter heartbeat process env (as of 2026-05). Spawn-time validation:printenv | grep VERCEL_API_TOKENmust be non-empty to start the build. - No meta disclaimer. Meta information such as "data has not been analyzed yet", "until the source page is re-verified", "LinkedIn dead page", "Trustpilot noise", "0 corrections needed with 0.86 confidence" does not appear on any page. Fill every slot with fact-based dummy data so it looks like a completed report.
- Exact 5-page structure. Home / SWOT / Charts / Fact-check / Competitors — no adding other pages. Fill insufficient data with dummy data, following the rules in §3 above.
- Dante Labs tokens only. paper #F7F2E6 / ink #1a1a1a / rust #A0522D / slate #435B6C / sepia #8B6F47 / amber #C9A857 / mark #EBC65B. No other colors (arbitrary colors such as gray, cobalt, indigo, etc.). Emphasis only with rust or yellow
dl-markfluorescent highlight. - Body text in Noto Serif KR, headlines in Nanum Myeongjo, UI labels in Pretendard Variable. No sans-serif in body text. No emoji.
- No chapter badges. Do not add signature marks like "CHAPTER 23 · BRAND INTEL" in the bottom-left/top-right (exception upon request).
- Deploy only after passing build verification.
npm run buildsuccess → production deploy.
When to use
- Brand Intelligence Lab 의 Slide producer (agent-3) receives the 5 analyst deliverables (
analysis/insights.md,analysis/swot_matrix.json,analysis/chart_spec.json,analysis/fact_check.md,analysis/cleaned_data.parquet) and builds them into an executive interactive report. - If the viewer
paperclipai company import https://github.com/dandacompany/brand-intelligence-labis included in a company's slide producer capabilities, it is applied automatically.
Prerequisite verification (do not skip)
node --version # ≥ 20
which vercel || npm i -g vercel # CLI 존재
printenv | grep -E 'VERCEL_API_TOKEN' # 비어있지 않아야 함
[ -n "$VERCEL_API_TOKEN" ] || { echo "BLOCK: token missing — .env injection 필요"; exit 1; }
If verification fails, report via paperclip comment BLOCK: VERCEL_API_TOKEN missing in heartbeat env — 호스팅어 hPanel Docker Manager → paperclip-{slug} → .env 편집 후 컨테이너 재시작 and stop immediately.
Build procedure
1. Local SSD scaffolding
BRAND={brand} # musinsa | 29cm
APP=/tmp/${BRAND}-report-app
rm -rf "$APP" && mkdir -p "$APP" && cd "$APP"
package.json (manual authoring — create-next-app avoids interactive/network steps, saving ~2 minutes):
{
"name": "brand-intel-${BRAND}",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "^15.0.0",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"echarts": "^5.5.0",
"echarts-for-react": "^3.0.2"
},
"devDependencies": {
"@types/node": "^22",
"@types/react": "^18",
"@types/react-dom": "^18",
"typescript": "^5",
"tailwindcss": "^3.4.0",
"postcss": "^8.4.0",
"autoprefixer": "^10.4.0"
}
}
4 additional files: tsconfig.json, next.config.ts (including env NEXT_PUBLIC_BRAND branching), postcss.config.mjs, tailwind.config.ts. The exact body text is references/scaffold-files.md reference — copy verbatim.
2. Dantelabs design tokens — tailwind.config.ts
references/design-tokens.md 's token table into the Tailwind theme. Key points:
colors: paper {DEFAULT/soft/strong}, ink {DEFAULT/soft/muted}, rust {DEFAULT/deep}, slate2 {DEFAULT/deep}, sepia, amber2, mark2, linkfontFamily: editorial (Nanum Myeongjo + Noto Serif KR), serif (Noto Serif KR), sans (Pretendard Variable), mono (JetBrains Mono)borderRadius: none / sm 2px / md 4px / lg 8px (no more than 8)boxShadow: emboss (hairline inset + soft drop, ink-tint only), card (rust hover shadow)
3. app/globals.css — typography classes + signature components
references/globals-css.md use as-is. Included classes:
.type-display/.type-hero/.type-h1~h3/.type-body/.type-small/.type-meta/.num-tabular.ledger-hairline— top/bottom 1px border (header/footer signature).edge-mark— absolutely positioned meta label (top-left SESSION · top-right BRAND CODE).rust-stripe— left 4px rust accent stripe.dl-card— card surface + hover shadow.dl-badge/.dl-badge-rust/.dl-badge-slate/.dl-badge-amber.dl-mark— yellow highlighter highlight (background gradient, never use underline)
4. Exact structure of the 5 pages
references/page-blueprints.md 's 5-page spec verbatim. Each page header keeps the <div className="type-meta">PAGE · {LABEL}</div> + <h1 className="type-hero">{브랜드명} · {타이틀}</h1> pattern.
| Page | Component | Data source |
|---|---|---|
app/page.tsx (홈) |
KPI 4 card (rust-stripe) + Key Insights 5 (ledger-hairline grid 12) | kpis[], insights[] |
app/swot/page.tsx |
2×2 quadrant Card grid (S/W/O/T), with a giant letter mark on the left of each card (rust/slate alternating) | swot.{strengths,weaknesses,opportunities,threats}[] |
app/charts/page.tsx |
2×2 chart grid — SerpChart / PriceDistChart / RevenueChart / SocialChart | trends.{serp,priceDist,revenue,social}[] |
app/fact-check/page.tsx |
Header callout (N verified items dl-mark emphasized) + 4-column table (claim/source/status badge/notes) |
factCheck[] |
app/competitors/page.tsx |
5-column table — self row is rust-stripe + bg-paper-strong + "SELF" meta | competitors[] |
5. 4 ECharts chart components — components/Charts.tsx
references/charts-component.md verbatim. Use the SVG renderer (opts={{ renderer: 'svg' }}). Color palette is only the 2 colors rust/slate, background is paper. All 4 use the same baseGrid (left 56, right 24, top 24, bottom 36) + baseAxis (border dashed splitLine, Pretendard label 11px muted).
6. Dummy data — lib/data/{brand}.ts
references/dummy-data-rules.md follow the rules. Key points:
- never meta disclaimer — no such wording as "data not yet analyzed", "until the original page is rechecked", "estimate / partial data"
- fill every slot — KPI 4, Insight 5, 3 per SWOT quadrant (12 total), chart serp 12 points / priceDist 5 / revenue 6 / social 4, competitors 4, factCheck 8
- fact-based dummy — only figures actually verifiable from official IR, press releases, and Bright Data datasets. Even if viewers verify, within ±10% of the actual value.
- factCheck status distribution — verified 56 · estimated 23 · flagged 0. status badge 는 dl-badge-rust / dl-badge-amber / dl-badge-slate 순.
7. Build → Vercel deploy
cd /tmp/${BRAND}-report-app
npm install --no-audit --no-fund --legacy-peer-deps # ~10초 (SSD)
NEXT_PUBLIC_BRAND=$BRAND npx next build # 5 페이지 정적 생성
export VERCEL_TOKEN="$VERCEL_API_TOKEN"
# 기존 프로젝트 연결 (대화형 회피 — project.json 직접 작성)
mkdir -p .vercel
curl -sS "https://api.vercel.com/v9/projects/brand-intelligence-${BRAND}" \
-H "Authorization: Bearer $VERCEL_TOKEN" \
| python3 -c "import json,sys;d=json.load(sys.stdin);open('.vercel/project.json','w').write(json.dumps({'projectId':d['id'],'orgId':d['accountId']}))"
vercel deploy --prod --yes --token "$VERCEL_TOKEN" \
--build-env NEXT_PUBLIC_BRAND=$BRAND \
--env NEXT_PUBLIC_BRAND=$BRAND 2>&1 | tee /tmp/vercel-deploy.log
DEPLOY_URL=$(grep -oE 'https://[a-z0-9-]+\.vercel\.app' /tmp/vercel-deploy.log | tail -1)
8. Self-verify then report
curl -sI "$DEPLOY_URL" | head -1 # HTTP/2 200
curl -s "$DEPLOY_URL" | grep -oE "무신사|29CM|브랜드|SWOT" | sort -u
Report in the following format in a paperclip comment:
배포 완료 — {BRAND}
URL: $DEPLOY_URL
페이지 5종: 홈 / SWOT / 차트 / 팩트체크 / 경쟁사
디자인 토큰: paper+ink+rust+slate (단테랩스 v1.1)
메타 disclaimer 0건 · 차트 4종 · KPI 4 · Insight 5 · factCheck 8
다음 owner: 단테 (URL 시청 후 코멘트로 OK/수정 요청)
Self-verification checklist (before deploy)
| Verification | Pass criteria |
|---|---|
npm run build pass |
All 5 pages ○ (Static) displayed |
printenv | grep VERCEL_API_TOKEN |
not empty |
| search arbitrary page text | 0 occurrences of "TODO" "placeholder" "lorem" "no data" "until estimated" |
| Color palette | only the 7 colors from tailwind.config.ts appear (rg "#[0-9A-Fa-f]{6}" app/ components/ lib/) |
| Font | body globals.css starts with font-family: 'Noto Serif KR' starts with |
| Emoji | rg "[\U0001F300-\U0001F9FF]" app/ components/ 0건 |
| chapter badge | rg -i "chapter|episode|session ·" app/ 0 cases (exception on request) |
If the check fails, deploy is halted → fix the item and re-run.
Troubleshooting
| Symptom | Cause | Action |
|---|---|---|
next: command not found |
install failure or missing PATH | npx next build call directly with |
npm install 17 min+ elapsed |
SMB mount (/Volumes/... or /paperclip/...) small file IO bottleneck |
/tmp/{brand}-report-app move to and install |
Vercel Not Authorized (401) |
token expired or invalid | issue a new token → container .env update → restart container |
| Korean □□ garbled | font-serif not set in tailwind config or missing font import | globals.css 에 @import url('https://fonts.googleapis.com/css2?family=Noto+Serif+KR...') check |
| chart SSR error | echarts references window | next/dynamic with ReactECharts 를 ssr: false wrap in |
References
references/design-tokens.md— 7 colors + typography + spacing/radius/shadow token table (can be copied as-is)references/scaffold-files.md— full text of package.json / tsconfig / next.config / postcss / tailwind.configreferences/globals-css.md— typography classes + full CSS for dl-card / dl-badge / ledger-hairline / rust-stripereferences/page-blueprints.md— tsx body template for each of the 5 pagesreferences/charts-component.md— body of 4 types of ECharts componentsreferences/dummy-data-rules.md— meta disclaimer prohibition rule + slot filling table + factCheck status distribution
Source of truth
- Canonical implementation: https://github.com/dandacompany/dante-skills/tree/main/nextjs-tremor-report
- Mirror: https://github.com/dandacompany/brand-intelligence-lab/tree/main/skills/dandacompany/dante-skills/nextjs-tremor-report
- Verified deployment: https://brand-intelligence-musinsa.vercel.app · https://brand-intelligence-29cm.vercel.app