@taloswork/ose-shared 0.1.2 → 0.1.3

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 (138) hide show
  1. package/package.json +3 -3
  2. package/skills/document/SKILL.md +29 -33
  3. package/skills/document/assets/fonts/Archivo-Regular.woff2 +0 -0
  4. package/skills/document/assets/fonts/Archivo-SemiBold.woff2 +0 -0
  5. package/skills/document/assets/fonts/BigShouldersDisplay-Bold.woff2 +0 -0
  6. package/skills/document/assets/fonts/BodoniModa-SemiBold.woff2 +0 -0
  7. package/skills/document/assets/fonts/CormorantGaramond-SemiBold.woff2 +0 -0
  8. package/skills/document/assets/fonts/Fraunces-SemiBold.woff2 +0 -0
  9. package/skills/document/assets/fonts/GochiHand-Regular.woff2 +0 -0
  10. package/skills/document/assets/fonts/IBMPlexSans-Regular.woff2 +0 -0
  11. package/skills/document/assets/fonts/IBMPlexSans-SemiBold.woff2 +0 -0
  12. package/skills/document/assets/fonts/Inter-Regular.woff2 +0 -0
  13. package/skills/document/assets/fonts/Jost-Regular.woff2 +0 -0
  14. package/skills/document/assets/fonts/Jost-SemiBold.woff2 +0 -0
  15. package/skills/document/assets/fonts/Karla-Regular.woff2 +0 -0
  16. package/skills/document/assets/fonts/Lora-Regular.woff2 +0 -0
  17. package/skills/document/assets/fonts/Manrope-Bold.woff2 +0 -0
  18. package/skills/document/assets/fonts/Manrope-Regular.woff2 +0 -0
  19. package/skills/document/assets/fonts/Marcellus-Regular.woff2 +0 -0
  20. package/skills/document/assets/fonts/PublicSans-Regular.woff2 +0 -0
  21. package/skills/document/assets/fonts/Sora-Regular.woff2 +0 -0
  22. package/skills/document/assets/fonts/Sora-SemiBold.woff2 +0 -0
  23. package/skills/document/assets/fonts/fonts.json +218 -0
  24. package/skills/document/bin/deck-build.cjs +273 -5
  25. package/skills/document/bin/doc-gen.cjs +108 -23
  26. package/skills/document/bin/html2pptx.cjs +280 -49
  27. package/skills/document/catalog.json +25 -0
  28. package/skills/document/deck-design.md +191 -0
  29. package/skills/document/layouts/README.md +32 -0
  30. package/skills/document/layouts/banner-columns.tpl +9 -9
  31. package/skills/document/layouts/bento.tpl +3 -3
  32. package/skills/document/layouts/big-stat.tpl +3 -3
  33. package/skills/document/layouts/blocks-2x2.tpl +12 -12
  34. package/skills/document/layouts/brand-values.tpl +5 -5
  35. package/skills/document/layouts/cards-3.tpl +3 -3
  36. package/skills/document/layouts/cards-grid.tpl +3 -3
  37. package/skills/document/layouts/chart-full.tpl +3 -3
  38. package/skills/document/layouts/chart-kpi.tpl +3 -3
  39. package/skills/document/layouts/color-palette.tpl +5 -5
  40. package/skills/document/layouts/comparison.tpl +3 -3
  41. package/skills/document/layouts/concept-hub.tpl +3 -3
  42. package/skills/document/layouts/cover-centered.tpl +1 -1
  43. package/skills/document/layouts/cover-image.tpl +1 -1
  44. package/skills/document/layouts/cover-minimal.tpl +3 -3
  45. package/skills/document/layouts/cover-statement.tpl +3 -3
  46. package/skills/document/layouts/cover.tpl +1 -1
  47. package/skills/document/layouts/data-table.tpl +3 -3
  48. package/skills/document/layouts/dos-donts.tpl +14 -14
  49. package/skills/document/layouts/editorial-panel.tpl +11 -11
  50. package/skills/document/layouts/ending-contact.tpl +1 -1
  51. package/skills/document/layouts/ending.tpl +1 -1
  52. package/skills/document/layouts/funnel.tpl +3 -3
  53. package/skills/document/layouts/gantt.tpl +3 -3
  54. package/skills/document/layouts/hero.tpl +3 -3
  55. package/skills/document/layouts/icon-row.tpl +3 -3
  56. package/skills/document/layouts/image-full.tpl +5 -5
  57. package/skills/document/layouts/image-grid.tpl +3 -3
  58. package/skills/document/layouts/image-left.tpl +3 -3
  59. package/skills/document/layouts/list.tpl +3 -3
  60. package/skills/document/layouts/logo-guidelines.tpl +8 -8
  61. package/skills/document/layouts/map-distribution.tpl +3 -3
  62. package/skills/document/layouts/map-quad.tpl +6 -6
  63. package/skills/document/layouts/matrix-2x2.tpl +3 -3
  64. package/skills/document/layouts/numbered-brief.tpl +12 -12
  65. package/skills/document/layouts/org-tree.tpl +3 -3
  66. package/skills/document/layouts/problem-solution-banner.tpl +7 -7
  67. package/skills/document/layouts/problem-solution.tpl +3 -3
  68. package/skills/document/layouts/pyramid.tpl +3 -3
  69. package/skills/document/layouts/quote.tpl +1 -1
  70. package/skills/document/layouts/radar.tpl +3 -3
  71. package/skills/document/layouts/ring-progress.tpl +3 -3
  72. package/skills/document/layouts/section-fullbleed.tpl +3 -3
  73. package/skills/document/layouts/section-image.tpl +1 -1
  74. package/skills/document/layouts/section-stat.tpl +1 -1
  75. package/skills/document/layouts/section.tpl +1 -1
  76. package/skills/document/layouts/slots.json +1 -1
  77. package/skills/document/layouts/split-two-col.tpl +3 -3
  78. package/skills/document/layouts/stats-chart.tpl +3 -3
  79. package/skills/document/layouts/steps-serpentine.tpl +11 -11
  80. package/skills/document/layouts/steps-vertical.tpl +3 -3
  81. package/skills/document/layouts/steps.tpl +3 -3
  82. package/skills/document/layouts/team-row.tpl +4 -4
  83. package/skills/document/layouts/three-kpi.tpl +3 -3
  84. package/skills/document/layouts/timeline.tpl +3 -3
  85. package/skills/document/layouts/title-meta.tpl +5 -5
  86. package/skills/document/layouts/title.tpl +2 -2
  87. package/skills/document/layouts/toc-agenda.tpl +3 -3
  88. package/skills/document/layouts/toc-editorial.tpl +15 -0
  89. package/skills/document/layouts/toc-panel.tpl +4 -4
  90. package/skills/document/layouts/toc.tpl +3 -3
  91. package/skills/document/layouts/transition.tpl +1 -1
  92. package/skills/document/layouts/two-kpi.tpl +3 -3
  93. package/skills/document/layouts/type-specimen.tpl +10 -10
  94. package/skills/document/layouts/versus.tpl +3 -3
  95. package/skills/document/motion/README.md +11 -0
  96. package/skills/document/packs/README.md +9 -0
  97. package/skills/document/styles/README.md +36 -15
  98. package/skills/document/styles/_contract-defaults.css +55 -0
  99. package/skills/document/styles/_samples/_groups/biz-premium.webp +0 -0
  100. package/skills/document/styles/_samples/_groups/creative.webp +0 -0
  101. package/skills/document/styles/_samples/_groups/editorial.webp +0 -0
  102. package/skills/document/styles/_samples/_groups/minimal.webp +0 -0
  103. package/skills/document/styles/_samples/_groups/natural.webp +0 -0
  104. package/skills/document/styles/_samples/_groups/tech-future.webp +0 -0
  105. package/skills/document/styles/_samples/anthropic.webp +0 -0
  106. package/skills/document/styles/_samples/apple.webp +0 -0
  107. package/skills/document/styles/_samples/black-gold.webp +0 -0
  108. package/skills/document/styles/_samples/branding.webp +0 -0
  109. package/skills/document/styles/_samples/cinereel.webp +0 -0
  110. package/skills/document/styles/_samples/cool.webp +0 -0
  111. package/skills/document/styles/_samples/hand-drawn.webp +0 -0
  112. package/skills/document/styles/_samples/ivory-gold.webp +0 -0
  113. package/skills/document/styles/_samples/magazine-ink.webp +0 -0
  114. package/skills/document/styles/_samples/mckinsey.webp +0 -0
  115. package/skills/document/styles/_samples/mono.webp +0 -0
  116. package/skills/document/styles/_samples/olive-gold.webp +0 -0
  117. package/skills/document/styles/_samples/swiss-grid.webp +0 -0
  118. package/skills/document/styles/anthropic/backdrop.html +4 -0
  119. package/skills/document/styles/anthropic/skin.css +15 -8
  120. package/skills/document/styles/apple/backdrop.html +4 -1
  121. package/skills/document/styles/apple/skin.css +5 -2
  122. package/skills/document/styles/black-gold/backdrop.html +3 -0
  123. package/skills/document/styles/black-gold/skin.css +15 -8
  124. package/skills/document/styles/branding/backdrop.html +4 -0
  125. package/skills/document/styles/branding/skin.css +14 -7
  126. package/skills/document/styles/cinereel/skin.css +28 -10
  127. package/skills/document/styles/cool/backdrop.html +3 -0
  128. package/skills/document/styles/cool/skin.css +5 -2
  129. package/skills/document/styles/hand-drawn/skin.css +14 -6
  130. package/skills/document/styles/ivory-gold/skin.css +19 -6
  131. package/skills/document/styles/magazine-ink/skin.css +6 -1
  132. package/skills/document/styles/mckinsey/backdrop.html +5 -0
  133. package/skills/document/styles/mckinsey/skin.css +5 -2
  134. package/skills/document/styles/mono/backdrop.html +6 -0
  135. package/skills/document/styles/mono/skin.css +5 -2
  136. package/skills/document/styles/olive-gold/backdrop.html +5 -0
  137. package/skills/document/styles/olive-gold/skin.css +15 -8
  138. package/skills/document/styles/swiss-grid/skin.css +6 -1
