排版引擎大升级:CJK修复 + 外链脚注 + 暗黑模式 + 容器语法 + 16主题 + 画廊UI
converter.py 新增 6 项能力: - CJK-Latin 自动加空格(中英混排更易读) - 加粗标点外移(修复微信渲染 bug) - ul/ol 转 section(微信原生列表不稳定) - 外链→编号脚注 + 文末参考链接(微信屏蔽外链) - data-darkmode-* 属性注入(适配微信暗黑模式) - :::dialogue / :::timeline / :::callout / :::quote 容器语法 主题系统: - 从 4 个扩充到 16 个(含字节/少数派/报纸/包豪斯/水墨/午夜等风格) - 所有主题新增 darkmode 色值 - 新增 gallery 命令:浏览器内 16 主题并排预览 + 一键复制 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d4ca5ba9ef
commit
2fa0d7fa6d
18 changed files with 2909 additions and 0 deletions
166
toolkit/cli.py
166
toolkit/cli.py
|
|
@ -142,6 +142,164 @@ def cmd_themes(args):
|
|||
print(f" {name:24s} {theme.description}")
|
||||
|
||||
|
||||
def cmd_gallery(args):
|
||||
"""Render all themes side by side in a browser gallery."""
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
# Use provided markdown or a built-in sample
|
||||
if args.input:
|
||||
md_text = Path(args.input).read_text(encoding="utf-8")
|
||||
else:
|
||||
md_text = _gallery_sample_markdown()
|
||||
|
||||
names = list_themes()
|
||||
results = {}
|
||||
|
||||
def render_theme(name):
|
||||
theme = load_theme(name)
|
||||
converter = WeChatConverter(theme=theme)
|
||||
result = converter.convert(md_text)
|
||||
return name, theme.description, result.html
|
||||
|
||||
# Parallel rendering
|
||||
with ThreadPoolExecutor(max_workers=8) as pool:
|
||||
for name, desc, html in pool.map(lambda n: render_theme(n), names):
|
||||
results[name] = (desc, html)
|
||||
|
||||
# Build gallery HTML
|
||||
gallery_html = _build_gallery_html(results, names)
|
||||
output = args.output or "/tmp/wewrite-gallery.html"
|
||||
Path(output).write_text(gallery_html, encoding="utf-8")
|
||||
print(f"Gallery: {output} ({len(names)} themes)")
|
||||
|
||||
if not args.no_open:
|
||||
webbrowser.open(f"file://{Path(output).absolute()}")
|
||||
|
||||
|
||||
def _gallery_sample_markdown():
|
||||
return """# 示例文章标题
|
||||
|
||||
## 第一部分
|
||||
|
||||
这是一段正常的文章内容,用来展示不同主题的排版效果。WeWrite 支持多种排版主题,每种都有独特的视觉风格。
|
||||
|
||||
说实话,选主题这件事——看截图永远不如看实际渲染效果。
|
||||
|
||||
## 关键数据
|
||||
|
||||
| 指标 | 数值 | 变化 |
|
||||
|------|------|------|
|
||||
| 阅读量 | 12,580 | +23% |
|
||||
| 分享率 | 4.7% | +0.8% |
|
||||
| 完读率 | 68% | -2% |
|
||||
|
||||
## 代码示例
|
||||
|
||||
```python
|
||||
def hello():
|
||||
print("Hello, WeWrite!")
|
||||
```
|
||||
|
||||
> 好的排版不是让读者注意到设计,而是让读者忘记设计,只记住内容。
|
||||
|
||||
## 列表展示
|
||||
|
||||
- 第一个要点:简洁是设计的灵魂
|
||||
- 第二个要点:一致性比创意更重要
|
||||
- 第三个要点:移动端体验优先
|
||||
|
||||
**加粗文本**和*斜体文本*的样式也需要关注。
|
||||
|
||||
最后这段用来展示文章结尾的留白和间距效果。一篇好文章的结尾,应该像一首好歌的最后一个音符——恰到好处地收束。
|
||||
"""
|
||||
|
||||
|
||||
def _join_newline(items):
|
||||
"""Join items with comma + newline (workaround for f-string limitation)."""
|
||||
return ",\n".join(items)
|
||||
|
||||
|
||||
def _build_gallery_html(results, names):
|
||||
cards = []
|
||||
for name in names:
|
||||
desc, html = results[name]
|
||||
# Escape for embedding in JS
|
||||
escaped_html = html.replace('\\', '\\\\').replace('`', '\\`').replace('$', '\\$')
|
||||
cards.append(f"""
|
||||
<div class="theme-card" onclick="selectTheme('{name}')">
|
||||
<div class="theme-name">{name}</div>
|
||||
<div class="theme-desc">{desc}</div>
|
||||
<div class="phone-frame">
|
||||
<div class="phone-content" id="preview-{name}">{html}</div>
|
||||
</div>
|
||||
<button class="copy-btn" onclick="event.stopPropagation(); copyHTML('{name}')">复制 HTML</button>
|
||||
</div>""")
|
||||
|
||||
# Store HTML data for copy
|
||||
data_entries = []
|
||||
for name in names:
|
||||
desc, html = results[name]
|
||||
safe = html.replace('\\', '\\\\').replace("'", "\\'").replace('\n', '\\n')
|
||||
data_entries.append(f" '{name}': '{safe}'")
|
||||
|
||||
return f"""<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>WeWrite 主题画廊</title>
|
||||
<style>
|
||||
* {{ margin: 0; padding: 0; box-sizing: border-box; }}
|
||||
body {{ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0f0f0f; color: #fff; }}
|
||||
.header {{ text-align: center; padding: 40px 20px 20px; }}
|
||||
.header h1 {{ font-size: 28px; font-weight: 700; }}
|
||||
.header p {{ color: #888; margin-top: 8px; font-size: 15px; }}
|
||||
.grid {{ display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 24px; padding: 24px; max-width: 1440px; margin: 0 auto; }}
|
||||
.theme-card {{ background: #1a1a1a; border-radius: 12px; padding: 16px; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; }}
|
||||
.theme-card:hover {{ transform: translateY(-4px); box-shadow: 0 8px 24px rgba(0,0,0,0.4); }}
|
||||
.theme-name {{ font-size: 16px; font-weight: 700; margin-bottom: 4px; }}
|
||||
.theme-desc {{ font-size: 13px; color: #888; margin-bottom: 12px; }}
|
||||
.phone-frame {{ background: #fff; border-radius: 8px; overflow: hidden; max-height: 480px; overflow-y: auto; }}
|
||||
.phone-content {{ padding: 16px; font-size: 14px; transform: scale(0.85); transform-origin: top left; width: 118%; }}
|
||||
.copy-btn {{ margin-top: 12px; width: 100%; padding: 8px; background: #333; color: #fff; border: none; border-radius: 6px; cursor: pointer; font-size: 14px; }}
|
||||
.copy-btn:hover {{ background: #555; }}
|
||||
.toast {{ position: fixed; bottom: 40px; left: 50%; transform: translateX(-50%); background: #333; color: #fff; padding: 10px 24px; border-radius: 8px; font-size: 14px; display: none; z-index: 999; }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>WeWrite 主题画廊</h1>
|
||||
<p>{len(names)} 个主题 · 点击卡片查看大图 · 点击「复制 HTML」直接粘贴到公众号编辑器</p>
|
||||
</div>
|
||||
<div class="grid">
|
||||
{''.join(cards)}
|
||||
</div>
|
||||
<div class="toast" id="toast">已复制到剪贴板</div>
|
||||
<script>
|
||||
const themeData = {{
|
||||
{_join_newline(data_entries)}
|
||||
}};
|
||||
function copyHTML(name) {{
|
||||
const html = themeData[name];
|
||||
if (html) {{
|
||||
navigator.clipboard.writeText(html).then(() => {{
|
||||
const t = document.getElementById('toast');
|
||||
t.style.display = 'block';
|
||||
setTimeout(() => t.style.display = 'none', 1500);
|
||||
}});
|
||||
}}
|
||||
}}
|
||||
function selectTheme(name) {{
|
||||
localStorage.setItem('wewrite-theme', name);
|
||||
// Scroll to card for visual feedback
|
||||
const el = document.getElementById('preview-' + name);
|
||||
if (el) el.scrollIntoView({{ behavior: 'smooth', block: 'center' }});
|
||||
}}
|
||||
</script>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="wewrite",
|
||||
|
|
@ -169,6 +327,12 @@ def main():
|
|||
# themes
|
||||
sub.add_parser("themes", help="List available themes")
|
||||
|
||||
# gallery
|
||||
p_gallery = sub.add_parser("gallery", help="Open theme gallery in browser")
|
||||
p_gallery.add_argument("input", nargs="?", default=None, help="Markdown file (optional, uses sample if omitted)")
|
||||
p_gallery.add_argument("-o", "--output", help="Output HTML file path")
|
||||
p_gallery.add_argument("--no-open", action="store_true", help="Don't open browser")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
|
|
@ -178,6 +342,8 @@ def main():
|
|||
cmd_publish(args)
|
||||
elif args.command == "themes":
|
||||
cmd_themes(args)
|
||||
elif args.command == "gallery":
|
||||
cmd_gallery(args)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ class WeChatConverter:
|
|||
title = self._extract_title(markdown_text)
|
||||
markdown_text = self._strip_h1(markdown_text)
|
||||
|
||||
# Pre-process container blocks (:::dialogue, :::timeline, etc.)
|
||||
markdown_text = self._preprocess_containers(markdown_text)
|
||||
|
||||
# CJK fix: auto-space between CJK and Latin characters
|
||||
markdown_text = self._fix_cjk_spacing(markdown_text)
|
||||
|
||||
# Parse Markdown → HTML
|
||||
html = self._markdown_to_html(markdown_text)
|
||||
|
||||
|
|
@ -58,12 +64,24 @@ class WeChatConverter:
|
|||
# Process images (ensure responsive styling)
|
||||
html, images = self._process_images(html)
|
||||
|
||||
# CJK fix: move punctuation outside bold tags
|
||||
html = self._fix_cjk_bold_punctuation(html)
|
||||
|
||||
# CJK fix: convert ul/ol to section-based lists (WeChat renders native lists unreliably)
|
||||
html = self._convert_lists_to_sections(html)
|
||||
|
||||
# Convert external links to footnotes (WeChat blocks external links)
|
||||
html = self._convert_links_to_footnotes(html)
|
||||
|
||||
# Apply inline CSS from theme
|
||||
html = self._apply_inline_styles(html)
|
||||
|
||||
# Apply WeChat compatibility fixes
|
||||
html = self._apply_wechat_fixes(html)
|
||||
|
||||
# Inject dark mode attributes
|
||||
html = self._inject_darkmode(html)
|
||||
|
||||
# Generate digest from plain text
|
||||
digest = self._generate_digest(html)
|
||||
|
||||
|
|
@ -201,6 +219,294 @@ class WeChatConverter:
|
|||
|
||||
return str(soup)
|
||||
|
||||
# -- CJK compatibility fixes --
|
||||
|
||||
def _fix_cjk_spacing(self, text: str) -> str:
|
||||
"""Auto-insert thin space between CJK and Latin/digit characters.
|
||||
|
||||
WeChat renders CJK-Latin without spacing, making mixed text hard to read.
|
||||
This inserts a thin space (U+200A) at CJK↔Latin boundaries.
|
||||
Runs on raw Markdown before parsing, skipping code blocks and links.
|
||||
"""
|
||||
# CJK unicode ranges
|
||||
cjk = r'[\u4e00-\u9fff\u3400-\u4dbf\u3000-\u303f\uff00-\uffef]'
|
||||
latin = r'[A-Za-z0-9]'
|
||||
|
||||
lines = text.split('\n')
|
||||
result = []
|
||||
in_code_block = False
|
||||
|
||||
for line in lines:
|
||||
if line.strip().startswith('```'):
|
||||
in_code_block = not in_code_block
|
||||
result.append(line)
|
||||
continue
|
||||
if in_code_block:
|
||||
result.append(line)
|
||||
continue
|
||||
|
||||
# CJK followed by Latin
|
||||
line = re.sub(f'({cjk})({latin})', r'\1 \2', line)
|
||||
# Latin followed by CJK
|
||||
line = re.sub(f'({latin})({cjk})', r'\1 \2', line)
|
||||
result.append(line)
|
||||
|
||||
return '\n'.join(result)
|
||||
|
||||
def _fix_cjk_bold_punctuation(self, html: str) -> str:
|
||||
"""Move Chinese punctuation outside bold/strong tags.
|
||||
|
||||
WeChat renders bold CJK punctuation with ugly spacing.
|
||||
Move trailing punctuation (,。!?;:、) outside </strong>.
|
||||
"""
|
||||
# Match: <strong>内容+中文标点</strong> → <strong>内容</strong>标点
|
||||
pattern = r'(<strong>)(.*?)([,。!?;:、]+)(</strong>)'
|
||||
return re.sub(pattern, r'\1\2\4\3', html)
|
||||
|
||||
def _convert_lists_to_sections(self, html: str) -> str:
|
||||
"""Convert <ul>/<ol> to styled <section> elements.
|
||||
|
||||
WeChat's native list rendering is unreliable (inconsistent bullet
|
||||
style, broken indentation on some devices). Using section+span
|
||||
for bullets/numbers gives full control over appearance.
|
||||
"""
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
text_color = self._theme.colors.get("text", "#333333")
|
||||
primary = self._theme.colors.get("primary", "#2563eb")
|
||||
|
||||
for ul in soup.find_all("ul"):
|
||||
section = soup.new_tag("section")
|
||||
for li in ul.find_all("li", recursive=False):
|
||||
item = soup.new_tag("section", style=f"display: flex; align-items: flex-start; margin-bottom: 8px; color: {text_color}")
|
||||
bullet = soup.new_tag("span", style=f"color: {primary}; margin-right: 8px; flex-shrink: 0; font-size: 18px; line-height: 1.6")
|
||||
bullet.string = "•"
|
||||
content = soup.new_tag("span", style="flex: 1")
|
||||
for child in list(li.children):
|
||||
content.append(child.extract() if hasattr(child, 'extract') else child)
|
||||
item.append(bullet)
|
||||
item.append(content)
|
||||
section.append(item)
|
||||
ul.replace_with(section)
|
||||
|
||||
for idx, ol in enumerate(soup.find_all("ol")):
|
||||
section = soup.new_tag("section")
|
||||
for num, li in enumerate(ol.find_all("li", recursive=False), 1):
|
||||
item = soup.new_tag("section", style=f"display: flex; align-items: flex-start; margin-bottom: 8px; color: {text_color}")
|
||||
number = soup.new_tag("span", style=f"color: {primary}; margin-right: 8px; flex-shrink: 0; font-weight: 700; line-height: 1.8")
|
||||
number.string = f"{num}."
|
||||
content = soup.new_tag("span", style="flex: 1")
|
||||
for child in list(li.children):
|
||||
content.append(child.extract() if hasattr(child, 'extract') else child)
|
||||
item.append(number)
|
||||
item.append(content)
|
||||
section.append(item)
|
||||
ol.replace_with(section)
|
||||
|
||||
return str(soup)
|
||||
|
||||
# -- External link → footnote conversion --
|
||||
|
||||
def _convert_links_to_footnotes(self, html: str) -> str:
|
||||
"""Convert external <a> links to superscript footnote numbers.
|
||||
|
||||
WeChat blocks external links — readers see dead text. This converts
|
||||
each external link to a superscript number with the URL collected
|
||||
into a reference list appended at the end.
|
||||
"""
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
footnotes = []
|
||||
counter = 0
|
||||
primary = self._theme.colors.get("primary", "#2563eb")
|
||||
|
||||
for a in soup.find_all("a"):
|
||||
href = a.get("href", "")
|
||||
if not href or href.startswith("#"):
|
||||
continue # skip anchors
|
||||
|
||||
counter += 1
|
||||
text = a.get_text()
|
||||
footnotes.append((counter, text, href))
|
||||
|
||||
# Replace <a> with text + superscript number
|
||||
sup = soup.new_tag("sup")
|
||||
sup_link = soup.new_tag("span", style=f"color: {primary}; font-size: 12px")
|
||||
sup_link.string = f"[{counter}]"
|
||||
sup.append(sup_link)
|
||||
a.replace_with(text, sup)
|
||||
|
||||
if footnotes:
|
||||
# Append reference section
|
||||
hr = soup.new_tag("hr", style="border: none; border-top: 1px solid #e5e5e5; margin: 32px 0 16px")
|
||||
soup.append(hr)
|
||||
ref_title = soup.new_tag("p", style="font-size: 13px; color: #999999; margin-bottom: 8px; font-weight: 700")
|
||||
ref_title.string = "参考链接"
|
||||
soup.append(ref_title)
|
||||
for num, text, href in footnotes:
|
||||
ref = soup.new_tag("p", style="font-size: 12px; color: #999999; margin: 2px 0; word-break: break-all")
|
||||
ref.string = f"[{num}] {text}: {href}"
|
||||
soup.append(ref)
|
||||
|
||||
return str(soup)
|
||||
|
||||
# -- Dark mode --
|
||||
|
||||
def _inject_darkmode(self, html: str) -> str:
|
||||
"""Inject data-darkmode-* attributes for WeChat dark mode.
|
||||
|
||||
WeChat auto-inverts colors in dark mode, which often breaks
|
||||
designed color schemes. Explicit darkmode attributes tell WeChat
|
||||
exactly what colors to use instead of guessing.
|
||||
"""
|
||||
darkmode = self._theme.colors.get("darkmode", {})
|
||||
if not darkmode:
|
||||
return html
|
||||
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
dm_text = darkmode.get("text", "#c8c8c8")
|
||||
dm_bg = darkmode.get("background", "#1e1e1e")
|
||||
dm_primary = darkmode.get("primary", "#6aadff")
|
||||
|
||||
# Body-level elements (p, li, section, span)
|
||||
for tag_name in ("p", "span", "section"):
|
||||
for elem in soup.find_all(tag_name):
|
||||
style = elem.get("style", "")
|
||||
# Only set if element has a color
|
||||
if "color" in style:
|
||||
elem["data-darkmode-color"] = dm_text
|
||||
elem["data-darkmode-bgcolor"] = "transparent"
|
||||
|
||||
# Headings
|
||||
dm_heading = darkmode.get("text", "#e0e0e0")
|
||||
for tag_name in ("h1", "h2", "h3", "h4"):
|
||||
for elem in soup.find_all(tag_name):
|
||||
elem["data-darkmode-color"] = dm_heading
|
||||
elem["data-darkmode-bgcolor"] = "transparent"
|
||||
|
||||
# Code blocks
|
||||
dm_code_bg = darkmode.get("code_bg", "#2d2d2d")
|
||||
dm_code_color = darkmode.get("code_color", "#d4d4d4")
|
||||
for pre in soup.find_all("pre"):
|
||||
pre["data-darkmode-bgcolor"] = dm_code_bg
|
||||
pre["data-darkmode-color"] = dm_code_color
|
||||
for code in soup.find_all("code"):
|
||||
code["data-darkmode-color"] = dm_code_color
|
||||
|
||||
# Blockquotes
|
||||
dm_quote_bg = darkmode.get("quote_bg", "#2a2a2a")
|
||||
for bq in soup.find_all("blockquote"):
|
||||
bq["data-darkmode-bgcolor"] = dm_quote_bg
|
||||
bq["data-darkmode-color"] = dm_text
|
||||
|
||||
# Strong/em with primary color
|
||||
for strong in soup.find_all("strong"):
|
||||
strong["data-darkmode-color"] = dm_primary
|
||||
|
||||
return str(soup)
|
||||
|
||||
# -- Container block syntax --
|
||||
|
||||
def _preprocess_containers(self, text: str) -> str:
|
||||
"""Pre-process :::container blocks into styled HTML before Markdown parsing.
|
||||
|
||||
Supports:
|
||||
:::dialogue — chat bubble layout
|
||||
:::timeline — vertical timeline with dots
|
||||
:::callout — Obsidian-style callout (tip/warning/info/danger)
|
||||
:::quote — styled pull quote
|
||||
"""
|
||||
text = self._process_dialogue(text)
|
||||
text = self._process_timeline(text)
|
||||
text = self._process_callout(text)
|
||||
text = self._process_quote_block(text)
|
||||
return text
|
||||
|
||||
def _process_dialogue(self, text: str) -> str:
|
||||
"""Convert :::dialogue blocks to chat bubble HTML."""
|
||||
primary = self._theme.colors.get("primary", "#2563eb")
|
||||
|
||||
def replace_dialogue(match):
|
||||
content = match.group(1).strip()
|
||||
bubbles = []
|
||||
for line in content.split('\n'):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
if line.startswith('> '):
|
||||
# Right-aligned (reply) bubble
|
||||
msg = line[2:].strip()
|
||||
bubbles.append(f'<section style="display: flex; justify-content: flex-end; margin-bottom: 12px">'
|
||||
f'<section style="background: {primary}; color: white; padding: 10px 14px; border-radius: 12px 12px 2px 12px; max-width: 80%; font-size: 15px; line-height: 1.6">{msg}</section></section>')
|
||||
else:
|
||||
# Left-aligned bubble
|
||||
bubbles.append(f'<section style="display: flex; justify-content: flex-start; margin-bottom: 12px">'
|
||||
f'<section style="background: #f3f4f6; color: #333; padding: 10px 14px; border-radius: 12px 12px 12px 2px; max-width: 80%; font-size: 15px; line-height: 1.6">{line}</section></section>')
|
||||
return '\n'.join(bubbles)
|
||||
|
||||
return re.sub(r':::dialogue\n(.*?)\n:::', replace_dialogue, text, flags=re.DOTALL)
|
||||
|
||||
def _process_timeline(self, text: str) -> str:
|
||||
"""Convert :::timeline blocks to vertical timeline HTML."""
|
||||
primary = self._theme.colors.get("primary", "#2563eb")
|
||||
|
||||
def replace_timeline(match):
|
||||
content = match.group(1).strip()
|
||||
items = []
|
||||
for line in content.split('\n'):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
# Format: "**title** description" or just "description"
|
||||
items.append(
|
||||
f'<section style="display: flex; margin-bottom: 16px">'
|
||||
f'<section style="flex-shrink: 0; width: 12px; display: flex; flex-direction: column; align-items: center">'
|
||||
f'<section style="width: 10px; height: 10px; border-radius: 50%; background: {primary}; margin-top: 6px"></section>'
|
||||
f'<section style="width: 2px; flex: 1; background: #e5e7eb; margin-top: 4px"></section>'
|
||||
f'</section>'
|
||||
f'<section style="flex: 1; padding-left: 12px; padding-bottom: 8px; font-size: 15px; line-height: 1.7">{line}</section>'
|
||||
f'</section>'
|
||||
)
|
||||
return '\n'.join(items)
|
||||
|
||||
return re.sub(r':::timeline\n(.*?)\n:::', replace_timeline, text, flags=re.DOTALL)
|
||||
|
||||
def _process_callout(self, text: str) -> str:
|
||||
"""Convert :::callout blocks to styled callout boxes.
|
||||
|
||||
Syntax: :::callout tip/warning/info/danger
|
||||
"""
|
||||
colors_map = {
|
||||
"tip": ("#059669", "#ecfdf5", "💡"),
|
||||
"warning": ("#d97706", "#fffbeb", "⚠️"),
|
||||
"info": ("#2563eb", "#eff6ff", "ℹ️"),
|
||||
"danger": ("#dc2626", "#fef2f2", "🚨"),
|
||||
}
|
||||
|
||||
def replace_callout(match):
|
||||
ctype = match.group(1).strip().lower()
|
||||
content = match.group(2).strip()
|
||||
color, bg, icon = colors_map.get(ctype, colors_map["info"])
|
||||
return (f'<section style="background: {bg}; border-left: 4px solid {color}; '
|
||||
f'padding: 14px 16px; border-radius: 4px; margin: 16px 0; font-size: 15px; line-height: 1.7">'
|
||||
f'<section style="font-weight: 700; color: {color}; margin-bottom: 6px">{icon} {ctype.upper()}</section>'
|
||||
f'{content}</section>')
|
||||
|
||||
return re.sub(r':::callout\s+(\w+)\n(.*?)\n:::', replace_callout, text, flags=re.DOTALL)
|
||||
|
||||
def _process_quote_block(self, text: str) -> str:
|
||||
"""Convert :::quote blocks to styled pull quotes."""
|
||||
primary = self._theme.colors.get("primary", "#2563eb")
|
||||
|
||||
def replace_quote(match):
|
||||
content = match.group(1).strip()
|
||||
return (f'<section style="margin: 24px 0; padding: 20px 24px; border-left: 4px solid {primary}; '
|
||||
f'background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); border-radius: 0 8px 8px 0">'
|
||||
f'<section style="font-size: 18px; line-height: 1.8; color: #333; font-style: italic">'
|
||||
f'"{content}"</section></section>')
|
||||
|
||||
return re.sub(r':::quote\n(.*?)\n:::', replace_quote, text, flags=re.DOTALL)
|
||||
|
||||
# -- Digest generation --
|
||||
|
||||
def _generate_digest(self, html: str, max_bytes: int = 120) -> str:
|
||||
"""Generate a digest that fits within WeChat's byte limit (120 bytes UTF-8)."""
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
|
|
|
|||
207
toolkit/themes/bauhaus.yaml
Normal file
207
toolkit/themes/bauhaus.yaml
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
name: "bauhaus"
|
||||
description: "包豪斯设计风格:纯白底黑色为主,红蓝黄色块点缀,几何感强烈"
|
||||
colors:
|
||||
primary: "#e63226"
|
||||
secondary: "#004592"
|
||||
text: "#1a1a1a"
|
||||
text_light: "#555555"
|
||||
background: "#ffffff"
|
||||
code_bg: "#f0f0f0"
|
||||
code_color: "#004592"
|
||||
quote_border: "#e63226"
|
||||
quote_bg: "#fff5f5"
|
||||
border_radius: "0px"
|
||||
darkmode:
|
||||
background: "#111111"
|
||||
text: "#e8e8e8"
|
||||
text_light: "#a0a0a0"
|
||||
primary: "#f04438"
|
||||
code_bg: "#222222"
|
||||
code_color: "#5b9bd5"
|
||||
quote_bg: "#1e1212"
|
||||
quote_border: "#f04438"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
color: #1a1a1a;
|
||||
background: #ffffff;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 30px;
|
||||
font-weight: 900;
|
||||
color: #1a1a1a;
|
||||
margin: 36px 0 18px 0;
|
||||
padding: 12px 16px;
|
||||
background: #e63226;
|
||||
color: #ffffff;
|
||||
line-height: 1.3;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
color: #004592;
|
||||
margin: 32px 0 14px 0;
|
||||
padding: 8px 0;
|
||||
border-bottom: 4px solid #1a1a1a;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin: 24px 0 12px 0;
|
||||
padding-left: 12px;
|
||||
border-left: 6px solid #f5b700;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
color: #1a1a1a;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 800;
|
||||
color: #e63226;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #f0f0f0;
|
||||
color: #004592;
|
||||
padding: 2px 6px;
|
||||
border-radius: 0px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #1a1a1a;
|
||||
color: #f0f0f0;
|
||||
padding: 16px;
|
||||
border-radius: 0px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
border-left: 6px solid #e63226;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #f0f0f0;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 6px solid #e63226;
|
||||
background: #fff5f5;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
color: #1a1a1a;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #004592;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #004592;
|
||||
color: #ffffff;
|
||||
font-weight: 700;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 2px solid #1a1a1a;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 2px solid #1a1a1a;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 0px;
|
||||
border: 2px solid #1a1a1a;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #004592;
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
border-bottom: 2px solid #f5b700;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
height: 4px;
|
||||
background: #1a1a1a;
|
||||
margin: 28px 0;
|
||||
}
|
||||
198
toolkit/themes/bold-green.yaml
Normal file
198
toolkit/themes/bold-green.yaml
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
name: "bold-green"
|
||||
description: "大胆森林绿风格:白底绿色主色,清新自然,适合环保健康和可持续发展内容"
|
||||
colors:
|
||||
primary: "#16a34a"
|
||||
secondary: "#22c55e"
|
||||
text: "#1a2e1a"
|
||||
text_light: "#4a6a4a"
|
||||
background: "#ffffff"
|
||||
code_bg: "#f0fdf4"
|
||||
code_color: "#15803d"
|
||||
quote_border: "#16a34a"
|
||||
quote_bg: "#f0fdf4"
|
||||
border_radius: "8px"
|
||||
darkmode:
|
||||
background: "#0f1a0f"
|
||||
text: "#d8e8d8"
|
||||
text_light: "#8aaa8a"
|
||||
primary: "#4ade80"
|
||||
code_bg: "#162816"
|
||||
code_color: "#6ee7a0"
|
||||
quote_bg: "#142014"
|
||||
quote_border: "#4ade80"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a2e1a;
|
||||
background: #ffffff;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
margin: 32px 0 16px 0;
|
||||
padding: 12px 16px;
|
||||
background: #16a34a;
|
||||
border-radius: 8px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #16a34a;
|
||||
margin: 28px 0 14px 0;
|
||||
padding: 8px 0 8px 12px;
|
||||
border-left: 4px solid #16a34a;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #15803d;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1a2e1a;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a2e1a;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #16a34a;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #4a6a4a;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #f0fdf4;
|
||||
color: #15803d;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #f0fdf4;
|
||||
color: #1a2e1a;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #bbf7d0;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #1a2e1a;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #16a34a;
|
||||
background: #f0fdf4;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 8px 8px 0;
|
||||
color: #1a2e1a;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #1a2e1a;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a2e1a;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #16a34a;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #16a34a;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #16a34a;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #d1fae5;
|
||||
color: #1a2e1a;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #16a34a;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 2px solid #d1fae5;
|
||||
margin: 24px 0;
|
||||
}
|
||||
197
toolkit/themes/bold-navy.yaml
Normal file
197
toolkit/themes/bold-navy.yaml
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
name: "bold-navy"
|
||||
description: "大胆藏青风格:白底藏青主色,稳重专业,适合金融商务和行业分析内容"
|
||||
colors:
|
||||
primary: "#1e3a5f"
|
||||
secondary: "#2c5282"
|
||||
text: "#1a1a2e"
|
||||
text_light: "#4a5568"
|
||||
background: "#ffffff"
|
||||
code_bg: "#f0f4f8"
|
||||
code_color: "#1e3a5f"
|
||||
quote_border: "#1e3a5f"
|
||||
quote_bg: "#f0f4f8"
|
||||
border_radius: "6px"
|
||||
darkmode:
|
||||
background: "#0a0f1a"
|
||||
text: "#d8dce8"
|
||||
text_light: "#8890a0"
|
||||
primary: "#5b8cc8"
|
||||
code_bg: "#141a28"
|
||||
code_color: "#7ca8e0"
|
||||
quote_bg: "#101828"
|
||||
quote_border: "#5b8cc8"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a1a2e;
|
||||
background: #ffffff;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: #1e3a5f;
|
||||
margin: 32px 0 16px 0;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 3px solid #1e3a5f;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #1e3a5f;
|
||||
margin: 28px 0 14px 0;
|
||||
padding: 8px 0 8px 12px;
|
||||
border-left: 4px solid #1e3a5f;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #2c5282;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1a1a2e;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a1a2e;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #1e3a5f;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #4a5568;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #f0f4f8;
|
||||
color: #1e3a5f;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #1e3a5f;
|
||||
color: #e2e8f0;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #e2e8f0;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #1e3a5f;
|
||||
background: #f0f4f8;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 6px 6px 0;
|
||||
color: #2c5282;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #2c5282;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a1a2e;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #1e3a5f;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #1e3a5f;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #1e3a5f;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #e2e8f0;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2c5282;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 2px solid #e2e8f0;
|
||||
margin: 24px 0;
|
||||
}
|
||||
199
toolkit/themes/bytedance.yaml
Normal file
199
toolkit/themes/bytedance.yaml
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
name: "bytedance"
|
||||
description: "字节跳动风:白底品牌蓝,现代无衬线,大间距,适合科技产品内容"
|
||||
colors:
|
||||
primary: "#1966FF"
|
||||
secondary: "#4e8fff"
|
||||
text: "#1f2329"
|
||||
text_light: "#646a73"
|
||||
background: "#ffffff"
|
||||
code_bg: "#f5f6f7"
|
||||
code_color: "#1966FF"
|
||||
quote_border: "#1966FF"
|
||||
quote_bg: "#f0f5ff"
|
||||
border_radius: "8px"
|
||||
darkmode:
|
||||
background: "#1a1a1a"
|
||||
text: "#e8e8e8"
|
||||
text_light: "#a0a0a0"
|
||||
primary: "#4e8fff"
|
||||
code_bg: "#2a2a2a"
|
||||
code_color: "#6ea8fe"
|
||||
quote_bg: "#1e2a3a"
|
||||
quote_border: "#4e8fff"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 2;
|
||||
color: #1f2329;
|
||||
background: #ffffff;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
word-wrap: break-word;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
color: #1f2329;
|
||||
margin: 40px 0 20px 0;
|
||||
padding-bottom: 14px;
|
||||
border-bottom: 3px solid #1966FF;
|
||||
line-height: 1.4;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #1f2329;
|
||||
margin: 36px 0 16px 0;
|
||||
padding: 10px 0 10px 14px;
|
||||
border-left: 4px solid #1966FF;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1966FF;
|
||||
margin: 28px 0 14px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1f2329;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 2;
|
||||
color: #1f2329;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #1966FF;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #646a73;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #f5f6f7;
|
||||
color: #1966FF;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #f5f6f7;
|
||||
color: #1f2329;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
overflow-x: auto;
|
||||
margin: 20px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #e5e6e8;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #1f2329;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #1966FF;
|
||||
background: #f0f5ff;
|
||||
margin: 20px 0;
|
||||
padding: 16px 20px;
|
||||
border-radius: 0 8px 8px 0;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 28px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 28px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 2;
|
||||
color: #1f2329;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #1966FF;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #1966FF;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
padding: 12px 16px;
|
||||
text-align: left;
|
||||
border: 1px solid #1966FF;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 12px 16px;
|
||||
border: 1px solid #e5e6e8;
|
||||
color: #1f2329;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 28px auto;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #1966FF;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #e5e6e8;
|
||||
margin: 32px 0;
|
||||
}
|
||||
198
toolkit/themes/elegant-rose.yaml
Normal file
198
toolkit/themes/elegant-rose.yaml
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
name: "elegant-rose"
|
||||
description: "优雅玫瑰风格:浅粉底玫瑰色点缀,温柔精致,适合女性生活和时尚内容"
|
||||
colors:
|
||||
primary: "#be185d"
|
||||
secondary: "#db2777"
|
||||
text: "#3d1f2e"
|
||||
text_light: "#7a5068"
|
||||
background: "#fdf2f8"
|
||||
code_bg: "#fce7f3"
|
||||
code_color: "#be185d"
|
||||
quote_border: "#be185d"
|
||||
quote_bg: "#fce7f3"
|
||||
border_radius: "12px"
|
||||
darkmode:
|
||||
background: "#1a0f14"
|
||||
text: "#e8d0dc"
|
||||
text_light: "#a07888"
|
||||
primary: "#f472b6"
|
||||
code_bg: "#2a1520"
|
||||
code_color: "#f9a8d4"
|
||||
quote_bg: "#221018"
|
||||
quote_border: "#f472b6"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.85;
|
||||
color: #3d1f2e;
|
||||
background: #fdf2f8;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: #be185d;
|
||||
margin: 32px 0 16px 0;
|
||||
text-align: center;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 2px solid #f9a8d4;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #be185d;
|
||||
margin: 28px 0 14px 0;
|
||||
padding: 8px 0 8px 12px;
|
||||
border-left: 4px solid #be185d;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #db2777;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #3d1f2e;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.85;
|
||||
color: #3d1f2e;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #be185d;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #7a5068;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #fce7f3;
|
||||
color: #be185d;
|
||||
padding: 2px 6px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #fce7f3;
|
||||
color: #3d1f2e;
|
||||
padding: 16px;
|
||||
border-radius: 12px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #fbcfe8;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #3d1f2e;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #be185d;
|
||||
background: #fce7f3;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 12px 12px 0;
|
||||
color: #7a5068;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #7a5068;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.85;
|
||||
color: #3d1f2e;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #be185d;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #be185d;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #be185d;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #fbcfe8;
|
||||
color: #3d1f2e;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #fdf2f8;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #be185d;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #fbcfe8;
|
||||
margin: 24px 0;
|
||||
}
|
||||
197
toolkit/themes/focus-red.yaml
Normal file
197
toolkit/themes/focus-red.yaml
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
name: "focus-red"
|
||||
description: "聚焦红风格:白底中国红标题和引用边框,醒目有力,适合新闻评论和观点输出"
|
||||
colors:
|
||||
primary: "#dc2626"
|
||||
secondary: "#ef4444"
|
||||
text: "#1a1a1a"
|
||||
text_light: "#555555"
|
||||
background: "#ffffff"
|
||||
code_bg: "#fef2f2"
|
||||
code_color: "#b91c1c"
|
||||
quote_border: "#dc2626"
|
||||
quote_bg: "#fef2f2"
|
||||
border_radius: "6px"
|
||||
darkmode:
|
||||
background: "#1a0f0f"
|
||||
text: "#e8d8d8"
|
||||
text_light: "#a08888"
|
||||
primary: "#f87171"
|
||||
code_bg: "#2a1515"
|
||||
code_color: "#fca5a5"
|
||||
quote_bg: "#221010"
|
||||
quote_border: "#f87171"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a1a1a;
|
||||
background: #ffffff;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 800;
|
||||
color: #dc2626;
|
||||
margin: 32px 0 16px 0;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 3px solid #dc2626;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #dc2626;
|
||||
margin: 28px 0 14px 0;
|
||||
padding: 8px 0 8px 12px;
|
||||
border-left: 4px solid #dc2626;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a1a1a;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #dc2626;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #fef2f2;
|
||||
color: #b91c1c;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #fef2f2;
|
||||
color: #1a1a1a;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #fecaca;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #1a1a1a;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #dc2626;
|
||||
background: #fef2f2;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 6px 6px 0;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #1a1a1a;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #dc2626;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #dc2626;
|
||||
color: #ffffff;
|
||||
font-weight: 700;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #dc2626;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #e5e7eb;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #dc2626;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 2px solid #fecaca;
|
||||
margin: 24px 0;
|
||||
}
|
||||
198
toolkit/themes/github.yaml
Normal file
198
toolkit/themes/github.yaml
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
name: "github"
|
||||
description: "GitHub风格:白底蓝色链接,等宽代码块,简洁清晰,适合技术文档和开发者内容"
|
||||
colors:
|
||||
primary: "#0969da"
|
||||
secondary: "#0550ae"
|
||||
text: "#1f2328"
|
||||
text_light: "#656d76"
|
||||
background: "#ffffff"
|
||||
code_bg: "#f6f8fa"
|
||||
code_color: "#0550ae"
|
||||
quote_border: "#d0d7de"
|
||||
quote_bg: "#f6f8fa"
|
||||
border_radius: "6px"
|
||||
darkmode:
|
||||
background: "#0d1117"
|
||||
text: "#e6edf3"
|
||||
text_light: "#8b949e"
|
||||
primary: "#58a6ff"
|
||||
code_bg: "#161b22"
|
||||
code_color: "#79c0ff"
|
||||
quote_bg: "#161b22"
|
||||
quote_border: "#30363d"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
color: #1f2328;
|
||||
background: #ffffff;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
color: #1f2328;
|
||||
margin: 32px 0 16px 0;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #d1d9e0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #1f2328;
|
||||
margin: 28px 0 14px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #d1d9e0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1f2328;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1f2328;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
color: #1f2328;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 600;
|
||||
color: #1f2328;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #1f2328;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
||||
font-size: 13.6px;
|
||||
background: rgba(175,184,193,0.2);
|
||||
color: #1f2328;
|
||||
padding: 3px 6px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #f6f8fa;
|
||||
color: #1f2328;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.5;
|
||||
border: 1px solid #d1d9e0;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: ui-monospace, "SFMono-Regular", "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
||||
font-size: 13.6px;
|
||||
background: none;
|
||||
color: #1f2328;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #d0d7de;
|
||||
background: transparent;
|
||||
margin: 16px 0;
|
||||
padding: 4px 16px;
|
||||
border-radius: 0;
|
||||
color: #656d76;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #656d76;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 28px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 28px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.75;
|
||||
color: #1f2328;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #f6f8fa;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #f6f8fa;
|
||||
color: #1f2328;
|
||||
font-weight: 600;
|
||||
padding: 8px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #d1d9e0;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 8px 14px;
|
||||
border: 1px solid #d1d9e0;
|
||||
color: #1f2328;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0969da;
|
||||
text-decoration: none;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
height: 2px;
|
||||
background: #d1d9e0;
|
||||
margin: 24px 0;
|
||||
}
|
||||
204
toolkit/themes/ink.yaml
Normal file
204
toolkit/themes/ink.yaml
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
name: "ink"
|
||||
description: "水墨中国风:宣纸底墨色文字,中文衬线字体,留白疏朗,适合文化和人文内容"
|
||||
colors:
|
||||
primary: "#4a4a4a"
|
||||
secondary: "#6b6b6b"
|
||||
text: "#1a1a1a"
|
||||
text_light: "#666666"
|
||||
background: "#f8f5f0"
|
||||
code_bg: "#f0ebe3"
|
||||
code_color: "#555555"
|
||||
quote_border: "#999999"
|
||||
quote_bg: "#f4f0e8"
|
||||
border_radius: "2px"
|
||||
darkmode:
|
||||
background: "#1a1816"
|
||||
text: "#d8d2c8"
|
||||
text_light: "#9a9488"
|
||||
primary: "#b0a898"
|
||||
code_bg: "#252220"
|
||||
code_color: "#c0b8a8"
|
||||
quote_bg: "#222018"
|
||||
quote_border: "#706858"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: "Songti SC", "SimSun", "Noto Serif SC", Georgia, serif;
|
||||
font-size: 16px;
|
||||
line-height: 2;
|
||||
color: #1a1a1a;
|
||||
background: #f8f5f0;
|
||||
max-width: 680px;
|
||||
margin: 0 auto;
|
||||
padding: 28px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin: 48px 0 24px 0;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
letter-spacing: 0.1em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin: 40px 0 16px 0;
|
||||
text-align: center;
|
||||
padding-bottom: 12px;
|
||||
line-height: 1.4;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin: 32px 0 14px 0;
|
||||
line-height: 1.4;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 2;
|
||||
color: #1a1a1a;
|
||||
margin: 16px 0;
|
||||
text-indent: 2em;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #f0ebe3;
|
||||
color: #555555;
|
||||
padding: 2px 6px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #f0ebe3;
|
||||
color: #1a1a1a;
|
||||
padding: 16px;
|
||||
border-radius: 2px;
|
||||
overflow-x: auto;
|
||||
margin: 20px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #ddd5c8;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #1a1a1a;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 3px solid #999999;
|
||||
background: #f4f0e8;
|
||||
margin: 20px 0;
|
||||
padding: 14px 18px;
|
||||
border-radius: 0 2px 2px 0;
|
||||
color: #555555;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #555555;
|
||||
text-indent: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 2;
|
||||
color: #1a1a1a;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #4a4a4a;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #4a4a4a;
|
||||
color: #f8f5f0;
|
||||
font-weight: 600;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #4a4a4a;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #ddd5c8;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #f8f5f0;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 32px auto;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #555555;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
text-align: center;
|
||||
margin: 36px 0;
|
||||
height: 20px;
|
||||
background: transparent;
|
||||
border-bottom: 1px solid #ccc5b8;
|
||||
}
|
||||
197
toolkit/themes/midnight.yaml
Normal file
197
toolkit/themes/midnight.yaml
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
name: "midnight"
|
||||
description: "午夜深色主题:深蓝黑底白色文字,蓝色高亮,适合技术和深夜阅读内容"
|
||||
colors:
|
||||
primary: "#60a5fa"
|
||||
secondary: "#93c5fd"
|
||||
text: "#e2e8f0"
|
||||
text_light: "#94a3b8"
|
||||
background: "#0f172a"
|
||||
code_bg: "#1e293b"
|
||||
code_color: "#7dd3fc"
|
||||
quote_border: "#60a5fa"
|
||||
quote_bg: "#172040"
|
||||
border_radius: "8px"
|
||||
darkmode:
|
||||
background: "#0f172a"
|
||||
text: "#e2e8f0"
|
||||
text_light: "#94a3b8"
|
||||
primary: "#60a5fa"
|
||||
code_bg: "#1e293b"
|
||||
code_color: "#7dd3fc"
|
||||
quote_bg: "#172040"
|
||||
quote_border: "#60a5fa"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #e2e8f0;
|
||||
background: #0f172a;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: #f1f5f9;
|
||||
margin: 32px 0 16px 0;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 2px solid #60a5fa;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #60a5fa;
|
||||
margin: 28px 0 14px 0;
|
||||
padding: 8px 0 8px 12px;
|
||||
border-left: 4px solid #60a5fa;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #93c5fd;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #cbd5e1;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #e2e8f0;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #60a5fa;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #1e293b;
|
||||
color: #7dd3fc;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #1e293b;
|
||||
color: #e2e8f0;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #334155;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #e2e8f0;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #60a5fa;
|
||||
background: #172040;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 8px 8px 0;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #e2e8f0;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #1e3a5f;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #1e3a5f;
|
||||
color: #f1f5f9;
|
||||
font-weight: 600;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #334155;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #334155;
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #0f172a;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #60a5fa;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #334155;
|
||||
margin: 24px 0;
|
||||
}
|
||||
202
toolkit/themes/minimal-gold.yaml
Normal file
202
toolkit/themes/minimal-gold.yaml
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
name: "minimal-gold"
|
||||
description: "极简金色风格:白底金色细线点缀,奢华但克制,适合高端品牌和精品内容"
|
||||
colors:
|
||||
primary: "#b8860b"
|
||||
secondary: "#d4a843"
|
||||
text: "#2a2a2a"
|
||||
text_light: "#6b6b6b"
|
||||
background: "#ffffff"
|
||||
code_bg: "#faf8f3"
|
||||
code_color: "#8b6914"
|
||||
quote_border: "#b8860b"
|
||||
quote_bg: "#fdfbf5"
|
||||
border_radius: "4px"
|
||||
darkmode:
|
||||
background: "#141210"
|
||||
text: "#e0dcd0"
|
||||
text_light: "#9a9488"
|
||||
primary: "#d4a843"
|
||||
code_bg: "#1e1c18"
|
||||
code_color: "#e0c060"
|
||||
quote_bg: "#1a1810"
|
||||
quote_border: "#d4a843"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #2a2a2a;
|
||||
background: #ffffff;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
color: #2a2a2a;
|
||||
margin: 36px 0 18px 0;
|
||||
text-align: center;
|
||||
padding-bottom: 14px;
|
||||
border-bottom: 1px solid #b8860b;
|
||||
line-height: 1.4;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 21px;
|
||||
font-weight: 600;
|
||||
color: #2a2a2a;
|
||||
margin: 30px 0 14px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #d4c59a;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #b8860b;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #2a2a2a;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #2a2a2a;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #b8860b;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #6b6b6b;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #faf8f3;
|
||||
color: #8b6914;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #faf8f3;
|
||||
color: #2a2a2a;
|
||||
padding: 16px;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #e8e0c8;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #2a2a2a;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 2px solid #b8860b;
|
||||
background: #fdfbf5;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
color: #6b6b6b;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #6b6b6b;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
color: #2a2a2a;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #2a2a2a;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #2a2a2a;
|
||||
color: #d4a843;
|
||||
font-weight: 600;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #2a2a2a;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #e8e0c8;
|
||||
color: #2a2a2a;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #b8860b;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #d4c59a;
|
||||
margin: 28px auto;
|
||||
width: 40%;
|
||||
}
|
||||
|
|
@ -11,6 +11,15 @@ colors:
|
|||
quote_border: "#cccccc"
|
||||
quote_bg: "#f9f9f9"
|
||||
border_radius: "4px"
|
||||
darkmode:
|
||||
background: "#1a1a1a"
|
||||
text: "#c0c0c0"
|
||||
text_light: "#888888"
|
||||
primary: "#e0e0e0"
|
||||
code_bg: "#252525"
|
||||
code_color: "#c0c0c0"
|
||||
quote_bg: "#222222"
|
||||
quote_border: "#555555"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
|
|
|
|||
206
toolkit/themes/newspaper.yaml
Normal file
206
toolkit/themes/newspaper.yaml
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
name: "newspaper"
|
||||
description: "经典报纸风格:米黄底深棕文字,衬线字体质感,适合深度报道和评论"
|
||||
colors:
|
||||
primary: "#8b4513"
|
||||
secondary: "#a0522d"
|
||||
text: "#2c2416"
|
||||
text_light: "#5c4a3a"
|
||||
background: "#f5f0e8"
|
||||
code_bg: "#ede7db"
|
||||
code_color: "#8b4513"
|
||||
quote_border: "#8b4513"
|
||||
quote_bg: "#f0eade"
|
||||
border_radius: "2px"
|
||||
darkmode:
|
||||
background: "#1e1a14"
|
||||
text: "#ddd5c8"
|
||||
text_light: "#a09580"
|
||||
primary: "#c8915a"
|
||||
code_bg: "#2a2418"
|
||||
code_color: "#d4a574"
|
||||
quote_bg: "#28221a"
|
||||
quote_border: "#c8915a"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: Georgia, "Songti SC", "SimSun", "Noto Serif SC", serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.9;
|
||||
color: #2c2416;
|
||||
background: #f5f0e8;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #2c2416;
|
||||
margin: 36px 0 16px 0;
|
||||
text-align: center;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 3px double #8b4513;
|
||||
line-height: 1.3;
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #2c2416;
|
||||
margin: 30px 0 14px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #8b4513;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #5c4a3a;
|
||||
margin: 24px 0 12px 0;
|
||||
line-height: 1.4;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #5c4a3a;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.9;
|
||||
color: #2c2416;
|
||||
margin: 14px 0;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #2c2416;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #5c4a3a;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #ede7db;
|
||||
color: #8b4513;
|
||||
padding: 2px 6px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #ede7db;
|
||||
color: #2c2416;
|
||||
padding: 16px;
|
||||
border-radius: 2px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #d4cbb8;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #2c2416;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 3px solid #8b4513;
|
||||
background: #f0eade;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 2px 2px 0;
|
||||
color: #5c4a3a;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #5c4a3a;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 14px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 14px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.9;
|
||||
color: #2c2416;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #8b4513;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #8b4513;
|
||||
color: #f5f0e8;
|
||||
font-weight: 700;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #8b4513;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #d4cbb8;
|
||||
color: #2c2416;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #f5f0e8;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #d4cbb8;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #8b4513;
|
||||
text-decoration: underline;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #d4cbb8;
|
||||
margin: 28px auto;
|
||||
width: 60%;
|
||||
}
|
||||
|
|
@ -11,6 +11,15 @@ colors:
|
|||
quote_border: "#2563eb"
|
||||
quote_bg: "#eff6ff"
|
||||
border_radius: "8px"
|
||||
darkmode:
|
||||
background: "#1e1e1e"
|
||||
text: "#c8c8c8"
|
||||
text_light: "#999999"
|
||||
primary: "#6aadff"
|
||||
code_bg: "#2d2d2d"
|
||||
code_color: "#d4d4d4"
|
||||
quote_bg: "#252525"
|
||||
quote_border: "#4a90d9"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
|
|
|
|||
198
toolkit/themes/sspai.yaml
Normal file
198
toolkit/themes/sspai.yaml
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
name: "sspai"
|
||||
description: "少数派风格:暖白底红色点缀,清爽文艺,适合数码生活和效率工具内容"
|
||||
colors:
|
||||
primary: "#c7372f"
|
||||
secondary: "#d4524b"
|
||||
text: "#333333"
|
||||
text_light: "#888888"
|
||||
background: "#fafaf7"
|
||||
code_bg: "#f5f2ed"
|
||||
code_color: "#c7372f"
|
||||
quote_border: "#c7372f"
|
||||
quote_bg: "#fdf5f4"
|
||||
border_radius: "6px"
|
||||
darkmode:
|
||||
background: "#1c1c1a"
|
||||
text: "#e0ddd8"
|
||||
text_light: "#9a9790"
|
||||
primary: "#e05a52"
|
||||
code_bg: "#2a2825"
|
||||
code_color: "#e87c76"
|
||||
quote_bg: "#2a2220"
|
||||
quote_border: "#e05a52"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.85;
|
||||
color: #333333;
|
||||
background: #fafaf7;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 26px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin: 36px 0 18px 0;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 21px;
|
||||
font-weight: 700;
|
||||
color: #c7372f;
|
||||
margin: 30px 0 14px 0;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #c7372f;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin: 24px 0 12px 0;
|
||||
padding-left: 10px;
|
||||
border-left: 3px solid #c7372f;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin: 20px 0 10px 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
line-height: 1.85;
|
||||
color: #333333;
|
||||
margin: 14px 0;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
color: #c7372f;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: #f5f2ed;
|
||||
color: #c7372f;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #f5f2ed;
|
||||
color: #333333;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0;
|
||||
line-height: 1.6;
|
||||
border: 1px solid #e8e4dc;
|
||||
}
|
||||
|
||||
pre code {
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
color: #333333;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid #c7372f;
|
||||
background: #fdf5f4;
|
||||
margin: 16px 0;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 6px 6px 0;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 8px 0;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 24px;
|
||||
margin: 14px 0;
|
||||
}
|
||||
|
||||
ol {
|
||||
padding-left: 24px;
|
||||
margin: 14px 0;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 16px;
|
||||
line-height: 1.85;
|
||||
color: #333333;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #c7372f;
|
||||
}
|
||||
|
||||
th {
|
||||
background: #c7372f;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border: 1px solid #c7372f;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #e8e4dc;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: #fafaf7;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 24px auto;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #c7372f;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #e8e4dc;
|
||||
margin: 28px 0;
|
||||
}
|
||||
|
|
@ -11,6 +11,15 @@ colors:
|
|||
quote_border: "#7c3aed"
|
||||
quote_bg: "#f8f5ff"
|
||||
border_radius: "8px"
|
||||
darkmode:
|
||||
background: "#1a1a2e"
|
||||
text: "#c8c8c8"
|
||||
text_light: "#999999"
|
||||
primary: "#a78bfa"
|
||||
code_bg: "#1e1e2e"
|
||||
code_color: "#c8cad8"
|
||||
quote_bg: "#232340"
|
||||
quote_border: "#7c3aed"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,15 @@ colors:
|
|||
quote_border: "#d97706"
|
||||
quote_bg: "#fffbeb"
|
||||
border_radius: "8px"
|
||||
darkmode:
|
||||
background: "#1e1e1e"
|
||||
text: "#d4c8b8"
|
||||
text_light: "#a09080"
|
||||
primary: "#f0a830"
|
||||
code_bg: "#2a2520"
|
||||
code_color: "#d4b896"
|
||||
quote_bg: "#2a2418"
|
||||
quote_border: "#d97706"
|
||||
base_css: |
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
|
||||
|
|
|
|||
Loading…
Reference in a new issue