Files
pangolin/design/flutter

穿山甲 VPN — Flutter 设计令牌

生产前端使用 Flutter。本目录提供与 ../colors_and_type.css 一一对应的 Dart 令牌,Flutter 可直接消费。ui_kits/ 下的 React/HTML 是视觉规范参考(像素级还原 + 交互),Flutter 实现以它们为蓝本、以本文件为令牌来源。

快速开始

  1. 新建 Flutter 工程,把本目录的 pubspec.yaml 覆盖到根目录(按需改 name)。
  2. 拷贝:pangolin_theme.dartlib/;widgets/ 整个目录 → lib/widgets/;main.dartlib/;assets/*.svg → 工程 assets/
  3. 自备 4 款字体的 ttf 放 fonts/(或改用 google_fonts 包),族名须与 pubspec.yaml 一致。
  4. flutter pub getflutter runmain.dart 已串好「登录 → 引导 → 主框架」可直接跑。

文件

  • pubspec.yaml工程清单模板:已配好 flutter_svg / lucide_icons 依赖、4 个 SVG 资产、4 款字体声明(族名对齐 PangolinFonts)。拷到工程根目录,补字体 ttf,flutter pub get 即可。
  • main.dart入口示例:runApp + 明/暗主题 + 「登录 → 引导 → 主框架」RootFlow 串接,可直接跑通。
  • pangolin_theme.dart — 全部令牌 + 明/暗 ThemeData:
    • PangolinColors — clay / sand / 语义色阶(const Color)
    • PangolinSchemeThemeExtension)— 语义令牌(bg/surface/fg/accent/border/success…),含 .light / .dark
    • PangolinSpacing(4px 基准)、PangolinRadiusPangolinMotion(时长 + 缓动曲线)
    • PangolinFontsPangolinText(字号阶)、PangolinShadow(暖色软阴影)
    • PangolinTheme.light / PangolinTheme.dark — 开箱即用
  • widgets/核心组件 Dart 雏形(纯样式,业务逻辑自接),全部读 context.pangolin 令牌:
    • pangolin_icons.dartLucide 图标映射表:PangolinIcons.power 等直用常量 + PangolinIcons.byName('shield-check') 查表(从 React data-lucide 名移植)。需 lucide_icons 包。
    • pangolin_button.dartPangolinButton(primary / secondary / ghost / danger,胶囊形)
    • country_code.dartCountryCode(2 字母国家码块)、SignalBars(延迟信号条)
    • status_pill.dartStatusPill(连接态 / PRO 等色点胶囊)
    • connect_button.dartConnectButton(核心连接键三态:off 轨道环 / connecting 旋转弧 / on 满环 + 计时)
    • server_tile.dartServerTile + ServerInfo(服务器列表行)
    • plan_card.dartPlanCard(套餐卡,专业版渐变高亮 + 「最受欢迎」浮标)
    • auth_screen.dartAuthScreen(登录 / 邮箱验证码注册,分屏式,带 zh 简单 i18n)
    • onboarding_screen.dartOnboardingScreen(首次引导 PageView,3 屏可滑动 + 进度点 + 跳过)
    • home_shell.dartHomeShell(主框架:底部 4 Tab 连接/节点/统计/账户 + 连接状态机 + 计时;各页骨架)
    • account_screens.dart — 账户子页:PlansScreen(套餐选择)、DevicesScreen(设备管理 + 移除)、RedeemScreen(兑换码 + 购买渠道)、ContactScreen(联系渠道 + 服务时间);均为带返回栏的独立页,HomeShell 账户页已 push 接入
    • pangolin_logo.dartPangolinMark / PangolinBrandLockup / PangolinWordmark / PangolinAppIcon(flutter_svg 加载 assets/ 矢量 logo,深色自动反白)
    • pangolin_widgets.dart — 统一 export

    这些是视觉雏形:对应 React UI Kit 的同名组件,Flutter 工程师可直接拷贝/微调,接上真实状态与导航。图标已走 PangolinIcons(Lucide),与设计一致。

接入

MaterialApp(
  theme: PangolinTheme.light,
  darkTheme: PangolinTheme.dark,
  themeMode: ThemeMode.system, // 跟随系统;也可由设置里的开关控制
);

读语义色(随明暗自动切换):

final c = context.pangolin;          // PangolinScheme
Container(color: c.surface);
Text('已连接', style: PangolinText.h3.copyWith(color: c.success));

令牌直取:

PangolinColors.clay500            // 品牌主色
PangolinSpacing.x4                // 16
BorderRadius.circular(PangolinRadius.lg)
AnimatedContainer(duration: PangolinMotion.base, curve: PangolinMotion.easeOut, ...)

组件雏形(组合示例):

import 'widgets/pangolin_widgets.dart';

// 连接键
ConnectButton(status: VpnStatus.on, elapsed: const Duration(seconds: 8048), onTap: toggle);

// 服务器行
ServerTile(
  server: const ServerInfo(code: 'HK', name: '香港 · 流媒体', sub: 'Hong Kong', ping: 18),
  active: true, onTap: () {},
);

// 套餐卡(专业版高亮)
PlanCard(
  name: '专业版', price: '¥25', period: '/月', popularLabel: '最受欢迎', featured: true,
  features: const ['80+ 全球节点', '无限流量 · 极速', '5 台设备同时在线'],
  ctaLabel: '立即升级', onPressed: () {},
);

PangolinButton(label: '连接', icon: PangolinIcons.power, onPressed: () {});
StatusPill(label: '已连接', status: PangolinStatus.connected);

页面串接(登录 → 引导 → 主应用):

enum AppStage { auth, onboarding, app }

class _RootState extends State<Root> {
  AppStage stage = AppStage.auth;
  @override
  Widget build(BuildContext context) => switch (stage) {
    AppStage.auth       => AuthScreen(onDone: () => setState(() => stage = AppStage.onboarding)),
    AppStage.onboarding => OnboardingScreen(onDone: () => setState(() => stage = AppStage.app)),
    AppStage.app        => const HomeShell(), // 主框架:底部 4 Tab(连接/节点/统计/账户)
  };
}

字体

pubspec.yaml 注册 Sora(display)、Manrope(正文/UI)、Noto Sans SC(中文)、JetBrains Mono(数据)。可用 google_fonts 包或打包本地字体;族名见 PangolinFonts

图标

UI Kit 用 Lucide(细线条)。Flutter 侧用 lucide_icons 包,经 widgets/pangolin_icons.dart 的映射表引用:Icon(PangolinIcons.power)pubspec.yamllucide_icons: ^0.x。某常量名若在你的包版本缺失,按 IDE 提示替换为最接近名即可(文件内已注明 Lucide 原名)。

Logo / 品牌标(SVG)

矢量 logo 在 assets/(logo-mark.svg clay 标、logo-mark-white.svg 反白标、logo-wordmark.svg 字标、app-icon.svg App 图标)。用 flutter_svg 加载,封装在 widgets/pangolin_logo.dart:

  • PangolinMark(size: 28) — 仅标记,深色主题自动用反白版(可 forceLight/forceDark)
  • PangolinBrandLockup(zh: true) — 标记 + 「穿山甲 / Pangolin」(随主题变色 + 双语,顶栏用)
  • PangolinWordmark(height: 28) — 横版字标锁版(浅背景)
  • PangolinAppIcon(size: 64) — App 图标(自动圆角)

接入步骤:

  1. pubspec.yaml 加依赖与资产:
    dependencies:
      flutter_svg: ^2.0.0
    flutter:
      assets:
        - assets/logo-mark.svg
        - assets/logo-mark-white.svg
        - assets/logo-wordmark.svg
        - assets/app-icon.svg
    
  2. 把本目录的 assets/*.svg 拷进你工程的 assets/(若用别的前缀,改 pangolin_logo.dart 顶部的 _base)。
  3. AuthScreen / HomeShell 顶栏已用 PangolinMark / PangolinBrandLockup,无需再改。
  4. App 启动图标 / 桌面图标用 app-icon.svg 导出 PNG(flutter_launcher_icons 包)。

规则(务必遵守)

  • 颜色只用语义令牌,组件天然适配明/暗,不要硬编码十六进制。
  • 暖色基调:表面是暖白/暖 espresso,不要纯白纯黑大面积填充。
  • 圆角偏大、阴影柔和暖调;状态用「色点 + 文字」,不用 emoji;国家用 2 字母码块,不用 emoji 国旗。
  • 界面单语言显示(中文 EN),由设置切换;不要中英并排。
  • App 内不放支付表单;走兑换码 + 外部渠道。

⚠️ 字体均为开源字体(Google Fonts),作为本品牌正式选定字体。若你已有授权品牌字体,替换族名与文件即可。