Communitygithub.com

Varnan-Tech/opendirectory

ブランドアセットとキーメッセージから、ハイエナジーなサズルリール(ハイプ動画)をMP4形式で生成します。ダイナミックなカット、太字テキストオーバーレイ、オプションの音楽を使用した高速モンタージュ形式。4つのトーンプリセットと、音楽ファイルに応じたビート同期カットに対応。HyperFrames(GSAP + ヘッドレスChromium + FFmpeg)上に構築。

opendirectory とは?

これは、ブランドアセットとキーメッセージから、プロフェッショナルでハイエナジーなサズルリール(ハイプ動画)を生成するAIエージェントスキルです。動画は「Cold Open」(導入)、「Build」(展開)、「Peak」(山場)、「Land」(着地)の4セクション構造で、energetic(エネルギッシュ)、cinematic(シネマティック)、emotional(エモーショナル)、professional(プロフェッショナル)の4つのトーンプリセットを提供します。音楽ファイルが指定された場合、ビートに合わせたカット(ビート同期)を自動実行します。このスキルは、Claude CodeやCursor、CodexなどのAIエージェントと連携し、ユーザーが「sizzle reel」「hype video」「highlight reel」「launch hype」「conference opener」「event promo video」「investor pitch video」「brand video montage」といったキーワードで呼び出すことを想定しています。内部では、GSAPを使ったHTMLアニメーションをヘッドレスChromiumでレンダリングし、FFmpegでH.264のMP4ファイルとして出力する「HyperFrames」パイプラインを採用。料金のかかるAI動画API(Runway、Pikaなど)に依存せず、Node.jsとFFmpegのみでゼロランニングコストを実現している点が最大の特徴です。注意点として、ブランド名は必ず最後の「Land」セクションでのみ表示し、それ以前は表示しない、といった厳格なルールに従って動画を構成します。

対応✓Claude Code✓Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/Varnan-Tech/opendirectory/tree/main/skills/vid-sizzle-reel

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

vid-sizzle-reel

ブランドアセットとキーメッセージから、ハイエナジーなサズルリール(ハイプ動画)を生成します。 パイプライン: HyperFrames HTML 構成 (GSAP タイムライン) → ヘッドレス Chromium → FFmpeg H.264 MP4。 Runway、Pika、AI 動画 API は不要。Node.js + FFmpeg 以外のランタイムコストはゼロ。

vid-product-launch との違い:

  • vid-product-launch は物語を語る — ひとつの明かし、5つのセクション、緊張の弧
  • vid-sizzle-reel はエネルギーと興奮を生み出す — 高速カット、音楽ファースト、単一のストーリービートなし

重要ルール(生成前に毎回読むこと)

  1. キーメッセージは自分で書くか、ユーザーに書いてもらうこと。 これらは画面に表示される正確なフレーズです。「AI がなんとかする」は中身のないものになります。3〜5行の鋭いメッセージが、サズルリールの全内容です。

  2. ブランド名は Land セクションでのみ表示すること。 Cold Open と Build ではブランド名を出さずに緊張感を構築します。Land セクションがその見返りです。

  3. リズムパターンを、HTML を書く前にスクリプトの先頭にコメントとして宣言すること。 フォーマット: // RHYTHM: flash-sequence | Cold[0-5s]: stat | Build[5-40s]: msg(1.5s)|flash|... | Peak[40-55s]: ... | Land[55-60s]: logo+CTA。すべてのタイミング決定はこれに照らしてチェックします。

  4. まず CSS で最終状態のレイアウトを構築すること — GSAP はまだ使わない。 すべての要素を、最も見える瞬間の位置に静的な CSS で配置します。その後、gsap.from() で GSAP による登場アニメーション、gsap.to() で終了アニメーションを追加します。アニメーションの開始状態で配置しないこと。

  5. タイミングを持つすべての要素に class="clip" を付与すること。 HyperFrames で必須です。これがないと、要素はプレイヤーから見えなくなります。

  6. すべてのクリップに data-start、data-duration、data-track-index を設定すること。 例外はありません。同じトラックインデックスのクリップは重複できません — 異なるトラックインデックスを使用してください。

  7. Math.random() を使用しないこと。 HyperFrames では決定論的な構成が必要です。疑似乱数値が必要な場合は、シード付き PRNG(mulberry32)を使用してください。

  8. すべての GSAP タイムラインは { paused: true } で開始し、window.__timelines["comp-id"] に登録すること。 HyperFrames プレイヤーが再生を制御します — tl.play() を呼び出さないでください。

  9. .scene-content コンテナに position: absolute を使用しないこと。 width:100%; height:100%; padding:Npx; display:flex を使用してください。position:absolute は装飾要素にのみ予約します。

  10. 音楽: 別の <audio> 要素に data-track-index を設定すること。 動画は muted playsinline にする必要があります。<video> 要素に音声を入れないでください。

  11. HTML を生成する前に、references/cut-patterns.md と references/tone-presets.md を読むこと。

  12. HTML をチャットにダンプしないこと。 ファイルに保存し、概要のみを表示してください。


