skill-forge-hub 1.3.10 → 1.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.en.md +9 -0
  2. package/CHANGELOG.md +9 -0
  3. package/annual-report/SKILL.md +1 -1
  4. package/annual-report/resources/reference.html +2 -2
  5. package/annual-report/resources/skillforge-guide.html +5 -1
  6. package/article-to-html/SKILL.md +1 -1
  7. package/article-to-html/resources/reference.html +2 -2
  8. package/article-to-html/resources/skillforge-guide.html +5 -1
  9. package/commit-heatmap/SKILL.md +1 -1
  10. package/commit-heatmap/resources/reference.html +2 -2
  11. package/commit-heatmap/resources/skillforge-guide.html +5 -1
  12. package/daily-report/SKILL.md +1 -1
  13. package/daily-report/resources/reference.html +2 -2
  14. package/daily-report/resources/skillforge-guide.html +5 -1
  15. package/data-prepper/resources/skillforge-guide.html +5 -1
  16. package/decision-log/resources/skillforge-guide.html +5 -1
  17. package/deck-stage/resources/skillforge-guide.html +5 -1
  18. package/magic-deck/SKILL.md +1 -1
  19. package/magic-deck/resources/reference.html +2 -2
  20. package/magic-deck/resources/skillforge-guide.html +5 -1
  21. package/meeting-minutes/SKILL.md +1 -1
  22. package/meeting-minutes/resources/reference.html +2 -2
  23. package/meeting-minutes/resources/skillforge-guide.html +5 -1
  24. package/meta-forge/resources/skillforge-guide.html +5 -1
  25. package/monthly-report/SKILL.md +1 -1
  26. package/monthly-report/resources/reference.html +2 -2
  27. package/monthly-report/resources/skillforge-guide.html +5 -1
  28. package/one-pager/SKILL.md +1 -1
  29. package/one-pager/resources/reference.html +2 -2
  30. package/one-pager/resources/skillforge-guide.html +5 -1
  31. package/package.json +1 -1
  32. package/prompt-pouch/SKILL.md +1 -1
  33. package/prompt-pouch/resources/reference.html +2 -2
  34. package/prompt-pouch/resources/skillforge-guide.html +5 -1
  35. package/quarterly-report/SKILL.md +1 -1
  36. package/quarterly-report/resources/reference.html +2 -2
  37. package/quarterly-report/resources/skillforge-guide.html +5 -1
  38. package/release-notes/resources/skillforge-guide.html +5 -1
  39. package/skill-doctor/resources/skillforge-guide.html +5 -1
  40. package/spec-doc2spec/resources/skillforge-guide.html +5 -1
  41. package/spec-spec2doc/resources/skillforge-guide.html +5 -1
  42. package/team-report-collector/SKILL.md +1 -1
  43. package/team-report-collector/resources/reference.html +2 -2
  44. package/team-report-collector/resources/skillforge-guide.html +5 -1
  45. package/twin-docs/resources/skillforge-guide.html +5 -1
  46. package/weekly-report/SKILL.md +1 -1
  47. package/weekly-report/resources/reference.html +2 -2
  48. package/weekly-report/resources/skillforge-guide.html +5 -1
package/CHANGELOG.en.md CHANGED
@@ -4,6 +4,15 @@
4
4
 
5
5
  Version history of the SkillForge npm package `skill-forge-hub` (command name `skill-forge`).
6
6
 
7
+ ## 1.3.11 (2026-11-13)
8
+
9
+ **Theme-fade full coverage: 22 install guide pages get the transition, 12 templates upgrade to Material easing**
10
+
11
+ - Gap audit: skillforge-guide.html install pages (repo root + 21 identical copies under skill resources) previously switched instantly — all now carry the transient .theming fade, matching the 12 product templates
12
+ - Easing upgrade: transition curve changed from default ease to the Material Design standard cubic-bezier(.4,0,.2,1) — quick start, soft landing, crisper feel; duration stays 0.45s
13
+ - All 12 template stamps bumped again: daily/weekly/monthly/quarterly @3→4, annual/meeting-minutes @4→5, prompt-pouch @16→17, one-pager @12→13, article-to-html @3→4, commit-heatmap/team-report-collector @2→3, magic-deck @3→4
14
+ - Notes: the deck-stage cover template sets its theme statically at generation time (no interactive switching), so no transition is needed; View Transitions API deliberately not adopted — full-page snapshot crossfade suits route changes, while color transitions look cleaner for theme switching without double animation
15
+
7
16
  ## 1.3.10 (2026-11-13)
