Stop shipping html-ppt README preview payloads
Constraint: README preview media and pre-rendered verification screenshots are nonessential for installed skills. Rejected: WebP recompression | GIF conversion increased size and static compression leaves unnecessary package payload. Confidence: high Scope-risk: moderate Directive: Use external source pruning fields instead of hand-editing generated plugin assets. Tested: python scripts/validate_marketplace.py; validate_plugin.py plugins/codex/plugins/html-ppt; uv run python -m pytest backend/tests/test_skill_market_publish.py backend/tests/test_skill_market_scheduler.py -q; node web/tests/skills-market-ui.test.mjs; git diff --check Not-tested: PowerShell execution because pwsh/powershell is not installed locally.
@@ -289,6 +289,19 @@
|
||||
"README.md",
|
||||
"README.zh-CN.md",
|
||||
"LICENSE"
|
||||
],
|
||||
"excludePaths": [
|
||||
"docs/readme",
|
||||
"scripts/verify-output"
|
||||
],
|
||||
"readmeImageExcludes": [
|
||||
"docs/readme"
|
||||
],
|
||||
"readmeLineExcludes": [
|
||||
"Every preview above",
|
||||
"上图里的每一个预览",
|
||||
"scripts/verify-output/",
|
||||
"verify-output/"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
**License:** MIT
|
||||
**中文文档:** [README.zh-CN.md](README.zh-CN.md)
|
||||
|
||||

|
||||
|
||||
> One command installs **36 themes × 20 canvas FX × 31 layouts × 15 full decks + presenter mode**. Every preview above is a live iframe of a real template file rendering inside the deck — no screenshots, no mock-ups.
|
||||
|
||||
## 🎤 Presenter Mode (new!)
|
||||
|
||||
@@ -21,7 +19,6 @@ draggable, resizable **magnetic cards**: current slide, next slide preview,
|
||||
speaker script (逐字稿), and timer. Two windows stay in sync via
|
||||
`BroadcastChannel`.
|
||||
|
||||

|
||||
|
||||
**Why previews are pixel-perfect:** each card is an `<iframe>` that loads the
|
||||
same deck HTML with a `?preview=N` query param. The runtime detects this and
|
||||
@@ -68,7 +65,6 @@ that supports AgentSkills can author presentations by asking things like:
|
||||
| ✨ **CSS animations** | **27** | `assets/animations/animations.css` |
|
||||
| 💥 **Canvas FX animations** | **20** | `assets/animations/fx/*.js` |
|
||||
| 🖼️ **Showcase decks** | 4 | `templates/*-showcase.html` |
|
||||
| 📸 **Verification screenshots** | 56 | `scripts/verify-output/` |
|
||||
|
||||
### 36 Themes
|
||||
|
||||
@@ -81,13 +77,11 @@ that supports AgentSkills can author presentations by asking things like:
|
||||
`corporate-clean`, `academic-paper`, `news-broadcast`, `pitch-deck-vc`,
|
||||
`magazine-bold`, `engineering-whiteprint`.
|
||||
|
||||

|
||||
|
||||
Each is a pure CSS-tokens file — swap one `<link>` to reskin the entire deck.
|
||||
Browse them all in `templates/theme-showcase.html` (each slide rendered in an
|
||||
isolated iframe so theme ≠ theme is visually guaranteed).
|
||||
|
||||

|
||||
|
||||
### 15 Full-deck templates
|
||||
|
||||
@@ -113,7 +107,6 @@ Each is a self-contained folder with scoped `.tpl-<name>` CSS so multiple
|
||||
decks can be previewed side-by-side without collisions. Browse the full
|
||||
gallery in `templates/full-decks-index.html`.
|
||||
|
||||

|
||||
|
||||
### 31 Single-page layouts
|
||||
|
||||
@@ -126,11 +119,9 @@ chart-pie · chart-radar · arch-diagram · process-steps · cta · thanks
|
||||
Every layout ships with realistic demo data so you can drop it into a deck
|
||||
and immediately see it render.
|
||||
|
||||

|
||||
|
||||
*The big iframe is loading `templates/single-page/<name>.html` directly and cycling through all 31 layouts every 2.8 seconds.*
|
||||
|
||||

|
||||
|
||||
### 27 CSS animations + 20 Canvas FX
|
||||
|
||||
@@ -212,7 +203,6 @@ html-ppt-skill/
|
||||
├── scripts/
|
||||
│ ├── new-deck.sh scaffold
|
||||
│ ├── render.sh headless Chrome → PNG
|
||||
│ └── verify-output/ 56 self-test screenshots
|
||||
└── examples/demo-deck/ complete working deck
|
||||
```
|
||||
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
**协议:** MIT
|
||||
**English docs:** [README.md](README.md)
|
||||
|
||||

|
||||
|
||||
> 一行命令装好 **36 主题 × 20 Canvas FX × 31 布局 × 15 完整 deck + 演讲者模式**。
|
||||
> 上图里的每一个预览都是真实的 iframe 加载真实模板文件 —— 不是截图,不是色卡。
|
||||
|
||||
## 🎤 演讲者模式(全新)
|
||||
|
||||
@@ -20,7 +18,6 @@
|
||||
可调整大小的磁吸卡片**:当前页预览、下一页预览、逐字稿、计时器。两个窗口
|
||||
通过 `BroadcastChannel` 双向同步翻页。
|
||||
|
||||

|
||||
|
||||
**为什么预览是像素级完美的:** 每个卡片是一个 `<iframe>`,加载的是**同一
|
||||
份 deck HTML 文件**,只是 URL 多了 `?preview=N` 参数。runtime 检测到这个
|
||||
@@ -65,7 +62,6 @@ npx skills add https://github.com/lewislulu/html-ppt-skill
|
||||
| ✨ **CSS 动画** | **27** | `assets/animations/animations.css` |
|
||||
| 💥 **Canvas FX 动画** | **20** | `assets/animations/fx/*.js` |
|
||||
| 🖼️ **Showcase deck** | 4 | `templates/*-showcase.html` |
|
||||
| 📸 **验证截图** | 56 | `scripts/verify-output/` |
|
||||
|
||||
### 36 套主题
|
||||
|
||||
@@ -78,13 +74,11 @@ npx skills add https://github.com/lewislulu/html-ppt-skill
|
||||
`corporate-clean`、`academic-paper`、`news-broadcast`、`pitch-deck-vc`、
|
||||
`magazine-bold`、`engineering-whiteprint`
|
||||
|
||||

|
||||
|
||||
每个主题都是一份纯 CSS token 文件 —— 只需要换一行 `<link>` 就能给整份 deck
|
||||
换皮。在 `templates/theme-showcase.html` 里可以浏览全部(每一页用独立 iframe
|
||||
渲染,避免样式互相污染)。
|
||||
|
||||

|
||||
|
||||
### 15 套完整 deck 模板
|
||||
|
||||
@@ -113,7 +107,6 @@ npx skills add https://github.com/lewislulu/html-ppt-skill
|
||||
每个模板都是自包含的文件夹,用 scoped `.tpl-<name>` CSS,所以多个模板可以
|
||||
同时加载不会互相污染。在 `templates/full-decks-index.html` 可以看全套 gallery。
|
||||
|
||||

|
||||
|
||||
### 31 种单页布局
|
||||
|
||||
@@ -125,12 +118,10 @@ chart-pie · chart-radar · arch-diagram · process-steps · cta · thanks
|
||||
|
||||
每个布局都带真实的示例数据,拖进 deck 立即看得到效果。
|
||||
|
||||

|
||||
|
||||
*大 iframe 直接加载 `templates/single-page/<name>.html` 文件,每 2.8 秒
|
||||
自动切换到下一个布局。*
|
||||
|
||||

|
||||
|
||||
### 27 个 CSS 动画 + 20 个 Canvas FX
|
||||
|
||||
@@ -217,7 +208,6 @@ html-ppt-skill/
|
||||
├── scripts/
|
||||
│ ├── new-deck.sh 脚手架
|
||||
│ ├── render.sh headless Chrome → PNG
|
||||
│ └── verify-output/ 56 张自测截图
|
||||
└── examples/demo-deck/ 完整可运行的示例 deck
|
||||
```
|
||||
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
**License:** MIT
|
||||
**中文文档:** [README.zh-CN.md](README.zh-CN.md)
|
||||
|
||||

|
||||
|
||||
> One command installs **36 themes × 20 canvas FX × 31 layouts × 15 full decks + presenter mode**. Every preview above is a live iframe of a real template file rendering inside the deck — no screenshots, no mock-ups.
|
||||
|
||||
## 🎤 Presenter Mode (new!)
|
||||
|
||||
@@ -21,7 +19,6 @@ draggable, resizable **magnetic cards**: current slide, next slide preview,
|
||||
speaker script (逐字稿), and timer. Two windows stay in sync via
|
||||
`BroadcastChannel`.
|
||||
|
||||

|
||||
|
||||
**Why previews are pixel-perfect:** each card is an `<iframe>` that loads the
|
||||
same deck HTML with a `?preview=N` query param. The runtime detects this and
|
||||
@@ -68,7 +65,6 @@ that supports AgentSkills can author presentations by asking things like:
|
||||
| ✨ **CSS animations** | **27** | `assets/animations/animations.css` |
|
||||
| 💥 **Canvas FX animations** | **20** | `assets/animations/fx/*.js` |
|
||||
| 🖼️ **Showcase decks** | 4 | `templates/*-showcase.html` |
|
||||
| 📸 **Verification screenshots** | 56 | `scripts/verify-output/` |
|
||||
|
||||
### 36 Themes
|
||||
|
||||
@@ -81,13 +77,11 @@ that supports AgentSkills can author presentations by asking things like:
|
||||
`corporate-clean`, `academic-paper`, `news-broadcast`, `pitch-deck-vc`,
|
||||
`magazine-bold`, `engineering-whiteprint`.
|
||||
|
||||

|
||||
|
||||
Each is a pure CSS-tokens file — swap one `<link>` to reskin the entire deck.
|
||||
Browse them all in `templates/theme-showcase.html` (each slide rendered in an
|
||||
isolated iframe so theme ≠ theme is visually guaranteed).
|
||||
|
||||

|
||||
|
||||
### 15 Full-deck templates
|
||||
|
||||
@@ -113,7 +107,6 @@ Each is a self-contained folder with scoped `.tpl-<name>` CSS so multiple
|
||||
decks can be previewed side-by-side without collisions. Browse the full
|
||||
gallery in `templates/full-decks-index.html`.
|
||||
|
||||

|
||||
|
||||
### 31 Single-page layouts
|
||||
|
||||
@@ -126,11 +119,9 @@ chart-pie · chart-radar · arch-diagram · process-steps · cta · thanks
|
||||
Every layout ships with realistic demo data so you can drop it into a deck
|
||||
and immediately see it render.
|
||||
|
||||

|
||||
|
||||
*The big iframe is loading `templates/single-page/<name>.html` directly and cycling through all 31 layouts every 2.8 seconds.*
|
||||
|
||||

|
||||
|
||||
### 27 CSS animations + 20 Canvas FX
|
||||
|
||||
@@ -212,7 +203,6 @@ html-ppt-skill/
|
||||
├── scripts/
|
||||
│ ├── new-deck.sh scaffold
|
||||
│ ├── render.sh headless Chrome → PNG
|
||||
│ └── verify-output/ 56 self-test screenshots
|
||||
└── examples/demo-deck/ complete working deck
|
||||
```
|
||||
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
**协议:** MIT
|
||||
**English docs:** [README.md](README.md)
|
||||
|
||||

|
||||
|
||||
> 一行命令装好 **36 主题 × 20 Canvas FX × 31 布局 × 15 完整 deck + 演讲者模式**。
|
||||
> 上图里的每一个预览都是真实的 iframe 加载真实模板文件 —— 不是截图,不是色卡。
|
||||
|
||||
## 🎤 演讲者模式(全新)
|
||||
|
||||
@@ -20,7 +18,6 @@
|
||||
可调整大小的磁吸卡片**:当前页预览、下一页预览、逐字稿、计时器。两个窗口
|
||||
通过 `BroadcastChannel` 双向同步翻页。
|
||||
|
||||

|
||||
|
||||
**为什么预览是像素级完美的:** 每个卡片是一个 `<iframe>`,加载的是**同一
|
||||
份 deck HTML 文件**,只是 URL 多了 `?preview=N` 参数。runtime 检测到这个
|
||||
@@ -65,7 +62,6 @@ npx skills add https://github.com/lewislulu/html-ppt-skill
|
||||
| ✨ **CSS 动画** | **27** | `assets/animations/animations.css` |
|
||||
| 💥 **Canvas FX 动画** | **20** | `assets/animations/fx/*.js` |
|
||||
| 🖼️ **Showcase deck** | 4 | `templates/*-showcase.html` |
|
||||
| 📸 **验证截图** | 56 | `scripts/verify-output/` |
|
||||
|
||||
### 36 套主题
|
||||
|
||||
@@ -78,13 +74,11 @@ npx skills add https://github.com/lewislulu/html-ppt-skill
|
||||
`corporate-clean`、`academic-paper`、`news-broadcast`、`pitch-deck-vc`、
|
||||
`magazine-bold`、`engineering-whiteprint`
|
||||
|
||||

|
||||
|
||||
每个主题都是一份纯 CSS token 文件 —— 只需要换一行 `<link>` 就能给整份 deck
|
||||
换皮。在 `templates/theme-showcase.html` 里可以浏览全部(每一页用独立 iframe
|
||||
渲染,避免样式互相污染)。
|
||||
|
||||

|
||||
|
||||
### 15 套完整 deck 模板
|
||||
|
||||
@@ -113,7 +107,6 @@ npx skills add https://github.com/lewislulu/html-ppt-skill
|
||||
每个模板都是自包含的文件夹,用 scoped `.tpl-<name>` CSS,所以多个模板可以
|
||||
同时加载不会互相污染。在 `templates/full-decks-index.html` 可以看全套 gallery。
|
||||
|
||||

|
||||
|
||||
### 31 种单页布局
|
||||
|
||||
@@ -125,12 +118,10 @@ chart-pie · chart-radar · arch-diagram · process-steps · cta · thanks
|
||||
|
||||
每个布局都带真实的示例数据,拖进 deck 立即看得到效果。
|
||||
|
||||

|
||||
|
||||
*大 iframe 直接加载 `templates/single-page/<name>.html` 文件,每 2.8 秒
|
||||
自动切换到下一个布局。*
|
||||
|
||||

|
||||
|
||||
### 27 个 CSS 动画 + 20 个 Canvas FX
|
||||
|
||||
@@ -217,7 +208,6 @@ html-ppt-skill/
|
||||
├── scripts/
|
||||
│ ├── new-deck.sh 脚手架
|
||||
│ ├── render.sh headless Chrome → PNG
|
||||
│ └── verify-output/ 56 张自测截图
|
||||
└── examples/demo-deck/ 完整可运行的示例 deck
|
||||
```
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>theme cell</title>
|
||||
<link rel="stylesheet" href="../../assets/fonts.css">
|
||||
<link rel="stylesheet" href="../../assets/base.css">
|
||||
<link id="theme-link" rel="stylesheet" href="../../assets/themes/minimal-white.css">
|
||||
<style>
|
||||
html,body{height:100%;margin:0;overflow:hidden}
|
||||
body{
|
||||
background:var(--bg,#fff);color:var(--text-1,#111);
|
||||
font-family:var(--font-sans);box-sizing:border-box;
|
||||
padding:5cqw 6cqw;container-type:size;
|
||||
}
|
||||
.k{font:700 2.6cqw/1 var(--font-mono,monospace);color:var(--text-3,#888);letter-spacing:.14em;text-transform:uppercase;margin-bottom:2.5cqh}
|
||||
h1{font:900 11cqw/.95 var(--font-display,var(--font-sans));letter-spacing:-.025em;margin:0 0 3cqh;color:var(--text-1)}
|
||||
.lede{font:500 3.2cqw/1.4 var(--font-sans);color:var(--text-2,#555);margin:0 0 3.5cqh;max-width:85cqw}
|
||||
.row{display:flex;gap:1.4cqw;flex-wrap:wrap}
|
||||
.pill{padding:1.2cqh 2.4cqw;border-radius:999px;background:var(--surface-2,#f4f4f8);color:var(--text-1);font:600 2.3cqw/1 var(--font-sans);border:1px solid var(--border,#e5e5ea)}
|
||||
.pill.accent{background:var(--accent,#7c5cff);color:#fff;border-color:transparent}
|
||||
.kpi{margin-top:4cqh;display:flex;gap:5cqw}
|
||||
.kpi div{font:900 10cqw/1 var(--font-display,var(--font-sans));letter-spacing:-.03em;color:var(--accent,#7c5cff)}
|
||||
.kpi div span{display:block;font:500 1.8cqw/1 var(--font-sans);color:var(--text-3,#888);margin-top:1cqh;letter-spacing:.08em;text-transform:uppercase}
|
||||
.gradient-hero{background:linear-gradient(90deg,var(--accent,#7c5cff),var(--accent-2,#22d3ee),var(--accent-3,#ff4d8d));-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="k" id="kname">theme · minimal-white</div>
|
||||
<h1 id="h1">2026<br>年度回顾</h1>
|
||||
<p class="lede">同一份 outline,换一行 theme,排版、字体、色系、装饰全部重写。</p>
|
||||
<div class="row">
|
||||
<span class="pill accent">12 里程碑</span>
|
||||
<span class="pill">团队 +40%</span>
|
||||
<span class="pill">SAT 98%</span>
|
||||
</div>
|
||||
<div class="kpi">
|
||||
<div>98%<span>Sat</span></div>
|
||||
<div>12<span>MS</span></div>
|
||||
<div>7×<span>Faster</span></div>
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
const m = /[?&]theme=([\w-]+)/.exec(location.search||'');
|
||||
if (m){
|
||||
const name = m[1];
|
||||
document.getElementById('theme-link').href = '../../assets/themes/'+name+'.css';
|
||||
document.getElementById('kname').textContent = 'theme · ' + name;
|
||||
if (/rainbow|aurora|cyberpunk|vaporwave|y2k/.test(name)){
|
||||
document.getElementById('h1').classList.add('gradient-hero');
|
||||
}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 600 KiB |
|
Before Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 556 KiB |
|
Before Width: | Height: | Size: 115 KiB |
@@ -1,61 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-theme="aurora">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>47 animations showcase</title>
|
||||
<link rel="stylesheet" href="../../assets/fonts.css">
|
||||
<link rel="stylesheet" href="../../assets/base.css">
|
||||
<link rel="stylesheet" href="../../assets/themes/aurora.css">
|
||||
<link rel="stylesheet" href="../../assets/animations/animations.css">
|
||||
<style>
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
html,body{width:1920px;height:1080px;overflow:hidden}
|
||||
body{background:#0a0a14;font-family:"PingFang SC","Noto Sans SC","Inter",-apple-system,sans-serif;color:#fff;padding:48px 56px 44px;display:flex;flex-direction:column;gap:28px}
|
||||
.hdr{display:flex;align-items:flex-end;justify-content:space-between}
|
||||
.hdr h2{font:900 48px/1 "Inter",sans-serif;letter-spacing:-.02em;color:#fff}
|
||||
.hdr h2 b{display:inline-block;font-size:58px;padding-right:14px;background:linear-gradient(90deg,#ff4d8d,#f59e0b,#22d3ee);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
|
||||
.hdr .sub{font:600 16px/1 "JetBrains Mono","SF Mono",monospace;color:#aab0c0;letter-spacing:.1em;text-transform:uppercase}
|
||||
.grid{flex:1;display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(2,1fr);gap:18px;min-height:0}
|
||||
.cell{position:relative;border-radius:18px;overflow:hidden;border:1px solid rgba(255,255,255,.08);box-shadow:0 20px 56px rgba(0,0,0,.45);background:#050510;min-height:0}
|
||||
.cell .fx-host{position:absolute;inset:0}
|
||||
.cell .label{position:absolute;left:14px;bottom:12px;z-index:5;font:700 11px/1 "JetBrains Mono","SF Mono",monospace;letter-spacing:.1em;padding:6px 12px;border-radius:999px;background:rgba(10,10,20,.72);color:#fff;text-transform:uppercase;border:1px solid rgba(255,255,255,.14);backdrop-filter:blur(6px)}
|
||||
.cell .kind{position:absolute;left:14px;top:12px;z-index:5;font:700 10px/1 "JetBrains Mono","SF Mono",monospace;letter-spacing:.14em;padding:5px 10px;border-radius:999px;background:rgba(255,255,255,.1);color:#fff;text-transform:uppercase;border:1px solid rgba(255,255,255,.16)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="hdr">
|
||||
<h2><b>47</b>Animations — 27 CSS · 20 Canvas FX</h2>
|
||||
<div class="sub">html-ppt · data-anim="…" / data-fx="…" · pick 8 canvas FX</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="cell"><span class="kind">data-fx</span><div class="fx-host" data-fx="knowledge-graph" style="--accent:#7c5cff;--accent-2:#22d3ee;--text-1:#fff"></div><span class="label">knowledge-graph</span></div>
|
||||
<div class="cell"><span class="kind">data-fx</span><div class="fx-host" data-fx="neural-net" style="--accent:#22d3ee;--accent-2:#ff4d8d"></div><span class="label">neural-net</span></div>
|
||||
<div class="cell"><span class="kind">data-fx</span><div class="fx-host" data-fx="galaxy-swirl" style="--accent:#7c5cff;--accent-2:#ff4d8d"></div><span class="label">galaxy-swirl</span></div>
|
||||
<div class="cell"><span class="kind">data-fx</span><div class="fx-host" data-fx="constellation" style="--accent:#9fb4ff"></div><span class="label">constellation</span></div>
|
||||
<div class="cell"><span class="kind">data-fx</span><div class="fx-host" data-fx="matrix-rain"></div><span class="label">matrix-rain</span></div>
|
||||
<div class="cell"><span class="kind">data-fx</span><div class="fx-host" data-fx="starfield" style="--accent:#fff;--accent-2:#9fb4ff"></div><span class="label">starfield</span></div>
|
||||
<div class="cell"><span class="kind">data-fx</span><div class="fx-host" data-fx="firework" style="--accent:#ff4d8d;--accent-2:#22d3ee"></div><span class="label">firework</span></div>
|
||||
<div class="cell"><span class="kind">data-fx</span><div class="fx-host" data-fx="particle-burst" style="--accent:#ff4d8d;--accent-2:#7c5cff"></div><span class="label">particle-burst</span></div>
|
||||
</div>
|
||||
<script src="../../assets/animations/fx/_util.js"></script>
|
||||
<script src="../../assets/animations/fx/knowledge-graph.js"></script>
|
||||
<script src="../../assets/animations/fx/neural-net.js"></script>
|
||||
<script src="../../assets/animations/fx/galaxy-swirl.js"></script>
|
||||
<script src="../../assets/animations/fx/constellation.js"></script>
|
||||
<script src="../../assets/animations/fx/matrix-rain.js"></script>
|
||||
<script src="../../assets/animations/fx/starfield.js"></script>
|
||||
<script src="../../assets/animations/fx/firework.js"></script>
|
||||
<script src="../../assets/animations/fx/particle-burst.js"></script>
|
||||
<script>
|
||||
(function(){
|
||||
document.querySelectorAll('[data-fx]').forEach(el => {
|
||||
const name = el.getAttribute('data-fx');
|
||||
const fn = window.HPX && window.HPX[name];
|
||||
if (typeof fn === 'function') {
|
||||
try { fn(el, {}); } catch(e) { console.warn('[fx]', name, e); }
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,72 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>31 layouts showcase</title>
|
||||
<style>
|
||||
:root{--ink:#0b0b10;--muted:#6b6b78;--line:#e7e7ef}
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
html,body{width:1920px;height:1080px;overflow:hidden}
|
||||
body{background:#f6f7fa;font-family:"PingFang SC","Noto Sans SC","Inter",-apple-system,sans-serif;color:var(--ink);padding:48px 56px 44px;display:flex;flex-direction:column;gap:28px}
|
||||
.hdr{display:flex;align-items:flex-end;justify-content:space-between}
|
||||
.hdr h2{font:900 48px/1 "Inter",sans-serif;letter-spacing:-.02em}
|
||||
.hdr h2 b{display:inline-block;font-size:58px;padding-right:14px;background:linear-gradient(90deg,#2563eb,#22d3ee);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
|
||||
.hdr .sub{font:600 16px/1 "JetBrains Mono","SF Mono",monospace;color:var(--muted);letter-spacing:.1em;text-transform:uppercase}
|
||||
.grid{flex:1;display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(2,1fr);gap:18px;min-height:0}
|
||||
.cell{position:relative;border-radius:18px;overflow:hidden;border:1px solid var(--line);box-shadow:0 16px 48px rgba(10,10,30,.1);background:#fff;min-height:0}
|
||||
.cell iframe{position:absolute;inset:0;width:1920px;height:1080px;border:0;pointer-events:none;transform-origin:top left}
|
||||
.cell .label{position:absolute;left:14px;bottom:12px;z-index:5;font:700 11px/1 "JetBrains Mono","SF Mono",monospace;letter-spacing:.1em;padding:6px 12px;border-radius:999px;background:rgba(255,255,255,.94);color:#1a1a22;text-transform:uppercase;border:1px solid rgba(0,0,0,.06)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="hdr">
|
||||
<h2><b>31</b>Layouts — batteries included, demo data bundled</h2>
|
||||
<div class="sub">html-ppt · templates/single-page/*.html · pick 8 of 31</div>
|
||||
</div>
|
||||
<div class="grid" id="grid"></div>
|
||||
|
||||
<script>
|
||||
const LAYOUTS = [
|
||||
['kpi-grid','KPI Grid'],
|
||||
['chart-bar','Chart · Bar'],
|
||||
['timeline','Timeline'],
|
||||
['mindmap','Mindmap'],
|
||||
['flow-diagram','Flow Diagram'],
|
||||
['roadmap','Roadmap'],
|
||||
['pros-cons','Pros / Cons'],
|
||||
['code','Code']
|
||||
];
|
||||
const grid = document.getElementById('grid');
|
||||
LAYOUTS.forEach(([name,label]) => {
|
||||
const cell = document.createElement('div');
|
||||
cell.className = 'cell';
|
||||
const ifr = document.createElement('iframe');
|
||||
ifr.src = '../../templates/single-page/' + name + '.html';
|
||||
ifr.loading = 'eager';
|
||||
cell.appendChild(ifr);
|
||||
const lab = document.createElement('span');
|
||||
lab.className = 'label';
|
||||
lab.textContent = label + ' · ' + name;
|
||||
cell.appendChild(lab);
|
||||
grid.appendChild(cell);
|
||||
});
|
||||
|
||||
function fit(){
|
||||
document.querySelectorAll('.cell iframe').forEach(ifr => {
|
||||
const c = ifr.parentElement;
|
||||
const w = c.clientWidth, h = c.clientHeight;
|
||||
const s = Math.min(w / 1920, h / 1080);
|
||||
ifr.style.transform = 'scale('+s+')';
|
||||
const sw = 1920*s, sh = 1080*s;
|
||||
ifr.style.left = ((w - sw)/2) + 'px';
|
||||
ifr.style.top = ((h - sh)/2) + 'px';
|
||||
ifr.style.position = 'absolute';
|
||||
});
|
||||
}
|
||||
window.addEventListener('resize', fit);
|
||||
setTimeout(fit, 80);
|
||||
setTimeout(fit, 400);
|
||||
setTimeout(fit, 1200);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,72 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>14 full-deck templates showcase</title>
|
||||
<style>
|
||||
:root{--ink:#0b0b10;--muted:#6b6b78;--line:#e7e7ef}
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
html,body{width:1920px;height:1080px;overflow:hidden}
|
||||
body{background:#f6f7fa;font-family:"PingFang SC","Noto Sans SC","Inter",-apple-system,sans-serif;color:var(--ink);padding:48px 56px 44px;display:flex;flex-direction:column;gap:28px}
|
||||
.hdr{display:flex;align-items:flex-end;justify-content:space-between}
|
||||
.hdr h2{font:900 48px/1 "Inter",sans-serif;letter-spacing:-.02em}
|
||||
.hdr h2 b{display:inline-block;font-size:58px;padding-right:14px;background:linear-gradient(90deg,#f59e0b,#ff4d8d);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
|
||||
.hdr .sub{font:600 16px/1 "JetBrains Mono","SF Mono",monospace;color:var(--muted);letter-spacing:.1em;text-transform:uppercase}
|
||||
.grid{flex:1;display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(2,1fr);gap:20px;min-height:0}
|
||||
.cell{position:relative;border-radius:20px;overflow:hidden;border:1px solid var(--line);box-shadow:0 20px 56px rgba(10,10,30,.12);background:#fff;min-height:0}
|
||||
.cell.dark{background:#0a0a14;border-color:rgba(255,255,255,.08)}
|
||||
.cell iframe{position:absolute;inset:0;width:1920px;height:1080px;border:0;pointer-events:none;transform-origin:top left}
|
||||
.cell .label{position:absolute;left:16px;bottom:14px;z-index:5;font:700 12px/1 "JetBrains Mono","SF Mono",monospace;letter-spacing:.1em;padding:7px 14px;border-radius:999px;background:rgba(255,255,255,.94);color:#1a1a22;text-transform:uppercase;border:1px solid rgba(0,0,0,.06)}
|
||||
.cell.dark .label{background:rgba(10,10,20,.78);color:#fff;border-color:rgba(255,255,255,.14)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="hdr">
|
||||
<h2><b>14</b>Full-Deck Templates — complete world-views</h2>
|
||||
<div class="sub">html-ppt · templates/full-decks/* · pick 6 of 14</div>
|
||||
</div>
|
||||
<div class="grid" id="grid"></div>
|
||||
|
||||
<script>
|
||||
const DECKS = [
|
||||
['graphify-dark-graph',true],
|
||||
['xhs-post',false],
|
||||
['hermes-cyber-terminal',true],
|
||||
['knowledge-arch-blueprint',false],
|
||||
['pitch-deck',false],
|
||||
['xhs-white-editorial',false]
|
||||
];
|
||||
const grid = document.getElementById('grid');
|
||||
DECKS.forEach(([name, dark]) => {
|
||||
const cell = document.createElement('div');
|
||||
cell.className = 'cell' + (dark ? ' dark' : '');
|
||||
const ifr = document.createElement('iframe');
|
||||
ifr.src = '../../templates/full-decks/' + name + '/index.html';
|
||||
ifr.loading = 'eager';
|
||||
cell.appendChild(ifr);
|
||||
const lab = document.createElement('span');
|
||||
lab.className = 'label';
|
||||
lab.textContent = name;
|
||||
cell.appendChild(lab);
|
||||
grid.appendChild(cell);
|
||||
});
|
||||
|
||||
function fit(){
|
||||
document.querySelectorAll('.cell iframe').forEach(ifr => {
|
||||
const c = ifr.parentElement;
|
||||
const w = c.clientWidth, h = c.clientHeight;
|
||||
const s = Math.min(w / 1920, h / 1080);
|
||||
ifr.style.transform = 'scale('+s+')';
|
||||
const sw = 1920*s, sh = 1080*s;
|
||||
ifr.style.left = ((w - sw)/2) + 'px';
|
||||
ifr.style.top = ((h - sh)/2) + 'px';
|
||||
ifr.style.position = 'absolute';
|
||||
});
|
||||
}
|
||||
window.addEventListener('resize', fit);
|
||||
setTimeout(fit, 100);
|
||||
setTimeout(fit, 500);
|
||||
setTimeout(fit, 1500);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,38 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>36 themes showcase</title>
|
||||
<style>
|
||||
:root{--ink:#0b0b10;--muted:#6b6b78;--line:#e7e7ef}
|
||||
*{box-sizing:border-box;margin:0;padding:0}
|
||||
html,body{width:1920px;height:1080px;overflow:hidden}
|
||||
body{background:#f6f7fa;font-family:"PingFang SC","Noto Sans SC","Inter","SF Pro Display",-apple-system,sans-serif;color:var(--ink);padding:48px 56px 44px;display:flex;flex-direction:column;gap:28px}
|
||||
.hdr{display:flex;align-items:flex-end;justify-content:space-between}
|
||||
.hdr h2{font:900 48px/1 "Inter",sans-serif;letter-spacing:-.02em}
|
||||
.hdr h2 b{display:inline-block;font-size:58px;padding-right:14px;background:linear-gradient(90deg,#7c5cff,#22d3ee);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
|
||||
.hdr .sub{font:600 16px/1 "JetBrains Mono","SF Mono",monospace;color:var(--muted);letter-spacing:.1em;text-transform:uppercase}
|
||||
.grid{flex:1;display:grid;grid-template-columns:repeat(4,1fr);grid-template-rows:repeat(2,1fr);gap:18px;min-height:0}
|
||||
.cell{position:relative;border-radius:18px;overflow:hidden;border:1px solid var(--line);box-shadow:0 16px 48px rgba(10,10,30,.1);background:#fff;min-height:0}
|
||||
.cell iframe{position:absolute;inset:0;width:100%;height:100%;border:0;pointer-events:none}
|
||||
.cell .label{position:absolute;left:14px;bottom:12px;z-index:5;font:700 11px/1 "JetBrains Mono","SF Mono",monospace;letter-spacing:.1em;padding:6px 12px;border-radius:999px;background:rgba(255,255,255,.94);color:#1a1a22;text-transform:uppercase;border:1px solid rgba(0,0,0,.06)}
|
||||
.cell.dark .label{background:rgba(10,10,20,.78);color:#fff;border-color:rgba(255,255,255,.14)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="hdr">
|
||||
<h2><b>36</b>Themes — one keyword, new identity</h2>
|
||||
<div class="sub">html-ppt · assets/themes/*.css · pick 8 of 36</div>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="cell"><iframe src="_theme-cell.html?theme=minimal-white"></iframe><span class="label">minimal-white</span></div>
|
||||
<div class="cell dark"><iframe src="_theme-cell.html?theme=tokyo-night"></iframe><span class="label">tokyo-night</span></div>
|
||||
<div class="cell dark"><iframe src="_theme-cell.html?theme=aurora"></iframe><span class="label">aurora</span></div>
|
||||
<div class="cell"><iframe src="_theme-cell.html?theme=xiaohongshu-white"></iframe><span class="label">xiaohongshu-white</span></div>
|
||||
<div class="cell dark"><iframe src="_theme-cell.html?theme=cyberpunk-neon"></iframe><span class="label">cyberpunk-neon</span></div>
|
||||
<div class="cell dark"><iframe src="_theme-cell.html?theme=dracula"></iframe><span class="label">dracula</span></div>
|
||||
<div class="cell"><iframe src="_theme-cell.html?theme=soft-pastel"></iframe><span class="label">soft-pastel</span></div>
|
||||
<div class="cell"><iframe src="_theme-cell.html?theme=magazine-bold"></iframe><span class="label">magazine-bold</span></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 503 KiB |
|
Before Width: | Height: | Size: 290 KiB |
|
Before Width: | Height: | Size: 245 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 316 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 248 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 78 KiB |
@@ -89,6 +89,132 @@ function Copy-DirectoryFiltered {
|
||||
}
|
||||
}
|
||||
|
||||
function Assert-RelativePathValue {
|
||||
param([string]$Path)
|
||||
$trimmed = $Path.Trim()
|
||||
if ([string]::IsNullOrWhiteSpace($Path) -or $trimmed -eq "." -or [System.IO.Path]::IsPathRooted($Path)) {
|
||||
throw "Invalid external source exclude path: $Path"
|
||||
}
|
||||
$parts = $trimmed -split '[\\/]'
|
||||
if ($parts -contains "..") {
|
||||
throw "Invalid external source exclude path: $Path"
|
||||
}
|
||||
}
|
||||
|
||||
function Remove-ConfiguredExcludes {
|
||||
param(
|
||||
[string]$Root,
|
||||
[object]$ExcludePaths,
|
||||
[string]$Within
|
||||
)
|
||||
if ($null -eq $ExcludePaths) {
|
||||
return
|
||||
}
|
||||
foreach ($exclude in @($ExcludePaths)) {
|
||||
$relative = [string]$exclude
|
||||
Assert-RelativePathValue -Path $relative
|
||||
Remove-PathIfExists -Path (Join-Path $Root $relative) -Within $Within
|
||||
}
|
||||
}
|
||||
|
||||
function Get-MarkdownImageTarget {
|
||||
param([string]$Line)
|
||||
$match = [regex]::Match($Line, '^\s*!\[[^\]]*\]\(([^)\s]+)(?:\s+"[^"]*")?\)\s*$')
|
||||
if (-not $match.Success) {
|
||||
return $null
|
||||
}
|
||||
return $match.Groups[1].Value.Trim().Trim("<", ">").Replace("\", "/").TrimStart([char[]]@(".", "/"))
|
||||
}
|
||||
|
||||
function Remove-ReadmeImageReferences {
|
||||
param(
|
||||
[string]$Root,
|
||||
[object]$ImagePathPrefixes
|
||||
)
|
||||
if ($null -eq $ImagePathPrefixes) {
|
||||
return
|
||||
}
|
||||
$prefixes = @(
|
||||
foreach ($prefix in @($ImagePathPrefixes)) {
|
||||
$normalized = ([string]$prefix).Trim().Replace("\", "/").Trim("/")
|
||||
if ($normalized) {
|
||||
$normalized
|
||||
}
|
||||
}
|
||||
)
|
||||
if ($prefixes.Count -eq 0) {
|
||||
return
|
||||
}
|
||||
foreach ($readme in Get-ChildItem -LiteralPath $Root -Recurse -Filter "README*.md" | Where-Object { -not $_.PSIsContainer }) {
|
||||
$lines = @([System.IO.File]::ReadAllLines($readme.FullName, [System.Text.Encoding]::UTF8))
|
||||
$updated = New-Object System.Collections.Generic.List[string]
|
||||
$changed = $false
|
||||
foreach ($line in $lines) {
|
||||
$target = Get-MarkdownImageTarget -Line $line
|
||||
$strip = $false
|
||||
if ($target) {
|
||||
foreach ($prefix in $prefixes) {
|
||||
if ($target -eq $prefix -or $target.StartsWith("$prefix/")) {
|
||||
$strip = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($strip) {
|
||||
$changed = $true
|
||||
} else {
|
||||
$updated.Add($line)
|
||||
}
|
||||
}
|
||||
if ($changed) {
|
||||
Write-Utf8NoBomText -Path $readme.FullName -Text (($updated -join "`n").TrimEnd() + "`n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Remove-ReadmeLines {
|
||||
param(
|
||||
[string]$Root,
|
||||
[object]$LineExcludes
|
||||
)
|
||||
if ($null -eq $LineExcludes) {
|
||||
return
|
||||
}
|
||||
$needles = @(
|
||||
foreach ($lineExclude in @($LineExcludes)) {
|
||||
$needle = [string]$lineExclude
|
||||
if ($needle) {
|
||||
$needle
|
||||
}
|
||||
}
|
||||
)
|
||||
if ($needles.Count -eq 0) {
|
||||
return
|
||||
}
|
||||
foreach ($readme in Get-ChildItem -LiteralPath $Root -Recurse -Filter "README*.md" | Where-Object { -not $_.PSIsContainer }) {
|
||||
$lines = @([System.IO.File]::ReadAllLines($readme.FullName, [System.Text.Encoding]::UTF8))
|
||||
$updated = New-Object System.Collections.Generic.List[string]
|
||||
$changed = $false
|
||||
foreach ($line in $lines) {
|
||||
$strip = $false
|
||||
foreach ($needle in $needles) {
|
||||
if ($line.Contains($needle)) {
|
||||
$strip = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($strip) {
|
||||
$changed = $true
|
||||
} else {
|
||||
$updated.Add($line)
|
||||
}
|
||||
}
|
||||
if ($changed) {
|
||||
Write-Utf8NoBomText -Path $readme.FullName -Text (($updated -join "`n").TrimEnd() + "`n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Read-JsonFile {
|
||||
param([string]$Path)
|
||||
$resolvedPath = (Resolve-Path -LiteralPath $Path).Path
|
||||
@@ -350,6 +476,9 @@ function Sync-CodexPlugin {
|
||||
$dst = Join-Path $pluginDir $include
|
||||
Copy-PathIfExists -Source $src -Destination $dst -Within $RepoRoot
|
||||
}
|
||||
Remove-ConfiguredExcludes -Root $pluginDir -ExcludePaths $Source.excludePaths -Within $RepoRoot
|
||||
Remove-ReadmeImageReferences -Root $pluginDir -ImagePathPrefixes $Source.readmeImageExcludes
|
||||
Remove-ReadmeLines -Root $pluginDir -LineExcludes $Source.readmeLineExcludes
|
||||
Apply-LocalOverrides -PluginDir $pluginDir -Source $Source
|
||||
Write-Provenance -PluginDir $pluginDir -Source $Source -Commit $Commit -SyncedAt $SyncedAt -SourcePath $relativeSourcePath
|
||||
}
|
||||
@@ -407,6 +536,9 @@ function Sync-ClaudeSkill {
|
||||
foreach ($rootFile in $includeRootFiles) {
|
||||
Copy-PathIfExists -Source (Join-Path $ClonePath $rootFile) -Destination (Join-Path $pluginDir $rootFile) -Within $RepoRoot
|
||||
}
|
||||
Remove-ConfiguredExcludes -Root $skillDest -ExcludePaths $Source.excludePaths -Within $RepoRoot
|
||||
Remove-ReadmeImageReferences -Root $pluginDir -ImagePathPrefixes $Source.readmeImageExcludes
|
||||
Remove-ReadmeLines -Root $pluginDir -LineExcludes $Source.readmeLineExcludes
|
||||
|
||||
$description = $metadata.description
|
||||
if (-not $description) {
|
||||
|
||||