ネタ神AI Pro – アイデアメーカー

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>ネタ神AI Pro - アイデアメーカー</title>

  <style>
    :root {
      --bg: #070914;
      --bg2: #111831;
      --card: rgba(255, 255, 255, 0.08);
      --card2: rgba(255, 255, 255, 0.13);
      --text: #f5f7ff;
      --muted: #aeb8df;
      --line: rgba(255, 255, 255, 0.16);
      --primary: #7c5cff;
      --cyan: #00d4ff;
      --green: #38ffad;
      --yellow: #ffd35c;
      --red: #ff5c7c;
      --shadow: 0 22px 55px rgba(0, 0, 0, 0.35);
      --radius: 22px;
    }

    body.light {
      --bg: #eef2ff;
      --bg2: #ffffff;
      --card: rgba(255, 255, 255, 0.8);
      --card2: rgba(255, 255, 255, 0.95);
      --text: #151829;
      --muted: #566179;
      --line: rgba(20, 30, 60, 0.14);
      --shadow: 0 18px 45px rgba(40, 60, 110, 0.16);
    }

    * {
      box-sizing: border-box;
    }

    body {
      margin: 0;
      min-height: 100vh;
      font-family: "Segoe UI", "Hiragino Sans", "Yu Gothic", sans-serif;
      color: var(--text);
      background:
        radial-gradient(circle at 20% 10%, rgba(124, 92, 255, 0.32), transparent 28%),
        radial-gradient(circle at 90% 20%, rgba(0, 212, 255, 0.24), transparent 28%),
        radial-gradient(circle at 50% 100%, rgba(255, 92, 124, 0.15), transparent 32%),
        linear-gradient(135deg, var(--bg), var(--bg2));
      transition: 0.25s;
    }

    button,
    input,
    select,
    textarea {
      font-family: inherit;
    }

    button {
      border: 1px solid var(--line);
      border-radius: 14px;
      background: var(--card2);
      color: var(--text);
      padding: 11px 14px;
      font-weight: 800;
      cursor: pointer;
      transition: 0.2s;
      backdrop-filter: blur(12px);
    }

    button:hover {
      transform: translateY(-2px);
      filter: brightness(1.08);
    }

    .btn-main {
      border: none;
      background: linear-gradient(135deg, var(--primary), var(--cyan));
      color: white;
      box-shadow: 0 16px 35px rgba(0, 212, 255, 0.2);
    }

    .btn-green {
      border: none;
      background: linear-gradient(135deg, #13bf84, var(--green));
      color: #06120d;
    }

    .btn-red {
      border-color: rgba(255, 92, 124, 0.4);
      background: rgba(255, 92, 124, 0.14);
    }

    .app {
      width: min(1380px, 94%);
      margin: 0 auto;
      padding: 28px 0 70px;
    }

    header {
      display: flex;
      justify-content: space-between;
      gap: 18px;
      align-items: center;
      margin-bottom: 22px;
    }

    .brand {
      display: flex;
      align-items: center;
      gap: 14px;
    }

    .logo {
      width: 58px;
      height: 58px;
      border-radius: 20px;
      background: linear-gradient(135deg, var(--primary), var(--cyan));
      display: grid;
      place-items: center;
      font-size: 30px;
      box-shadow: 0 20px 45px rgba(124, 92, 255, 0.35);
    }

    h1, h2, h3, h4, p {
      margin-top: 0;
    }

    .brand h1 {
      margin: 0;
      font-size: clamp(27px, 4vw, 46px);
      letter-spacing: 0.03em;
    }

    .brand p {
      margin: 4px 0 0;
      color: var(--muted);
      font-size: 14px;
    }

    .header-actions {
      display: flex;
      gap: 10px;
      flex-wrap: wrap;
      justify-content: flex-end;
    }

    .hero {
      border: 1px solid var(--line);
      background: var(--card);
      border-radius: var(--radius);
      box-shadow: var(--shadow);
      backdrop-filter: blur(16px);
      padding: 26px;
      margin-bottom: 22px;
      overflow: hidden;
      position: relative;
    }

    .hero::after {
      content: "";
      position: absolute;
      width: 320px;
      height: 320px;
      right: -120px;
      bottom: -160px;
      border-radius: 50%;
      background: rgba(0, 212, 255, 0.13);
      filter: blur(8px);
    }

    .hero h2 {
      font-size: clamp(24px, 3vw, 40px);
      margin-bottom: 10px;
      line-height: 1.35;
    }

    .hero p {
      color: var(--muted);
      line-height: 1.8;
      max-width: 900px;
      margin-bottom: 0;
    }

    .stats {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 14px;
      margin-bottom: 22px;
    }

    .stat {
      border: 1px solid var(--line);
      background: var(--card);
      border-radius: 18px;
      padding: 16px;
      box-shadow: var(--shadow);
    }

    .stat strong {
      display: block;
      font-size: 24px;
      margin-bottom: 3px;
    }

    .stat span {
      color: var(--muted);
      font-size: 13px;
    }

    .layout {
      display: grid;
      grid-template-columns: 420px 1fr;
      gap: 22px;
      align-items: start;
    }

    .panel {
      border: 1px solid var(--line);
      background: var(--card);
      border-radius: var(--radius);
      box-shadow: var(--shadow);
      backdrop-filter: blur(16px);
      overflow: hidden;
    }

    .panel-header {
      padding: 18px 20px;
      border-bottom: 1px solid var(--line);
      display: flex;
      justify-content: space-between;
      gap: 12px;
      align-items: center;
    }

    .panel-header h3 {
      margin: 0;
      font-size: 19px;
    }

    .panel-body {
      padding: 20px;
    }

    .badge {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      padding: 6px 10px;
      border-radius: 999px;
      background: linear-gradient(135deg, var(--green), var(--cyan));
      color: #06121c;
      font-size: 12px;
      font-weight: 900;
      white-space: nowrap;
    }

    .form-group {
      margin-bottom: 16px;
    }

    label {
      display: block;
      color: var(--muted);
      font-size: 13px;
      font-weight: 800;
      margin-bottom: 8px;
    }

    input,
    select,
    textarea {
      width: 100%;
      border: 1px solid var(--line);
      background: rgba(0, 0, 0, 0.22);
      color: var(--text);
      border-radius: 14px;
      padding: 12px 13px;
      outline: none;
      font-size: 15px;
      transition: 0.2s;
    }

    body.light input,
    body.light select,
    body.light textarea {
      background: rgba(255, 255, 255, 0.85);
    }

    select option {
      background: #10162a;
      color: white;
    }

    input:focus,
    select:focus,
    textarea:focus {
      border-color: rgba(0, 212, 255, 0.85);
      box-shadow: 0 0 0 4px rgba(0, 212, 255, 0.12);
    }

    textarea {
      min-height: 105px;
      resize: vertical;
      line-height: 1.7;
    }

    .two {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 12px;
    }

    .chips {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-top: 10px;
    }

    .chip {
      border: 1px solid var(--line);
      background: rgba(255, 255, 255, 0.08);
      color: var(--muted);
      border-radius: 999px;
      padding: 8px 10px;
      font-size: 12px;
      font-weight: 800;
      cursor: pointer;
      transition: 0.2s;
    }

    .chip:hover {
      color: var(--text);
      border-color: rgba(0, 212, 255, 0.7);
      transform: translateY(-1px);
    }

    .button-grid {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 10px;
      margin-top: 16px;
    }

    .button-grid .wide-btn {
      grid-column: 1 / -1;
    }

    .result-tools {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      justify-content: flex-end;
    }

    .empty {
      text-align: center;
      padding: 70px 24px;
      color: var(--muted);
    }

    .empty .icon {
      font-size: 64px;
      margin-bottom: 12px;
    }

    .idea-list {
      display: grid;
      gap: 16px;
    }

    .idea-card {
      border: 1px solid var(--line);
      background: rgba(0, 0, 0, 0.18);
      border-radius: 20px;
      overflow: hidden;
    }

    body.light .idea-card {
      background: rgba(255, 255, 255, 0.78);
    }

    .idea-top {
      padding: 20px;
      border-bottom: 1px solid var(--line);
      display: grid;
      grid-template-columns: 1fr auto;
      gap: 15px;
      align-items: start;
    }

    .idea-title {
      margin: 0;
      font-size: clamp(24px, 3vw, 36px);
      line-height: 1.25;
    }

    .meta {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin-top: 10px;
    }

    .pill {
      font-size: 12px;
      font-weight: 900;
      padding: 6px 9px;
      border-radius: 999px;
      border: 1px solid var(--line);
      color: var(--muted);
      background: rgba(255,255,255,0.07);
    }

    .score-box {
      width: 96px;
      text-align: center;
      padding: 12px;
      border-radius: 18px;
      background: linear-gradient(135deg, rgba(124, 92, 255, 0.35), rgba(0, 212, 255, 0.24));
      border: 1px solid var(--line);
    }

    .score-box strong {
      display: block;
      font-size: 26px;
    }

    .score-box span {
      color: var(--muted);
      font-size: 12px;
      font-weight: 800;
    }

    .catch {
      padding: 16px 20px;
      font-size: 17px;
      line-height: 1.7;
      background: rgba(255, 255, 255, 0.07);
      border-bottom: 1px solid var(--line);
    }

    .idea-body {
      padding: 20px;
    }

    .sections {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 14px;
    }

    .section {
      border: 1px solid var(--line);
      border-radius: 17px;
      padding: 16px;
      background: rgba(0, 0, 0, 0.18);
    }

    body.light .section {
      background: rgba(255, 255, 255, 0.62);
    }

    .section.wide {
      grid-column: 1 / -1;
    }

    .section h4 {
      margin: 0 0 10px;
      font-size: 15px;
    }

    .section p,
    .section li {
      color: var(--muted);
      line-height: 1.75;
      font-size: 14px;
    }

    .section p {
      margin-bottom: 0;
    }

    .section ul,
    .section ol {
      margin: 0;
      padding-left: 22px;
    }

    .idea-actions {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      padding: 0 20px 20px;
    }

    .history-controls {
      display: grid;
      grid-template-columns: 1fr 180px;
      gap: 10px;
      margin-bottom: 14px;
    }

    .history-list {
      display: grid;
      gap: 10px;
    }

    .history-item {
      border: 1px solid var(--line);
      border-radius: 16px;
      padding: 13px;
      cursor: pointer;
      background: rgba(0, 0, 0, 0.15);
      transition: 0.2s;
    }

    body.light .history-item {
      background: rgba(255, 255, 255, 0.7);
    }

    .history-item:hover {
      transform: translateY(-2px);
      border-color: rgba(0, 212, 255, 0.6);
    }

    .history-item strong {
      display: block;
      margin-bottom: 5px;
    }

    .history-item small {
      color: var(--muted);
    }

    .toast {
      position: fixed;
      right: 20px;
      bottom: 20px;
      background: rgba(10, 15, 30, 0.94);
      color: white;
      border: 1px solid rgba(255,255,255,0.16);
      border-radius: 16px;
      padding: 14px 18px;
      box-shadow: var(--shadow);
      opacity: 0;
      transform: translateY(20px);
      pointer-events: none;
      transition: 0.25s;
      z-index: 100;
    }

    .toast.show {
      opacity: 1;
      transform: translateY(0);
    }

    .footer {
      margin-top: 28px;
      text-align: center;
      color: var(--muted);
      font-size: 13px;
    }

    @media (max-width: 1050px) {
      header {
        flex-direction: column;
        align-items: flex-start;
      }

      .layout {
        grid-template-columns: 1fr;
      }

      .stats {
        grid-template-columns: repeat(2, 1fr);
      }

      .sections {
        grid-template-columns: 1fr;
      }

      .idea-top {
        grid-template-columns: 1fr;
      }

      .score-box {
        width: 100%;
      }
    }

    @media (max-width: 620px) {
      .two,
      .button-grid,
      .history-controls,
      .stats {
        grid-template-columns: 1fr;
      }

      .header-actions {
        width: 100%;
      }

      .header-actions button {
        flex: 1;
      }
    }
  </style>
</head>

<body>
  <div class="app">
    <header>
      <div class="brand">
        <div class="logo">💡</div>
        <div>
          <h1>ネタ神AI Pro</h1>
          <p>API不要。ブラウザだけで動く創作・Webサービス企画メーカー</p>
        </div>
      </div>

      <div class="header-actions">
        <button onclick="toggleTheme()">テーマ切替</button>
        <button onclick="downloadText()">TXT出力</button>
        <button onclick="downloadJSON()">JSON出力</button>
        <button class="btn-red" onclick="clearAll()">全削除</button>
      </div>
    </header>

    <section class="hero">
      <h2>APIなしでも、かなり使える「企画書生成ツール」にする。</h2>
      <p>
        外部AIに接続せず、ローカルのテンプレート・ランダム生成・条件分岐だけで、Webサービス、AIツール、ゲーム、小説、SNSなどの企画案を作ります。
        API料金もキー管理も不要です。まず作品として公開しやすい形です。
      </p>
    </section>

    <section class="stats">
      <div class="stat">
        <strong id="statIdeas">0</strong>
        <span>今回生成した案</span>
      </div>
      <div class="stat">
        <strong id="statSaved">0</strong>
        <span>保存済みアイデア</span>
      </div>
      <div class="stat">
        <strong>0円</strong>
        <span>API利用料</span>
      </div>
      <div class="stat">
        <strong>100%</strong>
        <span>ローカル動作</span>
      </div>
    </section>

    <main class="layout">
      <section class="panel">
        <div class="panel-header">
          <h3>生成条件</h3>
          <span class="badge">NO API</span>
        </div>

        <div class="panel-body">
          <div class="two">
            <div class="form-group">
              <label for="genre">ジャンル</label>
              <select id="genre">
                <option>Webサービス</option>
                <option>AIツール</option>
                <option>ゲーム</option>
                <option>小説</option>
                <option>SNS</option>
                <option>動画サイト</option>
                <option>ポートフォリオ</option>
                <option>便利ツール</option>
                <option>学習サービス</option>
                <option>創作支援</option>
              </select>
            </div>

            <div class="form-group">
              <label for="mood">雰囲気</label>
              <select id="mood">
                <option>かっこいい</option>
                <option>やさしい</option>
                <option>近未来</option>
                <option>ファンタジー</option>
                <option>シンプル</option>
                <option>高級感</option>
                <option>かわいい</option>
                <option>ダーク</option>
                <option>実用的</option>
                <option>ゲーム風</option>
              </select>
            </div>
          </div>

          <div class="two">
            <div class="form-group">
              <label for="level">開発難易度</label>
              <select id="level">
                <option>簡単</option>
                <option>普通</option>
                <option>本格</option>
                <option>超本格</option>
              </select>
            </div>

            <div class="form-group">
              <label for="target">ターゲット</label>
              <select id="target">
                <option>個人クリエイター</option>
                <option>学生</option>
                <option>社会人</option>
                <option>在宅ワーカー</option>
                <option>ゲーム制作者</option>
                <option>小説家志望</option>
                <option>配信者</option>
                <option>初心者</option>
                <option>副業したい人</option>
              </select>
            </div>
          </div>

          <div class="two">
            <div class="form-group">
              <label for="amount">生成数</label>
              <select id="amount">
                <option value="1">1個</option>
                <option value="3" selected>3個</option>
                <option value="5">5個</option>
              </select>
            </div>

            <div class="form-group">
              <label for="style">出力スタイル</label>
              <select id="style">
                <option>企画書風</option>
                <option>サービス紹介風</option>
                <option>開発メモ風</option>
                <option>ピッチ資料風</option>
              </select>
            </div>
          </div>

          <div class="form-group">
            <label for="keywords">キーワード</label>
            <textarea id="keywords" placeholder="例:AI / RPG / SNS / メモ / 仕事 / 創作 / ポートフォリオ"></textarea>

            <div class="chips">
              <span class="chip" onclick="addKeyword('AI')">AI</span>
              <span class="chip" onclick="addKeyword('RPG')">RPG</span>
              <span class="chip" onclick="addKeyword('SNS')">SNS</span>
              <span class="chip" onclick="addKeyword('小説')">小説</span>
              <span class="chip" onclick="addKeyword('仕事')">仕事</span>
              <span class="chip" onclick="addKeyword('メモ')">メモ</span>
              <span class="chip" onclick="addKeyword('ポートフォリオ')">ポートフォリオ</span>
              <span class="chip" onclick="addKeyword('動画')">動画</span>
              <span class="chip" onclick="addKeyword('学習')">学習</span>
              <span class="chip" onclick="addKeyword('ゲーム開発')">ゲーム開発</span>
            </div>
          </div>

          <div class="form-group">
            <label for="problem">解決したい悩み</label>
            <textarea id="problem" placeholder="例:何を作ればいいかわからない。作業が続かない。アイデアを整理できない。"></textarea>
          </div>

          <div class="button-grid">
            <button class="btn-main wide-btn" onclick="generateIdeas()">アイデア生成</button>
            <button onclick="randomSet()">ランダム条件</button>
            <button onclick="makePractical()">現実的にする</button>
            <button onclick="makeFantasy()">派手にする</button>
            <button onclick="clearForm()">入力クリア</button>
          </div>
        </div>
      </section>

      <section class="panel">
        <div class="panel-header">
          <h3>生成結果</h3>
          <div class="result-tools">
            <button onclick="copyAll()">コピー</button>
            <button class="btn-green" onclick="saveAll()">全部保存</button>
          </div>
        </div>

        <div class="panel-body">
          <div id="result">
            <div class="empty">
              <div class="icon">🧠</div>
              <h2>まだアイデアはありません</h2>
              <p>左の条件を入れて「アイデア生成」を押してください。</p>
            </div>
          </div>
        </div>
      </section>
    </main>

    <section class="panel" style="margin-top:22px;">
      <div class="panel-header">
        <h3>保存したアイデア</h3>
        <span class="badge" id="savedCount">0件</span>
      </div>

      <div class="panel-body">
        <div class="history-controls">
          <input id="historySearch" placeholder="保存アイデアを検索" oninput="renderHistory()" />
          <select id="historyGenre" onchange="renderHistory()">
            <option value="all">全ジャンル</option>
            <option>Webサービス</option>
            <option>AIツール</option>
            <option>ゲーム</option>
            <option>小説</option>
            <option>SNS</option>
            <option>動画サイト</option>
            <option>ポートフォリオ</option>
            <option>便利ツール</option>
            <option>学習サービス</option>
            <option>創作支援</option>
          </select>
        </div>

        <div class="history-list" id="historyList"></div>
      </div>
    </section>

    <div class="footer">
      ネタ神AI Pro / APIなしローカル版 / HTML・CSS・JavaScriptのみ
    </div>
  </div>

  <div class="toast" id="toast">完了しました</div>

  <script>
    const DATA = {
      titleHeads: [
        "Nova", "Idea", "Neta", "Mira", "Chrono", "Elder", "Prompt", "Vision",
        "Craft", "Yume", "Neo", "Astra", "Luna", "Meta", "Spark", "Quest"
      ],

      titleTails: {
        "Webサービス": ["Hub", "Works", "Base", "Cloud", "Studio", "Panel", "Link", "Board"],
        "AIツール": ["AI", "Brain", "Agent", "Prompt", "Copilot", "Mind", "Assist", "Genius"],
        "ゲーム": ["Quest", "Chronicle", "Saga", "Blade", "Dungeon", "Legend", "Arc", "World"],
        "小説": ["Novel", "Story", "Tale", "Script", "Lore", "Ink", "Scene", "Dream"],
        "SNS": ["Verse", "Circle", "Post", "Talk", "Room", "Link", "Wave", "Nest"],
        "動画サイト": ["Tube", "Stream", "Clip", "Vision", "Cast", "Channel", "View", "Media"],
        "ポートフォリオ": ["Portfolio", "Gallery", "Works", "Profile", "Card", "Showcase", "Archive", "Page"],
        "便利ツール": ["Tool", "Memo", "Desk", "Kit", "Task", "Quick", "Utility", "Simple"],
        "学習サービス": ["Learn", "Study", "Lesson", "Skill", "Academy", "Trainer", "Coach", "Note"],
        "創作支援": ["Create", "Maker", "Muse", "Seed", "Craft", "Atelier", "Generator", "Factory"]
      },

      moodDesc: {
        "かっこいい": "鋭く洗練された印象で、使うだけで制作意欲が上がる",
        "やさしい": "初心者でも迷わない、安心感のある",
        "近未来": "AI時代らしい自動化と先進性を感じる",
        "ファンタジー": "クエストやギルドのような世界観を活かした",
        "シンプル": "余計な機能を削り、すぐ使えることに集中した",
        "高級感": "プロ向けツールのように落ち着いた印象の",
        "かわいい": "親しみやすく、毎日開きたくなる",
        "ダーク": "深い世界観と中二感を活かした",
        "実用的": "仕事や制作の効率化に直結する",
        "ゲーム風": "レベル、経験値、クエストのような要素を持つ"
      },

      features: {
        "Webサービス": ["ユーザー投稿", "検索", "タグ分類", "お気に入り", "ランキング", "管理画面", "コメント", "カテゴリ管理", "共有リンク", "レスポンシブUI"],
        "AIツール": ["文章生成", "テンプレート選択", "プロンプト保存", "履歴管理", "自動分類", "要約", "言い換え", "コピー", "お気に入り", "出力形式変更"],
        "ゲーム": ["キャラクター管理", "クエスト", "ステージ選択", "スキル", "装備", "敵図鑑", "ストーリー分岐", "進行度保存", "称号", "実績"],
        "小説": ["キャラ設定", "世界観管理", "章立て", "プロット", "セリフ案", "伏線メモ", "用語集", "文体変換", "シーン整理", "年表"],
        "SNS": ["タイムライン", "投稿", "いいね", "フォロー", "通知", "プロフィール", "ハッシュタグ", "DM風UI", "おすすめ投稿", "AI投稿提案"],
        "動画サイト": ["動画カード", "検索", "カテゴリ", "ランキング", "チャンネル", "視聴履歴", "コメント", "お気に入り", "おすすめ", "タグ"],
        "ポートフォリオ": ["作品カード", "リンク管理", "カテゴリ分類", "紹介文生成", "スキル表示", "実績一覧", "検索", "テーマ変更", "外部リンク", "更新履歴"],
        "便利ツール": ["メモ", "ToDo", "検索", "タグ", "自動整形", "コピー", "履歴", "エクスポート", "チェックリスト", "通知風表示"],
        "学習サービス": ["学習記録", "復習リスト", "クイズ", "用語集", "進捗", "AI風解説", "弱点メモ", "計画作成", "達成バッジ", "問題生成"],
        "創作支援": ["アイデア生成", "タイトル案", "キャッチコピー", "キャラ案", "世界観案", "企画書化", "画像プロンプト", "構成案", "メモ保存", "ネタ帳"]
      },

      monetization: [
        "無料版+Pro版",
        "広告表示",
        "買い切り版",
        "テンプレート販売",
        "月額プレミアム",
        "法人向けプラン",
        "追加保存枠の課金",
        "作品公開ページの有料カスタム",
        "支援・投げ銭",
        "素材パック販売"
      ],

      risks: [
        "機能を増やしすぎると完成しにくくなる",
        "最初からログインや課金を入れると開発が重くなる",
        "ターゲットが広すぎると特徴が薄くなる",
        "保存機能の設計を後回しにすると作り直しが出やすい",
        "見た目だけ作って実用性が弱いと使われにくい",
        "スマホ対応を忘れると使い勝手が落ちる"
      ],

      firstSteps: {
        "簡単": ["1画面UIを作る", "入力欄と生成ボタンを作る", "結果表示を作る", "コピー機能を付ける", "ローカル保存を付ける"],
        "普通": ["基本UIを作る", "複数パターン生成を作る", "履歴保存を作る", "検索と絞り込みを作る", "テキスト出力を作る"],
        "本格": ["MVPを作る", "保存データ構造を決める", "ログインなし版を完成させる", "ユーザー登録版を検討する", "公開ページを整える"],
        "超本格": ["小さいMVPを先に作る", "フロントとバックエンドを分ける", "DB設計をする", "課金やログインを後から追加する", "運用コストを確認する"]
      }
    };

    let currentIdeas = [];
    let generatedCount = 0;

    function $(id) {
      return document.getElementById(id);
    }

    function val(id) {
      return $(id).value.trim();
    }

    function pick(arr) {
      return arr[Math.floor(Math.random() * arr.length)];
    }

    function shuffle(arr) {
      return [...arr].sort(() => Math.random() - 0.5);
    }

    function escapeHTML(str) {
      return String(str)
        .replaceAll("&", "&amp;")
        .replaceAll("<", "&lt;")
        .replaceAll(">", "&gt;")
        .replaceAll('"', "&quot;")
        .replaceAll("'", "&#039;");
    }

    function addKeyword(word) {
      const box = $("keywords");
      if (!box.value.includes(word)) {
        box.value = box.value ? box.value + " / " + word : word;
      }
    }

    function randomSet() {
      randomSelect("genre");
      randomSelect("mood");
      randomSelect("level");
      randomSelect("target");
      randomSelect("style");

      const sets = [
        "AI / メモ / 作業効率",
        "RPG / クエスト / 進捗管理",
        "SNS / 投稿 / AI風返信",
        "小説 / 世界観 / キャラクター",
        "在宅ワーク / 日報 / 整理",
        "ポートフォリオ / 作品 / 自動紹介",
        "動画 / まとめ / ランキング",
        "学習 / 復習 / クイズ",
        "ゲーム開発 / アイデア / 仕様書",
        "創作 / ネタ帳 / 企画書"
      ];

      const problems = [
        "何を作ればいいかわからない",
        "作業が続かない",
        "アイデアが散らばって整理できない",
        "作品紹介文を書くのが難しい",
        "学習した内容を忘れやすい",
        "毎日の進捗を見える化したい",
        "企画を作っても途中で止まりやすい"
      ];

      $("keywords").value = pick(sets);
      $("problem").value = pick(problems);
      showToast("ランダム条件を入れました");
    }

    function randomSelect(id) {
      const el = $(id);
      el.selectedIndex = Math.floor(Math.random() * el.options.length);
    }

    function makePractical() {
      $("mood").value = "実用的";
      $("level").value = "簡単";
      $("style").value = "開発メモ風";
      if (!$("problem").value) {
        $("problem").value = "毎日の作業やアイデアを整理して、次にやることを明確にしたい";
      }
      showToast("現実的な条件に寄せました");
    }

    function makeFantasy() {
      $("mood").value = "ファンタジー";
      $("style").value = "サービス紹介風";
      if (!$("keywords").value.includes("ギルド")) {
        addKeyword("ギルド");
        addKeyword("クエスト");
      }
      showToast("派手な条件に寄せました");
    }

    function clearForm() {
      $("keywords").value = "";
      $("problem").value = "";
      showToast("入力をクリアしました");
    }

    function generateIdeas() {
      const amount = Number(val("amount"));
      currentIdeas = [];

      for (let i = 0; i < amount; i++) {
        currentIdeas.push(createIdea(i));
      }

      generatedCount += amount;
      $("statIdeas").textContent = generatedCount;
      renderIdeas();
      showToast(`${amount}個のアイデアを生成しました`);
    }

    function createIdea(index) {
      const genre = val("genre");
      const mood = val("mood");
      const level = val("level");
      const target = val("target");
      const style = val("style");
      const keywords = val("keywords") || "AI / 創作 / アイデア";
      const problem = val("problem") || "アイデアを整理して、作り始めやすくしたい";

      const title = makeTitle(genre, keywords, index);
      const features = shuffle(DATA.features[genre]).slice(0, 6);
      const mvp = features.slice(0, 3);
      const money = shuffle(DATA.monetization).slice(0, 3);
      const risks = shuffle(DATA.risks).slice(0, 3);
      const steps = DATA.firstSteps[level];
      const score = calcScore(genre, level);
      const keywordMain = splitKeywords(keywords)[0] || "アイデア";

      return {
        id: Date.now() + Math.random(),
        createdAt: new Date().toLocaleString("ja-JP"),
        title,
        genre,
        mood,
        level,
        target,
        style,
        keywords,
        problem,
        score,
        catchcopy: makeCatch(target, mood, genre, keywordMain),
        overview: makeOverview(genre, mood, target, keywords, problem, style),
        unique: makeUnique(genre, mood, keywordMain),
        features,
        mvp,
        money,
        risks,
        steps,
        devTime: makeDevTime(level),
        nextAction: makeNextAction(level, genre),
        design: makeDesign(mood),
        pitch: makePitch(title, target, genre, problem)
      };
    }

    function splitKeywords(text) {
      return text.split(/[\/、,\s]+/).map(x => x.trim()).filter(Boolean);
    }

    function makeTitle(genre, keywords, index) {
      const keys = splitKeywords(keywords);
      const key = keys[index % Math.max(keys.length, 1)] || "Idea";
      const head = pick(DATA.titleHeads);
      const tail = pick(DATA.titleTails[genre] || DATA.titleTails["創作支援"]);

      const patterns = [
        `${head}${tail}`,
        `${key}${tail}`,
        `${head} ${tail}`,
        `${key}メーカー`,
        `${key}ギルド`,
        `${key}Forge`,
        `${head}ノート`,
        `${key}ラボ`,
        `${head}Factory`,
        `${key}クエスト`
      ];

      return pick(patterns);
    }

    function makeCatch(target, mood, genre, key) {
      const desc = DATA.moodDesc[mood];
      const patterns = [
        `${target}の「作りたい」を形にする、${desc}${genre}。`,
        `${key}を起点に、企画・整理・実行まで支える${genre}。`,
        `思いつきを企画に変える、${target}向けの${desc}サービス。`,
        `迷っている時間を減らし、制作を前に進める${genre}。`
      ];
      return pick(patterns);
    }

    function makeOverview(genre, mood, target, keywords, problem, style) {
      const desc = DATA.moodDesc[mood];

      if (style === "ピッチ資料風") {
        return `${problem}という悩みを持つ${target}に向けて、${keywords}を軸にした${genre}を提供します。${desc}体験により、ユーザーはアイデア出しから整理、実行までを短時間で進められます。`;
      }

      if (style === "開発メモ風") {
        return `${keywords}をテーマにした${genre}。まずは小さく作る。${target}が抱える「${problem}」を解決するため、生成、保存、検索、コピーの流れを重視する。`;
      }

      if (style === "サービス紹介風") {
        return `この${genre}は、${target}が${keywords}に関するアイデアをすばやく整理できるサービスです。${desc}デザインで、毎日開きたくなる使い心地を目指します。`;
      }

      return `${keywords}をテーマにした${genre}です。${target}が抱える「${problem}」を解決するため、アイデア出し、情報整理、保存、次の行動提案をまとめて行える企画にします。`;
    }

    function makeUnique(genre, mood, key) {
      return `${key}をただ生成するだけでなく、MVP、開発手順、収益化、注意点まで同時に出せる点が特徴です。${mood}な方向性を明確にすることで、似たような${genre}との差別化もしやすくなります。`;
    }

    function calcScore(genre, level) {
      let score = 82;

      if (level === "簡単") score += 10;
      if (level === "普通") score += 5;
      if (level === "本格") score -= 2;
      if (level === "超本格") score -= 9;

      if (genre === "便利ツール") score += 4;
      if (genre === "AIツール") score += 3;
      if (genre === "ゲーム") score -= 4;
      if (genre === "SNS") score -= 3;

      score += Math.floor(Math.random() * 9) - 4;

      return Math.max(55, Math.min(98, score));
    }

    function makeDevTime(level) {
      if (level === "簡単") return "1日〜3日";
      if (level === "普通") return "1週間〜2週間";
      if (level === "本格") return "1か月〜3か月";
      return "3か月以上";
    }

    function makeNextAction(level, genre) {
      if (level === "簡単") {
        return `まずは${genre}の1画面版を作ります。入力欄、生成ボタン、結果表示、保存だけで完成扱いにするのが安全です。`;
      }

      if (level === "普通") {
        return `最初にUIを作り、そのあと保存・検索・出力機能を追加します。ログイン機能は後回しで大丈夫です。`;
      }

      if (level === "本格") {
        return `MVPを公開できる状態まで作ってから、ユーザー登録やデータベースを検討します。最初から全部入れない方が完成します。`;
      }

      return `超本格版は重いので、まずはプロトタイプを完成させてください。完成後にサーバー、DB、課金、ログインを分割して追加する流れが安全です。`;
    }

    function makeDesign(mood) {
      const map = {
        "かっこいい": "黒背景、青紫グラデーション、カード型UI、シャープなボタン",
        "やさしい": "白背景、淡い青や緑、角丸カード、大きめ文字",
        "近未来": "ダーク背景、ネオン、水色アクセント、ガラス風UI",
        "ファンタジー": "羊皮紙風、ギルドカード、クエストボード風UI",
        "シンプル": "白背景、余白多め、入力欄と結果表示を中心にする",
        "高級感": "黒と金、細い罫線、落ち着いたカードUI",
        "かわいい": "パステルカラー、丸いボタン、アイコン多め",
        "ダーク": "黒、赤紫、重厚な影、世界観重視",
        "実用的": "管理画面風、見出し明確、コピー・保存ボタンを目立たせる",
        "ゲーム風": "ステータス画面、経験値バー、クエストカード風"
      };

      return map[mood] || "カード型で見やすいUI";
    }

    function makePitch(title, target, genre, problem) {
      return `${title}は、${target}が抱える「${problem}」を解決する${genre}です。複雑な作業を整理し、次にやることを明確にすることで、制作や仕事を止めずに進められるようにします。`;
    }

    function renderIdeas() {
      const result = $("result");

      if (currentIdeas.length === 0) {
        result.innerHTML = `
          <div class="empty">
            <div class="icon">🧠</div>
            <h2>まだアイデアはありません</h2>
            <p>左の条件を入れて「アイデア生成」を押してください。</p>
          </div>
        `;
        return;
      }

      result.innerHTML = `
        <div class="idea-list">
          ${currentIdeas.map(renderIdeaCard).join("")}
        </div>
      `;
    }

    function renderIdeaCard(idea, index) {
      return `
        <article class="idea-card">
          <div class="idea-top">
            <div>
              <h2 class="idea-title">${escapeHTML(idea.title)}</h2>
              <div class="meta">
                <span class="pill">${escapeHTML(idea.genre)}</span>
                <span class="pill">${escapeHTML(idea.mood)}</span>
                <span class="pill">${escapeHTML(idea.level)}</span>
                <span class="pill">${escapeHTML(idea.target)}</span>
                <span class="pill">開発目安 ${escapeHTML(idea.devTime)}</span>
              </div>
            </div>

            <div class="score-box">
              <strong>${idea.score}</strong>
              <span>実現度</span>
            </div>
          </div>

          <div class="catch">
            ${escapeHTML(idea.catchcopy)}
          </div>

          <div class="idea-body">
            <div class="sections">
              <div class="section wide">
                <h4>📝 概要</h4>
                <p>${escapeHTML(idea.overview)}</p>
              </div>

              <div class="section">
                <h4>🎯 解決する悩み</h4>
                <p>${escapeHTML(idea.problem)}</p>
              </div>

              <div class="section">
                <h4>🎨 デザイン方針</h4>
                <p>${escapeHTML(idea.design)}</p>
              </div>

              <div class="section">
                <h4>⚙️ 主な機能</h4>
                <ul>
                  ${idea.features.map(x => `<li>${escapeHTML(x)}</li>`).join("")}
                </ul>
              </div>

              <div class="section">
                <h4>🚀 MVP機能</h4>
                <ol>
                  ${idea.mvp.map(x => `<li>${escapeHTML(x)}</li>`).join("")}
                </ol>
              </div>

              <div class="section">
                <h4>💰 収益化案</h4>
                <ul>
                  ${idea.money.map(x => `<li>${escapeHTML(x)}</li>`).join("")}
                </ul>
              </div>

              <div class="section">
                <h4>⚠️ リスク</h4>
                <ul>
                  ${idea.risks.map(x => `<li>${escapeHTML(x)}</li>`).join("")}
                </ul>
              </div>

              <div class="section wide">
                <h4>✅ 開発ステップ</h4>
                <ol>
                  ${idea.steps.map(x => `<li>${escapeHTML(x)}</li>`).join("")}
                </ol>
              </div>

              <div class="section wide">
                <h4>✨ 差別化ポイント</h4>
                <p>${escapeHTML(idea.unique)}</p>
              </div>

              <div class="section wide">
                <h4>📣 紹介文</h4>
                <p>${escapeHTML(idea.pitch)}</p>
              </div>

              <div class="section wide">
                <h4>👉 次にやること</h4>
                <p>${escapeHTML(idea.nextAction)}</p>
              </div>
            </div>
          </div>

          <div class="idea-actions">
            <button onclick="copyOne(${index})">この案をコピー</button>
            <button onclick="saveOne(${index})">保存</button>
            <button onclick="regenerateOne(${index})">この案だけ再生成</button>
          </div>
        </article>
      `;
    }

    function ideaToText(idea) {
      return `
【タイトル】
${idea.title}

【ジャンル】
${idea.genre}

【雰囲気】
${idea.mood}

【ターゲット】
${idea.target}

【開発難易度】
${idea.level}

【開発目安】
${idea.devTime}

【実現度】
${idea.score}点

【キャッチコピー】
${idea.catchcopy}

【解決する悩み】
${idea.problem}

【概要】
${idea.overview}

【主な機能】
${idea.features.map((x, i) => `${i + 1}. ${x}`).join("\n")}

【MVP機能】
${idea.mvp.map((x, i) => `${i + 1}. ${x}`).join("\n")}

【収益化案】
${idea.money.map((x, i) => `${i + 1}. ${x}`).join("\n")}

【リスク】
${idea.risks.map((x, i) => `${i + 1}. ${x}`).join("\n")}

【開発ステップ】
${idea.steps.map((x, i) => `${i + 1}. ${x}`).join("\n")}

【デザイン方針】
${idea.design}

【差別化ポイント】
${idea.unique}

【紹介文】
${idea.pitch}

【次にやること】
${idea.nextAction}
      `.trim();
    }

    function copyOne(index) {
      const idea = currentIdeas[index];
      if (!idea) return;
      copyText(ideaToText(idea));
    }

    function copyAll() {
      if (currentIdeas.length === 0) {
        showToast("先に生成してください");
        return;
      }

      copyText(currentIdeas.map(ideaToText).join("\n\n====================\n\n"));
    }

    function copyText(text) {
      navigator.clipboard.writeText(text)
        .then(() => showToast("コピーしました"))
        .catch(() => showToast("コピーに失敗しました"));
    }

    function regenerateOne(index) {
      currentIdeas[index] = createIdea(index);
      renderIdeas();
      showToast("再生成しました");
    }

    function getSaved() {
      try {
        return JSON.parse(localStorage.getItem("netagami_saved")) || [];
      } catch {
        return [];
      }
    }

    function setSaved(data) {
      localStorage.setItem("netagami_saved", JSON.stringify(data));
      updateStats();
    }

    function saveOne(index) {
      const idea = currentIdeas[index];
      if (!idea) return;

      const saved = getSaved();
      saved.unshift(idea);
      setSaved(saved.slice(0, 100));
      renderHistory();
      showToast("保存しました");
    }

    function saveAll() {
      if (currentIdeas.length === 0) {
        showToast("先に生成してください");
        return;
      }

      const saved = getSaved();
      setSaved([...currentIdeas, ...saved].slice(0, 100));
      renderHistory();
      showToast("全部保存しました");
    }

    function renderHistory() {
      const list = $("historyList");
      const saved = getSaved();
      const q = $("historySearch").value.trim().toLowerCase();
      const genre = $("historyGenre").value;

      let filtered = saved;

      if (genre !== "all") {
        filtered = filtered.filter(x => x.genre === genre);
      }

      if (q) {
        filtered = filtered.filter(x => {
          return JSON.stringify(x).toLowerCase().includes(q);
        });
      }

      $("savedCount").textContent = `${saved.length}件`;

      if (filtered.length === 0) {
        list.innerHTML = `<p style="color:var(--muted);">保存アイデアはありません。</p>`;
        return;
      }

      list.innerHTML = filtered.map(item => `
        <div class="history-item" onclick="loadSaved('${item.id}')">
          <strong>${escapeHTML(item.title)}</strong>
          <small>${escapeHTML(item.genre)} / ${escapeHTML(item.level)} / ${escapeHTML(item.createdAt)}</small>
        </div>
      `).join("");
    }

    function loadSaved(id) {
      const saved = getSaved();
      const idea = saved.find(x => String(x.id) === String(id));

      if (!idea) return;

      currentIdeas = [idea];
      renderIdeas();
      window.scrollTo({ top: 0, behavior: "smooth" });
      showToast("保存アイデアを表示しました");
    }

    function downloadText() {
      if (currentIdeas.length === 0) {
        showToast("先に生成してください");
        return;
      }

      const text = currentIdeas.map(ideaToText).join("\n\n====================\n\n");
      downloadFile("netagami-ideas.txt", text, "text/plain");
      showToast("TXT出力しました");
    }

    function downloadJSON() {
      const data = currentIdeas.length ? currentIdeas : getSaved();

      if (data.length === 0) {
        showToast("出力するデータがありません");
        return;
      }

      downloadFile("netagami-ideas.json", JSON.stringify(data, null, 2), "application/json");
      showToast("JSON出力しました");
    }

    function downloadFile(filename, content, type) {
      const blob = new Blob([content], { type: type + ";charset=utf-8" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");

      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();

      URL.revokeObjectURL(url);
    }

    function clearAll() {
      if (!confirm("生成結果と保存履歴を削除しますか?")) return;

      currentIdeas = [];
      localStorage.removeItem("netagami_saved");
      renderIdeas();
      renderHistory();
      updateStats();
      showToast("削除しました");
    }

    function toggleTheme() {
      document.body.classList.toggle("light");
      localStorage.setItem("netagami_theme", document.body.classList.contains("light") ? "light" : "dark");
    }

    function updateStats() {
      $("statSaved").textContent = getSaved().length;
    }

    function showToast(message) {
      const toast = $("toast");
      toast.textContent = message;
      toast.classList.add("show");

      setTimeout(() => {
        toast.classList.remove("show");
      }, 1800);
    }

    function init() {
      if (localStorage.getItem("netagami_theme") === "light") {
        document.body.classList.add("light");
      }

      $("keywords").value = "AI / 創作 / Webサービス / メモ";
      $("problem").value = "何を作ればいいかわからない。アイデアを企画書レベルまで整理したい。";

      renderHistory();
      updateStats();
    }

    init();
  </script>
</body>
</html>

投稿者: chosuke

趣味はゲームやアニメや漫画などです

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です