@@ -1,4 +1,4 @@
1
1
  <!-- layouts/versus — structure-only variant (paint via skin). reuses class contract, no skin change. -->
2
- <section class="slide" data-layout="versus" style="position:relative;width:1280px;height:720px;overflow:hidden"><div class="slide-backdrop"></div><div class="eyebrow-row" style="position:absolute;left:96px;top:132px;display:flex;align-items:center;gap:14px"><span class="accent-bar" style="width:30px;height:1px;display:inline-block"></span><span class="eyebrow" style="font-size:13px;letter-spacing:.28em">{{eyebrow|BEFORE / AFTER}}</span></div><h2 class="deck-title" style="position:absolute;left:92px;top:158px;font-size:48px;letter-spacing:-.4px">{{title|改造前后对比}}</h2>
3
- <div class="card" style="position:absolute;left:96px;top:300px;width:472px;height:300px;padding:34px;display:flex;flex-direction:column;justify-content:center"><div class="card-title" style="font-size:20px;font-weight:700">{{before_title|改造前}}</div><div class="kpi-num" style="font-size:72px;font-weight:800;line-height:1.1;margin-top:10px">{{before_num|T+1}}</div><p class="card-body" style="font-size:15px;margin-top:8px">{{before_body|报表时效,人工汇总。}}</p></div><div class="step-circle" style="position:absolute;left:50%;top:410px;transform:translateX(-50%);width:88px;height:88px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:24px;font-weight:700;z-index:2">VS</div><div class="card cmp-col--rec" style="position:absolute;right:96px;top:300px;width:472px;height:300px;padding:34px;display:flex;flex-direction:column;justify-content:center"><div class="card-title" style="font-size:20px;font-weight:700">{{after_title|改造后}}</div><div class="kpi-num" style="font-size:72px;font-weight:800;line-height:1.1;margin-top:10px">{{after_num|分钟级}}</div><p class="card-body" style="font-size:15px;margin-top:8px">{{after_body|实时计算,自动刷新。}}</p></div>
4
- <div class="rule rule-foot" style="position:absolute;left:96px;right:96px;bottom:40px;height:1px"></div><div class="deck-footer" style="position:absolute;left:96px;bottom:17px;font-size:12px;letter-spacing:.1em">{{footer|报告标题 / 章节}}</div><div class="deck-pageno" style="position:absolute;right:96px;bottom:17px;font-size:12px">{{pageno|01}}</div></section>
2
+ <section class="slide" data-layout="versus" style="position:relative;width:1280px;height:720px;overflow:hidden"><div class="slide-backdrop"></div><div class="eyebrow-row" style="position:absolute;left:calc(96px * var(--space-scale,1));top:132px;display:flex;align-items:center;gap:14px"><span class="accent-bar" style="width:30px;height:1px;display:inline-block"></span><span class="eyebrow" style="font-size:calc(13px * var(--type-scale,1));letter-spacing:.28em">{{eyebrow|BEFORE / AFTER}}</span></div><h2 class="deck-title" style="position:absolute;left:calc(92px * var(--space-scale,1));top:158px;font-size:calc(48px * var(--type-scale,1));letter-spacing:-.4px">{{title|改造前后对比}}</h2>
3
+ <div class="card" style="position:absolute;left:calc(96px * var(--space-scale,1));top:300px;width:472px;height:300px;padding:34px;display:flex;flex-direction:column;justify-content:center"><div class="card-title" style="font-size:calc(20px * var(--type-scale,1));font-weight:700">{{before_title|改造前}}</div><div class="kpi-num" style="font-size:calc(72px * var(--type-scale,1));font-weight:800;line-height:1.1;margin-top:10px">{{before_num|T+1}}</div><p class="card-body" style="font-size:calc(15px * var(--type-scale,1));margin-top:8px">{{before_body|报表时效,人工汇总。}}</p></div><div class="step-circle" style="position:absolute;left:50%;top:410px;transform:translateX(-50%);width:88px;height:88px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:calc(24px * var(--type-scale,1));font-weight:700;z-index:2">VS</div><div class="card cmp-col--rec" style="position:absolute;right:calc(96px * var(--space-scale,1));top:300px;width:472px;height:300px;padding:34px;display:flex;flex-direction:column;justify-content:center"><div class="card-title" style="font-size:calc(20px * var(--type-scale,1));font-weight:700">{{after_title|改造后}}</div><div class="kpi-num" style="font-size:calc(72px * var(--type-scale,1));font-weight:800;line-height:1.1;margin-top:10px">{{after_num|分钟级}}</div><p class="card-body" style="font-size:calc(15px * var(--type-scale,1));margin-top:8px">{{after_body|实时计算,自动刷新。}}</p></div>
4
+ <div class="rule rule-foot" style="position:absolute;left:calc(96px * var(--space-scale,1));right:calc(96px * var(--space-scale,1));bottom:40px;height:1px"></div><div class="deck-footer" style="position:absolute;left:calc(96px * var(--space-scale,1));bottom:17px;font-size:calc(12px * var(--type-scale,1));letter-spacing:.1em">{{footer|报告标题 / 章节}}</div><div class="deck-pageno" style="position:absolute;right:calc(96px * var(--space-scale,1));bottom:17px;font-size:calc(12px * var(--type-scale,1))">{{pageno|01}}</div></section>
@@ -0,0 +1,11 @@
1
+ # motion —— 族的动画预设
2
+
3
+ 每族一份 `<id>.json`:`transition`(页面切换)+ `entrance`(按页面 role 分组的入场序列)。
4
+ `deck-build` 填槽时按 role 注入 `data-anim*` / `data-transition*`;deck.html 里已有的
5
+ 同名属性优先,不被覆盖。
6
+
7
+ **motion 是可选的** —— 没有预设文件的族不注入任何动画,与 `data-anim` 默认全关一致。
8
+ 现有 13 个 skin 在 P0 不配 motion(保证行为零变化),P2 补齐。
9
+
10
+ 效果集必须与 `packages/core/src/document/pptx-anim.ts` 一致:
11
+ fade · fade-up · float · appear · fly-up · fly-down · fly-left · fly-right
@@ -0,0 +1,9 @@
1
+ # packs —— 模板包(pack)
2
+
3
+ pack = 实现完整 class 契约的 `pack.css` **加上**一组包专属签名版式。
4
+
5
+ 因为 `pack.css` 实现了契约,共享 `layouts/` 的全部结构版式在包内天然可用;
6
+ 包自带的 `layouts/<id>.tpl` 与共享同名时**包内优先**(同名遮蔽)。
7
+
8
+ 目录结构见 `docs/superpowers/specs/2026-09-01-ppt-tpl-prod-design.md` §5.3。
9
+ P0 不产出任何 pack;首批 2 个包在 P1 落地。
@@ -1,9 +1,14 @@
1
1
  # Skin catalog (styles) — pick ONE per deck
2
2
 