ステップ 1: 情報収集

必須:

  • key_messages — 画面に表示する、3〜5行のキャッチーなフレーズ(ユーザーが書く必要があります)

オプションパラメータとデフォルト値:

パラメータデフォルト説明
brand_assetsなしロゴ URL/パス、ブランドカラー(16進数)、キースクリーンショット
toneenergeticenergetic / cinematic / emotional / professional
musicなしファイルパス、または BPM/ジャンル文字列(例: "128bpm electronic")
duration6030 / 60 / 90 秒
aspect_ratio9:169:16 (1080x1920) / 16:9 (1920x1080)
cut_styleautofast (1-2s) / cinematic (3-5s) — auto は tone から自動設定
end_cardautoLand セクション用のロゴ + タグライン + CTA URL

cut_style の自動デフォルト値: energetic → fast; professional → fast (2s); cinematic → cinematic; emotional → mixed

key_messages がない場合、正確に次のように質問してください:

「サズルリールを生成するには、キーメッセージが必要です。画面に表示する正確なフレーズを教えてください。3〜5行のキャッチーなメッセージをお願いします。これがこの動画で最も重要な要素です。

例: '500以上のグロースチームが利用' / '日単位から分単位へ' / 'Claude、Codex、Geminiと連携'

また、トーン(energetic/cinematic/emotional/professional)、尺(30/60/90秒)、ブランドカラーやロゴ URL があると便利です。」

キーメッセージが提供されたら → すぐにステップ 2 に進みます。


ステップ 2: HyperFrames のインストール

HyperFrames スキルをインストールします(初回のみ — すでにインストール済みの場合はスキップ):

npx skills add heygen-com/hyperframes

環境を確認:

node --version   # 22 以上であること
ffmpeg -version  # インストールされていること

プロジェクトをスキャフォールド:

npx hyperframes init sizzle-[slug] --example kinetic-type --non-interactive
cd sizzle-[slug]

Slug: end_card のブランド名または最初のキーメッセージから kebab-case で、最大 25 文字。


ステップ 3: 内部アーキテクチャ(ユーザーには非表示)

1. duration + cut_style からカットポイントのタイミングを導出:

セクション30s60s90s
Cold Open0-5s0-5s0-8s
Build5-25s5-40s8-65s
Peak25-28s40-55s65-80s
Land28-30s55-60s80-90s

すべての境界をミリ秒に変換します。cut_style からシーンごとの長さを計算:

  • fast: メッセージあたり 1.2s-1.8s(デフォルト 1.5s を使用)
  • cinematic: メッセージあたり 3.5s-5.0s(デフォルト 4.0s を使用)
  • mixed: セクションのエネルギーに応じて 2.0s-4.0s で変動

2. key_messages をシーンにマッピング:

  • Cold Open(1シーン): 1つのインパクト統計または質問 — ブランド名なし、興味をそそる
  • Build: キーメッセージごとに 1 シーン
  • Peak: 最も強いメッセージを 2 倍のスケールで繰り返す、または 2 つのメッセージを高速フラッシュで組み合わせる
  • Land: ブランド名 + タグライン + CTA URL

