把应用里各自手写的三块收进库,风格沿用前台、行为参数化: - Brand:logo 图片或首字圆形标记 + 名称,href 决定是链接还是纯展示,size/tone 可选 - SearchField:语义版搜索框(onChange 直接给字符串),variant 切 plain / card, 支持 shortcut 提示与 hotkey 聚焦 - Ticker:无限滚动信息条,内部三份内容按实测宽度位移,循环不跳帧; speed / paused / label 可配 - 令牌补展示级字号 --su-font-size-2xl / --su-line-height-2xl(32 / 40) - 展示页新增 #site-chrome(Brand / Ticker / SearchField),COMPONENTS.md 补契约与 changelog
272 lines
9.9 KiB
CSS
272 lines
9.9 KiB
CSS
/**
|
||
* Stash UI 设计令牌。
|
||
*
|
||
* 取值来自 Alright 主题的 `:root` 设计变量(Stash 控制台即按它实现),
|
||
* 与 `ALRIGHT-DESIGN.md` 的第 1 节一一对应:灰阶、语义色、圆角、阴影、字号、动效。
|
||
*
|
||
* 约定:
|
||
* - 前缀 `--su-`(stash ui),避免和使用方应用自己的变量重名;
|
||
* - 组件里只允许引用令牌,不写死色值 / 尺寸,换主题时只覆盖这个文件;
|
||
* - 想改主题:在使用方覆盖同名变量即可(例如 `:root[data-theme='dark']`)。
|
||
*/
|
||
|
||
:root {
|
||
/* ---------- 中性色(灰阶) ---------- */
|
||
--su-gray-1: #f7f8fa; /* 页面背景 */
|
||
--su-gray-2: #f6f6f6; /* 边框、浅底 */
|
||
--su-gray-3: #eeeeee; /* hover 底色 */
|
||
--su-gray-4: #c9cdd4; /* 分隔线、禁用 */
|
||
--su-gray-5: #86909c; /* 说明文字 */
|
||
--su-gray-6: #4e5969; /* 次级文字 */
|
||
--su-gray-7: #2c343c; /* 强调文字 */
|
||
--su-gray-8: #1d2129; /* 主文字 */
|
||
--su-white: #ffffff;
|
||
|
||
/* ---------- 品牌与语义色 ---------- */
|
||
--su-color-primary: #3858f6;
|
||
--su-color-primary-hover: #2f4de0;
|
||
--su-color-primary-soft: rgba(56, 88, 246, 0.1);
|
||
--su-color-danger: #ff3e3e;
|
||
--su-color-danger-hover: #e63535;
|
||
--su-color-danger-soft: rgba(255, 62, 62, 0.1);
|
||
--su-color-danger-border: rgba(255, 62, 62, 0.25);
|
||
--su-color-warning: #ffba3a;
|
||
--su-color-warning-soft: rgba(255, 186, 58, 0.14);
|
||
--su-color-warning-text: #a86a00;
|
||
--su-color-success: #4abd86;
|
||
--su-color-success-soft: rgba(74, 189, 134, 0.12);
|
||
--su-color-orange-dark: #ff8338;
|
||
--su-color-orange-light: #fffbe8;
|
||
|
||
/* ---------- 渐变(主题里只用于角标) ---------- */
|
||
/* 认证角标:参考站头像右下角的对勾 */
|
||
--su-gradient-verified: linear-gradient(135deg, #ffb74a, #fd900f);
|
||
/* 热门标记 / 置顶 / 付费:参考站的 .item-badge */
|
||
--su-gradient-hot: linear-gradient(135deg, #ff2f43, #ff6327);
|
||
--su-gradient-paid: linear-gradient(135deg, #ff952f, #ff662b);
|
||
--su-gradient-red: linear-gradient(to right, #ff6034, #ff3e3e);
|
||
|
||
/* ---------- 语义别名 ---------- */
|
||
--su-bg-page: var(--su-gray-1);
|
||
--su-bg-card: var(--su-white);
|
||
--su-bg-hover: var(--su-gray-3);
|
||
/* 浅色块:标签底、次要按钮底(对应参考站的 --bg-light,比页面底色深一档) */
|
||
--su-bg-subtle: var(--su-gray-1);
|
||
--su-bg-light: var(--su-gray-2);
|
||
/* 骨架屏扫光的高光色(深色下要更弱) */
|
||
--su-skeleton-shine: rgba(255, 255, 255, 0.5);
|
||
/* 说明型提示条的半透明白底(叠在页面底色上) */
|
||
--su-bg-notice: rgba(255, 255, 255, 0.7);
|
||
--su-bg-danger-soft: #fff5f5;
|
||
--su-text-main: var(--su-gray-8);
|
||
/* 次级正文:参考站的 .text-secondary 用的就是 gray-7 */
|
||
--su-text-secondary: var(--su-gray-7);
|
||
--su-text-sub: var(--su-gray-6);
|
||
/* 说明文字:参考站的 .text-muted 用的是 gray-6,这里保留 gray-5 给更弱的占位 */
|
||
--su-text-muted: var(--su-gray-5);
|
||
--su-text-placeholder: var(--su-gray-5);
|
||
--su-text-disabled: var(--su-gray-4);
|
||
--su-border: var(--su-gray-2);
|
||
--su-border-strong: var(--su-gray-3);
|
||
/* 卡片描边:参考站的 .box-block 用的是 gray-1(几乎看不见的那层) */
|
||
--su-card-border: var(--su-gray-1);
|
||
|
||
/* ---------- 圆角 ---------- */
|
||
--su-radius-xs: 4px;
|
||
--su-radius-sm: 6px;
|
||
--su-radius-md: 12px;
|
||
--su-radius-lg: 24px;
|
||
--su-radius-pill: 999px;
|
||
/* 封面卡圆角:比常规卡片小一档,贴图时不显胖 */
|
||
--su-radius-cover: 8px;
|
||
/* 资料卡头像的无图底色(参考站实测) */
|
||
--su-avatar-gradient: linear-gradient(135deg, #dfe4ff, #c9d0ff);
|
||
|
||
/* ---------- 布局 ----------
|
||
* 页面级骨架的常用值,Layout 与页面共用,避免各页面写死 1380 / 60。
|
||
*/
|
||
--su-layout-width: 1380px;
|
||
--su-header-height: 60px;
|
||
/* 阅读型正文的行高(文章详情);组件默认 24px 的普通行高 */
|
||
--su-reading-line-height: 1.9;
|
||
|
||
/* ---------- 阴影 ----------
|
||
* 参考站只有一层极轻的卡片阴影:0 6px 16px 0 rgb(27 26 49 / 1%),
|
||
* 悬停用 /3%,再重的阴影会破坏主题的「纸片感」。
|
||
*/
|
||
--su-shadow-card: 0 6px 16px 0 rgba(27, 26, 49, 0.01);
|
||
--su-shadow-hover: 0 6px 16px 0 rgba(27, 26, 49, 0.03);
|
||
--su-shadow-card-strong: 0 6px 16px 0 rgba(27, 26, 49, 0.02);
|
||
--su-shadow-pop: 0 8px 24px rgba(27, 26, 49, 0.12);
|
||
|
||
/* 封面底部压暗层:保证白色标题在任何图片上都可读 */
|
||
--su-cover-scrim: linear-gradient(
|
||
to top,
|
||
rgba(0, 0, 0, 0.85) 0%,
|
||
rgba(0, 0, 0, 0.4) 60%,
|
||
transparent 100%
|
||
);
|
||
|
||
/* ---------- 间距(4 的倍数) ---------- */
|
||
--su-space-1: 4px;
|
||
--su-space-2: 8px;
|
||
--su-space-3: 12px;
|
||
--su-space-4: 16px;
|
||
--su-space-5: 20px;
|
||
--su-space-6: 24px;
|
||
--su-space-8: 32px;
|
||
--su-space-10: 40px;
|
||
|
||
/* ---------- 字号阶梯 ----------
|
||
* 取自参考站实际渲染的 .text-* 工具类(body 16/24,组件内 13~18),
|
||
* 不是主题 tokens 里那套 10/12/14/16 的旧值。
|
||
*/
|
||
--su-font-size-xs: 12px;
|
||
--su-font-size-sm: 13px;
|
||
--su-font-size-md: 14px;
|
||
/* 内容正文字号:文章段落、卡片标题(参考站 body 16/24) */
|
||
--su-font-size-base: 16px;
|
||
--su-font-size-lg: 18px;
|
||
--su-font-size-xl: 24px;
|
||
/* 展示级字号:封面占位字、引号这类装饰性大字,不用来排版正文 */
|
||
--su-font-size-2xl: 32px;
|
||
|
||
--su-line-height-xs: 16px;
|
||
--su-line-height-sm: 20px;
|
||
--su-line-height-md: 22px;
|
||
--su-line-height-base: 24px;
|
||
--su-line-height-lg: 26px;
|
||
--su-line-height-xl: 32px;
|
||
--su-line-height-2xl: 40px;
|
||
|
||
/* 主题的「加粗」是 500 */
|
||
--su-font-weight-normal: 400;
|
||
--su-font-weight-bold: 500;
|
||
--su-font-weight-semibold: 600;
|
||
/* 只给字形类(如认证角标的 ✓)用的重字重 */
|
||
--su-font-weight-strong: 700;
|
||
|
||
--su-font-sans:
|
||
'LXGW WenKai', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||
'Hiragino Sans GB', 'Microsoft YaHei', 'Source Han Sans CN', sans-serif;
|
||
--su-font-mono: ui-monospace, SFMono-Regular, Consolas, 'Liberation Mono', monospace;
|
||
|
||
/* ---------- 控件尺寸 ---------- */
|
||
/* 按钮 / 输入框 / 未来 Select 共用的外框高度,保证并排时对齐 */
|
||
--su-control-height-sm: 32px;
|
||
--su-control-height-md: 36px;
|
||
--su-control-height-lg: 44px;
|
||
/* 圆形图标按钮:参考站的 .btn-icon 是 28 / 36 / 44,字号 16 / 20 / 24 */
|
||
--su-icon-button-xs: 28px;
|
||
--su-icon-button-sm: 36px;
|
||
--su-icon-button-md: 44px;
|
||
|
||
/* ---------- 动效 ---------- */
|
||
--su-duration-fast: 0.2s;
|
||
--su-duration-base: 0.3s;
|
||
--su-ease-out: ease-out;
|
||
--su-ease-in: ease-in;
|
||
/* 参考站的颜色/背景过渡统一是 .3s ease-in-out */
|
||
--su-ease-in-out: ease-in-out;
|
||
|
||
/* ---------- 焦点环 ----------
|
||
* 参考站把 focus 的 box-shadow 干掉了(a11y 不合格),组件库自己补一圈:
|
||
* 键盘聚焦时 2px 主色描边 + 2px 间距,鼠标点击不出现。
|
||
*/
|
||
--su-focus-ring: 2px solid var(--su-color-primary);
|
||
--su-focus-ring-offset: 2px;
|
||
|
||
/* ---------- 层级 ---------- */
|
||
--su-z-header: 100;
|
||
--su-z-float: 90;
|
||
}
|
||
|
||
/**
|
||
* 暗色主题。
|
||
*
|
||
* 用法:在 `html` 上设置 `data-scheme="dark"`(或 `"auto"` 跟随系统)。
|
||
* 取值来自参考站 `body[data-scheme=dark]` 的实测映射:
|
||
* 灰阶整体反相、卡片底 #202022、描边 #303030,语义变量跟着翻转——
|
||
* 所以组件只要用语义令牌(bg-card / bg-subtle / text-* / border-*)就自动适配。
|
||
*/
|
||
:root[data-scheme='dark'] {
|
||
/* 灰阶反相(与参考站一致) */
|
||
--su-gray-5: #494949;
|
||
--su-gray-6: #303030;
|
||
--su-gray-7: #202022;
|
||
--su-gray-8: #0f0f11;
|
||
|
||
--su-bg-page: #0f0f11;
|
||
--su-bg-card: #202022;
|
||
--su-bg-subtle: #2a2a2e;
|
||
--su-bg-light: #303034;
|
||
--su-bg-hover: #3a3a3f;
|
||
--su-skeleton-shine: rgba(255, 255, 255, 0.08);
|
||
--su-bg-notice: rgba(32, 32, 34, 0.7);
|
||
--su-bg-danger-soft: #2c1a1c;
|
||
|
||
--su-text-main: #f7f8fa;
|
||
--su-text-secondary: #e5e6eb;
|
||
--su-text-sub: #c9cdd4;
|
||
--su-text-muted: #86909c;
|
||
--su-text-placeholder: #6b7280;
|
||
--su-text-disabled: #4e5560;
|
||
|
||
--su-border: #303033;
|
||
--su-border-strong: #3a3a3f;
|
||
--su-card-border: #2a2a2e;
|
||
|
||
/* 浅色底在深色下要提亮,否则标签几乎看不见 */
|
||
--su-color-primary-soft: rgba(56, 88, 246, 0.22);
|
||
--su-color-danger-soft: rgba(255, 62, 62, 0.16);
|
||
--su-color-success-soft: rgba(74, 189, 134, 0.16);
|
||
--su-color-warning-soft: rgba(255, 186, 58, 0.16);
|
||
--su-color-warning-text: #ffc96b;
|
||
--su-avatar-gradient: linear-gradient(135deg, rgba(56, 88, 246, 0.32), rgba(56, 88, 246, 0.14));
|
||
|
||
/* 深色下阴影只能靠更深的黑,透明度要高一些才看得出来 */
|
||
--su-shadow-card: 0 6px 16px 0 rgba(0, 0, 0, 0.45);
|
||
--su-shadow-hover: 0 6px 16px 0 rgba(0, 0, 0, 0.6);
|
||
--su-shadow-card-strong: 0 6px 16px 0 rgba(0, 0, 0, 0.55);
|
||
}
|
||
|
||
/* `data-scheme="auto"`:跟随系统 */
|
||
@media (prefers-color-scheme: dark) {
|
||
:root[data-scheme='auto'] {
|
||
--su-gray-5: #494949;
|
||
--su-gray-6: #303030;
|
||
--su-gray-7: #202022;
|
||
--su-gray-8: #0f0f11;
|
||
|
||
--su-bg-page: #0f0f11;
|
||
--su-bg-card: #202022;
|
||
--su-bg-subtle: #2a2a2e;
|
||
--su-bg-light: #303034;
|
||
--su-bg-hover: #3a3a3f;
|
||
--su-skeleton-shine: rgba(255, 255, 255, 0.08);
|
||
--su-bg-notice: rgba(32, 32, 34, 0.7);
|
||
--su-bg-danger-soft: #2c1a1c;
|
||
|
||
--su-text-main: #f7f8fa;
|
||
--su-text-secondary: #e5e6eb;
|
||
--su-text-sub: #c9cdd4;
|
||
--su-text-muted: #86909c;
|
||
--su-text-placeholder: #6b7280;
|
||
--su-text-disabled: #4e5560;
|
||
|
||
--su-border: #303033;
|
||
--su-border-strong: #3a3a3f;
|
||
--su-card-border: #2a2a2e;
|
||
|
||
--su-color-primary-soft: rgba(56, 88, 246, 0.22);
|
||
--su-color-danger-soft: rgba(255, 62, 62, 0.16);
|
||
--su-color-success-soft: rgba(74, 189, 134, 0.16);
|
||
--su-color-warning-soft: rgba(255, 186, 58, 0.16);
|
||
--su-color-warning-text: #ffc96b;
|
||
--su-avatar-gradient: linear-gradient(135deg, rgba(56, 88, 246, 0.32), rgba(56, 88, 246, 0.14));
|
||
|
||
--su-shadow-card: 0 6px 16px 0 rgba(0, 0, 0, 0.45);
|
||
--su-shadow-hover: 0 6px 16px 0 rgba(0, 0, 0, 0.6);
|
||
}
|
||
}
|