Files
aurora-admin 5ee5d829a4
Regression / regression (push) Canceled after 0s
refactor(详情页+S8): 详情页减重(导航互斥/入口去重/i18n去重) + 品牌标识入库
本提交含两条并行工作线,因互相咬合(package.json scripts、regression.yml、
npm run build 链)无法按文件干净拆分,故合并为一次自洽提交。

## 详情页减重(本轮主任务:修复「AI 干太重」)

- 导航收敛:宽屏只用右侧目录、≤1200px 只用页内 sticky 导航,纯 CSS 媒体查询
  实现(不引入 JS 宽度监听)。此前两套导航同时可见,active 状态互相打架。
- 入口去重:标题区由「查看示例/在线测试/契约 JSON」三个减为「在线测试」一个;
  契约 JSON 归入实现资源;删除示例底部重复的「在线测试」。
- 示例工具栏:删除与目录锚点重复的示例下拉选择器;「全部展开代码」只在
  示例数 >1 时出现(103 个组件里 49 个仅 1 个示例,此前恒显示)。
- 重复文案:示例区两句同义导语合并为一句。
- 首页 CTA 由 5 个减为 2 个(浏览组件/快速开始),测试总览入口挂到已有的
  通过率统计卡上,不再另占 Hero 按钮。
- 统一详情取数:抽出 fetchDetail/loadDetail 作为 details/*.json 的唯一路径,
  FAQ 不再自行 fetch 一遍,与组件页共用缓存与失败兜底。

## i18n

- 删除 12 组重复键(含整段 FAQ 说明),字典 604 → 585 唯一键。
- 删除本次改动产生的 6 个死键。
- verify-i18n.mjs 新增 `unique dictionary keys` 断言:重复键在对象字面量里
  是静默的后值覆盖,此前无从发现;现由门禁拦住。

## 文档事实修正(实测为准)

- TESTING/CONTRIBUTING:79 → 103 组件;旧断言数改为回指 tests/report.json。
- PLATFORMS:移动端 108 文件/18 端 → 282 文件/47 端;契约 5 → 47;
  令牌 17 → 15;uni-app SFC 21 → 50。
- AGENTS:断言 1405/18 页 → 1464/103 页(PC)、807/47 页(移动端)。
- package.json:YOUR-ACCOUNT 占位 → gitea 实址与 kole-ui.mymoyu.top。

## 品牌标识(并行会话成果,一并入库)

- brand-mark.json 收归真源,build:brand 生成 favicon 与单色 SVG;
  PC 与移动端共用资产,verify:brand 24 条断言。
- regression.yml 增加 verify:brand 步骤。

## 门禁与验收

新增工具:verify-component-page.mjs(86 条真实浏览器断言,随详情页改造同步
更新为「只允许一套导航可见」)、verify-brand-mark.mjs、lib/i18n-dead-keys.mjs
(只读诊断)。

回归:PC 100%(1464/1464,103 页,N/A 50)· 移动端 100%(807/807,47 页)。
门禁:component-page 86 · i18n 17 · brand 24 · routes all · smoke all ·
theme OK · isolation 31 · nav all · examples 9 · api-docs 10 · mobile-docs 12。

已知未做:i18n 另有约 44 条历史死键(非本次产生),已记为 ROADMAP S8-P6;
顶栏与悬浮区的两个主题入口为刻意设计(verify-theme 断言其互斥),未删。
2026-09-22 23:56:05 +08:00

2214 lines
84 KiB
CSS
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Kole UI 组件库文档 — 文档站样式(复用 colors_and_type.css 设计令牌) */
* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 80px; }
body {
margin: 0;
font-family: var(--kole-font-family);
color: var(--kole-color-text-body);
background: var(--kole-color-page-bg);
font-size: 14px;
line-height: 22px;
}
.hidden { display: none !important; }
a { color: var(--kole-color-brand); text-decoration: none; }
a:hover { color: var(--kole-color-brand-hover); }
/* ================= 顶部导航 ================= */
.topbar {
position: fixed;
top: 0; left: 0; right: 0;
height: 60px;
background: var(--kole-color-card-bg);
border-bottom: 1px solid var(--kole-color-border);
z-index: 100;
}
.topbar-inner {
max-width: 1440px;
margin: 0 auto;
height: 100%;
display: flex;
align-items: center;
gap: var(--kole-space-24);
padding: 0 var(--kole-space-24);
}
.logo {
display: flex;
align-items: center;
gap: 10px;
color: var(--kole-color-text-title);
flex-shrink: 0;
}
.logo:hover { color: var(--kole-color-text-title); }
.logo-mark {
width: 32px; height: 32px;
border-radius: var(--kole-radius-large);
background: var(--kole-color-brand);
color: var(--kole-color-text-inverse);
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
/* 品牌标记由 brand-mark.json 生成的单色 SVG 作为 mask 提供几何,
盒子本身仍是品牌蓝,内部标记继承 currentColor。这样 PC、移动站与 favicon
不再各自维护一份路径;mask 不参与布局,≤1366px 时仍是唯一品牌标识。 */
.logo-mark[data-brand-mark="mono"]::before {
content: '';
width: 20px; height: 20px;
display: block;
background: currentColor;
-webkit-mask: url('assets/kole-mark-mono.svg') center / contain no-repeat;
mask: url('assets/kole-mark-mono.svg') center / contain no-repeat;
}
.logo-mark svg { display: none; }
.logo-text { font-size: 16px; font-weight: 600; white-space: nowrap; }
.logo-text em { font-style: normal; font-weight: 500; color: var(--kole-color-text-secondary); }
/* ---------- 顶栏版本选择器(自成一体的下拉组件)----------
结构:.ver-picker(定位容器)> .ver-trigger(角标按钮)+ .ver-menu(下拉面板)。
菜单是绝对定位,**必须**锚在这个 position:relative 的容器上;早先直接放在
.topbar-inner 里时容器没有定位,菜单锚到了页面 → 实测跑到了左上角。
面板右对齐(角标在顶栏靠左,但右对齐能让长版本号也不越出视口),
窄屏再退化为只露版本号。 */
.ver-picker { position: relative; flex-shrink: 0; }
.ver-trigger {
display: inline-flex; align-items: center; gap: 4px;
height: 22px; padding: 0 7px;
border: 1px solid transparent; border-radius: var(--kole-radius-small);
background: var(--kole-color-brand-bg);
color: var(--kole-color-brand);
font-family: var(--kole-font-family-num); font-size: 12px; font-weight: 500;
cursor: pointer; flex-shrink: 0;
transition: border-color .15s, background .15s, color .15s, box-shadow .15s;
}
.ver-trigger:hover { border-color: var(--kole-color-brand); }
.ver-trigger:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 1px; }
.ver-trigger[aria-expanded="true"] {
border-color: var(--kole-color-brand);
box-shadow: 0 0 0 2px var(--kole-color-focus-ring);
}
.ver-caret { opacity: .75; transition: transform .18s ease; }
.ver-trigger[aria-expanded="true"] .ver-caret { transform: rotate(180deg); }
/* data-single="1" 只出现在「清单拿不到任何版本」时(未构建/未部署):
退回纯角标观感,不留一个点不开的下拉。只要清单里有版本(哪怕只有一版)就是正常下拉。 */
.ver-trigger[data-single="1"] { pointer-events: none; }
.ver-trigger[data-single="1"] .ver-caret { display: none; }
.ver-menu {
/* 左对齐到触发角标(角标在顶栏靠左,右对齐会让 216px 面板从左侧溢出视口);
width 用 min() 跟着视口收,窄屏不会顶出右边界。 */
position: absolute; top: calc(100% + 8px); left: 0; z-index: 130;
width: min(216px, calc(100vw - 24px));
padding: 6px;
display: flex; flex-direction: column; gap: 2px;
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
box-shadow: var(--kole-shadow-high);
animation: ver-menu-in .16s ease-out;
}
.ver-menu.hidden { display: none; }
@keyframes ver-menu-in {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: translateY(0); }
}
.ver-menu-head {
padding: 3px 8px 7px; margin-bottom: 2px;
border-bottom: 1px solid var(--kole-color-border);
color: var(--kole-color-text-secondary); font-size: 11px; line-height: 16px;
}
.ver-opt {
display: flex; align-items: center; gap: 8px;
width: 100%; min-height: 32px; padding: 0 8px;
border: 0; border-radius: var(--kole-radius-small);
background: transparent; color: var(--kole-color-text-body);
font: inherit; font-size: 13px; text-align: left; cursor: pointer;
}
.ver-opt:hover,
.ver-opt:focus-visible { background: var(--kole-color-brand-bg); color: var(--kole-color-brand); outline: none; }
.ver-opt[aria-selected="true"] { color: var(--kole-color-brand); font-weight: 600; }
.ver-opt-num { flex: 1; white-space: nowrap; font-family: var(--kole-font-family-num); }
.ver-opt-tag {
font-family: var(--kole-font-family-num); font-size: 10.5px; letter-spacing: .04em;
color: var(--kole-color-text-placeholder); white-space: nowrap;
}
.ver-opt[aria-selected="true"] .ver-opt-tag { color: var(--kole-color-brand); }
.ver-opt-check { flex: 0 0 auto; opacity: 0; transition: opacity .12s; }
.ver-opt[aria-selected="true"] .ver-opt-check { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
.ver-menu { animation: none; }
.ver-caret, .ver-opt-check { transition: none; }
}
.search-trigger {
flex: 1;
max-width: 360px;
height: 34px;
display: flex;
align-items: center;
gap: 8px;
padding: 0 12px;
border: 1px solid transparent;
border-radius: var(--kole-radius-base);
background: var(--kole-color-page-bg);
color: var(--kole-color-text-placeholder);
font-size: 13px;
font-family: inherit;
cursor: pointer;
transition: background .15s, border-color .15s;
}
.search-trigger:hover { background: var(--kole-color-table-header-bg); border-color: var(--kole-color-border); }
.search-trigger .st-text { flex: 1; text-align: left; color: var(--kole-color-text-secondary); }
.search-trigger kbd {
font-family: var(--kole-font-family-num);
font-size: 11px;
color: var(--kole-color-text-secondary);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-small);
background: var(--kole-color-card-bg);
padding: 1px 5px;
}
.topnav {
margin-left: auto;
display: flex;
align-items: center;
gap: var(--kole-space-8);
height: 100%;
}
.topnav a {
position: relative;
display: flex;
align-items: center;
height: 100%;
padding: 0 var(--kole-space-12);
color: var(--kole-color-text-body);
font-size: 14px;
}
.topnav a:hover { color: var(--kole-color-brand); }
.topnav a.active { color: var(--kole-color-brand); font-weight: 500; }
/* 语言切换:下拉选择(触发器 + 语言菜单),与悬浮主题菜单同一套令牌语言 */
.lang-select { position: relative; margin-left: 12px; flex-shrink: 0; }
/* ---- 顶栏主题模式选择器(日间 / 夜间 / 自动)----
与 .lang-trigger 同一档高度与圆角;不同处:图标带品牌色底衬(这是全站唯一的「主题」入口,
需要一点视觉权重),展开态用 2px 光晕而不是换底色。菜单沿用 .mode-menu 的选项样式,
只把定位从「悬浮按钮左侧」改成「触发器下方」。 */
.theme-select { position: relative; margin-left: 12px; flex-shrink: 0; }
.theme-trigger {
height: 34px; padding: 0 11px 0 6px;
display: inline-flex; align-items: center; gap: 8px;
border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg); cursor: pointer;
font-family: var(--kole-font-family); font-size: 13px;
color: var(--kole-color-text-body);
transition: border-color .16s ease, color .16s ease, box-shadow .16s ease;
}
.theme-trigger:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.theme-trigger:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 1px; }
.theme-trigger[aria-expanded="true"] {
border-color: var(--kole-color-brand);
color: var(--kole-color-brand);
box-shadow: 0 0 0 2px var(--kole-color-focus-ring);
}
/* 图标底衬:15×15 的浅色圆角块(**不撑大触发器** —— 1367px 顶栏只剩 24px 余量,
任何加宽都会溢出)。hover / 展开时换成品牌浅底,给出「这是可点的主题入口」的提示。 */
.theme-icon {
flex: 0 0 auto;
border-radius: var(--kole-radius-small);
background: var(--kole-color-table-header-bg);
transition: background .16s ease;
}
.theme-trigger:hover .theme-icon,
.theme-trigger[aria-expanded="true"] .theme-icon { background: var(--kole-color-brand-bg); }
.theme-cur { line-height: 1; white-space: nowrap; font-weight: 500; }
/* 不加下拉箭头:顶栏在 1367px(英文,导航尚未折叠)原本只剩 2px 余量,
箭头占 12px 会直接溢出(实测 6px)。按钮外观 + 点击展开的菜单已足够表达可展开。 */
.theme-caret { display: none; }
/* 顶栏菜单从触发器下方展开(悬浮按钮那份是 right:52px / bottom:0,互不影响) */
#topbar-mode-menu {
top: calc(100% + 8px);
right: 0;
left: auto;
bottom: auto;
z-index: 120;
width: 186px;
animation: lang-menu-in .16s ease-out;
}
.lang-trigger {
height: 34px; padding: 0 10px;
display: inline-flex; align-items: center; gap: 7px;
border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg); cursor: pointer;
font-family: var(--kole-font-family); font-size: 13px;
color: var(--kole-color-text-body);
transition: border-color .15s, color .15s, box-shadow .15s;
}
.lang-trigger:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.lang-trigger:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 1px; }
.lang-trigger[aria-expanded="true"] {
border-color: var(--kole-color-brand);
color: var(--kole-color-brand);
box-shadow: 0 0 0 2px var(--kole-color-focus-ring);
}
.lang-globe { flex: 0 0 auto; }
.lang-cur { line-height: 1; white-space: nowrap; }
.lang-caret { flex: 0 0 auto; opacity: .7; transition: transform .18s ease; }
.lang-trigger[aria-expanded="true"] .lang-caret { transform: rotate(180deg); }
.lang-menu {
position: absolute; top: calc(100% + 8px); right: 0; z-index: 120;
width: 186px; padding: 6px;
display: flex; flex-direction: column; gap: 2px;
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
box-shadow: var(--kole-shadow-high);
animation: lang-menu-in .16s ease-out;
}
.lang-menu.hidden { display: none; }
@keyframes lang-menu-in {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: translateY(0); }
}
.lang-head {
padding: 3px 8px 7px; margin-bottom: 2px;
border-bottom: 1px solid var(--kole-color-border);
color: var(--kole-color-text-secondary); font-size: 11px; line-height: 16px;
}
.lang-opt {
display: flex; align-items: center; gap: 8px;
width: 100%; min-height: 32px; padding: 0 8px;
border: 0; border-radius: var(--kole-radius-small);
background: transparent; color: var(--kole-color-text-body);
font: inherit; font-size: 13px; text-align: start; cursor: pointer;
}
.lang-opt:hover,
.lang-opt:focus-visible { background: var(--kole-color-brand-bg); color: var(--kole-color-brand); outline: none; }
.lang-opt[aria-selected="true"] { color: var(--kole-color-brand); font-weight: 600; }
.lang-opt-name { flex: 1; white-space: nowrap; }
.lang-opt-code {
font-family: var(--kole-font-family-num); font-size: 10.5px; letter-spacing: .04em;
color: var(--kole-color-text-placeholder);
}
.lang-opt[aria-selected="true"] .lang-opt-code { color: var(--kole-color-brand); }
.lang-check { flex: 0 0 auto; opacity: 0; transition: opacity .12s; }
.lang-opt[aria-selected="true"] .lang-check { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
.lang-menu { animation: none; }
.lang-caret, .lang-check { transition: none; }
#topbar-mode-menu { animation: none; }
.theme-caret { transition: none; }
}
/* 窄屏收起语言名(仅留图标 + 箭头,56px):实测 1100px 以下顶栏会被挤到溢出 */
@media (max-width: 1100px) {
.lang-cur { display: none; }
/* 主题模式与语言同一处理:只留图标 + 箭头(模式名在菜单里和 tooltip 里都有) */
.theme-cur { display: none; }
}
.topnav a.active::after {
content: '';
position: absolute;
left: 12px; right: 12px; bottom: 0;
height: 2px;
background: var(--kole-color-brand);
border-radius: 1px 1px 0 0;
}
/* ================= 三栏布局 ================= */
.body-wrap {
display: flex;
padding-top: 60px;
max-width: 1440px;
margin: 0 auto;
min-height: 100vh;
align-items: flex-start;
}
/* ---- 左侧栏 ---- */
.sidebar {
width: 240px;
flex-shrink: 0;
position: sticky;
top: 60px;
height: calc(100vh - 60px);
overflow-y: auto;
padding: var(--kole-space-16) var(--kole-space-8) var(--kole-space-32);
border-right: 1px solid var(--kole-color-border);
background: var(--kole-color-card-bg);
}
.side-link {
display: flex;
align-items: center;
height: 34px;
padding: 0 var(--kole-space-12);
border-radius: var(--kole-radius-base);
color: var(--kole-color-text-body);
font-size: 14px;
cursor: pointer;
border: none;
background: transparent;
width: 100%;
text-align: left;
font-family: inherit;
}
.side-link:hover { background: var(--kole-color-table-header-bg); color: var(--kole-color-brand); }
.side-link.active { background: var(--kole-color-brand-bg); color: var(--kole-color-brand); font-weight: 500; }
/* ---- 侧栏平台入口(2026-09-20 两轴模型:PC 文档站 ↔ 移动端独立站)----
比普通 side-link 高一行副标题:另一侧站里有什么,一眼能看清,不用点进去才知道。 */
.side-platform {
height: auto;
min-height: 46px;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 2px;
padding: 6px var(--kole-space-12);
}
.side-platform .sp-top { display: flex; align-items: center; gap: 6px; font-size: 14px; }
.side-platform .sp-name { white-space: nowrap; }
.side-platform .sp-badge {
height: 16px; padding: 0 6px; border-radius: 8px;
background: var(--kole-color-table-header-bg); color: var(--kole-color-text-secondary);
font-size: 10px; line-height: 16px; font-weight: 400;
}
.side-platform.active .sp-badge { background: var(--kole-color-brand); color: var(--kole-color-text-inverse); }
.side-platform .sp-sub {
font-size: 11px; line-height: 15px; font-weight: 400;
/* 亮色下 text-placeholder #767676 压浅底只有 4.16:1,不足 AA → 用 text-secondary(4.75:1) */
color: var(--kole-color-text-secondary);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.side-platform:hover .sp-sub { color: var(--kole-color-text-secondary); }
.side-group {
margin-top: var(--kole-space-16);
padding: 0 var(--kole-space-12) var(--kole-space-4);
font-size: 12px;
color: var(--kole-color-text-secondary);
display: flex;
justify-content: space-between;
align-items: center;
}
/* 段标题(开发指南 / 组件):比分类组更上位 —— 字号更小、字距拉开,与可点的分类组区分开。
文字色用 text-secondary(与 .side-group 一致):text-placeholder #767676 在页面底色 #F5F7FA 上
只有 4.23:1,达不到 AA 正文 4.5:1。 */
.side-section {
margin-top: var(--kole-space-20);
padding: 0 var(--kole-space-12) 6px;
font-size: 11px;
font-weight: 600;
letter-spacing: .08em;
color: var(--kole-color-text-secondary);
display: flex;
justify-content: space-between;
align-items: center;
}
.side-section:first-child { margin-top: var(--kole-space-8); }
.side-section .cnt {
font-family: var(--kole-font-family-num);
letter-spacing: 0;
background: var(--kole-color-table-header-bg);
border-radius: var(--kole-radius-small);
padding: 0 6px;
line-height: 18px;
font-size: 11px;
}
.side-group .cnt {
font-family: var(--kole-font-family-num);
background: var(--kole-color-table-header-bg);
border-radius: var(--kole-radius-small);
padding: 0 6px;
line-height: 18px;
font-size: 11px;
}
.side-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
height: 32px;
padding: 0 var(--kole-space-12);
border-radius: var(--kole-radius-base);
color: var(--kole-color-text-body);
font-size: 13px;
cursor: pointer;
border: none;
background: transparent;
width: 100%;
text-align: left;
font-family: inherit;
}
.side-item:hover { background: var(--kole-color-table-header-bg); color: var(--kole-color-brand); }
.side-item.active { background: var(--kole-color-brand-bg); color: var(--kole-color-brand); font-weight: 500; }
.side-item .zh { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.side-item .en {
font-family: var(--kole-font-family-num);
font-size: 11px;
color: var(--kole-color-text-secondary);
flex-shrink: 0;
}
.side-item.active .en { color: var(--kole-color-brand); opacity: .7; }
/* ---- 内容区 ---- */
.content {
flex: 1;
min-width: 0;
padding: var(--kole-space-32) var(--kole-space-40) var(--kole-space-64);
}
.page-inner { max-width: 880px; margin: 0 auto; }
.page-title {
font-size: 26px;
line-height: 34px;
font-weight: 600;
color: var(--kole-color-text-title);
margin: 0 0 4px;
}
.page-desc {
color: var(--kole-color-text-secondary);
margin: 0 0 var(--kole-space-24);
font-size: 14px;
}
.page-desc strong { font-family: var(--kole-font-family-num); color: var(--kole-color-text-body); }
/* ---- 组件总览网格 ---- */
.ov-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: var(--kole-space-16);
}
.ov-card {
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
overflow: hidden;
cursor: pointer;
transition: box-shadow .2s, transform .2s, border-color .2s;
}
.ov-card:hover {
box-shadow: var(--kole-shadow-medium);
border-color: var(--kole-color-brand);
transform: translateY(-2px);
}
.ov-thumb {
height: 150px;
background: var(--kole-color-card-bg);
border-bottom: 1px solid var(--kole-color-border);
overflow: hidden;
position: relative;
}
.ov-thumb iframe {
width: 260%;
height: 260%;
border: none;
transform: scale(.4);
transform-origin: 0 0;
pointer-events: none;
}
.ov-thumb .ph {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
color: var(--kole-color-text-placeholder);
font-size: 12px;
}
.ov-info { padding: 10px var(--kole-space-12) 12px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ov-info .zh { font-size: 14px; font-weight: 500; color: var(--kole-color-text-title); }
.ov-card:hover .ov-info .zh { color: var(--kole-color-brand); }
.ov-info .en { font-family: var(--kole-font-family-num); font-size: 12px; color: var(--kole-color-text-secondary); }
/* ---- 组件详情 ---- */
.detail-head h1 {
display: flex;
align-items: baseline;
gap: 10px;
font-size: 26px;
font-weight: 600;
color: var(--kole-color-text-title);
margin: 0 0 6px;
}
.detail-head h1 .en {
font-family: var(--kole-font-family-num);
font-size: 16px;
font-weight: 400;
color: var(--kole-color-text-secondary);
}
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: var(--kole-space-24); }
.chip {
display: inline-flex;
align-items: center;
height: 22px;
padding: 0 8px;
border-radius: var(--kole-radius-small);
font-size: 12px;
background: var(--kole-color-table-header-bg);
color: var(--kole-color-text-secondary);
white-space: nowrap;
}
.chip.blue { background: var(--kole-color-brand-bg); color: var(--kole-color-brand); }
a.chip:hover { color: var(--kole-color-brand); }
/* 更新日志页的版本入口:窄屏(≤560px)顶栏版本控件让位后,这里是唯一入口 */
.cl-ver-row {
display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
margin: 0 0 var(--kole-space-24);
}
.cl-ver-label { font-size: 12px; color: var(--kole-color-text-secondary); }
.cl-ver-chip {
height: 24px; padding: 0 10px;
border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-small);
background: var(--kole-color-card-bg); color: var(--kole-color-text-body);
font-family: var(--kole-font-family-num); font-size: 12px; cursor: pointer;
transition: border-color .15s, color .15s;
}
.cl-ver-chip:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.cl-ver-chip:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 1px; }
.cl-ver-chip.cur {
background: var(--kole-color-brand-bg); border-color: transparent;
color: var(--kole-color-brand); font-weight: 600; cursor: default;
}
.sec { margin-bottom: var(--kole-space-40); }
.sec > h2 {
font-size: 20px;
font-weight: 600;
color: var(--kole-color-text-title);
margin: 0 0 var(--kole-space-12);
padding-bottom: var(--kole-space-8);
border-bottom: 1px solid var(--kole-color-border);
}
/* 规格说明 */
.spec-box {
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-left: 3px solid var(--kole-color-brand);
border-radius: var(--kole-radius-medium);
padding: var(--kole-space-16) var(--kole-space-20);
}
.spec-box ul { margin: 0; padding-left: 18px; }
.spec-box li { margin: 4px 0; }
.spec-box p { margin: 6px 0; }
.spec-box table { border-collapse: collapse; margin: 8px 0; width: 100%; }
.spec-box th, .spec-box td {
border: 1px solid var(--kole-color-border);
padding: 6px 10px;
font-size: 13px;
text-align: left;
}
.spec-box th { background: var(--kole-color-table-header-bg); font-weight: 500; }
/* 代码演示卡片 */
.demo-card {
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
overflow: hidden;
}
.demo-stage { position: relative; }
.demo-stage iframe {
display: block;
width: 100%;
/* 420px 只是兜底:app.js 的 autoSizeFrame() 量到内容高度后会写成实际高度,
演示整段展示、帧内不滚动(Element 文档 .source 的行为) */
height: 420px;
border: none;
background: var(--kole-color-card-bg);
}
.demo-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px var(--kole-space-16);
border-top: 1px solid var(--kole-color-border);
background: var(--kole-color-card-bg);
}
.demo-toolbar .dt-left, .demo-toolbar .dt-right { display: flex; align-items: center; gap: 4px; }
.tool-btn {
display: inline-flex;
align-items: center;
gap: 6px;
height: 28px;
padding: 0 10px;
border: none;
border-radius: var(--kole-radius-base);
background: transparent;
color: var(--kole-color-text-secondary);
font-size: 12px;
font-family: inherit;
cursor: pointer;
}
.tool-btn:hover { color: var(--kole-color-brand); background: var(--kole-color-brand-bg); }
.tool-btn .arr { transition: transform .2s; font-size: 10px; }
.tool-btn.open .arr { transform: rotate(180deg); }
.demo-code {
border-top: 1px solid var(--kole-color-border);
background: var(--kole-color-tooltip-bg);
}
.demo-code .code-tabs {
display: flex;
gap: 2px;
padding: 6px 12px 0;
border-bottom: 1px solid rgba(255,255,255,.08);
}
.demo-code .code-tabs button {
border: none;
background: transparent;
color: #8B95A7;
font-size: 12px;
font-family: var(--kole-font-family-num);
padding: 6px 12px;
cursor: pointer;
border-radius: var(--kole-radius-base) var(--kole-radius-base) 0 0;
}
.demo-code .code-tabs button.active { color: #fff; background: rgba(255,255,255,.08); }
.demo-code pre {
margin: 0;
padding: var(--kole-space-16);
/* 不设 max-height:源码整段展示,随页面滚动,不在代码块里再套一层纵向滚动条
(Element 文档同样显式 max-height:none)。长行仍可横向滚动。 */
overflow: auto;
}
.demo-code code {
font-family: Consolas, "JetBrains Mono", Menlo, monospace;
font-size: 12.5px;
line-height: 20px;
color: #D6DEEB;
white-space: pre;
}
/* 设计契约 */
.contract-block { margin-bottom: var(--kole-space-20); }
.contract-block h3 {
font-size: 14px;
font-weight: 600;
color: var(--kole-color-text-title);
margin: 0 0 8px;
}
.dim-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 6px 0; }
.dim-row .dim-name { width: 90px; color: var(--kole-color-text-secondary); font-size: 13px; flex-shrink: 0; }
.dim-chip {
font-family: var(--kole-font-family-num);
font-size: 12px;
background: var(--kole-color-brand-bg);
color: var(--kole-color-brand);
border-radius: var(--kole-radius-small);
padding: 1px 8px;
}
.kv-table { border-collapse: collapse; width: 100%; }
.kv-table th, .kv-table td {
border: 1px solid var(--kole-color-border);
padding: 8px 12px;
font-size: 13px;
text-align: left;
vertical-align: top;
}
.kv-table th {
width: 160px;
background: var(--kole-color-table-header-bg);
font-weight: 500;
color: var(--kole-color-text-title);
}
.callout {
border-radius: var(--kole-radius-medium);
padding: 10px var(--kole-space-16);
font-size: 13px;
margin-top: var(--kole-space-12);
}
/* 警告色改用规格定义的 #8C5A00:#AD6800 压 #FFF7E6 实测仅 4.14:1(亮色即不达标) */
.callout.warn { background: #FFF7E6; border: 1px solid #FFE58F; color: #8C5A00; }
.callout.note { background: var(--kole-color-brand-bg); border: 1px solid rgba(47,84,235,.25); color: var(--kole-color-brand-active); }
.callout ul { margin: 4px 0; padding-left: 18px; }
.callout-explain { margin: 6px 0 8px; line-height: 20px; }
.contract-note { margin-top: 6px; padding: 8px 10px; border-left: 2px solid currentColor; background: rgba(255,255,255,.55); line-height: 20px; }
.contract-note p { margin: 0; }
.contract-note p + p { margin-top: 4px; }
/* 实现资源表 */
.res-table { border-collapse: collapse; width: 100%; background: var(--kole-color-card-bg); }
.res-table th, .res-table td {
border: 1px solid var(--kole-color-border);
padding: 8px 12px;
font-size: 13px;
text-align: left;
}
.res-table th { background: var(--kole-color-table-header-bg); font-weight: 500; }
.res-table td.num { font-family: var(--kole-font-family-num); }
/* 上一篇/下一篇 */
.pager { display: flex; justify-content: space-between; gap: var(--kole-space-16); margin-top: var(--kole-space-48); }
.pager a {
flex: 1;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
background: var(--kole-color-card-bg);
padding: var(--kole-space-12) var(--kole-space-16);
transition: border-color .15s, box-shadow .15s;
}
.pager a:hover { border-color: var(--kole-color-brand); box-shadow: var(--kole-shadow-low); text-decoration: none; }
.pager a.next { text-align: right; }
.pager .dir { font-size: 12px; color: var(--kole-color-text-secondary); display: block; }
.pager .name { font-size: 15px; font-weight: 500; color: var(--kole-color-brand); }
/* ---- 设计规范页 ---- */
.tok-group { margin-bottom: var(--kole-space-32); }
.tok-group > h2 {
font-size: 18px;
font-weight: 600;
color: var(--kole-color-text-title);
margin: 0 0 var(--kole-space-12);
}
.tok-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: var(--kole-space-12); }
.tok-card {
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-medium);
overflow: hidden;
}
.tok-swatch { height: 56px; border-bottom: 1px solid var(--kole-color-border); }
/* 令牌导出卡:无 swatch,整卡可点下载 */
.tok-export { display: block; padding: 12px; text-decoration: none; transition: border-color .15s, box-shadow .15s; }
.tok-export:hover { border-color: var(--kole-color-brand); box-shadow: var(--kole-shadow-low); }
.tok-export .t-val { color: var(--kole-color-text-title); font-size: 13px; margin: 4px 0 2px; }
.tok-meta { padding: 8px 12px; }
.tok-meta .t-name { font-family: var(--kole-font-family-num); font-size: 12px; color: var(--kole-color-text-title); word-break: break-all; }
.tok-meta .t-val { font-family: var(--kole-font-family-num); font-size: 12px; color: var(--kole-color-brand); }
.tok-meta .t-cmt { font-size: 11px; color: var(--kole-color-text-secondary); margin-top: 2px; }
.type-row {
display: flex;
align-items: baseline;
gap: var(--kole-space-16);
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-medium);
padding: 10px 16px;
margin-bottom: 8px;
}
.type-sample { color: var(--kole-color-text-title); white-space: nowrap; }
.type-meta { color: var(--kole-color-text-secondary); font-size: 12px; font-family: var(--kole-font-family-num); }
.space-row { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.space-bar { height: 16px; background: var(--kole-color-brand-bg); border: 1px solid var(--kole-color-brand); border-radius: 2px; }
.space-meta { font-family: var(--kole-font-family-num); font-size: 12px; color: var(--kole-color-text-secondary); }
.radius-row { display: flex; gap: var(--kole-space-16); flex-wrap: wrap; }
.radius-demo {
width: 96px; height: 72px;
background: var(--kole-color-brand-bg);
border: 2px solid var(--kole-color-brand);
display: flex; align-items: flex-end; justify-content: center;
font-size: 12px; color: var(--kole-color-brand-active);
padding-bottom: 4px;
font-family: var(--kole-font-family-num);
}
.shadow-row { display: flex; gap: var(--kole-space-24); flex-wrap: wrap; }
.shadow-demo {
width: 140px; height: 80px;
background: var(--kole-color-card-bg);
border-radius: var(--kole-radius-medium);
display: flex; align-items: flex-end; justify-content: center;
font-size: 12px; color: var(--kole-color-text-secondary);
padding-bottom: 8px;
}
.ctrl-row { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.ctrl-pill {
background: var(--kole-color-brand);
color: var(--kole-color-text-inverse);
border-radius: var(--kole-radius-base);
display: inline-flex; align-items: center; justify-content: center;
font-size: 13px;
}
/* ---- 右侧目录 ---- */
.toc {
width: 180px;
flex-shrink: 0;
position: sticky;
top: 60px;
height: calc(100vh - 60px);
overflow-y: auto;
padding: var(--kole-space-32) var(--kole-space-16) var(--kole-space-32) 0;
font-size: 13px;
}
.toc-title { color: var(--kole-color-text-title); font-weight: 500; margin-bottom: 8px; padding-left: 10px; }
.toc a {
display: block;
color: var(--kole-color-text-secondary);
padding: 4px 10px;
border-left: 2px solid var(--kole-color-border);
line-height: 20px;
}
.toc a:hover { color: var(--kole-color-brand); }
.toc a.active { color: var(--kole-color-brand); border-left-color: var(--kole-color-brand); font-weight: 500; }
/* ---- 搜索弹窗 ---- */
.modal-mask {
position: fixed;
inset: 0;
background: var(--kole-color-mask);
z-index: 200;
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 12vh;
}
.modal {
width: 560px;
max-width: calc(100vw - 48px);
max-height: 70vh;
background: var(--kole-color-card-bg);
border-radius: var(--kole-radius-large);
box-shadow: var(--kole-shadow-high);
display: flex;
flex-direction: column;
overflow: hidden;
}
.modal-input-wrap {
display: flex;
align-items: center;
gap: 10px;
padding: 12px 16px;
border-bottom: 1px solid var(--kole-color-border);
color: var(--kole-color-text-secondary);
}
#search-input {
flex: 1;
border: none;
outline: none;
font-size: 15px;
font-family: inherit;
color: var(--kole-color-text-body);
background: transparent;
}
/* 搜索弹窗:分类过滤 chips + 命中高亮 */
.search-cats {
display: flex;
flex-wrap: wrap;
gap: 6px;
padding: 10px 16px 8px;
border-bottom: 1px solid var(--kole-color-border);
}
.sc-chip {
border: 1px solid var(--kole-color-border);
background: transparent;
color: var(--kole-color-text-secondary);
border-radius: 999px;
padding: 2px 10px;
font-size: 12px;
line-height: 18px;
cursor: pointer;
font-family: inherit;
}
.sc-chip:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.sc-chip.active {
background: var(--kole-color-brand-bg);
border-color: var(--kole-color-brand);
color: var(--kole-color-brand);
}
.sr-item .sr-name mark {
background: transparent;
color: var(--kole-color-brand);
font-weight: 600;
padding: 0;
}
.search-results { flex: 1; overflow-y: auto; padding: 8px; }
.sr-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 8px 12px;
border-radius: var(--kole-radius-base);
cursor: pointer;
}
.sr-item .sr-name { font-size: 14px; color: var(--kole-color-text-body); }
.sr-item .sr-name .en { font-family: var(--kole-font-family-num); color: var(--kole-color-text-secondary); margin-left: 8px; font-size: 12px; }
.sr-item .sr-cat { font-size: 11px; color: var(--kole-color-text-secondary); background: var(--kole-color-table-header-bg); border-radius: var(--kole-radius-small); padding: 0 6px; line-height: 18px; flex-shrink: 0; }
.sr-item:hover, .sr-item.hover { background: var(--kole-color-brand-bg); }
.sr-item:hover .sr-name, .sr-item.hover .sr-name { color: var(--kole-color-brand); }
.sr-empty { padding: 32px; text-align: center; color: var(--kole-color-text-secondary); }
/* 更新日志页 */
.cl-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.cl-date { font-family: var(--kole-font-family-num); font-size: 13px; color: var(--kole-color-text-secondary); }
.cl-sec-title { font-size: 15px; font-weight: 600; color: var(--kole-color-text-title); margin: 14px 0 6px; }
/* 相关组件(交叉引用) */
.rel-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--kole-space-12); }
.rel-card {
display: flex;
flex-direction: column;
gap: 4px;
padding: 14px 16px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg);
text-decoration: none;
}
.rel-card:hover { border-color: var(--kole-color-brand); background: var(--kole-color-brand-bg); }
.rel-card strong { font-size: 14px; color: var(--kole-color-text-title); }
.rel-card span { font-family: var(--kole-font-family-num); font-size: 12px; color: var(--kole-color-text-secondary); }
.rel-card .rel-why { font-style: normal; font-size: 12px; color: var(--kole-color-text-secondary); line-height: 1.5; }
.modal-foot {
display: flex;
gap: var(--kole-space-16);
padding: 8px 16px;
border-top: 1px solid var(--kole-color-border);
color: var(--kole-color-text-secondary);
font-size: 12px;
}
/* ---- 致命错误 ---- */
.fatal {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: var(--kole-color-page-bg);
color: var(--kole-color-error);
font-size: 16px;
z-index: 999;
}
/* ---- 首页落地页 ---- */
.home .hero {
background: linear-gradient(180deg, var(--kole-color-brand-bg) 0%, var(--kole-color-page-bg) 100%);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
padding: 56px 48px 40px;
text-align: center;
margin-bottom: var(--kole-space-40);
}
.hero-kicker {
font-family: var(--kole-font-family-num);
font-size: 12px;
letter-spacing: .2em;
color: var(--kole-color-brand);
margin-bottom: 12px;
}
.hero-title {
margin: 0 0 12px;
font-size: 40px;
line-height: 52px;
font-weight: 600;
color: var(--kole-color-text-title);
}
.hero-sub {
margin: 0 auto var(--kole-space-24);
max-width: 560px;
font-size: 15px;
color: var(--kole-color-text-secondary);
}
.hero-actions { display: flex; justify-content: center; gap: var(--kole-space-12); margin-bottom: var(--kole-space-32); }
.btn-primary-lg, .btn-ghost-lg {
display: inline-flex;
align-items: center;
height: 40px;
padding: 0 var(--kole-space-20);
border-radius: var(--kole-radius-base);
font-size: 14px;
cursor: pointer;
}
.btn-primary-lg { background: var(--kole-color-brand); color: var(--kole-color-text-inverse); }
.btn-primary-lg:hover { background: var(--kole-color-brand-hover); color: var(--kole-color-text-inverse); }
.btn-ghost-lg { border: 1px solid var(--kole-color-border); background: var(--kole-color-card-bg); color: var(--kole-color-text-body); }
.btn-ghost-lg:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.hero-stats { display: flex; justify-content: center; gap: var(--kole-space-40); }
.hero-stats .stat { display: flex; flex-direction: column; align-items: center; }
.hero-stats strong { font-family: var(--kole-font-family-num); font-size: 26px; font-weight: 600; color: var(--kole-color-brand); line-height: 34px; }
.hero-stats span { font-size: 12px; color: var(--kole-color-text-secondary); }
.stat-sub { font-style: normal; font-size: 11px; color: var(--kole-color-success); font-family: var(--kole-font-family-num); }
.play-btn {
border: 1px solid var(--kole-color-border);
background: var(--kole-color-card-bg);
color: var(--kole-color-text-secondary);
font-size: 12px;
border-radius: 999px;
padding: 3px 12px;
cursor: pointer;
font-family: inherit;
}
.play-btn:hover { color: var(--kole-color-brand); border-color: var(--kole-color-brand); }
.play-btn.ghost { background: transparent; }
.home-h2 { font-size: 20px; font-weight: 600; color: var(--kole-color-text-title); margin: 0 0 var(--kole-space-16); }
.feat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--kole-space-16); margin-bottom: var(--kole-space-32); }
.feat-card {
display: flex;
gap: 12px;
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
padding: var(--kole-space-16);
}
.feat-icon {
width: 36px; height: 36px;
flex-shrink: 0;
border-radius: var(--kole-radius-medium);
background: var(--kole-color-brand-bg);
color: var(--kole-color-brand);
display: flex; align-items: center; justify-content: center;
}
.feat-body h3 { margin: 0 0 4px; font-size: 14px; color: var(--kole-color-text-title); }
.feat-body p { margin: 0; font-size: 12.5px; color: var(--kole-color-text-secondary); line-height: 19px; }
/* 首页核心组件区:卡片与组件总览同款(.ov-grid / .ov-card),这里只补区块间距 */
.home-core-grid { margin-bottom: var(--kole-space-32); }
/* 首页区块说明文案:跟在 .home-h2 之后,说明该区块的用途 */
.home-note { margin: calc(var(--kole-space-16) * -1 + 4px) 0 var(--kole-space-16); font-size: 12.5px; color: var(--kole-color-text-secondary); line-height: 19px; }
.batch-wrap { display: flex; flex-wrap: wrap; gap: var(--kole-space-8); }
.batch-chip {
display: inline-flex;
align-items: center;
height: 28px;
padding: 0 12px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg);
font-size: 13px;
color: var(--kole-color-text-body);
}
.batch-chip:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); text-decoration: none; }
/* ---- 快速开始 ---- */
.guide-p { color: var(--kole-color-text-body); margin: 0 0 12px; }
/* 快速开始的「本节将介绍…」清单:每步一行,说明这一步做什么 */
.guide-outline {
margin: 0 0 20px;
padding-left: 22px;
color: var(--kole-color-text-body);
font-size: 14px;
line-height: 1.9;
}
.guide-outline li { margin-bottom: 2px; }
.guide-outline li::marker { color: var(--kole-color-brand); }
.guide-p code, .page-desc code {
font-family: Consolas, Menlo, monospace;
font-size: 12.5px;
background: var(--kole-color-table-header-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-small);
padding: 1px 6px;
color: var(--kole-color-brand-active);
}
.code-inline {
margin: 0 0 12px;
padding: var(--kole-space-16);
background: var(--kole-color-tooltip-bg);
border-radius: var(--kole-radius-medium);
overflow: auto;
}
.code-inline code {
font-family: Consolas, "JetBrains Mono", Menlo, monospace;
font-size: 12.5px;
line-height: 20px;
color: #D6DEEB;
white-space: pre;
}
.guide-ul { margin: 0; padding-left: 18px; }
.guide-ul li { margin: 6px 0; }
/* S2-P9 FAQ 页:分组小标题(复用 contract-block h3 的视觉层级) */
.guide-h3 { margin: 12px 0 4px; font-size: 14px; font-weight: 600; color: var(--kole-color-text-title); }
/* ---- 侧栏类目英文副标 ---- */
.side-group .cat-zh { font-style: normal; }
.side-group .cat-en {
font-style: normal;
font-family: var(--kole-font-family-num);
font-size: 10px;
letter-spacing: .04em;
color: var(--kole-color-text-placeholder);
margin-left: 6px;
}
/* ---- 组件页一句话描述 ---- */
.detail-head .page-desc { margin: 0 0 var(--kole-space-12); font-size: 14px; }
/* ---- 演示块小标题(Element 风格) ---- */
.demo-intro { margin-bottom: var(--kole-space-12); }
.demo-intro h3 { margin: 0 0 4px; font-size: 15px; font-weight: 600; color: var(--kole-color-text-title); }
.demo-intro p { margin: 0; font-size: 13px; color: var(--kole-color-text-secondary); }
/* ---- 代码区控制条(Element 风格:居中「显示代码 / 隐藏代码」,悬停才显字)---- */
.demo-strip {
position: relative;
display: flex;
align-items: center;
justify-content: center;
height: 44px;
border-top: 1px solid var(--kole-color-border);
background: var(--kole-color-card-bg);
transition: background var(--kole-duration-fast) var(--kole-ease-standard);
}
.demo-strip .strip-toggle {
display: inline-flex;
align-items: center;
gap: 6px;
height: 100%;
padding: 0 var(--kole-space-12);
border: none;
background: transparent;
color: var(--kole-color-icon-inactive);
font-family: inherit;
font-size: 12px;
cursor: pointer;
transition: color var(--kole-duration-fast) var(--kole-ease-standard);
}
.demo-strip .arr { font-size: 11px; }
.demo-strip .lbl { opacity: 0; transition: opacity var(--kole-duration-base) var(--kole-ease-standard); }
.demo-strip:hover { background: var(--kole-color-table-header-bg); }
.demo-strip:hover .strip-toggle,
.demo-strip .strip-toggle:focus-visible { color: var(--kole-color-brand); }
/* 字随悬停浮现是 Element 的原样行为;键盘聚焦时同样浮现,不能只靠鼠标 */
.demo-strip:hover .lbl,
.demo-strip .strip-toggle:focus-visible .lbl { opacity: 1; }
/* 「在线测试」是跳转入口,常显——藏在悬停里会没人发现 */
.demo-strip .strip-go {
position: absolute;
right: var(--kole-space-12);
top: 50%;
transform: translateY(-50%);
font-size: 12px;
color: var(--kole-color-text-secondary);
transition: color var(--kole-duration-fast) var(--kole-ease-standard);
}
.demo-strip .strip-go:hover { color: var(--kole-color-brand); }
/* ---- 演示代码区头部:tabs + 复制 ---- */
.code-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 12px 0;
border-bottom: 1px solid rgba(255,255,255,.08);
}
.code-copy {
border: 1px solid rgba(255,255,255,.18);
background: transparent;
color: #AAB4C6;
font-size: 12px;
font-family: inherit;
border-radius: var(--kole-radius-base);
height: 26px;
padding: 0 10px;
cursor: pointer;
margin-bottom: 6px;
}
.code-copy:hover { color: #fff; border-color: rgba(255,255,255,.4); }
/* ---- 总览过滤条 ---- */
.ov-filter {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--kole-space-12);
flex-wrap: wrap;
margin-bottom: var(--kole-space-16);
}
.filter-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.filter-chip {
height: 26px;
padding: 0 12px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg);
color: var(--kole-color-text-secondary);
font-size: 12.5px;
font-family: inherit;
cursor: pointer;
}
.filter-chip:hover { color: var(--kole-color-brand); border-color: var(--kole-color-brand); }
.filter-chip.active {
background: var(--kole-color-brand);
border-color: var(--kole-color-brand);
color: var(--kole-color-text-inverse);
}
.filter-input {
width: 200px;
height: 30px;
padding: 0 10px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
font-size: 13px;
font-family: inherit;
color: var(--kole-color-text-body);
outline: none;
background: var(--kole-color-card-bg);
}
.filter-input:focus { border-color: var(--kole-color-brand); box-shadow: 0 0 0 2px var(--kole-color-focus-ring); }
/* ---- 常见问题页搜索:交互对齐全局组件搜索(Ctrl+K 弹窗) ---- */
.faq-search { position: relative; max-width: 380px; }
.faq-search > svg.faq-search-icon {
position: absolute;
left: 11px; top: 50%;
transform: translateY(-50%);
color: var(--kole-color-text-placeholder);
pointer-events: none;
}
.faq-search-input {
width: 100%; height: 36px;
padding: 0 62px 0 34px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg);
color: var(--kole-color-text-body);
font-family: inherit; font-size: 13px;
outline: none;
transition: border-color .15s, box-shadow .15s;
}
/* 自带清空按钮(与 / 提示同位,故隐藏浏览器原生的那个,避免两个叉叠在一起) */
.faq-search-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.faq-search-kbd,
.faq-search-clear {
position: absolute; top: 50%; transform: translateY(-50%); right: 10px;
}
.faq-search-kbd {
font-family: var(--kole-font-family-num);
font-size: 11px;
color: var(--kole-color-text-secondary);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-small);
background: var(--kole-color-card-bg);
padding: 1px 5px;
pointer-events: none;
}
.faq-search-clear {
display: inline-flex; align-items: center; justify-content: center;
width: 20px; height: 20px; padding: 0;
border: 0; border-radius: 50%;
background: transparent;
color: var(--kole-color-text-placeholder);
cursor: pointer;
}
.faq-search-clear:hover { background: var(--kole-color-table-header-bg); color: var(--kole-color-brand); }
.faq-search-clear:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 1px; }
.faq-cats { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
/* 命中高亮:与搜索弹窗一致(透明底 + 品牌色),条目标出片段、标题标出组件名 */
.faq-list mark,
.faq-list h2 mark { background: transparent; color: var(--kole-color-brand); font-weight: 600; }
/* 键盘定位到的条目(↑↓ 移动) */
.faq-list li.hover {
background: var(--kole-color-brand-bg);
color: var(--kole-color-brand);
border-radius: var(--kole-radius-small);
outline: 2px solid var(--kole-color-focus-ring);
outline-offset: 2px;
}
.faq-search-input::placeholder { color: var(--kole-color-text-placeholder); }
.faq-search-input:focus { border-color: var(--kole-color-brand); box-shadow: 0 0 0 2px var(--kole-color-focus-ring); }
/* 结果计数紧跟在搜索框下方:.guide-p 默认只有下边距,这里补上呼吸 */
.faq-search + .guide-p { margin-top: 10px; }
/* ---- 悬浮工具(主题 + 回顶) ---- */
.fab-stack {
position: fixed;
right: 24px;
bottom: 32px;
z-index: 150;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10px;
}
.mode-control { position: relative; display: flex; align-items: flex-end; }
.mode-menu {
position: absolute;
right: 52px;
bottom: 0;
width: 184px;
padding: 6px;
display: flex;
flex-direction: column;
gap: 2px;
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
box-shadow: var(--kole-shadow-high);
animation: mode-menu-in .16s ease-out;
}
.mode-menu.hidden { display: none; }
@keyframes mode-menu-in {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: translateY(0); }
}
/* 菜单头:写明「当前选中 + 实际生效」。两者在自动模式下可能不同(系统是夜间、用户选了自动),
这里用两行分列而不是挤成一行 —— 一行塞不下时会折行,反而更难读。 */
.mode-current {
display: flex; flex-direction: column; gap: 3px;
padding: 6px 8px 8px; margin-bottom: 4px;
border-bottom: 1px solid var(--kole-color-border);
color: var(--kole-color-text-secondary);
font-size: 11px; line-height: 1.4;
}
.mode-current b { color: var(--kole-color-text-title); font-weight: 600; }
.mode-current em { font-style: normal; color: var(--kole-color-brand); }
.mode-menu button {
display: flex;
align-items: center;
gap: 9px;
width: 100%;
min-height: 34px;
padding: 0 8px;
border: 0;
border-radius: var(--kole-radius-small);
background: transparent;
color: var(--kole-color-text-body);
font: inherit;
font-size: 12.5px;
text-align: start;
cursor: pointer;
transition: background .12s ease, color .12s ease;
}
.mode-menu button:hover,
.mode-menu button:focus-visible,
.mode-menu button.is-active { background: var(--kole-color-brand-bg); color: var(--kole-color-brand); outline: none; }
/* 选中行加一条左侧色条:浅底在暗色下对比有限,色条让「当前选中」一眼可见(不占宽度) */
.mode-menu button.is-active { box-shadow: inset 2px 0 0 var(--kole-color-brand); }
/* 三态色标:日间=白底、夜间=页面深底、自动=左右半分(日/夜各一半,直接表达「跟随系统」)。
用 --kole-color-page-bg 而不是 --kole-color-tooltip-bg:后者是**反色**工具提示底,
亮色主题下是深色、暗色主题下反而变成 #E8EAED 浅色,当「夜间」色标会正好反掉。 */
.mode-dot {
width: 14px; height: 14px; flex: 0 0 14px; box-sizing: border-box;
border: 1px solid var(--kole-color-border);
border-radius: 50%;
}
.mode-dot-light {
background: #FFFFFF;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06);
}
.mode-dot-dark { background: var(--kole-color-page-bg); }
.mode-dot-auto {
background: linear-gradient(90deg, #FFFFFF 0 50%, var(--kole-color-page-bg) 50% 100%);
color: transparent; font-size: 0;
}
.fab {
width: 42px;
height: 42px;
border-radius: 50%;
border: 1px solid var(--kole-color-border);
background: var(--kole-color-card-bg);
color: var(--kole-color-text-secondary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: var(--kole-shadow-medium);
transition: color .15s, border-color .15s, transform .15s;
}
.fab:hover { color: var(--kole-color-brand); border-color: var(--kole-color-brand); transform: translateY(-2px); }
.fab[style*="flex"] { display: flex; }
.theme-panel {
width: 280px;
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
box-shadow: var(--kole-shadow-high);
padding: var(--kole-space-16);
}
.tp-head { font-size: 14px; font-weight: 600; color: var(--kole-color-text-title); margin-bottom: 12px; }
/* 主题预设 */
.tp-presets {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 6px;
margin-bottom: 12px;
}
.tp-preset {
display: flex;
align-items: center;
gap: 6px;
border: 1px solid var(--kole-color-border);
background: transparent;
border-radius: var(--kole-radius-small);
padding: 4px 6px;
cursor: pointer;
font-family: inherit;
font-size: 12px;
color: var(--kole-color-text-secondary);
}
.tp-preset:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.tp-swatch { width: 14px; height: 14px; border-radius: 4px; flex-shrink: 0; box-shadow: inset 0 0 0 1px rgba(0,0,0,.08); }
.tp-preset-label { white-space: nowrap; }
.tp-row {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 8px;
}
.tp-row input[type=color] {
width: 36px;
height: 26px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-small);
background: var(--kole-color-card-bg);
padding: 1px;
cursor: pointer;
}
.tp-label { flex: 1; font-size: 13px; color: var(--kole-color-text-body); }
.tp-val { font-family: var(--kole-font-family-num); font-size: 12px; color: var(--kole-color-text-secondary); text-transform: uppercase; }
.tp-actions { display: flex; gap: 8px; margin-top: 12px; }
.tp-btn {
flex: 1;
height: 30px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg);
color: var(--kole-color-text-body);
font-size: 12.5px;
font-family: inherit;
cursor: pointer;
}
.tp-btn:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.tp-btn.primary {
background: var(--kole-color-brand);
border-color: var(--kole-color-brand);
color: var(--kole-color-text-inverse);
}
.tp-btn.primary:hover { background: var(--kole-color-brand-hover); color: var(--kole-color-text-inverse); }
.tp-note { margin-top: 10px; font-size: 11.5px; color: var(--kole-color-text-secondary); line-height: 17px; }
/* ---- 顶栏框架选择器(技术栈)----
2026-09-20 美化:由裸 <select> 改为「胶囊触发器 + 卡片菜单」,与 .lang-trigger / .theme-trigger
同高(34px)、同边框、同展开态;菜单复用 .lang-menu 卡片(绝对定位,不占顶栏宽度)。 */
.fw-select-wrap { position: relative; flex-shrink: 0; }
.fw-trigger {
height: 34px; padding: 0 9px 0 10px;
display: inline-flex; align-items: center; gap: 7px;
border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg); cursor: pointer;
font-family: var(--kole-font-family-num); font-size: 13px; font-weight: 500;
color: var(--kole-color-brand);
transition: border-color .15s, color .15s, box-shadow .15s;
}
.fw-trigger:hover { border-color: var(--kole-color-brand); }
.fw-trigger:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 1px; }
.fw-trigger[aria-expanded="true"] {
border-color: var(--kole-color-brand);
box-shadow: 0 0 0 2px var(--kole-color-focus-ring);
}
.fw-glyph, .fw-caret { flex: 0 0 auto; }
.fw-glyph { color: var(--kole-color-text-secondary); }
.fw-trigger:hover .fw-glyph,
.fw-trigger[aria-expanded="true"] .fw-glyph { color: var(--kole-color-brand); }
.fw-caret { opacity: .6; transition: transform .18s ease, opacity .15s; }
.fw-trigger[aria-expanded="true"] .fw-caret { transform: rotate(180deg); opacity: 1; }
.fw-cur { line-height: 1; white-space: nowrap; }
/* 原生 select 保留为状态真源(app.js 的 change 管道与既有验证脚本都读它):
1px 视觉隐藏,仍可被 inputValue()/selectOption() 访问,但不参与布局与 Tab 序列。 */
.fw-native {
position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
border: 0; opacity: 0; pointer-events: none;
}
/* 菜单比语言菜单略宽:多一列「端文件名」角标(html / jsx / vue2 / vue3) */
.fw-menu { width: 210px; }
.fw-menu .lang-head { display: flex; align-items: center; gap: 6px; }
.fw-menu .fw-head-file {
margin-left: auto; font-family: var(--kole-font-family-num); font-size: 10px;
letter-spacing: .04em; color: var(--kole-color-text-placeholder);
}
@media (prefers-reduced-motion: reduce) {
.fw-caret { transition: none; }
}
/* ---- 顶栏版本选择(≤900px 档,原生 select)----
≤900px 顶栏放不下「角标 + 下拉面板」这套(面板要空间、角标也让位给搜索),
这一档改用原生 select:手机上系统原生的选择器体验比自绘面板更好。
默认 display:none —— 清单拿不到版本时整块不出现,是否显示由 app.js 决定(去掉 hidden)。 */
.ver-select-wrap {
display: none;
align-items: center;
height: 34px;
padding: 0 8px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg);
flex-shrink: 0;
}
.ver-select-wrap[hidden] { display: none; }
#ver-select {
border: none;
outline: none;
background: transparent;
font-size: 13px;
font-family: var(--kole-font-family-num);
color: var(--kole-color-brand);
font-weight: 500;
cursor: pointer;
}
@media (max-width: 900px) {
/* 自绘下拉这一档收起(面板空间不足),select 顶替它出现 */
.ver-picker { display: none; }
.ver-select-wrap:not([hidden]) { display: inline-flex; }
}
/* ≤560px:select 也让位 —— 实测 375px 下 品牌标记+搜索+主题+语言+版本+汉堡 = 398px(溢出 23px)。
这一档的版本入口在导航抽屉里(见文件末尾的 .drawer-ver)。
!important 是必需的:上面那条 :not([hidden]) 的权重(0,2,0)高于单类选择器。 */
@media (max-width: 560px) {
.ver-select-wrap { display: none !important; }
}
/* ---- 其他端折叠 ---- */
.other-files { margin-top: 10px; }
.other-files summary {
cursor: pointer;
font-size: 13px;
color: var(--kole-color-text-secondary);
user-select: none;
}
.other-files summary:hover { color: var(--kole-color-brand); }
.other-files ul { margin: 8px 0 0; }
.other-files a { font-size: 13px; }
/* ---- 深色模式(S2-P5 选型 A:令牌值收归 .design_library 令牌文件的 html.kole-dark 组,
本处只留站点结构样式;演示 iframe 由 app.js 注入 kole-dark 类随令牌同步反色) ---- */
html.kole-dark body { background: var(--kole-color-page-bg); }
html.kole-dark .topbar { background: rgba(20, 22, 28, 0.92); }
html.kole-dark .demo-code { background: var(--kole-color-page-bg); }
/* 逐示例代码区(.ex-code)与整份源码区同皮:暗色下同样要脱离 tooltip-bg 的浅色 */
html.kole-dark .ex-code { background: var(--kole-color-page-bg); }
/* 代码块借用了 --kole-color-tooltip-bg,而该令牌在暗色下是**浅色**(#E8EAED,tooltip 反色),
代码文字却是固定浅色 #D6DEEB → 浅压浅,实测 2.88:1。暗色下改用深底(实测 11.1:1)。 */
html.kole-dark .code-inline { background: var(--kole-color-table-header-bg); }
html.kole-dark .a11y-key kbd { background: var(--kole-color-table-header-bg); border-color: var(--kole-color-border); border-bottom-color: var(--kole-color-border-strong); }
/* 深色下用「品牌基色」(applyTheme 混白 45%)替代偏暗的 brand-active:
实测 code 2.88:1 / .radius-demo 3.44:1 / .callout.note 4.14:1 → 换后 ~6.2 / ~7.3:1。
注意这些是文档站自身的 chrome,组件演示页不受影响。 */
html.kole-dark .guide-p code,
html.kole-dark .page-desc code,
html.kole-dark .callout.note,
html.kole-dark .radius-demo { color: var(--kole-color-brand); }
/* 警告 callout 在深色下保留浅底会晃眼,改成同色低透明底 + 警告色文字(实测 6.49:1) */
html.kole-dark .callout.warn {
background: rgba(229, 163, 0, 0.14);
border-color: rgba(229, 163, 0, 0.4);
color: var(--kole-color-warning);
}
/* ---- 演示说明脚注 ---- */
.demo-note { color: var(--kole-color-text-placeholder); font-size: 12px; margin-top: 2px; }
/* ---- 逐示例卡片(P21:一个使用场景 = 一块预览 + 一块调用代码) ----
Element 文档形态:标题 → 预览 → 代码。每张卡片自带预览与代码,读一个场景不用翻整份源码。 */
.ex-list { display: flex; flex-direction: column; gap: var(--kole-space-20); }
.ex-card {
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-large);
overflow: hidden;
}
.ex-head {
display: flex;
align-items: baseline;
gap: 8px;
padding: var(--kole-space-16) var(--kole-space-20) 0;
}
.ex-num {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 20px;
padding: 0 5px;
border-radius: var(--kole-radius-small);
background: var(--kole-color-brand-bg);
color: var(--kole-color-brand);
font-family: var(--kole-font-family-num);
font-size: 12px;
flex-shrink: 0;
}
.ex-title {
margin: 0;
font-size: 15px;
font-weight: 600;
color: var(--kole-color-text-title);
}
.ex-desc {
margin: 6px var(--kole-space-20) 0;
font-size: 13px;
color: var(--kole-color-text-secondary);
}
.ex-stage {
position: relative;
margin-top: var(--kole-space-12);
border-top: 1px solid var(--kole-color-border);
background: var(--kole-color-card-bg);
}
.ex-stage iframe {
display: block;
width: 100%;
/* 420px 只是兜底:加载后由 fitFrame() 量到内容高度写成实际值 */
height: 320px;
border: none;
background: var(--kole-color-card-bg);
}
.ex-note {
display: block;
padding: 6px var(--kole-space-20);
border-top: 1px dashed var(--kole-color-border);
font-size: 12px;
color: var(--kole-color-text-placeholder);
}
/* ---- 演示帧提升:把「演示框内的全屏」还原成真全屏 ----
演示页嵌在自动高度的 iframe 里(帧视口 = 内容高度),组件里 position:fixed 的覆盖层
(模态 / 图片预览 / 全屏弹窗 / 加载遮罩)因此只在演示框内铺开。帧内一旦出现覆盖型浮层,
app.js 的 watchStageLift() 会给演示舞台加 .is-lifted —— 帧升到视图层:
position:fixed 改以宿主视口为包含块,覆盖层的 inset:0 随之落在真实视口上。
判据、边界与反向用例见 site/app.js 该函数注释与 tools/verify-stage-overlay.mjs。 */
html.kole-stage-locked { overflow: hidden; }
.demo-stage.is-lifted,
.ex-stage.is-lifted {
position: fixed;
inset: 0;
z-index: 9000; /* 站点最高层(顶栏 100 / 搜索 200 / 致命提示 999)之上 */
margin: 0;
border: 0;
border-radius: 0;
background: var(--kole-color-card-bg);
}
.demo-stage.is-lifted iframe,
.ex-stage.is-lifted iframe {
/* 提升期间帧铺满视口:高度由这里接管,fitFrame() 会早退不再写内联高 */
width: 100%;
height: 100% !important;
}
/* 用法代码区:与整份源码区同一套深色皮肤,但只放这一段的调用写法 */
.ex-code { border-top: 1px solid var(--kole-color-border); background: var(--kole-color-tooltip-bg); }.ex-code-bar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 6px 12px 0;
border-bottom: 1px solid rgba(255,255,255,.08);
}
.ex-tabs { display: flex; gap: 2px; }
.ex-tabs button {
border: none;
background: transparent;
color: #8B95A7;
font-size: 12px;
font-family: var(--kole-font-family-num);
padding: 6px 12px;
cursor: pointer;
border-radius: var(--kole-radius-base) var(--kole-radius-base) 0 0;
}
.ex-tabs button.active { color: #fff; background: rgba(255,255,255,.08); }
.ex-src {
margin-left: auto;
font-size: 11px;
color: #8B95A7;
white-space: nowrap;
}
.ex-code .code-copy { margin-bottom: 6px; }
.ex-code pre {
margin: 0;
padding: var(--kole-space-16);
overflow: auto;
}
.ex-code code {
font-family: Consolas, "JetBrains Mono", Menlo, monospace;
font-size: 12.5px;
line-height: 20px;
color: #D6DEEB;
white-space: pre;
}
.ex-foot {
display: flex;
gap: var(--kole-space-16);
font-size: 12.5px;
padding: 0 2px;
}
.ex-foot a { color: var(--kole-color-text-secondary); }
.ex-foot a:hover { color: var(--kole-color-brand); }
@media (max-width: 900px) {
.ex-head, .ex-desc { padding-left: var(--kole-space-12); padding-right: var(--kole-space-12); }
.ex-head { padding-top: var(--kole-space-12); }
.ex-desc { margin-left: var(--kole-space-12); margin-right: var(--kole-space-12); }
.ex-note { padding-left: var(--kole-space-12); }
}
/* ---- 2.5 组件 API 规范表 ---- */
.api-section { margin-top: 8px; }
.api-subhead {
font-size: 15px;
font-weight: 600;
color: var(--kole-color-text-title);
margin: 20px 0 10px;
}
.api-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 24px;
font-size: 13px;
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-medium);
overflow: hidden;
}
.api-table th {
background: var(--kole-color-table-header-bg);
color: var(--kole-color-text-title);
font-weight: 600;
text-align: left;
padding: 10px 14px;
border-bottom: 1px solid var(--kole-color-border);
}
.api-table td {
padding: 10px 14px;
border-bottom: 1px solid var(--kole-color-border);
color: var(--kole-color-text-body);
vertical-align: middle;
}
.api-table tr:last-child td { border-bottom: none; }
.api-table tr:hover td { background: var(--kole-color-brand-bg); }
/* API 说明的出处标记与未明示条目(不发明描述:无出处的行显式标出来) */
.api-legend {
margin: 0 0 12px;
font-size: 12px;
line-height: 1.7;
color: var(--kole-color-text-secondary);
}
.api-legend strong { color: var(--kole-color-text-body); }
.api-legend a { color: var(--kole-color-brand); }
.api-src {
margin-left: 6px;
padding: 0 4px;
border: 1px solid var(--kole-color-border);
border-radius: 3px;
font-size: 10px;
font-weight: 400;
color: var(--kole-color-text-secondary);
cursor: help;
white-space: nowrap;
}
.api-unknown {
color: var(--kole-color-text-secondary);
font-style: italic;
}
.api-opts {
display: block;
margin-top: 2px;
font-size: 12px;
color: var(--kole-color-text-secondary);
}
.api-row-unknown td { background: var(--kole-color-page-bg); }
.prop-name code {
color: var(--kole-color-brand);
background: var(--kole-color-brand-bg);
padding: 2px 6px;
border-radius: 4px;
font-weight: 600;
}
.prop-type code {
color: #722ED1;
background: #F9F0FF;
padding: 2px 6px;
border-radius: 4px;
font-size: 12px;
}
.prop-def code {
color: var(--kole-color-text-secondary);
font-family: Consolas, Monaco, monospace;
}
.prop-desc { line-height: 1.5; color: var(--kole-color-text-body); }
/* 必填/可选徽章:原先用硬编码浅色对,实测两种模式都不足 AA
(.badge-opt #8C8C8C/#F5F5F5 = 3.08:1、.badge-req #F5222D/#FFF1F0 = 3.71:1)→ 改用令牌,
亮色 4.88 / 5.57:1,暗色 5.97 / 5.64:1(实测见 tools/verify-dark.mjs 第 4 组)。 */
.badge-req {
display: inline-block;
background: var(--kole-color-card-bg);
color: var(--kole-color-error);
border: 1px solid var(--kole-color-error);
border-radius: 3px;
padding: 1px 6px;
font-size: 11px;
font-weight: 500;
}
.badge-opt {
display: inline-block;
background: var(--kole-color-table-header-bg);
color: var(--kole-color-text-secondary);
border: 1px solid var(--kole-color-border);
border-radius: 3px;
padding: 1px 6px;
font-size: 11px;
}
/* ---- 2.6 无障碍指引 ---- */
.a11y-section { margin-top: 8px; }
.a11y-intro {
color: var(--kole-color-text-secondary);
font-size: 13px;
margin-bottom: 14px;
line-height: 1.6;
}
.a11y-key kbd {
display: inline-block;
background: #FAFAFA;
border: 1px solid #D9D9D9;
border-bottom: 2px solid #BFBFBF;
border-radius: 4px;
padding: 2px 8px;
font-family: Consolas, Monaco, monospace;
font-size: 12px;
font-weight: 600;
color: var(--kole-color-text-title);
}
/* ---- 2.7 设计避坑指南 (Do's & Don'ts) ---- */
.dodont-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 12px;
}
@media (max-width: 768px) {
.dodont-grid { grid-template-columns: 1fr; }
}
.dodont-card {
background: var(--kole-color-card-bg);
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-medium);
padding: 16px 20px;
box-shadow: 0 1px 4px rgba(0,0,0,0.03);
}
.dodont-card.do {
border-top: 3px solid #52C41A;
}
.dodont-card.dont {
border-top: 3px solid #F5222D;
}
.dodont-title {
font-size: 14px;
font-weight: 600;
margin-bottom: 12px;
color: var(--kole-color-text-title);
}
.dodont-card ul {
margin: 0;
padding-left: 18px;
color: var(--kole-color-text-body);
font-size: 13px;
line-height: 22px;
}
/* ---- 轻量语法高亮着色 ----
调色板按**代码块深底**(--kole-color-tooltip-bg = #1F2329)实测对比度选,
全部 ≥ 4.5:1(标签 8.24 / 属性 7.16 / 字符串 6.97 / 注释 5.23 / 关键字 7.35 / 数字 7.55)。
原 #2F54EB 与 #722ED1 在深底上只有 2.70 / 2.27:1—— 之前代码区默认收起、
verify-theme 的对比度抽查扫不到;P21 改为常显后立刻被抓出来,故换浅一档的品牌色。 */
.hl-tag { color: #A8B8FF; font-weight: 600; }
.hl-attr { color: #13C2C2; }
.hl-str { color: #52C41A; }
.hl-com { color: #8B95A7; font-style: italic; }
.hl-kw { color: #C7A0F5; font-weight: 600; }
.hl-num { color: #FFC53D; }
/* ---- 响应式 ---- */
@media (max-width: 1200px) { .toc { display: none; } }
@media (max-width: 900px) {
.sidebar { display: none; }
.search-trigger .st-text { display: none; }
.search-trigger kbd { display: none; }
/* 这里原本还有一条「收紧链接近距到 8px」的补丁;≤1366px 折叠为抽屉后,
链接是抽屉里的整行条目(padding 12/20),该补丁已无任何生效宽度,故移除。 */
.content { padding: var(--kole-space-24) var(--kole-space-16); }
}
/* ---- 组件内容页:概览 / 示例 / API / 设计与资源 ---- */
.kole-component-page { min-width: 0; }
.kole-component-page [hidden] { display: none !important; }
.kole-component-page .detail-head { padding: 4px 0 28px; }
.kole-detail-breadcrumb {
display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
margin-bottom: 24px; color: var(--kole-color-text-secondary); font-size: 12px;
}
.kole-detail-breadcrumb a { color: var(--kole-color-text-secondary); }
.kole-detail-breadcrumb a:hover { color: var(--kole-color-brand); }
.kole-detail-breadcrumb [aria-current] { color: var(--kole-color-text-body); }
.kole-detail-title { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-bottom: 12px; }
.kole-detail-title h1 { margin: 0; font-size: 34px; line-height: 1.35; letter-spacing: -.025em; flex-wrap: wrap; }
.kole-detail-title h1 .en { font-size: 22px; letter-spacing: -.015em; }
.kole-detail-title .chip { border: 1px solid var(--kole-color-border); background: transparent; }
.kole-component-page .detail-head .page-desc { margin-bottom: 22px; line-height: 1.8; max-width: 68ch; }
.kole-detail-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.kole-detail-action {
display: inline-flex; align-items: center; justify-content: center; min-height: 36px; padding: 7px 14px;
border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-medium);
color: var(--kole-color-text-body); background: var(--kole-color-card-bg); font-size: 13px; font-weight: 500;
}
.kole-detail-action:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.kole-detail-action-primary { color: var(--kole-color-brand); background: var(--kole-color-brand-bg); border-color: transparent; }
.kole-detail-resource { padding: 6px; font-size: 12px; color: var(--kole-color-text-secondary); }
.kole-component-nav {
display: flex; gap: 24px; position: sticky; top: 60px; z-index: 30;
min-height: 52px; margin-bottom: 28px; background: var(--kole-color-page-bg);
border-top: 1px solid var(--kole-color-border); border-bottom: 1px solid var(--kole-color-border);
}
.kole-component-nav a {
display: inline-flex; align-items: center; position: relative; padding: 13px 0;
color: var(--kole-color-text-secondary); white-space: nowrap; font-size: 13px;
}
.kole-component-nav a:hover, .kole-component-nav a.active { color: var(--kole-color-brand); }
.kole-component-nav a.active { font-weight: 600; }
.kole-component-nav a.active::after { content: ''; position: absolute; height: 2px; background: currentColor; bottom: -1px; inset-inline: 0; }
.kole-component-page .sec, .kole-component-page .ex-card { scroll-margin-top: 72px; }
/* 详情页只有一套可见导航:宽屏(>1200px)用右侧目录,页内 sticky 导航收起来;
≤1200px 右侧目录本就隐藏(见本文件 .toc 的响应式规则),改由页内导航承担。
两边都不出现「两套导航同时可见」的空档 —— 断点与滚动落点一同定义。 */
@media (min-width: 1201px) {
.kole-component-nav { display: none; }
}
@media (max-width: 1200px) {
.kole-component-page .sec, .kole-component-page .ex-card { scroll-margin-top: 124px; }
}
.kole-component-page .sec > h2 { border: 0; padding: 0; margin-bottom: 8px; font-size: 22px; line-height: 1.5; }
.kole-component-page .sec > h3 { font-size: 17px; color: var(--kole-color-text-title); margin: 0 0 14px; }
.kole-component-page .demo-intro { margin: 0 0 20px; }
.kole-component-page .demo-intro p { margin: 3px 0; color: var(--kole-color-text-secondary); }
.kole-component-page .demo-note { font-size: 12px; }
.kole-examples-tools { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.kole-example-picker {
min-width: 0; max-width: 65%; height: 34px; padding: 0 28px 0 10px;
border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg); color: var(--kole-color-text-body); font: inherit; font-size: 12px;
text-overflow: ellipsis; cursor: pointer;
}
.kole-expand-code, .kole-example-toggle {
border: 0; background: transparent; color: var(--kole-color-text-secondary);
padding: 6px 0; font: inherit; font-size: 12px; cursor: pointer; flex-shrink: 0;
}
.kole-expand-code:hover, .kole-example-toggle:hover { color: var(--kole-color-brand); }
.kole-component-page .ex-list { gap: 24px; }
.kole-component-page .ex-head { align-items: center; padding: 18px 20px 0; }
.kole-component-page .ex-title { font-size: 16px; line-height: 1.6; }
.kole-component-page .ex-num { background: var(--kole-color-table-header-bg); color: var(--kole-color-text-secondary); font-size: 11px; }
.kole-example-link { color: var(--kole-color-text-secondary); margin-inline-start: auto; padding: 0 4px; font-size: 18px; }
.kole-component-page .ex-stage:not(.is-lifted) { margin-top: 16px; }
.kole-example-toolbar {
display: flex; align-items: center; justify-content: space-between; gap: 12px;
padding: 4px 18px; border-top: 1px solid var(--kole-color-border); background: var(--kole-color-card-bg);
}
.kole-example-preview { color: var(--kole-color-text-secondary); font-size: 11px; }
.kole-component-page .ex-code-bar { flex-wrap: wrap; row-gap: 4px; }
.kole-component-page .ex-tabs { flex-wrap: wrap; }
.kole-component-page .ex-code pre { max-height: 360px; scrollbar-width: thin; }
.kole-component-page .ex-code .code-copy { margin-left: auto; flex-shrink: 0; }
.kole-component-page .ex-foot { flex-wrap: wrap; }
.kole-component-page #api, .kole-detail-reference, .kole-component-page #related { padding-top: 30px; border-top: 1px solid var(--kole-color-border); }
.kole-doc-table { max-width: 100%; overflow-x: auto; margin-bottom: 24px; border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-medium); }
.kole-doc-table > table { margin: 0; border: 0; }
.kole-component-page .api-table { min-width: 540px; }
.kole-component-page .api-table th { white-space: nowrap; }
.kole-component-page .api-table td { overflow-wrap: anywhere; }
.kole-component-page .api-legend { margin-top: 16px; padding: 12px 14px; background: var(--kole-color-table-header-bg); border-radius: var(--kole-radius-medium); }
.kole-spec-disclosure { border: 1px solid var(--kole-color-border); border-radius: var(--kole-radius-medium); background: var(--kole-color-card-bg); }
.kole-spec-disclosure summary { cursor: pointer; padding: 14px 18px; color: var(--kole-color-text-body); font-size: 13px; }
.kole-spec-disclosure[open] summary { border-bottom: 1px solid var(--kole-color-border); }
.kole-spec-disclosure .spec-box { border: 0; background: transparent; }
.kole-detail-reference > .page-desc { margin-bottom: 28px; }
.kole-detail-resources { display: flex; flex-wrap: wrap; gap: 10px 18px; margin-top: 20px; font-size: 12px; color: var(--kole-color-text-secondary); }
.kole-detail-resources code { overflow-wrap: anywhere; }
.kole-component-page .rel-row { margin-top: 16px; }
.kole-component-page :is(a, button, select, summary, pre, .kole-doc-table):focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 3px; }
.toc a.kole-toc-child { padding-inline-start: 20px; font-size: 12px; }
@media (max-width: 900px) {
.kole-detail-title h1 { font-size: 30px; }
.kole-component-nav { gap: 20px; }
}
@media (max-width: 560px) {
.kole-detail-breadcrumb { margin-bottom: 18px; }
.kole-detail-title { gap: 10px; }
.kole-detail-title h1 .en { font-size: 18px; }
.kole-component-nav { gap: 18px; }
.kole-component-nav a { font-size: 12px; }
.kole-component-page .ex-head { padding: 14px 12px 0; }
.kole-component-page .ex-src { width: 100%; order: 3; padding-bottom: 6px; white-space: normal; }
.kole-component-page .ex-tabs button { padding: 6px 8px; }
.kole-component-page .ex-code pre { padding: 12px; }
.kole-component-page .kole-examples-tools { flex-wrap: wrap; }
.kole-example-picker { flex: 1; max-width: 100%; }
.kole-component-page .res-table { min-width: 460px; }
}
/* ================= 顶栏窄屏折叠:汉堡 + 导航抽屉 =================
* 折叠前实测基线(Chromium,中英双语):
* 中文 1280px 起 7 条链接全部折行;1100px 起文字顶出 60px 顶栏(5 条出血);
* 960px 起顶栏溢出;768px 起最右链接不可达;480px 起 7 条全部不可见。
* 英文 1366px 起顶栏溢出(1280px 溢出 107px、375px 溢出 864px)。
* 处置:收紧间距改为无条件基础层(见下);≤1366px 折叠为汉堡 + 抽屉。
* 注意 60px 顶栏高度被 5 处引用(.body-wrap / .sidebar / .toc 的 padding-top
* 与 top+height、html 的 scroll-padding-top),本方案不改高度,故无需连带修改。
*/
/* 汉堡按钮:宽屏隐藏 */
.nav-toggle {
display: none;
flex-shrink: 0;
width: 34px;
height: 34px;
padding: 0;
align-items: center;
justify-content: center;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg);
color: var(--kole-color-text-body);
cursor: pointer;
transition: border-color .15s, color .15s;
}
.nav-toggle:hover { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
.nav-toggle:focus-visible { outline: 2px solid var(--kole-color-focus-ring); outline-offset: 1px; }
body.nav-open .nav-toggle { border-color: var(--kole-color-brand); color: var(--kole-color-brand); }
/* 抽屉遮罩:宽屏隐藏,仅窄屏且抽屉打开时出现 */
.nav-backdrop {
position: fixed;
inset: 60px 0 0 0;
z-index: 110;
display: none;
background: rgba(0, 0, 0, .35);
}
/* 顶栏收紧(无条件,不挂断点):
* .topbar-inner 上限是 1440px,而英文导航(Getting Started / Design Tokens / For Agents)
* 加上完整 logo 副标与可读搜索框在 1440 内始终排不下 —— 实测英文在 1600px 也折成 2 行,
* 因为 inner 已被 1440 截断。所以这三项收紧该是常态,而不是某个断点的特例。 */
.topbar-inner { gap: var(--kole-space-16); padding: 0 var(--kole-space-16); }
/* nowrap 是防"竖排/顶出顶栏"的关键:中文没有词边界,缺它会被逐字换行 */
.topnav a { padding: 0 10px; white-space: nowrap; }
.logo-sub { display: none; }
.search-trigger { max-width: 220px; }
/* ≤1366px:折叠为汉堡 + 右侧抽屉(.topnav 原地变成抽屉,不复制 DOM)
* 1366 是英文实测下限:1366px 起链接不再折行,其下必须折叠。 */
@media (max-width: 1366px) {
.nav-toggle { display: inline-flex; }
body.nav-open { overflow: hidden; }
body.nav-open .nav-backdrop { display: block; }
.topnav {
position: fixed;
top: 60px;
right: 0;
bottom: 0;
z-index: 120;
width: min(320px, 84vw);
height: auto;
margin: 0;
padding: var(--kole-space-8) 0 var(--kole-space-16);
flex-direction: column;
align-items: stretch;
gap: 0;
overflow-y: auto;
overscroll-behavior: contain;
background: var(--kole-color-card-bg);
border-left: 1px solid var(--kole-color-border);
box-shadow: -12px 0 32px rgba(0, 0, 0, .12);
transform: translateX(100%);
/* visibility 不能在过渡里插值:否则类切换后的首帧仍是 hidden,
JS 的 focus() 会静默失败(键盘用户进不了抽屉)。
故关闭时延迟到动画结束再隐藏,打开时立即生效。 */
visibility: hidden;
transition: transform .22s ease, visibility 0s .22s;
}
body.nav-open .topnav {
transform: none;
visibility: visible;
transition: transform .22s ease, visibility 0s;
}
.topnav a {
height: auto;
padding: var(--kole-space-12) var(--kole-space-20);
font-size: 15px;
}
.topnav a:hover { background: var(--kole-color-page-bg); }
.topnav a.active { background: var(--kole-color-brand-bg); }
.topnav a.active::after { display: none; }
}
/* ≤900px:搜索收成方形图标按钮(原先只剩图标却仍占一条长条),并把右侧一组顶到最右 */
@media (max-width: 900px) {
.search-trigger {
flex: 0 0 34px;
width: 34px;
height: 34px;
padding: 0;
justify-content: center;
margin-left: auto;
}
.ver { display: none; }
}
/* ≤560px:只留品牌标记与功能控件(品牌名与框架选择器让位) */
@media (max-width: 560px) {
.topbar-inner { gap: 10px; padding: 0 12px; }
.logo-text { display: none; }
/* 框架选择器整块收起(含 2026-09-20 起的胶囊触发器):实测 375px 下
品牌标记+搜索+技术栈+主题+语言+汉堡 = 374px,已顶满视口,320px 溢出 54px。
技术栈选择在组件页内仍有入口(详情页的端页签),主题与语言是常驻控件,优先保它们。 */
.fw-select-wrap { display: none; }
}
/* ≤600px:版本选择器收紧为只露版本号。
原生 select 的固有宽度取最长选项,而选项带「· 最新版」后缀(v2.0.0 · 最新版)
→ 控件实测 122px(select 104px)。上限取 68px 后版本号 v2.0.0(约 44px)完整可见,
只截掉「· 最新版」半截(完整文案仍在 title / aria-label 里)。
2026-09-20 实测(.topbar-inner 溢出量,中英同档):
改动前 375px 溢出 23px、360px 溢出 34px(汉堡被挤出右边界:左 364 → 右 398);
若只按 ≤560 收紧,561–593px 这一档仍溢出(最多 33px,实测 594px 起才归零)——
因为框架选择器在 >560px 复现、而版本选择器又长回 122px。
故阈值取 600:600px 以上版本号与「最新版」都完整,无溢出。 */
@media (max-width: 600px) {
.ver-select-wrap { padding: 0 6px; }
#ver-select { max-width: 68px; }
}
/* ≤340px:语言选择器让位(主题模式留在顶栏)。
实测 375px 一行放得下 品牌标记+搜索+主题+语言+汉堡(276px),只有 320px 会溢出 15px;
故阈值取 340px,常见手机宽度(360/375/390/414)语言切换仍可用。 */
@media (max-width: 340px) {
.lang-select { display: none; }
}
/* ---- 抽屉内的版本入口 ----
≤560px 顶栏放不下版本控件(见上方 ≤600px 段的实测),抽屉是这一档唯一的入口:
汉堡菜单里与导航链接同列,原生 select,宽度不受顶栏挤压。
只在 ≤560px 出现 —— 561~1366px 顶栏 select 还在,抽屉里再放一份就是两个入口。
清单拿不到版本时整行不出现(hidden)。 */
.drawer-ver { display: none; }
@media (max-width: 560px) {
.drawer-ver:not([hidden]) {
display: flex;
align-items: center;
gap: 10px;
padding: var(--kole-space-12) var(--kole-space-20);
border-top: 1px solid var(--kole-color-border);
}
}
.drawer-ver-label { font-size: 13px; color: var(--kole-color-text-secondary); flex-shrink: 0; }
#drawer-ver-select {
flex: 1;
min-width: 0;
height: 32px;
padding: 0 8px;
border: 1px solid var(--kole-color-border);
border-radius: var(--kole-radius-base);
background: var(--kole-color-card-bg);
color: var(--kole-color-brand);
font-family: var(--kole-font-family-num);
font-size: 13px;
font-weight: 500;
cursor: pointer;
}
@media (prefers-reduced-motion: reduce) {
.topnav { transition: none; }
}