3. 音楽が提供された場合、ビート同期を検出:

npx hyperframes tts --analyze-beats [music-file]

利用できない場合は、BPM から計算: beat_ms = 60000 / BPM。2 拍ごとにカットを合わせます。

4. トーンプリセットを選択 — CSS トークンについては references/tone-presets.md を参照。

5. リズムパターンを宣言 — スクリプトの先頭にコメントを書きます:

// RHYTHM: flash-sequence
// Cold Open [0-5000ms]: stat
// Build [5000-40000ms]: msg-1(1500ms)|flash|msg-2(1500ms)|flash|msg-3(1500ms)|flash|msg-4(1500ms)|flash|build-accum(10000ms)
// Peak [40000-55000ms]: msg-strongest(1200ms)|flash|msg-2nd(1200ms)|flash|HOLD(5600ms)
// Land [55000-60000ms]: logo+tagline+cta

6. ピクセル寸法を決定:

  • 9:16 → W=1080、H=1920(デフォルト — Instagram Reels、TikTok、YouTube Shorts)
  • 16:9 → W=1920、H=1080

ステップ 4: HyperFrames HTML 構成

コードを書く前に references/cut-patterns.md と HyperFrames スキル (/hyperframes) を読んでください。

必須の HTML スケルトン:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
[トーンプリセットからのフォント CDN リンク]
<style>
:root {
  [トーンプリセットからのすべての CSS トークン]
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
</style>
</head>
<body>
<div
  data-composition-id="sizzle-[slug]"
  data-width="[W]"
  data-height="[H]"
  style="position:relative;width:[W]px;height:[H]px;overflow:hidden;background:var(--bg)"
>

  [cut-flash: true の場合]
  <div id="cut-flash"
    style="position:absolute;inset:0;background:var(--cut-flash-bg);opacity:0;pointer-events:none;z-index:200"></div>
  [end if]

  [film-grain: true の場合]
  <canvas id="grain-overlay"
    width="240" height="135"
    style="position:absolute;inset:0;width:[W]px;height:[H]px;pointer-events:none;opacity:0.022;mix-blend-mode:overlay;z-index:50"></canvas>
  [end if]

  [vignette: true の場合]
  <div id="vignette-overlay"
    style="position:absolute;inset:0;background:radial-gradient(ellipse at center,transparent 35%,rgba(0,0,0,0.65) 100%);pointer-events:none;z-index:51"></div>
  [end if]

  <!-- シーン — シーンごとに 1 つの div -->
  <div id="scene-cold"
    class="clip"
    data-start="0"
    data-duration="5"
    data-track-index="0"
    style="position:absolute;inset:0;opacity:0"
  >
    <div class="scene-content" style="width:100%;height:100%;padding:120px;display:flex;flex-direction:column;align-items:center;justify-content:center;box-sizing:border-box">
      [cold open コンテンツ — 1 つの統計またはインパクトフレーズ、ブランド名なし]
    </div>
  </div>

  [Build シーンごとに 1 つの div、data-start はカット時間分ずつ増加]
  [Peak シーン]
  [Land シーン — ブランド名 + タグライン + CTA]

  [音楽が提供された場合]
  <audio id="music"
    class="clip"
    data-start="0"
    data-duration="[total_duration]"
    data-track-index="10"
    data-volume="0.85"
    src="[music_path]"
  ></audio>
  [end if]

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
  <script>
  // ── リズム宣言 ──────────────────────────────────────────────────────────────
  // RHYTHM: [flash-sequence | cinematic-hold | beat-sync | mixed]
  // Cold Open [0-Nms]: ...
  // Build [N-Nms]: ...
  // Peak [N-Nms]: ...
  // Land [N-Nms]: ...

  // ── シード付き PRNG(grain のみ — その他の乱数は使用しない)───────────────────
  function mulberry32(seed) {
    return function() {
      seed |= 0; seed = seed + 0x6D2B79F5 | 0;
      let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
      t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
      return ((t ^ t >>> 14) >>> 0) / 4294967296;
    };
  }

  [film-grain: true の場合]
  // ── フィルムグレイン(cinematic/emotional のみ)─────────────────────────────
  const grainCanvas = document.getElementById('grain-overlay');
  const grainCtx = grainCanvas ? grainCanvas.getContext('2d') : null;
  // グレインは GSAP ティッカーで更新(フレームキャプチャではない — HyperFrames が処理)
  [end if]

  // ── GSAP タイムライン ───────────────────────────────────────────────────────
  const tl = gsap.timeline({ paused: true });

  // ── COLD OPEN ───────────────────────────────────────────────────────────────
  [cold open の登場と終了のトゥイーン — 正確なパターンは cut-patterns.md を参照]

  // ── BUILD セクション ─────────────────────────────────────────────────────────
  [メッセージごとのトゥイーン — cut-patterns.md の flash-sequence または cinematic-hold]

  // ── PEAK セクション ─────────────────────────────────────────────────────────
  [peak トゥイーン — build と同じパターンだがタイミングはよりタイトに]

  // ── LAND セクション ─────────────────────────────────────────────────────────
  [land の登場 — ロゴ、タグライン、CTA。終了なし — 最後まで保持]

  // ── タイムライン登録 ────────────────────────────────────────────────────────
  window.__timelines = window.__timelines || {};
  window.__timelines["sizzle-[slug]"] = tl;
  </script>
</div>
</body>
</html>

デザイン品質ルール:

  • Cold open の統計: 16:9 の場合はフォントサイズ ≥160px、9:16 の場合は ≥100px
  • キーメッセージ: フォントサイズ ≥80px — 一目で読めること
  • Land セクションのブランド名: 16:9 の場合は ≥120px
  • すべての色はプリセットのトークン変数から — フリーヘックスは不可。var(--accent) リテラル16進数のみ、canvas の fillStyle 内で使用
  • scene-content は常に padding + flex を使用 — コンテンツコンテナに position:absolute は使用しない
  • data-start を持つすべての要素に class="clip"

ステップ 5: セルフ QA(ステップ 6 の前にすべての失敗を修正すること)

コンテンツ:

  • key_messages — 各フレーズが正確に 1 回出現、重複なし
  • ブランド名は Land セクションでのみ表示(cold open、build、peak では表示しない)
  • Cold open にはブランド名も製品名も含まれていない — 統計またはインパクトフレーズのみ
  • Land セクションに以下がある: ブランド名 + タグライン + CTA URL(最低 3 要素)
  • end_card CTA URL が最終フレームに存在する

HyperFrames 契約:

  • data-start を持つすべての要素に class="clip"
  • すべてのクリップに data-start、data-duration、data-track-index
  • ルートのコンポジション div に data-composition-id
  • window.__timelines["sizzle-[slug]"] = tl が登録されている
  • すべてのタイムラインは { paused: true } で開始
  • Math.random() なし — シード付き PRNG のみ
  • tl.play() または tl.resume() の呼び出しなし

GSAP / レイアウト:

  • すべての登場は gsap.from()(画面外から CSS 位置へ)
  • すべての終了は gsap.to()(CSS 位置から画面外へ)
  • .scene-content コンテナに position:absolute なし
  • リズムパターンがスクリプトの先頭にコメントとして宣言されている

カットタイミング:

  • fast トーン: 平均カット時間 ≤ 2.0s
  • cinematic トーン: 平均カット時間 ≥ 3.0s
  • energetic トーンの場合、カット境界ごとにカットフラッシュが発火(60ms、opacity 0→1→0)
  • 同じトラックのクリップは重複しない(すべての data-track-index グループを確認)

SFX:

  • window.__sfxTimeline が存在し、タイムライン登録の前に配置されている
  • キーメッセージごとの word-hit イベント
  • Build → Peak の遷移境界での whoosh
  • Land 開始時の cta-chime
  • 500ms より前に SFX が発火しない

ステップ 6: Lint、レンダリング、出力

npx hyperframes lint
npx hyperframes inspect --json

すべての lint エラーを修正します。すべての inspect エラー(テキストオーバーフロー、クリップがコンテナからはみ出すなど)を修正します。その後、レンダリング:

npx hyperframes render --output sizzle/[slug]/sizzle-reel.mp4

出力:

## サズルリール: [end_card のブランド名]
トーン: [tone] | 尺: [N]s | カットスタイル: [cut_style] | アスペクト比: [ratio]
リズム: [宣言されたパターン]

セクション
  Cold Open [0-Ns]:  [インパクト統計またはフレーズ]
  Build     [N-Ns]:  [N 個のキーメッセージをリスト]
  Peak      [N-Ns]:  [最も強いメッセージを最大スケールで]
  Land      [N-Ns]:  [ブランド名] + "[タグライン]" + [CTA URL]

ファイル
  Source: sizzle/[slug]/index.html
  Output: sizzle/[slug]/sizzle-reel.mp4

SFX タイムライン(すべてのコンポジションに埋め込む)

vid-product-launch と同じ FFmpeg 合成 SFX システム。window.__sfxTimeline を GSAP タイムライン登録の直前に配置します。

サズルリール用の SFX タイプリファレンス:

タイプ音声長さ配置
word-hitサブパンチ (50Hz) + 過渡クリック (2.2kHz) + ノイズバースト180msキーメッセージシーン開始ごとに 1 回
whoosh2バンドノイズスイープ (1.1kHz ボディ + 4-8kHz エアー)700msBuild → Peak 境界
cta-chimeAメジャーコード (440+554+659+880Hz) + 反響ベルのきらめき1.2sLand 開始と同時
window.__sfxTimeline = [
  // キーメッセージごとに 1 つの word-hit(シーン開始時間から計算)
  { ms: MSG_1_START_MS,           sfx: 'word-hit',   vol: 0.50 },
  { ms: MSG_2_START_MS,           sfx: 'word-hit',   vol: 0.50 },
  { ms: MSG_3_START_MS,           sfx: 'word-hit',   vol: 0.50 },
  // ... 各メッセージ分繰り返す
  { ms: PEAK_START_MS - 700,      sfx: 'whoosh',     vol: 0.55 },
  { ms: LAND_START_MS,            sfx: 'cta-chime',  vol: 0.65 },
];

すべての ms 値は、宣言されたセクションの境界から計算します。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

Varnan-Tech/opendirectory

Use when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.

Varnan-Tech/opendirectory

World-class brand strategist and naming expert. Uses an interrogation-led discovery phase to extract your brand's DNA, then applies scientific naming frameworks (Phonosemantics) and automated multi-TLD domain checking.

Varnan-Tech/opendirectory

Use when the user asks to generate or update a project's CLAUDE or AGENTS context file from a codebase scan. Writes a focused file under 100 lines containing only the non-obvious build commands, conventions, and gotchas Claude Code needs.

Varnan-Tech/opendirectory

Use when the user wants to verify cold emails, enrich a lead list, or autonomously guess email addresses from a CSV using ValidEmail.co or the open-source Reacher engine.

Varnan-Tech/opendirectory

Competitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.

Varnan-Tech/opendirectory

Give it your product URL or description. It finds your top 5 competitors, runs three-track PR research across all of them (editorial, podcasts, communities), identifies which channels appear most frequently, looks up the journalist or host for each, and returns a tiered outreach list with story angles and ready-to-send cold pitch drafts tailored to your product. Use when asked to find PR opportunities, discover where competitors got featured, build a media outreach list, find which journalists cover my space, or get pitch templates for press coverage.

Varnan-Tech/opendirectory

Generate high-converting, deep-dive growth case studies in MDX format. Use this skill when asked to write a case study or blog post about a company's growth, tech stack, or product-led strategy. It handles the full pipeline (researching the company via Tavily, generating a 16:9 cover image, quality checking the draft, uploading assets to cloud storage, and pushing directly to the target repository).

Varnan-Tech/opendirectory

Scans your project for outdated npm, pip, Cargo, Go, or Ruby packages. Runs a CVE security audit. Fetches changelogs, summarizes breaking changes with Gemini, and opens one PR per risk group (patch, minor, major). Includes Diagnosis Mode for install conflicts. Use when asked to update dependencies, check for outdated packages, open dependency PRs, scan for package updates, audit for CVEs, or flag breaking changes in upgrades. Trigger when a user says "check for outdated packages", "update my dependencies", "open PRs for dependency updates", "scan for CVEs", or "which packages need upgrading".

Varnan-Tech/opendirectory

Generates and updates README.md and API reference docs by reading your codebase's functions, routes, types, schemas, and architecture. Uses graphify to build a knowledge graph first, then writes accurate docs from it. Use when asked to write docs, generate a README, document an API, update stale docs, create an API reference from code, add an architecture section, or document a project in any language. Trigger when a user says their docs are missing, outdated, or wants to document their codebase without writing it manually.

Varnan-Tech/opendirectory

Evaluates expired domain candidates against a target niche, scores them by topical relevance, historical activity level, and history cleanliness, then outputs a ranked shortlist with explainable reasoning and risk flags.

Varnan-Tech/opendirectory

Brutally honest developer-experience audit for a GitHub repo. Scores 10 DX dimensions (time-to-first-success, README clarity, visual proof, install, quick-start, docs, examples, community, trust, marketing), writes a shareable roast in the requested tone (brutal/honest/kind), produces a prioritized action plan ranked by impact × effort, and sketches an ideal README. Trigger when user says "roast my repo", "audit my README", "dx audit", "developer experience review", "score my GitHub project", "before launch checklist", or "make my repo shareable".

Varnan-Tech/opendirectory

Drafts and designs a complete HTML email newsletter from a topic or content brief. Outputs paste-ready HTML for Loops, Mailchimp, Beehiiv, Resend, or any standard email platform. Includes subject line options and plain-text fallback. Trigger when a user says "write a newsletter", "draft an email newsletter", "create an HTML email", "design an email for my subscribers", or "write a newsletter about [topic]".

Varnan-Tech/opendirectory

Takes a GitHub PR URL or the current branch and writes a plain-English explanation of what it does and why, then posts it as a PR comment. Use when asked to explain a PR, summarize a pull request, write a plain-English description of a PR, add a summary comment to a PR, or understand what a PR changes. Trigger when a user says "explain this PR", "summarize this pull request", "what does this PR do", "add a comment explaining the PR", or shares a GitHub PR URL and asks what it does.

Varnan-Tech/opendirectory

Audit how often LLMs recommend your brand vs competitors and generate a GEO action plan.

Varnan-Tech/opendirectory

Takes a competitor's public GitHub repo URL, fetches their open issues via the GitHub REST API, filters noise locally, clusters issues into 6 demand categories, computes a demand score per issue and per cluster, and outputs a ranked demand gap report with a GTM messaging brief. Use when asked to scan a competitor's GitHub issues, find what their users are begging for, turn GitHub complaints into product positioning, identify competitor feature gaps, or generate messaging from real user demand. Trigger when a user says "scan competitor issues", "what are users asking for on X repo", "find demand gaps in Y", "turn GitHub issues into messaging", or "what should I build based on competitor complaints".

Varnan-Tech/opendirectory

Find recurring confusion in your repo's GitHub Discussions, rank it by urgency, and draft the actual docs fixes and content angles — with verbatim community quotes and source links as evidence.

Varnan-Tech/opendirectory

SEO keyword research workflow for blog generation using Google Trends data. Use when writing blog posts, planning content calendars, or optimizing articles for search engines. Finds breakout keywords, builds content structure, and generates SEO-optimized blog outlines targeting tech and developer audiences.

Varnan-Tech/opendirectory

Generates a professionally designed case study PDF for B2B SaaS sales and marketing. Supports 7 page layouts, 9 style presets, 1-4 page output. Trigger when user says "create a case study", "write a customer story", "make a case study PDF", "design a success story", "turn this customer win into a PDF".

Varnan-Tech/opendirectory

Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6. 1080×1080px default, 5 style presets, highlight annotations. Trigger when user says "create a chart", "visualize data", "make a bar chart", "line graph", "pie chart", "data visualization", "chart this data", "plot", "graph", or "visualize these numbers".

Varnan-Tech/opendirectory

Fetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.

関連スキル