3
+ **族名单的真源是 `catalog.json`**(groups + entries),本文件是人读的说明;新增族
4
+ 两边都要更新。`verify-catalog.mjs` **不读本文件** —— 它比对的是 `catalog.json`
5
+ 与磁盘(样图/CSS/motion 是否存在、`styles/<id>` 目录有没有漏登记、oneliner 有没有
6
+ 超长),所以"目录建了但没登记"抓得住,"登记了但本 README 忘了写"抓不住,只能靠人。
7
+
3
8
  A **skin** = the paint (colors + fonts + design tokens) applied to structure-only
4
9
  `layouts/*.tpl` at render time via `--style <name>`. Pick ONE skin for the whole
5
10
  deck by vibe/scenario; never mix. Each skin fully defines the class contract, so any
6
- of the 54 layouts renders in any skin.
11
+ layout renders in any skin — see `layouts/README.md` for the current count and index.
7
12
 
8
13
  `html2pptx deck.html out.pptx --style <name> [--backdrop <variant>]`
9
14
 
@@ -11,17 +16,17 @@ of the 54 layouts renders in any skin.
11
16
 
12
17
  | skin | light/dark | 适用场景 | signature |
13
18
  |---|---|---|---|
14
- | **cool** ⭐默认 | dark | 科技 · 发布 · pitch · 主题演讲 | 深蓝 + 蓝青辉光 + 玻璃卡 + 4色 ramp |
15
- | **black-gold** | dark | 金融 · 年报 · 路演 · 奢侈品 · 高端商务 | 纯黑 + 金辉光 + 衬线;金曲线仅封面 |
16
- | **apple** | dark | 产品发布 · 主题演讲 · 极简演示 | 纯黑舞台 + 超大留白 + 单色白层级 |
17
- | **olive-gold** | dark | 高端 · 证书 · 招商 · 品牌 | 深橄榄金 + 亮金 + 奶白粗体 |
18
- | **mckinsey** | light | 咨询 · 战略汇报 · 评审 · 董事会 | 白底藏青 + 克制蓝 + **蓝方块序号卡** |
19
- | **anthropic** | light | AI/产品 · 研究分享 · 人文品牌 | 奶油 + 赤陶珊瑚 + Georgia 衬线 |
20
- | **branding** | light | 品牌手册 · 可持续 · 美妆 · 零售 · 极简 | 暖米底 + 鼠尾草/薄荷绿 + 优雅衬线标题 |
21
- | **hand-drawn** | light | 创意 · 头脑风暴 · 教学 · 工作坊 | 纸感 + 马克笔色 + **手绘歪框卡** |
22
- | **mono** | light | 极简 · 高端 · 设计 · 单色报告 | 纯白 + 黑灰明度层级 + 细线 + 大留白 |
23
- | **ivory-gold** | light | 奢华极简 · 品牌手册 · 路演 · 高端零售 | 奶油底 + 青铜金 Anton 粗体大写标题(标题=accent)+ **黑色反色区块**(`.slide-inverse`) |
24
- | **cinereel** | dark | 影视 · 创意作品集 · 音乐/传媒行业 · 幕后花絮 | 黑底/照片底 + 白色 Anton 粗体大写(无色相)+ **常驻胶片取景框**(顶/底黑遮幅条,每页恒定)+ 浅灰面板反色(`.slide-inverse`) |
19
+ | **cool** ⭐默认 | dark | 科技 · 发布 · pitch · 主题演讲 | 深蓝 + 蓝青辉光 + 玻璃卡 + **Sora** 几何无衬线 + **右上仪表刻度尺** |
20
+ | **black-gold** | dark | 金融 · 年报 · 路演 · 奢侈品 · 高端商务 | 纯黑 + 金辉光 + **Bodoni Moda** 高反差 didone + **双线证书内框** |
21
+ | **apple** | dark | 产品发布 · 主题演讲 · 极简演示 | 纯黑舞台 + 最大留白(`--space-scale:1.22`)+ **Manrope** + **底部地平线与反射** |
22
+ | **olive-gold** | dark | 高端 · 证书 · 招商 · 品牌 | 深橄榄金 + 亮金 + **Marcellus** 古典罗马体 + **四角雕版角标** |
23
+ | **mckinsey** | light | 咨询 · 战略汇报 · 评审 · 董事会 | 白底藏青 + **IBM Plex Sans** + 最高信息密度(`--space-scale:0.86`)+ **顶部实心页眉条与档案标签** |
24
+ | **anthropic** | light | AI/产品 · 研究分享 · 人文品牌 | 奶油 + 赤陶珊瑚 + **Fraunces** 有机衬线 + **右侧边注竖线** |
25
+ | **branding** | light | 品牌手册 · 可持续 · 美妆 · 零售 · 极简 | 暖米底 + 鼠尾草绿 + **Cormorant Garamond** + **左侧装订书脊带** |
26
+ | **hand-drawn** | light | 创意 · 头脑风暴 · 教学 · 工作坊 | 纸感 + 马克笔色 + **Gochi Hand** 手写体(已 bake)+ **手绘歪框卡** |
27
+ | **mono** | light | 极简 · 高端 · 设计 · 单色报告 | 纯白 + 黑灰明度层级 + **Archivo** + **印刷裁切框与四角对位十字** |
28
+ | **ivory-gold** | light | 奢华极简 · 品牌手册 · 路演 · 高端零售 | 奶油底 + 青铜金 **Anton** 粗体大写标题(标题=accent)+ **黑色反色区块**(`.slide-inverse`) |
29
+ | **cinereel** | dark | 影视 · 创意作品集 · 音乐/传媒行业 · 幕后花絮 | 黑底/照片底 + 白色超浓缩粗体大写(Big Shoulders Display,无色相)+ 几何无衬线正文(Jost)+ **常驻胶片取景框**(顶/底黑遮幅条,每页恒定)+ 浅灰面板反色(`.slide-inverse`) |
25
30
  | **magazine-ink** | light | 人文分享 · 行业观察 · 商业发布 · 杂志感演讲 | 瓷白底 + 靛蓝 Noto Serif SC 衬线大标题 + 无衬线正文 + 等宽元数据 + 无阴影无卡片盒(纯发丝线分隔)+ 巨幅淡墨水印章节号 |
26
31
  | **swiss-grid** | light | 科技产品 · 数据汇报 · 设计/工程分享 · 年度总结 | 全无衬线 + 克莱因蓝单色高亮 + 极致字号反差(标题细/KPI 粗)+ 零阴影零圆角零渐变 + 点阵网格底纹 |
27
32
 
@@ -39,6 +44,22 @@ padding of your own:
39
44
  `cinereel` → **黑白胶片 · 影视创意** · `magazine-ink` → **瓷白靛蓝 · 杂志人文** ·
40
45
  `swiss-grid` → **克莱因蓝白 · 瑞士国际**
41
46
 
47
+ ## 皮肤靠什么区分(不只是配色)
48
+
49
+ 三条正交的轴。只改配色的皮肤会和别的皮肤长得一样 —— 加皮肤时三条都要想过:
50
+
51
+ 1. **字体** — 每个皮肤的 `--font-head`/`--font-body` 组合都是唯一的,并且 CJK 首选也
52
+ 分了宋体系/黑体系/楷体系(纯拉丁字体对中文 deck 不起作用,只有 CJK 栈能拉开中文观感)。
53
+ 非系统字体必须在 `assets/fonts/fonts.json` 里登记;**衬线/展示字体还必须 bake**,否则
54
+ 只在预览里生效、进不了交付的 pptx(见 deck-design.md § Fonts)。
55
+ 2. **结构签名** — `backdrop.html` 里一个有边界的标记:页眉条、裁切框、书脊带、四角角标、
56
+ 刻度尺、地平线。这是 layout 之外唯一能引入**结构**差异的地方,也是同质化最容易发生的
57
+ 环节 —— 弥散的渐变光晕换到别的皮肤上没人看得出,不算签名。
58
+ 3. **排版节奏** — `--space-scale` / `--type-scale`。`layouts/*.tpl` 的字号与页边距都写成
59
+ `calc(N * var(--…-scale,1))`,所以皮肤可以在不碰任何 layout 的前提下定义自己的疏密。
60
+ 当前跨度:`mckinsey` 0.86(董事会材料的信息密度)→ `apple` 1.22(发布会舞台的留白)。
61
+ **改动后必须跑 deck-qa** —— 缩放会重排文字,过大就 off-canvas。
62
+
42
63
  ## Backdrop variants
43
64
 
44
65
  Every skin ships its own signature `styles/<skin>/backdrop.html`. Beyond that,
@@ -81,9 +102,9 @@ generations of the same skin don't all look identical. Pass `--backdrop
81
102
 
