Files
yingqing/电商AI平台/assets/restraint.css
T
iyeandClaude Opus 4.7 cae935588b init: 电商AI平台 v2.1 静态设计稿
- 10 个页面 (工作台/项目/商品/流水线/资产/账户/创建向导)
- V2.1 Restraint 设计规范 (冷灰底 + #FA5D19 + 8px 圆角)
- 完整 design-system.html 组件库参考
- SVG line icon · stroke 1.5 全合规

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-15 17:55:11 +08:00

886 lines
32 KiB
CSS
Raw 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.
/* ============================================================
流·Studio · Restraint V2.1 · Firecrawl-aligned · 纯净版
============================================================
严格遵循 DESIGN_SPEC_V2.md V2.1 · 不含任何 V1/V2 legacy alias
============================================================ */
/* ============ Web font · Alibaba PuHuiTi 3.0 ============ */
@font-face {
font-family: 'Alibaba PuHuiTi';
font-weight: 400;
font-style: normal;
font-display: swap;
src: local('Alibaba PuHuiTi 3.0'),
local('AlibabaPuHuiTi-3-55-Regular'),
local('Alibaba PuHuiTi 2.0'),
local('AlibabaPuHuiTi-2-55-Regular'),
url('https://chinese-fonts-cdn.deno.dev/packages/alibaba_puhuiti/dist/AlibabaPuHuiTi-3-55-Regular/AlibabaPuHuiTi-3-55-Regular.woff2') format('woff2');
}
@font-face {
font-family: 'Alibaba PuHuiTi';
font-weight: 500;
font-style: normal;
font-display: swap;
src: local('Alibaba PuHuiTi 3.0 Medium'),
local('AlibabaPuHuiTi-3-65-Medium'),
local('AlibabaPuHuiTi-2-65-Medium'),
url('https://chinese-fonts-cdn.deno.dev/packages/alibaba_puhuiti/dist/AlibabaPuHuiTi-3-65-Medium/AlibabaPuHuiTi-3-65-Medium.woff2') format('woff2');
}
@font-face {
font-family: 'Alibaba PuHuiTi';
font-weight: 600;
font-style: normal;
font-display: swap;
src: local('AlibabaPuHuiTi-3-75-SemiBold'),
local('AlibabaPuHuiTi-2-75-SemiBold'),
url('https://chinese-fonts-cdn.deno.dev/packages/alibaba_puhuiti/dist/AlibabaPuHuiTi-3-75-SemiBold/AlibabaPuHuiTi-3-75-SemiBold.woff2') format('woff2');
}
@font-face {
font-family: 'Alibaba PuHuiTi';
font-weight: 700;
font-style: normal;
font-display: swap;
src: local('Alibaba PuHuiTi 3.0 Bold'),
local('AlibabaPuHuiTi-3-85-Bold'),
local('AlibabaPuHuiTi-2-85-Bold'),
url('https://chinese-fonts-cdn.deno.dev/packages/alibaba_puhuiti/dist/AlibabaPuHuiTi-3-85-Bold/AlibabaPuHuiTi-3-85-Bold.woff2') format('woff2');
}
* { box-sizing: border-box; margin: 0; padding: 0; }
:root {
/* ===== Backgrounds (冷灰) ===== */
--background-base: #f9f9f9;
--background-lighter: #fbfbfb;
--surface: #ffffff;
--surface-raised: #ffffff;
/* ===== Borders (冷灰 3 档,语义优先) ===== */
--border-faint: #ededed;
--border-muted: #e8e8e8;
--border-loud: #e6e6e6;
/* ===== Accent multi-color (5 色信号) ===== */
--accent-black: #262626;
--accent-white: #ffffff;
--accent-amethyst: #9061ff;
--accent-bluetron: #2a6dfb;
--accent-crimson: #eb3424;
--accent-forest: #42c366;
--accent-honey: #ecb730;
/* status 配套底/边 */
--forest-bg: rgba(66, 195, 102, .08);
--forest-bd: rgba(66, 195, 102, .20);
--crimson-bg: rgba(235, 52, 36, .08);
--crimson-bd: rgba(235, 52, 36, .20);
--honey-bg: rgba(236, 183, 48, .08);
--honey-bd: rgba(236, 183, 48, .20);
/* ===== Heat · 单 hue + 8 档 alpha ===== */
--heat: #fa5d19;
--heat-90: rgba(250, 93, 25, .90);
--heat-40: rgba(250, 93, 25, .40);
--heat-20: rgba(250, 93, 25, .20);
--heat-16: rgba(250, 93, 25, .16);
--heat-12: rgba(250, 93, 25, .12);
--heat-8: rgba(250, 93, 25, .08);
--heat-4: rgba(250, 93, 25, .04);
/* ===== Black-alpha 阶梯 (20 档) ===== */
--black-alpha-1: rgba(0, 0, 0, .01);
--black-alpha-2: rgba(0, 0, 0, .02);
--black-alpha-3: rgba(0, 0, 0, .03);
--black-alpha-4: rgba(0, 0, 0, .04);
--black-alpha-5: rgba(0, 0, 0, .05);
--black-alpha-6: rgba(0, 0, 0, .06);
--black-alpha-7: rgba(0, 0, 0, .07);
--black-alpha-8: rgba(0, 0, 0, .08);
--black-alpha-10: rgba(0, 0, 0, .10);
--black-alpha-12: rgba(0, 0, 0, .12);
--black-alpha-16: rgba(0, 0, 0, .16);
--black-alpha-20: rgba(0, 0, 0, .20);
--black-alpha-24: rgba(0, 0, 0, .24);
--black-alpha-32: rgba(38, 38, 38, .32);
--black-alpha-40: rgba(38, 38, 38, .40);
--black-alpha-48: rgba(38, 38, 38, .48);
--black-alpha-56: rgba(38, 38, 38, .56);
--black-alpha-64: rgba(38, 38, 38, .64);
--black-alpha-72: rgba(38, 38, 38, .72);
--black-alpha-88: rgba(38, 38, 38, .88);
/* ===== Radius ===== */
--r-sm: 4px;
--r-md: 8px;
--r-pill: 999px;
/* ===== Font · 关键:--font-mono 必须含 PuHuiTi 中文 fallback ===== */
/* Inter / JetBrains Mono 都不含 CJK 字形。
字体链按字符级 fallthrough,中文字符会找下一个候选 —— 必须包含 PuHuiTi。 */
--font-sans: 'Inter', 'Alibaba PuHuiTi', 'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif;
--font-inter: 'Inter', system-ui, sans-serif;
--font-mono: 'JetBrains Mono', 'Geist Mono', ui-monospace, 'Alibaba PuHuiTi', 'PingFang SC', 'Microsoft YaHei', monospace;
/* ===== Transition ===== */
--t-fast: 100ms ease;
--t-base: 200ms ease;
--t-slow: 300ms cubic-bezier(0.34, 1.56, 0.64, 1);
/* ===== Shadows ===== */
--shadow-cta:
inset 0 -4px 8px rgba(250, 93, 25, .20),
0 1px 1px rgba(250, 93, 25, .12),
0 2px 4px rgba(250, 93, 25, .10),
0 .5px .5px rgba(250, 93, 25, .16);
--shadow-cta-hover:
inset 0 -4px 8px rgba(250, 93, 25, .20),
0 1px 1px rgba(250, 93, 25, .16),
0 4px 8px rgba(250, 93, 25, .20),
0 .5px .5px rgba(250, 93, 25, .16);
--shadow-cta-active:
inset 0 -4px 8px rgba(250, 93, 25, .28),
0 1px 2px rgba(250, 93, 25, .16);
--shadow-floating: 0 4px 20px rgba(21, 20, 15, .06);
}
::selection { background: var(--heat-20); color: var(--heat); }
html, body {
background: var(--background-base);
color: var(--accent-black);
font-family: var(--font-sans);
font-size: 14px;
line-height: 1.65;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; border: 0; background: none; color: inherit; }
input, textarea, select { font: inherit; color: inherit; outline: none; }
img, svg, video { display: block; max-width: 100%; }
.num, .tnum { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-mono); }
.muted { color: var(--black-alpha-56); }
.muted-2 { color: var(--black-alpha-48); }
.spacer { flex: 1; }
.hstack { display: flex; align-items: center; gap: 8px; }
.vstack { display: flex; flex-direction: column; gap: 8px; }
.divider { height: 1px; background: var(--border-faint); margin: 16px 0; }
/* ─── App shell ─── */
.app { display: grid; grid-template-columns: 248px 1fr; min-height: 100vh; }
/* ─── Sidebar ─── */
aside.sidebar {
padding: 22px 16px;
border-right: 1px solid var(--border-faint);
background: var(--background-base);
position: sticky;
top: 0;
height: 100vh;
overflow-y: auto;
}
.brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 16px; }
.flame { width: 22px; height: 22px; color: var(--heat); }
.flame svg { width: 100%; height: 100%; }
.brand .name { font-weight: 600; font-size: 18px; letter-spacing: -.012em; color: var(--accent-black); }
/* sidebar search · Ctrl K Inter Bold 平铺 */
.search-box {
display: flex; align-items: center; gap: 10px;
padding: 9px 12px;
background: var(--surface);
border: 1px solid var(--border-faint);
border-radius: var(--r-md);
color: var(--black-alpha-48);
margin-bottom: 18px;
cursor: text;
transition: border-color var(--t-base);
}
.search-box:hover { border-color: var(--black-alpha-24); }
.search-box:focus-within { border-color: var(--heat-40); box-shadow: inset 0 0 0 1px var(--heat-40); }
.search-box svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--black-alpha-56); }
.search-box input {
flex: 1; min-width: 0;
border: 0; background: transparent;
font-size: 13.5px; color: var(--accent-black);
padding: 0;
}
.search-box input::placeholder { color: var(--black-alpha-48); }
.search-box .kbd {
margin-left: auto;
flex-shrink: 0;
white-space: nowrap;
font-family: var(--font-inter);
font-weight: 700;
font-size: 11px;
color: var(--black-alpha-48);
letter-spacing: .02em;
}
.nav-section {
font-size: 11px; color: var(--black-alpha-48);
padding: 16px 12px 8px;
letter-spacing: .04em;
font-weight: 500;
/* 中文标签用 sans 字体,不用 mono + uppercase */
}
nav { display: flex; flex-direction: column; gap: 2px; }
nav a {
display: flex; align-items: center; gap: 11px;
padding: 9px 12px;
color: var(--black-alpha-56);
font-size: 13.5px; font-weight: 500;
border-radius: var(--r-md);
cursor: pointer;
user-select: none;
transition: background var(--t-base), color var(--t-base);
}
nav a:hover { background: var(--black-alpha-4); color: var(--accent-black); }
nav a.active { background: var(--heat-12); color: var(--heat); }
nav a svg { width: 14px; height: 14px; opacity: .85; }
nav a.active svg { opacity: 1; }
nav a .pill-mini {
margin-left: auto;
font-family: var(--font-mono);
font-size: 9.5px; font-weight: 600;
padding: 2px 7px;
background: var(--surface);
color: var(--black-alpha-48);
border: 1px solid var(--border-faint);
border-radius: var(--r-pill);
letter-spacing: .04em;
}
nav a.disabled { color: var(--black-alpha-32); cursor: not-allowed; }
nav a.disabled:hover { background: transparent; color: var(--black-alpha-32); }
.aside-foot { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--border-faint); }
.user {
display: flex; align-items: center; gap: 10px;
padding: 8px 10px;
border-radius: var(--r-md);
cursor: pointer;
transition: background var(--t-base);
}
.user:hover { background: var(--black-alpha-4); }
.user .av {
width: 26px; height: 26px;
border-radius: 6px;
background: var(--accent-black);
color: var(--accent-white);
display: flex; align-items: center; justify-content: center;
font-weight: 600; font-size: 11px;
}
.user .em { font-size: 13px; color: var(--accent-black); }
/* ─── Main + grid background ─── */
main { position: relative; overflow: hidden; background: var(--background-base); }
.grid-bg {
position: absolute; inset: 0; pointer-events: none;
background-image:
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><g stroke='%23c8c8c8' stroke-width='1' fill='none'><path d='M-5 0 L5 0 M0 -5 L0 5'/><path d='M235 0 L245 0 M240 -5 L240 5'/><path d='M-5 240 L5 240 M0 235 L0 245'/><path d='M235 240 L245 240 M240 235 L240 245'/></g></svg>"),
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='60' height='60'><circle cx='60' cy='60' r='0.9' fill='%23d8d8d8'/></svg>"),
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><g stroke='%23ebebeb' stroke-width='1' fill='none' stroke-dasharray='1.5 4'><path d='M240 0 L240 240'/><path d='M0 240 L240 240'/></g></svg>");
background-size: 240px 240px, 60px 60px, 240px 240px;
mask-image: radial-gradient(ellipse 95% 80% at 50% 35%, #000 25%, transparent 95%);
-webkit-mask-image: radial-gradient(ellipse 95% 80% at 50% 35%, #000 25%, transparent 95%);
}
.scatter {
position: absolute;
font-family: var(--font-mono); font-size: 8.5px; line-height: 1.05;
color: var(--black-alpha-20); white-space: pre; pointer-events: none;
opacity: .85; letter-spacing: .04em;
}
.tag-corner {
position: absolute;
color: var(--black-alpha-48);
font-family: var(--font-mono);
font-size: 10.5px; letter-spacing: .06em;
pointer-events: none; opacity: .85; z-index: 1;
}
.sq-mark { position: absolute; width: 5px; height: 5px; background: var(--black-alpha-24); pointer-events: none; }
/* ─── Topbar ─── */
.topbar {
display: flex; align-items: center; gap: 12px;
padding: 14px 28px;
border-bottom: 1px solid var(--border-faint);
background: var(--background-base);
position: relative; z-index: 2;
}
.crumbs { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--black-alpha-48); }
.crumbs .sep { color: var(--black-alpha-32); }
.crumbs .here { color: var(--accent-black); font-weight: 500; }
.crumbs a:hover { color: var(--accent-black); }
.topbar .right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.balance-chip {
display: inline-flex; align-items: center; gap: 7px;
height: 36px;
padding: 0 14px 0 12px;
background: var(--surface);
border: 1px solid var(--border-faint);
border-radius: var(--r-pill);
font-size: 13px;
color: var(--black-alpha-56);
cursor: pointer;
transition: background var(--t-base), border-color var(--t-base);
}
.balance-chip:hover { background: var(--black-alpha-4); border-color: var(--black-alpha-24); }
.balance-chip strong { color: var(--accent-black); font-weight: 600; font-variant-numeric: tabular-nums; }
.balance-chip svg { width: 13px; height: 13px; color: var(--heat); }
.icon-btn {
width: 36px; height: 36px;
display: flex; align-items: center; justify-content: center;
background: var(--surface);
border: 1px solid var(--border-faint);
border-radius: var(--r-md);
color: var(--black-alpha-56);
cursor: pointer;
position: relative;
transition: background var(--t-base), border-color var(--t-base), color var(--t-base);
}
.icon-btn:hover { background: var(--black-alpha-4); color: var(--accent-black); border-color: var(--black-alpha-24); }
.icon-btn svg { width: 15px; height: 15px; }
.icon-btn .dot-noti {
position: absolute; top: 8px; right: 9px;
width: 7px; height: 7px; border-radius: 50%;
background: var(--heat); border: 1.5px solid var(--surface);
}
/* ─── Content ─── */
.content {
padding: 48px 56px 72px;
position: relative;
z-index: 1;
max-width: 1480px;
margin: 0 auto;
min-height: calc(100vh - 64px);
}
.content > .corner-mark { display: none; }
.page-head {
display: flex; align-items: flex-start; justify-content: space-between;
margin-bottom: 36px; gap: 16px; flex-wrap: wrap;
}
.page-head h1 {
font-size: 28px; font-weight: 600; letter-spacing: -.02em; line-height: 1.25;
color: var(--accent-black);
}
.page-head .sub {
font-size: 14px; color: var(--black-alpha-56);
margin-top: 10px;
display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.page-head .sub .mono { font-family: var(--font-mono); font-size: 11.5px; color: var(--black-alpha-48); letter-spacing: .04em; }
.page-head .actions { display: flex; gap: 10px; align-items: center; }
.section-h { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 14px; }
.section-h h2 { font-size: 16px; font-weight: 600; letter-spacing: -.01em; color: var(--accent-black); }
.section-h .more {
font-family: var(--font-mono); font-size: 11.5px;
color: var(--black-alpha-48); letter-spacing: .04em;
cursor: pointer;
transition: color var(--t-base);
}
.section-h .more:hover { color: var(--heat); }
/* ─── Buttons · 统一高度 36 / 8 px 圆角 / 真 1px border / hover bg 切换 ─── */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 6px;
height: 36px;
padding: 0 16px;
border-radius: var(--r-md);
font-size: 13px; font-weight: 500;
background: var(--surface);
color: var(--accent-black);
cursor: pointer;
white-space: nowrap;
font-family: inherit;
border: 1px solid var(--black-alpha-12);
transition: background var(--t-base), border-color var(--t-base), transform var(--t-fast);
}
.btn:hover { background: var(--black-alpha-4); border-color: var(--black-alpha-24); }
.btn:active { background: var(--black-alpha-7); transform: scale(.99); }
.btn:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--background-base), 0 0 0 4px var(--heat-40); }
.btn:disabled, .btn.disabled {
color: var(--black-alpha-32);
background: var(--black-alpha-5);
border-color: var(--black-alpha-12);
cursor: not-allowed;
transform: none;
}
.btn:disabled:hover, .btn.disabled:hover {
background: var(--black-alpha-5);
border-color: var(--black-alpha-12);
}
.btn svg { width: 13px; height: 13px; }
.btn-primary {
background: var(--heat);
color: var(--accent-white);
border-color: var(--heat);
font-weight: 600;
/* 继承 .btn 的 height: 36px / padding: 0 16px */
box-shadow: var(--shadow-cta);
}
.btn-primary:hover {
background: var(--heat);
border-color: var(--heat);
box-shadow: var(--shadow-cta-hover);
}
.btn-primary:active {
background: var(--heat);
transform: scale(.995);
box-shadow: var(--shadow-cta-active);
}
.btn-primary:disabled, .btn-primary.disabled {
background: var(--heat-40);
color: var(--accent-white);
border-color: var(--heat-40);
box-shadow: none;
}
.btn-ghost {
background: transparent;
border-color: transparent;
color: var(--black-alpha-56);
}
.btn-ghost:hover { background: var(--black-alpha-4); border-color: transparent; color: var(--accent-black); }
.btn-ghost:active { background: var(--black-alpha-7); }
.btn-sm { height: 28px; padding: 0 12px; font-size: 12px; border-radius: var(--r-md); }
.btn-lg { height: 40px; padding: 0 20px; font-size: 13.5px; }
/* ─── Pills ─── */
.pill {
display: inline-flex; align-items: center; gap: 6px;
padding: 4px 10px;
border-radius: var(--r-pill);
font-size: 11.5px; font-weight: 500;
border: 1px solid var(--border-faint);
background: var(--surface);
color: var(--black-alpha-56);
white-space: nowrap;
}
.pill.info { background: var(--heat-12); color: var(--heat); border-color: var(--heat-20); }
.pill.ok { background: var(--forest-bg); color: var(--accent-forest); border-color: var(--forest-bd); }
.pill.err { background: var(--crimson-bg); color: var(--accent-crimson); border-color: var(--crimson-bd); }
.pill.neutral { background: var(--black-alpha-4); color: var(--black-alpha-56); border-color: var(--border-faint); }
.pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
/* ─── Cards / containers · V2.1 统一 8 px 圆角 ─── */
.card-hard {
background: var(--surface);
border: 1px solid var(--border-faint);
border-radius: var(--r-md);
position: relative;
}
/* V2.1 spec §5.3 · 容器四角准星 · SVG 圆弧内凹(22×21 viewBox) */
.card-hard.with-corners::before, .card-hard.with-corners::after,
.with-corners .corner-tr, .with-corners .corner-bl {
content: ''; position: absolute;
width: 14px; height: 14px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 21' fill='%23e8e8e8'%3E%3Cpath d='M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z'/%3E%3C/svg%3E") no-repeat center;
background-size: contain;
pointer-events: none;
}
.card-hard.with-corners::before { top: -7px; left: -7px; }
.card-hard.with-corners::after { bottom: -7px; right: -7px; }
.with-corners .corner-tr { top: -7px; right: -7px; }
.with-corners .corner-bl { bottom: -7px; left: -7px; }
/* ─── Stats (KPI bar) ─── */
.stats {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0;
background: var(--surface);
border: 1px solid var(--border-faint);
border-radius: var(--r-md);
position: relative;
margin-bottom: 36px;
overflow: hidden;
}
.stat {
padding: 24px 28px;
border-right: 1px solid var(--border-faint);
position: relative;
cursor: pointer;
transition: background var(--t-base);
}
.stat:hover { background: var(--black-alpha-4); }
.stat:last-child { border-right: 0; }
.stat .lbl {
font-size: 12.5px; color: var(--black-alpha-48);
font-weight: 500; display: flex; align-items: center; gap: 8px;
}
.stat .lbl .badge {
font-family: var(--font-mono);
font-size: 10px; color: var(--black-alpha-48);
background: var(--black-alpha-4);
padding: 1px 7px;
border-radius: var(--r-sm);
border: 1px solid var(--border-faint);
letter-spacing: .04em;
}
.stat .v {
font-size: 32px; font-weight: 600; letter-spacing: -.02em;
line-height: 1.1; margin-top: 14px;
font-variant-numeric: tabular-nums;
color: var(--accent-black);
}
.stat .v small { font-size: 15px; color: var(--black-alpha-48); font-weight: 500; margin-left: 2px; }
.stat .delta {
font-family: var(--font-mono); font-size: 11px;
margin-top: 10px; color: var(--black-alpha-48); letter-spacing: .02em;
}
.stat .delta.up { color: var(--accent-forest); }
.stat .bar { height: 5px; background: var(--black-alpha-7); border-radius: 3px; margin-top: 14px; overflow: hidden; }
.stat .bar > span { display: block; height: 100%; background: var(--heat); border-radius: 3px; }
.stat .sub {
font-family: var(--font-mono); font-size: 10.5px;
color: var(--black-alpha-48); margin-top: 10px; letter-spacing: .02em;
}
/* ─── Form fields ─── */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.field-label { font-size: 13px; font-weight: 500; color: var(--accent-black); }
.field-label .req { color: var(--accent-crimson); margin-left: 2px; }
.field-hint { font-size: 12px; color: var(--black-alpha-48); }
.input, .textarea, .select {
height: 36px;
padding: 0 14px;
background: var(--surface);
border: 1px solid var(--black-alpha-12);
border-radius: var(--r-md);
font-size: 13.5px;
width: 100%;
font-family: inherit;
color: var(--accent-black);
transition: border-color var(--t-base), box-shadow var(--t-base), background var(--t-base);
}
.input:hover, .textarea:hover, .select:hover { border-color: var(--black-alpha-24); }
.input:focus, .textarea:focus, .select:focus {
border-color: var(--heat-40);
box-shadow: inset 0 0 0 1px var(--heat-40);
}
.input::placeholder, .textarea::placeholder { color: var(--black-alpha-48); }
.input:disabled, .textarea:disabled, .select:disabled {
background: var(--black-alpha-5);
color: var(--black-alpha-32);
cursor: not-allowed;
}
.textarea { height: auto; min-height: 88px; padding: 12px 14px; line-height: 1.6; resize: vertical; }
.select {
appearance: none;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 16 16' fill='none'><path d='M4 6l4 4 4-4' stroke='%237a7a7a' stroke-width='1.4'/></svg>");
background-repeat: no-repeat;
background-position: right 12px center;
padding-right: 32px;
}
/* ─── Tabs ─── */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border-faint); margin-bottom: 20px; }
.tab {
padding: 10px 14px; font-size: 13px;
color: var(--black-alpha-56);
border-bottom: 2px solid transparent;
margin-bottom: -1px;
cursor: pointer;
font-weight: 500; user-select: none;
transition: color var(--t-base), background var(--t-base);
border-radius: var(--r-md) var(--r-md) 0 0;
}
.tab:hover { color: var(--accent-black); background: var(--black-alpha-4); }
.tab.active { color: var(--accent-black); border-bottom-color: var(--heat); }
.tab .count {
font-family: var(--font-mono); font-size: 10.5px;
color: var(--black-alpha-48); margin-left: 6px;
padding: 1px 7px;
background: var(--black-alpha-4);
border-radius: var(--r-sm); letter-spacing: .04em;
}
.tab.active .count { background: var(--heat-12); color: var(--heat); }
/* ─── Filter chips · 统一高度 36 px 与 .btn / .input 对齐 ─── */
.chip {
height: 36px; padding: 0 14px;
border: 1px solid var(--border-faint);
background: var(--surface);
border-radius: var(--r-md);
font-size: 13px;
color: var(--black-alpha-56);
display: inline-flex; align-items: center; gap: 6px;
cursor: pointer;
font-family: inherit;
transition: background var(--t-base), border-color var(--t-base), color var(--t-base);
}
.chip:hover { background: var(--black-alpha-4); border-color: var(--black-alpha-24); color: var(--accent-black); }
.chip.active { border-color: var(--heat-40); color: var(--heat); background: var(--heat-12); }
.chip svg { width: 12px; height: 12px; }
/* ─── Toolbar ─── */
.toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; flex-wrap: wrap; }
.toolbar .search-inline {
position: relative; flex: 1; max-width: 360px;
}
.toolbar .search-inline svg {
position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
color: var(--black-alpha-56); width: 14px; height: 14px;
z-index: 2; pointer-events: none;
}
.toolbar .search-inline input { padding-left: 36px; }
/* ─── Progress (5 段流水线 · V2.1 语义色 + 脉动) ─── */
.prog { display: flex; gap: 3px; }
.prog span {
width: 18px; height: 5px; border-radius: 2px;
background: var(--black-alpha-8);
transition: background var(--t-base);
}
.prog span.done { background: var(--accent-forest); }
.prog span.cur {
background: var(--heat);
animation: prog-pulse 1.4s ease-in-out infinite;
}
.prog span.fail { background: var(--accent-crimson); }
@keyframes prog-pulse {
0%, 100% { opacity: 1; transform: scaleY(1); }
50% { opacity: .55; transform: scaleY(.7); }
}
/* ─── Table ─── */
table.t {
width: 100%; border-collapse: collapse;
background: var(--surface);
border: 1px solid var(--border-faint);
border-radius: var(--r-md);
overflow: hidden;
}
table.t thead th {
text-align: left;
font-size: 11.5px;
font-weight: 500;
color: var(--black-alpha-48);
padding: 14px 16px;
background: var(--black-alpha-3);
border-bottom: 1px solid var(--border-faint);
letter-spacing: .04em;
text-transform: uppercase;
font-family: var(--font-mono);
}
table.t tbody td {
padding: 16px;
border-bottom: 1px solid var(--border-faint);
font-size: 13px;
vertical-align: middle;
color: var(--accent-black);
}
table.t tbody tr:last-child td { border-bottom: 0; }
table.t tbody tr { cursor: pointer; transition: background var(--t-base); }
table.t tbody tr:hover { background: var(--black-alpha-4); }
/* ─── Placeholder thumb ─── */
.placeholder {
background:
repeating-linear-gradient(135deg, rgba(0,0,0,0.025) 0 1px, transparent 1px 12px),
var(--black-alpha-4);
border: 1px solid var(--border-faint);
border-radius: var(--r-md);
display: grid; place-items: center;
color: var(--black-alpha-48);
font-family: var(--font-mono);
font-size: 10px;
letter-spacing: .04em;
user-select: none;
overflow: hidden;
position: relative;
text-align: center;
padding: 6px;
}
.placeholder .ph-frame {
background: rgba(255, 255, 255, .92);
border: 1px solid var(--border-faint);
border-radius: var(--r-sm);
padding: 3px 8px;
font-size: 10.5px;
color: var(--black-alpha-56);
font-weight: 500;
}
/* ─── Toast ─── */
.toast {
position: fixed; bottom: 24px; right: 24px;
background: var(--surface);
border: 1px solid var(--border-faint);
border-radius: var(--r-md);
padding: 14px 18px;
display: flex; align-items: center; gap: 12px;
box-shadow: var(--shadow-floating);
transform: translateX(420px);
transition: transform var(--t-slow);
z-index: 1000;
min-width: 260px;
}
.toast.show { transform: translateX(0); }
.toast .ic-t {
width: 26px; height: 26px;
background: var(--heat-12);
color: var(--heat);
border-radius: var(--r-md);
display: grid; place-items: center;
flex-shrink: 0;
}
.toast .ic-t svg { width: 13px; height: 13px; }
.toast .txt { font-size: 13px; color: var(--accent-black); font-weight: 500; }
.toast .txt .mono {
font-family: var(--font-mono); font-size: 11px;
color: var(--black-alpha-48); display: block; margin-top: 2px;
letter-spacing: .04em; font-weight: 400;
}
/* ─── Modal ─── */
.modal-bg {
position: fixed; inset: 0;
background: rgba(21, 20, 15, .42);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
display: none; align-items: center; justify-content: center;
z-index: 999;
opacity: 0;
transition: opacity .2s;
}
.modal-bg.show { display: flex; opacity: 1; }
.modal {
background: var(--surface);
border: 1px solid var(--border-faint);
border-radius: var(--r-md);
max-width: 480px; width: 90%;
position: relative;
transform: scale(.96);
transition: transform .25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.modal-bg.show .modal { transform: scale(1); }
.modal::before, .modal::after {
content: '';
position: absolute;
width: 14px; height: 14px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 21' fill='%23e8e8e8'%3E%3Cpath d='M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z'/%3E%3C/svg%3E") no-repeat center;
background-size: contain;
pointer-events: none;
color: var(--black-alpha-48);
font-family: var(--font-mono);
font-size: 13px; line-height: 1;
}
.modal::before { top: -7px; left: -7px; }
.modal::after { bottom: -7px; right: -7px; }
.modal .corner-tr, .modal .corner-bl {
position: absolute;
width: 14px; height: 14px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 21' fill='%23e8e8e8'%3E%3Cpath d='M10.5 4C10.5 7.31371 7.81371 10 4.5 10H0.5V11H4.5C7.81371 11 10.5 13.6863 10.5 17V21H11.5V17C11.5 13.6863 14.1863 11 17.5 11H21.5V10H17.5C14.1863 10 11.5 7.31371 11.5 4V0H10.5V4Z'/%3E%3C/svg%3E") no-repeat center;
background-size: contain;
pointer-events: none;
}
.modal .corner-tr { top: -7px; right: -7px; }
.modal .corner-bl { bottom: -7px; left: -7px; }
.modal-h {
padding: 22px 24px 16px;
border-bottom: 1px solid var(--border-faint);
display: flex; align-items: center; gap: 14px;
}
.modal-h .ic-m {
width: 36px; height: 36px;
background: var(--heat-12);
color: var(--heat);
border-radius: var(--r-md);
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.modal-h .ic-m svg { width: 17px; height: 17px; }
.modal-h .ti { font-size: 16px; font-weight: 600; line-height: 1.4; color: var(--accent-black); }
.modal-h .ti span {
display: block; font-family: var(--font-mono); font-size: 11px;
color: var(--black-alpha-48); font-weight: 400; margin-top: 4px; letter-spacing: .04em;
}
.modal-b { padding: 20px 24px; font-size: 13.5px; color: var(--black-alpha-72); line-height: 1.75; }
.modal-b .mono-acc {
font-family: var(--font-mono); color: var(--heat);
background: var(--heat-12); padding: 2px 6px;
font-size: 11.5px; border-radius: var(--r-sm);
}
.modal-f {
padding: 16px 24px;
border-top: 1px solid var(--border-faint);
display: flex; justify-content: flex-end; gap: 10px;
}
/* ─── Drawer ─── */
.drawer-bg {
position: fixed; inset: 0;
background: rgba(21, 20, 15, .32);
display: none;
z-index: 90;
}
.drawer-bg.show { display: block; }
.drawer {
position: fixed; right: 0; top: 0; bottom: 0;
width: 540px; max-width: 100vw;
background: var(--surface);
border-left: 1px solid var(--border-faint);
z-index: 95;
transform: translateX(100%);
transition: transform .25s cubic-bezier(.32, .72, 0, 1);
display: flex; flex-direction: column;
box-shadow: -4px 0 24px rgba(21, 20, 15, .04);
}
.drawer.show { transform: translateX(0); }
.drawer-h {
padding: 20px 24px;
border-bottom: 1px solid var(--border-faint);
display: flex; align-items: center;
}
.drawer-h h3 { font-size: 16px; font-weight: 600; color: var(--accent-black); }
.drawer-h .x {
margin-left: auto; width: 32px; height: 32px;
border-radius: var(--r-md);
display: grid; place-items: center;
color: var(--black-alpha-56); cursor: pointer;
transition: background var(--t-base);
}
.drawer-h .x:hover { background: var(--black-alpha-4); color: var(--accent-black); }
.drawer-b { padding: 24px; overflow-y: auto; flex: 1; }
.drawer-f {
padding: 16px 24px;
border-top: 1px solid var(--border-faint);
display: flex; gap: 10px; justify-content: flex-end;
background: var(--background-lighter);
}
/* ─── Scrollbar ─── */
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--black-alpha-12); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--black-alpha-24); }
/* ─── Responsive ─── */
@media (max-width: 1100px) {
.app { grid-template-columns: 1fr; }
aside.sidebar { display: none; }
.stats { grid-template-columns: repeat(2, 1fr); }
.stat:nth-child(2) { border-right: 0; }
.stat:nth-child(1), .stat:nth-child(2) { border-bottom: 1px solid var(--border-faint); }
.content { padding: 28px 24px 48px; }
}
/* ─── Spinner ─── */
.spinner {
width: 18px; height: 18px;
border: 2px solid var(--border-faint);
border-top-color: var(--heat);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }