skill-forge-hub 1.3.10 → 1.3.12

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 +18 -0
  2. package/CHANGELOG.md +18 -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 +44 -44
  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,24 @@
4
4
 
5
5
  Version history of the SkillForge npm package `skill-forge-hub` (command name `skill-forge`).
6
6
 
7
+ ## 1.3.12 (2026-11-13)
8
+
9
+ **one-pager privilege templates get "mood response": six signature palettes now track the theme's light/dark mood (@14)**
10
+
11
+ - Fix: acid / glitch / vaporwave / inkwash / palace / landscape previously hardcoded their signature hues, so theme switching only changed the page chrome (docks / container) while the poster body stayed frozen — the reported "only the browser shell changes"
12
+ - Mood-response approach: every signature hue now uses CSS color-mix() against theme tokens — backgrounds mix var(--bg) at 22%, accents mix var(--accent) at 20%, ink text mixes var(--text) at 20%, muted text mixes var(--muted) at 25%; the signature look dominates (character preserved) while brightness/warmth subtly follow the theme (the switch is felt), covering all 25 themes with zero lookup tables
13
+ - Fade compatibility: the transient transition list across all 34 interactive-skin HTML files now also includes background — solid backgrounds (paper base, mountain layers) fade smoothly on theme switch, gradient backgrounds switch discretely per browser standard; existing color / border / shadow fades unaffected
14
+ - Template stamp one-pager@13 → @14
15
+
16
+ ## 1.3.11 (2026-11-13)
17
+
18
+ **Theme-fade full coverage: 22 install guide pages get the transition, 12 templates upgrade to Material easing**
19
+
20
+ - 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
21
+ - 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
22
+ - 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
23
+ - 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
24
+
7
25
  ## 1.3.10 (2026-11-13)
8
26
 
9
27
  **one-pager theme panel stays open on color pick, closes via a new × button (@12)**
package/CHANGELOG.md CHANGED
@@ -4,6 +4,24 @@
4
4
 
5
5
  SkillForge(技能锻造坊)npm 包 `skill-forge-hub`(命令名 `skill-forge`)版本变更记录。
6
6
 
7
+ ## 1.3.12(2026-11-13)
8
+
9
+ **one-pager 特许模板「氛围响应」:六款风格固有色随主题明暗冷暖适配(@14)**
10
+
11
+ - 问题修复:acid / glitch / vaporwave / 水墨 / 宫廷 / 青绿山水六款特许模板此前硬编码风格本体色,切换主题时只有页面壳(换肤坞 / 容器)在变、海报主体纹丝不动——用户反馈「主题切换只是浏览器的壳在变化」
12
+ - 氛围响应方案:特许本色一律改为 CSS color-mix() 与主题变量按比例混合——背景色混 var(--bg) 22%、强调装饰色混 var(--accent) 20%、墨字混 var(--text) 20%、灰字混 var(--muted) 25%,本色主导(气质不丢)又随主题明暗冷暖微调(切换有感),零映射表天然覆盖全部 25 主题
13
+ - 渐变兼容:34 个交互换肤 HTML 的瞬态过渡列表统一加 background 属性——纯色背景(宣纸底 / 山峦等)切主题平滑渐变,渐变背景按浏览器标准离散切换;既有 color / border / 阴影渐变不受影响
14
+ - 版本戳 one-pager@13 → @14
15
+
16
+ ## 1.3.11(2026-11-13)
17
+
18
+ **换肤渐变全覆盖:22 份安装引导页补齐过渡,12 模板缓动升级 Material 标准曲线**
19
+
20
+ - 盘点补漏:skillforge-guide.html 安装引导页(仓库根 + 21 个 skill resources 下同源副本)此前点色瞬切,本轮全部补齐瞬态 .theming 渐变机制,与 12 个产物模板同款效果
21
+ - 缓动升级:过渡曲线由默认 ease 换为 Material Design 标准缓动 cubic-bezier(.4,0,.2,1)——快启柔收,切换观感更利落专业;时长 0.45s 不变
22
+ - 12 模板版本戳再 +1:日报/周报/月报/季报 @3→4、年报/会议纪要 @4→5、锦囊 @16→17、一页纸 @12→13、文章页 @3→4、热力图/收集台 @2→3、演示稿 @3→4
23
+ - 说明:封面模板(deck-stage cover-template)主题由 AI 生成时静态写入、无交互换肤,无需过渡;未引入 View Transitions API——整页快照交叉淡化适合路由切换,换肤场景颜色过渡观感更干净,不叠加双重动画
24
+
7
25
  ## 1.3.10(2026-11-13)