82
103
  Add a skin = **one `styles/<name>/skin.css`** defining the full class contract
83
104
  (+ optional `backdrop.html`). The `deck-layouts` guard checks every skin paints the
84
- contract. All 54 layouts get the new skin for free. Build a skin from a reference
85
- image: sample its palette → fill the token/class contract (mirror an existing skin
86
- of the same light/dark polarity).
105
+ contract. Every layout in `layouts/README.md` gets the new skin for free. Build a
106
+ skin from a reference image: sample its palette → fill the token/class contract
107
+ (mirror an existing skin of the same light/dark polarity).
87
108
 
88
109
  Chart color: `stats-chart` fills its bars from **`--chart-1`** (substituted into the
89
110
  `__CHART1__` placeholder), NOT the raw `--accent` — accent is tuned as a text/hairline
@@ -0,0 +1,55 @@
1
+ /* styles/_contract-defaults.css — 扩展契约的中性兜底实现。
2
+ 注入顺序:SKELETON_CSS → 本文件 → styles/<id>/skin.css | packs/<id>/pack.css
3
+ 皮肤/包可以覆写其中任意一条;不覆写就拿到这里的中性版本。
4
+ 目的:扩展契约从"改 N 个皮肤"降为"改这一个文件",让 promote-layout 反向通道跑得起来。
5
+ 规则:只能引用已有 token(--accent/--title/--body/--muted/--hair/--c1..--c4/--card-radius),
6
+ 一个裸十六进制都不许有 —— deck-layouts.test.ts 会断言。
7
+
8
+ **加一条声明之前必读(属性粒度,不是选择器粒度)**:
9
+ "所有皮肤都定义了这个选择器,所以兜底是惰性的" —— 这个推理只在选择器粒度成立。
10
+ CSS 是逐**属性**层叠的:皮肤在 `.panel` 上只写了 `background`,兜底里的 `border`
11
+ 照样会落到它头上。而且皮肤常常把颜色写在更具体的作用域里(比如
12
+ `.steps .step:nth-child(n) .step-circle`),那条规则在没有 `.steps` 祖先的版式里
13
+ (icon-row)根本不匹配,兜底的 `color` 就会赢。
14
+ 所以本文件只保留"没有任何现役皮肤会被它改变观感"的属性。逐属性实测(每条声明单独
15
+ 注入,与不注入逐字节比对 PNG)后删掉的四条,括号内是实测受影响的组合数:
16
+ .dt-head 的 font-family(7/13 —— anthropic/black-gold/branding/cinereel/hand-drawn/
17
+ ivory-gold/olive-gold 的 data-table 表头字体会从正文体翻成展示体:cinereel
18
+ Jost→Big Shoulders Display、anthropic 无衬线→Fraunces 衬线、hand-drawn
19
+ Comic Sans→Gochi Hand,肉眼可辨。只有 magazine-ink 自己写了 font-family,
20
+ 其余五个族的正文体与展示体恰好同族才没变);
21
+ .step-circle 的 color(39/78 —— 皮肤只在 `.steps .step:nth-child(n) .step-circle`
22
+ 作用域里定色,icon-row/steps-vertical/versus 没有 .steps 祖先,13 个族全中);
23
+ .panel 的 border(21/26 —— 多数皮肤只写 background/box-shadow);
24
+ 同一条规则里的 border-radius 实测 0/26,但一个既无边框又无底色的盒子谈不上圆角,
25
+ 所以一并去掉,不留没有意义的声明;
26
+ .cmp-col--rec 的 box-shadow(4/39 —— cinereel 与 magazine-ink 没写)。
27
+ 保留下来的 `.cmp-col--rec{border}` 实测 0/39:没写 border 的 swiss-grid 在自己的
28
+ `.cmp-col` 规则里定了边(同特异性、位置在后),仍然赢过兜底。
29
+ 改完必须重跑 `node scripts/deck-fidelity.mjs`(它现在会注入本文件,此前不注入,
30
+ 所以这个文件曾经完全在像素闸门的视野之外),并按
31
+ `.claude/skills/ppt-tpl-prod/SKILL.md`"改 _contract-defaults.css"一节做
32
+ 注入/不注入的对照渲染 —— deck-fidelity 的 32x18 签名对这类细微改动不够敏感。 */
33
+
34
+ /* compare */
35
+ .cmp-col--rec{border:1px solid var(--accent)}
36
+ /* process */
37
+ .step-circle{background:transparent;border:1px solid var(--hair);font-family:var(--font-head)}
38
+ /* toc */
39
+ .toc-num{color:var(--muted);font-family:var(--font-head)}
40
+ /* surfaces */
41
+ .surface{background:transparent;border:1px solid var(--hair);border-radius:var(--card-radius,4px)}
42
+ .panel{background:transparent}
43
+ /* timeline */
44
+ .tl-date{color:var(--title);font-family:var(--font-head)}
45
+ /* concept hub */
46
+ .hub-center{background:transparent;border:1px solid var(--accent);color:var(--title)}
47
+ /* image overlays — 压在图/scrim 上,与皮肤明暗无关 */
48
+ .scrim{background:linear-gradient(180deg,rgba(0,0,0,0) 0%,rgba(0,0,0,.55) 100%)}
49
+ .overlay-title{color:rgba(255,255,255,1)}
50
+ /* data table */
51
+ .dt-head{color:var(--title);border-bottom:1px solid var(--hair)}
52
+ /* figures */
53
+ .gantt-bar{background:var(--c1)}
54
+ .map-pin{background:var(--accent)}
55
+ .ring-fill{stroke:var(--accent)}
@@ -1 +1,5 @@
1
1
  <div style="position:absolute;inset:0;background:radial-gradient(46% 60% at 88% 8%,__ACCENT__24,transparent 60%),radial-gradient(40% 52% at 8% 96%,__ACCENT__14,transparent 64%)"></div><div class="bd-arc" style="position:absolute;left:0;right:0;height:120px;top:var(--bd-arc-y,540px);pointer-events:none"><svg width="100%" height="100%" viewBox="0 0 1280 120" preserveAspectRatio="none"><defs><linearGradient id="arc" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".12"/><stop offset=".5" stop-color="__ACCENT__" stop-opacity=".34"/><stop offset="1" stop-color="__ACCENT__" stop-opacity=".12"/></linearGradient><filter id="arcb"><feGaussianBlur stdDeviation="1.4"/></filter></defs><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width="1.6" filter="url(#arcb)"/><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width=".7"/></svg></div>
2
+ <!-- signature: the margin rule — a scholar's side-note line with an accent tick. -->
3
+ <div style="position:absolute;right:58px;top:104px;bottom:104px;width:1px;background:var(--hair);pointer-events:none"></div>
4
+ <div style="position:absolute;right:46px;top:104px;width:26px;height:2px;background:var(--accent);pointer-events:none"></div>
5
+ <div style="position:absolute;right:46px;bottom:104px;width:26px;height:2px;background:var(--hair);pointer-events:none"></div>
@@ -1,11 +1,14 @@
1
1
  /* styles/anthropic — 温暖人文:奶油底 + 赤陶(clay)珊瑚 + Georgia 衬线标题 + 土系 ramp + 软卡。
2
2
  皮肤层:定义 layouts/*.tpl 用到的全部语义 class。换 skin 只换这一个文件。 */
