refactor(web): 营销站重构为 Eleventy SSG,内容迁移至 Markdown
- 引入 Eleventy 静态站点生成器,页面统一使用 Nunjucks 模板 - base.njk 提供公共 nav / footer / CSS,消除三个页面间的重复代码 - 抽取 color.css(设计 token)+ style.css(公共组件 + utility 类) - index.njk:首页迁移,用 utility class 替换大量页面私有 CSS - download.njk:下载页重构,版本号/更新日志从 CHANGELOG.md 构建时解析,OS 自动识别 - docs.njk:文档页重构,12 章内容从 web/content/docs.md 构建时渲染,三列布局保留 - docs.css 单独提取,docs 专有样式不污染公共 CSS - 内容面向非技术用户重写,去除技术术语和内部路径引用 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
/* =========================================================================
|
||||
岩美 Design System — Foundations
|
||||
Tokens for color, type, spacing, radius, shadow.
|
||||
Import once at root: <link rel="stylesheet" href="colors_and_type.css">
|
||||
========================================================================= */
|
||||
|
||||
:root {
|
||||
color-scheme: light;
|
||||
|
||||
/* ---------- Brand: Primary (Slate Blue) ---------- */
|
||||
/* Trustworthy enterprise blue with a slight slate cast. */
|
||||
--brand-50: #EEF4FB;
|
||||
--brand-100: #D6E5F5;
|
||||
--brand-200: #ADC9EA;
|
||||
--brand-300: #7FA8DA;
|
||||
--brand-400: #4F86C6;
|
||||
--brand-500: #2563AC; /* Primary action */
|
||||
--brand-600: #1B4F8E; /* Hover */
|
||||
--brand-700: #154072; /* Pressed */
|
||||
--brand-800: #0F3057;
|
||||
--brand-900: #0A1F3B; /* Brand ink — headers, logo on light bg */
|
||||
|
||||
/* ---------- Neutrals (cool slate gray) ---------- */
|
||||
--gray-0: #FFFFFF;
|
||||
--gray-25: #FBFCFD;
|
||||
--gray-50: #F5F7FA;
|
||||
--gray-100: #ECEFF4;
|
||||
--gray-200: #DCE2EB;
|
||||
--gray-300: #C2CAD6;
|
||||
--gray-400: #99A3B3;
|
||||
--gray-500: #6E7888;
|
||||
--gray-600: #4F5867;
|
||||
--gray-700: #353C48;
|
||||
--gray-800: #232934;
|
||||
--gray-900: #141821;
|
||||
|
||||
/* ---------- Accent (bordeaux / 酒红) ---------- */
|
||||
/* Used sparingly: brand context cue (wine), key highlights, marketing only. */
|
||||
--accent-50: #FAEEF0;
|
||||
--accent-100: #F1D2D7;
|
||||
--accent-300: #C97B86;
|
||||
--accent-500: #8B2331;
|
||||
--accent-700: #5F1621;
|
||||
|
||||
/* ---------- Semantic ---------- */
|
||||
--success-50: #E8F5EE;
|
||||
--success-500: #2E8B57;
|
||||
--success-700: #1F6B41;
|
||||
|
||||
--warning-50: #FFF4DB;
|
||||
--warning-500: #E08E00;
|
||||
--warning-700: #A66700;
|
||||
|
||||
--danger-50: #FDECEC;
|
||||
--danger-500: #D14343;
|
||||
--danger-700: #9E2A2A;
|
||||
|
||||
--info-50: #E5F1FB;
|
||||
--info-500: #2F7BD0;
|
||||
--info-700: #1F5C9F;
|
||||
|
||||
/* ---------- Semantic foreground / background ---------- */
|
||||
--bg-app: var(--gray-50);
|
||||
--bg-surface: var(--gray-0);
|
||||
--bg-raised: var(--gray-0);
|
||||
--bg-sunken: var(--gray-100);
|
||||
--bg-overlay: rgba(20, 24, 33, 0.45);
|
||||
|
||||
--fg-default: var(--gray-800);
|
||||
--fg-muted: var(--gray-600);
|
||||
--fg-subtle: var(--gray-500);
|
||||
--fg-disabled: var(--gray-400);
|
||||
--fg-on-brand: #FFFFFF;
|
||||
--fg-link: var(--brand-500);
|
||||
|
||||
--border-subtle: var(--gray-100);
|
||||
--border-default: var(--gray-200);
|
||||
--border-strong: var(--gray-300);
|
||||
--border-focus: var(--brand-500);
|
||||
|
||||
/* ---------- Typography ---------- */
|
||||
/* Chinese-primary stack with PingFang on macOS/iOS, Microsoft YaHei on Windows,
|
||||
Noto Sans SC as web fallback (loaded via Google Fonts in index files). */
|
||||
--font-sans: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
|
||||
"Source Han Sans CN", "Noto Sans SC", -apple-system,
|
||||
BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
--font-display: var(--font-sans);
|
||||
--font-mono: "JetBrains Mono", "SF Mono", "Roboto Mono", Menlo, Consolas,
|
||||
"Microsoft YaHei", monospace;
|
||||
|
||||
/* Type scale — mobile-first, scales up for desktop dashboards */
|
||||
--text-2xs: 11px;
|
||||
--text-xs: 12px;
|
||||
--text-sm: 13px;
|
||||
--text-md: 14px; /* dashboard body default */
|
||||
--text-lg: 16px;
|
||||
--text-xl: 18px;
|
||||
--text-2xl: 22px;
|
||||
--text-3xl: 28px;
|
||||
--text-4xl: 36px;
|
||||
--text-5xl: 48px;
|
||||
|
||||
--leading-tight: 1.25;
|
||||
--leading-snug: 1.4;
|
||||
--leading-normal: 1.55;
|
||||
--leading-loose: 1.75;
|
||||
|
||||
--weight-regular: 400;
|
||||
--weight-medium: 500;
|
||||
--weight-semibold: 600;
|
||||
--weight-bold: 700;
|
||||
|
||||
/* Tracking — Chinese reads better with subtle positive tracking */
|
||||
--tracking-tight: -0.01em;
|
||||
--tracking-normal: 0;
|
||||
--tracking-wide: 0.02em;
|
||||
--tracking-cn-display: 0.04em; /* Chinese display headers */
|
||||
|
||||
/* ---------- Spacing (4px base) ---------- */
|
||||
--space-0: 0;
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 12px;
|
||||
--space-4: 16px;
|
||||
--space-5: 20px;
|
||||
--space-6: 24px;
|
||||
--space-8: 32px;
|
||||
--space-10: 40px;
|
||||
--space-12: 48px;
|
||||
--space-16: 64px;
|
||||
--space-20: 80px;
|
||||
--space-24: 96px;
|
||||
|
||||
/* ---------- Radius — restrained, enterprise-grade ---------- */
|
||||
--radius-xs: 2px;
|
||||
--radius-sm: 4px;
|
||||
--radius-md: 6px; /* default for inputs, buttons, badges */
|
||||
--radius-lg: 10px; /* cards */
|
||||
--radius-xl: 14px;
|
||||
--radius-pill: 999px;
|
||||
|
||||
/* ---------- Elevation — soft, neutral, no colored shadows ---------- */
|
||||
--shadow-xs: 0 1px 2px rgba(20, 24, 33, 0.04);
|
||||
--shadow-sm: 0 1px 2px rgba(20, 24, 33, 0.06), 0 1px 3px rgba(20, 24, 33, 0.04);
|
||||
--shadow-md: 0 2px 4px rgba(20, 24, 33, 0.06), 0 4px 8px rgba(20, 24, 33, 0.05);
|
||||
--shadow-lg: 0 4px 12px rgba(20, 24, 33, 0.08), 0 12px 24px rgba(20, 24, 33, 0.06);
|
||||
--shadow-xl: 0 8px 20px rgba(20, 24, 33, 0.10), 0 20px 40px rgba(20, 24, 33, 0.08);
|
||||
--shadow-inset: inset 0 1px 0 rgba(255,255,255,0.6), inset 0 -1px 0 rgba(20,24,33,0.04);
|
||||
--ring-focus: 0 0 0 3px rgba(37, 99, 172, 0.22);
|
||||
|
||||
/* ---------- Motion ---------- */
|
||||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||||
--ease-emphasized: cubic-bezier(0.2, 0, 0, 1.2);
|
||||
--ease-decelerate: cubic-bezier(0, 0, 0.2, 1);
|
||||
--duration-fast: 120ms;
|
||||
--duration-base: 180ms;
|
||||
--duration-slow: 240ms;
|
||||
|
||||
/* ---------- Layout ---------- */
|
||||
--layout-sidebar: 240px;
|
||||
--layout-sidebar-collapsed: 64px;
|
||||
--layout-topbar: 56px;
|
||||
--layout-content-max: 1440px;
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
Semantic element styles — apply to base elements within design system docs.
|
||||
These do NOT bleed into ui_kits / pages with their own styles.
|
||||
========================================================================= */
|
||||
.ds-typography {
|
||||
font-family: var(--font-sans);
|
||||
color: var(--fg-default);
|
||||
font-feature-settings: "tnum" 1, "ss01" 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
.ds-typography h1,
|
||||
.ds-h1 {
|
||||
font-size: var(--text-4xl);
|
||||
font-weight: var(--weight-semibold);
|
||||
line-height: var(--leading-tight);
|
||||
letter-spacing: var(--tracking-cn-display);
|
||||
color: var(--brand-900);
|
||||
margin: 0 0 var(--space-4);
|
||||
}
|
||||
.ds-typography h2,
|
||||
.ds-h2 {
|
||||
font-size: var(--text-3xl);
|
||||
font-weight: var(--weight-semibold);
|
||||
line-height: var(--leading-tight);
|
||||
letter-spacing: var(--tracking-cn-display);
|
||||
color: var(--brand-900);
|
||||
margin: 0 0 var(--space-3);
|
||||
}
|
||||
.ds-typography h3,
|
||||
.ds-h3 {
|
||||
font-size: var(--text-2xl);
|
||||
font-weight: var(--weight-semibold);
|
||||
line-height: var(--leading-snug);
|
||||
color: var(--gray-900);
|
||||
margin: 0 0 var(--space-3);
|
||||
}
|
||||
.ds-typography h4,
|
||||
.ds-h4 {
|
||||
font-size: var(--text-xl);
|
||||
font-weight: var(--weight-semibold);
|
||||
line-height: var(--leading-snug);
|
||||
color: var(--gray-900);
|
||||
margin: 0 0 var(--space-2);
|
||||
}
|
||||
.ds-typography h5,
|
||||
.ds-h5 {
|
||||
font-size: var(--text-lg);
|
||||
font-weight: var(--weight-semibold);
|
||||
line-height: var(--leading-snug);
|
||||
color: var(--gray-800);
|
||||
margin: 0 0 var(--space-2);
|
||||
}
|
||||
.ds-typography p,
|
||||
.ds-body {
|
||||
font-size: var(--text-md);
|
||||
font-weight: var(--weight-regular);
|
||||
line-height: var(--leading-normal);
|
||||
color: var(--fg-default);
|
||||
margin: 0 0 var(--space-3);
|
||||
}
|
||||
.ds-typography small,
|
||||
.ds-caption {
|
||||
font-size: var(--text-xs);
|
||||
color: var(--fg-muted);
|
||||
line-height: var(--leading-snug);
|
||||
}
|
||||
.ds-typography code,
|
||||
.ds-mono {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.93em;
|
||||
background: var(--gray-100);
|
||||
padding: 1px 6px;
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--gray-800);
|
||||
}
|
||||
.ds-num {
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-feature-settings: "tnum" 1;
|
||||
}
|
||||
.ds-label {
|
||||
font-size: var(--text-xs);
|
||||
font-weight: var(--weight-medium);
|
||||
letter-spacing: var(--tracking-wide);
|
||||
text-transform: none; /* Chinese never uppercases */
|
||||
color: var(--fg-muted);
|
||||
}
|
||||
|
||||
/* Focus ring shared across the system */
|
||||
.ds-focusable:focus-visible,
|
||||
:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: var(--ring-focus);
|
||||
border-color: var(--border-focus);
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
/* ====================================================================
|
||||
DOCS SUB-HEADER
|
||||
==================================================================== */
|
||||
.docs-subnav {
|
||||
background: var(--gray-25);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
position: sticky;
|
||||
top: 64px;
|
||||
z-index: 40;
|
||||
}
|
||||
.docs-subnav-inner {
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
padding: 12px 32px;
|
||||
display: flex; align-items: center; gap: 24px;
|
||||
}
|
||||
.breadcrumb {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
font-size: var(--text-sm);
|
||||
color: var(--fg-muted);
|
||||
}
|
||||
.breadcrumb .sep { color: var(--gray-300); }
|
||||
.breadcrumb a { color: var(--fg-muted); }
|
||||
.breadcrumb a:hover { color: var(--brand-500); }
|
||||
.breadcrumb .current { color: var(--gray-900); font-weight: 500; }
|
||||
|
||||
.docs-search {
|
||||
flex: 1; max-width: 480px;
|
||||
position: relative;
|
||||
}
|
||||
.docs-search input {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
padding: 0 12px 0 38px;
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-md);
|
||||
background: var(--gray-0);
|
||||
font-family: inherit;
|
||||
font-size: var(--text-sm);
|
||||
color: var(--gray-800);
|
||||
outline: none;
|
||||
transition: border-color var(--duration-fast) var(--ease-standard),
|
||||
box-shadow var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
.docs-search input:focus { border-color: var(--brand-500); box-shadow: var(--ring-focus); }
|
||||
.docs-search input::placeholder { color: var(--fg-subtle); }
|
||||
.docs-search .search-icon {
|
||||
position: absolute;
|
||||
left: 12px; top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 16px; height: 16px;
|
||||
color: var(--fg-subtle);
|
||||
}
|
||||
.docs-search .kbd {
|
||||
position: absolute;
|
||||
right: 8px; top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: var(--gray-100);
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: 3px;
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
color: var(--fg-muted);
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.docs-version {
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
background: var(--gray-0);
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 6px 12px;
|
||||
font-size: var(--text-sm);
|
||||
color: var(--gray-700);
|
||||
}
|
||||
.docs-version .icon { width: 14px; height: 14px; }
|
||||
.docs-version-label { color: var(--fg-subtle); font-size: var(--text-xs); }
|
||||
|
||||
/* ====================================================================
|
||||
DOCS LAYOUT (three-column)
|
||||
==================================================================== */
|
||||
.docs-layout {
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
padding: 32px;
|
||||
display: grid;
|
||||
grid-template-columns: 240px 1fr 240px;
|
||||
gap: 48px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
/* ====================================================================
|
||||
LEFT TOC
|
||||
==================================================================== */
|
||||
.docs-toc {
|
||||
position: sticky;
|
||||
top: 132px;
|
||||
max-height: calc(100vh - 152px);
|
||||
overflow-y: auto;
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
.toc-section { margin-bottom: 18px; }
|
||||
.toc-section-title {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--fg-subtle);
|
||||
text-transform: uppercase;
|
||||
margin: 0 0 10px;
|
||||
padding-left: 12px;
|
||||
}
|
||||
.toc-link {
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
padding: 7px 12px;
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--gray-700);
|
||||
font-weight: 400;
|
||||
transition: background var(--duration-fast) var(--ease-standard),
|
||||
color var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
.toc-link:hover { background: var(--gray-100); color: var(--brand-900); }
|
||||
.toc-link .toc-num {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 11px;
|
||||
color: var(--fg-subtle);
|
||||
min-width: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.toc-link.active {
|
||||
background: var(--brand-50);
|
||||
color: var(--brand-700);
|
||||
font-weight: 500;
|
||||
}
|
||||
.toc-link.active .toc-num { color: var(--brand-500); }
|
||||
|
||||
/* ====================================================================
|
||||
MAIN CONTENT
|
||||
==================================================================== */
|
||||
.docs-main { min-width: 0; max-width: 760px; }
|
||||
|
||||
.docs-chapter { padding-bottom: 48px; border-bottom: 1px solid var(--border-subtle); margin-bottom: 48px; }
|
||||
.docs-chapter:last-child { border-bottom: none; margin-bottom: 0; }
|
||||
|
||||
.docs-main h2 {
|
||||
font-size: var(--text-2xl);
|
||||
font-weight: 600;
|
||||
color: var(--brand-900);
|
||||
margin: 0 0 16px;
|
||||
letter-spacing: 0.02em;
|
||||
scroll-margin-top: 132px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 2px solid var(--brand-100);
|
||||
}
|
||||
.docs-main h3 {
|
||||
font-size: var(--text-lg);
|
||||
font-weight: 600;
|
||||
color: var(--gray-900);
|
||||
margin: 32px 0 12px;
|
||||
scroll-margin-top: 132px;
|
||||
}
|
||||
.docs-main p {
|
||||
font-size: var(--text-md);
|
||||
color: var(--gray-700);
|
||||
line-height: 1.75;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
.docs-main strong { color: var(--brand-900); font-weight: 600; }
|
||||
.docs-main em { color: var(--brand-700); font-style: normal; font-weight: 500; }
|
||||
.docs-main code {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.92em;
|
||||
background: var(--gray-100);
|
||||
color: var(--brand-700);
|
||||
padding: 1px 6px;
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
.docs-main a {
|
||||
color: var(--brand-500);
|
||||
font-weight: 500;
|
||||
border-bottom: 1px solid var(--brand-200);
|
||||
}
|
||||
.docs-main a:hover { color: var(--brand-700); border-color: var(--brand-500); }
|
||||
|
||||
.docs-main ol, .docs-main ul {
|
||||
margin: 0 0 16px;
|
||||
padding-left: 24px;
|
||||
}
|
||||
.docs-main li {
|
||||
font-size: var(--text-md);
|
||||
color: var(--gray-700);
|
||||
line-height: 1.75;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.docs-main ol li::marker {
|
||||
color: var(--brand-500);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Rendered markdown tables */
|
||||
.docs-main table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 16px 0 24px;
|
||||
font-size: var(--text-sm);
|
||||
background: var(--gray-0);
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
}
|
||||
.docs-main th, .docs-main td {
|
||||
padding: 10px 14px;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
line-height: 1.55;
|
||||
}
|
||||
.docs-main thead th {
|
||||
background: var(--gray-50);
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 600;
|
||||
color: var(--gray-700);
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
border-bottom: 1px solid var(--border-default);
|
||||
}
|
||||
.docs-main tbody tr:last-child td { border-bottom: none; }
|
||||
.docs-main tbody tr:hover { background: var(--gray-25); }
|
||||
|
||||
/* Rendered markdown code blocks */
|
||||
.docs-main pre {
|
||||
background: var(--gray-25);
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 16px 20px;
|
||||
overflow-x: auto;
|
||||
margin: 16px 0 24px;
|
||||
}
|
||||
.docs-main pre code {
|
||||
background: none;
|
||||
color: var(--gray-800);
|
||||
padding: 0;
|
||||
font-size: var(--text-sm);
|
||||
line-height: 1.6;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/* Blockquote → callout-style */
|
||||
.docs-main blockquote {
|
||||
background: var(--info-50);
|
||||
border-left: 3px solid var(--info-500);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 14px 18px;
|
||||
margin: 16px 0 24px;
|
||||
color: var(--info-700);
|
||||
}
|
||||
.docs-main blockquote p { color: var(--gray-700); margin: 0; font-size: var(--text-sm); line-height: 1.6; }
|
||||
|
||||
/* ====================================================================
|
||||
RIGHT RAIL
|
||||
==================================================================== */
|
||||
.docs-rail {
|
||||
position: sticky;
|
||||
top: 132px;
|
||||
font-size: var(--text-sm);
|
||||
}
|
||||
.rail-title {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--fg-subtle);
|
||||
text-transform: uppercase;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
.rail-list { display: flex; flex-direction: column; gap: 2px; list-style: none; padding: 0; margin: 0 0 24px; }
|
||||
.rail-list a {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--fg-muted);
|
||||
font-size: 13px;
|
||||
border-left: 2px solid transparent;
|
||||
}
|
||||
.rail-list a:hover { color: var(--brand-700); }
|
||||
.rail-list a.active {
|
||||
color: var(--brand-700);
|
||||
border-left-color: var(--brand-500);
|
||||
font-weight: 500;
|
||||
}
|
||||
.rail-actions {
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
display: flex; flex-direction: column; gap: 6px;
|
||||
}
|
||||
.rail-action {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
padding: 6px 10px;
|
||||
font-size: 13px;
|
||||
color: var(--fg-muted);
|
||||
border-radius: var(--radius-sm);
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
font-family: inherit;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
.rail-action:hover { background: var(--gray-50); color: var(--brand-700); }
|
||||
.rail-action .icon { width: 14px; height: 14px; }
|
||||
|
||||
/* ====================================================================
|
||||
FEEDBACK WIDGET
|
||||
==================================================================== */
|
||||
.docs-feedback {
|
||||
margin-top: 40px;
|
||||
padding: 24px;
|
||||
background: var(--gray-25);
|
||||
border-radius: var(--radius-lg);
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.feedback-q { font-size: var(--text-md); color: var(--gray-800); }
|
||||
.feedback-actions { display: flex; gap: 8px; }
|
||||
.feedback-btn {
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
background: var(--gray-0);
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-md);
|
||||
padding: 6px 14px;
|
||||
font-size: var(--text-sm);
|
||||
color: var(--gray-700);
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
.feedback-btn:hover { border-color: var(--brand-500); color: var(--brand-700); }
|
||||
.feedback-btn .icon { width: 14px; height: 14px; }
|
||||
|
||||
/* ====================================================================
|
||||
RESPONSIVE
|
||||
==================================================================== */
|
||||
@media (max-width: 1200px) {
|
||||
.docs-layout { grid-template-columns: 220px 1fr; gap: 32px; }
|
||||
.docs-rail { display: none; }
|
||||
}
|
||||
@media (max-width: 880px) {
|
||||
.docs-layout { grid-template-columns: 1fr; gap: 24px; padding: 16px; }
|
||||
.docs-toc { position: static; max-height: none; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 16px; margin-bottom: 8px; }
|
||||
.docs-subnav-inner { padding: 10px 16px; }
|
||||
.docs-search { max-width: none; }
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
(function() {
|
||||
var KEYS = ['access_token','refresh_token','username','real_name','shop_no','shop_id','role'];
|
||||
|
||||
function getAuthUser() {
|
||||
var token = localStorage.getItem('flutter.access_token');
|
||||
var username = localStorage.getItem('flutter.username');
|
||||
if (!token || !username) return null;
|
||||
return {
|
||||
username: username,
|
||||
realName: localStorage.getItem('flutter.real_name') || '',
|
||||
role: localStorage.getItem('flutter.role') || '',
|
||||
shopNo: localStorage.getItem('flutter.shop_no') || '',
|
||||
};
|
||||
}
|
||||
|
||||
function doLogout() {
|
||||
KEYS.forEach(function(k) { localStorage.removeItem('flutter.' + k); });
|
||||
location.reload();
|
||||
}
|
||||
|
||||
function toggleUserMenu() {
|
||||
var el = document.getElementById('userDropdown');
|
||||
if (el) el.classList.toggle('open');
|
||||
}
|
||||
|
||||
// 点击外部关闭 dropdown
|
||||
document.addEventListener('click', function(e) {
|
||||
var menu = document.getElementById('userDropdown');
|
||||
if (!menu) return;
|
||||
var navUser = menu.closest('.nav-user');
|
||||
if (navUser && !navUser.contains(e.target)) menu.classList.remove('open');
|
||||
});
|
||||
|
||||
function renderNav() {
|
||||
var cta = document.getElementById('nav-cta');
|
||||
if (!cta) return;
|
||||
var user = getAuthUser();
|
||||
if (user) {
|
||||
var display = user.realName || user.username;
|
||||
var initial = display.charAt(0).toUpperCase();
|
||||
var roleMap = { admin: '管理员', user: '成员', readonly: '只读' };
|
||||
var roleLabel = roleMap[user.role] || user.role;
|
||||
cta.innerHTML =
|
||||
'<div class="nav-user">'
|
||||
+ '<button class="nav-user-btn" onclick="toggleUserMenu()">'
|
||||
+ '<div class="nav-avatar">' + initial + '</div>'
|
||||
+ '<span>' + display + '</span>'
|
||||
+ '<i data-lucide="chevron-down" class="icon"></i>'
|
||||
+ '</button>'
|
||||
+ '<div class="nav-dropdown" id="userDropdown">'
|
||||
+ '<div style="padding:10px 14px 6px;border-bottom:1px solid var(--border-subtle);margin-bottom:4px">'
|
||||
+ '<div style="font-size:13px;font-weight:600;color:var(--brand-900)">' + display + '</div>'
|
||||
+ '<div style="font-size:11px;color:var(--fg-muted);margin-top:2px">'
|
||||
+ (user.shopNo ? user.shopNo + ' · ' : '') + roleLabel
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
+ '<a href="/app/"><i data-lucide="layout-dashboard" class="icon"></i>进入管理端</a>'
|
||||
+ '<div class="nav-dropdown-divider"></div>'
|
||||
+ '<button class="logout" onclick="doLogout()"><i data-lucide="log-out" class="icon"></i>退出登录</button>'
|
||||
+ '</div></div>';
|
||||
} else {
|
||||
cta.innerHTML =
|
||||
'<a href="/app/" class="btn btn-ghost">登录</a>'
|
||||
+ '<a href="/app/" class="btn btn-primary">免费试用</a>';
|
||||
}
|
||||
if (window.lucide) lucide.createIcons();
|
||||
}
|
||||
|
||||
// 暴露给 onclick 调用
|
||||
window.toggleUserMenu = toggleUserMenu;
|
||||
window.doLogout = doLogout;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
renderNav();
|
||||
if (window.lucide) lucide.createIcons();
|
||||
|
||||
// 页内锚点平滑滚动
|
||||
document.querySelectorAll('a[href^="#"]').forEach(function(a) {
|
||||
a.addEventListener('click', function(e) {
|
||||
var id = a.getAttribute('href');
|
||||
if (!id || id.length < 2) return;
|
||||
var target = document.querySelector(id);
|
||||
if (target) {
|
||||
e.preventDefault();
|
||||
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,183 @@
|
||||
/* ================================================================
|
||||
shared.css — 跨页面公用样式
|
||||
设计 token 由 colors_and_type.css 提供
|
||||
================================================================ */
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
font-family: var(--font-sans);
|
||||
color: var(--fg-default);
|
||||
background: var(--gray-25);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "tnum" 1;
|
||||
}
|
||||
img, svg { display: block; max-width: 100%; }
|
||||
a { color: inherit; text-decoration: none; }
|
||||
button { font-family: inherit; cursor: pointer; }
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Buttons
|
||||
---------------------------------------------------------------- */
|
||||
.btn {
|
||||
display: inline-flex; align-items: center; gap: 8px;
|
||||
height: 40px; padding: 0 18px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--text-md); font-weight: 500;
|
||||
border: 1px solid transparent;
|
||||
transition: background var(--duration-fast) var(--ease-standard),
|
||||
border-color var(--duration-fast) var(--ease-standard),
|
||||
color var(--duration-fast) var(--ease-standard);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.btn-primary { background: var(--brand-500); color: #fff; }
|
||||
.btn-primary:hover { background: var(--brand-600); }
|
||||
.btn-primary:active { background: var(--brand-700); }
|
||||
.btn-secondary { background: var(--gray-0); color: var(--brand-900); border-color: var(--border-default); }
|
||||
.btn-secondary:hover { background: var(--gray-50); border-color: var(--border-strong); }
|
||||
.btn-ghost { background: transparent; color: var(--fg-default); }
|
||||
.btn-ghost:hover { background: var(--gray-100); }
|
||||
.btn-lg { height: 48px; padding: 0 24px; font-size: var(--text-lg); }
|
||||
.btn .icon { width: 18px; height: 18px; }
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Layout helpers
|
||||
---------------------------------------------------------------- */
|
||||
.container {
|
||||
max-width: 1280px;
|
||||
margin: 0 auto;
|
||||
padding: 0 32px;
|
||||
}
|
||||
.section { padding: 96px 0; }
|
||||
.section-tight { padding: 64px 0; }
|
||||
.eyebrow {
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--brand-500);
|
||||
text-transform: uppercase;
|
||||
margin: 0 0 12px;
|
||||
}
|
||||
.section-title {
|
||||
font-size: var(--text-4xl);
|
||||
font-weight: 600;
|
||||
line-height: 1.18;
|
||||
letter-spacing: var(--tracking-cn-display);
|
||||
color: var(--brand-900);
|
||||
margin: 0 0 16px;
|
||||
max-width: 720px;
|
||||
}
|
||||
.section-sub {
|
||||
font-size: var(--text-lg);
|
||||
line-height: 1.6;
|
||||
color: var(--fg-muted);
|
||||
margin: 0;
|
||||
max-width: 640px;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Top Nav
|
||||
---------------------------------------------------------------- */
|
||||
.topnav {
|
||||
position: sticky; top: 0; z-index: 50;
|
||||
background: rgba(255,255,255,0.85);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.topnav-inner {
|
||||
height: 64px;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
max-width: 1440px; margin: 0 auto; padding: 0 32px;
|
||||
}
|
||||
.topnav-brand { display: flex; align-items: center; gap: 10px; }
|
||||
.topnav-brand img { height: 32px; }
|
||||
.topnav-links {
|
||||
display: flex; align-items: center; gap: 4px;
|
||||
font-size: var(--text-md); color: var(--gray-700);
|
||||
}
|
||||
.topnav-links a {
|
||||
padding: 8px 14px;
|
||||
border-radius: var(--radius-md);
|
||||
transition: background var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
.topnav-links a:hover { background: var(--gray-100); color: var(--brand-900); }
|
||||
.topnav-cta { display: flex; gap: 10px; align-items: center; }
|
||||
|
||||
/* Nav user dropdown */
|
||||
.nav-user { position: relative; }
|
||||
.nav-user-btn {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
height: 36px; padding: 0 12px;
|
||||
background: var(--gray-0); border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-pill); cursor: pointer;
|
||||
font-size: var(--text-md); color: var(--gray-800); font-weight: 500;
|
||||
transition: border-color var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
.nav-user-btn:hover { border-color: var(--border-strong); }
|
||||
.nav-avatar {
|
||||
width: 22px; height: 22px; border-radius: 50%;
|
||||
background: var(--brand-500); color: #fff;
|
||||
display: grid; place-items: center;
|
||||
font-size: 10px; font-weight: 700; flex-shrink: 0;
|
||||
}
|
||||
.nav-user-btn .icon { width: 14px; height: 14px; color: var(--fg-muted); }
|
||||
.nav-dropdown {
|
||||
display: none; position: absolute; top: calc(100% + 8px); right: 0;
|
||||
min-width: 160px; background: var(--gray-0);
|
||||
border: 1px solid var(--border-default); border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-lg); overflow: hidden; z-index: 100;
|
||||
}
|
||||
.nav-dropdown.open { display: block; }
|
||||
.nav-dropdown a, .nav-dropdown button {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
width: 100%; padding: 10px 14px;
|
||||
font-size: var(--text-sm); color: var(--gray-800);
|
||||
background: none; border: none; cursor: pointer;
|
||||
text-decoration: none; font-family: inherit;
|
||||
transition: background var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
.nav-dropdown a:hover, .nav-dropdown button:hover { background: var(--gray-50); }
|
||||
.nav-dropdown .icon { width: 14px; height: 14px; color: var(--fg-muted); }
|
||||
.nav-dropdown-divider { height: 1px; background: var(--border-subtle); margin: 4px 0; }
|
||||
.nav-dropdown .logout { color: var(--danger-600); }
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Footer
|
||||
---------------------------------------------------------------- */
|
||||
footer {
|
||||
background: var(--gray-25);
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
padding: 64px 0 40px;
|
||||
}
|
||||
.footer-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1.5fr repeat(4, 1fr);
|
||||
gap: 48px;
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
.footer-brand img { height: 32px; margin-bottom: 16px; }
|
||||
.footer-brand p { margin: 0 0 16px; max-width: 320px; line-height: 1.6; color: var(--fg-muted); }
|
||||
.footer-contact { font-size: var(--text-sm); color: var(--gray-700); line-height: 1.8; }
|
||||
.footer-col h5 {
|
||||
font-size: var(--text-xs); font-weight: 600;
|
||||
color: var(--brand-900); letter-spacing: 0.06em;
|
||||
margin: 0 0 16px; text-transform: uppercase;
|
||||
}
|
||||
.footer-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
|
||||
.footer-col li a { color: var(--gray-600); }
|
||||
.footer-col li a:hover { color: var(--brand-500); }
|
||||
.footer-bottom {
|
||||
border-top: 1px solid var(--border-subtle); padding-top: 24px;
|
||||
display: flex; justify-content: space-between;
|
||||
font-size: var(--text-xs); color: var(--fg-subtle);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Responsive
|
||||
---------------------------------------------------------------- */
|
||||
@media (max-width: 1024px) {
|
||||
.footer-grid { grid-template-columns: 1fr 1fr; }
|
||||
.container { padding: 0 20px; }
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
/* ================================================================
|
||||
style.css — 全局样式
|
||||
Token 由 color.css 提供
|
||||
分三层:① Reset & 基础 ② 组件 ③ 工具类
|
||||
================================================================ */
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
① Reset & 基础
|
||||
---------------------------------------------------------------- */
|
||||
* { box-sizing: border-box; }
|
||||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
font-family: var(--font-sans);
|
||||
color: var(--fg-default);
|
||||
background: var(--gray-25);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-feature-settings: "tnum" 1;
|
||||
}
|
||||
img, svg { display: block; max-width: 100%; }
|
||||
a { color: inherit; text-decoration: none; }
|
||||
button { font-family: inherit; cursor: pointer; }
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
② 组件
|
||||
---------------------------------------------------------------- */
|
||||
|
||||
/* -- Buttons -- */
|
||||
.btn {
|
||||
display: inline-flex; align-items: center; gap: 8px;
|
||||
height: 40px; padding: 0 18px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--text-md); font-weight: 500;
|
||||
border: 1px solid transparent;
|
||||
transition: background var(--duration-fast) var(--ease-standard),
|
||||
border-color var(--duration-fast) var(--ease-standard),
|
||||
color var(--duration-fast) var(--ease-standard);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.btn-primary { background: var(--brand-500); color: #fff; }
|
||||
.btn-primary:hover { background: var(--brand-600); }
|
||||
.btn-primary:active { background: var(--brand-700); }
|
||||
.btn-secondary { background: var(--gray-0); color: var(--brand-900); border-color: var(--border-default); }
|
||||
.btn-secondary:hover { background: var(--gray-50); border-color: var(--border-strong); }
|
||||
.btn-ghost { background: transparent; color: var(--fg-default); }
|
||||
.btn-ghost:hover { background: var(--gray-100); }
|
||||
.btn-lg { height: 48px; padding: 0 24px; font-size: var(--text-lg); }
|
||||
.btn .icon { width: 18px; height: 18px; }
|
||||
|
||||
/* -- Layout helpers -- */
|
||||
.container { max-width: 1280px; margin: 0 auto; padding: 0 32px; }
|
||||
.section { padding: 96px 0; }
|
||||
.section-tight { padding: 64px 0; }
|
||||
.eyebrow {
|
||||
font-size: var(--text-xs); font-weight: 600;
|
||||
letter-spacing: 0.12em; color: var(--brand-500);
|
||||
text-transform: uppercase; margin: 0 0 12px;
|
||||
}
|
||||
.section-title {
|
||||
font-size: var(--text-4xl); font-weight: 600;
|
||||
line-height: 1.18; letter-spacing: var(--tracking-cn-display);
|
||||
color: var(--brand-900); margin: 0 0 16px; max-width: 720px;
|
||||
}
|
||||
.section-sub {
|
||||
font-size: var(--text-lg); line-height: 1.6;
|
||||
color: var(--fg-muted); margin: 0; max-width: 640px;
|
||||
}
|
||||
|
||||
/* -- Top Nav -- */
|
||||
.topnav {
|
||||
position: sticky; top: 0; z-index: 50;
|
||||
background: rgba(255,255,255,0.85);
|
||||
backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.topnav-inner {
|
||||
height: 64px; display: flex; align-items: center; justify-content: space-between;
|
||||
max-width: 1440px; margin: 0 auto; padding: 0 32px;
|
||||
}
|
||||
.topnav-brand { display: flex; align-items: center; gap: 10px; }
|
||||
.topnav-brand img { height: 32px; }
|
||||
.topnav-links {
|
||||
display: flex; align-items: center; gap: 4px;
|
||||
font-size: var(--text-md); color: var(--gray-700);
|
||||
}
|
||||
.topnav-links a {
|
||||
padding: 8px 14px; border-radius: var(--radius-md);
|
||||
transition: background var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
.topnav-links a:hover { background: var(--gray-100); color: var(--brand-900); }
|
||||
.topnav-cta { display: flex; gap: 10px; align-items: center; }
|
||||
|
||||
/* Nav user dropdown */
|
||||
.nav-user { position: relative; }
|
||||
.nav-user-btn {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
height: 36px; padding: 0 12px;
|
||||
background: var(--gray-0); border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-pill); cursor: pointer;
|
||||
font-size: var(--text-md); color: var(--gray-800); font-weight: 500;
|
||||
transition: border-color var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
.nav-user-btn:hover { border-color: var(--border-strong); }
|
||||
.nav-avatar {
|
||||
width: 22px; height: 22px; border-radius: 50%;
|
||||
background: var(--brand-500); color: #fff;
|
||||
display: grid; place-items: center;
|
||||
font-size: 10px; font-weight: 700; flex-shrink: 0;
|
||||
}
|
||||
.nav-user-btn .icon { width: 14px; height: 14px; color: var(--fg-muted); }
|
||||
.nav-dropdown {
|
||||
display: none; position: absolute; top: calc(100% + 8px); right: 0;
|
||||
min-width: 160px; background: var(--gray-0);
|
||||
border: 1px solid var(--border-default); border-radius: var(--radius-lg);
|
||||
box-shadow: var(--shadow-lg); overflow: hidden; z-index: 100;
|
||||
}
|
||||
.nav-dropdown.open { display: block; }
|
||||
.nav-dropdown a, .nav-dropdown button {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
width: 100%; padding: 10px 14px;
|
||||
font-size: var(--text-sm); color: var(--gray-800);
|
||||
background: none; border: none; cursor: pointer;
|
||||
text-decoration: none; font-family: inherit;
|
||||
transition: background var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
.nav-dropdown a:hover, .nav-dropdown button:hover { background: var(--gray-50); }
|
||||
.nav-dropdown .icon { width: 14px; height: 14px; color: var(--fg-muted); }
|
||||
.nav-dropdown-divider { height: 1px; background: var(--border-subtle); margin: 4px 0; }
|
||||
.nav-dropdown .logout { color: var(--danger-600); }
|
||||
|
||||
/* -- Footer -- */
|
||||
footer {
|
||||
background: var(--gray-25);
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
padding: 64px 0 40px;
|
||||
}
|
||||
.footer-grid {
|
||||
display: grid; grid-template-columns: 1.5fr repeat(4, 1fr);
|
||||
gap: 48px; margin-bottom: 48px;
|
||||
}
|
||||
.footer-brand img { height: 32px; margin-bottom: 16px; }
|
||||
.footer-brand p { margin: 0 0 16px; max-width: 320px; line-height: 1.6; color: var(--fg-muted); }
|
||||
.footer-contact { font-size: var(--text-sm); color: var(--gray-700); line-height: 1.8; }
|
||||
.footer-col h5 {
|
||||
font-size: var(--text-xs); font-weight: 600;
|
||||
color: var(--brand-900); letter-spacing: 0.06em;
|
||||
margin: 0 0 16px; text-transform: uppercase;
|
||||
}
|
||||
.footer-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
|
||||
.footer-col li a { color: var(--gray-600); }
|
||||
.footer-col li a:hover { color: var(--brand-500); }
|
||||
.footer-bottom {
|
||||
border-top: 1px solid var(--border-subtle); padding-top: 24px;
|
||||
display: flex; justify-content: space-between;
|
||||
font-size: var(--text-xs); color: var(--fg-subtle);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
③ 工具类
|
||||
命名规则:{属性}-{值}
|
||||
间距值直接对应像素:p-8 = padding:8px,gap-16 = gap:16px
|
||||
---------------------------------------------------------------- */
|
||||
|
||||
/* -- Display -- */
|
||||
.d-flex { display: flex }
|
||||
.d-inline-flex { display: inline-flex }
|
||||
.d-grid { display: grid }
|
||||
.d-block { display: block }
|
||||
.d-inline { display: inline }
|
||||
.d-inline-block{ display: inline-block }
|
||||
.d-none { display: none }
|
||||
.place-center { display: grid; place-items: center } /* 图标容器常用 */
|
||||
|
||||
/* -- Flex -- */
|
||||
.flex-col { flex-direction: column }
|
||||
.flex-wrap { flex-wrap: wrap }
|
||||
.flex-1 { flex: 1 }
|
||||
.flex-shrink-0 { flex-shrink: 0 }
|
||||
.items-center { align-items: center }
|
||||
.items-start { align-items: flex-start }
|
||||
.items-end { align-items: flex-end }
|
||||
.items-baseline { align-items: baseline }
|
||||
.justify-center { justify-content: center }
|
||||
.justify-between { justify-content: space-between }
|
||||
.justify-end { justify-content: flex-end }
|
||||
.justify-start { justify-content: flex-start }
|
||||
|
||||
/* -- Grid 列模板 -- */
|
||||
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr) }
|
||||
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr) }
|
||||
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr) }
|
||||
.grid-5 { display: grid; grid-template-columns: repeat(5, 1fr) }
|
||||
|
||||
/* -- Gap -- */
|
||||
.gap-2 { gap: 2px }
|
||||
.gap-4 { gap: 4px }
|
||||
.gap-6 { gap: 6px }
|
||||
.gap-8 { gap: 8px }
|
||||
.gap-10 { gap: 10px }
|
||||
.gap-12 { gap: 12px }
|
||||
.gap-14 { gap: 14px }
|
||||
.gap-16 { gap: 16px }
|
||||
.gap-18 { gap: 18px }
|
||||
.gap-24 { gap: 24px }
|
||||
.gap-32 { gap: 32px }
|
||||
.gap-48 { gap: 48px }
|
||||
.gap-64 { gap: 64px }
|
||||
|
||||
/* -- Padding(全方向) -- */
|
||||
.p-0 { padding: 0 }
|
||||
.p-4 { padding: 4px }
|
||||
.p-6 { padding: 6px }
|
||||
.p-8 { padding: 8px }
|
||||
.p-10 { padding: 10px }
|
||||
.p-12 { padding: 12px }
|
||||
.p-14 { padding: 14px }
|
||||
.p-16 { padding: 16px }
|
||||
.p-18 { padding: 18px }
|
||||
.p-20 { padding: 20px }
|
||||
.p-24 { padding: 24px }
|
||||
.p-28 { padding: 28px }
|
||||
.p-32 { padding: 32px }
|
||||
.p-48 { padding: 48px }
|
||||
.p-56 { padding: 56px }
|
||||
.p-64 { padding: 64px }
|
||||
|
||||
/* px / py */
|
||||
.px-4 { padding-left: 4px; padding-right: 4px }
|
||||
.px-6 { padding-left: 6px; padding-right: 6px }
|
||||
.px-8 { padding-left: 8px; padding-right: 8px }
|
||||
.px-10 { padding-left: 10px; padding-right: 10px }
|
||||
.px-12 { padding-left: 12px; padding-right: 12px }
|
||||
.px-14 { padding-left: 14px; padding-right: 14px }
|
||||
.px-16 { padding-left: 16px; padding-right: 16px }
|
||||
.px-20 { padding-left: 20px; padding-right: 20px }
|
||||
.px-24 { padding-left: 24px; padding-right: 24px }
|
||||
.px-28 { padding-left: 28px; padding-right: 28px }
|
||||
.px-32 { padding-left: 32px; padding-right: 32px }
|
||||
|
||||
.py-2 { padding-top: 2px; padding-bottom: 2px }
|
||||
.py-4 { padding-top: 4px; padding-bottom: 4px }
|
||||
.py-6 { padding-top: 6px; padding-bottom: 6px }
|
||||
.py-8 { padding-top: 8px; padding-bottom: 8px }
|
||||
.py-10 { padding-top: 10px; padding-bottom: 10px }
|
||||
.py-12 { padding-top: 12px; padding-bottom: 12px }
|
||||
.py-14 { padding-top: 14px; padding-bottom: 14px }
|
||||
.py-16 { padding-top: 16px; padding-bottom: 16px }
|
||||
.py-20 { padding-top: 20px; padding-bottom: 20px }
|
||||
.py-24 { padding-top: 24px; padding-bottom: 24px }
|
||||
.py-32 { padding-top: 32px; padding-bottom: 32px }
|
||||
|
||||
/* pt / pb / pl / pr */
|
||||
.pt-4 { padding-top: 4px } .pb-4 { padding-bottom: 4px }
|
||||
.pt-6 { padding-top: 6px } .pb-6 { padding-bottom: 6px }
|
||||
.pt-8 { padding-top: 8px } .pb-8 { padding-bottom: 8px }
|
||||
.pt-12 { padding-top: 12px } .pb-12 { padding-bottom: 12px }
|
||||
.pt-14 { padding-top: 14px } .pb-14 { padding-bottom: 14px }
|
||||
.pt-16 { padding-top: 16px } .pb-16 { padding-bottom: 16px }
|
||||
.pt-24 { padding-top: 24px } .pb-24 { padding-bottom: 24px }
|
||||
.pt-32 { padding-top: 32px } .pb-32 { padding-bottom: 32px }
|
||||
.pl-12 { padding-left: 12px } .pr-12 { padding-right: 12px }
|
||||
.pl-16 { padding-left: 16px } .pr-16 { padding-right: 16px }
|
||||
.pl-24 { padding-left: 24px } .pr-24 { padding-right: 24px }
|
||||
|
||||
/* -- Margin -- */
|
||||
.m-0 { margin: 0 }
|
||||
.mx-auto { margin-left: auto; margin-right: auto }
|
||||
|
||||
.mb-0 { margin-bottom: 0 }
|
||||
.mb-2 { margin-bottom: 2px }
|
||||
.mb-4 { margin-bottom: 4px }
|
||||
.mb-6 { margin-bottom: 6px }
|
||||
.mb-8 { margin-bottom: 8px }
|
||||
.mb-10 { margin-bottom: 10px }
|
||||
.mb-12 { margin-bottom: 12px }
|
||||
.mb-14 { margin-bottom: 14px }
|
||||
.mb-16 { margin-bottom: 16px }
|
||||
.mb-18 { margin-bottom: 18px }
|
||||
.mb-24 { margin-bottom: 24px }
|
||||
.mb-32 { margin-bottom: 32px }
|
||||
.mb-48 { margin-bottom: 48px }
|
||||
|
||||
.mt-2 { margin-top: 2px }
|
||||
.mt-4 { margin-top: 4px }
|
||||
.mt-6 { margin-top: 6px }
|
||||
.mt-8 { margin-top: 8px }
|
||||
.mt-12 { margin-top: 12px }
|
||||
.mt-16 { margin-top: 16px }
|
||||
.mt-24 { margin-top: 24px }
|
||||
.mt-32 { margin-top: 32px }
|
||||
.mt-48 { margin-top: 48px }
|
||||
|
||||
.ml-4 { margin-left: 4px }
|
||||
.ml-8 { margin-left: 8px }
|
||||
.mr-4 { margin-right: 4px }
|
||||
.mr-8 { margin-right: 8px }
|
||||
|
||||
/* -- Font size(复用 token) -- */
|
||||
.fs-xs { font-size: var(--text-xs) }
|
||||
.fs-sm { font-size: var(--text-sm) }
|
||||
.fs-md { font-size: var(--text-md) }
|
||||
.fs-lg { font-size: var(--text-lg) }
|
||||
.fs-xl { font-size: var(--text-xl) }
|
||||
.fs-2xl { font-size: var(--text-2xl) }
|
||||
.fs-3xl { font-size: var(--text-3xl) }
|
||||
.fs-4xl { font-size: var(--text-4xl) }
|
||||
|
||||
/* -- Font weight -- */
|
||||
.fw-4 { font-weight: 400 }
|
||||
.fw-5 { font-weight: 500 }
|
||||
.fw-6 { font-weight: 600 }
|
||||
.fw-7 { font-weight: 700 }
|
||||
|
||||
/* -- Line height -- */
|
||||
.lh-1 { line-height: 1 }
|
||||
.lh-12 { line-height: 1.2 }
|
||||
.lh-14 { line-height: 1.4 }
|
||||
.lh-15 { line-height: 1.5 }
|
||||
.lh-16 { line-height: 1.6 }
|
||||
.lh-17 { line-height: 1.7 }
|
||||
.lh-18 { line-height: 1.8 }
|
||||
|
||||
/* -- Letter spacing -- */
|
||||
.ls-1 { letter-spacing: 0.04em }
|
||||
.ls-2 { letter-spacing: 0.06em }
|
||||
.ls-3 { letter-spacing: 0.10em }
|
||||
.ls-4 { letter-spacing: 0.12em }
|
||||
.ls-disp { letter-spacing: var(--tracking-cn-display) }
|
||||
|
||||
/* -- Text color -- */
|
||||
.text-brand { color: var(--brand-500) }
|
||||
.text-brand-hi { color: var(--brand-700) }
|
||||
.text-brand-900{ color: var(--brand-900) }
|
||||
.text-default { color: var(--fg-default) }
|
||||
.text-muted { color: var(--fg-muted) }
|
||||
.text-subtle { color: var(--fg-subtle) }
|
||||
.text-gray-6 { color: var(--gray-600) }
|
||||
.text-gray-7 { color: var(--gray-700) }
|
||||
.text-gray-8 { color: var(--gray-800) }
|
||||
.text-gray-9 { color: var(--gray-900) }
|
||||
.text-white { color: #fff }
|
||||
.text-success { color: var(--success-700) }
|
||||
.text-warning { color: var(--warning-700) }
|
||||
.text-danger { color: var(--danger-700) }
|
||||
.text-info { color: var(--info-700) }
|
||||
|
||||
/* -- Background -- */
|
||||
.bg-0 { background: var(--gray-0) }
|
||||
.bg-25 { background: var(--gray-25) }
|
||||
.bg-50 { background: var(--gray-50) }
|
||||
.bg-100 { background: var(--gray-100) }
|
||||
.bg-brand { background: var(--brand-500) }
|
||||
.bg-brand-50 { background: var(--brand-50) }
|
||||
.bg-brand-900{ background: var(--brand-900) }
|
||||
.bg-success-50 { background: var(--success-50) }
|
||||
.bg-warning-50 { background: var(--warning-50) }
|
||||
.bg-danger-50 { background: var(--danger-50) }
|
||||
.bg-info-50 { background: var(--info-50) }
|
||||
|
||||
/* -- Border -- */
|
||||
.border { border: 1px solid var(--border-default) }
|
||||
.border-top { border-top: 1px solid var(--border-default) }
|
||||
.border-bottom { border-bottom: 1px solid var(--border-default) }
|
||||
.border-left { border-left: 1px solid var(--border-default) }
|
||||
.border-subtle { border-color: var(--border-subtle) }
|
||||
.border-strong { border-color: var(--border-strong) }
|
||||
.border-brand { border-color: var(--brand-500) }
|
||||
.border-0 { border: none }
|
||||
|
||||
/* -- Border radius -- */
|
||||
.rounded-sm { border-radius: var(--radius-sm) }
|
||||
.rounded-md { border-radius: var(--radius-md) }
|
||||
.rounded-lg { border-radius: var(--radius-lg) }
|
||||
.rounded-xl { border-radius: var(--radius-xl) }
|
||||
.rounded-pill { border-radius: var(--radius-pill) }
|
||||
.rounded-full { border-radius: 50% }
|
||||
|
||||
/* -- Shadow -- */
|
||||
.shadow-sm { box-shadow: var(--shadow-sm) }
|
||||
.shadow-md { box-shadow: var(--shadow-md) }
|
||||
.shadow-lg { box-shadow: var(--shadow-lg) }
|
||||
.shadow-xl { box-shadow: var(--shadow-xl) }
|
||||
|
||||
/* -- Text helpers -- */
|
||||
.text-upper { text-transform: uppercase }
|
||||
.text-center { text-align: center }
|
||||
.text-right { text-align: right }
|
||||
.text-nowrap { white-space: nowrap }
|
||||
.font-mono { font-family: var(--font-mono) }
|
||||
.tabular { font-variant-numeric: tabular-nums }
|
||||
|
||||
/* -- Sizing & position -- */
|
||||
.w-full { width: 100% }
|
||||
.h-full { height: 100% }
|
||||
.min-w-0 { min-width: 0 }
|
||||
.pos-relative { position: relative }
|
||||
.pos-absolute { position: absolute }
|
||||
.pos-sticky { position: sticky }
|
||||
.overflow-hidden { overflow: hidden }
|
||||
.overflow-x-auto { overflow-x: auto }
|
||||
|
||||
/* -- Transition(常用属性组合) -- */
|
||||
.transition {
|
||||
transition: background var(--duration-fast) var(--ease-standard),
|
||||
border-color var(--duration-fast) var(--ease-standard),
|
||||
color var(--duration-fast) var(--ease-standard),
|
||||
box-shadow var(--duration-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Card & Badge 高频组合
|
||||
---------------------------------------------------------------- */
|
||||
|
||||
/* card:bg-0 + border + rounded-lg,三个页面共用 15+ 次 */
|
||||
.card {
|
||||
background: var(--gray-0);
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-lg);
|
||||
}
|
||||
|
||||
/* badge:状态标签小胶囊 */
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: var(--radius-pill);
|
||||
font-size: var(--text-xs);
|
||||
font-weight: 600;
|
||||
}
|
||||
.badge-brand { background: var(--brand-50); color: var(--brand-700) }
|
||||
.badge-success { background: var(--success-50); color: var(--success-700) }
|
||||
.badge-warning { background: var(--warning-50); color: var(--warning-700) }
|
||||
.badge-danger { background: var(--danger-50); color: var(--danger-700) }
|
||||
.badge-info { background: var(--info-50); color: var(--info-700) }
|
||||
.badge-gray { background: var(--gray-100); color: var(--gray-700) }
|
||||
.badge-solid { background: var(--brand-500); color: #fff }
|
||||
|
||||
/* icon 尺寸 */
|
||||
.icon-sm { width: 14px; height: 14px }
|
||||
.icon-md { width: 18px; height: 18px }
|
||||
.icon-lg { width: 22px; height: 22px }
|
||||
.icon-xl { width: 28px; height: 28px }
|
||||
.icon-2xl { width: 36px; height: 36px }
|
||||
|
||||
/* icon-box:方形图标容器(带背景色时使用) */
|
||||
.icon-box-sm { width: 28px; height: 28px; border-radius: var(--radius-sm); display: grid; place-items: center }
|
||||
.icon-box-md { width: 36px; height: 36px; border-radius: 8px; display: grid; place-items: center }
|
||||
.icon-box-lg { width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center }
|
||||
.icon-box-xl { width: 56px; height: 56px; border-radius: var(--radius-md); display: grid; place-items: center }
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
Responsive
|
||||
---------------------------------------------------------------- */
|
||||
@media (max-width: 1024px) {
|
||||
.footer-grid { grid-template-columns: 1fr 1fr; }
|
||||
.container { padding: 0 20px; }
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.grid-3, .grid-4, .grid-5 { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
Reference in New Issue
Block a user