--- id: wiki-2026-0508-stylecounsel title: StyleCounsel category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Style Counsel, Brand Style Consistency Tool] duplicate_of: none source_trust_level: B confidence_score: 0.75 verification_status: applied tags: [style-guide, brand-consistency, design-system, ai-tooling] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: typescript framework: design-system-tooling --- # StyleCounsel ## 매 한 줄 > **"매 brand/style guide 의 enforcement 의 AI counsel"**. 매 design token, voice/tone, visual identity 의 multi-surface consistency 의 검증/제안 layer. 2026 의 맥락 = 매 Figma Variables + Storybook + LLM critic — 매 Cursor/Claude 가 매 PR 의 styleguide drift 를 review. ## 매 핵심 ### 매 의도 / 정의 - **StyleCounsel** = 매 brand/style consistency 의 AI-augmented enforcement tool (project-internal naming). - 매 deliverable: design token compliance, copy voice/tone check, asset spec validation. - 매 distinct from: ESLint (code style), Prettier (formatting), Stylelint (CSS) — 매 brand layer 의 위. ### 매 layer - **Design tokens** (W3C Design Tokens spec): color, typography, spacing — 매 single source. - **Voice/Tone**: 매 brand guideline (Mailchimp/IBM/Atlassian 의 공개 guide 참조). - **Visual assets**: logo placement, image filters, illustration style. - **UX copy**: 매 micro-copy consistency (button labels, error msgs). ### 매 응용 / target use 1. 매 monorepo 에서 매 multi-product brand drift 의 방지. 2. 매 marketing/blog/docs 의 voice consistency 의 LLM check. 3. 매 generated asset (DALL-E 4, FLUX Pro 1.5) 의 brand spec 의 validation. 4. 매 PR review 의 automated suggestions. 5. 매 onboarding 의 brand training material. ## 💻 패턴 ### Design tokens (W3C spec, 2026) ```json { "color": { "brand": { "primary": { "$value": "#0A66FF", "$type": "color" }, "secondary": { "$value": "#FF5C39", "$type": "color" } } }, "typography": { "heading-xl": { "$value": { "fontFamily": "Inter", "fontWeight": 700, "fontSize": "48px", "lineHeight": "1.1" }, "$type": "typography" } } } ``` ### Style Dictionary export → CSS / Tailwind ```javascript // style-dictionary.config.js export default { source: ["tokens/**/*.json"], platforms: { css: { transformGroup: "css", buildPath: "build/css/", files: [{ destination: "tokens.css", format: "css/variables" }] }, tailwind: { transformGroup: "js", buildPath: "build/tw/", files: [{ destination: "tokens.js", format: "javascript/es6" }] }, }, }; ``` ### Voice/tone LLM critic (Claude Opus 4.7) ```typescript import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic(); const BRAND_VOICE = ` - Friendly but professional (no slang) - Active voice; sentences <= 20 words - Use "you" not "users" - Avoid jargon; explain acronyms first time `; export async function styleCounselReview(copy: string) { const res = await client.messages.create({ model: "claude-opus-4-7", max_tokens: 1024, system: `You are StyleCounsel. Check copy against brand voice:\n${BRAND_VOICE}\nReturn JSON: {issues: [{line, problem, suggestion}], score: 0-1}`, messages: [{ role: "user", content: copy }], }); return JSON.parse(res.content[0].type === "text" ? res.content[0].text : "{}"); } ``` ### PR review GitHub Action ```yaml # .github/workflows/stylecounsel.yml name: StyleCounsel on: [pull_request] jobs: review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: 22 } - run: npm ci - run: npx stylecounsel review --base origin/${{ github.base_ref }} env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} - uses: actions/github-script@v7 with: script: | const fs = require('fs'); const report = JSON.parse(fs.readFileSync('stylecounsel.json', 'utf8')); await github.rest.issues.createComment({ ...context.repo, issue_number: context.payload.pull_request.number, body: `## StyleCounsel\nScore: ${report.score}\n\n${report.issues.map(i=>`- L${i.line}: ${i.problem} — ${i.suggestion}`).join('\n')}`, }); ``` ### Image asset spec validation ```typescript import sharp from "sharp"; const SPEC = { hero: { minWidth: 1920, aspect: 16/9, colorspace: "srgb" }, thumb: { minWidth: 800, aspect: 1, colorspace: "srgb" }, }; export async function validateAsset(path: string, kind: keyof typeof SPEC) { const meta = await sharp(path).metadata(); const spec = SPEC[kind]; const aspect = (meta.width ?? 0) / (meta.height ?? 1); const issues: string[] = []; if ((meta.width ?? 0) < spec.minWidth) issues.push(`width < ${spec.minWidth}`); if (Math.abs(aspect - spec.aspect) > 0.02) issues.push(`aspect ${aspect.toFixed(2)} != ${spec.aspect}`); if (meta.space !== spec.colorspace) issues.push(`colorspace ${meta.space} != ${spec.colorspace}`); return { ok: issues.length === 0, issues }; } ``` ### Storybook brand-token a11y check ```typescript // .storybook/preview.ts import { themes } from "@storybook/theming"; import "../build/css/tokens.css"; export const parameters = { a11y: { config: { rules: [{ id: "color-contrast", enabled: true }] } }, backgrounds: { values: [ { name: "brand-primary", value: "var(--color-brand-primary)" }, { name: "brand-bg", value: "var(--color-bg)" }, ], }, }; ``` ### Generated image brand-spec gate (FLUX Pro 1.5) ```typescript import { Replicate } from "replicate"; const replicate = new Replicate(); async function brandedImage(prompt: string) { const out = await replicate.run("black-forest-labs/flux-pro-1.5", { input: { prompt: `${prompt}, brand style: minimal, sans-serif, blue-orange palette, no text`, aspect_ratio: "16:9", output_format: "png", }, }); // 매 then run validateAsset() before publish return out; } ``` ## 매 결정 기준 | 상황 | Approach | |---|---| | 매 small team / single product | 매 design tokens + Storybook 만 | | 매 multi-product / monorepo | 매 StyleCounsel pipeline (tokens + LLM critic + CI gate) | | 매 marketing copy 일관성 | 매 LLM voice critic + 매 weekly editor review | | 매 generated asset (AI image) | 매 spec gate + manual approval | **기본값**: 매 design tokens (W3C) + Style Dictionary + LLM voice critic via PR Action — 매 매 light-weight 시작. ## 🔗 Graph - 부모: [[Design-Systems]] - 변형: [[Design-Tokens]] - 응용: [[Storybook]] · [[Style-Dictionary]] · [[Figma-Variables]] - Adjacent: [[ESLint-Static-Analysis]] · [[Prettier]] ## 🤖 LLM 활용 **언제**: 매 voice/tone review, 매 multi-surface copy consistency, 매 asset spec interpretation, 매 brand violation suggestion. **언제 X**: 매 strict legal/compliance copy — 매 final human review 필수. 매 LLM 의 brand creativity 의 generation 의 over-trust X. ## ❌ 안티패턴 - **Token X / 매 hardcoded color**: 매 #0A66FF 의 매 30곳 hard-code → 매 brand refresh 시 hell. - **매 LLM 의 final 결정**: 매 voice critic 의 false positive — 매 human review gate 필요. - **매 over-strict gate**: 매 PR 의 모든 brand drift block — 매 velocity 죽음. 매 warning 우선. - **매 brand guide 의 stale**: 매 1년 X update — 매 quarterly 의 refresh 필요. ## 🧪 검증 / 중복 - 신뢰도 B (project-internal naming, 매 공개 standard X — W3C Design Tokens / Style Dictionary / Storybook 은 매 검증된 공개 standard). - 매 외부 source 의 추가 검증 시 A 로 승격. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — StyleCounsel 의 brand consistency tooling 정의 + W3C design tokens / LLM critic pipeline |