3
3
  :root{
4
+ /* 排版节奏 — layouts 的字号与页边距都写成 calc(N * var(--…-scale,1)),
5
+ 所以皮肤可以在不碰任何 layout 的前提下定义自己的疏密。研究分享:呼吸感。 */
6
+ --space-scale:1.05; --type-scale:1.0;
4
7
  --accent:#CC785C; --c1:#CC785C; --c2:#7C9082; --c3:#BD5D3E; --c4:#B7A99A; --chart-1:#C4785C;
5
8
  --title:#191919; --body:#514B3F; --muted:#6B6558; --foot:#9A917F;
6
9
  --hair:#DDD6C7; --card-radius:12px;
7
- --font-head:Georgia,'Songti SC','Times New Roman',serif;
8
- --font-body:'Helvetica Neue','PingFang SC','Hiragino Sans GB',sans-serif;
10
+ --font-head:'Fraunces','Iowan Old Style','Songti SC','Noto Serif SC','Source Han Serif SC',serif;
11
+ --font-body:'Public Sans','PingFang SC','Noto Sans SC','Hiragino Sans GB',sans-serif;
9
12
  /* theme-compat vars: SKELETON_CSS's section.slide h1/h2/h3 + section.slide out-specify
10
13
  the skin's .cover-title/.slide, so titles/body fall back to these — define them so
11
14
  --style alone fully colors the deck. */
@@ -18,7 +21,11 @@
18
21
  .deck-header,.deck-footer,.deck-pageno{color:var(--muted)}
19
22
  .rule{background:var(--hair)} .rule-foot{background:#E7E1D3}
20
23
  .eyebrow{color:var(--accent);font-weight:700} .accent-bar{background:var(--accent);border-radius:1px}
21
- .deck-title,.cover-title,.section-title,.ending-title{color:var(--title);font-family:var(--font-head);font-weight:700}
24
+ /* This skin's identity IS this face — a didone/garalde/roman falling back to the
25
+ system serif reads as a different deck entirely. Bake the display classes so the
26
+ audience sees it; body copy stays native (editable/searchable). See
27
+ deck-design.md § Fonts for why bundling alone doesn't reach the native text layer. */
28
+ .deck-title,.cover-title,.section-title,.ending-title{color:var(--title);font-family:var(--font-head);font-weight:700;--talos-bake:1}
22
29
  .cover-sub,.ending-sub,.section-desc{color:var(--muted)}
23
30
  /* soft warm card + earthy ramp */
24
31
  .card{border-radius:var(--card-radius);background:#FAF8F2;border:1px solid var(--hair);box-shadow:0 10px 28px rgba(80,55,30,.07);overflow:hidden}
@@ -35,19 +42,19 @@
35
42
  .cmp-col--rec .cmp-v{color:var(--accent)}
36
43
  .cmp-badge{background:var(--accent);color:#FBF6EF;font-family:var(--font-body)}
37
44
  /* kpi / big-stat */
38
- .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head)} .kpi-label{color:var(--muted)}
45
+ .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head);--talos-bake:1} .kpi-label{color:var(--muted)}
39
46
  .stat-unit{color:var(--accent)} .stat-lead{color:var(--title)} .stat-note{color:var(--body)}
40
47
  /* steps */
41
48
  .step-line{background:var(--hair)}