8
26
 
9
27
  **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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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@14">`(模板升级时递增 @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@14">
7
7
  <meta name="poster-id" content="REF-POSTER-0000">
8
8
  <title>AI 改变工作 · 一页纸海报</title>
9
9
  <style>
@@ -463,10 +463,10 @@ body{background:linear-gradient(180deg,var(--bg) 12%,var(--bg2) 135%);color:var(
463
463
  .tpl-artnouveau ul.points .num{font-family:Georgia,serif;font-size:15px;font-style:italic;color:var(--accent);margin-right:8px}
464
464
  .tpl-artnouveau footer{font-size:10px;letter-spacing:3px;color:var(--muted);display:flex;gap:24px}
465
465
 
466
- /* 21. acid 酸性设计:液态金属 blob + 荧光斜切徽章(风格本体色特许:金属灰) */
466
+ /* 21. acid 酸性设计:液态金属 blob + 荧光斜切徽章(风格本体色特许:金属灰,经 color-mix 混入主题强调色) */
467
467
  .tpl-acid{display:flex;flex-direction:column;justify-content:center;width:min(82%,1100px);height:100%;padding:6vh 0;position:relative}
468
468
  .tpl-acid .liquid{position:absolute;inset:0;pointer-events:none;background:linear-gradient(115deg,transparent 42%,var(--border) 46%,transparent 52%),repeating-linear-gradient(90deg,var(--border) 0 1px,transparent 1px 90px);opacity:.8}
469
- .tpl-acid .blob{position:absolute;top:8%;right:6%;width:min(24vw,190px);height:min(24vw,190px);border-radius:58% 42% 55% 45% / 48% 55% 45% 52%;background:conic-gradient(from 210deg,rgba(180,180,170,.9),rgba(70,70,80,.9),rgba(220,220,210,.9),rgba(90,90,100,.9),rgba(180,180,170,.9));box-shadow:inset 0 0 24px rgba(0,0,0,.35);opacity:.85}
469
+ .tpl-acid .blob{position:absolute;top:8%;right:6%;width:min(24vw,190px);height:min(24vw,190px);border-radius:58% 42% 55% 45% / 48% 55% 45% 52%;background:conic-gradient(from 210deg,color-mix(in srgb,rgba(180,180,170,.9) 80%,var(--accent) 20%),color-mix(in srgb,rgba(70,70,80,.9) 80%,var(--accent) 20%),color-mix(in srgb,rgba(220,220,210,.9) 80%,var(--accent) 20%),color-mix(in srgb,rgba(90,90,100,.9) 80%,var(--accent) 20%),color-mix(in srgb,rgba(180,180,170,.9) 80%,var(--accent) 20%));box-shadow:inset 0 0 24px rgba(0,0,0,.35);opacity:.85}
470
470
  .tpl-acid .badge{font-size:12px;font-weight:900;letter-spacing:3px;color:var(--bg);background:var(--accent);padding:7px 16px;border-radius:2px;transform:skewX(-12deg);margin-bottom:3vh;align-self:flex-start}
471
471
  .tpl-acid h1{font-size:clamp(44px,5.8vw,76px);font-weight:900;line-height:1.02;letter-spacing:-1px;color:var(--text);margin-bottom:2.5vh}
472
472
  .tpl-acid .quote{font-size:15px;color:var(--muted);margin-bottom:4vh;max-width:70%;border-left:4px solid var(--accent);padding-left:16px}
@@ -476,24 +476,24 @@ body{background:linear-gradient(180deg,var(--bg) 12%,var(--bg2) 135%);color:var(
476
476
  .tpl-acid ul.points .num{color:var(--accent);font-family:ui-monospace,'SF Mono',Menlo,monospace}
477
477
  .tpl-acid footer{display:flex;justify-content:space-between;font-size:10px;letter-spacing:2px;color:var(--muted);border-top:1px dashed var(--border);padding-top:12px}
478
478
 
479
- /* 22. glitch 故障艺术:RGB 错位标题 + 阶梯裁切卡(风格本体色特许:品红/青错位影) */
479
+ /* 22. glitch 故障艺术:RGB 错位标题 + 阶梯裁切卡(风格本体色特许:品红/青错位影,经 color-mix 混入主题强调色) */
480
480
  .tpl-glitch{display:flex;flex-direction:column;justify-content:center;width:min(84%,1150px);height:100%;padding:6vh 0;position:relative}
481
- .tpl-glitch .bars{position:absolute;inset:0;pointer-events:none;background:repeating-linear-gradient(0deg,transparent 0 18px,rgba(255,0,200,.06) 18px 21px,rgba(0,255,255,.06) 21px 24px)}
481
+ .tpl-glitch .bars{position:absolute;inset:0;pointer-events:none;background:repeating-linear-gradient(0deg,transparent 0 18px,color-mix(in srgb,var(--accent) 6%,transparent) 18px 21px,color-mix(in srgb,var(--accent2) 6%,transparent) 21px 24px)}
482
482
  .tpl-glitch .badge{font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:12px;letter-spacing:3px;color:var(--accent);border:1.5px solid var(--accent);padding:5px 12px;margin-bottom:3vh;align-self:flex-start}
483
483
  .tpl-glitch h1{position:relative;font-size:clamp(44px,6vw,80px);font-weight:900;line-height:1.05;color:var(--text);margin-bottom:3vh}
484
484
  .tpl-glitch h1::before,.tpl-glitch h1::after{content:attr(data-t);position:absolute;inset:0;opacity:.7}
485
- .tpl-glitch h1::before{color:#f0f;transform:translate(-3px,2px);clip-path:inset(12% 0 58% 0)}
486
- .tpl-glitch h1::after{color:#0ff;transform:translate(3px,-2px);clip-path:inset(58% 0 12% 0)}
485
+ .tpl-glitch h1::before{color:color-mix(in srgb,#f0f 78%,var(--accent) 22%);transform:translate(-3px,2px);clip-path:inset(12% 0 58% 0)}
486
+ .tpl-glitch h1::after{color:color-mix(in srgb,#0ff 78%,var(--accent2) 22%);transform:translate(3px,-2px);clip-path:inset(58% 0 12% 0)}
487
487
  .tpl-glitch .quote{font-size:15px;color:var(--muted);margin-bottom:4vh;max-width:70%;font-family:ui-monospace,'SF Mono',Menlo,monospace}
488
488
  .tpl-glitch ul.points{list-style:none;display:grid;grid-template-columns:repeat(2,1fr);gap:14px;margin-bottom:4vh}
489
489
  .tpl-glitch ul.points li{font-size:14px;color:var(--text);background:var(--panel-solid);border:1px solid var(--border);padding:12px 14px;display:flex;gap:10px;align-items:baseline;clip-path:polygon(0 0,100% 0,100% calc(100% - 8px),calc(100% - 8px) 100%,0 100%)}
490
490
  .tpl-glitch ul.points .num{font-family:ui-monospace,'SF Mono',Menlo,monospace;color:var(--accent);font-weight:800}
491
491
  .tpl-glitch footer{display:flex;justify-content:space-between;font-size:10px;letter-spacing:2px;color:var(--muted);font-family:ui-monospace,'SF Mono',Menlo,monospace}
492
492
 
493
- /* 23. vaporwave 蒸汽波:落日渐变 + 透视网格地平线(风格本体色特许:粉紫地平线) */
493
+ /* 23. vaporwave 蒸汽波:落日渐变 + 透视网格地平线(风格本体色特许:粉紫地平线,经 color-mix 混入主题强调色) */
494
494
  .tpl-vaporwave{display:flex;flex-direction:column;justify-content:flex-end;width:min(86%,1150px);height:100%;padding:7vh 0 6vh;position:relative}
495
495
  .tpl-vaporwave .sun{position:absolute;top:12%;left:50%;transform:translateX(-50%);width:min(34vw,260px);height:min(34vw,260px);border-radius:50%;background:linear-gradient(180deg,var(--accent2),transparent 62%);opacity:.55;pointer-events:none}
496
- .tpl-vaporwave .grid{position:absolute;bottom:0;left:0;right:0;height:42%;pointer-events:none;background:linear-gradient(180deg,transparent,rgba(180,80,255,.28)),repeating-linear-gradient(90deg,rgba(255,255,255,.14) 0 1px,transparent 1px 64px),repeating-linear-gradient(0deg,rgba(255,255,255,.14) 0 1px,transparent 1px 34px);transform:perspective(340px) rotateX(58deg);transform-origin:bottom}
496
+ .tpl-vaporwave .grid{position:absolute;bottom:0;left:0;right:0;height:42%;pointer-events:none;background:linear-gradient(180deg,transparent,color-mix(in srgb,rgba(180,80,255,.28) 76%,var(--accent) 24%)),repeating-linear-gradient(90deg,rgba(255,255,255,.14) 0 1px,transparent 1px 64px),repeating-linear-gradient(0deg,rgba(255,255,255,.14) 0 1px,transparent 1px 34px);transform:perspective(340px) rotateX(58deg);transform-origin:bottom}
497
497
  .tpl-vaporwave .badge{font-size:12px;letter-spacing:5px;color:var(--bg);background:linear-gradient(90deg,var(--accent),var(--accent2));padding:7px 18px;border-radius:999px;margin-bottom:3vh;align-self:flex-start}
498
498
  .tpl-vaporwave h1{font-size:clamp(40px,5.4vw,70px);font-weight:900;line-height:1.1;letter-spacing:1px;color:var(--text);margin-bottom:2.5vh}
499
499
  .tpl-vaporwave .quote{font-size:15px;color:var(--muted);margin-bottom:4vh;max-width:64%}
@@ -571,52 +571,52 @@ body{background:linear-gradient(180deg,var(--bg) 12%,var(--bg2) 135%);color:var(
571
571
  .tpl-notice ul.points .num{color:var(--accent);font-weight:800}
572
572
  .tpl-notice footer{display:flex;flex-direction:column;align-items:flex-end;font-size:12px;color:var(--muted);gap:6px;margin-top:auto}
573
573
 
574
- /* 29. inkwash 水墨:宣纸底 + 墨色远山 + 朱印落款(风格本体色特许:宣纸米/墨黑/朱砂红) */
575
- .tpl-inkwash{display:flex;align-items:center;justify-content:center;width:100%;height:100%;position:relative;overflow:hidden;background:#f5f0e3}
576
- .tpl-inkwash .mt{position:absolute;border-radius:50%;pointer-events:none;background:#26221e}
574
+ /* 29. inkwash 水墨:宣纸底 + 墨色远山 + 朱印落款(风格本体色特许:宣纸米/墨黑/朱砂红,经 color-mix 与主题变量氛围混合) */
575
+ .tpl-inkwash{display:flex;align-items:center;justify-content:center;width:100%;height:100%;position:relative;overflow:hidden;background:color-mix(in srgb,#f5f0e3 78%,var(--bg) 22%)}
576
+ .tpl-inkwash .mt{position:absolute;border-radius:50%;pointer-events:none;background:color-mix(in srgb,#26221e 78%,var(--bg) 22%)}
577
577
  .tpl-inkwash .m1{width:76%;height:26%;left:-6%;bottom:-7%;opacity:.07}
578
578
  .tpl-inkwash .m2{width:92%;height:30%;left:14%;bottom:-13%;opacity:.13}
579
579
  .tpl-inkwash .m3{width:104%;height:34%;left:24%;bottom:-17%;opacity:.2}
580
- .tpl-inkwash .sun{position:absolute;right:15%;top:11%;width:min(15vw,110px);height:min(15vw,110px);border-radius:50%;background:#b03a2e;opacity:.92;pointer-events:none}
580
+ .tpl-inkwash .sun{position:absolute;right:15%;top:11%;width:min(15vw,110px);height:min(15vw,110px);border-radius:50%;background:color-mix(in srgb,#b03a2e 80%,var(--accent) 20%);opacity:.92;pointer-events:none}
581
581
  .tpl-inkwash .content{position:relative;display:flex;flex-direction:column;justify-content:center;width:min(82%,1060px);height:100%;padding:7vh 0}
582
- .tpl-inkwash .seal{align-self:flex-start;font-family:Georgia,'Songti SC','SimSun',serif;font-size:13px;font-weight:700;letter-spacing:2px;color:#f5f0e3;background:#b03a2e;padding:8px 12px;border-radius:4px;margin-bottom:3vh}
583
- .tpl-inkwash h1{font-family:Georgia,'Songti SC','SimSun',serif;font-size:clamp(38px,5.2vw,66px);font-weight:700;color:#26221e;line-height:1.4;margin-bottom:2.5vh}
584
- .tpl-inkwash .quote{font-size:16px;font-style:italic;color:#6b645a;margin-bottom:4vh;max-width:72%;border-left:3px solid #b03a2e;padding-left:18px;line-height:1.9}
582
+ .tpl-inkwash .seal{align-self:flex-start;font-family:Georgia,'Songti SC','SimSun',serif;font-size:13px;font-weight:700;letter-spacing:2px;color:color-mix(in srgb,#f5f0e3 78%,var(--bg) 22%);background:color-mix(in srgb,#b03a2e 80%,var(--accent) 20%);padding:8px 12px;border-radius:4px;margin-bottom:3vh}
583
+ .tpl-inkwash h1{font-family:Georgia,'Songti SC','SimSun',serif;font-size:clamp(38px,5.2vw,66px);font-weight:700;color:color-mix(in srgb,#26221e 80%,var(--text) 20%);line-height:1.4;margin-bottom:2.5vh}
584
+ .tpl-inkwash .quote{font-size:16px;font-style:italic;color:color-mix(in srgb,#6b645a 75%,var(--muted) 25%);margin-bottom:4vh;max-width:72%;border-left:3px solid color-mix(in srgb,#b03a2e 80%,var(--accent) 20%);padding-left:18px;line-height:1.9}
585
585
  .tpl-inkwash ul.points{list-style:none;display:flex;flex-direction:column;gap:14px;margin-bottom:4vh}
586
- .tpl-inkwash ul.points li{font-size:15px;color:#26221e;display:flex;gap:12px;align-items:baseline;line-height:1.8}
587
- .tpl-inkwash ul.points .num{font-family:Georgia,'Songti SC','SimSun',serif;color:#b03a2e;font-weight:700;flex:none}
588
- .tpl-inkwash footer{display:flex;justify-content:space-between;font-size:10px;letter-spacing:3px;color:#6b645a;border-top:1px solid rgba(38,34,30,.18);padding-top:14px}
586
+ .tpl-inkwash ul.points li{font-size:15px;color:color-mix(in srgb,#26221e 80%,var(--text) 20%);display:flex;gap:12px;align-items:baseline;line-height:1.8}
587
+ .tpl-inkwash ul.points .num{font-family:Georgia,'Songti SC','SimSun',serif;color:color-mix(in srgb,#b03a2e 80%,var(--accent) 20%);font-weight:700;flex:none}
588
+ .tpl-inkwash footer{display:flex;justify-content:space-between;font-size:10px;letter-spacing:3px;color:color-mix(in srgb,#6b645a 75%,var(--muted) 25%);border-top:1px solid color-mix(in srgb,rgba(38,34,30,.18) 75%,var(--border) 25%);padding-top:14px}
589
589
 
590
- /* 30. palace 红金宫廷:朱红底 + 回纹金边双线框 + 衬线金字(风格本体色特许:朱红/鎏金/米白) */
591
- .tpl-palace{display:flex;align-items:center;justify-content:center;width:100%;height:100%;background:linear-gradient(160deg,#7a1f1f,#5e1717);padding:6vh 0}
592
- .tpl-palace .frame{position:relative;width:min(80%,1060px);height:100%;display:flex;flex-direction:column;justify-content:center;border:2px solid #d4af37;outline:1px solid #d4af37;outline-offset:5px;padding:7vh 5vw;text-align:center;background:repeating-linear-gradient(90deg,rgba(212,175,55,.08) 0 2px,transparent 2px 34px)}
590
+ /* 30. palace 红金宫廷:朱红底 + 回纹金边双线框 + 衬线金字(风格本体色特许:朱红/鎏金/米白,经 color-mix 与主题变量氛围混合) */
591
+ .tpl-palace{display:flex;align-items:center;justify-content:center;width:100%;height:100%;background:linear-gradient(160deg,color-mix(in srgb,#7a1f1f 78%,var(--bg) 22%),color-mix(in srgb,#5e1717 78%,var(--bg) 22%));padding:6vh 0}
592
+ .tpl-palace .frame{position:relative;width:min(80%,1060px);height:100%;display:flex;flex-direction:column;justify-content:center;border:2px solid color-mix(in srgb,#d4af37 80%,var(--accent) 20%);outline:1px solid color-mix(in srgb,#d4af37 80%,var(--accent) 20%);outline-offset:5px;padding:7vh 5vw;text-align:center;background:repeating-linear-gradient(90deg,rgba(212,175,55,.08) 0 2px,transparent 2px 34px)}
593
593
  .tpl-palace .frame::after{content:'';position:absolute;inset:9px;border:1px solid rgba(212,175,55,.5);pointer-events:none}
594
- .tpl-palace .badge{font-size:12px;letter-spacing:8px;color:#d4af37;margin-bottom:2.5vh}
595
- .tpl-palace h1{font-family:Georgia,'Songti SC','SimSun',serif;font-size:clamp(36px,4.8vw,62px);font-weight:700;color:#f5ead1;margin-bottom:2vh;line-height:1.4}
596
- .tpl-palace .divider{display:flex;align-items:center;gap:14px;justify-content:center;color:#d4af37;font-size:13px;margin-bottom:2.5vh}
597
- .tpl-palace .divider::before,.tpl-palace .divider::after{content:'';height:1px;width:110px;background:linear-gradient(90deg,transparent,#d4af37)}
598
- .tpl-palace .divider::after{background:linear-gradient(90deg,#d4af37,transparent)}
599
- .tpl-palace .quote{font-size:15px;font-style:italic;color:#e8cba0;margin-bottom:3.5vh;max-width:70%;margin-left:auto;margin-right:auto}
594
+ .tpl-palace .badge{font-size:12px;letter-spacing:8px;color:color-mix(in srgb,#d4af37 80%,var(--accent) 20%);margin-bottom:2.5vh}
595
+ .tpl-palace h1{font-family:Georgia,'Songti SC','SimSun',serif;font-size:clamp(36px,4.8vw,62px);font-weight:700;color:color-mix(in srgb,#f5ead1 80%,var(--text) 20%);margin-bottom:2vh;line-height:1.4}
596
+ .tpl-palace .divider{display:flex;align-items:center;gap:14px;justify-content:center;color:color-mix(in srgb,#d4af37 80%,var(--accent) 20%);font-size:13px;margin-bottom:2.5vh}
597
+ .tpl-palace .divider::before,.tpl-palace .divider::after{content:'';height:1px;width:110px;background:linear-gradient(90deg,transparent,color-mix(in srgb,#d4af37 80%,var(--accent) 20%))}
598
+ .tpl-palace .divider::after{background:linear-gradient(90deg,color-mix(in srgb,#d4af37 80%,var(--accent) 20%),transparent)}
599
+ .tpl-palace .quote{font-size:15px;font-style:italic;color:color-mix(in srgb,#e8cba0 80%,var(--text) 20%);margin-bottom:3.5vh;max-width:70%;margin-left:auto;margin-right:auto}
600
600
  .tpl-palace ul.points{list-style:none;display:flex;justify-content:center;gap:3.5vw;flex-wrap:wrap;margin-bottom:3.5vh}
601
- .tpl-palace ul.points li{font-size:14px;color:#f5ead1;display:flex;gap:8px;align-items:center;line-height:1.8}
602
- .tpl-palace ul.points .num{width:22px;height:22px;border:1px solid #d4af37;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;color:#d4af37;flex:none}
603
- .tpl-palace footer{display:flex;justify-content:center;gap:26px;font-size:10px;letter-spacing:3px;color:#d8b878}
601
+ .tpl-palace ul.points li{font-size:14px;color:color-mix(in srgb,#f5ead1 80%,var(--text) 20%);display:flex;gap:8px;align-items:center;line-height:1.8}
602
+ .tpl-palace ul.points .num{width:22px;height:22px;border:1px solid color-mix(in srgb,#d4af37 80%,var(--accent) 20%);border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;color:color-mix(in srgb,#d4af37 80%,var(--accent) 20%);flex:none}
603
+ .tpl-palace footer{display:flex;justify-content:center;gap:26px;font-size:10px;letter-spacing:3px;color:color-mix(in srgb,#d8b878 75%,var(--muted) 25%)}
604
604
 
605
- /* 31. landscape 青绿山水:clip-path 层叠山峦 + 留白天际 + 题跋落款(风格本体色特许:青绿/赭石/留白) */
606
- .tpl-landscape{display:flex;align-items:center;justify-content:center;width:100%;height:100%;position:relative;overflow:hidden;background:#f4f1e8}
605
+ /* 31. landscape 青绿山水:clip-path 层叠山峦 + 留白天际 + 题跋落款(风格本体色特许:青绿/赭石/留白,经 color-mix 与主题变量氛围混合) */
606
+ .tpl-landscape{display:flex;align-items:center;justify-content:center;width:100%;height:100%;position:relative;overflow:hidden;background:color-mix(in srgb,#f4f1e8 78%,var(--bg) 22%)}
607
607
  .tpl-landscape .peak{position:absolute;left:-6%;right:-6%;pointer-events:none}
608
- .tpl-landscape .p1{bottom:36%;height:32%;background:#a8c6b4;clip-path:polygon(0 100%,8% 42%,18% 66%,30% 30%,44% 58%,56% 38%,68% 62%,80% 34%,100% 70%,100% 100%)}
609
- .tpl-landscape .p2{bottom:23%;height:32%;background:#6ea08d;clip-path:polygon(0 100%,12% 48%,26% 72%,40% 40%,58% 68%,72% 44%,86% 70%,100% 50%,100% 100%)}
610
- .tpl-landscape .p3{bottom:9%;height:30%;background:#4a8a76;clip-path:polygon(0 100%,10% 58%,30% 78%,50% 52%,70% 80%,88% 60%,100% 84%,100% 100%)}
611
- .tpl-landscape .p4{bottom:-5%;height:24%;background:#356b5a;clip-path:polygon(0 100%,18% 62%,42% 86%,64% 66%,84% 90%,100% 74%,100% 100%)}
608
+ .tpl-landscape .p1{bottom:36%;height:32%;background:color-mix(in srgb,#a8c6b4 80%,var(--accent) 20%);clip-path:polygon(0 100%,8% 42%,18% 66%,30% 30%,44% 58%,56% 38%,68% 62%,80% 34%,100% 70%,100% 100%)}
609
+ .tpl-landscape .p2{bottom:23%;height:32%;background:color-mix(in srgb,#6ea08d 80%,var(--accent) 20%);clip-path:polygon(0 100%,12% 48%,26% 72%,40% 40%,58% 68%,72% 44%,86% 70%,100% 50%,100% 100%)}
610
+ .tpl-landscape .p3{bottom:9%;height:30%;background:color-mix(in srgb,#4a8a76 80%,var(--accent) 20%);clip-path:polygon(0 100%,10% 58%,30% 78%,50% 52%,70% 80%,88% 60%,100% 84%,100% 100%)}
611
+ .tpl-landscape .p4{bottom:-5%;height:24%;background:color-mix(in srgb,#356b5a 80%,var(--accent) 20%);clip-path:polygon(0 100%,18% 62%,42% 86%,64% 66%,84% 90%,100% 74%,100% 100%)}
612
612
  .tpl-landscape .content{position:relative;display:flex;flex-direction:column;justify-content:center;width:min(82%,1060px);height:100%;padding:7vh 0}
613
- .tpl-landscape .badge{align-self:flex-start;font-family:Georgia,'Songti SC','SimSun',serif;font-size:12px;letter-spacing:6px;color:#356b5a;border:1px solid #356b5a;padding:6px 14px;margin-bottom:3vh}
614
- .tpl-landscape h1{font-family:Georgia,'Songti SC','SimSun',serif;font-size:clamp(36px,4.8vw,62px);font-weight:700;color:#26352e;line-height:1.45;margin-bottom:2vh;max-width:82%}
615
- .tpl-landscape .quote{font-size:15px;color:#5c6b62;margin-bottom:4vh;max-width:64%;line-height:1.9}
613
+ .tpl-landscape .badge{align-self:flex-start;font-family:Georgia,'Songti SC','SimSun',serif;font-size:12px;letter-spacing:6px;color:color-mix(in srgb,#356b5a 80%,var(--accent) 20%);border:1px solid color-mix(in srgb,#356b5a 80%,var(--accent) 20%);padding:6px 14px;margin-bottom:3vh}
614
+ .tpl-landscape h1{font-family:Georgia,'Songti SC','SimSun',serif;font-size:clamp(36px,4.8vw,62px);font-weight:700;color:color-mix(in srgb,#26352e 80%,var(--text) 20%);line-height:1.45;margin-bottom:2vh;max-width:82%}
615
+ .tpl-landscape .quote{font-size:15px;color:color-mix(in srgb,#5c6b62 75%,var(--muted) 25%);margin-bottom:4vh;max-width:64%;line-height:1.9}
616
616
  .tpl-landscape ul.points{list-style:none;display:flex;flex-direction:column;gap:12px;margin-bottom:3.5vh}
617
- .tpl-landscape ul.points li{font-size:14px;color:#26352e;display:flex;gap:10px;align-items:baseline}
618
- .tpl-landscape ul.points .num{font-family:Georgia,'Songti SC','SimSun',serif;color:#b06a3b;font-weight:700;flex:none}
619
- .tpl-landscape footer{display:flex;justify-content:space-between;font-size:10px;letter-spacing:3px;color:#5c6b62}
617
+ .tpl-landscape ul.points li{font-size:14px;color:color-mix(in srgb,#26352e 80%,var(--text) 20%);display:flex;gap:10px;align-items:baseline}
618
+ .tpl-landscape ul.points .num{font-family:Georgia,'Songti SC','SimSun',serif;color:color-mix(in srgb,#b06a3b 80%,var(--accent) 20%);font-weight:700;flex:none}
619
+ .tpl-landscape footer{display:flex;justify-content:space-between;font-size:10px;letter-spacing:3px;color:color-mix(in srgb,#5c6b62 75%,var(--muted) 25%)}
620
620
 
621
621
  /* 32. watermark 水印公文:斜置大字背景水印 + 居中公文正文(颜色跟随主题令牌) */
622
622
  .tpl-watermark{display:flex;align-items:center;justify-content:center;width:100%;height:100%;position:relative;overflow:hidden}
@@ -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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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.12",
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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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 .45s cubic-bezier(.4,0,.2,1), 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>