8
17
 
9
18
  **one-pager theme panel stays open on color pick, closes via a new × button (@12)**
package/CHANGELOG.md CHANGED
@@ -4,6 +4,15 @@
4
4
 
5
5
  SkillForge(技能锻造坊)npm 包 `skill-forge-hub`(命令名 `skill-forge`)版本变更记录。
6
6
 
7
+ ## 1.3.11(2026-11-13)
8
+
9
+ **换肤渐变全覆盖:22 份安装引导页补齐过渡,12 模板缓动升级 Material 标准曲线**
10
+
11
+ - 盘点补漏:skillforge-guide.html 安装引导页(仓库根 + 21 个 skill resources 下同源副本)此前点色瞬切,本轮全部补齐瞬态 .theming 渐变机制,与 12 个产物模板同款效果
12
+ - 缓动升级:过渡曲线由默认 ease 换为 Material Design 标准缓动 cubic-bezier(.4,0,.2,1)——快启柔收,切换观感更利落专业;时长 0.45s 不变
13
+ - 12 模板版本戳再 +1:日报/周报/月报/季报 @3→4、年报/会议纪要 @4→5、锦囊 @16→17、一页纸 @12→13、文章页 @3→4、热力图/收集台 @2→3、演示稿 @3→4
14
+ - 说明:封面模板(deck-stage cover-template)主题由 AI 生成时静态写入、无交互换肤,无需过渡;未引入 View Transitions API——整页快照交叉淡化适合路由切换,换肤场景颜色过渡观感更干净,不叠加双重动画
15
+
7
16
  ## 1.3.10(2026-11-13)
8
17
 
9
18
  **one-pager 主题面板点色不关闭,改由 × 按钮收起(@12)**
@@ -53,7 +53,7 @@ disable-model-invocation: false
53
53
 
54
54
  ## 产物升级(回炉)
55
55
 
56
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="annual-report@4">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧年报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="annual-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版年报(vN-1 或无版本戳的历史产物),说『把我旧年报都升级成新样式』即可一键升级」,不让用户背触发语。
56
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="annual-report@5">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧年报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="annual-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版年报(vN-1 或无版本戳的历史产物),说『把我旧年报都升级成新样式』即可一键升级」,不让用户背触发语。
57
57
 
58
58
  ## 🔧 报修处理流程(用户报页面问题时)
59
59
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="sf-template" content="annual-report@4">
6
+ <meta name="sf-template" content="annual-report@5">
7
7
  <meta name="annual-id" content="REF-ANNUAL-0000">
8
8
  <title>2026 研发年度总结</title>
9
9
  <style>
@@ -253,7 +253,7 @@ html.js .rv.in{ opacity:1; translate:0 0; }
253
253
  .header-card h1{ font-size:26px; }
254
254
  }
255
255
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
256
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
256
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
257
257
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
258
258
 
259
259
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -32,7 +32,7 @@ Turn any Word/Markdown/plain-text article into a standalone styled HTML page and
32
32
 
33
33
  ## 产物升级(回炉)
34
34
 
35
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="article-to-html@3">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧文章页换新样式」时:扫落盘目录下本技能生成的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="article-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本/手改状态——html 与同目录 md 底稿正文对比,不一致视为可能手改过;无 md 底稿时标记「无法比对」)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从 md 底稿按当前 reference.html 重建(无 md 底稿则提取旧 html 正文重建),先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物(vN-1 或无版本戳的历史产物)主动告知「技能模板已升级至 vN,检测到 X 份旧版文章页,说『把我旧文章页都升级成新样式』即可一键升级」,不让用户背触发语。
35
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="article-to-html@4">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧文章页换新样式」时:扫落盘目录下本技能生成的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="article-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本/手改状态——html 与同目录 md 底稿正文对比,不一致视为可能手改过;无 md 底稿时标记「无法比对」)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从 md 底稿按当前 reference.html 重建(无 md 底稿则提取旧 html 正文重建),先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物(vN-1 或无版本戳的历史产物)主动告知「技能模板已升级至 vN,检测到 X 份旧版文章页,说『把我旧文章页都升级成新样式』即可一键升级」,不让用户背触发语。
36
36
 