42
- .step-circle{background:#F6F1E7;border:1px solid var(--hair);box-shadow:0 10px 24px rgba(80,55,30,.06);font-family:var(--font-head)}
49
+ .step-circle{background:#F6F1E7;border:1px solid var(--hair);box-shadow:0 10px 24px rgba(80,55,30,.06);font-family:var(--font-head);--talos-bake:1}
43
50
  .steps .step:nth-child(4n+1) .step-circle{color:var(--c1)} .steps .step:nth-child(4n+2) .step-circle{color:var(--c2)} .steps .step:nth-child(4n+3) .step-circle{color:var(--c3)} .steps .step:nth-child(4n+4) .step-circle{color:var(--c4)}
44
51
  .step-tag,.step-body{color:var(--muted)} .step-title{color:var(--title)}
45
52
  /* toc */
46
53
  .toc-item{border-top:1px solid var(--hair)} .toc-grid .toc-item:nth-child(1){border-top-color:var(--accent)} .toc-grid .toc-item:nth-child(2){border-top-color:var(--c2)}
47
- .toc-grid .toc-item:nth-child(1) .toc-num{color:var(--accent)} .toc-grid .toc-item:nth-child(2) .toc-num{color:var(--c2)} .toc-num{color:var(--foot);font-family:var(--font-head)}
54
+ .toc-grid .toc-item:nth-child(1) .toc-num{color:var(--accent)} .toc-grid .toc-item:nth-child(2) .toc-num{color:var(--c2)} .toc-num{color:var(--foot);font-family:var(--font-head);--talos-bake:1}
48
55
  .toc-title{color:var(--title)} .toc-desc{color:var(--muted)}
49
56
  /* section ghost + surface */
50
- .section-ghost{color:transparent;-webkit-text-stroke:1px rgba(204,120,92,.20);font-family:var(--font-head)}
57
+ .section-ghost{color:transparent;-webkit-text-stroke:1px rgba(204,120,92,.20);font-family:var(--font-head);--talos-bake:1}
51
58
  .surface{background:#F6F1E7;border:1px solid var(--hair);border-radius:12px} .surface-label{color:var(--muted)}
52
59
  .ending-contact{color:var(--muted)}
53
60
 
@@ -56,7 +63,7 @@
56
63
  .overlay-sub{color:rgba(255,255,255,.82)}
57
64
  /* batch-5 layouts: timeline / concept-hub / cover-image */
58
65
  .tl-dot{background:var(--accent);border-radius:50%}
59
- .tl-date{color:var(--accent);font-family:var(--font-head)}
66
+ .tl-date{color:var(--accent);font-family:var(--font-head);--talos-bake:1}
60
67
  .tl-title{color:var(--title)} .tl-desc{color:var(--muted)}
61
68
  .hub-center{border-radius:50%;border:2px solid var(--accent)}
62
69
  .hub-title{color:var(--accent)}
@@ -1 +1,4 @@
1
- <div style="position:absolute;inset:0;background:radial-gradient(70% 50% at 50% -12%,rgba(255,255,255,.07),transparent 55%),radial-gradient(130% 90% at 50% 128%,rgba(0,0,0,.42),transparent 48%)"></div><div class="bd-arc" style="position:absolute;left:0;right:0;height:120px;top:var(--bd-arc-y,540px);pointer-events:none"><svg width="100%" height="100%" viewBox="0 0 1280 120" preserveAspectRatio="none"><defs><linearGradient id="arc" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".12"/><stop offset=".5" stop-color="__ACCENT__" stop-opacity=".34"/><stop offset="1" stop-color="__ACCENT__" stop-opacity=".12"/></linearGradient><filter id="arcb"><feGaussianBlur stdDeviation="1.4"/></filter></defs><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width="1.6" filter="url(#arcb)"/><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width=".7"/></svg></div><svg style="position:absolute;inset:0;width:100%;height:100%;opacity:.02;mix-blend-mode:screen;pointer-events:none"><filter id="bdap"><feTurbulence type="fractalNoise" baseFrequency=".9" numOctaves="2" stitchTiles="stitch"/></filter><rect width="100%" height="100%" filter="url(#bdap)"/></svg>
1
+ <div style="position:absolute;inset:0;background:radial-gradient(70% 50% at 50% -12%,rgba(255,255,255,.07),transparent 55%),radial-gradient(130% 90% at 50% 128%,rgba(0,0,0,.42),transparent 48%)"></div><div class="bd-arc" style="position:absolute;left:0;right:0;height:120px;top:var(--bd-arc-y,540px);pointer-events:none"><svg width="100%" height="100%" viewBox="0 0 1280 120" preserveAspectRatio="none"><defs><linearGradient id="arc" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".12"/><stop offset=".5" stop-color="__ACCENT__" stop-opacity=".34"/><stop offset="1" stop-color="__ACCENT__" stop-opacity=".12"/></linearGradient><filter id="arcb"><feGaussianBlur stdDeviation="1.4"/></filter></defs><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width="1.6" filter="url(#arcb)"/><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width=".7"/></svg></div><svg style="position:absolute;inset:0;width:100%;height:100%;opacity:.02;mix-blend-mode:screen;pointer-events:none"><filter id="bdap"><feTurbulence type="fractalNoise" baseFrequency=".9" numOctaves="2" stitchTiles="stitch"/></filter><rect width="100%" height="100%" filter="url(#bdap)"/></svg>
2
+ <!-- signature: the keynote stage — one hairline horizon with a faint floor reflection. -->
3
+ <div style="position:absolute;left:0;right:0;bottom:96px;height:112px;pointer-events:none;background:linear-gradient(180deg,transparent,color-mix(in srgb,var(--accent) 14%,transparent))"></div>
4
+ <div style="position:absolute;left:0;right:0;bottom:96px;height:1px;pointer-events:none;background:linear-gradient(90deg,transparent,var(--accent),transparent);opacity:.55"></div>
@@ -1,11 +1,14 @@
1
1
  /* styles/apple — keynote 舞台:纯黑底 + 超大留白 + 近白单色层级(无彩色 accent,靠字号/明度分层)。
2
2
  皮肤层:定义 layouts/*.tpl 用到的全部语义 class。换 skin 只换这一个文件。 */
3
3
  :root{
4
+ /* 排版节奏 — layouts 的字号与页边距都写成 calc(N * var(--…-scale,1)),
5
+ 所以皮肤可以在不碰任何 layout 的前提下定义自己的疏密。发布会舞台:超大留白,标题略放。 */
6
+ --space-scale:1.22; --type-scale:1.04;
4
7
  --accent:#F5F5F7; --c1:#F5F5F7; --c2:#C7C7CC; --c3:#98989D; --c4:#636366; --chart-1:#6E6E73;
5
8
  --title:#F5F5F7; --body:#A1A1A6; --muted:#86868B; --foot:#636366;
6
9
  --hair:rgba(255,255,255,.09); --card-radius:20px;
7
- --font-head:'Helvetica Neue','SF Pro Display','PingFang SC','Hiragino Sans GB',sans-serif;
8
- --font-body:'Helvetica Neue','SF Pro Text','PingFang SC',sans-serif;
10
+ --font-head:'Manrope','PingFang SC','Noto Sans SC','Hiragino Sans GB',sans-serif;
11
+ --font-body:'Manrope','PingFang SC','Noto Sans SC','Hiragino Sans GB',sans-serif;
9
12
  /* theme-compat vars: SKELETON_CSS targets section.slide h1/h2/h3 + section.slide
10
13
  (specificity 0,1,2 / 0,1,1) which out-specify the skin's .cover-title/.slide, so
11
14
  titles/body fall back to these. Define them so --style alone fully colors the deck. */
@@ -1 +1,4 @@
1
1
  <div class="bd-arc" style="position:absolute;left:0;right:0;height:120px;top:var(--bd-arc-y,540px);pointer-events:none"><svg width="100%" height="100%" viewBox="0 0 1280 120" preserveAspectRatio="none"><defs><linearGradient id="arc" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="__ACCENT__" stop-opacity=".12"/><stop offset=".5" stop-color="__ACCENT__" stop-opacity=".34"/><stop offset="1" stop-color="__ACCENT__" stop-opacity=".12"/></linearGradient><filter id="arcb"><feGaussianBlur stdDeviation="1.4"/></filter></defs><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width="1.6" filter="url(#arcb)"/><path d="M-40 100 C 360 22,920 22,1320 100" fill="none" stroke="url(#arc)" stroke-width=".7"/></svg></div><svg style="position:absolute;inset:0;width:100%;height:100%;opacity:.045;mix-blend-mode:overlay;pointer-events:none"><filter id="bgn"><feTurbulence type="fractalNoise" baseFrequency=".8" numOctaves="2" stitchTiles="stitch"/></filter><rect width="100%" height="100%" filter="url(#bgn)"/></svg>
2
+ <!-- signature: the certificate — a double rule inside the trim, bond-paper convention. -->
3
+ <div style="position:absolute;inset:26px;border:1px solid var(--accent);opacity:.38;pointer-events:none"></div>
4
+ <div style="position:absolute;inset:33px;border:1px solid var(--hair);pointer-events:none"></div>
@@ -1,10 +1,13 @@
1
1
  /* styles/black-gold — 纯黑 + 金辉光 + 衬线 + 单色金 ramp。复用同一套 layouts。 */
2
2
  :root{
3
+ /* 排版节奏 — layouts 的字号与页边距都写成 calc(N * var(--…-scale,1)),
4
+ 所以皮肤可以在不碰任何 layout 的前提下定义自己的疏密。年报:庄重的边距。 */
5
+ --space-scale:1.1; --type-scale:1.0;
3
6
  --accent:#D4AF37; --c1:#D4AF37; --c2:#E7C08A; --c3:#C9A24B; --c4:#F5D98B; --chart-1:#B8912C;
4
7
  --title:#F6E8C2; --body:#b3a887; --muted:#8a7f63; --foot:#6a614a;
5
8
  --hair:rgba(212,175,55,.16); --card-radius:16px;
6
- --font-head:'Georgia','Times New Roman','Songti SC','Noto Serif SC',serif;
7
- --font-body:'Georgia','Songti SC',serif;
9
+ --font-head:'Bodoni Moda','Didot','Songti SC','Noto Serif SC','Source Han Serif SC',serif;
10
+ --font-body:'Lora','Songti SC','Noto Serif SC','Source Han Serif SC',serif;
8
11
  /* theme-compat vars: SKELETON_CSS's section.slide h1/h2/h3 + section.slide out-specify
9
12
  the skin's .cover-title/.slide, so titles/body fall back to these — define them so
10
13
  --style alone fully colors the deck (else headings render dark on the dark bg). */
@@ -18,7 +21,11 @@
18
21
  .deck-header,.deck-footer,.deck-pageno{color:var(--muted)}
19
22
  .rule{background:var(--hair)} .rule-foot{background:rgba(212,175,55,.10)}
20
23
  .eyebrow{color:var(--accent)} .accent-bar{background:var(--accent);border-radius:1px}
21
- .deck-title,.cover-title,.section-title,.ending-title{color:var(--title);font-family:var(--font-head);font-weight:700}
24
+ /* This skin's identity IS this face — a didone/garalde/roman falling back to the
25
+ system serif reads as a different deck entirely. Bake the display classes so the
26
+ audience sees it; body copy stays native (editable/searchable). See
27
+ deck-design.md § Fonts for why bundling alone doesn't reach the native text layer. */
28
+ .deck-title,.cover-title,.section-title,.ending-title{color:var(--title);font-family:var(--font-head);font-weight:700;--talos-bake:1}
22
29
  .cover-sub,.ending-sub,.section-desc{color:var(--body)}
23
30
  .card{border-radius:var(--card-radius);background:linear-gradient(180deg,rgba(212,175,55,.06),rgba(212,175,55,.015));border:1px solid rgba(212,175,55,.20);box-shadow:0 24px 60px rgba(0,0,0,.5);overflow:hidden}
24
31
  .card-idx{color:var(--muted)} .card-body{color:var(--body)}
@@ -32,16 +39,16 @@
32
39
  .cmp-title{color:var(--title)} .cmp-k{color:var(--muted)} .cmp-v{color:var(--title)}
33
40
  .cmp-col--rec .cmp-v{color:var(--accent)}
34
41
  .cmp-badge{background:var(--accent);color:#241a04}
35
- .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head)} .kpi-label{color:var(--muted)}
42
+ .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head);--talos-bake:1} .kpi-label{color:var(--muted)}
36
43
  .stat-unit{color:var(--accent)} .stat-lead{color:var(--title)} .stat-note{color:var(--body)}
37
44
  .step-line{background:linear-gradient(90deg,transparent,var(--accent),transparent);opacity:.5}
38
- .step-circle{background:linear-gradient(180deg,rgba(212,175,55,.06),rgba(212,175,55,.015));border:1px solid rgba(212,175,55,.22);box-shadow:0 20px 44px rgba(0,0,0,.5);font-family:var(--font-head)}
45
+ .step-circle{background:linear-gradient(180deg,rgba(212,175,55,.06),rgba(212,175,55,.015));border:1px solid rgba(212,175,55,.22);box-shadow:0 20px 44px rgba(0,0,0,.5);font-family:var(--font-head);--talos-bake:1}
39
46
  .steps .step:nth-child(4n+1) .step-circle{color:var(--c1)} .steps .step:nth-child(4n+2) .step-circle{color:var(--c2)} .steps .step:nth-child(4n+3) .step-circle{color:var(--c3)} .steps .step:nth-child(4n+4) .step-circle{color:var(--c4)}
40
47
  .step-tag,.step-body{color:var(--muted)} .step-title{color:var(--title)}
41
48
  .toc-item{border-top:1px solid var(--hair)} .toc-grid .toc-item:nth-child(1){border-top-color:var(--c1)} .toc-grid .toc-item:nth-child(2){border-top-color:var(--c2)}
42
- .toc-grid .toc-item:nth-child(1) .toc-num{color:var(--c1)} .toc-grid .toc-item:nth-child(2) .toc-num{color:var(--c2)} .toc-num{color:var(--foot);font-family:var(--font-head)}
49
+ .toc-grid .toc-item:nth-child(1) .toc-num{color:var(--c1)} .toc-grid .toc-item:nth-child(2) .toc-num{color:var(--c2)} .toc-num{color:var(--foot);font-family:var(--font-head);--talos-bake:1}
43
50
  .toc-title{color:var(--title)} .toc-desc{color:var(--muted)}
44
- .section-ghost{color:transparent;-webkit-text-stroke:1px rgba(212,175,55,.16);font-family:var(--font-head)}
51
+ .section-ghost{color:transparent;-webkit-text-stroke:1px rgba(212,175,55,.16);font-family:var(--font-head);--talos-bake:1}
45
52
  .surface{background:rgba(212,175,55,.04);border:1px solid rgba(212,175,55,.20);border-radius:16px} .surface-label{color:var(--muted)}
46
53
  .ending-contact{color:var(--muted)}
47
54
 
@@ -50,7 +57,7 @@
50
57
  .overlay-sub{color:rgba(255,255,255,.82)}
51
58
  /* batch-5 layouts: timeline / concept-hub / cover-image (added classes) */
52
59
  .tl-dot{background:var(--accent);border-radius:50%}
53
- .tl-date{color:var(--accent);font-family:var(--font-head)}
60
+ .tl-date{color:var(--accent);font-family:var(--font-head);--talos-bake:1}
54
61
  .tl-title{color:var(--title)} .tl-desc{color:var(--muted)}
55
62
  .hub-center{border-radius:50%;border:2px solid var(--accent)}
56
63
  .hub-title{color:var(--accent)}
@@ -1 +1,5 @@
1
1
  <div style="position:absolute;inset:0;background:radial-gradient(50% 64% at 92% 4%,rgba(122,154,114,.11),transparent 58%),radial-gradient(44% 54% at 4% 98%,rgba(183,156,110,.07),transparent 62%)"></div><svg width="1280" height="720" viewBox="0 0 1280 720" style="position:absolute;inset:0" preserveAspectRatio="none"><defs><linearGradient id="brl" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="#7A9A72" stop-opacity="0"/><stop offset=".5" stop-color="#7A9A72" stop-opacity=".26"/><stop offset="1" stop-color="#7A9A72" stop-opacity="0"/></linearGradient></defs><path d="M-40 150 C 380 92,880 128,1330 44" fill="none" stroke="url(#brl)" stroke-width=".7"/></svg><svg style="position:absolute;inset:0;width:100%;height:100%;opacity:.04;mix-blend-mode:multiply;pointer-events:none"><filter id="brn"><feTurbulence type="fractalNoise" baseFrequency=".82" numOctaves="2" stitchTiles="stitch"/></filter><rect width="100%" height="100%" filter="url(#brn)"/></svg>
2
+ <!-- signature: the brand-book spine — a bound left edge with its fold rule. -->
3
+ <div style="position:absolute;left:0;top:0;bottom:0;width:30px;background:var(--accent);opacity:.15;pointer-events:none"></div>
4
+ <div style="position:absolute;left:30px;top:0;bottom:0;width:1px;background:var(--hair);pointer-events:none"></div>
5
+ <div style="position:absolute;left:0;top:64px;width:30px;height:44px;background:var(--accent);opacity:.5;pointer-events:none"></div>
@@ -2,11 +2,14 @@
2
2
  清爽、留白大、可持续/美妆/零售调性。原创皮肤(风格方向,非复刻任何模版)。
3
3
  浅色 skin:复用同一套 layouts。 */
4
4
  :root{
5
+ /* 排版节奏 — layouts 的字号与页边距都写成 calc(N * var(--…-scale,1)),
6
+ 所以皮肤可以在不碰任何 layout 的前提下定义自己的疏密。品牌手册:书页般的宽边距。 */
7
+ --space-scale:1.12; --type-scale:0.98;
5
8
  --accent:#7A9A72; --c1:#7A9A72; --c2:#B79C6E; --c3:#5E7D5A; --c4:#A9A288; --chart-1:#6F9169;
6
9
  --title:#26261F; --body:#57574A; --muted:#8A876F; --foot:#A8A48C;
7
10
  --hair:#DFD8C5; --card-radius:10px;
8
- --font-head:Georgia,'Songti SC','Noto Serif SC','Times New Roman',serif;
9
- --font-body:'Helvetica Neue','PingFang SC','Hiragino Sans GB',sans-serif;
11
+ --font-head:'Cormorant Garamond','Palatino','Songti SC','Noto Serif SC','Source Han Serif SC',serif;
12
+ --font-body:'Karla','PingFang SC','Noto Sans SC','Hiragino Sans GB',sans-serif;
10
13
  /* theme-compat */
11
14
  --title-color:#26261F; --body-color:#57574A; --slide-bg:#F3EEE2; --font-heading:var(--font-head);
12
15
  }
@@ -21,6 +24,10 @@
21
24
  /* --talos-bake:1 → titles bake into the backdrop so the serif shows for CJK too
22
25
  (pinning a CJK pptx typeface vanishes in hybrid). Trade-off: title is image,
23
26
  not editable/searchable — the accepted cost for a serif 品牌 skin. */
27
+ /* This skin's identity IS this face — a didone/garalde/roman falling back to the
28
+ system serif reads as a different deck entirely. Bake the display classes so the
29
+ audience sees it; body copy stays native (editable/searchable). See
30
+ deck-design.md § Fonts for why bundling alone doesn't reach the native text layer. */
24
31
  .deck-title,.cover-title,.section-title,.ending-title{color:var(--title);font-family:var(--font-head);font-weight:700;--talos-bake:1}
25
32
  .cover-sub,.ending-sub,.section-desc{color:var(--body)}
26
33
  .card{border-radius:var(--card-radius);background:#FBF7EC;border:1px solid var(--hair);box-shadow:0 14px 34px rgba(60,58,40,.09);overflow:hidden}
@@ -35,16 +42,16 @@
35
42
  .cmp-title{color:var(--title)} .cmp-k{color:var(--muted)} .cmp-v{color:var(--title)}
36
43
  .cmp-col--rec .cmp-v{color:var(--accent)}
37
44
  .cmp-badge{background:var(--accent);color:#F6F2E8}
38
- .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head);font-weight:700} .kpi-label{color:var(--muted)}
45
+ .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head);font-weight:700;--talos-bake:1} .kpi-label{color:var(--muted)}
39
46
  .stat-unit{color:var(--accent)} .stat-lead{color:var(--title)} .stat-note{color:var(--body)}
