/* ============================================================= 穿山甲 VPN · Pangolin VPN — Design Tokens colors_and_type.css Single source of truth: color ramps, semantic colors (light + dark), typography, spacing, radii, shadows, motion. ============================================================= */ /* ---- Webfonts (open-source; documented as the brand's chosen faces) ---- Sora — display / headings (geometric, friendly) Manrope — body / UI (humanist geometric) Noto Sans SC — Chinese (CJK companion) JetBrains Mono — data readouts (IP, speed, keys) */ @import url('https://fonts.googleapis.com/css2?family=Sora:wght@500;600;700&family=Manrope:wght@400;500;600;700&family=Noto+Sans+SC:wght@400;500;700&family=JetBrains+Mono:wght@400;500&display=swap'); :root { /* =========================================================== 1. PRIMITIVE COLOR RAMPS =========================================================== */ /* Clay / Copper — the pangolin-armor primary (warm earth) */ --clay-50: #FAF3ED; --clay-100: #F2E2D4; --clay-200: #E6C7AC; --clay-300: #D9A982; --clay-400: #CC8B5C; --clay-500: #B96A3D; /* ← brand primary */ --clay-600: #9E5630; --clay-700: #7E4426; --clay-800: #5E331D; --clay-900: #3D2213; /* Sand / Taupe — warm neutral ramp */ --sand-50: #FAF8F4; --sand-100: #F2EEE7; --sand-200: #E6DFD3; --sand-300: #D2C8B8; --sand-400: #B0A491; --sand-500: #8C8270; --sand-600: #6B6253; --sand-700: #4E4940; --sand-800: #2E2A24; --sand-900: #1F1C18; --sand-950: #14110E; /* warm espresso near-black */ /* Semantic hues (earth-tuned) */ --green-400: #7FB07A; --green-500: #5B8C5A; /* connected / secure */ --green-600: #467046; --amber-400: #E2B05A; --amber-500: #D69A3C; /* connecting / warning */ --amber-600: #B47E29; --red-400: #D4715A; --red-500: #C0533B; /* error / disconnect */ --red-600: #9E4230; /* =========================================================== 2. SEMANTIC TOKENS — LIGHT THEME (default) =========================================================== */ /* Backgrounds & surfaces */ --bg: var(--sand-50); /* app canvas */ --bg-subtle: var(--sand-100); /* striped / inset regions */ --surface: #FFFFFF; /* cards, sheets */ --surface-2: var(--sand-50); /* nested surface */ --overlay: rgba(31, 28, 24, 0.45); /* Foreground / text */ --fg1: var(--sand-900); /* primary text */ --fg2: var(--sand-600); /* secondary text */ --fg3: var(--sand-500); /* tertiary / captions */ --fg-on-accent: #FFFFFF; /* text on clay fills */ /* Brand / accent */ --accent: var(--clay-500); --accent-hover: var(--clay-600); --accent-press: var(--clay-700); --accent-subtle: var(--clay-50); --accent-border: var(--clay-200); /* Borders & lines */ --border: var(--sand-200); --border-strong: var(--sand-300); --ring: rgba(185, 106, 61, 0.35); /* focus ring (clay) */ /* Status */ --success: var(--green-500); --success-subtle: #E9F0E6; --warning: var(--amber-500); --warning-subtle: #F8EED6; --danger: var(--red-500); --danger-subtle: #F6E1DA; /* =========================================================== 3. TYPOGRAPHY =========================================================== */ --font-display: 'Sora', 'Noto Sans SC', system-ui, sans-serif; --font-sans: 'Manrope', 'Noto Sans SC', system-ui, sans-serif; --font-cjk: 'Noto Sans SC', 'Manrope', system-ui, sans-serif; --font-mono: 'JetBrains Mono', ui-monospace, 'SFMono-Regular', monospace; /* Type scale (root 16px) */ --text-display-xl: 3rem; /* 48 */ --text-display: 2.25rem; /* 36 */ --text-h1: 1.875rem; /* 30 */ --text-h2: 1.5rem; /* 24 */ --text-h3: 1.25rem; /* 20 */ --text-body-lg: 1.125rem; /* 18 */ --text-body: 1rem; /* 16 */ --text-sm: 0.875rem; /* 14 */ --text-caption: 0.75rem; /* 12 */ --leading-tight: 1.15; --leading-snug: 1.3; --leading-normal:1.5; --leading-relaxed:1.65; --tracking-tight: -0.02em; --tracking-snug: -0.01em; --tracking-wide: 0.04em; --tracking-caps: 0.08em; /* =========================================================== 4. SPACING (4px base) =========================================================== */ --space-0: 0; --space-1: 0.25rem; /* 4 */ --space-2: 0.5rem; /* 8 */ --space-3: 0.75rem; /* 12 */ --space-4: 1rem; /* 16 */ --space-5: 1.25rem; /* 20 */ --space-6: 1.5rem; /* 24 */ --space-8: 2rem; /* 32 */ --space-10: 2.5rem; /* 40 */ --space-12: 3rem; /* 48 */ --space-16: 4rem; /* 64 */ /* =========================================================== 5. RADII (generous = friendly) =========================================================== */ --radius-sm: 6px; --radius-md: 10px; --radius-lg: 14px; --radius-xl: 20px; --radius-2xl: 28px; --radius-full: 999px; /* =========================================================== 6. SHADOWS (warm-tinted, soft) =========================================================== */ --shadow-sm: 0 1px 2px rgba(45, 30, 20, 0.06); --shadow-md: 0 4px 14px rgba(45, 30, 20, 0.08); --shadow-lg: 0 12px 32px rgba(45, 30, 20, 0.12); --shadow-xl: 0 24px 60px rgba(45, 30, 20, 0.16); --shadow-focus: 0 0 0 4px var(--ring); /* =========================================================== 7. MOTION =========================================================== */ --ease-out: cubic-bezier(0.22, 1, 0.36, 1); /* @kind other */ --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* @kind other */ --dur-fast: 140ms; /* @kind other */ --dur-base: 220ms; /* @kind other */ --dur-slow: 360ms; /* @kind other */ } /* =========================================================== DARK THEME — warm espresso Apply via [data-theme="dark"] on or any container. =========================================================== */ [data-theme="dark"] { --bg: var(--sand-950); --bg-subtle: var(--sand-900); --surface: #221E19; --surface-2: #2A251F; --overlay: rgba(0, 0, 0, 0.6); --fg1: #F4EFE8; --fg2: #B6AC9C; --fg3: #897F6F; --fg-on-accent: #1F1C18; --accent: var(--clay-400); --accent-hover: var(--clay-300); --accent-press: var(--clay-500); --accent-subtle: rgba(204, 139, 92, 0.14); --accent-border: rgba(204, 139, 92, 0.30); --border: rgba(242, 238, 231, 0.10); --border-strong: rgba(242, 238, 231, 0.18); --ring: rgba(204, 139, 92, 0.45); --success: var(--green-400); --success-subtle: rgba(127, 176, 122, 0.16); --warning: var(--amber-400); --warning-subtle: rgba(226, 176, 90, 0.16); --danger: var(--red-400); --danger-subtle: rgba(212, 113, 90, 0.16); --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4); --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.45); --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.5); --shadow-xl: 0 24px 60px rgba(0, 0, 0, 0.55); } /* =========================================================== SEMANTIC TYPE CLASSES (use directly in markup) =========================================================== */ .t-display-xl { font-family: var(--font-display); font-size: var(--text-display-xl); font-weight: 700; line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); } .t-display { font-family: var(--font-display); font-size: var(--text-display); font-weight: 700; line-height: var(--leading-tight); letter-spacing: var(--tracking-tight); } .t-h1 { font-family: var(--font-display); font-size: var(--text-h1); font-weight: 600; line-height: var(--leading-snug); letter-spacing: var(--tracking-snug); } .t-h2 { font-family: var(--font-display); font-size: var(--text-h2); font-weight: 600; line-height: var(--leading-snug); letter-spacing: var(--tracking-snug); } .t-h3 { font-family: var(--font-sans); font-size: var(--text-h3); font-weight: 600; line-height: var(--leading-snug); } .t-body-lg { font-family: var(--font-sans); font-size: var(--text-body-lg); font-weight: 400; line-height: var(--leading-relaxed); } .t-body { font-family: var(--font-sans); font-size: var(--text-body); font-weight: 400; line-height: var(--leading-normal); } .t-sm { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 400; line-height: var(--leading-normal); } .t-caption { font-family: var(--font-sans); font-size: var(--text-caption); font-weight: 500; line-height: var(--leading-normal); } .t-overline { font-family: var(--font-sans); font-size: var(--text-caption); font-weight: 600; text-transform: uppercase; letter-spacing: var(--tracking-caps); } .t-mono { font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 400; font-feature-settings: 'tnum' 1; }