Files
opencloud/docs/style-system.md
Mplan 55c90e8c60 style(ui): unify sky-atlas visual system
Centralize interactive component styles, adopt the fresh eucalyptus palette, and keep map controls square with hard shadows. Update project guidance and the OpenCloud style skill to match the implementation.
2026-07-25 02:41:27 +08:00

5.1 KiB
Raw Permalink Blame History

OpenCloud 样式体系

这套体系用于让视觉规则集中、Vue 模板可读,同时保留 Tailwind 对一次性布局的灵活性。它不是“所有样式都写成全局类”,而是把会跨页面复用、带有产品语义或必须一致的规则集中管理。

分层

层级 文件 职责
设计令牌 src/styles/tokens.css 颜色、字体、渐变、阴影、动效时长等稳定决策
基础规则 src/styles/base.css 页面基线、选中文本、全局圆角策略
组件规则 src/styles/components.css 页面 Hero、容器、表单、面板、按钮等共享语义类
第三方主题 src/lib/theme.ts Naive UI 的全局主题契约;值应与设计令牌保持一致
单组件样式 Vue 文件的 <style scoped> 只属于一个功能的滑杆、动画、地图或媒体细节
一次性布局 Vue 模板中的 Tailwind 类 flex/grid、间距、响应式排列及确实只出现一次的视觉调整

src/style.css 只负责按以上顺序装配全局样式,不再直接堆放组件规则。

清新绿色策略

OpenCloud 的绿色应接近清晨的桉叶与嫩叶,而不是灰暗的苔藓色或高饱和的荧光青绿。

  • 品牌、导航与账户交互使用清透但稳重的桉叶绿。
  • 成功、通过和公开状态使用更偏嫩叶的成功绿色,与品牌色保持区分。
  • teal-* 和 emerald-* 是现有模板的兼容类名,实际色值由 tokens.css 重映射;不要假定它们仍是 Tailwind 默认色。
  • 不直接使用 Tailwind 默认 green-*、lime-*,也不要在组件里写亮绿色十六进制值或 RGB。
  • 新增绿色前先判断它属于品牌交互还是成功状态,并优先使用已有语义类或设计令牌。
语义 主色 深色 浅色表面
品牌/交互 #34745d #274c40 #f2faf6
成功/通过 #4d7f3b #35522c #f4faef

命名规则

  • 所有共享类使用 oc- 前缀,避免与 Naive UI、AMap 和 Tailwind 冲突。
  • 组件使用 .oc-block,内部结构使用 .oc-block__element,变体使用 .oc-block--modifier。
  • 变体不能脱离基础类使用,例如 oc-panel-button oc-panel-button--sky。
  • 类名描述用途,不描述当前颜色。例如使用 oc-field-error,而不是 oc-red-text。
  • 只有至少跨两个页面复用,或承载全局产品规则时才新增共享类。仅服务单一功能的代码留在组件内。

常用契约

页面结构

<section class="oc-page-hero">
  <div class="oc-container oc-container--content oc-page-hero__inner">
    <p class="oc-page-eyebrow">Cloud Upload</p>
    <h1 class="oc-page-title">上传云图</h1>
    <p class="oc-page-description">页面描述</p>
  </div>
</section>

<main class="oc-container oc-container--content oc-page-content">
  <!-- 页面内容 -->
</main>

容器宽度只有三个语义档位:oc-container--narrow、oc-container--content、oc-container--wide。不要在同类页面重复手写 max-w-* mx-auto px-*。

表单

<label class="oc-field-label">
  拍摄时间 <span class="oc-field-required">*</span>
</label>
<input class="oc-field-control" />
<p class="oc-field-help">补充说明</p>
<p class="oc-field-error">错误信息</p>

原生 input、select 和 textarea 共用 oc-field-control。尺寸或布局差异可以追加少量 Tailwind 类,例如 class="oc-field-control mt-2 resize-none"。

信息与面板

  • oc-section-label:详情面板中的字段标题。
  • oc-stat-label / oc-stat-value:统计数据的标签和值。
  • oc-inset-panel:详情中的浅色信息块。
  • oc-panel-card / oc-panel-card-soft:Naive UI 卡片的硬阴影。
  • oc-surface:普通 HTML 容器的标准白色表面。
  • oc-empty-card:空状态表面。

按钮

Naive UI 按钮继续使用 type="default",视觉语义由共享类控制:

<NButton class="oc-panel-button oc-panel-button--neutral" type="default">
  取消
</NButton>
<NButton class="oc-panel-button oc-panel-button--sky" type="default">
  保存
</NButton>

页面级主操作使用 oc-primary-button;面板内操作使用 oc-panel-button。可用变体为 neutral、sky、teal、amber、danger,不要临时创建新的强调色。其中 teal 是兼容命名,视觉上使用的是清新桉叶绿。

新增或修改样式的决策顺序

  1. 先确认现有 oc-* 类能否表达该语义。
  2. 一次性布局使用 Tailwind,不为单次 flex、gap 或响应式网格创建共享类。
  3. 跨页面重复或属于产品视觉契约时,在 components.css 增加语义类;涉及稳定视觉值时先在 tokens.css 增加令牌。
  4. 只属于一个交互或组件的规则放在对应 Vue 文件的 <style scoped> 中。
  5. 修改 Naive UI 全局值时同步检查 theme.ts 与 tokens.css。

验证

提交前运行:

npm run check:styles
npm run build

check:styles 会阻止已经淘汰的重复 class、非项目调色板以及缺少基础类的按钮修饰类回流;build 同时执行 Vue/TypeScript 类型检查和生产构建。