37
37
  ## Prerequisites(新用户准备)
38
38
 
@@ -13,7 +13,7 @@
13
13
  <head>
14
14
  <meta charset="UTF-8">
15
15
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
16
- <meta name="sf-template" content="article-to-html@3">
16
+ <meta name="sf-template" content="article-to-html@4">
17
17
  <meta name="article-id" content="REF-ARTICLE-0000">
18
18
  <title>设计系统组件示范 · article-to-html</title>
19
19
  <style>
@@ -310,7 +310,7 @@ td.hl{font-weight:700;color:var(--ink)}
310
310
 
311
311
  .foot{text-align:center;padding:34px 0 44px;color:var(--ink-4);font-size:12.5px}
312
312
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
313
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
313
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
314
314
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
315
315
 
316
316
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -51,7 +51,7 @@ disable-model-invocation: false
51
51
 
52
52
  ## 产物升级(回炉)
53
53
 
54
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="commit-heatmap@2">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧热力图/回炉」时:扫落盘目录读版本戳筛旧版(无版本戳或缺少 `<meta name="heat-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文原样保留;深升级(DOM 结构变化)重新跑 git 收集按当前 reference.html 重建,先备份旧版 `.bak-时间戳`,重建必须沿用原页 heat-id meta 值(换 ID = 主题记忆失联)→ 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动、数据格式改动、页面改动任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知用户「说『把我旧热力图都升级成新样式』即可一键升级」。
54
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="commit-heatmap@3">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧热力图/回炉」时:扫落盘目录读版本戳筛旧版(无版本戳或缺少 `<meta name="heat-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文原样保留;深升级(DOM 结构变化)重新跑 git 收集按当前 reference.html 重建,先备份旧版 `.bak-时间戳`,重建必须沿用原页 heat-id meta 值(换 ID = 主题记忆失联)→ 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动、数据格式改动、页面改动任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知用户「说『把我旧热力图都升级成新样式』即可一键升级」。
55
55
 
56
56
  ## 规则速览
57
57
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="sf-template" content="commit-heatmap@2">
6
+ <meta name="sf-template" content="commit-heatmap@3">
7
7
  <meta name="heat-id" content="REF-HEAT-0000">
8
8
  <title>提交热力图 · 示例项目</title>
9
9
  <style>
@@ -75,7 +75,7 @@ body{background:var(--bg);color:var(--text);font-family:system-ui,'Segoe UI',Rob
75
75
  footer{text-align:center;color:var(--muted);font-size:10px;margin-top:26px}
76
76
  html[data-shot] .card{animation:none!important}
77
77
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
78
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
78
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
79
79
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
80
80
 
81
81
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -53,7 +53,7 @@ disable-model-invocation: false
53
53
 
54
54
  ## 产物升级(回炉)
55
55
 
56
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="daily-report@3">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧日报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="daily-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版日报(vN-1 或无版本戳的历史产物),说『把我旧日报都升级成新样式』即可一键升级」,不让用户背触发语。
56
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="daily-report@4">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧日报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="daily-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版日报(vN-1 或无版本戳的历史产物),说『把我旧日报都升级成新样式』即可一键升级」,不让用户背触发语。
57
57
 
58
58
  ## 🔧 报修处理流程(用户报页面问题时)
59
59
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="sf-template" content="daily-report@3">
6
+ <meta name="sf-template" content="daily-report@4">
7
7
  <meta name="daily-id" content="REF-DAILY-0000">
8
8
  <title>今日日报 - 20261106</title>
9
9
  <style>
@@ -407,7 +407,7 @@ html.js .rv.in{ opacity:1; translate:0 0; }
407
407
  .header-card h1{ font-size:26px; }
408
408
  }
409
409
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
410
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
410
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
411
411
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
412
412
 
413
413
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -76,7 +76,7 @@ disable-model-invocation: false
76
76
 
77
77
  ## 产物升级(回炉)
78
78
 
79
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="magic-deck@3">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧演示稿换新样式」时:扫落盘目录下本技能生成的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="deck-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本/手改状态——deck 是单文件产物无 md 底稿,标记「无底稿,正文保留」)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文与 slide 内容原样保留;深升级(DOM 结构变化)提取旧页 slide 内容按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物(vN-1 或无版本戳的历史产物)主动告知「技能模板已升级至 vN,检测到 X 份旧版演示稿,说『把我旧演示稿都升级成新样式』即可一键升级」,不让用户背触发语。
79
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="magic-deck@4">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧演示稿换新样式」时:扫落盘目录下本技能生成的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="deck-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本/手改状态——deck 是单文件产物无 md 底稿,标记「无底稿,正文保留」)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文与 slide 内容原样保留;深升级(DOM 结构变化)提取旧页 slide 内容按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物(vN-1 或无版本戳的历史产物)主动告知「技能模板已升级至 vN,检测到 X 份旧版演示稿,说『把我旧演示稿都升级成新样式』即可一键升级」,不让用户背触发语。
80
80
 
81
81
  ## 📏 文档同步自检纪律(维护者必读)
82
82
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="sf-template" content="magic-deck@3">
6
+ <meta name="sf-template" content="magic-deck@4">
7
7
  <meta name="deck-id" content="REF-DECK-0000">
8
8
  <title>Reference 骨架 — magic-deck 定稿样例</title>
9
9
  <style>
@@ -785,7 +785,7 @@ body:hover .nav{ opacity:1; }
785
785
  }
