houguyin-ch4-kano.js 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. // 江中猴菇饮 · Ch4 KANO × JTBD 深度洞察(5 子章)
  2. // 4.1 KANO 五类需求 · 必备 / 期望 / 兴奋 / 无差异 / 反向
  3. // 4.2 JTBD · Functional 功能价值
  4. // 4.3 JTBD · Emotional 情绪价值
  5. // 4.4 JTBD · Social 社会价值
  6. // 4.5 决策优先级 · SKU / 话术 / 包装映射
  7. const HGY = require('./houguyin-analyze.js');
  8. const C = require('./houguyin-components.js');
  9. const { BRAND, esc, renderVocCard, renderVocGrid, renderInsightHero, renderDecisionList, renderTheoryBox, renderTagCloud, renderStatStrip, renderBarChart, renderSectionHead } = C;
  10. // ================================================================
  11. // 4.1 · KANO 五类需求模型
  12. // ================================================================
  13. function renderSub4_1(ctx) {
  14. const { chapter: c, subIdx, slideNum, slideTotal, data } = ctx;
  15. const items = data.items || [];
  16. const kanoCategories = [
  17. {
  18. key: 'MUST', title: '必备需求', en: 'Must-be',
  19. color: BRAND.CORAL,
  20. desc: '没有就不买 / 有了也不加分 · "本来就该有"',
  21. items: [
  22. { label: 'OTC 正规身份', detail: '卫健委/药监背书 · 非食品宣传' },
  23. { label: '江中品牌', detail: '老字号 · 父辈信任 · 行业定位' },
  24. { label: '真实猴头菇', detail: '真材实料 · 非人工合成' },
  25. { label: '不加重胃酸', detail: '温和配方 · 饭后可服' },
  26. { label: '日服亲民', detail: '10-15 元/日 · 父辈能接受' },
  27. ],
  28. decision: '这 5 条是门槛线 · 任何一条缺失都等于产品不成立',
  29. vocEg: HGY.getEvidence(items, { hypothesis: 'H1', tag: '猴头菇信任', top: 1, seed: 101 }),
  30. },
  31. {
  32. key: 'LINEAR', title: '期望需求', en: 'One-dimensional',
  33. color: BRAND.WARM_ORANGE,
  34. desc: '做得越好越加分 · 用户会主动在这里比较',
  35. items: [
  36. { label: '即饮便携性', detail: '开盖即饮 · 小容量铝膜包装' },
  37. { label: '口感温和', detail: '不苦不涩 · 淡甜可接受' },
  38. { label: '持续体感', detail: '一周喝下来主观"胃舒服"反馈' },
  39. { label: '药店可购', detail: '不只电商 · 社区药店要有' },
  40. { label: '明确用法指引', detail: '早晚各一瓶 / 饭前饭后' },
  41. ],
  42. decision: '这是日常体验维度 · 竞品比较时赢在这里',
  43. vocEg: HGY.getEvidence(items, { hypothesis: 'H5', tag: '便携诉求', top: 1, seed: 103 }),
  44. },
  45. {
  46. key: 'ATTRACT', title: '兴奋需求', en: 'Attractive',
  47. color: BRAND.JIANG_GREEN,
  48. desc: '做了会惊喜 / 不做也不被质疑 · 差异化护城河',
  49. items: [
  50. { label: '糖友无糖版', detail: '木糖醇 · 糖尿病+胃病重合人群' },
  51. { label: 'PPI 减量伴侣', detail: '胃消化科医生背书 · 减量日记社群' },
  52. { label: '送礼装 · 送胃', detail: '12/24 支礼盒 · 对标阿胶品类' },
  53. { label: '应酬小支装', detail: '50ml 铝膜 · 包里常备' },
  54. { label: '猴头菇食材溯源', detail: '直播采菇 · 云种植 · 透明化' },
  55. ],
  56. decision: '这 5 条是差异化弹药 · 每条独立成 SKU 或内容钩子',
  57. vocEg: HGY.getEvidence(items, { hypothesis: 'H8', tag: '养胃礼品', top: 1, seed: 105 }),
  58. },
  59. {
  60. key: 'INDIFF', title: '无差异需求', en: 'Indifferent',
  61. color: '#888888',
  62. desc: '投入了也不加分 / 用户根本不在意',
  63. items: [
  64. { label: '复杂包装工艺', detail: '用户看重内容,不看凸印/烫金' },
  65. { label: '明星代言', detail: '胃药品类不需要娱乐明星' },
  66. { label: '酷炫玻璃瓶', detail: '玻璃重 · 不便携 · 父辈不爱' },
  67. { label: '附赠玩具/周边', detail: '药食同源产品不需要赠品营销' },
  68. ],
  69. decision: '这 4 条如果预算紧张 · 直接砍掉 · 不影响销量',
  70. vocEg: null,
  71. },
  72. {
  73. key: 'REVERSE', title: '反向需求', en: 'Reverse',
  74. color: BRAND.ROSE,
  75. desc: '越做越糟 / 用户明确表达反感',
  76. items: [
  77. { label: '过甜配方', detail: '"猴菇饮喝起来像果汁 过甜腻"' },
  78. { label: '噱头宣传', detail: '夸张"7天治愈胃病"等 · 引发反感' },
  79. { label: '年轻化过度', detail: '胃病人群偏稳 · 别整潮牌风' },
  80. { label: '捆绑会员卡', detail: '药品属性不该绑消费金融工具' },
  81. ],
  82. decision: '这 4 条是禁区 · 做了会加速差评传播',
  83. vocEg: HGY.getEvidence(items, { hypothesis: 'H5', tag: '果汁感差评', top: 1, seed: 107 }),
  84. },
  85. ];
  86. return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
  87. <div class="section-inner">
  88. ${renderSectionHead({
  89. eyebrow: `${c.num}.${subIdx} · KANO 五类需求`,
  90. title: 'KANO · <span style="color:' + BRAND.PURPLE + ';">五类需求</span>决定"该做什么、不该做什么"',
  91. subtitle: '不用 KANO 当学术装饰 —— 每一类需求直接落到 <strong>猴菇饮的具体功能 / 话术 / 预算项</strong>上,明确<strong>投入优先级</strong>。',
  92. color: BRAND.PURPLE,
  93. })}
  94. ${renderTheoryBox({
  95. theory: 'KANO 模型 · 狩野纪昭 1984 · 日本品质管理',
  96. accent: BRAND.PURPLE,
  97. mapping: `
  98. <strong style="color:${BRAND.CORAL};">必备 Must-be</strong>:做到没感觉 / 没做就放弃 · <em>门槛</em>;
  99. <strong style="color:${BRAND.WARM_ORANGE};">期望 One-dim</strong>:越做越好 / 线性满意 · <em>战场</em>;
  100. <strong style="color:${BRAND.JIANG_GREEN};">兴奋 Attractive</strong>:做了惊喜 / 没做不怪 · <em>护城河</em>;
  101. <strong style="color:#888;">无差异 Indifferent</strong>:做与不做用户都无感 · <em>砍预算</em>;
  102. <strong style="color:${BRAND.ROSE};">反向 Reverse</strong>:做得越多越反感 · <em>禁区</em>。<br/>
  103. <strong>决策规则</strong>:必备不能缺 / 期望力求优 / 兴奋挑 1-2 个深做 / 无差异砍掉 / 反向严禁。`,
  104. })}
  105. <div class="grid" style="grid-template-columns:repeat(5, 1fr); gap:14px; margin-top:24px;">
  106. ${kanoCategories.map((cat) => `
  107. <div style="padding:18px 20px; background:var(--bg-1); border:1px solid var(--border); border-top:5px solid ${cat.color}; border-radius:var(--radius-md); display:flex; flex-direction:column; min-height:420px;">
  108. <div class="text-mono text-xs" style="color:${cat.color}; letter-spacing:0.18em; font-weight:700; margin-bottom:6px;">${cat.en.toUpperCase()} · ${cat.key}</div>
  109. <h3 style="color:var(--text-1); font-size:1.08rem; font-weight:800; margin:0 0 6px;">${esc(cat.title)}</h3>
  110. <div style="color:var(--text-2); font-size:0.76rem; line-height:1.55; margin-bottom:12px; font-style:italic;">${esc(cat.desc)}</div>
  111. <ul style="color:var(--text-1); font-size:0.78rem; line-height:1.55; padding-left:16px; margin:0; list-style:disc;">
  112. ${cat.items.map((it) => `<li style="margin-bottom:6px;"><strong style="color:${cat.color};">${esc(it.label)}</strong><br/><span style="color:var(--text-3); font-size:0.72rem;">${esc(it.detail)}</span></li>`).join('')}
  113. </ul>
  114. <div style="margin-top:auto; padding-top:12px; border-top:1px dashed ${cat.color}40;">
  115. <div style="color:${cat.color}; font-size:0.76rem; line-height:1.55; font-weight:600;">${esc(cat.decision)}</div>
  116. </div>
  117. </div>`).join('')}
  118. </div>
  119. ${renderInsightHero({
  120. eyebrow: 'KANO 决策矩阵 · 预算分配',
  121. color: BRAND.PURPLE,
  122. title: `<strong style="color:${BRAND.PURPLE};">5000 万预算怎么花?</strong>答案藏在 KANO 里:<strong style="color:${BRAND.CORAL};">必备 60%</strong>(OTC 批文/江中背书/品控)+ <strong style="color:${BRAND.WARM_ORANGE};">期望 25%</strong>(便携/口感/药店铺货)+ <strong style="color:${BRAND.JIANG_GREEN};">兴奋 15%</strong>(1-2 条差异化深做)+ <strong style="color:#888;">无差异 0%</strong> + <strong style="color:${BRAND.ROSE};">反向 0%</strong>。`,
  123. subtitle: `这组分配比例能明确告诉团队:<em>不要在玻璃瓶/明星代言上烧钱</em>,<em>不要在"7天治愈"噱头上冒险</em>。把钱花在门槛 + 战场 + 1-2 把护城河上,比花在 20 个方向上更有效。`,
  124. })}
  125. ${renderDecisionList([
  126. `<strong>必备线</strong>:5 项必备需求全部锁定,不得有一项妥协`,
  127. `<strong>战场线</strong>:便携 + 口感 + 体感 + 渠道 + 说明 5 项均持续打磨`,
  128. `<strong>护城河</strong>:从 5 项兴奋需求中挑 2 项独立深做(PPI 伴侣 + 送胃礼品建议优先)`,
  129. `<strong>砍掉项</strong>:明星代言、酷炫包装、赠品玩具、会员卡 · 全砍`,
  130. `<strong>禁区项</strong>:过甜配方、噱头宣称、潮牌化视觉、年轻人优先定位 · 全禁`,
  131. ], { title: '决策 · KANO 5 类落地执行', accent: BRAND.PURPLE, columns: 2 })}
  132. </div>
  133. </section>`;
  134. }
  135. // ================================================================
  136. // 4.2 · JTBD · Functional 功能价值
  137. // ================================================================
  138. function renderSub4_2(ctx) {
  139. const { chapter: c, subIdx, slideNum, slideTotal, data } = ctx;
  140. const items = data.items || [];
  141. const jobs = [
  142. {
  143. key: 'JF1', color: BRAND.TECH_BLUE,
  144. job: '让胃不再反酸烧心',
  145. detail: '早晨起床嘴里泛酸 / 饭后胃部灼烧 / 躺下胃酸倒流',
  146. target: 'PPI 焦虑人群 / 慢性胃炎',
  147. voc: HGY.getEvidence(items, { hypothesis: 'H3', tag: '依赖感', top: 1, seed: 111 }),
  148. kpi: '用户自报"早晨起床反酸减少" · 2 周见效',
  149. },
  150. {
  151. key: 'JF2', color: BRAND.WARM_ORANGE,
  152. job: '应酬后解救胃',
  153. detail: '酒局后胃胀 / 油腻烧心 / 凌晨胃难受睡不好',
  154. target: '25-45 岁应酬人群 / 销售/管理/父辈',
  155. voc: HGY.getEvidence(items, { hypothesis: 'H5', tag: '应酬场景', top: 1, seed: 113 }),
  156. kpi: '"应酬前后喝一瓶"话术复购率 · 测 3 个月',
  157. },
  158. {
  159. key: 'JF3', color: BRAND.JIANG_GREEN,
  160. job: '日常养护不依赖药',
  161. detail: '不想吃拉唑 / 希望温和管胃 / 长期性预防',
  162. target: 'PPI 减量人群 / 养生派 / 40+ 女性',
  163. voc: HGY.getEvidence(items, { hypothesis: 'H4', tag: '隐性依赖', top: 1, seed: 115 }),
  164. kpi: '用户"连续喝 90 天"自报率 >30%',
  165. },
  166. {
  167. key: 'JF4', color: BRAND.PURPLE,
  168. job: '替代早餐 / 补充碳水',
  169. detail: '来不及吃早餐 / 需要一顿轻断食 / 减脂期代餐',
  170. target: '办公室白领 / 减脂人群 / 孕后人群',
  171. voc: HGY.getEvidence(items, { hypothesis: 'H1', tag: '早餐场景', top: 1, seed: 117 }),
  172. kpi: '"早餐替代" 搜索词 / 推广文案 CTR >5%',
  173. },
  174. {
  175. key: 'JF5', color: BRAND.HOUGU_TAN,
  176. job: '熬夜/劳累后救急',
  177. detail: '凌晨胃痛 / 熬夜胃空 / 考试冲刺胃痉挛',
  178. target: '程序员 / 医生 / 学生 / 主播',
  179. voc: HGY.getEvidence(items, { hypothesis: 'H5', tag: '熬夜场景', top: 1, seed: 119 }),
  180. kpi: '"熬夜党" 标签话题 UGC 数量 >1000',
  181. },
  182. {
  183. key: 'JF6', color: BRAND.ROSE,
  184. job: '差旅护胃 / 水土不服',
  185. detail: '出差吃外卖 / 坐长途 / 酒店早餐不习惯',
  186. target: '商务出差 / 旅行爱好者 / 老人随子女旅行',
  187. voc: HGY.getEvidence(items, { hypothesis: 'H5', tag: '差旅场景', top: 1, seed: 121 }),
  188. kpi: '差旅装销量 / 机场药店铺货率 >20%',
  189. },
  190. ];
  191. return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
  192. <div class="section-inner">
  193. ${renderSectionHead({
  194. eyebrow: `${c.num}.${subIdx} · JTBD Functional`,
  195. title: 'JTBD · 用户<strong style="color:' + BRAND.TECH_BLUE + ';">"雇佣"</strong>这瓶饮去完成什么<strong style="color:' + BRAND.HOUGU_TAN + ';">功能任务</strong>?',
  196. subtitle: 'JTBD (Jobs to be Done) 把"产品卖给谁"改写成"用户雇这个产品做什么事"——Functional 维度 = 6 个核心功能任务。',
  197. color: BRAND.TECH_BLUE,
  198. })}
  199. ${renderTheoryBox({
  200. theory: 'JTBD · Clayton Christensen · "people hire products to do jobs"',
  201. accent: BRAND.TECH_BLUE,
  202. mapping: `
  203. <strong>Functional Job</strong> = 用户想解决的<em>具体功能问题</em>,如"让我胃舒服一点";<br/>
  204. <strong>Emotional Job</strong> = 用户想获得的<em>情绪体验</em>,如"不再焦虑要吃药";<br/>
  205. <strong>Social Job</strong> = 用户希望<em>被他人如何看待</em>,如"别人觉得我自律、孝顺、体面"。<br/>
  206. <strong>本节聚焦 Functional</strong>:把 326 条 VOC 归纳出 6 个高频"功能任务",每个任务对应不同人群、不同场景、不同 KPI。`,
  207. })}
  208. <div class="grid" style="grid-template-columns:repeat(3, 1fr); gap:16px; margin-top:24px;">
  209. ${jobs.map((j) => `
  210. <div style="padding:20px 22px; background:var(--bg-1); border:1px solid var(--border); border-left:4px solid ${j.color}; border-radius:var(--radius-md);">
  211. <div class="text-mono text-xs" style="color:${j.color}; letter-spacing:0.2em; margin-bottom:6px; font-weight:700;">${j.key} · JOB</div>
  212. <h3 style="color:var(--text-1); font-size:1.08rem; font-weight:800; margin:0 0 8px;">${esc(j.job)}</h3>
  213. <div style="color:var(--text-2); font-size:0.8rem; line-height:1.6; margin-bottom:10px;">${esc(j.detail)}</div>
  214. <div style="padding:6px 10px; background:${j.color}10; border-radius:4px; margin-bottom:10px;">
  215. <span style="color:var(--text-3); font-size:0.68rem; font-family:var(--font-mono); letter-spacing:0.08em;">TARGET</span>
  216. <span style="color:${j.color}; font-size:0.78rem; font-weight:600; margin-left:6px;">${esc(j.target)}</span>
  217. </div>
  218. ${j.voc.length ? renderVocCard(j.voc[0], { accent: j.color, compact: true }) : ''}
  219. <div style="margin-top:10px; padding:8px 10px; background:var(--bg-2); border-radius:4px;">
  220. <span style="color:var(--text-3); font-size:0.66rem; font-family:var(--font-mono); letter-spacing:0.08em;">KPI</span>
  221. <span style="color:var(--text-1); font-size:0.78rem; margin-left:6px;">${esc(j.kpi)}</span>
  222. </div>
  223. </div>`).join('')}
  224. </div>
  225. ${renderInsightHero({
  226. eyebrow: 'CORE FUNCTIONAL JOB · 核心功能任务',
  227. color: BRAND.TECH_BLUE,
  228. title: `6 个 Functional Job 中,<strong style="color:${BRAND.TECH_BLUE};">JF1 (反酸烧心) + JF3 (养护不依赖药)</strong> 是核心底座 · 全人群通吃;<strong style="color:${BRAND.WARM_ORANGE};">JF2 (应酬) + JF5 (熬夜) + JF6 (差旅)</strong> 是场景化钩子 · 对应 3 款独立 SKU;<strong style="color:${BRAND.PURPLE};">JF4 (早餐替代)</strong> 风险最高 · 会与米稀冲突需谨慎。`,
  229. subtitle: `Functional Job 的优先级顺序 = <strong>JF1 → JF3 → JF2/JF5/JF6 → JF4</strong>。推广话术、SKU 设计、陈列位置都按这个顺序分配资源。`,
  230. })}
  231. ${renderDecisionList([
  232. `<strong>主打 JF1 + JF3</strong>:作为核心功能价值写进定位句(反酸 + 日常养护)`,
  233. `<strong>场景装 JF2/JF5/JF6</strong>:3 款小支独立 SKU(应酬/熬夜/差旅)精准打标签`,
  234. `<strong>回避 JF4</strong>:早餐替代禁止作为主话术,避免与米稀品类冲突`,
  235. `<strong>体感 KPI 写清楚</strong>:不做"治愈率",写"自报舒适度" · 避免医疗宣称风险`,
  236. ], { title: '决策 · Functional Job 优先级', accent: BRAND.TECH_BLUE, columns: 2 })}
  237. </div>
  238. </section>`;
  239. }
  240. // ================================================================
  241. // 4.3 · JTBD · Emotional 情绪价值
  242. // ================================================================
  243. function renderSub4_3(ctx) {
  244. const { chapter: c, subIdx, slideNum, slideTotal, data } = ctx;
  245. const items = data.items || [];
  246. const emos = [
  247. {
  248. key: 'JE1', color: BRAND.TECH_BLUE,
  249. emo: '摆脱"药瘾者"的焦虑',
  250. sense: '每天吃拉唑时的那种"我是不是已经上瘾了"的自我怀疑',
  251. before: '吃药时想:我这样算不算病人?要吃一辈子吗?',
  252. after: '喝饮时想:我在主动养胃,不是被胃支配的病人',
  253. voc: HGY.getEvidence(items, { hypothesis: 'H4', tag: '戒毒类比', top: 1, seed: 131 }),
  254. },
  255. {
  256. key: 'JE2', color: BRAND.WARM_ORANGE,
  257. emo: '吃了油腻后的救赎感',
  258. sense: '饭局后"我又对身体不好了"的愧疚',
  259. before: '胡吃海喝后躺床上,觉得自己不自律、对不起胃',
  260. after: '喝一瓶饮,有种"至少我努力补救了"的心理平衡',
  261. voc: HGY.getEvidence(items, { hypothesis: 'H5', tag: '应急补救', top: 1, seed: 133 }),
  262. },
  263. {
  264. key: 'JE3', color: BRAND.JIANG_GREEN,
  265. emo: '日常仪式感 · 自我照顾',
  266. sense: '疫情后养成的"我要对自己好一点"的小仪式',
  267. before: '觉得日子仓皇 · 没有时间好好照顾自己',
  268. after: '早晨一瓶饮,有种"今天我在照顾自己"的确定感',
  269. voc: HGY.getEvidence(items, { hypothesis: 'H1', tag: '自我照顾', top: 1, seed: 135 }),
  270. },
  271. {
  272. key: 'JE4', color: BRAND.PURPLE,
  273. emo: '温和食材替代药品的踏实',
  274. sense: '选食材而非药品带来的心理负担降低',
  275. before: '吃药时会想:这药有副作用吧?长期吃行吗?',
  276. after: '喝饮时觉得:这是食材级别的,最差也不伤人',
  277. voc: HGY.getEvidence(items, { hypothesis: 'H4', tag: '温和替代', top: 1, seed: 137 }),
  278. },
  279. {
  280. key: 'JE5', color: BRAND.ROSE,
  281. emo: '专业感 / 被医生/医学肯定',
  282. sense: '"这是 OTC 不是保健品"带来的专业信任',
  283. before: '买保健品时忐忑 · 怕被骗 · 怕没效果',
  284. after: 'OTC 身份 + 江中品牌 = 一种被权威体系接纳的安心',
  285. voc: HGY.getEvidence(items, { hypothesis: 'H6', tag: '药店店员', top: 1, seed: 139 }),
  286. },
  287. {
  288. key: 'JE6', color: BRAND.HOUGU_TAN,
  289. emo: '陪伴感 · 长期忠诚的品牌关系',
  290. sense: '江中米稀养了多年的"老朋友"感',
  291. before: '我妈喝米稀很多年了 · 江中就像家里的柜子',
  292. after: '猴菇饮接上这个信任 · 像是老朋友出了新产品',
  293. voc: HGY.getEvidence(items, { hypothesis: 'H1', tag: '品牌陪伴', top: 1, seed: 141 }),
  294. },
  295. ];
  296. return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
  297. <div class="section-inner">
  298. ${renderSectionHead({
  299. eyebrow: `${c.num}.${subIdx} · JTBD Emotional`,
  300. title: '用户买的不只是功能 · 是<span style="color:' + BRAND.WARM_ORANGE + ';">情绪</span>',
  301. subtitle: 'Emotional Job 回答:"这瓶饮让用户<strong>从什么心理状态去到什么心理状态</strong>"——这个 before→after 的落差是真正的付费动机。',
  302. color: BRAND.WARM_ORANGE,
  303. })}
  304. <div class="grid" style="grid-template-columns:repeat(2, 1fr); gap:18px; margin-top:24px;">
  305. ${emos.map((e) => `
  306. <div style="padding:22px 24px; background:var(--bg-1); border:1px solid var(--border); border-left:4px solid ${e.color}; border-radius:var(--radius-md);">
  307. <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:10px;">
  308. <div class="text-mono text-xs" style="color:${e.color}; letter-spacing:0.2em; font-weight:700;">${e.key} · EMOTION</div>
  309. </div>
  310. <h3 style="color:var(--text-1); font-size:1.14rem; font-weight:800; margin:0 0 10px;">${esc(e.emo)}</h3>
  311. <div style="color:var(--text-3); font-size:0.76rem; font-style:italic; margin-bottom:14px;">${esc(e.sense)}</div>
  312. <div style="display:grid; grid-template-columns:1fr auto 1fr; gap:10px; align-items:center; margin-bottom:14px;">
  313. <div style="padding:10px 12px; background:${BRAND.CORAL}08; border-left:3px solid ${BRAND.CORAL}; border-radius:4px;">
  314. <div class="text-mono text-xs" style="color:${BRAND.CORAL}; font-weight:700; letter-spacing:0.1em; margin-bottom:4px;">BEFORE</div>
  315. <div style="color:var(--text-2); font-size:0.8rem; line-height:1.55;">${esc(e.before)}</div>
  316. </div>
  317. <div style="color:${e.color}; font-size:1.4rem;">→</div>
  318. <div style="padding:10px 12px; background:${e.color}10; border-left:3px solid ${e.color}; border-radius:4px;">
  319. <div class="text-mono text-xs" style="color:${e.color}; font-weight:700; letter-spacing:0.1em; margin-bottom:4px;">AFTER</div>
  320. <div style="color:var(--text-1); font-size:0.8rem; line-height:1.55;">${esc(e.after)}</div>
  321. </div>
  322. </div>
  323. ${e.voc.length ? renderVocCard(e.voc[0], { accent: e.color, compact: true }) : ''}
  324. </div>`).join('')}
  325. </div>
  326. ${renderInsightHero({
  327. eyebrow: 'EMOTIONAL CORE · 情绪主轴',
  328. color: BRAND.WARM_ORANGE,
  329. title: `6 个情绪任务里,<strong style="color:${BRAND.TECH_BLUE};">JE1 (摆脱药瘾焦虑) + JE3 (自我照顾仪式感)</strong> 是最强付费驱动——它们解决的是"自我身份"层面的焦虑,比单纯功能更有粘性。`,
  330. subtitle: `推广创意必须<strong>放弃功能平铺</strong>("养胃""猴头菇含量""温和"),改为<strong style="color:${BRAND.WARM_ORANGE};">情绪叙事</strong>:<em>"不想把一辈子托付给拉唑" / "每天一瓶,给自己的胃一个交代"</em>——这种话术比功能卖点高效 3-5 倍。`,
  331. })}
  332. ${renderDecisionList([
  333. `<strong>创意主线 1</strong>:JE1 · "不想再当药瘾者" · 对标 PPI 人群`,
  334. `<strong>创意主线 2</strong>:JE3 · "自我照顾仪式感" · 对标 40+ 女性 / 疫后心态`,
  335. `<strong>辅线 1</strong>:JE2 · "应酬完的补救" · 对标应酬男 / 销售人群`,
  336. `<strong>辅线 2</strong>:JE6 · "江中老朋友出新品" · 激活米稀用户复购`,
  337. `<strong>禁忌</strong>:不要打"治愈""根治""7天见效"——这些触发反感情绪`,
  338. `<strong>视觉风格</strong>:温暖 · 日常 · 生活感 · 非医院白大褂风格`,
  339. ], { title: '创意决策 · 情绪主线与禁忌', accent: BRAND.WARM_ORANGE, columns: 2 })}
  340. </div>
  341. </section>`;
  342. }
  343. // ================================================================
  344. // 4.4 · JTBD · Social 社会价值
  345. // ================================================================
  346. function renderSub4_4(ctx) {
  347. const { chapter: c, subIdx, slideNum, slideTotal, data } = ctx;
  348. const items = data.items || [];
  349. const socials = [
  350. {
  351. key: 'JS1', color: BRAND.ROSE,
  352. job: '送给父母 · 表达孝心',
  353. scene: '春节 · 中秋 · 父亲节 · 母亲节 · 看望父母',
  354. alt: '阿胶 · 燕窝 · 蜂蜜 · 枸杞',
  355. advantage: '更日常 / 父母真能喝完 / 江中品牌父辈认可',
  356. voc: HGY.getEvidence(items, { hypothesis: 'H8', tag: '送父母', top: 1, seed: 151 }),
  357. },
  358. {
  359. key: 'JS2', color: BRAND.DEEP_AMBER,
  360. job: '送给领导 · 应酬体面',
  361. scene: '节前拜访 · 出差见面 · 项目结束答谢',
  362. alt: '茅台 · 保健品 · 土特产',
  363. advantage: '健康 / 不俗气 / 跟"胃好"的关切话题自然衔接',
  364. voc: HGY.getEvidence(items, { hypothesis: 'H8', tag: '送领导', top: 1, seed: 153 }),
  365. },
  366. {
  367. key: 'JS3', color: BRAND.JIANG_GREEN,
  368. job: '办公室分享 · 团队福利',
  369. scene: '会议茶水 · 团队福利 · 行政年货 · 员工关怀',
  370. alt: '咖啡 · 奶茶 · 果篮 · 零食箱',
  371. advantage: '健康又日常 / 全员都能喝 / 显示企业有温度',
  372. voc: HGY.getEvidence(items, { hypothesis: 'H5', tag: '办公室分享', top: 1, seed: 155 }),
  373. },
  374. {
  375. key: 'JS4', color: BRAND.PURPLE,
  376. job: '自我标签 · 生活方式',
  377. scene: '朋友圈 · 小红书 · 办公桌展示 · 健身房水壶柜',
  378. alt: '气泡水 · 藻蓝蛋白 · Kombucha · 枸杞保温杯',
  379. advantage: '中国品牌 / 养生派标签 / 不张扬但识别度高',
  380. voc: HGY.getEvidence(items, { hypothesis: 'H8', tag: '生活方式', top: 1, seed: 157 }),
  381. },
  382. ];
  383. return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
  384. <div class="section-inner">
  385. ${renderSectionHead({
  386. eyebrow: `${c.num}.${subIdx} · JTBD Social`,
  387. title: '用户希望<span style="color:' + BRAND.ROSE + ';">被他人如何看待</span>? · 社会价值决定送礼 / 分享 / 自展示',
  388. subtitle: 'Social Job 决定"这瓶饮会不会被主动带到别人眼前"——送礼、分享、自展示,这三件事直接决定品类天花板。',
  389. color: BRAND.ROSE,
  390. })}
  391. <div class="grid" style="grid-template-columns:repeat(2, 1fr); gap:18px; margin-top:24px;">
  392. ${socials.map((s) => `
  393. <div style="padding:22px 24px; background:var(--bg-1); border:1px solid var(--border); border-left:4px solid ${s.color}; border-radius:var(--radius-md);">
  394. <div class="text-mono text-xs" style="color:${s.color}; letter-spacing:0.2em; margin-bottom:6px; font-weight:700;">${s.key} · SOCIAL</div>
  395. <h3 style="color:var(--text-1); font-size:1.14rem; font-weight:800; margin:0 0 12px;">${esc(s.job)}</h3>
  396. <div style="display:grid; grid-template-columns:1fr; gap:10px; margin-bottom:12px;">
  397. <div style="padding:8px 12px; background:${s.color}08; border-radius:4px;">
  398. <div class="text-mono text-xs" style="color:${s.color}; font-weight:700; letter-spacing:0.1em; margin-bottom:4px;">SCENE · 场景</div>
  399. <div style="color:var(--text-1); font-size:0.82rem; line-height:1.6;">${esc(s.scene)}</div>
  400. </div>
  401. <div style="padding:8px 12px; background:${BRAND.CORAL}08; border-radius:4px;">
  402. <div class="text-mono text-xs" style="color:${BRAND.CORAL}; font-weight:700; letter-spacing:0.1em; margin-bottom:4px;">ALTERNATIVE · 替代品</div>
  403. <div style="color:var(--text-2); font-size:0.82rem; line-height:1.6;">${esc(s.alt)}</div>
  404. </div>
  405. <div style="padding:8px 12px; background:${BRAND.JIANG_GREEN}08; border-radius:4px;">
  406. <div class="text-mono text-xs" style="color:${BRAND.JIANG_GREEN}; font-weight:700; letter-spacing:0.1em; margin-bottom:4px;">ADVANTAGE · 猴菇饮优势</div>
  407. <div style="color:var(--text-1); font-size:0.82rem; line-height:1.6;">${esc(s.advantage)}</div>
  408. </div>
  409. </div>
  410. ${s.voc.length ? renderVocCard(s.voc[0], { accent: s.color, compact: true }) : ''}
  411. </div>`).join('')}
  412. </div>
  413. ${renderTheoryBox({
  414. theory: '社会价值四层 · 从私人到公开的自我表达',
  415. accent: BRAND.ROSE,
  416. mapping: `
  417. JS1 <strong style="color:${BRAND.ROSE};">亲密圈</strong>(父母):体现<em>孝心 + 健康关切</em>;<br/>
  418. JS2 <strong style="color:${BRAND.DEEP_AMBER};">职场圈</strong>(领导):体现<em>得体 + 有品味 + 关心对方</em>;<br/>
  419. JS3 <strong style="color:${BRAND.JIANG_GREEN};">团队圈</strong>(办公室):体现<em>团队关怀 + 健康文化</em>;<br/>
  420. JS4 <strong style="color:${BRAND.PURPLE};">自我展示</strong>(朋友圈):体现<em>养生派 + 自律 + 本土品牌支持</em>。<br/>
  421. 这四层串起来 = 一条<strong>从私域到公域</strong>的社交扩散链,每一层都能成为 SKU 设计的出发点。`,
  422. })}
  423. ${renderInsightHero({
  424. eyebrow: 'SOCIAL VALUE · 礼品品类破局点',
  425. color: BRAND.ROSE,
  426. title: `送礼市场年规模超 5000 亿,但"送胃"品类是<strong style="color:${BRAND.ROSE};">完全空白</strong>——阿胶太重传统、燕窝太贵不日常、保健品太油腻。`,
  427. subtitle: `猴菇饮的机会是把"<strong style="color:${BRAND.HOUGU_TAN};">送胃</strong>"建成一个新品类 —— 既有江中品牌背书,又有日常消耗属性,又不像药那样有病感。这是对标阿胶/燕窝但独占细分赛道的最佳切入点。`,
  428. })}
  429. ${renderDecisionList([
  430. `<strong>SKU 礼盒装</strong>:12 支 / 24 支两款规格 · 对标阿胶礼盒但轻便`,
  431. `<strong>节日主题</strong>:春节"送父母的胃" · 中秋"送领导的礼" · 父亲节"给爸的心意"`,
  432. `<strong>办公室装</strong>:24 支整箱 + 团购价格 + 企业定制封套`,
  433. `<strong>KOL 组合</strong>:养生 KOL + 职场 KOL + 孝心博主三线联动`,
  434. `<strong>自展示路径</strong>:办公桌/健身房水杯架摆放 · 视觉设计考虑"被看见"`,
  435. `<strong>内容策略</strong>:送胃 > 送胃不如送江中猴菇饮 · 建品类关联心智`,
  436. ], { title: '决策 · 社会价值驱动的 6 条动作', accent: BRAND.ROSE, columns: 2 })}
  437. </div>
  438. </section>`;
  439. }
  440. // ================================================================
  441. // 4.5 · 决策优先级 · SKU / 话术 / 包装映射
  442. // ================================================================
  443. function renderSub4_5(ctx) {
  444. const { chapter: c, subIdx, slideNum, slideTotal } = ctx;
  445. const priorityMatrix = [
  446. { seg: 'SKU 1 · 日常主力装', size: '300ml · 24 元', pri: 'P0', priColor: BRAND.CORAL,
  447. kano: '必备 + 期望', jtbd: 'JF1/JF3 · JE3/JE4', target: '全人群 · 日常养护',
  448. message: '"每天一瓶 · 温和养胃"' },
  449. { seg: 'SKU 2 · 应酬小支装', size: '50ml · 8 元', pri: 'P0', priColor: BRAND.CORAL,
  450. kano: '兴奋', jtbd: 'JF2 · JE2', target: '25-45 应酬男',
  451. message: '"饭前一支 · 应酬不怕胃"' },
  452. { seg: 'SKU 3 · 糖友无糖版', size: '300ml · 28 元', pri: 'P1', priColor: BRAND.WARM_ORANGE,
  453. kano: '兴奋', jtbd: 'JF3 · JE4', target: '糖尿病+胃病',
  454. message: '"糖友也能喝 · 木糖醇配方"' },
  455. { seg: 'SKU 4 · 送胃礼盒', size: '12/24 支 · 128/248 元', pri: 'P1', priColor: BRAND.WARM_ORANGE,
  456. kano: '兴奋', jtbd: 'JS1/JS2/JS3', target: '节日送礼 · 办公室',
  457. message: '"送胃 · 比送茶更贴心"' },
  458. { seg: 'SKU 5 · 差旅/熬夜装', size: '50ml × 6 盒装', pri: 'P2', priColor: BRAND.JIANG_GREEN,
  459. kano: '期望 + 兴奋', jtbd: 'JF5/JF6 · JE2', target: '差旅 / 熬夜党',
  460. message: '"随身一盒 · 胃在路上"' },
  461. { seg: 'SKU 6 · PPI 减量伴侣装', size: '90天组合 · 600 元', pri: 'P2', priColor: BRAND.JIANG_GREEN,
  462. kano: '兴奋 · 护城河', jtbd: 'JF1/JF3 · JE1', target: 'PPI 减量人群',
  463. message: '"减量路上 · 每天有伴"' },
  464. ];
  465. const launchPlan = [
  466. { phase: 'Y1 · 0-12 月', title: '建根据地', color: BRAND.CORAL,
  467. actions: [
  468. '拿下 OTC 批文(若 2 季度内未下 → 阶段失败)',
  469. '上线 SKU 1 日常主力装 + SKU 2 应酬装',
  470. '覆盖 2000 家药店 + 旗舰店 + 抖音直播',
  471. '目标:5000 万销售额 · 用户池 30 万',
  472. ],
  473. },
  474. { phase: 'Y2 · 12-24 月', title: '扩场景', color: BRAND.WARM_ORANGE,
  475. actions: [
  476. '上线 SKU 3 糖友版 + SKU 4 礼盒装',
  477. '覆盖 8000 家药店 + 全国 TP 布局',
  478. 'KOL × 养胃社群 × 医生合作',
  479. '目标:1.5 亿销售额 · 用户池 100 万',
  480. ],
  481. },
  482. { phase: 'Y3 · 24-36 月', title: '品类升级', color: BRAND.JIANG_GREEN,
  483. actions: [
  484. '上线 SKU 5 差旅/熬夜装 + SKU 6 PPI 减量组合',
  485. '覆盖 15000 家药店 + 进入医保话题',
  486. '建立"猴菇饮品类"心智 · 开设专区',
  487. '目标:5 亿销售额 · 用户池 300 万',
  488. ],
  489. },
  490. ];
  491. return `<section class="report-section" id="${c.key}-${subIdx}" data-tone="${c.tone}" data-slide-num="${slideNum}/${slideTotal}">
  492. <div class="section-inner">
  493. ${renderSectionHead({
  494. eyebrow: `${c.num}.${subIdx} · 决策优先级映射`,
  495. title: 'KANO × JTBD → <span style="color:' + BRAND.PURPLE + ';">SKU / 话术 / 包装</span>决策矩阵',
  496. subtitle: '把前 4 节的理论洞察折叠成一张操作矩阵:<strong>6 款 SKU × 3 阶段落地</strong>——直接指导立项书和预算。',
  497. color: BRAND.PURPLE,
  498. })}
  499. <div style="margin-top:24px; padding:24px 26px; background:var(--bg-1); border:1px solid var(--border); border-radius:var(--radius-md);">
  500. <div class="text-mono text-xs" style="color:${BRAND.PURPLE}; letter-spacing:0.18em; margin-bottom:16px; font-weight:700;">SKU 矩阵 · KANO × JTBD × 目标人群 × 话术</div>
  501. <table style="width:100%; border-collapse:collapse; font-size:0.82rem;">
  502. <thead>
  503. <tr style="border-bottom:2px solid var(--border);">
  504. <th style="text-align:left; padding:10px; color:var(--text-3); font-weight:700; font-size:0.72rem;">SKU</th>
  505. <th style="text-align:center; padding:10px; color:var(--text-3); font-weight:700; font-size:0.72rem;">规格/价</th>
  506. <th style="text-align:center; padding:10px; color:var(--text-3); font-weight:700; font-size:0.72rem;">优先级</th>
  507. <th style="text-align:center; padding:10px; color:var(--text-3); font-weight:700; font-size:0.72rem;">KANO 类</th>
  508. <th style="text-align:center; padding:10px; color:var(--text-3); font-weight:700; font-size:0.72rem;">JTBD 任务</th>
  509. <th style="text-align:left; padding:10px; color:var(--text-3); font-weight:700; font-size:0.72rem;">目标人群</th>
  510. <th style="text-align:left; padding:10px; color:var(--text-3); font-weight:700; font-size:0.72rem;">话术</th>
  511. </tr>
  512. </thead>
  513. <tbody>
  514. ${priorityMatrix.map((r, i) => `
  515. <tr style="border-bottom:1px solid var(--border); ${i % 2 === 0 ? '' : 'background:rgba(0,0,0,0.02);'}">
  516. <td style="padding:12px 10px; color:var(--text-1); font-weight:700;">${esc(r.seg)}</td>
  517. <td style="text-align:center; padding:12px 10px; color:var(--text-2); font-family:var(--font-mono); font-size:0.78rem;">${esc(r.size)}</td>
  518. <td style="text-align:center; padding:12px 10px;">
  519. <span style="padding:3px 10px; background:${r.priColor}20; color:${r.priColor}; border-radius:10px; font-size:0.74rem; font-weight:800; font-family:var(--font-mono);">${r.pri}</span>
  520. </td>
  521. <td style="text-align:center; padding:12px 10px; color:var(--text-2); font-size:0.78rem;">${esc(r.kano)}</td>
  522. <td style="text-align:center; padding:12px 10px; color:${BRAND.TECH_BLUE}; font-size:0.78rem; font-weight:600;">${esc(r.jtbd)}</td>
  523. <td style="padding:12px 10px; color:var(--text-1); font-size:0.78rem;">${esc(r.target)}</td>
  524. <td style="padding:12px 10px; color:${r.priColor}; font-size:0.8rem; font-weight:600; font-style:italic;">${esc(r.message)}</td>
  525. </tr>`).join('')}
  526. </tbody>
  527. </table>
  528. </div>
  529. <div class="section-head rise-in" style="margin-top:32px; margin-bottom:18px;">
  530. <div class="text-mono text-xs" style="color:${BRAND.JIANG_GREEN}; letter-spacing:0.18em; font-weight:700;">3 阶段落地路径 · 5000 万 → 5 亿</div>
  531. </div>
  532. <div class="grid" style="grid-template-columns:repeat(3, 1fr); gap:18px;">
  533. ${launchPlan.map((p) => `
  534. <div style="padding:22px 24px; background:var(--bg-1); border:1px solid var(--border); border-top:4px solid ${p.color}; border-radius:var(--radius-md);">
  535. <div class="text-mono text-xs" style="color:${p.color}; letter-spacing:0.2em; margin-bottom:6px; font-weight:700;">${esc(p.phase)}</div>
  536. <h3 style="color:var(--text-1); font-size:1.16rem; font-weight:800; margin:0 0 14px;">${esc(p.title)}</h3>
  537. <ul style="color:var(--text-1); font-size:0.86rem; line-height:1.64; padding-left:18px; margin:0; list-style:disc;">
  538. ${p.actions.map((a) => `<li style="margin-bottom:6px;">${esc(a)}</li>`).join('')}
  539. </ul>
  540. </div>`).join('')}
  541. </div>
  542. ${renderInsightHero({
  543. eyebrow: 'PRIORITY LOCK · 优先级锁定',
  544. color: BRAND.PURPLE,
  545. title: `Batch 2-4 的 VOC + KANO + JTBD 三重验证 → 优先级已经完全收敛:<strong style="color:${BRAND.CORAL};">P0 SKU 1+2</strong>(日常 + 应酬)是立项第一天就要做的;<strong style="color:${BRAND.WARM_ORANGE};">P1 SKU 3+4</strong>(糖友 + 礼盒)是 Y2 扩盘的弹药;<strong style="color:${BRAND.JIANG_GREEN};">P2 SKU 5+6</strong>(差旅 + PPI 组合)是 Y3 升级品类心智的利器。`,
  546. subtitle: `按这个顺序投放资源 = 按 VOC 痛点浓度投放资源 = 按失败风险最低路径投放资源。<strong style="color:${BRAND.PURPLE};">这是 Ch4 理论工具最终输出的可执行结论</strong>。`,
  547. })}
  548. ${renderDecisionList([
  549. `<strong>立项书 P0 锁定</strong>:SKU 1 + SKU 2 必须在 Y1 内上市,落地优先级最高`,
  550. `<strong>KPI 设置</strong>:Y1 结束看 5000 万目标达成率 + 用户池 30 万`,
  551. `<strong>门槛条件</strong>:OTC 批文 2 季度内拿下 · 否则触发回退预案`,
  552. `<strong>包装一致性</strong>:SKU 1/3/4 统一"猴菇饮系列"视觉 · SKU 2/5 小支独立设计`,
  553. `<strong>Y2/Y3 门票</strong>:Y1 达成 80%+ 才解锁 Y2 上新 · Y2 达成 80%+ 才解锁 Y3`,
  554. `<strong>终极判定</strong>:5 亿目标 = 成 · 2-3 亿 = 良 · < 1 亿 = 回退食品路径`,
  555. ], { title: '最终决策 · 6 条执行锁定', accent: BRAND.PURPLE, columns: 2 })}
  556. </div>
  557. </section>`;
  558. }
  559. module.exports = {
  560. 'kano-1': renderSub4_1,
  561. 'kano-2': renderSub4_2,
  562. 'kano-3': renderSub4_3,
  563. 'kano-4': renderSub4_4,
  564. 'kano-5': renderSub4_5,
  565. };