关于 phoenix-duskmoon-design
面向 Phoenix 页面设计的 DuskMoon 规范技能,涵盖主题、组件、颜色、排版、布局与动效,供使用该设计系统的开发者参考。
主要功能
- 01主题配置与切换
- 02组件颜色规范
- 03基于令牌的配色规则
- 04排版与布局指导
- 05表面层级与动效规则
适用场景
- 01规划 Phoenix 页面视觉方向
- 02统一应用 DuskMoon 组件颜色
- 03设计表单、导航和数据视图
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gsmlg-dev/ code-agent --skill phoenix-duskmoon-design安装后在 Claude Code 中输入/phoenix-duskmoon-design确认已加载。
详细介绍
Phoenix DuskMoon 设计规范
设计思路
在构建任何页面或视图之前,先在 DuskMoon 设计系统中确定明确的美学方向:
- 用途:此页面的功能是什么?仪表盘、表单、营销、管理还是内容?
- 密度:密集的数据 UI,还是宽松的编辑式间距——每个视图选一种
- 强调:确定最重要的单个操作或内容区块——使用主色;其他内容则弱化
- 层次:此视图需要多少层表面?扁平(1-2 层)还是分层(3-4 层)
DuskMoon 提供设计令牌——你的任务是有意识地使用它们,而不是一概而论。
主题设置
CSS 入口(必需)
@import "tailwindcss";
@plugin "@duskmoon-dev/core/plugin";
@import "phoenix_duskmoon/components";
HTML 根节点(必需)
<html lang="en" data-theme="sunshine">
主题:sunshine(浅色)、moonlight(深色)。
Body 基础样式
<body class="bg-surface text-on-surface">
每个页面都以 surface 为底色,并使用 on-surface 文字。没有例外。
主题切换器
始终在应用栏中加入 <.dm_theme_switcher />。需要 ThemeSwitcher hook。
组件默认颜色
页面外壳
| 组件 | 颜色 | 类 / 模式 |
|---|---|---|
| 应用栏 | primary | appbar appbar-primary appbar-sticky |
| 页面背景 | surface | 在 <body> 上使用 bg-surface |
| 侧边栏 | secondary | bg-secondary text-secondary-content |
| 页脚 | surface-container-high | bg-surface-container-high |
| 底部导航 | primary | color="primary" |
| 抽屉 | secondary | bg-secondary text-secondary-content |
应用栏是品牌的视觉锚点——始终使用主色。侧边栏和抽屉使用辅助色,以营造鲜明的导航标识,与内容区域区分开。页面主体始终使用 surface。页脚使用更高的表面层级,实现微妙的区隔。
<.dm_appbar title={@page_title} sticky>
<:logo>...</:logo>
<:menu to={~p"/dashboard"} active={@active == :dashboard}>Dashboard</:menu>
<:user_profile><.dm_theme_switcher /></:user_profile>
</.dm_appbar>
<div class="flex">
<aside class="bg-secondary text-secondary-content w-64 min-h-screen p-4">
<.dm_left_menu active={@current_path}>
<:menu>...</:menu>
</.dm_left_menu>
</aside>
<main class="flex-1 p-6">
<%= @inner_content %>
</main>
</div>
<.dm_page_footer label="© 2026 MyApp" />
操作
| 组件 | 默认值 | 何时更改 |
|---|---|---|
| 主按钮 | variant="primary" | 页面主要操作——每个视图仅一个 |
| 次要按钮 | variant="secondary" | 替代操作 |
| 第三级按钮 | variant="tertiary" | 强调功能、特殊突出内容 |
| 危险按钮 | variant="error" | 删除、移除、不可逆操作 |
| 幽灵按钮 | variant="ghost" | 工具栏、低强调操作、取消 |
| 链接按钮 | variant="link" | 行内文本操作 |
| 轮廓按钮 | variant="outline" | 中等强调、可切换 |
<div class="flex gap-2">
<.dm_btn variant="ghost">Cancel</.dm_btn>
<.dm_btn variant="primary">Save Changes</.dm_btn>
</div>
内容
| 组件 | 颜色 | 备注 |
|---|---|---|
| 卡片 | surface-container | 默认 CSS——无需添加类 |
| 卡片(高层级) | surface-container-high | 添加 shadow="md" |
| 模态框 / 对话框 | surface-container-highest | 最高层级 |
| 工具提示 | primary | 默认使用 color="primary" |
| 弹出层 | surface-container-high | |
| 折叠面板 | surface-container | |
| 底部弹出层 | surface-container-high | |
| Snackbar | inverse-surface 或基于类型 | 使用 type 表示语义 |
数据展示
| 组件 | 颜色 | 备注 |
|---|---|---|
| 徽章 | variant="primary" | 使用 secondary/tertiary 区分类别 |
| 芯片 | color="primary" | 状态使用语义颜色:success、error |
| 进度条 | color="primary" | 完成时使用 success,达到限制时使用 error |
| 头像 | color="primary" | 用作姓名首字母占位符的颜色 |
| 统计值 | 无颜色 | 仅对关键指标使用 color="primary" |
| 时间线 | 每项使用语义颜色 | completed = 绿色,active = primary |
| 表格 | 无颜色 | 使用 zebra + hover 提高可读性 |
表单
| 组件 | 颜色 | 备注 |
|---|---|---|
| 输入框 | 无颜色 | 使用轮廓边框。仅在需要强调时设置 color |
| 复选框 | color="primary" | |
| 单选框 | color="primary" | |
| 开关 | color="primary" | |
| 选择框 | 无颜色 | |
| 滑块 | color="primary" | |
| 评分 | color="primary" | 星级评分使用 warning |
反馈
| 组件 | 颜色 | 说明 |
|---|---|---|
| 提示 | 基于类型 | variant="info"、"success"、"warning"、"error" |
| Flash | 基于种类 | :info、:error |
| Toast | 基于类型 | 始终设置 type |
| 加载旋转指示器 | variant="primary" |
导航
| 组件 | 颜色 | 说明 |
|---|---|---|
| 应用栏 | primary | 始终使用 |
| 导航栏 | surface-container-high | navbar-surface-container-high |
| 选项卡 | 无颜色 | 激活状态 = primary 下划线 |
| 面包屑 | on-surface-variant | 弱化文本 |
| 步骤 | color="primary" | 已完成 = 填充,未开始 = 轮廓 |
| 左侧菜单 | secondary | 激活项 = primary-content 高亮 |
颜色规则
规则 1:不使用硬编码颜色
切勿使用十六进制、rgb、hsl、命名颜色或 Tailwind 调色板类(bg-blue-500、text-slate-600)。所有颜色只能来自设计令牌。
<%# FORBIDDEN %>
<div style="background: #3b82f6;">
<div class="bg-blue-500 text-white">
<%# CORRECT %>
<div class="bg-primary text-primary-content">
规则 2:背景与文本搭配使用
每个背景令牌都有对应的文本令牌。始终搭配使用。
| 背景 | 文本 |
|---|---|
bg-primary | text-primary-content |
bg-secondary | text-secondary-content |
bg-tertiary | text-tertiary-content |
bg-surface | text-on-surface |
bg-surface-container-* | text-on-surface |
bg-primary-container | text-on-primary-container |
bg-error | text-error-content |
bg-error-container | text-on-error-container |
bg-inverse-surface | text-inverse-on-surface |
规则 3:表面层级——从低到高
表面应按层级从低到高嵌套。切勿在较高层级中放置较低层级。
surface (page)
├─ secondary (sidebar, drawer)
└─ surface-container (card)
└─ surface-container-high (navbar, popover, elevated card)
└─ surface-container-highest (dialog, tooltip)
规则 4:语义颜色仅用于状态
success、warning、error、info 用于表达状态,切勿用于装饰或品牌设计。
<%# CORRECT %>
<.dm_alert variant="error">Validation failed</.dm_alert>
<.dm_badge variant="success">Active</.dm_badge>
<%# WRONG %>
<.dm_btn variant="success">Submit</.dm_btn> <%# Use primary %>
规则 5:Primary = 品牌,Secondary = 支持,Tertiary = 点缀
| 角色 | 用途 | 示例 |
|---|---|---|
| Primary | 品牌标识、主要操作、重点关注 | 应用栏、主要 CTA、激活导航项 |
| Secondary | 辅助操作、替代性强调 | 次要 CTA、切换开关 |
| Tertiary | 特别突出、装饰性点缀 | 功能徽章、点缀卡片 |
规则 6:每个视图仅设置一个主要操作
每个可见区域仅使用一个 variant="primary" 按钮。辅助操作使用 secondary、ghost 或 outline。
规则 7:图标继承颜色
dm_mdi 和 dm_bsi 默认使用 currentcolor。除非图标必须与周围文本颜色不同,否则不要设置显式的 color=。
规则 8:使用容器颜色进行柔和强调
使用 primary-container / on-primary-container 作为色调较淡、对比度较低的背景。适用于精选区域、突出卡片和选中状态。
<div class="bg-primary-container text-on-primary-container p-4 rounded-lg">
Featured content with softer emphasis
</div>
排版
字体策略
DuskMoon 不规定字体——项目可自行选择。规则:
- 为标题选择独特的展示字体,避免使用 Inter、Roboto、Arial、system-ui。可从 Google Fonts 加载或自行托管。
- 搭配简洁的正文字体,与展示字体相得益彰。
- 代码块使用等宽字体,例如 JetBrains Mono、Fira Code 或类似字体。
- 将字体定义为 CSS 变量,而非内联定义。
/* Project CSS — after DuskMoon imports */
:root {
--font-display: 'Instrument Serif', serif;
--font-body: 'DM Sans', sans-serif;
--font-mono: 'JetBrains Mono', monospace;
}
body { font-family: var(--font-body); }
h1, h2, h3 { font-family: var(--font-display); }
code, pre { font-family: var(--font-mono); }
字号比例
| 元素 | 类 | 用途 |
|---|---|---|
| 页面标题 | text-3xl font-bold | 每页一个 |
| 区块标题 | text-2xl font-semibold | |
| 卡片标题 | text-lg font-semibold | |
| 正文 | text-base | 默认 |
| 次要文本 | text-sm text-on-surface-variant | 弱化的辅助信息 |
| 说明文字 | text-xs text-on-surface-variant | 时间戳、元数据 |
文本颜色层级
| 优先级 | 令牌 | 用途 |
|---|---|---|
| 主要文本 | text-on-surface | 标题、正文、标签 |
| 次要文本 | text-on-surface-variant | 描述、提示、时间戳 |
| 禁用文本 | text-on-surface-variant 搭配 opacity-50 | 禁用状态 |
| 链接文本 | text-primary | 可点击的行内文本 |
布局组合
空间原则
- 内容页面:留白充足——主区域使用
p-6或p-8,卡片之间使用gap-6 - 数据视图:间距紧凑——主区域使用
p-4,项目之间使用gap-3 - 间距保持一致:每个视图选用一种间距级别(使用
gap-4或gap-6,不要混用) - 最大宽度:内容区域应限制宽度——宽内容使用
max-w-7xl mx-auto,文本较多时使用max-w-3xl
卡片网格
<div class="grid grid-cols-auto-fit-80 gap-6">
<.dm_card :for={item <- @items}>
<:title><%= item.name %></:title>
<%= item.description %>
</.dm_card>
</div>
侧边栏 + 内容区
<div class="flex min-h-screen">
<aside class="bg-secondary text-secondary-content w-64 border-r border-outline-variant p-4 shrink-0">
<.dm_left_menu active={@current_path} />
</aside>
<main class="flex-1 bg-surface p-6 overflow-auto">
<%= @inner_content %>
</main>
</div>
具有层次感的堆叠区块
<section class="bg-surface-container-low p-8 rounded-2xl">
<h2 class="text-2xl font-semibold mb-6">Featured</h2>
<div class="grid grid-cols-3 gap-4">
<.dm_card shadow="md">...</.dm_card>
<.dm_card shadow="md">...</.dm_card>
<.dm_card shadow="md">...</.dm_card>
</div>
</section>
背景与层次感
表面分层
不要使用扁平页面。使用表面令牌构建层次感:
<body class="bg-surface text-on-surface">
<header class="bg-primary text-primary-content">...</header>
<div class="bg-surface-container-low -mt-8 pt-12 pb-8 rounded-t-3xl">
<div class="max-w-6xl mx-auto px-6">
<.dm_card shadow="lg" class="bg-surface-container">
...
</.dm_card>
</div>
</div>
</body>
Hero 区域
使用容器颜色渐变构建 Hero 区域:
.hero {
background: linear-gradient(
135deg,
var(--color-primary-container) 0%,
var(--color-tertiary-container) 100%
);
}
遮罩与叠加层
.overlay {
background-color: hsl(var(--color-scrim) / 0.5);
backdrop-filter: blur(4px);
}
边框与分隔线
outline-variant→ 用于细微的分隔线和装饰性边框outline→ 用于交互式边框(输入框、聚焦状态)
<hr class="border-outline-variant" />
<div class="border border-outline rounded-lg">Interactive element</div>
动效与过渡
主题过渡
* {
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
卡片悬停
.interactive-card {
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.interactive-card:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-md);
}
减少动态效果
始终尊重用户偏好:
@media (prefers-reduced-motion: reduce) {
* { transition: none !important; animation: none !important; }
}
动效原则
- 每次交互只设置一个过渡属性,不要让所有元素都动起来
- 路由切换时使用页面级动画(LiveView 过渡)
- 卡片和按钮使用细微的悬停状态——
translateY(-2px)为上限 - 加载状态使用
dm_loading_spinner或骨架组件,不要自定义加载动画
反模式
- Tailwind 颜色级别——不要使用
bg-blue-500、text-gray-600,这会破坏主题切换。 - 硬编码颜色——不要使用十六进制、rgb、hsl 或颜色名称。
- 用透明度伪造表面——不要使用
bg-white/80,请使用surface-container-*令牌。 - 内联颜色样式——不要使用
style="color: ..."。 - 使用原始 HTML 而非组件——有可用的
dm_*组件时,请使用这些组件。 - 所有地方都用统一的主题色——每个视图只保留一个主要操作,辅助操作应弱化。
- 将语义颜色用于装饰——
success/error/warning/info仅用于表示状态。 - 通用字体——不要有意选择 Inter、Roboto、Arial。请选择有辨识度的字体。
- 缺少文本颜色搭配——每个
bg-*都需要搭配相应的text-*-content或text-on-*。 - 扁平布局——使用表面层级营造层次感,页面不应给人单一平面的感觉。
- 颜色运用过于保守——以主色为主、搭配鲜明点缀,效果胜过分布均匀、缺乏重点的配色。明确主次层级。
- 千篇一律的页面——每种视图类型(仪表板、表单、内容、营销)都应有独特的空间构成。不要到处复制粘贴同一种布局。