Files
memind/scripts/bootstrap-premium-page-templates.mjs
T
john fde6503bdf
Memind CI / Test, build, and release guards (push) Has been cancelled
feat(mindspace): add SEO/GEO delivery, page template catalog, and admin hooks
Enable optional SEO/GEO injection and discovery routes for confirmed public pages while keeping private pages noindex. Add premium page template skills, portal catalog API, template shop UI, and Baidu push gated by memind_adm config.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-10 08:06:12 +08:00

877 lines
48 KiB
JavaScript

#!/usr/bin/env node
/**
* One-shot bootstrap: upgrade existing page-template HTML + add 7 premium templates.
* Run: node scripts/bootstrap-premium-page-templates.mjs
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
const skillsRoot = path.join(root, 'skills');
const previewRoot = path.join(root, 'public/assets/template-previews');
const FOOTER =
'<footer><p data-mindspace-page-tag="platform-brand">TKMind · 智趣</p></footer>';
function writeSkillFile(skillName, relativePath, content) {
const full = path.join(skillsRoot, skillName, relativePath);
fs.mkdirSync(path.dirname(full), { recursive: true });
fs.writeFileSync(full, `${content.trim()}\n`, 'utf8');
}
function writePreview(name, svg) {
fs.writeFileSync(path.join(previewRoot, name), `${svg.trim()}\n`, 'utf8');
}
const upgraded = {
'page-template-travel/templates/travel-hero.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; --accent2: {{ACCENT2}}; --ink: #f5f7fa; --muted: #a8b8cc; --bg: #060d18; }
* { box-sizing: border-box; }
body { margin: 0; font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", sans-serif; background: var(--bg); color: var(--ink); }
.hero { position: relative; min-height: 78vh; display: grid; align-items: end; padding: clamp(28px, 7vw, 80px); overflow: hidden; }
.hero::before { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(6,13,24,.15) 0%, rgba(6,13,24,.55) 45%, rgba(6,13,24,.94) 100%), url('{{HERO_IMAGE}}') center/cover no-repeat; transform: scale(1.02); }
.hero::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 80% 50% at 20% 0%, rgba(245,158,11,.18), transparent 60%); pointer-events: none; }
.hero-inner { position: relative; z-index: 1; max-width: 920px; }
.eyebrow { display: inline-flex; align-items: center; gap: 8px; color: var(--accent2); font-size: 11px; letter-spacing: .22em; text-transform: uppercase; font-weight: 800; }
.eyebrow::before { content: ""; width: 28px; height: 1px; background: var(--accent2); opacity: .7; }
h1 { margin: 16px 0 12px; font-size: clamp(38px, 8.5vw, 68px); line-height: 1.02; font-weight: 800; letter-spacing: -.02em; }
.subtitle { max-width: 40rem; color: var(--muted); font-size: clamp(16px, 2.2vw, 19px); line-height: 1.75; }
main { padding: clamp(32px, 6vw, 80px) clamp(20px, 5vw, 48px); max-width: 920px; margin: 0 auto; }
.content { font-size: 18px; line-height: 1.9; color: #dbe4ef; }
.content h2 { color: #fff; margin: 2.5rem 0 1rem; font-size: clamp(22px, 4vw, 28px); letter-spacing: -.01em; }
.content p { margin: 0 0 1.2em; }
footer { padding: 40px 24px 56px; text-align: center; color: #6b8299; font-size: 13px; letter-spacing: .06em; }
</style>
</head>
<body>
<header class="hero">
<div class="hero-inner">
<div class="eyebrow">{{HERO_EYEBROW}}</div>
<h1>{{HERO_HEADLINE}}</h1>
<p class="subtitle">{{HERO_SUBTITLE}}</p>
</div>
</header>
<main><div class="content">{{MAIN_CONTENT_HTML}}</div></main>
${FOOTER}
</body>
</html>`,
'page-template-campaign/templates/campaign-cta.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; --accent2: {{ACCENT2}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: linear-gradient(165deg, #fff9f5 0%, #fff 40%, #fef3ec 100%); color: #1a2332; }
.hero { display: grid; gap: clamp(24px, 4vw, 48px); padding: clamp(32px, 7vw, 72px); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); align-items: center; max-width: 1100px; margin: 0 auto; }
.hero-visual { position: relative; }
.hero-visual img { width: 100%; border-radius: 24px; object-fit: cover; aspect-ratio: 4/3; box-shadow: 0 32px 64px rgba(239,68,68,.15), 0 8px 24px rgba(31,41,51,.08); }
.hero-visual::after { content: ""; position: absolute; inset: -8px; border-radius: 28px; border: 1px solid rgba(239,68,68,.12); pointer-events: none; }
.tag { display: inline-block; padding: 6px 14px; border-radius: 999px; background: rgba(239,68,68,.08); color: var(--accent); font-weight: 800; letter-spacing: .14em; font-size: 11px; }
h1 { margin: 16px 0 12px; font-size: clamp(34px, 6.5vw, 56px); line-height: 1.06; font-weight: 800; letter-spacing: -.02em; }
.lead { color: #5c6b7a; font-size: 18px; line-height: 1.75; max-width: 36rem; }
.cta { display: inline-flex; align-items: center; gap: 8px; margin-top: 24px; padding: 16px 32px; border-radius: 999px; background: linear-gradient(135deg, var(--accent), var(--accent2)); color: #fff; text-decoration: none; font-weight: 700; font-size: 16px; box-shadow: 0 12px 32px rgba(239,68,68,.28); }
section { padding: 8px clamp(20px, 5vw, 64px) 32px; max-width: 960px; margin: 0 auto; }
.panel { background: #fff; border-radius: 24px; padding: clamp(24px, 4vw, 36px); box-shadow: 0 20px 60px rgba(31,41,51,.06); border: 1px solid rgba(31,41,51,.04); margin-bottom: 24px; }
.panel h2 { margin-top: 0; font-size: 22px; }
.cta-row { text-align: center; padding-bottom: 48px; }
footer { text-align: center; padding: 32px 16px 48px; color: #94a3b8; font-size: 13px; }
</style>
</head>
<body>
<header class="hero">
<div>
<div class="tag">{{PRODUCT_NAME}}</div>
<h1>{{HERO_HEADLINE}}</h1>
<p class="lead">{{HERO_SUBTITLE}}</p>
<a class="cta" href="{{CTA_URL}}">{{CTA_LABEL}}</a>
</div>
<div class="hero-visual"><img src="{{HERO_IMAGE}}" alt="{{PRODUCT_NAME}}"></div>
</header>
<section><div class="panel">{{SELLING_POINTS_HTML}}</div></section>
<section><div class="panel">{{OFFER_HTML}}</div></section>
<section class="cta-row"><a class="cta" href="{{CTA_URL}}">{{CTA_LABEL}}</a></section>
${FOOTER}
</body>
</html>`,
'page-template-survey/templates/survey-basic.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: radial-gradient(ellipse 120% 80% at 50% -20%, #e8f5ef, #f7f4ed 45%, #f0ebe3 100%); color: #1a2420; }
main { max-width: 640px; margin: 0 auto; padding: clamp(28px, 6vw, 64px) clamp(20px, 4vw, 32px); }
.card { background: rgba(255,255,255,.92); backdrop-filter: blur(12px); border-radius: 28px; padding: clamp(28px, 5vw, 44px); box-shadow: 0 24px 80px rgba(45,53,47,.1), 0 1px 0 rgba(255,255,255,.8) inset; border: 1px solid rgba(255,255,255,.6); }
h1 { margin: 0 0 12px; font-size: clamp(28px, 5.5vw, 40px); font-weight: 800; letter-spacing: -.02em; line-height: 1.15; }
.intro { color: #5c655f; line-height: 1.75; margin-bottom: 28px; font-size: 16px; }
label { display: block; font-weight: 600; margin: 20px 0 8px; font-size: 14px; color: #374151; }
input, textarea, select { width: 100%; padding: 14px 16px; border: 1px solid #e5e0d6; border-radius: 14px; font: inherit; background: #faf9f7; transition: border-color .2s, box-shadow .2s; }
input:focus, textarea:focus, select:focus { outline: none; border-color: #2f6f57; box-shadow: 0 0 0 3px rgba(47,111,87,.12); }
button[type="submit"] { margin-top: 28px; width: 100%; padding: 16px; border: 0; border-radius: 999px; background: linear-gradient(135deg, #2f6f57, #3d8b6e); color: #fff; font-size: 16px; font-weight: 700; cursor: pointer; box-shadow: 0 12px 32px rgba(47,111,87,.25); }
#status { margin-top: 16px; min-height: 1.2em; color: #2f6f57; font-weight: 600; text-align: center; }
footer { text-align: center; padding: 24px; color: #8a938d; font-size: 13px; }
</style>
</head>
<body>
<main>
<article class="card">
<h1>{{SURVEY_HEADLINE}}</h1>
<div class="intro">{{SURVEY_INTRO_HTML}}</div>
<form id="survey-form">
{{FORM_FIELDS_HTML}}
<button type="submit">{{SUBMIT_BUTTON_LABEL}}</button>
</form>
<div id="status" aria-live="polite"></div>
</article>
</main>
${FOOTER}
<script src="/assets/page-data-client.js"></script>
<script>
(function () {
var datasetId = '{{DATASET_ID}}';
var form = document.getElementById('survey-form');
var status = document.getElementById('status');
if (!window.PageDataClient || !datasetId) { status.textContent = 'Page Data 未就绪'; return; }
form.addEventListener('submit', function (event) {
event.preventDefault();
status.textContent = '提交中…';
var data = Object.fromEntries(new FormData(form).entries());
window.PageDataClient.insert(datasetId, data)
.then(function () { status.textContent = '提交成功,感谢填写!'; form.reset(); })
.catch(function () { status.textContent = '提交失败,请稍后重试'; });
});
})();
</script>
</body>
</html>`,
'page-template-restaurant/templates/restaurant-menu.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; --gold: #e8c896; --bg: #120c06; --card: rgba(255,248,240,.04); }
* { box-sizing: border-box; }
body { margin: 0; font-family: "Songti SC", Georgia, "Times New Roman", serif; background: var(--bg); color: #f5efe6; }
header { text-align: center; padding: clamp(48px, 10vw, 88px) 24px 40px; background: radial-gradient(ellipse 100% 80% at 50% 0%, #2a1a0c, var(--bg)); border-bottom: 1px solid rgba(232,200,150,.12); }
.tag { color: var(--accent); letter-spacing: .28em; font-size: 11px; font-weight: 700; font-family: system-ui, sans-serif; }
h1 { margin: 12px 0 8px; font-size: clamp(32px, 7vw, 52px); font-weight: 400; letter-spacing: .06em; }
.subtitle { color: #c4b5a0; font-size: 16px; font-style: italic; max-width: 28rem; margin: 0 auto; line-height: 1.6; }
main { max-width: 680px; margin: 0 auto; padding: clamp(32px, 6vw, 56px) 24px; }
.menu-section { background: var(--card); border: 1px solid rgba(232,200,150,.1); border-radius: 20px; padding: 28px 24px; margin-bottom: 20px; }
.menu-section h2 { margin: 0 0 16px; font-size: 20px; color: var(--gold); font-weight: 400; letter-spacing: .12em; text-transform: uppercase; font-family: system-ui, sans-serif; font-size: 13px; }
.menu-item { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-bottom: 1px dotted rgba(232,200,150,.15); font-size: 16px; }
.menu-item:last-child { border-bottom: 0; }
.menu-item .price { color: var(--accent); font-family: system-ui, sans-serif; font-weight: 700; white-space: nowrap; }
footer { text-align: center; padding: 40px 24px 56px; color: #7a6b58; font-size: 13px; font-family: system-ui, sans-serif; }
</style>
</head>
<body>
<header>
<div class="tag">{{VENUE_TAG}}</div>
<h1>{{VENUE_NAME}}</h1>
<p class="subtitle">{{VENUE_SUBTITLE}}</p>
</header>
<main>{{MENU_SECTIONS_HTML}}</main>
${FOOTER}
</body>
</html>`,
'page-template-portfolio/templates/portfolio-grid.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; --bg: #0a0c10; --card: #141820; --border: #252d3d; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: var(--bg); color: #e8ecf4; min-height: 100vh; }
.intro { text-align: center; padding: clamp(48px, 10vw, 88px) 24px 32px; }
h1 { margin: 0 0 10px; font-size: clamp(32px, 6vw, 48px); font-weight: 800; letter-spacing: -.03em; background: linear-gradient(135deg, #fff 30%, var(--accent)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
.lead { color: #94a3b8; margin: 0; font-size: 17px; letter-spacing: .04em; }
.grid { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); max-width: 1040px; margin: 0 auto; padding: 0 24px 64px; }
.card { background: var(--card); border-radius: 20px; padding: 24px; border: 1px solid var(--border); transition: transform .25s, border-color .25s, box-shadow .25s; }
.card h3 { margin: 0 0 10px; font-size: 18px; color: #fff; }
.card p { margin: 0; color: #94a3b8; line-height: 1.65; font-size: 15px; }
.card .tag { display: inline-block; margin-top: 14px; font-size: 11px; color: var(--accent); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
footer { text-align: center; padding: 32px 24px 48px; color: #64748b; font-size: 13px; }
</style>
</head>
<body>
<header class="intro">
<h1>{{CREATOR_NAME}}</h1>
<p class="lead">{{CREATOR_TAGLINE}}</p>
</header>
<main><div class="grid">{{PROJECT_CARDS_HTML}}</div></main>
${FOOTER}
</body>
</html>`,
};
for (const [rel, html] of Object.entries(upgraded)) {
const [skill, ...rest] = rel.split('/');
writeSkillFile(skill, rest.join('/'), html);
}
console.log(`Upgraded ${Object.keys(upgraded).length} templates (batch 1/3)`);
const upgraded2 = {
'page-template-event/templates/event-invite.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: radial-gradient(ellipse 80% 60% at 50% -10%, #3d1f5c, #0f1419 55%); color: #fff; display: grid; place-items: center; padding: 40px 24px; }
.card { width: 100%; max-width: 520px; background: rgba(255,255,255,.07); backdrop-filter: blur(20px); border: 1px solid rgba(255,255,255,.12); border-radius: 32px; padding: clamp(36px, 6vw, 48px); box-shadow: 0 40px 80px rgba(0,0,0,.35); }
.meta { color: #f9a8d4; font-weight: 700; font-size: 13px; letter-spacing: .08em; margin: 0 0 16px; }
h1 { margin: 0 0 16px; font-size: clamp(28px, 5vw, 36px); line-height: 1.2; font-weight: 800; }
.intro { color: #cbd5e1; line-height: 1.75; margin: 0 0 24px; font-size: 16px; }
.agenda { border-top: 1px solid rgba(255,255,255,.1); padding-top: 20px; color: #e2e8f0; line-height: 1.8; }
.agenda h2 { font-size: 13px; letter-spacing: .14em; text-transform: uppercase; color: #f9a8d4; margin: 0 0 12px; }
footer { position: fixed; bottom: 0; left: 0; right: 0; text-align: center; padding: 16px; color: rgba(255,255,255,.35); font-size: 12px; }
</style>
</head>
<body>
<article class="card">
<p class="meta">{{EVENT_DATE}} · {{EVENT_CITY}}</p>
<h1>{{EVENT_TITLE}}</h1>
<p class="intro">{{EVENT_INTRO}}</p>
<div class="agenda">{{AGENDA_HTML}}</div>
</article>
${FOOTER}
</body>
</html>`,
'page-template-course/templates/course-landing.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: #f8faff; color: #0f172a; }
.hero { padding: clamp(56px, 12vw, 96px) 24px; text-align: center; background: linear-gradient(160deg, var(--accent) 0%, #1e40af 100%); color: #fff; position: relative; overflow: hidden; }
.hero::before { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at 80% 20%, rgba(255,255,255,.15), transparent 50%); }
.hero-inner { position: relative; max-width: 680px; margin: 0 auto; }
h1 { margin: 0 0 12px; font-size: clamp(32px, 6vw, 48px); font-weight: 800; letter-spacing: -.02em; }
.subtitle { margin: 0; font-size: 18px; opacity: .9; line-height: 1.65; }
.cta { display: inline-flex; margin-top: 28px; padding: 16px 36px; background: #fff; color: var(--accent); border-radius: 999px; text-decoration: none; font-weight: 800; box-shadow: 0 16px 40px rgba(0,0,0,.15); }
main { max-width: 720px; margin: 0 auto; padding: clamp(32px, 6vw, 56px) 24px; }
.syllabus { background: #fff; border-radius: 24px; padding: clamp(28px, 4vw, 36px); box-shadow: 0 20px 60px rgba(37,99,235,.08); border: 1px solid rgba(37,99,235,.06); line-height: 1.8; }
.syllabus h2 { margin-top: 0; color: var(--accent); }
footer { text-align: center; padding: 32px 24px 48px; color: #64748b; font-size: 13px; }
</style>
</head>
<body>
<header class="hero"><div class="hero-inner"><h1>{{COURSE_TITLE}}</h1><p class="subtitle">{{COURSE_SUBTITLE}}</p><a class="cta" href="{{CTA_URL}}">{{CTA_LABEL}}</a></div></header>
<main><div class="syllabus">{{SYLLABUS_HTML}}</div></main>
${FOOTER}
</body>
</html>`,
'page-template-realestate/templates/realestate-listing.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: #f4f7f6; color: #0f2a24; }
.hero { min-height: 320px; background: linear-gradient(180deg, transparent 60%, rgba(15,42,36,.4)), url('{{HERO_IMAGE}}') center/cover; }
.wrap { max-width: 840px; margin: -56px auto 48px; background: #fff; border-radius: 24px; padding: clamp(28px, 5vw, 40px); box-shadow: 0 32px 80px rgba(15,42,36,.12); position: relative; }
h1 { margin: 0 0 8px; font-size: clamp(26px, 5vw, 36px); font-weight: 800; letter-spacing: -.02em; }
.location { color: #5a7a72; margin: 0 0 24px; font-size: 16px; }
table { width: 100%; border-collapse: collapse; margin-bottom: 24px; }
td { padding: 14px 0; border-bottom: 1px solid #e8f0ed; font-size: 15px; }
td:first-child { color: #5a7a72; width: 35%; font-weight: 500; }
td:last-child { font-weight: 700; color: #0f2a24; }
.highlights { line-height: 1.85; color: #374151; }
.highlights h2 { color: #0f2a24; font-size: 20px; margin: 0 0 12px; }
footer { text-align: center; padding: 24px; color: #94a3b8; font-size: 13px; }
</style>
</head>
<body>
<div class="hero"></div>
<article class="wrap">
<h1>{{LISTING_TITLE}}</h1>
<p class="location">{{LISTING_LOCATION}}</p>
<table>{{SPECS_TABLE_HTML}}</table>
<div class="highlights">{{HIGHLIGHTS_HTML}}</div>
</article>
${FOOTER}
</body>
</html>`,
'page-template-blog/templates/blog-article.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
* { box-sizing: border-box; }
body { margin: 0; font-family: "Songti SC", "Noto Serif SC", Georgia, serif; background: #fafaf8; color: #1c1917; line-height: 1.85; }
article { max-width: 680px; margin: 0 auto; padding: clamp(48px, 10vw, 88px) clamp(24px, 5vw, 40px); }
.meta { color: #78716c; font-size: 14px; margin: 0 0 20px; font-family: system-ui, sans-serif; letter-spacing: .02em; }
h1 { font-size: clamp(30px, 5.5vw, 44px); line-height: 1.25; font-weight: 700; margin: 0 0 32px; letter-spacing: -.01em; }
.content { font-size: 18px; }
.content h2 { margin: 2.5em 0 .75em; font-size: 24px; color: #292524; }
.content p { margin: 0 0 1.4em; }
.content blockquote { margin: 2em 0; padding-left: 20px; border-left: 3px solid #d6d3d1; color: #57534e; font-style: italic; }
footer { text-align: center; padding: 32px 24px 56px; color: #a8a29e; font-size: 13px; font-family: system-ui, sans-serif; }
</style>
</head>
<body>
<article>
<p class="meta">{{ARTICLE_DATE}} · {{ARTICLE_AUTHOR}}</p>
<h1>{{ARTICLE_TITLE}}</h1>
<div class="content">{{ARTICLE_BODY_HTML}}</div>
</article>
${FOOTER}
</body>
</html>`,
'page-template-resume/templates/resume-profile.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: linear-gradient(135deg, #eef2ff, #f8fafc); color: #0f172a; min-height: 100vh; padding: 32px 20px; }
.sheet { max-width: 780px; margin: 0 auto; background: #fff; border-radius: 24px; padding: clamp(32px, 5vw, 48px); box-shadow: 0 24px 80px rgba(29,78,216,.1); border: 1px solid rgba(29,78,216,.06); }
.header { border-bottom: 2px solid var(--accent); padding-bottom: 24px; margin-bottom: 28px; }
h1 { margin: 0; font-size: clamp(32px, 5vw, 42px); font-weight: 800; letter-spacing: -.02em; }
.role { color: var(--accent); font-weight: 700; font-size: 18px; margin: 8px 0 16px; }
.summary { color: #475569; line-height: 1.75; margin: 0; font-size: 16px; }
.section { margin-bottom: 28px; }
.section h2 { font-size: 13px; letter-spacing: .14em; text-transform: uppercase; color: var(--accent); margin: 0 0 14px; font-weight: 800; }
.section p { margin: 0 0 10px; line-height: 1.7; color: #334155; }
footer { text-align: center; padding: 32px 24px; color: #94a3b8; font-size: 13px; }
</style>
</head>
<body>
<article class="sheet">
<header class="header">
<h1>{{FULL_NAME}}</h1>
<p class="role">{{JOB_TITLE}}</p>
<p class="summary">{{SUMMARY}}</p>
</header>
<div class="section">{{EXPERIENCE_HTML}}</div>
<div class="section">{{SKILLS_HTML}}</div>
</article>
${FOOTER}
</body>
</html>`,
'page-template-wedding/templates/wedding-invite.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; font-family: "Songti SC", "Noto Serif SC", serif; background: radial-gradient(ellipse 100% 80% at 50% 0%, #fff5f9, #fdf2f8 50%, #fce7f3); color: #701a56; display: grid; place-items: center; padding: 48px 24px; }
.card { width: 100%; max-width: 480px; text-align: center; border: 1px solid rgba(244,114,182,.25); border-radius: 32px; padding: clamp(44px, 8vw, 56px) clamp(28px, 5vw, 40px); background: rgba(255,255,255,.75); backdrop-filter: blur(8px); box-shadow: 0 32px 80px rgba(190,24,93,.08); }
.preface { font-size: 14px; letter-spacing: .35em; color: #be185d; margin: 0 0 20px; }
.names { font-size: clamp(28px, 6vw, 36px); margin: 0 0 24px; font-weight: 400; letter-spacing: .1em; line-height: 1.4; }
.date, .venue { margin: 0 0 12px; font-size: 16px; color: #9d174d; line-height: 1.6; }
.details { margin-top: 28px; padding-top: 24px; border-top: 1px solid rgba(244,114,182,.2); color: #831843; line-height: 1.85; font-size: 15px; }
footer { position: fixed; bottom: 0; left: 0; right: 0; text-align: center; padding: 16px; color: rgba(157,23,77,.4); font-size: 12px; font-family: system-ui, sans-serif; }
</style>
</head>
<body>
<article class="card">
<p class="preface">诚挚邀请</p>
<h1 class="names">{{COUPLE_NAMES}}</h1>
<p class="date">{{WEDDING_DATE}}</p>
<p class="venue">{{WEDDING_VENUE}}</p>
<div class="details">{{DETAILS_HTML}}</div>
</article>
${FOOTER}
</body>
</html>`,
'page-template-fitness/templates/fitness-club.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: #030806; color: #eafff0; }
header { padding: clamp(48px, 10vw, 80px) 24px 40px; background: linear-gradient(135deg, #14532d 0%, #052e16 50%, #030806 100%); position: relative; overflow: hidden; }
header::after { content: ""; position: absolute; top: -50%; right: -20%; width: 60%; height: 200%; background: radial-gradient(circle, rgba(74,222,128,.12), transparent 60%); pointer-events: none; }
.header-inner { position: relative; max-width: 720px; margin: 0 auto; }
h1 { margin: 0 0 10px; font-size: clamp(34px, 7vw, 52px); font-weight: 900; letter-spacing: -.03em; text-transform: uppercase; }
.slogan { margin: 0; color: #86efac; font-size: 18px; font-weight: 600; letter-spacing: .04em; }
main { max-width: 720px; margin: 0 auto; padding: clamp(32px, 6vw, 48px) 24px 64px; }
.schedule-block { background: linear-gradient(145deg, rgba(255,255,255,.06), rgba(255,255,255,.02)); border: 1px solid rgba(134,239,172,.15); border-radius: 20px; padding: 28px 24px; }
.schedule-block h2 { margin: 0 0 16px; font-size: 13px; letter-spacing: .16em; text-transform: uppercase; color: #4ade80; }
.schedule-block p { margin: 0 0 10px; padding: 12px 16px; background: rgba(0,0,0,.25); border-radius: 12px; font-weight: 600; }
footer { text-align: center; padding: 32px 24px 48px; color: #4ade80; opacity: .5; font-size: 13px; }
</style>
</head>
<body>
<header><div class="header-inner"><h1>{{CLUB_NAME}}</h1><p class="slogan">{{CLUB_SLOGAN}}</p></div></header>
<main>{{SCHEDULE_HTML}}</main>
${FOOTER}
</body>
</html>`,
'page-template-product-grid/templates/product-grid.html': `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title>
<meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: linear-gradient(180deg, #fff7ed, #fff); color: #431407; }
.head { text-align: center; padding: clamp(40px, 8vw, 72px) 24px 24px; }
h1 { margin: 0 0 8px; font-size: clamp(28px, 5vw, 40px); font-weight: 800; letter-spacing: -.02em; }
.subtitle { margin: 0; color: #9a3412; font-size: 16px; opacity: .85; }
.grid { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); max-width: 1000px; margin: 0 auto; padding: 24px 24px 64px; }
.item { background: #fff; border-radius: 20px; padding: 20px; box-shadow: 0 12px 40px rgba(234,88,12,.1); border: 1px solid rgba(234,88,12,.08); transition: transform .2s, box-shadow .2s; }
.item h3 { margin: 0 0 8px; font-size: 17px; color: #431407; }
.item .price { color: var(--accent); font-weight: 800; font-size: 20px; margin: 0; }
.item .desc { color: #78716c; font-size: 14px; margin: 8px 0 0; line-height: 1.5; }
footer { text-align: center; padding: 32px 24px 48px; color: #a8a29e; font-size: 13px; }
</style>
</head>
<body>
<header class="head"><h1>{{COLLECTION_TITLE}}</h1><p class="subtitle">{{COLLECTION_SUBTITLE}}</p></header>
<main><div class="grid">{{PRODUCT_GRID_HTML}}</div></main>
${FOOTER}
</body>
</html>`,
};
for (const [rel, html] of Object.entries(upgraded2)) {
const [skill, ...rest] = rel.split('/');
writeSkillFile(skill, rest.join('/'), html);
}
console.log(`Upgraded ${Object.keys(upgraded2).length} templates (batch 2/3)`);
const newTemplates = {
'page-template-saas': {
templateFile: 'saas-landing.html',
label: 'SaaS 产品页',
description: '渐变 Hero + 功能特性 + 定价区,适合 B2B 软件落地页',
sortOrder: 140,
priceCents: 1290,
previewSvg: 'saas-landing',
html: `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title><meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; --accent2: {{ACCENT2}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: #06080f; color: #e8edf5; }
.hero { padding: clamp(64px, 12vw, 100px) 24px; text-align: center; background: radial-gradient(ellipse 80% 50% at 50% -20%, rgba(99,102,241,.35), transparent), linear-gradient(180deg, #0f1424, #06080f); }
.badge { display: inline-block; padding: 6px 14px; border-radius: 999px; background: rgba(99,102,241,.15); color: #a5b4fc; font-size: 12px; font-weight: 700; letter-spacing: .1em; }
h1 { margin: 20px auto 16px; max-width: 720px; font-size: clamp(36px, 7vw, 56px); font-weight: 800; letter-spacing: -.03em; line-height: 1.08; }
.lead { max-width: 540px; margin: 0 auto 32px; color: #94a3b8; font-size: 18px; line-height: 1.7; }
.cta { display: inline-flex; padding: 16px 36px; border-radius: 12px; background: linear-gradient(135deg, var(--accent), var(--accent2)); color: #fff; text-decoration: none; font-weight: 700; box-shadow: 0 16px 48px rgba(99,102,241,.35); }
.hero-img { max-width: 960px; margin: 48px auto 0; padding: 0 24px; }
.hero-img img { width: 100%; border-radius: 16px; border: 1px solid rgba(255,255,255,.08); box-shadow: 0 40px 80px rgba(0,0,0,.5); }
section { max-width: 960px; margin: 0 auto; padding: clamp(48px, 8vw, 72px) 24px; }
.features { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.feature { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.08); border-radius: 16px; padding: 24px; }
.pricing { background: rgba(255,255,255,.03); border-radius: 24px; padding: 32px; border: 1px solid rgba(255,255,255,.06); }
footer { text-align: center; padding: 40px 24px 56px; color: #64748b; font-size: 13px; }
</style>
</head>
<body>
<header class="hero">
<span class="badge">{{PRODUCT_NAME}}</span>
<h1>{{HERO_HEADLINE}}</h1>
<p class="lead">{{HERO_SUBTITLE}}</p>
<a class="cta" href="{{CTA_URL}}">{{CTA_LABEL}}</a>
<div class="hero-img"><img src="{{HERO_IMAGE}}" alt="{{PRODUCT_NAME}}"></div>
</header>
<section><div class="features">{{FEATURES_HTML}}</div></section>
<section><div class="pricing">{{PRICING_HTML}}</div></section>
${FOOTER}
</body>
</html>`,
},
'page-template-hotel': {
templateFile: 'hotel-retreat.html',
label: '酒店民宿',
description: '大图 Hero + 设施亮点 + 房型卡片,适合精品酒店与民宿',
sortOrder: 150,
priceCents: 1190,
previewSvg: 'hotel-retreat',
html: `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title><meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; --accent2: {{ACCENT2}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: "Songti SC", Georgia, serif; background: #faf8f5; color: #2c2419; }
.hero { min-height: 70vh; display: grid; align-items: end; padding: clamp(32px, 7vw, 72px); background: linear-gradient(180deg, transparent 30%, rgba(44,36,25,.85)), url('{{HERO_IMAGE}}') center/cover; color: #fff; }
.eyebrow { font-family: system-ui, sans-serif; font-size: 11px; letter-spacing: .25em; color: var(--accent2); font-weight: 700; }
h1 { margin: 12px 0 8px; font-size: clamp(36px, 7vw, 56px); font-weight: 400; letter-spacing: .04em; }
.tagline { font-family: system-ui, sans-serif; font-size: 17px; opacity: .9; max-width: 32rem; line-height: 1.65; }
main { max-width: 880px; margin: 0 auto; padding: clamp(40px, 8vw, 64px) 24px; }
.amenities { margin-bottom: 48px; line-height: 1.85; }
.amenities h2 { font-family: system-ui, sans-serif; font-size: 13px; letter-spacing: .16em; color: var(--accent); margin: 0 0 16px; }
.rooms { line-height: 1.8; }
.rooms h2 { font-family: system-ui, sans-serif; font-size: 22px; margin: 0 0 20px; }
.book { display: inline-block; margin-top: 32px; padding: 16px 40px; background: var(--accent); color: #fff; text-decoration: none; border-radius: 4px; font-family: system-ui, sans-serif; font-weight: 700; letter-spacing: .06em; }
footer { text-align: center; padding: 40px 24px; color: #a89882; font-size: 13px; font-family: system-ui, sans-serif; }
</style>
</head>
<body>
<header class="hero">
<div><div class="eyebrow">{{HOTEL_NAME}}</div><h1>{{HOTEL_TAGLINE}}</h1></div>
</header>
<main>
<div class="amenities">{{AMENITIES_HTML}}</div>
<div class="rooms">{{ROOMS_HTML}}</div>
<a class="book" href="{{BOOKING_CTA_URL}}">{{BOOKING_CTA_LABEL}}</a>
</main>
${FOOTER}
</body>
</html>`,
},
'page-template-agency': {
templateFile: 'agency-studio.html',
label: '创意机构',
description: '极简大标题 + 服务列表 + 案例展示,适合设计/广告工作室',
sortOrder: 160,
priceCents: 1090,
previewSvg: 'agency-studio',
html: `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title><meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: #fff; color: #111; }
header { padding: clamp(64px, 14vw, 120px) 24px 48px; max-width: 1100px; margin: 0 auto; border-bottom: 1px solid #eee; }
h1 { margin: 0 0 12px; font-size: clamp(40px, 9vw, 80px); font-weight: 900; letter-spacing: -.04em; line-height: .95; }
.tagline { margin: 0; font-size: clamp(18px, 3vw, 24px); color: #666; max-width: 36rem; line-height: 1.5; }
main { max-width: 1100px; margin: 0 auto; padding: clamp(48px, 8vw, 80px) 24px; }
.services { margin-bottom: 64px; }
.services h2, .showcase h2, .contact h2 { font-size: 13px; letter-spacing: .2em; text-transform: uppercase; color: var(--accent); margin: 0 0 24px; }
.showcase { margin-bottom: 64px; line-height: 1.75; }
.contact { color: #444; line-height: 1.8; }
footer { padding: 48px 24px; text-align: center; color: #999; font-size: 13px; border-top: 1px solid #eee; }
</style>
</head>
<body>
<header><h1>{{AGENCY_NAME}}</h1><p class="tagline">{{AGENCY_TAGLINE}}</p></header>
<main>
<div class="services">{{SERVICES_HTML}}</div>
<div class="showcase">{{SHOWCASE_HTML}}</div>
<div class="contact">{{CONTACT_HTML}}</div>
</main>
${FOOTER}
</body>
</html>`,
},
'page-template-photography': {
templateFile: 'photo-gallery.html',
label: '摄影画廊',
description: '全屏 Hero + 瀑布流作品区,适合摄影师与视觉艺术家',
sortOrder: 170,
priceCents: 990,
previewSvg: 'photo-gallery',
html: `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title><meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0a0a0a; color: #f5f5f5; }
.hero { min-height: 55vh; display: grid; place-items: center; text-align: center; padding: 48px 24px; background: linear-gradient(rgba(0,0,0,.4), rgba(0,0,0,.7)), url('{{HERO_IMAGE}}') center/cover; }
h1 { margin: 0 0 12px; font-size: clamp(32px, 6vw, 48px); font-weight: 300; letter-spacing: .15em; text-transform: uppercase; }
.bio { max-width: 480px; margin: 0 auto; color: #ccc; line-height: 1.75; font-size: 16px; font-weight: 300; }
main { max-width: 1200px; margin: 0 auto; padding: clamp(40px, 6vw, 64px) 20px 80px; }
.gallery { columns: 2; column-gap: 16px; }
@media (min-width: 768px) { .gallery { columns: 3; column-gap: 20px; } }
.gallery figure { break-inside: avoid; margin: 0 0 16px; border-radius: 4px; overflow: hidden; }
.gallery img { width: 100%; display: block; }
.gallery figcaption { padding: 10px 12px; background: #141414; font-size: 13px; color: #999; }
footer { text-align: center; padding: 32px; color: #555; font-size: 12px; letter-spacing: .1em; }
</style>
</head>
<body>
<header class="hero"><div><h1>{{PHOTOGRAPHER_NAME}}</h1><p class="bio">{{PHOTOGRAPHER_BIO}}</p></div></header>
<main><div class="gallery">{{GALLERY_HTML}}</div></main>
${FOOTER}
</body>
</html>`,
},
'page-template-podcast': {
templateFile: 'podcast-show.html',
label: '播客节目',
description: '封面 Hero + 单集列表 + 订阅引导,适合播客与音频栏目',
sortOrder: 180,
priceCents: 890,
previewSvg: 'podcast-show',
html: `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title><meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; --accent2: {{ACCENT2}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: linear-gradient(165deg, #1a0a2e, #0f0f14); color: #f1f5f9; }
.hero { display: grid; grid-template-columns: auto 1fr; gap: clamp(24px, 4vw, 40px); align-items: center; padding: clamp(40px, 8vw, 72px) 24px; max-width: 880px; margin: 0 auto; }
.cover { width: clamp(140px, 28vw, 220px); aspect-ratio: 1; border-radius: 20px; object-fit: cover; box-shadow: 0 24px 64px rgba(139,92,246,.3); }
h1 { margin: 0 0 8px; font-size: clamp(28px, 5vw, 40px); font-weight: 800; }
.tagline { margin: 0; color: #a78bfa; font-size: 16px; font-weight: 600; }
main { max-width: 880px; margin: 0 auto; padding: 0 24px 64px; }
.episodes { margin-bottom: 40px; }
.episodes h2 { font-size: 13px; letter-spacing: .14em; text-transform: uppercase; color: var(--accent2); margin: 0 0 20px; }
.episode { padding: 20px; background: rgba(255,255,255,.05); border-radius: 16px; margin-bottom: 12px; border: 1px solid rgba(255,255,255,.06); }
.subscribe { text-align: center; padding: 32px; background: linear-gradient(135deg, rgba(139,92,246,.2), rgba(99,102,241,.1)); border-radius: 20px; }
footer { text-align: center; padding: 32px; color: #64748b; font-size: 13px; }
</style>
</head>
<body>
<header class="hero">
<img class="cover" src="{{COVER_IMAGE}}" alt="{{SHOW_NAME}}">
<div><h1>{{SHOW_NAME}}</h1><p class="tagline">{{SHOW_TAGLINE}}</p></div>
</header>
<main>
<div class="episodes">{{EPISODES_HTML}}</div>
<div class="subscribe">{{SUBSCRIBE_HTML}}</div>
</main>
${FOOTER}
</body>
</html>`,
},
'page-template-charity': {
templateFile: 'charity-cause.html',
label: '公益募捐',
description: '情感 Hero + 项目故事 + 捐赠 CTA,适合公益与 CSR 活动',
sortOrder: 190,
priceCents: 0,
previewSvg: 'charity-cause',
html: `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title><meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: #fefdfb; color: #1c1917; }
.hero { min-height: 60vh; display: grid; align-items: end; padding: clamp(32px, 7vw, 64px); background: linear-gradient(180deg, transparent 20%, rgba(28,25,23,.75)), url('{{HERO_IMAGE}}') center/cover; color: #fff; }
h1 { margin: 0 0 12px; font-size: clamp(32px, 6vw, 48px); font-weight: 800; line-height: 1.15; max-width: 640px; }
.subtitle { margin: 0; font-size: 18px; opacity: .92; max-width: 520px; line-height: 1.65; }
main { max-width: 720px; margin: 0 auto; padding: clamp(40px, 8vw, 64px) 24px; }
.impact { background: #fff; border-radius: 20px; padding: 28px; box-shadow: 0 16px 48px rgba(28,25,23,.06); margin-bottom: 32px; line-height: 1.85; }
.story { line-height: 1.9; color: #44403c; margin-bottom: 32px; }
.donate { display: block; text-align: center; padding: 18px 36px; background: var(--accent); color: #fff; text-decoration: none; border-radius: 999px; font-weight: 800; font-size: 17px; box-shadow: 0 12px 32px rgba(220,38,38,.25); }
footer { text-align: center; padding: 40px 24px; color: #a8a29e; font-size: 13px; }
</style>
</head>
<body>
<header class="hero"><div><h1>{{CAUSE_TITLE}}</h1><p class="subtitle">{{CAUSE_SUBTITLE}}</p></div></header>
<main>
<div class="impact">{{IMPACT_HTML}}</div>
<div class="story">{{STORY_HTML}}</div>
<a class="donate" href="{{DONATE_CTA_URL}}">{{DONATE_CTA_LABEL}}</a>
</main>
${FOOTER}
</body>
</html>`,
},
'page-template-startup': {
templateFile: 'startup-pitch.html',
label: '创业融资',
description: 'Pitch Deck 风格单页:愿景 + 数据指标 + 团队 + CTA',
sortOrder: 200,
priceCents: 1490,
previewSvg: 'startup-pitch',
html: `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{PAGE_TITLE}}</title><meta name="description" content="{{PAGE_DESCRIPTION}}">
<meta name="mindspace-cover" content='{{MINDSPACE_COVER_JSON}}'>
<style>
:root { --accent: {{ACCENT}}; --accent2: {{ACCENT2}}; }
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", sans-serif; background: #030712; color: #f8fafc; }
.hero { padding: clamp(64px, 12vw, 100px) 24px; text-align: center; background: radial-gradient(ellipse 70% 50% at 50% 0%, rgba(56,189,248,.15), transparent), #030712; }
.startup { font-size: 13px; letter-spacing: .2em; color: var(--accent); font-weight: 800; margin-bottom: 16px; }
h1 { margin: 0 auto 16px; max-width: 760px; font-size: clamp(34px, 7vw, 52px); font-weight: 800; letter-spacing: -.03em; line-height: 1.1; }
.pitch-sub { max-width: 560px; margin: 0 auto 36px; color: #94a3b8; font-size: 18px; line-height: 1.7; }
.cta { display: inline-flex; padding: 16px 32px; border-radius: 10px; background: linear-gradient(135deg, var(--accent), var(--accent2)); color: #fff; text-decoration: none; font-weight: 700; }
main { max-width: 960px; margin: 0 auto; padding: clamp(40px, 8vw, 72px) 24px; }
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; margin-bottom: 48px; }
.metric { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.08); border-radius: 16px; padding: 24px; text-align: center; }
.section { margin-bottom: 48px; line-height: 1.8; }
.section h2 { font-size: 13px; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); margin: 0 0 16px; }
footer { text-align: center; padding: 40px 24px; color: #475569; font-size: 13px; }
</style>
</head>
<body>
<header class="hero">
<p class="startup">{{STARTUP_NAME}}</p>
<h1>{{PITCH_HEADLINE}}</h1>
<p class="pitch-sub">{{PITCH_SUBTITLE}}</p>
<a class="cta" href="{{CTA_URL}}">{{CTA_LABEL}}</a>
</header>
<main>
<div class="metrics">{{METRICS_HTML}}</div>
<div class="section">{{VISION_HTML}}</div>
<div class="section">{{TEAM_HTML}}</div>
</main>
${FOOTER}
</body>
</html>`,
},
};
function skillYaml(name, meta) {
return `name: ${name}
version: 1.0.0
label: ${meta.label}
description: ${meta.description}
catalog:
label: ${meta.label}
description: ${meta.description}
previewImage: /assets/template-previews/${meta.previewSvg}.svg
priceCents: ${meta.priceCents}
billingMode: ${meta.priceCents > 0 ? 'one_time' : 'free'}
sortOrder: ${meta.sortOrder}
trigger:
keywords:
- ${meta.label}
router:
promptKey: ${name}
priority: 25
executors:
- goose
`;
}
function skillMd(name, meta, templateFile) {
return `---
name: ${name}
description: ${meta.description}
---
# ${meta.label}
1. load_skill → \`${name}\`
2. read_file → \`.agents/skills/${name}/templates/${templateFile}\`
3. 替换全部占位符后 write_file → \`public/*.html\`
4. 遵守 static-page-publish 回复 Markdown 链接
`;
}
function previewSvg(title, subtitle, color1, color2) {
return `<svg xmlns="http://www.w3.org/2000/svg" width="640" height="360" viewBox="0 0 640 360" role="img" aria-label="${title}预览">
<defs><linearGradient id="g" x1="0" y1="0" x2="1" y2="1"><stop offset="0%" stop-color="${color1}"/><stop offset="100%" stop-color="${color2}"/></linearGradient></defs>
<rect width="640" height="360" fill="url(#g)"/>
<rect x="40" y="200" width="360" height="100" rx="16" fill="rgba(255,255,255,0.12)"/>
<text x="56" y="240" fill="rgba(255,255,255,0.7)" font-family="system-ui,sans-serif" font-size="12" font-weight="700">${subtitle}</text>
<text x="56" y="278" fill="#fff" font-family="system-ui,sans-serif" font-size="26" font-weight="800">${title}</text>
</svg>`;
}
const previewColors = {
'saas-landing': ['#312e81', '#0f172a'],
'hotel-retreat': ['#78350f', '#1c1917'],
'agency-studio': ['#f5f5f5', '#e5e5e5'],
'photo-gallery': ['#171717', '#0a0a0a'],
'podcast-show': ['#4c1d95', '#0f0f14'],
'charity-cause': ['#fef3c7', '#fde68a'],
'startup-pitch': ['#0c4a6e', '#030712'],
};
for (const [skillName, meta] of Object.entries(newTemplates)) {
writeSkillFile(skillName, `templates/${meta.templateFile}`, meta.html);
writeSkillFile(skillName, 'skill.yaml', skillYaml(skillName, meta));
writeSkillFile(skillName, 'SKILL.md', skillMd(skillName, meta, meta.templateFile));
const [c1, c2] = previewColors[meta.previewSvg];
writePreview(`${meta.previewSvg}.svg`, previewSvg(meta.label, 'Premium Template', c1, c2));
}
console.log(`Created ${Object.keys(newTemplates).length} new template skills (batch 3/3)`);
console.log('Done. Update chat-skills.mjs, skills-registry.mjs, page-template-catalog.mjs demos, and test count.');