786
786
 
787
787
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
788
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
788
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
789
789
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
790
790
 
791
791
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -40,7 +40,7 @@ disable-model-invocation: false
40
40
 
41
41
  ## 产物升级(回炉)
42
42
 
43
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="meeting-minutes@4">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧纪要换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="minutes-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版纪要(vN-1 或无版本戳的历史产物),说『把我旧纪要都升级成新样式』即可一键升级」,不让用户背触发语。
43
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="meeting-minutes@5">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧纪要换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="minutes-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版纪要(vN-1 或无版本戳的历史产物),说『把我旧纪要都升级成新样式』即可一键升级」,不让用户背触发语。
44
44
 
45
45
  ## 规则速览
46
46
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="sf-template" content="meeting-minutes@4">
6
+ <meta name="sf-template" content="meeting-minutes@5">
7
7
  <meta name="minutes-id" content="REF-MINUTES-0000">
8
8
  <title>示例项目 周例会纪要</title>
9
9
  <style>
@@ -210,7 +210,7 @@ html.js .rv.in{ opacity:1; translate:0 0; }
210
210
  .act-table th:nth-child(2), .act-table td:nth-child(2){ display:none; }
211
211
  }
212
212
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
213
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
213
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
214
214
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
215
215
 
216
216
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -42,7 +42,7 @@ disable-model-invocation: false
42
42
 
43
43
  ## 产物升级(回炉)
44
44
 
45
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="monthly-report@3">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧月报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="monthly-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版月报(vN-1 或无版本戳的历史产物),说『把我旧月报都升级成新样式』即可一键升级」,不让用户背触发语。
45
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="monthly-report@4">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧月报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="monthly-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版月报(vN-1 或无版本戳的历史产物),说『把我旧月报都升级成新样式』即可一键升级」,不让用户背触发语。
46
46
 
47
47
  ## 🔧 报修处理流程(用户报页面问题时)
48
48
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="sf-template" content="monthly-report@3">
6
+ <meta name="sf-template" content="monthly-report@4">
7
7
  <meta name="monthly-id" content="REF-MONTHLY-0000">
8
8
  <title>2026-11 研发月度总结</title>
9
9
  <style>
@@ -251,7 +251,7 @@ html.js .rv.in{ opacity:1; translate:0 0; }
251
251
  .header-card h1{ font-size:26px; }
252
252
  }
253
253
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
254
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
254
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
255
255
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
256
256
 
257
257
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -62,7 +62,7 @@ disable-model-invocation: false
62
62
 
63
63
  ## 产物升级(回炉)
64
64
 
