root 651cc9e1fd D121: xiaohongshu-cover module v5 complete
MODULE-COVER-001: full package for external AI consumption
- server.js + renderer.js + generate.js + config.js
- templates/ (5 templates: xiaohongshu + dynamic + jike + poster + registry)
- package.json + README.md + MODULE.hdlp
- INDEX.hdlp + SYSTEM.hdlp (HLDP declarations)
- Fonts: Noto Sans CJK SC priority (no tofu blocks)
- No domain watermark
- Updated module-registry.json
- Copyright 2026-A-00037559
2026-06-01 16:36:00 +08:00

191 lines
4.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* ═══════════════════════════════════════════════════
* 即刻卡片模板 · 1080×1080 (1:1)
* ═══════════════════════════════════════════════════
*/
import { STYLES } from '../config.js'
const W = STYLES.sizes.jike.width
const H = STYLES.sizes.jike.height
/**
* 生成即刻卡片 HTML
* @param {object} data
* @param {string} data.title - 标题/核心观点
* @param {string} data.body - 正文
* @param {string} data.meta - 元信息如「2026-05 · 思考碎片」)
* @param {string} data.emoji - 封面 emoji可选
* @param {'default'|'quote'|'minimal'} data.layout - 布局
*/
export function jikeCard(data) {
const {
title = '',
body = '',
meta = '',
emoji = '',
layout = 'default',
} = data
const C = STYLES.colors
const F = STYLES.fonts
const T = STYLES.typography
const bodyLines = body.split('\n').filter(Boolean)
const bodyHtml = bodyLines.map(line => `<p>${line}</p>`).join('\n')
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
@import url('https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap');
body {
width: ${W}px;
height: ${H}px;
overflow: hidden;
background: ${C.bg};
font-family: ${F.body};
display: flex;
flex-direction: column;
position: relative;
}
/* 顶部渐变装饰条 */
.accent-bar {
height: 6px;
background: linear-gradient(90deg, ${C.accent}, ${C.highlight}, ${C.gold});
}
.container {
flex: 1;
padding: 48px 56px;
display: flex;
flex-direction: column;
}
.meta {
font-size: ${T.captionSize}px;
color: ${C.textMuted};
letter-spacing: 2px;
margin-bottom: 16px;
}
.emoji-row {
font-size: 64px;
margin-bottom: 16px;
line-height: 1;
}
.title {
font-family: ${F.title};
font-size: 40px;
font-weight: 700;
line-height: 1.4;
color: ${C.primary};
margin-bottom: 20px;
letter-spacing: 1px;
}
.body {
flex: 1;
font-size: 26px;
line-height: 1.7;
color: ${C.text};
}
.body p {
margin-bottom: 10px;
}
/* 金句布局 */
.quote-section {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
padding: 0 32px;
}
.quote-emoji {
font-size: 72px;
margin-bottom: 20px;
}
.quote-line {
width: 40px;
height: 2px;
background: ${C.gold};
margin: 0 auto 24px;
}
.quote-title {
font-family: ${F.title};
font-size: 36px;
font-weight: 600;
line-height: 1.5;
color: ${C.primary};
letter-spacing: 2px;
}
.quote-body {
margin-top: 20px;
font-size: 24px;
color: ${C.textMuted};
line-height: 1.6;
}
/* 底部 */
.footer {
padding: 20px 56px 28px;
display: flex;
justify-content: space-between;
align-items: center;
border-top: 1px solid ${C.divider};
font-size: ${T.captionSize}px;
color: ${C.textMuted};
}
.brand {
opacity: ${STYLES.brand.opacity};
}
</style>
</head>
<body>
<div class="accent-bar"></div>
<div class="container">
${meta ? `<div class="meta">${meta}</div>` : ''}
${layout === 'quote' ? `
<div class="quote-section">
${emoji ? `<div class="quote-emoji">${emoji}</div>` : ''}
<div class="quote-line"></div>
<div class="quote-title">${title}</div>
${body ? `<div class="quote-body">${body}</div>` : ''}
</div>
` : `
${emoji ? `<div class="emoji-row">${emoji}</div>` : ''}
<div class="title">${title}</div>
<div class="body">${bodyHtml}</div>
`}
</div>
<div class="footer">
<span class="brand">${STYLES.brand.text}</span>
<span>即刻 · Jike</span>
</div>
</body>
</html>`
}