40
47
  .step-line{background:linear-gradient(90deg,transparent,var(--accent),transparent);opacity:.5}
41
- .step-circle{background:#FBF7EC;border:1px solid var(--hair);box-shadow:0 12px 28px rgba(60,58,40,.09);font-family:var(--font-head)}
48
+ .step-circle{background:#FBF7EC;border:1px solid var(--hair);box-shadow:0 12px 28px rgba(60,58,40,.09);font-family:var(--font-head);--talos-bake:1}
42
49
  .steps .step:nth-child(4n+1) .step-circle{color:var(--c1)} .steps .step:nth-child(4n+2) .step-circle{color:var(--c2)} .steps .step:nth-child(4n+3) .step-circle{color:var(--c3)} .steps .step:nth-child(4n+4) .step-circle{color:var(--c4)}
43
50
  .step-tag,.step-body{color:var(--muted)} .step-title{color:var(--title)}
44
51
  .toc-item{border-top:1px solid var(--hair)} .toc-grid .toc-item:nth-child(1){border-top-color:var(--c1)} .toc-grid .toc-item:nth-child(2){border-top-color:var(--c2)}
45
- .toc-grid .toc-item:nth-child(1) .toc-num{color:var(--c1)} .toc-grid .toc-item:nth-child(2) .toc-num{color:var(--c2)} .toc-num{color:var(--foot);font-family:var(--font-head)}
52
+ .toc-grid .toc-item:nth-child(1) .toc-num{color:var(--c1)} .toc-grid .toc-item:nth-child(2) .toc-num{color:var(--c2)} .toc-num{color:var(--foot);font-family:var(--font-head);--talos-bake:1}
46
53
  .toc-title{color:var(--title)} .toc-desc{color:var(--muted)}
47
- .section-ghost{color:transparent;-webkit-text-stroke:1px rgba(122,154,114,.28);font-family:var(--font-head)}
54
+ .section-ghost{color:transparent;-webkit-text-stroke:1px rgba(122,154,114,.28);font-family:var(--font-head);--talos-bake:1}
48
55
  .surface{background:#FBF7EC;border:1px solid var(--hair);border-radius:10px} .surface-label{color:var(--muted)}
49
56
  .ending-contact{color:var(--muted)}
50
57
  /* full-bleed image overlay — 始终浅色 */
@@ -52,7 +59,7 @@
52
59
  .scrim{background:linear-gradient(180deg,transparent 26%,rgba(0,0,0,.58))}
53
60
  /* timeline / concept-hub */
54
61
  .tl-dot{background:var(--accent);border-radius:50%}
55
- .tl-date{color:var(--accent);font-family:var(--font-head)}
62
+ .tl-date{color:var(--accent);font-family:var(--font-head);--talos-bake:1}
56
63
  .tl-title{color:var(--title)} .tl-desc{color:var(--muted)}
57
64
  .hub-center{border-radius:50%;border:2px solid var(--accent)} .hub-title{color:var(--accent)} .hub-link{stroke:var(--accent);opacity:.4}
58
65
  /* data-table */
@@ -1,13 +1,16 @@
1
- /* styles/cinereel — 胶片感黑白极简:黑底/照片底 + 白色 Anton 粗体大写标题(标题=accent,
1
+ /* styles/cinereel — 胶片感黑白极简:黑底/照片底 + 白色超浓缩粗体大写标题(Big Shoulders
2
+ Display,比 Anton 更窄、字腔更开,对齐 slidescarnival 音乐录影带模板;正文 Jost 几何无衬线)(标题=accent,
2
3
  无色相)+ 常驻胶片取景框(顶/底黑色遮幅条,每页恒定)+ .slide-inverse 浅灰面板反色(目录/流程页)。
3
4
  皮肤层:定义 layouts/*.tpl 用到的全部语义 class。换 skin 只换这一个文件。 */
4
- @font-face{font-family:'Anton';src:local('Anton'),url(data:font/woff2;base64,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) format('woff2');font-display:swap}
5
5
  :root{
6
+ /* 排版节奏 — layouts 的字号与页边距都写成 calc(N * var(--…-scale,1)),
7
+ 所以皮肤可以在不碰任何 layout 的前提下定义自己的疏密。遮幅条已经定了节奏,不再叠加。 */
8
+ --space-scale:1.0; --type-scale:1.0;
6
9
  --accent:#F5F4F0; --c1:#F5F4F0; --c2:#C7C5BE; --c3:#8A8880; --c4:#5A584F; --chart-1:#8A8880;
7
10
  --title:#F5F4F0; --body:#C7C5BE; --muted:#8A8880; --foot:#656358;
8
11
  --hair:rgba(245,244,240,.16); --card-radius:0px;
9
- --font-head:'Anton','Arial Narrow Bold','Heiti SC','PingFang SC',sans-serif;
10
- --font-body:'Helvetica Neue','Arial','PingFang SC','Microsoft YaHei',sans-serif;
12
+ --font-head:'Big Shoulders Display','Anton','Arial Narrow Bold','Heiti SC','PingFang SC',sans-serif;
13
+ --font-body:'Jost','Helvetica Neue','Arial','PingFang SC','Microsoft YaHei',sans-serif;
11
14
  /* theme-compat vars: SKELETON_CSS's section.slide h1/h2/h3 + section.slide out-specify
12
15
  the skin's .cover-title/.slide, so titles/body fall back to these — define them so
13
16
  --style alone fully colors the deck. */
@@ -50,19 +53,30 @@
50
53
  .cmp-col--rec .cmp-v{color:var(--accent)}
51
54
  .cmp-badge{background:var(--accent);color:#0D0D0C}
52
55
  /* kpi / big-stat */
53
- .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head)} .kpi-label{color:var(--muted)}
56
+ /* Anton in the NATIVE text layer is a lottery (the consuming app substitutes a wider
57
+ generic sans — wrong glyphs, and wide enough to wrap). These are decorative display
58
+ numerals/dates that nobody edits, so fidelity beats editability: bake them, same call
59
+ as the titles above. `.panel-item-title` is deliberately NOT baked — it is real
60
+ content a reader may want to change. Baked text is also invisible to data-anim and
61
+ deck-qa; see deck-design.md § Fonts. */
62
+ .kpi-num,.stat-num{color:var(--title);font-family:var(--font-head);--talos-bake:1} .kpi-label{color:var(--muted)}
54
63
  .stat-unit{color:var(--accent)} .stat-lead{color:var(--title)} .stat-note{color:var(--body)}
55
64
  /* steps */
56
65
  .step-line{background:var(--hair)}
57
- .step-circle{background:rgba(245,244,240,.04);border:1px solid var(--hair);font-family:var(--font-head);position:relative;z-index:1}
66
+ .step-circle{background:rgba(245,244,240,.04);border:1px solid var(--hair);font-family:var(--font-head);position:relative;z-index:1;--talos-bake:1}
58
67
  .steps .step:nth-child(4n+1) .step-circle{color:var(--c1)} .steps .step:nth-child(4n+2) .step-circle{color:var(--c2)} .steps .step:nth-child(4n+3) .step-circle{color:var(--c3)} .steps .step:nth-child(4n+4) .step-circle{color:var(--c4)}
59
68
  .step-tag,.step-body{color:var(--muted)} .step-title{color:var(--title)}
60
69
  /* toc */
61
70
  .toc-item{border-top:1px solid var(--hair)} .toc-grid .toc-item:nth-child(1){border-top-color:var(--c1)} .toc-grid .toc-item:nth-child(2){border-top-color:var(--c2)}
62
- .toc-grid .toc-item:nth-child(1) .toc-num{color:var(--c1)} .toc-grid .toc-item:nth-child(2) .toc-num{color:var(--c2)} .toc-num{color:var(--foot);font-family:var(--font-head)}
71
+ .toc-grid .toc-item:nth-child(1) .toc-num{color:var(--c1)} .toc-grid .toc-item:nth-child(2) .toc-num{color:var(--c2)} /* Anton is a custom condensed face the consuming app may fail to resolve for the
72
+ NATIVE text layer (same failure the title rule above documents). On a big
73
+ display numeral that substitution is wide enough to wrap the trailing "."
74
+ onto its own line — and the numeral renders in a generic sans instead of
75
+ Anton. Bake it: these numerals are decoration, editability buys nothing. */
76
+ .toc-num{color:var(--foot);font-family:var(--font-head);--talos-bake:1}
63
77
  .toc-title{color:var(--title)} .toc-desc{color:var(--muted)}
64
78
  /* section ghost + surface */
65
- .section-ghost{color:transparent;-webkit-text-stroke:1px rgba(245,244,240,.16);font-family:var(--font-head)}
79
+ .section-ghost{color:transparent;-webkit-text-stroke:1px rgba(245,244,240,.16);font-family:var(--font-head);--talos-bake:1}
66
80
  .surface{background:rgba(245,244,240,.05);border:1px solid var(--hair);border-radius:0;position:relative;z-index:1} .surface-label{color:var(--muted)}
67
81
  .ending-contact{color:var(--muted)}
68
82
 
@@ -71,7 +85,7 @@
71
85
  .overlay-sub{color:rgba(255,255,255,.82)}
72
86
  /* batch-5 layouts: timeline / concept-hub / cover-image */
73
87
  .tl-dot{background:var(--accent);border-radius:50%}
74
- .tl-date{color:var(--accent);font-family:var(--font-head)}
88
+ .tl-date{color:var(--accent);font-family:var(--font-head);--talos-bake:1}
75
89
  .tl-title{color:var(--title)} .tl-desc{color:var(--muted)}
76
90
  .hub-center{border-radius:50%;border:2px solid var(--accent)}
77
91
  .hub-title{color:var(--accent)}
@@ -125,6 +139,10 @@
125
139
  /* ===== .slide-inverse — 浅灰面板反色(目录/流程图这类页面,原模版里黑色取景框不变,
126
140
  只有中间内容区翻成浅灰;标题/accent 在这套皮肤里没有独立色相,必须跟着翻黑,
127
141
  与 ivory-gold 的"标题恒定金色"不同 —— 每个皮肤自行决定哪些 token 要翻)。 */
128
- .slide.slide-inverse{--slide-bg:#F0EFEA;--body:#3A3830;--muted:#6E6C61;--foot:#8F8D80;--hair:rgba(13,13,12,.14);--title:#0D0D0C;--accent:#0D0D0C;--title-color:#0D0D0C;--body-color:#3A3830}
142
+ .slide.slide-inverse{--slide-bg:#F0EFEA;--body:#3A3830;--muted:#6E6C61;--foot:#8F8D80;--hair:rgba(13,13,12,.14);--title:#0D0D0C;--accent:#0D0D0C;--title-color:#0D0D0C;--body-color:#3A3830;/* the 4-step ramp is a LIGHTNESS ladder tuned for the black ground (c1 near-white = most
143
+ emphasis). On the light panel it has to invert too, or the first two steps — the TOC
144
+ numerals, card rails, step circles — sit near-white on near-white and vanish. Same order
145
+ of emphasis, mirrored: c1 darkest. */
146
+ --c1:#0D0D0C;--c2:#3A3830;--c3:#55534A;--c4:#6E6C61}
129
147
  .slide.slide-inverse .card,.slide.slide-inverse .cmp-col,.slide.slide-inverse .step-circle,.slide.slide-inverse .surface{background:rgba(13,13,12,.04)}
130
148
  .slide.slide-inverse .cmp-badge,.slide.slide-inverse .banner-title{color:#F0EFEA}