mcpField
V
visualize

visualize

github.com/careerhackeralex设计与 UI24884 次安装34 周前更新
代码仓库

关于 visualize

visualize 是面向 Claude Code 对话场景的技能,可将想法、数据或内容制作为单文件 HTML 可视化。它规定了主题切换、图表、响应式布局和无障碍等结构要求,并支持多种可选可视化库。

主要功能

  1. 01生成单文件 HTML 可视化
  2. 02浅色与深色主题切换
  3. 03支持图表和多种可视化库
  4. 04响应式布局与打印样式
  5. 05包含动画及无障碍要求

适用场景

  1. 01将对话中的想法转成可视内容
  2. 02把数据制作成图表或仪表板
  3. 03将文章或链接内容整理为可视页面

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/careerhackeralex/visualize --skill visualize

安装后在 Claude Code 中输入/visualize确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
animations.md
anthropic-skill-guide-notes.md
css-techniques.md
design-system.md
eval.md
libraries.md
menu.md
skeleton.md
types.md

详细介绍

可视化

将任意想法、数据或内容转化为令人惊艳的单文件 HTML 可视化作品。

创建文件后

写入 HTML 文件后,务必完成以下两项操作:

  1. 自动在浏览器中打开: 运行 open <filename>.html(macOS)或 xdg-open <filename>.html(Linux),让用户立即查看
  2. 将文件路径作为可点击的 URL 返回: 在回复中包含 file://<absolute-path>,以便用户点击打开

创建后的回复示例:

Created your visualization! Opening in browser now...
📄 file:///Users/you/project/my-dashboard.html

关键要求(不可妥协)

⚠️ 缺少以下 8 项中的任何一项,都必定无法通过评估 ⚠️