65
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="one-pager@12">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧海报/回炉」时:顺扫海报库根目录(DIR 值)下两种形态——新子目录形态 `<slug>/poster.html` 与旧平铺形态 `poster-*.html`,读版本戳筛旧版(无版本戳或缺少 `<meta name="poster-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳`,重建必须沿用原页 poster-id meta 值(换 ID = 模板/主题记忆失联)→ 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动、数据格式改动、页面改动任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知用户「说『把我旧海报都升级成新样式』即可一键升级」。
65
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="one-pager@13">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧海报/回炉」时:顺扫海报库根目录(DIR 值)下两种形态——新子目录形态 `<slug>/poster.html` 与旧平铺形态 `poster-*.html`,读版本戳筛旧版(无版本戳或缺少 `<meta name="poster-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳`,重建必须沿用原页 poster-id meta 值(换 ID = 模板/主题记忆失联)→ 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动、数据格式改动、页面改动任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知用户「说『把我旧海报都升级成新样式』即可一键升级」。
66
66
 
67
67
  ## 规则速览
68
68
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="sf-template" content="one-pager@12">
6
+ <meta name="sf-template" content="one-pager@13">
7
7
  <meta name="poster-id" content="REF-POSTER-0000">
8
8
  <title>AI 改变工作 · 一页纸海报</title>
9
9
  <style>
@@ -700,7 +700,7 @@ html[data-shot] .dock-tpl,html[data-shot] .dock-theme{display:none!important}
700
700
  .dock-body{max-width:calc(100vw - 36px)}
701
701
  }
702
702
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
703
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
703
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
704
704
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
705
705
 
706
706
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skill-forge-hub",
3
- "version": "1.3.10",
3
+ "version": "1.3.11",
4
4
  "description": "SkillForge (技能锻造坊) — a curated collection of AI craft skills. Install once, then pick skills interactively: daily/weekly/monthly/quarterly/annual reports, meeting minutes, article-to-HTML, magic-deck slides, deck-stage PPTX, prompt-pouch manager, Pandoc doc converters, meta-forge.",
5
5
  "bin": {
6
6
  "skill-forge": "cli.js"
@@ -78,7 +78,7 @@ disable-model-invocation: false
78
78
 
79
79
  ## 产物升级(回炉)
80
80
 
81
- 生成/初始化页面时头部写版本戳 `<meta name="sf-template" content="prompt-pouch@16">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧锦囊/回炉旧页面/旧锦囊换新样式」时:扫 `<DIR>` 下 `prompt-pouch.html` 读版本戳筛出旧版(无版本戳或缺少 `<meta name="pouch-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本/有无用户数据)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本;深升级(DOM 结构变化)从 reference.html 重建,**必须沿用原页 pouch-id meta 值**(IndexedDB 用户数据按 pouch-id 命名空间存取,换 ID = 数据失联,重建后原收藏/分组照旧读回),`<DIR>/<DATA_DIR>/prompts.json` 数据文件一概不动,先备份旧页 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成/初始化新锦囊时顺扫 `<DIR>` 读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版锦囊,说『把我旧锦囊都升级成新样式』即可一键升级」,不让用户背触发语。
81
+ 生成/初始化页面时头部写版本戳 `<meta name="sf-template" content="prompt-pouch@17">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧锦囊/回炉旧页面/旧锦囊换新样式」时:扫 `<DIR>` 下 `prompt-pouch.html` 读版本戳筛出旧版(无版本戳或缺少 `<meta name="pouch-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本/有无用户数据)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本;深升级(DOM 结构变化)从 reference.html 重建,**必须沿用原页 pouch-id meta 值**(IndexedDB 用户数据按 pouch-id 命名空间存取,换 ID = 数据失联,重建后原收藏/分组照旧读回),`<DIR>/<DATA_DIR>/prompts.json` 数据文件一概不动,先备份旧页 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成/初始化新锦囊时顺扫 `<DIR>` 读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版锦囊,说『把我旧锦囊都升级成新样式』即可一键升级」,不让用户背触发语。
82
82
 
83
83
  ## ⚙️ 配置与自定义主题
84
84
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="sf-template" content="prompt-pouch@16">
6
+ <meta name="sf-template" content="prompt-pouch@17">
7
7
  <meta name="pouch-id" content="REF-POUCH-0000">
8
8
  <title>锦囊 Prompt Pouch — 提示词管理台</title>
9
9
  <style>
@@ -692,7 +692,7 @@ footer.open .ht-arrow{ transform:rotate(180deg); }
692
692
  .theme-dock .th-dot[data-theme="mint"]{ background:#4ade80; }
693
693
  @media print{ .theme-dock{ display:none; } }
694
694
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
695
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
695
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
696
696
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
697
697
 
698
698
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -42,7 +42,7 @@ disable-model-invocation: false
42
42
 
43
43
  ## 产物升级(回炉)
44
44
 
45
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="quarterly-report@3">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧季报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="quarterly-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版季报(vN-1 或无版本戳的历史产物),说『把我旧季报都升级成新样式』即可一键升级」,不让用户背触发语。
45
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="quarterly-report@4">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧季报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="quarterly-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版季报(vN-1 或无版本戳的历史产物),说『把我旧季报都升级成新样式』即可一键升级」,不让用户背触发语。
46
46
 
47
47
  ## 🔧 报修处理流程(用户报页面问题时)
48
48
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="sf-template" content="quarterly-report@3">
6
+ <meta name="sf-template" content="quarterly-report@4">
7
7
  <meta name="quarterly-id" content="REF-QUARTERLY-0000">
8
8
  <title>2026-Q4 研发季度总结</title>
9
9
  <style>
@@ -231,7 +231,7 @@ html.js .rv.in{ opacity:1; translate:0 0; }
231
231
  .header-card h1{ font-size:26px; }
232
232
  }
233
233
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
234
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
234
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
235
235
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
236
236
 
237
237
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -51,7 +51,7 @@ disable-model-invocation: false
51
51
 
52
52
  ## 产物升级(回炉)
53
53
 
54
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="team-report-collector@2">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧收集台/回炉」时:扫落盘目录读版本戳筛旧版(无版本戳或缺少 `<meta name="trc-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文原样保留;深升级(DOM 结构变化)从同目录 reports.json 数据按当前 reference.html 重建,先备份旧版 `.bak-时间戳`,重建必须沿用原页 trc-id meta 值(换 ID = 页面运行时收集的本地数据失联)→ 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动、数据格式改动、页面改动任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知用户「说『把我旧收集台都升级成新样式』即可一键升级」。
54
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="team-report-collector@3">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧收集台/回炉」时:扫落盘目录读版本戳筛旧版(无版本戳或缺少 `<meta name="trc-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单)→ 列清单(文件/旧版本)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文原样保留;深升级(DOM 结构变化)从同目录 reports.json 数据按当前 reference.html 重建,先备份旧版 `.bak-时间戳`,重建必须沿用原页 trc-id meta 值(换 ID = 页面运行时收集的本地数据失联)→ 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动、数据格式改动、页面改动任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知用户「说『把我旧收集台都升级成新样式』即可一键升级」。
55
55
 
56
56
  ## 规则速览
57
57
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="sf-template" content="team-report-collector@2">
6
+ <meta name="sf-template" content="team-report-collector@3">
7
7
  <meta name="trc-id" content="REF-TRC-0000">
8
8
  <title>示例团队日报收集台</title>
9
9
  <style>
@@ -191,7 +191,7 @@ html[data-shot] .card{animation:none!important}
191
191
  @media (max-width:680px){body{padding:24px 12px}.wrap{width:100%}.row2{grid-template-columns:1fr}.header-card h1{font-size:18px}}
192
192
  @media print{.theme-dock,.btn{display:none}}
193
193
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
194
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
194
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
195
195
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
196
196
 
197
197
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>
@@ -53,7 +53,7 @@ disable-model-invocation: false
53
53
 
54
54
  ## 产物升级(回炉)
55
55
 
56
- 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="weekly-report@3">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧周报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="weekly-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版周报(vN-1 或无版本戳的历史产物),说『把我旧周报都升级成新样式』即可一键升级」,不让用户背触发语。
56
+ 生成 HTML 时头部写版本戳 `<meta name="sf-template" content="weekly-report@4">`(模板升级时递增 @N 并同步 reference.html 与本文档)。用户说「升级旧产物/回炉旧页面/旧周报换新样式」时:扫落盘目录下本技能命名的 html,读版本戳筛出旧版(无版本戳或缺少 `<meta name="weekly-id">` 稳定 ID 的产物视为 v0 最旧版,一并进清单) → 列清单(文件/旧版本/手改状态——旧 html 正文与同目录 md 正文对比,不一致视为可能手改过)→ AskUserQuestion 选全部或部分 → 逐份升级:浅升级(仅 CSS/JS 变化)对旧页替换 `<style>` 块与交互脚本、正文内容原样保留;深升级(DOM 结构变化)从同目录 md 底稿按当前 reference.html 重建,先备份旧版 `.bak-时间戳` → 报告三段式:✅ 已升级清单 / ⚠️ 手改保留说明 / 🟡 失败项原因。模板改动分级:业务改动(板块/段落/标题体系)、数据格式改动(字段/存储结构)、页面改动(样式/布局/交互)任一发生即模板升级,版本戳 +1 并同步 reference.html 与本文档;纯措辞润色不 bump。每次生成 HTML 时顺扫落盘目录读版本戳:发现旧版产物主动告知「技能模板已升级至 vN,检测到 X 份旧版周报(vN-1 或无版本戳的历史产物),说『把我旧周报都升级成新样式』即可一键升级」,不让用户背触发语。
57
57
 
58
58
  ## 🔧 报修处理流程(用户报页面问题时)
59
59
 
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <meta name="sf-template" content="weekly-report@3">
6
+ <meta name="sf-template" content="weekly-report@4">
7
7
  <meta name="weekly-id" content="REF-WEEKLY-0000">
8
8
  <title>本周周报 - 20261102 ~ 20261106</title>
9
9
  <style>
@@ -529,7 +529,7 @@ html.js .rv.in{ opacity:1; translate:0 0; }
529
529
  .header-card h1{ font-size:26px; }
530
530
  }
531
531
  /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡;平时类不存在,不影响任何元素 */
532
- html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s ease, color .45s ease, border-color .45s ease, box-shadow .45s ease, fill .45s ease, stroke .45s ease !important; }
532
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
533
533
  @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
534
534
 
535
535
  </style>
@@ -205,6 +205,10 @@ footer{text-align:center;font-size:10px;color:var(--muted);letter-spacing:1px;pa
205
205
  .header-card{ padding:26px 18px 20px; }
206
206
  .header-card h1{ font-size:26px; }
207
207
  }
208
+ /* 主题切换渐变:切换瞬间给 html 挂 .theming 类(650ms 后自动摘除),期间全页颜色属性平滑过渡(Material 标准缓动);平时类不存在,不影响任何元素 */
209
+ html.theming, html.theming *, html.theming *::before, html.theming *::after{ transition: background-color .45s cubic-bezier(.4,0,.2,1), color .45s cubic-bezier(.4,0,.2,1), border-color .45s cubic-bezier(.4,0,.2,1), box-shadow .45s cubic-bezier(.4,0,.2,1), fill .45s cubic-bezier(.4,0,.2,1), stroke .45s cubic-bezier(.4,0,.2,1) !important; }
210
+ @media (prefers-reduced-motion: reduce){ html.theming, html.theming *{ transition: none !important; } }
211
+
208
212
  </style>
209
213
  </head>
210
214
  <body>
@@ -402,7 +406,7 @@ if (location.search.indexOf('shot=') !== -1) {
402
406
  var saved = null; try{ saved = localStorage.getItem('sf-guide-theme'); }catch(e){}
403
407
  if (saved && THEMES.indexOf(saved) !== -1 && saved !== cur){ apply(saved); }
404
408
  else{ dock.querySelectorAll('.th-dot').forEach(function(d){ d.classList.toggle('on', d.getAttribute('data-theme') === (cur || 'tech')); }); }
405
- dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ apply(d.getAttribute('data-theme')); }); });
409
+ dock.querySelectorAll('.th-dot').forEach(function(d){ d.addEventListener('click', function(){ var r = document.documentElement; r.classList.add('theming'); clearTimeout(r.__sfThT); r.__sfThT = setTimeout(function(){ r.classList.remove('theming'); }, 650); apply(d.getAttribute('data-theme')); }); });
406
410
  })();
407
411
  </script>
408
412
  </body>