每个文件都必须以 references/skeleton.md 中的骨架模板为基础——复制完整模板,然后添加内容。

  1. CSS 自定义属性: 必须使用以下确切名称:--bg, --surface, --surface-hover, --border, --text, --text-secondary, --accent, --accent-secondary, --positive, --negative, --warning——不得使用其他名称(不能使用 --bg-primary 或 --text-primary)。关键: 评估系统兼容性要求使用这些确切的属性名称。
  2. 实用工具菜单系统(强制要求): 完整的 .viz-menu 元素,其中包含 .viz-menu-toggle 按钮、.viz-menu-dropdown 容器、下载 PNG 按钮(onclick="downloadImage()")、打印按钮(onclick="window.print()"),以及 html-to-image CDN 脚本(<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html-to-image.js"></script>)。评估关键项: 系统会自动检查菜单系统;如果缺失,将导致评估失败。
  3. 主题类(评估关键项): 必须在样式表中明确定义 .theme-light 和 .theme-dark 两个类,并为它们完整定义自定义属性。必须采用以下示例:
:root { /* base properties */ }
.theme-light { --bg: #ffffff; --surface: #f8f9fa; --text: #1a1a1a; /* etc */ }
.theme-dark { --bg: #0a0a0a; --surface: #1a1a1a; --text: #ffffff; /* etc */ }

切勿仅依赖 :root 或 @media (prefers-color-scheme)——评估系统会检查基于类的主题。 4. 语义化 HTML: <main id="main-content"> 元素、强制要求:为主要内容区块(页眉、指标、图表等)使用多个 <section> 元素,以及跳转到内容的链接。每个不同的内容区域都必须用语义化的 <section> 标签包裹。 5. Chart.js 要求(评估关键项): 必须在结束 </head> 标签之前包含 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>。强制要求: 紧接在 Chart.js 脚本之后添加 <script>Chart.defaults.animation = false;</script>(用于防止动画故障,且评估系统会自动检查)。强制要求的图表校验: 每个图表函数都必须以 if (typeof Chart === 'undefined') { console.error('Chart.js not loaded'); return; } 开头。图表无障碍支持: 每个 canvas 元素都必须包含 role="img" 和描述性 aria-label 属性。关键图表配置: 为确保无障碍支持,设置 maintainAspectRatio: false、responsive: true 和 plugins: { tooltip: { enabled: true } }。切勿禁用工具提示——评估系统会检查工具提示是否已启用。图表可靠性系统: 使用专用的 ChartManager 模式,确保集成稳定可靠:

var ChartManager = {
  charts: new Map(),
  safeInit: function(canvasId, config) {
    if (typeof Chart === 'undefined') {
      console.error('Chart.js library not loaded - check CDN inclusion');
      return null;
    }
    try {
      if (this.charts.has(canvasId)) {
        this.charts.get(canvasId).destroy();
        this.charts.delete(canvasId);
      }
      var ctx = document.getElementById(canvasId);
      if (!ctx) {
        console.error('Canvas element not found: ' + canvasId);
        return null;
      }
      // Ensure no conflicting chart instances
      if (ctx.chart) {
        ctx.chart.destroy();
        delete ctx.chart;
      }
      // Set accessibility attributes
      ctx.setAttribute('role', 'img');
      if (!ctx.getAttribute('aria-label')) {
        ctx.setAttribute('aria-label', 'Chart visualization');
      }
      // Initialize with enhanced error handling
      var chart = new Chart(ctx, config);
      this.charts.set(canvasId, chart);
      return chart;
    } catch (error) {
      console.error('Chart initialization failed for ' + canvasId + ':', error);
      return null;
    }
  },
  updateTheme: function() {
    if (typeof Chart === 'undefined') return;
    this.charts.forEach(function(chart, canvasId) {
      try {
        chart.update();
      } catch (error) {
        console.error('Chart theme update failed for ' + canvasId + ':', error);
      }
    });
  },
  destroyAll: function() {
    this.charts.forEach(function(chart) {
      try {
        chart.destroy();
      } catch (error) {
        console.error('Chart destruction failed:', error);
      }
    });
    this.charts.clear();
  }
};

使用 ChartManager.safeInit(),而不是直接使用 new Chart()。关键图表配置: 为确保无障碍支持,设置 maintainAspectRatio: false、responsive: true 和 plugins: { tooltip: { enabled: true } }。图表容器尺寸: 容器必须明确设置 height,且不小于 300px,才能确保图表正常渲染。使用基于主题的 CSS 自定义属性设置颜色,切勿使用静态十六进制颜色。切勿在 Chart.js CDN 中使用 import/export 语法——只能使用标准 var 声明。 CHART.JS 故障排查(关键): 如果图表显示为空白区域:

  • 确认 Chart.js CDN 在 </head> 之前引入
  • 确认 Chart.defaults.animation = false; 紧跟在 CDN 之后
  • 确认图表初始化代码位于 DOMContentLoaded 事件侦听器中
  • 确认文件中任何位置都没有模块导入/导出语法
  • 确认正确使用了 ChartManager.safeInit() 模式
  • 确认 canvas 具有 role="img" 和 aria-label 属性
  1. 响应式设计: 区块间距 ≥48px,关键:视口宽度为 375px 时不得出现水平溢出(必须添加 @media (max-width: 375px) { body { overflow-x: hidden; } },以防止水平滚动),必须遵循字号层级: h1 ≥ 2.5rem,h2 ≥ 2rem,h3 ≥ 1.5rem,正文 = 1rem。幻灯片要求: 标题页 h1 ≥ 3rem,内容页标题 ≥ 2.5rem,标题层级之间要有清晰的视觉区分。幻灯片区块间距: 幻灯片中的主要区块间距必须 ≥48px(标题与内容、内容与图表、图表与导航之间)。在宽度为 375px 的视口下测试所有布局——仪表盘尤其容易出现图表容器溢出。 CSS 容器查询: 如需更高级的响应式设计,请使用基于容器的查询:
.chart-container { container-type: inline-size; }
@container (max-width: 400px) { 
  .chart-legend { display: none; } 
  .chart-title { font-size: 1rem; }
}

这能实现真正的组件级响应式效果,超越视口媒体查询的能力。 7. 打印与无障碍: 添加 @media print 样式,以及禁用动画的 @media (prefers-reduced-motion: reduce) 样式 8. 入场动画(必须): 必须通过 .animate 类、data-reveal 属性或 CSS @keyframes 添加入场动画。评估关键要求: 系统会自动检测动画是否存在,并将其视为必需项。 9. JavaScript 函数: cycleTheme()、toggleMenu(),顶层变量使用 var,而非 let/const

🔥 关键:原样复制 skeleton.md → 将 "YOUR CONTENT HERE" 替换为可视化内容 → 保存文件

核心原则

  1. 单文件 HTML —— 一个内联 CSS/JS 的 .html 文件。可在任何浏览器中打开,离线运行,也易于通过电子邮件分享。
  2. 针对浅色主题优化 —— 现代设计优先保证浅色模式的质量。可通过切换启用深色主题。
  3. 默认即精美 —— 首次生成的内容无需任何迭代,就应具备专业的外观。
  4. 内容优先 —— 可视化服务于信息表达。切勿为了美观而牺牲清晰度。
  5. 响应式 —— 除非明确要求固定尺寸(例如 16:9 幻灯片),否则应适用于桌面、平板和移动设备。
  6. 视觉克制 —— 专业设计应避免增加杂乱感的装饰元素。不要使用漂浮的渐变球、彩虹边框或装饰性动画。

理念

HTML 不是“网站”,而是一种可视化工具。编写代码成本很低,每个人都应该能够轻松地将任何内容可视化。这项技能可以在几秒钟内将对话上下文、URL、文章、数据或原始想法转化为直观易懂的内容。

用户会在与 Claude Code 对话过程中调用这项技能。请充分利用完整的对话上下文——无论用户一直在讨论什么、分享了哪些链接或粘贴了哪些数据,都可作为素材。收到 URL 时,请抓取其内容并提取出可视化的信息。

输出规则

强制第一步:复制 references/skeleton.md 中的完整骨架,其中包含所有必需元素(菜单、主题系统、CSS 属性、语义化 HTML、无障碍功能)。切勿从头编写 HTML。

  • 在 ~/Downloads/(或用户指定的路径)中编写一个 .html 文件
  • 文件名:使用描述性的 kebab-case 格式,例如 q4-revenue-dashboard.html、team-roadmap-deck.html
  • 以 skeleton.md 模板开头,将内容添加到 `` 部分
  • 所有自定义样式都放在骨架基础样式之后的 <style> 中
  • 建议使用 CDN 库——根据任务选用最佳工具:
    • Tailwind CSS — https://cdn.tailwindcss.com(实用优先的样式,可自由使用)
    • Chart.js — https://cdn.jsdelivr.net/npm/chart.js(柱状图、折线图、饼图、雷达图、圆环图)
    • D3.js — https://cdn.jsdelivr.net/npm/d3@7(复杂/自定义数据可视化、力导向图)
    • Mermaid — https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js(流程图、时序图)
    • Three.js — 适用于 3D 的场景
    • Reveal.js — 需要时使用功能齐全的幻灯片引擎。**关键:**必须设置 html, body { height: 100%; overflow: hidden; },并将 .reveal 容器的 height 设为 100%。配置必须使用数值尺寸:Reveal.initialize({ width: 1280, height: 720, center: true, controls: false })——切勿使用 '100%' 这样的字符串百分比,否则会导致视口高度为零、幻灯片空白。强制要求:禁用 Reveal.js 默认控件(controls: false)——默认的 < > 箭头叠层效果很差。请改为添加简洁的自定义底部导航栏:
<nav class="slide-nav" aria-label="Slide navigation">
  <button onclick="prevSlide()" aria-label="Previous slide">
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 18l-6-6 6-6"/></svg>
  </button>
  <span class="slide-counter" id="slideCounter">1 / 8</span>
  <button onclick="nextSlide()" aria-label="Next slide">
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 18l6-6-6-6"/></svg>
  </button>
</nav>
.slide-nav { position: fixed; bottom: 16px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 8px; z-index: 9998; }
.slide-nav button { width: 28px; height: 28px; border-radius: 6px; background: transparent; border: none; color: var(--text-secondary); cursor: pointer; display: flex; align-items: center; justify-content: center; opacity: 0.3; transition: opacity 0.2s; }
.slide-nav button:hover { opacity: 0.7; }
.slide-counter { font-size: 12px; color: var(--text-secondary); font-weight: 400; min-width: 40px; text-align: center; opacity: 0.35; }
  • Leaflet — 适用于地图和地理空间数据(https://unpkg.com/[email protected]/dist/leaflet.js + CSS)。**地理数据必需使用:**切勿手绘 SVG 大洲形状。使用 OpenStreetMap 瓦片或简洁的瓦片服务提供方。
  • 图标和简单图形使用 SVG——除非用户提供,否则切勿使用外部图片 URL
  • 尽可能优先使用 CSS 动画,而非 JS

详细的 CDN 链接、模式和技巧请参见 references/libraries.md。

设计系统

应用以下默认设置。这些设置经过精心制定和测试——只有用户提出要求时才覆盖。

**完整设计系统参考:**请参见 references/design-system.md,了解完整的字体、颜色、间距、动画、无障碍和视觉润色规范。

主要要点(完整详情请查阅参考文档):

设计说明

主题系统(关键):

  • 仅使用基于 class 的主题——<html class="theme-dark"> 或 <html class="theme-light">
  • 主题切换通过更改 html class 实现:document.documentElement.className = 'theme-' + newTheme
  • 切勿使用 data-theme 属性——评估系统要求使用基于 class 的主题
  • 必需的 CSS 自定义属性:--bg, --surface, --text, --accent, --border(评估兼容性的最低要求)

字体排版:

  • 必须使用 Inter 字体——https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap
  • **强制字体粗细层级:**h1 ≥ 700,h2 ≥ 600,h3 ≥ 500,正文 = 400(评估关键要求)
  • 标题字距设为 -0.03em
  • **韩文排版规范:**对于韩文内容,正文使用 Noto Sans KR,UI 元素使用 Inter。韩文行高设为 1.6(拉丁文字为 1.4)。韩文 Medium 字重对应西文 Regular(400)。请包含:https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;600;700&display=swap 颜色:
  • 仅使用基于类的主题(禁止使用 @media prefers-color-scheme)
  • 深色:背景 #0A0A0A,文字 #EDEDED。浅色:背景 #FAFAF9,文字 #0f172a
  • 完整调色板请参阅参考。
  • **卡片:**圆角 8px,仅在悬停时显示阴影(不使用 translateY/scale),边框为 1px solid var(--border)。**玻璃拟态升级:**对于高端布局,使用玻璃容器,设置 backdrop-filter: blur(8px)、半透明背景(使用 CSS 变量 --glass-opacity: 0.08)和增强阴影。仅在首屏区域或主要卡片中选择性应用,以打造精致的层次感。
  • **动画:**使用 CSS @keyframes 实现页面加载动画(.animate + .delay-N),使用 data-reveal + IntersectionObserver 实现滚动动画,使用 data-count 实现计数器动画。默认显示内容。首屏内容绝不可使用 data-reveal——应改用 .animate 类。谨慎使用 data-reveal(最多 3-4 个区块),且仅用于首屏以下的内容。
  • **无障碍:**跳转到内容的链接、aria-label、地标角色、:focus-visible,以及用于图表数据的 sr-only。完整检查清单请参阅参考。
  • **图标:**仅使用内联 SVG,禁止使用表情符号。采用 Lucide 风格,尺寸为 24x24,基于描边。
  • **Chart.js(强制模式):**在脚本顶部设置 Chart.defaults.animation = false;,切换主题时销毁并重新创建图表,明确指定 rgba() 颜色,始终启用工具提示,在所有图表选项中设置 maintainAspectRatio: false。无障碍:使用带有 role="img" 和描述性 aria-label 的 div 包裹 canvas。 **保护模式:**使用 chartsBuilt 标记——onThemeChange() 必须在重建前检查 if (chartsBuilt)。图表容器的最小高度需为 360px,以确保足够的视觉占比。
  • **Chart.js 自定义样式:**在默认样式基础上应用专业样式——自定义内边距(layout: { padding: 30 })、减少多余网格线(不透明度 ≤ 0.04)、使用圆角(borderRadius: 4),并选择与主题相配的配色。图表容器需要 12px 圆角、40px 内边距和 360px 最小高度,以确保足够的视觉占比。避免使用看起来像自动生成的库默认样式。
  • **字体层级:**必须采用字号递减层级:h1 > h2 > h3 > 正文。**最低要求:**h1:≥3rem(48px),h2:≥2rem(32px),h3:≥1.5rem(24px),正文:1rem(16px)。**评估重点:**每个标题层级都必须明显小于上一级,相邻层级至少相差 0.5rem。有效层级示例:h1:3rem,h2:2.5rem,h3:1.5rem,正文:1rem。
  • **视觉克制:**禁止使用浮动光球、渐变边框、标题渐变文字、缩放变换、发光效果和装饰性动画。
  • **统计值颜色:**彩色数字必须具有语义含义(绿色/正值 = 良好指标,红色/负值 = 不良指标,强调色 = 主要/中性重点)。若没有明确的语义含义,则使用 var(--text)。禁止随意给统计值添加颜色。**对于包含 4 张或更多卡片的 KPI 网格:**数值最多使用 2 种强调色——最重要的单项指标使用 var(--accent),其他所有指标使用 var(--text)。仅将 var(--positive)/var(--negative) 用于变化指示器(箭头、百分比),不要用于卡片的主要数值。
  • **背景氛围:**每个文件仅使用一种细微效果(径向渐变、噪点纹理或点阵网格)。背景氛围应与内容相适配——游戏仪表板应呈现出不同于财务报告的感觉。调整强调色和渐变色调,使其与主题内容相符。
  • **AI 原生信息架构:**现代设计优先采用洞察驱动的层级。将最重要的指标/洞察置于首屏。采用渐进式呈现模式——立即展示关键数据,并通过悬停/点击提供深入查看。将上下文操作放在相关内容附近。先给出结论,再提供细节。
  • **强制使用入场动画:**所有卡片/区块均使用 fadeInUp + stagger。
  • **单屏海报:**在固定尺寸的 body 上使用 overflow:hidden + justify-content:space-between。9:16、1:1、4:5 尺寸请参阅参考。

关键实现要求

必须:使用骨架模板——完整的可复制 HTML 和所有内置要求,请参阅 references/skeleton.md。

JavaScript 实现规则:

  • 所有顶层变量都必须使用 var(而不是 let/const),以避免函数提升导致 TDZ 错误
  • 主题切换必须使用 cycleTheme() 函数——骨架模板内置了该函数,并提供正确的 applyTheme() 实现
  • 菜单必须使用 toggleMenu() 并处理点击外部区域的情况——骨架模板包含在点击外部区域和按下 Escape 键时自动关闭下拉菜单的功能
  • **重建图表:**定义 function onThemeChange() {},以便在主题变化时重新渲染图表
  • **移动端响应式:**在 375px 视口宽度下测试所有布局——卡片网格使用 CSS Grid minmax(320px, 1fr)

评估检查器要求:

  • 存在且可正常运行 cycleTheme() 函数(可更改 html 类)
  • 存在 toggleMenu() 函数,且可在点击外部区域时关闭菜单
  • 顶层 JavaScript 变量使用 var 声明
  • 在 375px 宽度下没有水平溢出
  • 除基本菜单外还包含交互元素(悬停状态、图表交互等)

骨架模板会自动提供所有必需功能。始终从 skeleton.md 开始,以避免实现错误。

语义化 HTML 要求

所有可视化内容都必须包含以下语义元素:

必需结构:

  • 使用 <main> 元素包含主要内容
  • 使用 <section> 元素划分主要内容块
  • 地标角色(role="banner"、role="main"、role="complementary")或“跳转到内容”链接
  • 图表无障碍:在图表容器上设置 role="img" 和 aria-label

其他要求:

  • 定义 @media print 样式
  • 定义 @media (prefers-reduced-motion) 样式,以满足无障碍要求
  • 各部分之间留出足够间距(≥48px)
  • 为交互元素设置悬停状态

可视化类型

选择合适的格式。详细模式请参阅 references/types.md。

类型适用场景关键特点
幻灯片演示文稿演示、提案16:9、键盘导航、转场效果
信息图数据摘要、可视化叙事长页面滚动、大号数字、分区展示
仪表板指标、KPI卡片网格 + 图表
流程图流程、架构Mermaid 或 SVG 图表
时间线按时间顺序排列的事件左右交替、滚动触发
对比图并列分析特性矩阵、优缺点
数据可视化图表、数据叙事Chart.js 或 D3
单页文档摘要、简报单视口、便于打印
思维导图概念关系径向 SVG 布局
看板状态跟踪基于列的卡片
轮播卡片社交媒体(IG/LinkedIn)每张卡片 1080×1080,可滑动、大号文字
活动海报会议、聚会、网络研讨会竖版 A4/letter、大标题、日期/场地
简历/CV求职申请单页、双栏、针对打印优化
横幅/页眉邮件、博客、社交媒体封面1200×630 或 1500×500,视觉背景上居中显示文字
引言卡片社会认同、用户评价竖版/方形、大号引言、署名
流程指南操作指南、分步教程编号步骤、图标、流程清晰
状态报告高管进展汇报KPI + 进度条 + 要点,一页展示
组织结构图团队结构层级树、照片/头像、职位
数据故事叙事 + 数据滚动叙事,图表穿插于叙述文字中
产品卡片功能亮点、产品发布主视觉图片区域、功能标签、CTA
轮播卡片规则

轮播卡片对社交媒体非常重要。请遵循以下规则:

  • 正方形格式 — 1080×1080px(或通过 CSS var 配置)
  • 每张卡片表达一个观点 — 醒目的标题 + 最多 1-2 个辅助要点
  • 滑动导航 — 箭头 + 圆点 + 触控滑动 + 键盘操作
  • 卡片计数器 — 显示“3 / 8”
  • 全部下载 — 将单张卡片或整组卡片导出为 PNG
  • 以排版为主 — 标题字号为 2.5-4rem,正文尽量精简
  • 颜色区分 — 每张卡片都可以有细微变化的强调色
  • 打印布局 — 以网格形式展示所有卡片,方便打印
  • 最多 10 张卡片 — 内容应聚焦
活动海报规则
  • 纵向排版 — A4/letter 比例或正方形
  • 视觉层级 — 活动名称(最大)→ 日期/时间 → 地点 → 描述 → CTA
  • 醒目标题 — 3-5rem,最多 6 个词
  • 突出日期/时间 — 设计成徽章或高亮区块
  • 二维码区域 — 用占位框表示报名链接
  • 优先考虑打印 — 深色或浅色主题打印效果都出色
引言卡片规则
  • 大号引号 — 使用强调色装饰性地展示“ ”,并放大字号
  • 引言文字 — 1.5-2.5rem,可使用衬线字体或斜体字重形成对比
  • 署名 — 在引言下方标注姓名、职位、公司
  • 正方形或纵向排版 — 针对社交分享优化
  • 设计简洁 — 以引言为主角,其他元素保持低调
单屏 / 适配手机规则(海报、卡片、单页)

当用户要求内容适配“一个屏幕”“手机屏幕”“9:16”或“适配手机”时,应创建固定尺寸的单视口可视化内容,而不是可滚动页面。

尺寸:

  • 9:16 纵向(手机): width: 1080px; height: 1920px; — 标准 Instagram Story / 手机屏幕
  • 1:1 正方形: width: 1080px; height: 1080px; — Instagram 帖子
  • 4:5 纵向: width: 1080px; height: 1350px; — Instagram 纵向帖子
  • 16:9 横向: width: 1920px; height: 1080px; — 演示文稿幻灯片

关键 CSS 模式:

body {
  width: 1080px; height: 1920px; /* or chosen ratio */
  overflow: hidden; /* MUST — prevents scroll, enforces single screen */
  display: flex; flex-direction: column; /* Flex column fills canvas completely */
}
.poster-header { padding: 44px 48px 0; }
.poster-grid { flex: 1; padding: 24px 48px 0; } /* flex:1 expands to fill remaining space */
.poster-footer { padding: 16px 48px 36px; }

布局规则:

  • 在 body 上设置 overflow: hidden — 这是实现“单屏”的关键,不容妥协。
  • 在主容器上设置 justify-content: space-between — 均匀分布各个区块,不留大片空隙。
  • 在主要内容区域(网格、正文等)上使用 flex: 1,使其扩展并填满页眉和页脚之间的所有剩余空间。切勿使用会留下大片空白的固定 height 值。
  • 将每个逻辑区块包裹在 <div> 中,使 flexbox 能以区块为单位分配空间。
  • 杜绝空白规则: 海报画布应 100% 得到利用。底部或两侧不能留有大片空白边距。如果存在明显空白,要么扩展内容填满空间,要么缩小内边距。内容应与画布完美契合。
  • 在脑海中测试: 统计区块数量,将 1920px 分配给它们。每个区块约占 200-300px。如果内容稀疏,就放大元素(增大字号、增加内边距、放大图标)。
  • 固定尺寸海报不要使用汉堡菜单 — 它会浪费空间,而且海报是为截图/导出而设计的,不用于交互。

9:16 的内容密度:

  • 主视觉(标题 + 副标题):约占高度的 25%
  • 2-3 个内容区块:约占高度的 55%
  • 页脚/CTA:约占高度的 10%
  • 留白(间距):约占高度的 10%
  • 如果看起来空荡荡,说明内容太小。 放大字体、增加网格项目、使用更大的图标。

宽度为 1080px 的海报字体大小:

  • 主视觉 h1:68-80px(比网页上的更大 — 这是海报)
  • 区块标签:15-18px,大写,字母间距为 0.06em
  • 卡片文字:16-20px
  • 正文:20-24px

常见错误: 创建可滚动页面并对其截图。这不是海报,而是网页截图。海报是固定画布,每个像素都经过精心安排。

幻灯片规则

幻灯片是最常见的请求。请确保以下规则正确:

  • 16:9 宽高比 — 100vw × 100vh,内容居中
  • 响应式断点 — 使用 clamp() 和容器查询,让幻灯片适配移动设备:
    .slide-container { container-type: inline-size; }
    .slide-title { font-size: clamp(2rem, 8vw, 4rem); }
    @container (width < 768px) { .slide-content { padding: 1rem; } }
    
  • 每张幻灯片只讲一个想法 — 如果还需要补充第二个想法,就另做一张幻灯片
  • 每张幻灯片最多 40 个单词 — 超出时拆分内容或使用视觉元素
  • 标题最多 6 个单词 — 简短有力、令人难忘
  • 统计数据幻灯片采用大数字 + 小标签 — 数字设为 3-5rem,标签设为 0.875rem
  • 键盘导航 — ← → 方向键、Space、Enter
  • 触控导航 — 向左/向右滑动
  • 点击导航 — 左侧三分之一 = 上一张,右侧三分之二 = 下一张
  • 进度条 — 顶部的细渐变条,显示当前位置
  • 幻灯片计数器 — 在底部导航中显示 "3 / 12"
  • 突出移动端导航 — 确保移动设备上清晰显示导航控件。使用更大的触控区域(最小 44px)、对比鲜明的颜色,并为浮动导航添加 backdrop-blur
  • 平滑过渡 — 使用 transform: translateX(),持续时间为 500ms,并采用 cubic-bezier
  • 入场动画 — 幻灯片中的元素依次延迟播放入场动画
  • 演讲者备注 — 使用 data-notes 属性,仅在打印时显示
高影响力演示幻灯片(商业场景)

适用于投资者演示、初创公司路演和高管简报:

  • 强化主视觉幻灯片的视觉效果 — 使用更强烈的渐变、更大的字体(4-6rem),并醒目地展示引人注目的统计数据
  • 清晰传达价值主张 — 主视觉幻灯片应在 5 秒内传达核心价值
  • 彰显专业可信度 — 确保字体、间距和颜色选择符合企业级和投资级预期
  • 用数据讲述故事 — 每张图表幻灯片都应明确标出洞察,而不只是展示原始数据
适配主题的幻灯片渐变(重要)

幻灯片在深色和浅色主题下必须呈现明显不同的视觉效果。渐变背景必须随主题变化:

/* Dark theme: deep, saturated gradients */
.theme-dark .slide-title { background: linear-gradient(135deg, #1e1b4b 0%, #312e81 50%, #1e3a5f 100%); }
.theme-dark .slide-content { background: var(--bg); }

/* Light theme: soft, pastel gradients */
.theme-light .slide-title { background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 50%, #dbeafe 100%); }
.theme-light .slide-content { background: var(--bg); }

规则:

  • 标题/章节幻灯片:使用主题专属的渐变组合(深色主题 = 深沉且饱和,浅色主题 = 柔和且淡雅)。选择能体现内容主题的渐变颜色——科技路演使用冷蓝色,游戏路演使用鲜艳的紫色/青色,医疗演示文稿使用舒缓的绿色/蓝绿色。
  • 内容幻灯片:使用 var(--bg) 或 var(--surface),不要使用硬编码的深色背景
  • 幻灯片上的数据卡片:使用 var(--surface) 和 var(--border),它们会自动适配
  • 不要在幻灯片内容中硬编码 #1a1a2e 或类似的深色——请使用 CSS 变量
  • 测试:切换主题,确保每张幻灯片在对应模式下都经过精心设计
幻灯片类型
  1. 标题 — 适配主题的渐变背景、大标题、副标题。居中对齐。
  2. 内容 — 标题 + 项目符号,或标题 + 视觉元素。避免文字过多。
  3. 章节分隔页 — 全出血强调色,仅显示章节标题。
  4. 统计数据 — 一个大数字、一个标签、一句洞察。
  5. 图表 — 使用 Chart.js 可视化,并附标题和关键结论。必须使用 chart-container 包装类。
  6. 双栏 — 拆分布局,用于对比或组合文字与视觉元素。
  7. 引言 — 大号引用内容,并注明出处。
  8. 结束页 — 行动号召、联系信息,或摘要 + 社交链接。
幻灯片图表要求(重要)

演示文稿中的图表幻灯片必须遵循与仪表板相同的容器标准:

<div class="chart-slide-container">
  <h2>Chart Title</h2>
  <div class="chart-container" style="height: 400px; padding: 40px; border-radius: 12px; background: var(--surface);">
    <canvas id="slideChart" role="img" aria-label="Description"></canvas>
  </div>
</div>
  • 使用 chart-container 类 — 确保不同格式的评估标准一致
  • 幻灯片图表的最小高度为 400px — 高于仪表板图表,以便在演示文稿中清晰阅读
  • maintainAspectRatio: false — 正确适配幻灯片布局的必要设置

数据导入

用户提供数据时:

  • CSV — 使用 JS 解析,自动检测表头,并渲染合适的图表类型
  • JSON — 提取键作为标签、值作为数据,将嵌套对象作为数据系列
  • 表格 — 转换为可视化对比图或图表
  • 文本中的数字 — 提取并突出显示为统计卡片
  • URL — 抓取内容、提取关键信息,并将其可视化为摘要

上下文感知

此技能用于对话进行期间。充分利用所有内容:

  • 对话上下文 — 总结、整理或可视化已讨论的内容
  • URL/链接 — 抓取并提取内容,然后进行可视化
  • 粘贴的数据 — CSV、JSON、表格 → 图表、仪表板
  • 想法/概念 — 将抽象讨论转化为可视化图表
  • 代码/架构 — 可视化系统设计、数据流

始终使用真实内容。有真实上下文时,切勿生成占位数据。

特定类型的交互性(必须遵守)

每个文件都必须至少包含一种有意义的交互,主题切换和菜单除外。交互性不足的静态页面得分较低。

类型必需的交互
速查表搜索/筛选输入框 + 代码块的复制到剪贴板功能。使用 <details name="..."> 创建可折叠分组。
仪表板筛选工具栏或指标下钻。至少提供日期范围或类别筛选器。
状态报告可折叠的详情区域(使用 <details>)。进度条在滚动时进行动画展示。
引言卡片自动轮播引言,或支持滑动的轮播。提供分享/复制按钮。
活动海报带动画的倒计时(天/小时/分钟/秒)。提供 RSVP/注册按钮。
流程指南将步骤设为互斥手风琴(<details name="steps">)。或者使用交互式进度跟踪器。
架构图提供可点击节点,并显示弹出详情(使用 Popover API)。悬停时高亮关联项。
时间线按时代/类别筛选。或者点击以展开事件详情。
对比切换类别的显示/隐藏。或者逐行突出显示优胜项。
轮播支持触屏滑动 + 键盘操作 + 自动前进选项。始终显示卡片计数。
幻灯片已具备交互性(导航)。添加:演讲者计时器、幻灯片概览网格。

如果类型未列出,至少添加一种筛选、搜索、排序或展开/折叠交互。

布局变化(至关重要)

每个文件都必须呈现独特的设计,而不是只替换文字的模板。根据文件类型调整以下内容:

  • 网格结构:混合使用 1 列、2 列和 3 列布局。使用 CSS Grid 的 span 2 设置重点卡片。至关重要:务必在 768px 和 375px 屏幕宽度下进行测试,不得出现水平溢出。

移动优先的响应式模式(必须遵守):

.grid { 
  display: grid; 
  gap: 24px; 
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); 
}
@media (max-width: 768px) { 
  .grid { grid-template-columns: 1fr; gap: 16px; }
  .container { padding: 24px 16px; }
}
@media (max-width: 375px) {
  .card { padding: 16px; }  
  .stat-value { font-size: 2rem; }
}
  • 区块节奏:交替使用全宽区块、卡片网格和单焦点区块。
  • 内容密度:小尺寸下内容更丰富,比大尺寸下内容稀疏更显专业。包含 8 张 KPI 卡片 + 4 张图表的仪表板更真实;4 张 KPI 卡片 + 2 张图表则更像演示样例。
  • 视觉焦点:每个文件都需要一个视觉主导元素(重点数据、关键图表、主要信息),而不是所有元素权重相同。
  • 避免网格中出现落单项:网格项目数量为奇数且最后一行未填满时,为最后一个项目使用 grid-column: span 2,或调整 grid-template-columns,避免最后一行只剩一张卡片。

反模式

  • ❌ 大段文字 — 如果读起来像文档,那就不是可视化
  • ❌ 字体过小 — 正文至少 14px,演示标题至少 20px
  • ❌ 彩虹配色 — 使用调色板中的 2~3 种颜色,再搭配中性色
  • ❌ 占位内容 — 切勿使用“Lorem ipsum”或虚假数据
  • ❌ 过度设计 — 选择最简单且视觉效果出色的方案
  • ❌ 布局拥挤 — 拿不准时,就增加留白
  • ❌ 设计千篇一律 — 每种可视化都应有明确的设计意图,而不是套用模板
  • ❌ 缺少菜单 — 每个输出都必须包含汉堡菜单
  • ❌ 打印样式损坏 — 务必包含 @media print 样式

高级技巧

仅在有助于提升效果时使用。代码片段请参阅 references/css-techniques.md。

  • 玻璃拟态 — 使用 backdrop-blur-md bg-white/5 border border-white/10 创建悬浮卡片
  • 渐变文本 — 在主视觉标题中使用 background: linear-gradient(...); -webkit-background-clip: text
  • 滚动吸附 — 使用 scroll-snap-type: y mandatory 作为替代幻灯片导航的方式(无需 JS)
  • 圆锥渐变 — 使用 conic-gradient() 绘制纯 CSS 饼图/圆环图
  • 数字动画 — 滚动时将计数器从 0 动画递增至目标值
  • 弹簧缓动 — 使用 cubic-bezier(0.34, 1.56, 0.64, 1) 实现活泼的微交互
  • 动画过渡到 auto — 在 :root 上设置 interpolate-size: allow-keywords,即可实现平滑的 height: auto 过渡(Chrome 129+)
  • CSS 计数器 — 为分步骤流程自动编号
  • View Transitions API — 实现平滑的主题切换动画
  • 内联 SVG 图标 — 将简单图标绘制为 <svg> 路径,无需图标库

强制使用的 HTML 骨架

每个可视化内容都必须从此骨架开始。 复制后再添加内容。

完整骨架代码: 完整的可复制 HTML 模板(包含主题、打印样式、Inter 字体、动画、菜单和悬停效果),请参阅 references/skeleton.md。

骨架提供:

  • 基于类的深色/浅色主题(首次访问时检测 OS 设置,并通过 localStorage 持久保存)
  • CSS @keyframes 动画(fadeInUp、fadeIn、slideInLeft、slideInRight)以及 .animate/.delay-N 类
  • 通过 data-reveal 属性和 IntersectionObserver 实现滚动显示
  • 通过 data-count 属性实现数字计数器
  • 汉堡菜单,包含主题切换、PNG 下载(html-to-image)和打印/PDF 功能
  • Popover 和 details 手风琴样式(Chrome 114+/120+)
  • 使用 @page 边距框的打印样式
  • 支持 prefers-reduced-motion
骨架规则
  • 所有顶层 JS 变量都使用 var(避免 TDZ 错误)
  • 强制要求: 使用 data-reveal 实现滚动动画,或使用 .animate.delay-N 实现页面加载入场动画。为 .reveal 类添加 JavaScript 滚动观察器。
  • 定义 function onThemeChange() {},以便在切换主题时重新渲染图表
  • 使用语义化 HTML:<main>、<section>、<header>、<article>
  • 不要在脚本顶层使用 let/const

最小尺寸规则

元素必须足够大,确保清晰易读且具有足够的视觉分量:

  • 时间线卡片: 最小宽度 280px,最小内边距 20px
  • 时间线布局: 均匀分布时间线项目,避免出现大块空白。如果有 5 个项目,但只占用了 60% 的垂直空间,请添加更多内容区块(例如投资细分或影响指标),填满剩余的 40%。最后一个时间线项目下方绝不能留下大片空白。
  • 图表容器: 最小宽度为父容器的 60%,最小高度为 300px(仪表板为 360px+)。在网格布局中,图表应使用 flex-grow: 1 填满可用空间——300px 是下限,而非目标值。
  • 统计数字: 最小字号为 2rem (32px),字重为 bold/extrabold
  • 卡片内容区: 最小内边距 24px
  • 区块间距: 强制要求主要区块之间至少间隔 48px——在区块元素上使用 margin-bottom: 48px 或更大的值
  • 幻灯片标题: 最小字号为 2rem (32px),最多 6 个词
  • 正文: 最小字号为 1rem (16px),不得更小

如果内容看起来太小,那就确实太小。宁可做大一些。

文本可见性规则

文本必须始终清晰可见。 这是输出出错的首要原因。

  • 深色主题:文本必须使用 var(--text),其值为 #f9fafb(近白色)
  • 浅色主题:文本必须使用 var(--text),其值为 #0f172a(近黑色)
  • 渐变背景上:添加 text-shadow: 0 1px 3px rgba(0,0,0,0.3),提升可读性
  • 渐变/图片背景的主视觉幻灯片上:使用深色遮罩(rgba(0,0,0,0.5))
  • 绝不将文本颜色设置为与背景颜色接近的值
  • 在心中测试:“这段文本在深色 (#030712) 和浅色 (#f8fafc) 背景上都清晰可见吗?”

Chart.js 集成规则(关键 — 最常见的失败原因)

图表是第二常见的失败原因。以下规则对每个图表都必须遵守:

1. 容器结构(必需)

<div role="img" aria-label="Detailed description of chart data and insights">
  <div class="chart-container" style="height: 360px; padding: 40px; border-radius: 12px; background: var(--surface);">
    <canvas id="uniqueChartId"></canvas>
  </div>
</div>
2. Canvas 尺寸(必需)
  • **容器必须设置明确的高度:**仪表板至少为 360px,其他类型至少为 300px
  • Canvas 元素无需设置尺寸——当 maintainAspectRatio: false 时,Chart.js 会处理
  • **容器内边距:**设置 40px 内边距,呈现专业的间距效果
  • **容器圆角:**设置为 12px,呈现现代卡片外观
3. Chart.js 初始化(强制模式)
// REQUIRED: Chart destruction and canvas reset to prevent "Canvas already in use" errors
var chartsBuilt = false; // Guard flag

function buildCharts() {
  if (chartsBuilt) return; // Prevent double-initialization during theme detection
  
  // REQUIRED: Reset canvas before building
  function resetCanvas(id) {
    var old = document.getElementById(id);
    if (!old) return null;
    var parent = old.parentNode;
    var canvas = document.createElement('canvas');
    canvas.id = id;
    parent.replaceChild(canvas, old);
    return canvas;
  }
  
  // Example chart with required settings
  var ctx = resetCanvas('myChart');
  if (ctx) {
    new Chart(ctx, {
      type: 'bar',
      data: { /* your data */ },
      options: {
        responsive: true,
        maintainAspectRatio: false, // REQUIRED
        animation: false, // MANDATORY: Plus set Chart.defaults.animation = false globally
        plugins: {
          tooltip: {
            enabled: true, // NEVER disable tooltips
            padding: 12,
            cornerRadius: 8
          }
        },
        layout: { padding: 20 } // REQUIRED: breathing room
      }
    });
  }
  
  chartsBuilt = true; // Mark as built
}

// CRITICAL: Disable Chart.js default animations IMMEDIATELY after Chart.js loads
Chart.defaults.animation = false; // MUST be set before any chart creation

// REQUIRED: Build charts after DOM loads
document.addEventListener('DOMContentLoaded', buildCharts);

// REQUIRED: Rebuild charts on theme change
function onThemeChange() {
  chartsBuilt = false; // Reset flag
  setTimeout(buildCharts, 100); // Slight delay for CSS variable updates
}
  • 必须启用悬停工具提示——绝不要禁用 Chart.js 工具提示:
    options: {
      plugins: {
        tooltip: {
          enabled: true, // NEVER set to false
          mode: 'index',
          intersect: false
        }
      }
    }
    
  • **图表最小高度:**桌面端为 300px,移动端为 250px
  • **默认字体大小:**坐标轴刻度标签至少为 13px,坐标轴标题为 14px,图表标题至少为 16px。图例为 13px。
  • **图表内边距:**添加 layout: { padding: { top: 20, right: 20, bottom: 20, left: 20 } },留出充足空间
  • **坐标轴刻度配置:**设置 maxRotation: 0,让标签保持水平。如果标签超出空间,请使用 maxTicksLimit 减少数量
  • **网格线:**颜色要非常淡——深色主题使用 rgba(255,255,255,0.04),浅色主题使用 rgba(0,0,0,0.06)
  • **工具提示样式:**设置 padding: 12、cornerRadius: 8、titleFont: { size: 14 }、bodyFont: { size: 13 }
  • **数据点半径:**默认设为 0,悬停时设为 6——让折线图更简洁
  • 设置 maintainAspectRatio: false,并通过 CSS 容器控制尺寸
  • **使用适配主题的颜色:**在渲染时读取 CSS 变量,并在主题变更时重新渲染
  • **图表文本颜色:**设置 Chart.defaults.color = getComputedStyle(root).getPropertyValue('--text-secondary').trim()
  • **网格线颜色:**使用 var(--border) 的值
  • **图例位置:**横向图表设为 'top',有足够空间的纵向图表设为 'right'
  • **坐标轴标签:**尽可能保持水平——除非绝对必要,否则避免旋转
  • **环形图/饼图:**始终在扇区上标注百分比
  • 响应式:responsive: true 是默认值,但容器必须有明确的尺寸
  • **高对比度颜色:**确保数据系列之间有足够的颜色差异,以满足无障碍要求
// Theme-aware Chart.js setup (include in every chart visualization)
function getChartColors() {
  var s = getComputedStyle(document.documentElement);
  return {
    text: s.getPropertyValue('--text').trim(),
    textSecondary: s.getPropertyValue('--text-secondary').trim(),
    border: s.getPropertyValue('--border').trim(),
    surface: s.getPropertyValue('--surface').trim(),
    accent: s.getPropertyValue('--accent').trim(),
  };
}

// REQUIRED: Reset canvas before rebuilding charts (prevents "Canvas already in use" errors)
function resetCanvas(id) {
  var old = document.getElementById(id);
  var parent = old.parentNode;
  var canvas = document.createElement('canvas');
  canvas.id = id;
  parent.replaceChild(canvas, old);
  return canvas;
}

// Usage in buildCharts():
//   try { if (window.myChart) window.myChart.destroy(); } catch(e) {}
//   window.myChart = new Chart(resetCanvas('myChart'), { ... });

// CRITICAL: Always check chart existence before destroy() to prevent console errors
function buildCharts() {
  var isDark = document.documentElement.classList.contains('theme-dark');
  var colors = getChartColors();
  
  // Safe chart destruction and rebuild pattern
  if (window.myChart) {
    try { window.myChart.destroy(); } catch(e) { /* ignore */ }
  }
  window.myChart = new Chart(resetCanvas('myChart'), {
    // chart config with theme-aware colors
    options: {
      scales: {
        x: { ticks: { color: colors.textSecondary }, grid: { color: colors.border } },
        y: { ticks: { color: colors.textSecondary }, grid: { color: colors.border } }
      }
    }
  });
}

关键调试模式

计数器动画调试模式

如果 KPI 数值显示为“0%”而没有动画,请添加此调试模式:

// DEBUG: Add after counter observer setup to verify intersection
var counterEl = document.querySelector('[data-count]');
if (counterEl) {
  console.log('Counter element found:', counterEl); // DEBUG
  var cObs = new IntersectionObserver(function(entries) {
    console.log('Counter intersection triggered:', entries); // DEBUG
    entries.forEach(function(e) { 
      if (e.isIntersecting) { 
        console.log('Starting counter animation'); // DEBUG
        animateCounters(); 
        cObs.disconnect(); 
      } 
    });
  }, { threshold: 0.3 });
  cObs.observe(counterEl);
} else {
  console.warn('No [data-count] elements found'); // DEBUG
}
Chart.js 集成安全模式

所有 Chart.js 用法都必须遵循此模式,以防止控制台错误:

// STEP 1: Global variables - MUST use var, never let/const
var chartsBuilt = false;

// STEP 2: Chart building function with validation
function buildCharts() {
  // CRITICAL: Always validate Chart.js loaded first
  if (chartsBuilt || typeof Chart === 'undefined') return;
  
  // STEP 3: Destroy existing charts to prevent "Canvas already in use"
  if (window.myChart) window.myChart.destroy();
  
  // STEP 4: Reset canvas elements
  var canvas = document.getElementById('chartId');
  if (!canvas) return;
  
  // STEP 5: Get theme colors from CSS variables
  var isDark = document.documentElement.className.includes('theme-dark');
  var textColor = isDark ? '#EDEDED' : '#0f172a';
  var gridColor = isDark ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.06)';
  
  // STEP 6: Create chart with proper options
  try {
    window.myChart = new Chart(canvas.getContext('2d'), {
      // Your chart configuration here
      options: {
        responsive: true,
        maintainAspectRatio: false, // REQUIRED
        plugins: {
          tooltip: { enabled: true }, // REQUIRED - never disable
          legend: { 
            labels: { color: textColor, font: { family: 'Inter' } }
          }
        },
        scales: {
          x: { 
            ticks: { color: textColor },
            grid: { color: gridColor }
          },
          y: { 
            ticks: { color: textColor },
            grid: { color: gridColor }
          }
        }
      }
    });
    
    chartsBuilt = true;
  } catch (error) {
    console.error('Chart creation failed:', error);
  }
}

// STEP 7: Theme change handler
function onThemeChange() {
  if (chartsBuilt) {
    chartsBuilt = false;
    buildCharts();
  }
    var ctx = document.getElementById('myChart');
    if (!ctx) {
      console.error('Chart canvas #myChart not found');
      return;
    }
    // ... build chart
  } catch (error) {
    console.error('Chart building failed:', error);
  }
}
修复菜单的外部点击行为

通过加强事件处理程序,确保点击菜单外部时菜单会关闭:

document.addEventListener('click', function(e) { 
  var menu = document.querySelector('.viz-menu');
  var dropdown = document.getElementById('vizMenuDropdown');
  if (!e.target.closest('.viz-menu') && dropdown) {
    dropdown.classList.remove('open');
  }
});

流程

  1. 理解 — 消息是什么?受众是谁?适合什么格式?
  2. 从骨架开始 — 复制上方的必需 HTML 骨架。绝不要从空白文件开始。
  3. 规划结构 — 在填充骨架之前,先列出内容和章节大纲
  4. 构建 — 添加内容、图表和样式。所有颜色都使用 CSS 变量。
  5. 验证清单:
    • html.theme-dark 和 html.theme-light 基于类的主题选择器(不要使用 @media prefers-color-scheme)?
    • JS 是否在首次访问时检测操作系统偏好并将其存储在 localStorage 中?
    • 所有文本是否都使用 var(--text) 或 var(--text-secondary)?
    • @media print 是否隐藏菜单并显示所有内容?
    • 是否包含 @media (prefers-reduced-motion: reduce)?
    • 是否包含带切换、主题、下载和打印功能的 .viz-menu?
    • 是否加载了正确的字体?(默认使用 Inter,韩语使用 Noto Sans KR 等)
    • 非拉丁文字内容是否使用了合适的 CJK/RTL 字体?
    • 是否通过 .animate 类(CSS @keyframes)实现入场动画?
    • 滚动章节是否使用 data-reveal(即使没有 JS 也可见)?
    • .card:hover 是否具有变换效果?
    • 所有顶层 JS 变量是否都使用 var(而非 let/const)?
    • 图表是否使用 var 声明,并带有 onThemeChange 钩子?
    • 必须: 所有图表是否都用 role="img" aria-label="..." 包裹?
    • 必须: 所有图表是否都启用了悬停工具提示(绝不可禁用)?
    • 存在统计数据时,动画数字计数器是否使用 data-count?
    • 是否使用语义化 HTML:<main>、<section>、<header>、<article>?
    • 所有图表是否都设置了明确的容器尺寸(高度 ≥300px)?
    • 主视觉区/标题文本在两种主题下是否都清晰可见?
    • 是否遵循最小尺寸规则(卡片至少 280px,文本至少 16px)?
    • 加载时控制台是否没有任何错误?

质量标准:“好,就是好”,而不是“对 AI 生成的内容来说还不错”。

评论

支持 Markdown