/* =============================================================================
   链桥 ChainBridge —— 前端组件样式（硬规矩 A：drpc.org 风格）
   =============================================================================
   组织方式：
     ① RESET & BASE
     ② LAYOUT（容器 / 栅格 / 区块）
     ③ NAV（顶部导航 / 下拉 / 移动侧栏）
     ④ HERO 与营销组件（Logo 轮播 / 产品卡 / 链列表 / 证言 / 数字 / FAQ / CTA / 页脚）
     ⑤ 表单与按钮
     ⑥ 数据展示（表格 / 徽章 / 统计 / 进度 / 空态）
     ⑦ 反馈（Toast / Modal / 骨架屏 / 加载）
     ⑧ 工具页组件（安全中心 / 撤销工作台 / 控制台）
     ⑨ 工具类与响应式

   规则：所有色值只能引用 tokens.css 的变量，禁止硬编码十六进制色值
   （唯一例外：品牌链图标色，见 §⑧ 链色表）。
   ============================================================================= */

/* ============================ ① RESET & BASE ============================== */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; color-scheme: dark; }

/* 原生表单载体沿用站点色板；自绘弹层与窄屏内容限制在当前视口。 */
input, textarea, select { min-width: 0; max-width: 100%; font: inherit; }
input[type="checkbox"], input[type="radio"] {
  appearance: none; -webkit-appearance: none; display: inline-grid; place-content: center;
  width: 18px; height: 18px; flex: 0 0 18px; vertical-align: middle; margin: 0 6px 0 0;
  background: var(--inputBackgroundHex); border: 1px solid var(--inputBorderActive2); border-radius: var(--Radius-200);
}
input[type="radio"] { border-radius: 50%; }
input[type="checkbox"]:not(.cs-cbx):not(.cs-check input)::before { content: ''; width: 9px; height: 5px; border-left: 2px solid var(--textNegative); border-bottom: 2px solid var(--textNegative); transform: rotate(-45deg) scale(0); }
input[type="radio"]::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: var(--textNegative); transform: scale(0); }
input:is([type="checkbox"],[type="radio"]):checked { background: var(--primary); border-color: var(--primary); }
input:is([type="checkbox"],[type="radio"]):checked::before { transform: scale(1); }
input[type="checkbox"]:checked::before { transform: rotate(-45deg) scale(1); }
input[type="checkbox"]:indeterminate { background: var(--primary); border-color: var(--primary); }
input[type="checkbox"]:indeterminate::before { transform: scale(1); border-left: 0; height: 0; }
input:is([type="checkbox"],[type="radio"]):focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
input:is([type="checkbox"],[type="radio"]):disabled { opacity: .55; cursor: not-allowed; }
[data-cs-tooltip] { position: relative; }
/* 【为什么提示气泡是一个挂到 body 的独立元素，而不是伪元素】
   伪元素属于控件自己的盒子：它一旦超出按钮宽度，就会把 scrollWidth 撑大，
   整个页面出现横向滚动条（实测控制台导出按钮、自托管刷新按钮都因此溢出）。
   现在由 ui.js 创建一个 position:fixed 的单例气泡，坐标按视口夹紧，永远不参与布局。 */
.cs-tooltip {
  position: fixed; z-index: 1500;
  /* 260px 是「一句话能读完」的上限：再宽就变成一段需要来回扫的文字，
     而且会盖住相邻控件；窄视口下随视口收（两侧各留 12px）。 */
  max-width: min(260px, calc(100vw - 24px));
  padding: 8px 10px; border: 1px solid var(--borderSecondaryWhite);
  border-radius: var(--Radius-300);
  background: var(--backgroundSurface); color: var(--textPrimary);
  font-size: var(--Font-size-text-100); line-height: 1.5; text-align: left;
  white-space: normal; overflow-wrap: anywhere; pointer-events: none;
  box-shadow: var(--boxShadow);
}
.cs-tooltip[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   禁用控件的「可见原因」（G-18 / 规范 §4：禁用必须能解释）
   ---------------------------------------------------------------------------
   机制放在 ui.js：页面只写 `data-disabled-reason="中文原因"`，脚本负责
   ① 转成站内 tooltip（悬停/聚焦可看）；② 补 aria-describedby 给读屏；
   ③ 触屏点不动原生提示，所以同时支持把原因排成一行小字（`.cs-disabled-reason`）。
   样式侧只保证：禁用态光标统一、原因小字与表单提示同字号（12px）。
   ------------------------------------------------------------------------- */
[disabled], [aria-disabled="true"], .is-disabled { cursor: not-allowed; }
.cs-disabled-reason {
  display: flex; align-items: flex-start; gap: 6px;
  margin-top: 8px; max-width: 62ch;
  font-size: var(--Font-size-text-100); line-height: 1.55; color: var(--textSecondary);
}
.cs-disabled-reason::before {
  content: ''; flex: none; width: 5px; height: 5px; margin-top: 7px;
  border-radius: 50%; background: var(--textSecondary);
}

/* 只给读屏的说明（aria-describedby 指向这里），不占布局、不撑宽页面 */
.cs-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
.cs-selectbox { min-width: 0; max-width: 100%; }
.cs-selectbox__trigger[aria-invalid="true"] { border-color: var(--coral); }
.cs-selectbox__label { overflow-wrap: anywhere; }
.cs-modal { max-width: calc(100vw - 32px); max-height: calc(100dvh - 32px); overflow: auto; }
@media (max-width: 480px) {
  .cs-modal__ft { flex-wrap: wrap; }
  .cs-modal__ft .cs-btn { flex: 1 1 120px; }
  .cs-card, .cs-card__bd, .cs-main, .cs-console-main { min-width: 0; }
  pre { max-width: 100%; overflow-x: auto; }
}

body {
  margin: 0;
  background: var(--background);
  color: var(--textPrimary);
  font-family: var(--font-sans);
  font-size: var(--Font-size-text-300);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: 0;
}

p { margin: 0; }
a { color: inherit; text-decoration: none; }
a:hover { color: var(--primary); }
img, svg { max-width: 100%; display: block; }
button {
  font-family: inherit;
  color: inherit;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  -webkit-appearance: none;
  appearance: none;
}
code, pre, kbd { font-family: var(--font-mono); }

:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--cs-radius-sm);
}

::selection { background: var(--primaryTransparent); color: var(--textPrimary); }

/* 滚动条只在这里定义一次（另一处早先的 10px「深色轨」写法已删 — 见 G-11：
   两套语义互相覆盖，改哪一套都不生效，还让小容器的滚动条变得几乎点不到）。 */

@media print {
  .cs-nav, .cs-footer, .cs-toast-host, .cs-btn { display: none !important; }
  body { background: #fff; color: #000; }
}

/* ============================== ② LAYOUT ================================= */
.cs-container {
  width: 100%;
  max-width: var(--landing-max-width);
  margin: 0 auto;
  padding: 0 24px;
}
.cs-container--narrow { max-width: var(--landing-page-content-max-width); }
.cs-container--wide { max-width: var(--inner-landing-max-width); }

/* 【为什么只写上下】`.cs-container` 与 `.cs-section` 经常同时挂在同一个元素上
   （例如 8 个安全页面：`<div class="cs-container cs-section cs-section--tight">`）。
   如果这里用 `padding: 96px 0` 这种简写，会连同左右一起清成 0，把容器的 24px
   内边距覆盖掉，页面在桌面端就会贴屏幕边缘。只声明上下方向即可与容器共存。 */
.cs-section { padding-top: var(--cs-section-y); padding-bottom: var(--cs-section-y); }
.cs-section--tight { padding-top: 56px; padding-bottom: 56px; }
.cs-section--alt { background: var(--backgroundLandingDark); }
.cs-section--tertiary { background: var(--backgroundTertiary); }

.cs-section-head { margin-bottom: 40px; max-width: 760px; }
.cs-section-head--center { margin-left: auto; margin-right: auto; text-align: center; }
/* 居中标题区：副标题均衡换行，避免最后一行只剩一两个字 */
.cs-section-head--center > p { text-wrap: balance; margin-left: auto; margin-right: auto; }

.cs-eyebrow {
  display: inline-block;
  font-size: var(--Font-size-text-100);
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 12px;
}

/* 大标题用 Space Grotesk 时默认字距偏松，视觉上像「撑开」；drpc 的标题是收紧的。
   小屏用 40px 起，大屏最多 68px，避免 1280 下 58px 显得不够有分量、1080 下又挤爆两行。 */
/* drpc 的 H1 是 700，我们原来 500：56px 的标题会发虚，像没加载完字重。
   Space Grotesk 变量字体覆盖 400–600，取 600（再用 700 会掉进合成加粗）。 */
/* 【G-13】H1 只有这一处定义字号：`.cs-hero h1` 与单独使用的 `.cs-h1` 必须是同一档。
   原来 157 行（32px 起）与 497 行（36px 起）各写一条，390px 下同一站点的「大标题」
   相差 4px。现在统一以规范 §2.8 的移动端 36px 为下限，`.cs-hero h1` 只负责字重与行高。 */
.cs-hero h1, .cs-h1 {
  font-size: clamp(var(--Font-size-header-400), 5.2vw, 68px);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.cs-h2 { font-size: var(--Font-size-header-400); font-weight: 600; line-height: 1.15; }

/* 导流条（对标 drpc 的 Need Help Choosing）：一段说明 + 两个去处 */
.cs-choose {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 32px; align-items: center;
  padding: 32px; border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundTertiary);
}
.cs-choose__text .cs-h2 { margin-top: 10px; }
.cs-choose__text .cs-lead { margin-top: 12px; max-width: 62ch; }
.cs-choose__actions { display: flex; flex-direction: column; gap: 10px; }
.cs-choose__actions .cs-btn { white-space: nowrap; }
@media (max-width: 860px) {
  .cs-choose { grid-template-columns: minmax(0, 1fr); gap: 20px; padding: 24px; }
  .cs-choose__actions { flex-direction: row; flex-wrap: wrap; }
}
.cs-h3 { font-size: var(--Font-size-header-200); line-height: 1.25; }
.cs-h4 { font-size: var(--Font-size-header-100); line-height: 1.3; }

.cs-lead {
  font-size: var(--Font-size-text-400);
  color: var(--textSecondary);
  margin-top: 16px;
  max-width: 62ch;            /* 一行别超过 62 字符，超过就开始丢行 */
  text-wrap: pretty;          /* 避免末行只剩一两个字 */
  line-height: 1.65;
}
.cs-muted { color: var(--textSecondary); }
.cs-small { font-size: var(--Font-size-text-200); }
.cs-hidden { display: none !important; }

/* 【G-14】长文正文限宽：法务条款、隐私授权说明这类页面用的是 1280px 容器，
   16px 正文在 1280 下一行能塞 100+ 汉字，回行必然串行。规范 §3.5 要求 ≤72 字符，
   这里给出通用容器类：正文区块加 `.cs-prose` 即可（页面只加类，不改结构）。 */
.cs-prose { max-width: 72ch; }
.cs-prose p, .cs-prose li { max-width: 72ch; line-height: 1.75; }
.cs-prose > * + * { margin-top: 14px; }

.cs-grid > * { min-width: 0; }
.cs-grid { display: grid; gap: var(--cs-gap); }
.cs-grid--2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.cs-grid--3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.cs-grid--4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
/* 数量不固定的指标行（例如网络目录的 5 个统计）：按可用宽度自动排，
   避免「3 列放 5 项」时第二行只剩两个、右侧空一大块。 */
.cs-grid--auto { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

.cs-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
/* 按钮不能被同一行的长标题压扁：压到比文字还窄时它会溢出到视口外（实测 1280 宽度溢出 25px）。
   保持自身宽度，放不下就让整行换行。 */
.cs-row > .cs-btn { flex: 0 0 auto; min-width: max-content; }
.cs-row--between { justify-content: space-between; }
.cs-col { display: flex; flex-direction: column; gap: 12px; }

.cs-appbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin: 12px 0 20px;
}
.cs-appbar h1 { font-size: var(--Font-size-header-100); line-height: 1.25; }
.cs-appbar__actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
@media (max-width: 620px) {
  .cs-appbar { align-items: flex-start; flex-direction: column; gap: 12px; }
  .cs-appbar__actions { width: 100%; justify-content: flex-start; }
  .cs-appbar__actions > .cs-btn { flex: 1 1 auto; justify-content: center; }
}

/* =============================== ③ NAV =================================== */
.cs-nav {
  position: sticky;
  top: 0;
  z-index: 60;
  height: var(--landing-header-height-desktop);
  background: rgba(15,15,15,.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color .2s ease, background .2s ease;
}
.cs-nav.is-scrolled { border-bottom-color: var(--divider); background: rgba(15,15,15,.94); }

.cs-nav__inner {
  height: 100%;
  display: flex;
  align-items: center;
  gap: 32px;
}

.cs-logo { display: flex; align-items: center; gap: 10px; font-family: var(--font-display); font-size: var(--Font-size-text-400); font-weight: 600; }
.cs-logo__mark {
  width: 30px; height: 30px; border-radius: var(--Radius-300);
  background: var(--primaryTransparent);
  border: 1px solid var(--primary);
  display: grid; place-items: center;
  color: var(--primary);
}
.cs-logo__mark svg { width: 17px; height: 17px; }
.cs-logo__mark img { width: 23px; height: 23px; display: block; }
.cs-logo__text small { display: block; font-family: var(--font-sans); font-size: var(--Font-size-text-50); letter-spacing: 0; color: var(--textSecondary); text-transform: uppercase; }

.cs-nav__links { display: flex; align-items: center; gap: 4px; margin-left: 8px; }

.cs-navlink {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 12px;
  border-radius: var(--Radius-300);
  font-size: var(--Font-size-text-200);
  color: var(--textPrimaryMuted);
  background: transparent; border: 0; cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.cs-navlink:hover, .cs-navlink[aria-expanded="true"] { background: var(--white08); color: var(--textPrimary); }
.cs-navlink.is-active { color: var(--textPrimary); }
.cs-navlink__caret { width: 12px; height: 12px; transition: transform .2s ease; }
.cs-navlink[aria-expanded="true"] .cs-navlink__caret { transform: rotate(180deg); }

.cs-nav__right { margin-left: auto; display: flex; align-items: center; gap: 10px; }

.cs-icon-btn {
  width: 36px; height: 36px; display: inline-grid; place-items: center; flex: none;
  border: 1px solid var(--border); border-radius: var(--Radius-300);
  background: transparent; color: var(--textPrimaryMuted); cursor: pointer;
}
.cs-icon-btn:hover, .cs-icon-btn:focus-visible { color: var(--textPrimary); border-color: var(--primary); outline: none; }
.cs-locale { position: relative; display: inline-flex; flex: none; }
.cs-locale__menu { right: 0; left: auto; min-width: 168px; }
.cs-locale__option {
  width: 100%; min-height: 40px; padding: 8px 10px; display: flex; align-items: center;
  justify-content: space-between; gap: 12px; border: 0; border-radius: var(--Radius-300);
  color: var(--textPrimaryMuted); background: transparent; text-align: left; cursor: pointer;
}
.cs-locale__option:hover, .cs-locale__option:focus-visible, .cs-locale__option[aria-checked="true"] {
  color: var(--textPrimary); background: var(--white08); outline: none;
}
.cs-locale__option[aria-checked="true"] svg { color: var(--primary); }

.cs-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  min-width: 300px;
  background: var(--dropdownBackground);
  border: 1px solid var(--dropdownBorder);
  border-radius: var(--Radius-400);
  box-shadow: var(--boxShadow);
  padding: 8px;
  display: none;
  z-index: 70;
}
.cs-dropdown.is-open { display: block; }
.cs-dropdown__item {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 10px 12px; border-radius: var(--Radius-300);
  color: var(--textPrimaryMuted);
}
.cs-dropdown__item:hover { background: var(--selectItemActiveBackground); color: var(--textPrimary); }
.cs-dropdown__item strong { display: block; font-size: var(--Font-size-text-200); color: var(--textPrimary); font-weight: 500; }
.cs-dropdown__item span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }
.cs-dropdown__item svg { width: 18px; height: 18px; color: var(--primary); flex: none; margin-top: 2px; }
.cs-dropdown__sep { height: 1px; background: var(--divider); margin: 6px 4px; }

.cs-hamburger { display: none; background: transparent; border: 1px solid var(--border); border-radius: var(--Radius-300); width: 38px; height: 38px; color: var(--textPrimary); cursor: pointer; }

.cs-mobile-menu {
  position: fixed; inset: 0; z-index: 90;
  /* 原来写的是 var(--backgroundMobileSideMenu)，这个变量从来没定义过 → 整层透明，
     背后的 Hero 光晕会透上来，菜单看着像蒙了层雾。这里直接用 tokens 实色。 */
  background: var(--backgroundSecondary);   /* G-16：原变量 --backgroundMobileSideMenu 从未定义 */
  padding: 20px 20px 40px;
  overflow-y: auto;
  display: none;
}
.cs-mobile-menu.is-open { display: block; }
.cs-mobile-menu__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 24px; }
/* 下面那条 a/button 100% 宽也作用到了关闭按钮，把 logo 挤到只剩一个字宽、'链桥'竖着断成两行 */
.cs-mobile-menu__head > * { width: auto; }
.cs-mobile-menu__head .cs-logo__text { white-space: nowrap; }
.cs-mobile-menu__head .cs-modal__close { width: 40px; height: 40px; padding: 0; display: inline-grid; place-items: center; border: 0; flex: none; }
.cs-mobile-menu a, .cs-mobile-menu button {
  display: block; width: 100%; text-align: left;
  padding: 14px 4px; border: 0; background: transparent;
  border-bottom: 1px solid var(--divider);
  color: var(--textPrimaryMuted); font-size: var(--Font-size-text-300); cursor: pointer;
}
.cs-mobile-menu a:hover { color: var(--primary); }

@media (max-width: 900px) {
  .cs-nav { height: var(--landing-header-height-mobile); }
  .cs-nav__inner { gap: 12px; }
  .cs-nav__links { display: none; }
  .cs-nav__right { gap: 8px; }
  .cs-nav__right .cs-icon-btn,
  .cs-hamburger { width: 44px; height: 44px; }
  .cs-hamburger { display: inline-grid; place-items: center; flex: none; }
  .cs-nav__right .cs-btn { min-height: 44px; }
}
@media (max-width: 560px) {
  /* 390 下「用户中心 + 地球 + 汉堡」挤成三连块：只收起按钮上的**文字**，
     入口本身要留着 —— 顶部只剩汉堡时，用户找不到登录也切不了语言。
     文字用 .cs-sr-only 隐藏但仍给读屏；按钮缩成图标胶囊。 */
  .cs-nav__right > .cs-btn { padding: 0 10px; min-width: 40px; justify-content: center; }
  .cs-nav__right > .cs-btn .cs-nav__btn-label { position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
  .cs-nav__right > .cs-locale { display: inline-flex; }
}

/* ============================ ④ HERO / 营销 ============================== */
.cs-hero { padding: 120px 0 72px; position: relative; overflow: hidden; }
/* Hero 两栏：左侧文案 + 右侧「为什么可以放心用」承诺卡。
   1280 下右侧原本是 400px 的空洞，首屏显得左重右轻；卡片用真实承诺填满，
   不放任何演示数据。窄屏（<1080）退回单栏并隐藏卡片，避免挤压标题。 */
.cs-hero__inner { position: relative; max-width: 860px; }
.cs-hero__inner--split {
  max-width: none;
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(320px, .9fr);
  gap: 56px; align-items: center;
}
.cs-hero__copy { min-width: 0; max-width: 760px; }
.cs-flow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 20px minmax(0, 1.1fr) 20px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--Radius-400);
  background: var(--backgroundTertiary);
}
.cs-flow__col { display: flex; flex-direction: column; align-items: stretch; gap: 8px; min-width: 0; }
.cs-flow__col--center { align-items: center; text-align: center; }
.cs-flow__tag {
  display: block;
  padding: 7px 8px;
  border: 1px solid var(--borderSecondary);
  border-radius: var(--Radius-200);
  background: var(--backgroundSecondary);
  color: var(--textPrimaryMuted);
  font-size: var(--Font-size-text-100);
  line-height: 1.35;
  text-align: center;
  overflow-wrap: anywhere;
}
.cs-flow__arrow { color: var(--primary); font-size: var(--Font-size-text-500); line-height: 1; text-align: center; }
.cs-flow__node {
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 40px;
  padding: 8px;
  border: 1px solid var(--primaryLight);
  border-radius: var(--Radius-300);
  background: var(--primary08);
  color: var(--primary);
  font-size: var(--Font-size-text-200);
  font-weight: 600;
}
.cs-flow__hint { color: var(--textSecondary); font-size: var(--Font-size-text-100); line-height: 1.45; }
/* ---- 两种接入：两张可点的小卡 + 一条自助入口 ----
   之前是「01/02 数字牌 + 两段长文」的说明列表：数字和内容没有关系，
   正文两行以上，看完也不知道该点哪里。现在每一项自己是一张卡：
   图标说明是哪个产品，正文只留一句，具体校验项收进标签，整块可点。 */
.cs-promise {
  border: 1px solid var(--border);
  border-radius: var(--Radius-500);
  background: var(--backgroundSecondary);
  padding: 20px;
  box-shadow: var(--boxShadow);
}
.cs-promise__hd {
  display: flex; align-items: center; gap: 8px;
  font-size: var(--Font-size-text-200); color: var(--textSecondary);
  margin-bottom: 14px;
}
/* 头部圆点加一圈淡光：它是这张卡唯一的装饰色，也传达「可用」的意思 */
.cs-promise__dot {
  width: 6px; height: 6px; border-radius: 50%; background: var(--primary); flex: none;
  box-shadow: 0 0 0 3px var(--primary08);
}
.cs-promise__list { display: grid; gap: 10px; }
.cs-promise__item {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) 16px; gap: 12px;
  align-items: start; padding: 12px;
  border: 1px solid var(--borderSecondary); border-radius: var(--Radius-400);
  background: var(--white04);
  color: inherit; text-decoration: none;
  transition: background-color 160ms ease, border-color 160ms ease;
}
.cs-promise__item:hover { background: var(--white05); border-color: var(--primaryLight); }
.cs-promise__item:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.cs-promise__icon {
  display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 10px; background: var(--primary08); color: var(--primary);
  box-shadow: inset 0 0 0 1px var(--primaryLight);
}
.cs-promise__icon svg { width: 18px; height: 18px; }
.cs-promise__body { min-width: 0; }
.cs-promise__body b {
  display: block; font-size: var(--Font-size-text-300); font-weight: 500;
  color: var(--textPrimary); margin-bottom: 4px;
}
.cs-promise__desc {
  display: block; font-size: var(--Font-size-text-200); line-height: 1.65;
  color: var(--textSecondary); overflow-wrap: anywhere;
  /* 中文按字换行，默认会把「有效期」拆成「有 / 效期」这种断词；pretty 会尽量避免孤字。 */
  text-wrap: pretty;
}
/* 技术标签：把 SIWE/SIWX、EVM/Solana 这类词从正文里挪出来，
   正文读起来是一句人话，想核对能力的人也能一眼看到关键词。 */
.cs-promise__meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.cs-promise__meta em {
  font-style: normal; padding: 1px 6px; border-radius: 4px;
  background: var(--white05); color: var(--textSecondaryBright);
  font-family: var(--font-display); font-size: var(--Font-size-text-100);
  letter-spacing: .02em;
}
.cs-promise__arrow {
  display: grid; place-items: center; align-self: center;
  color: var(--textSecondary); transition: color 160ms ease, transform 160ms ease;
}
.cs-promise__arrow svg { width: 16px; height: 16px; }
.cs-promise__item:hover .cs-promise__arrow { color: var(--primary); transform: translateX(2px); }
/* 底部自助入口：原来是一句纯说明，现在给「暂时不想接入」的人一条真实去路 */
.cs-promise__foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--divider);
  font-size: var(--Font-size-text-100); line-height: 1.6; color: var(--textSecondary);
  text-decoration: none; transition: color 160ms ease;
}
.cs-promise__foot:hover { color: var(--primary); }
.cs-promise__foot:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }
.cs-promise__foot-arrow { display: grid; place-items: center; flex: none; color: inherit; }
.cs-promise__foot-arrow svg { width: 14px; height: 14px; }
@media (max-width: 1080px) {
  .cs-hero__inner--split { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  .cs-hero__aside { display: none; }
}
.cs-hero::before {
  content: ""; position: absolute; inset: -40% 20% auto -10%;
  height: 620px; pointer-events: none;
  background: radial-gradient(closest-side, var(--primary08), transparent 70%);
}
/* 字号由上面的 `.cs-hero h1, .cs-h1` 统一给出（G-13），这里只补 Hero 独有的排布 */
.cs-hero h1 {
  font-weight: 600;   /* 与 drpc 的 700 对齐观感；变量字体只到 600，再往上会触发合成加粗 */
  line-height: 1.04;
  letter-spacing: -0.025em;
  margin-bottom: 20px;
  text-wrap: balance;
}
/* 两栏时左列只有约 550–650px：标题必须跟着视口收一点，否则「安全撤销」会掉成第三行 */
.cs-hero__inner--split h1 { font-size: clamp(40px, 4.4vw, 60px); letter-spacing: -0.02em; text-wrap: balance; }
.cs-hero__grad {
  background: linear-gradient(90deg, var(--primary), var(--blueMarketing));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.cs-hero__sub { font-size: var(--Font-size-text-400); color: var(--textSecondary); max-width: 62ch; line-height: 1.65; text-wrap: pretty; }

/* 内页 Hero 居中：内页文案比首页短，1280 下左对齐会留下约 400px 的空洞。
   居中后两侧留白对称，也自然对齐下方居中的 FAQ / CTA 区块。首页保持左对齐 + 承诺卡。 */
.cs-hero--center { text-align: center; padding-bottom: 48px; }
.cs-hero--center .cs-hero__inner { max-width: 900px; margin-left: auto; margin-right: auto; }
.cs-hero--center .cs-hero__sub { margin-left: auto; margin-right: auto; }
.cs-hero--center .cs-hero__cta { justify-content: center; }
.cs-hero--center .cs-pill { margin-left: auto; margin-right: auto; }
.cs-hero--center h1 { text-wrap: balance; }

/* 窄屏没有右侧承诺卡：用一行标签把三条承诺补回来（桌面端隐藏，避免与卡片重复） */
.cs-hero__notes { display: grid; gap: 8px; max-width: 720px; margin-top: 24px; }
.cs-hero__notes p { margin: 0; }
.cs-hero__parity { font-size: var(--Font-size-text-100); line-height: 1.65; max-width: 64ch; opacity: .82; margin-top: 14px; }
.cs-hero__promise-inline { display: none; margin: 20px 0 0; font-size: var(--Font-size-text-200); line-height: 1.7; color: var(--textSecondary); }
@media (max-width: 1080px) {
  .cs-hero__promise-inline { display: block; }
}
/* Hero 里的第三颗「幽灵按钮」原来只有文字、没有边框，摆在两颗实心按钮旁边
   像是漏样式的一行链接。给它一个描边，层级变成 实心 / 描边 / 描边。 */
.cs-hero__cta .cs-btn--ghost { border: 1px solid var(--border); }
.cs-hero__cta .cs-btn--ghost:hover { border-color: var(--primary); }

.cs-hero__cta { display: flex; gap: 12px; margin-top: 32px; flex-wrap: wrap; }

.cs-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px 6px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--white04);
  font-size: var(--Font-size-text-100);
  color: var(--textPrimaryMuted);
  margin-bottom: 24px;
}
.cs-pill b { color: var(--primary); font-weight: 500; }
.cs-pill__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--primary); flex: none; }
/* 英文标签比中文长，窄屏会把 "Network coverage" 从中间折断成两行。
   让标签整体换行、每段内部不折，读起来是两块而不是碎词。 */
.cs-pill { flex-wrap: wrap; row-gap: 2px; max-width: 100%; }
.cs-pill b, .cs-pill > span:not(.cs-pill__dot) { white-space: nowrap; }
@media (max-width: 560px) {
  .cs-pill { padding: 8px 12px; font-size: var(--Font-size-text-50); gap: 6px; }
}

.cs-logos { border-top: 1px solid var(--divider); border-bottom: 1px solid var(--divider); padding: 28px 0; overflow: hidden; }
.cs-logos__track { display: flex; gap: 56px; align-items: center; animation: cs-marquee 42s linear infinite; width: max-content; }
.cs-logos__item { font-family: var(--font-display); font-size: var(--Font-size-text-400); color: var(--textSecondary); opacity: .55; white-space: nowrap; }
.cs-logos__item:hover { opacity: 1; color: var(--textPrimaryMuted); }
@keyframes cs-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

@media (prefers-reduced-motion: reduce) {
  .cs-logos__track { animation: none; }
}

.cs-card {
  background: var(--backgroundSecondary);
  border: 1px solid var(--border);
  border-radius: var(--Radius-500);
  padding: 24px;
}
.cs-card--dark { background: var(--backgroundLandingDark); }
.cs-card--flat { background: var(--backgroundTertiary); }
.cs-card--link { transition: border-color .2s ease, transform .2s ease; display: block; }
.cs-card--link:hover { border-color: var(--borderSecondaryWhite); transform: translateY(-2px); color: inherit; }
.cs-card__icon {
  width: 40px; height: 40px; border-radius: var(--Radius-300);
  background: var(--primaryTransparent); color: var(--primary);
  display: grid; place-items: center; margin-bottom: 16px;
}
.cs-card__icon svg { width: 20px; height: 20px; }
.cs-card h3 { font-size: var(--Font-size-header-100); margin-bottom: 10px; }
.cs-card p { color: var(--textSecondary); font-size: var(--Font-size-text-200); }
.cs-card__tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.cs-card__foot { margin-top: 20px; display: flex; align-items: center; justify-content: space-between; }
/* 服务卡片：品牌名放在标题上方（不在 h3 里混排），底部动作贴底对齐 */
.cs-card__kicker { display: block; font-size: var(--Font-size-text-100); color: var(--textSecondary); letter-spacing: 0; margin-bottom: 4px; }
.cs-card--service { display: flex; flex-direction: column; }
.cs-card--service .cs-card__foot { margin-top: auto; padding-top: 20px; }

/* 卡片底部的行动文字（审计 P-04）：此前用行内 style 染绿、没有 hover，
   同一意图在 pricing 里又用了一个未定义的 .cs-link。统一成一处定义。 */
.cs-card__cta { display: inline-flex; align-items: center; gap: 4px; font-size: var(--Font-size-text-100); color: var(--primary); font-weight: 500; }
.cs-card__cta-arrow { transition: transform .18s cubic-bezier(0.16, 1, 0.3, 1); }
.cs-card--link:hover .cs-card__cta-arrow,
.cs-card:hover .cs-card__cta-arrow { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) { .cs-card__cta-arrow { transition: none; } }

/* 正文内链接：两页各抄一份后收编到这里，underline 偏移保证不贴字底 */
.cs-link { color: var(--primary); text-decoration: underline; text-underline-offset: 3px; }
.cs-link:hover { text-decoration-thickness: 2px; }

/* 一组小特性放在卡片下面时，用一条分隔线明确层级 */
.cs-feature-row { margin-top: 32px; padding-top: 28px; border-top: 1px solid var(--divider); }

.cs-feature { display: flex; gap: 14px; align-items: flex-start; }
/* 三列之间用细竖线分开：没有线时三块文字像三个孤立段落 */
@media (min-width: 900px) {
  .cs-feature + .cs-feature { border-left: 1px solid var(--divider); padding-left: var(--cs-gap); margin-left: calc(var(--cs-gap) * -1); }
}
.cs-feature svg { width: 20px; height: 20px; color: var(--primary); flex: none; margin-top: 2px; }
.cs-feature strong { display: block; font-weight: 500; }
.cs-feature span { color: var(--textSecondary); font-size: var(--Font-size-text-200); }

/* 等宽网格：flex-wrap 会让最后一行只剩两三个，右边一大片空白 */
.cs-chainlist {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 10px;
}
/* 宽屏固定 6 列：首页只展示 12 条，6×2 正好铺满，auto-fill 会排出 7+5 的断行 */
@media (min-width: 1024px) { .cs-chainlist { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.cs-chainchip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--white04);
  font-size: var(--Font-size-text-200); color: var(--textPrimaryMuted);
}
.cs-chainchip:hover { border-color: var(--primary); color: var(--textPrimary); }
.cs-chainchip__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--textSecondary); }
.cs-chainchip.is-active .cs-chainchip__dot { background: var(--primary); }

.cs-quote {
  background: var(--landingReviewsPrimary);
  border: 1px solid var(--border);
  border-radius: var(--Radius-500);
  padding: 28px;
  display: flex; flex-direction: column; gap: 20px;
}
.cs-quote__text { font-size: var(--Font-size-text-400); color: var(--textPrimaryMuted); }
.cs-quote__by { display: flex; align-items: center; gap: 12px; }
.cs-quote__avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--backgroundSurface); display: grid; place-items: center; font-family: var(--font-display); color: var(--primary); }
.cs-quote__by strong { display: block; font-size: var(--Font-size-text-200); font-weight: 500; }
.cs-quote__by span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }

.cs-stat { text-align: left; }
.cs-stat__num { font-family: var(--font-display); font-size: var(--Font-size-header-500); line-height: 1; color: var(--primary); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.cs-stat__label { color: var(--textSecondary); font-size: var(--Font-size-text-200); margin-top: 8px; }

.cs-faq { max-width: var(--landing-page-content-max-width); margin: 0 auto; }
.cs-faq__group { margin-top: 48px; }
.cs-faq__group h3 { font-size: var(--Font-size-header-100); margin-bottom: 8px; }
.cs-faq__item { border-bottom: 1px solid var(--divider); }
.cs-faq__item:last-child { border-bottom: 0; }
.cs-faq__q {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 20px 0; background: transparent; border: 0; cursor: pointer;
  color: var(--textPrimary); font-size: var(--Font-size-text-400); text-align: left;
  font-family: var(--font-sans);
}
.cs-faq__q:hover { color: var(--primary); }
.cs-faq__sign { flex: none; width: 20px; height: 20px; position: relative; }
.cs-faq__sign::before, .cs-faq__sign::after {
  content: ""; position: absolute; background: currentColor; border-radius: 2px;
  transition: transform .2s ease, opacity .2s ease;
}
.cs-faq__sign::before { left: 0; right: 0; top: 9px; height: 2px; }
.cs-faq__sign::after { top: 0; bottom: 0; left: 9px; width: 2px; }
.cs-faq__item.is-open .cs-faq__sign::after { transform: scaleY(0); opacity: 0; }
.cs-faq__a { max-height: 0; overflow: hidden; transition: max-height .22s ease; }
/* 12 个问题单列排下来接近 1500px，滚到一半就没人看了；宽屏分两列 */
@media (min-width: 1024px) {
  .cs-faq { display: grid; grid-template-columns: 1fr 1fr; gap: 0 64px; align-items: start; }
  /* 同一行的两个问题标题行数经常不同（左边两行、右边一行）。.cs-faq__q 默认
     align-items: center，+ 会跟着整块标题居中，右边那个 + 就比左边的高出半行
     （实测 10.5px），同一行看着像没对齐。把 + 锚定到标题首行，两列同行的符号
     就落在同一条水平线上。首页的分组 FAQ（.cs-faq > .cs-faq__group 里的 item）
     是每组单列堆叠，没有这条对齐要求，因此只匹配直接子项。 */
  .cs-faq > .cs-faq__item > .cs-faq__q { align-items: flex-start; }
}
.cs-faq__item.is-open .cs-faq__a { max-height: 720px; }
.cs-faq__a p { padding: 0 0 22px; color: var(--textSecondary); font-size: var(--Font-size-text-300); max-width: 900px; }

.cs-cta {
  border: 1px solid var(--border);
  border-radius: var(--Radius-500);
  background: var(--backgroundLandingDark);
  padding: 56px 32px;
  text-align: center;
}
.cs-cta h2 { font-size: var(--Font-size-header-400); margin-bottom: 14px; }
.cs-cta p { color: var(--textSecondary); margin-bottom: 26px; }
.cs-cta__row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

.cs-footer { border-top: 1px solid var(--divider); padding: 64px 0 40px; background: var(--backgroundTertiary); }
.cs-footer__grid { display: grid; grid-template-columns: 1.4fr repeat(4, minmax(0,1fr)); gap: 32px; }
.cs-footer h4 { font-size: var(--Font-size-text-100); letter-spacing: 0; text-transform: uppercase; color: var(--textSecondary); margin-bottom: 16px; font-family: var(--font-sans); }
.cs-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.cs-footer a { color: var(--textPrimaryMuted); font-size: var(--Font-size-text-200); }
.cs-footer a:hover { color: var(--primary); }
.cs-footer__bottom { margin-top: 48px; padding-top: 24px; border-top: 1px solid var(--divider); display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; color: var(--textSecondary); font-size: var(--Font-size-text-100); }
@media (max-width: 768px) {
  .cs-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 20px; }
  .cs-footer__grid > :first-child { grid-column: 1 / -1; }
  .cs-footer__bottom { margin-top: 32px; padding-top: 20px; }
}
@media (max-width: 390px) {
  .cs-footer { padding-top: 48px; }
  .cs-footer__grid { gap: 24px 16px; }
  .cs-footer__bottom { gap: 12px; }
}

/* ========================= ⑤ 按钮与表单 ================================== */
.cs-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 40px; padding: 0 18px;
  border-radius: var(--Radius-300);
  border: 1px solid transparent;
  font-size: var(--Font-size-text-200); font-weight: 500;
  cursor: pointer; white-space: nowrap;
  transition: background .15s ease, border-color .15s ease, color .15s ease, opacity .15s ease;
}
.cs-btn svg { width: 16px; height: 16px; }
.cs-btn:disabled, .cs-btn[aria-disabled="true"] { cursor: not-allowed; }

.cs-btn--primary { background: var(--primary); color: var(--Content-primary_button_text); }
.cs-btn--primary:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--primaryHover); color: var(--Content-primary_button_text); }
.cs-btn--primary:active:not(:disabled):not([aria-disabled="true"]) { background: var(--primaryPressed); color: var(--Content-primary_button_text); }
/* 禁用态文字用 textSecondary 而不是 Content-text_disabled：#575656 压在 #272728 上
   对比度不到 2:1，用户看不清按钮说的是什么（尤其在「撤销选中的 0 条」这种带数量的文案上）。 */
.cs-btn--primary:disabled, .cs-btn--primary[aria-disabled="true"] { background: var(--primaryDisabled); color: var(--textSecondary); }

.cs-btn--secondary { background: var(--buttonBgSecondary); color: var(--textPrimary); border-color: var(--border); }
.cs-btn--secondary:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--buttonBgSecondaryHover); border-color: var(--borderSecondaryWhite); color: var(--textPrimary); }
.cs-btn--secondary:active:not(:disabled):not([aria-disabled="true"]) { background: var(--backgroundSurface); color: var(--textPrimary); }
.cs-btn--secondary:disabled, .cs-btn--secondary[aria-disabled="true"] { color: var(--Content-text_disabled); }

.cs-btn--ghost { background: transparent; color: var(--textSecondary); }
.cs-btn--ghost:hover:not(:disabled):not([aria-disabled="true"]) { color: var(--textPrimary); background: var(--white08); }

.cs-btn--danger { background: var(--errorTertiary); border-color: var(--errorSenary); color: var(--coral); }
.cs-btn--danger:hover:not(:disabled):not([aria-disabled="true"]) { background: var(--errorQuinary); border-color: var(--coral); color: var(--coral); }
.cs-btn--danger:active:not(:disabled):not([aria-disabled="true"]) { background: var(--errorSenary); color: var(--coral); }
.cs-btn--danger:disabled, .cs-btn--danger[aria-disabled="true"] { background: var(--primaryDisabled); color: var(--Content-text_disabled); }

.cs-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
.cs-btn--ghost:disabled, .cs-btn--ghost[aria-disabled="true"] { color: var(--Content-text_disabled); background: transparent; }

.cs-btn--sm { height: 32px; padding: 0 12px; font-size: var(--Font-size-text-100); border-radius: var(--Radius-200); }
/* 自带节点页：窄屏必须单列，否则 360px 侧栏会把整页撑出横向滚动条 */
.cs-nodes-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: 20px;
  align-items: start;
}
@media (max-width: 960px) {
  .cs-nodes-layout { grid-template-columns: minmax(0, 1fr); }
}
/* 行内状态文字：表单校验与操作结果的即时反馈（不自造颜色，全部取令牌） */
.cs-text-danger { color: var(--coral); }
.cs-text-ok { color: var(--primary); }
.cs-btn--lg { height: 48px; padding: 0 24px; font-size: var(--Font-size-text-300); border-radius: var(--Radius-400); }
.cs-btn--block { width: 100%; }

.cs-field { display: flex; flex-direction: column; gap: 8px; }
.cs-label { font-size: var(--Font-size-text-200); color: var(--textPrimaryMuted); }
.cs-label__req { color: var(--coral); margin-left: 4px; }
.cs-hint { font-size: var(--Font-size-text-100); color: var(--textSecondary); }

.cs-input, .cs-select, .cs-textarea {
  width: 100%; height: 40px; padding: 0 14px;
  background: var(--inputBackgroundHex);
  border: 1px solid var(--inputBorder);
  border-radius: var(--Radius-300);
  color: var(--textPrimary);
  font-size: var(--Font-size-text-200);
  font-family: var(--font-sans);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cs-textarea { height: auto; min-height: 104px; padding: 12px 14px; resize: vertical; line-height: 1.6; }
.cs-input::placeholder, .cs-textarea::placeholder { color: var(--inputPlaceholder); }
.cs-input:focus, .cs-select:focus, .cs-textarea:focus {
  outline: none;
  border-color: var(--inputBorderActive);
  box-shadow: 0 0 0 3px var(--primary08);
}
.cs-input.is-error, .cs-textarea.is-error { border-color: var(--error); }
.cs-input:disabled, .cs-select:disabled, .cs-textarea:disabled { opacity: .6; cursor: not-allowed; }
.cs-input--lg { height: 48px; font-size: var(--Font-size-text-300); }
.cs-input--mono { font-family: var(--font-mono); font-size: var(--Font-size-text-200); }
.cs-error-text { color: var(--coral); font-size: var(--Font-size-text-100); display: flex; gap: 6px; align-items: center; }
.cs-select { appearance: none; background-image: linear-gradient(45deg, transparent 50%, var(--textSecondary) 50%), linear-gradient(135deg, var(--textSecondary) 50%, transparent 50%); background-position: calc(100% - 18px) 17px, calc(100% - 13px) 17px; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 34px; }

/* ---------------------------------------------------------------------------
   自定义下拉（.cs-selectbox）
   ---------------------------------------------------------------------------
   为什么不用原生 <select>：原生控件的弹层由操作系统绘制，各平台外观不一致、
   无法跟随 drpc 暗色令牌，在 Windows/Android 上尤其突兀。
   这里由 ui.js 的 enhanceSelects() 自动把页面上每个 <select> 包成
   「隐藏原生控件 + 自绘触发器 + 自绘弹层」，原生控件仍留在 DOM 中，
   表单提交、value 读写、change 事件与 required 校验全部保持原样。
   --------------------------------------------------------------------------- */
.cs-selectbox { position: relative; display: inline-block; width: 100%; }

/* 只给读屏用的说明文字：视觉不可见，但在无障碍树里，可被 aria-describedby 引用 */
.cs-visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* 隐藏但保留在无障碍树之外，同时不参与 Tab 序列（焦点交给触发器） */
.cs-selectbox__native {
  position: absolute !important; width: 1px !important; height: 1px !important;
  margin: -1px !important; padding: 0 !important; border: 0 !important;
  overflow: hidden !important; clip: rect(0 0 0 0) !important; clip-path: inset(50%) !important;
  white-space: nowrap !important;
}

.cs-selectbox__trigger {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; height: 40px; padding: 0 12px 0 14px;
  background: var(--inputBackgroundHex);
  border: 1px solid var(--inputBorder);
  border-radius: var(--Radius-300);
  color: var(--textPrimary);
  font-family: var(--font-sans);
  font-size: var(--Font-size-text-200);
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cs-selectbox__trigger:hover:not(:disabled) { border-color: var(--inputBorderActive2); }
.cs-selectbox__trigger:focus-visible,
.cs-selectbox.is-open .cs-selectbox__trigger {
  outline: none;
  border-color: var(--inputBorderActive);
  box-shadow: 0 0 0 3px var(--primary08);
}
.cs-selectbox__trigger:disabled { opacity: .6; cursor: not-allowed; }
/* 跟随 .cs-input--lg 的大号尺寸，避免首页链选择器等位置被压矮 */
.cs-selectbox--lg .cs-selectbox__trigger { height: 48px; font-size: var(--Font-size-text-300); }

.cs-selectbox__value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-selectbox__value.is-placeholder { color: var(--inputPlaceholder); }
.cs-selectbox__caret { flex: none; display: inline-flex; color: var(--textSecondary); transition: transform .18s ease; }
.cs-selectbox.is-open .cs-selectbox__caret { transform: rotate(180deg); }

.cs-selectbox__panel {
  position: fixed; z-index: 160; display: none;
  flex-direction: column; gap: 4px; min-width: 140px;
  padding: 6px;
  background: var(--dropdownBackground);
  border: 1px solid var(--dropdownBorder);
  border-radius: var(--Radius-400);
  box-shadow: var(--boxShadow);
}
.cs-selectbox__panel.is-open { display: flex; }

.cs-selectbox__search {
  display: flex; align-items: center; gap: 8px;
  padding: 0 10px; height: 34px; flex: none;
  background: var(--inputBackgroundHex);
  border: 1px solid var(--inputBorder);
  border-radius: var(--Radius-200);
}
.cs-selectbox__search svg { flex: none; color: var(--textSecondary); }
.cs-selectbox__search input {
  flex: 1; min-width: 0; height: 100%;
  background: transparent; border: 0; outline: none;
  color: var(--textPrimary); font-family: var(--font-sans); font-size: var(--Font-size-text-200);
}
.cs-selectbox__search input::placeholder { color: var(--inputPlaceholder); }

.cs-selectbox__list { overflow-y: auto; flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 2px; }

.cs-selectbox__option {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 9px 10px; border: 0; border-radius: var(--Radius-200);
  background: transparent; color: var(--textPrimaryMuted);
  font-family: inherit; font-size: var(--Font-size-text-200); line-height: 1.3; text-align: left;
  cursor: pointer;
}
.cs-selectbox__option:hover:not(:disabled),
.cs-selectbox__option.is-active { background: var(--selectItemActiveBackground); color: var(--textPrimary); }
.cs-selectbox__option[aria-selected="true"] { color: var(--primary); }
.cs-selectbox__option:disabled { opacity: .4; cursor: not-allowed; }
.cs-selectbox__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-selectbox__tick { flex: none; display: inline-flex; opacity: 0; color: var(--primary); }
.cs-selectbox__option[aria-selected="true"] .cs-selectbox__tick { opacity: 1; }
.cs-selectbox__empty { padding: 12px 10px; text-align: center; color: var(--textSecondary); font-size: var(--Font-size-text-100); }

.cs-search {
  display: flex; align-items: center; gap: 10px;
  background: var(--inputBackgroundHex);
  border: 1px solid var(--inputBorder);
  border-radius: var(--Radius-400);
  padding: 6px 6px 6px 14px;
}
.cs-search:focus-within { border-color: var(--inputBorderActive); box-shadow: 0 0 0 3px var(--primary08); }
.cs-search input { flex: 1; height: 40px; background: transparent; border: 0; color: var(--textPrimary); font-size: var(--Font-size-text-300, 16px); font-family: var(--font-mono); }
.cs-search input:focus { outline: none; }
.cs-search input::placeholder { color: var(--inputPlaceholder); font-family: var(--font-sans); }
.cs-search svg { width: 18px; height: 18px; color: var(--textSecondary); flex: none; }

.cs-switch { display: inline-flex; align-items: center; gap: 10px; cursor: pointer; }
.cs-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.cs-switch__track { width: 40px; height: 22px; border-radius: 999px; background: var(--backgroundSurface); position: relative; transition: background .2s ease; flex: none; }
.cs-switch__track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: var(--textSecondary); transition: transform .2s ease, background .2s ease; }
.cs-switch input:checked + .cs-switch__track { background: var(--primaryTransparent); }
.cs-switch input:checked + .cs-switch__track::after { transform: translateX(18px); background: var(--primary); }
.cs-switch input:focus-visible + .cs-switch__track { outline: 2px solid var(--primary); outline-offset: 2px; }
.cs-switch input:disabled + .cs-switch__track { opacity: .5; cursor: not-allowed; }

.cs-check { display: inline-flex; align-items: flex-start; gap: 10px; cursor: pointer; font-size: var(--Font-size-text-200); color: var(--textPrimaryMuted); }
.cs-check input { margin: 3px 0 0; flex: none; }

.cs-tabs { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: 1px solid var(--divider); }
.cs-tab {
  padding: 12px 16px; border: 0; background: transparent; cursor: pointer;
  color: var(--textSecondary); font-size: var(--Font-size-text-200);
  border-bottom: 2px solid transparent; white-space: nowrap; font-family: var(--font-sans);
}
.cs-tab:hover { color: var(--textPrimary); }
.cs-tab[aria-selected="true"] { color: var(--primary); border-bottom-color: var(--primary); }
.cs-tabpanel { padding-top: 24px; }
.cs-tabpanel[hidden] { display: none; }

/* ========================== ⑥ 数据展示 =================================== */
/* 【G-10】表格容器只在这一处定义。原来 console.css 里还有一份同样的规则
   （多一个 --backgroundSecondary 底色），于是同一个 .cs-table 在定价页是
   「带底卡」、在文档页是「透明细边框」，外观取决于页面有没有引入控制台样式表。
   现在底色/圆角/横向滚动全在这里，控制台那份已删除。
   不用 overflow: hidden —— 那会把超出宽度的操作列直接裁掉。 */
.cs-table-wrap {
  overflow-x: auto; overflow-y: hidden;
  border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundSecondary);
}
.cs-table-wrap > .cs-table { margin: 0; }
.cs-table { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: var(--Font-size-text-200); }
.cs-table th {
  text-align: left; padding: 12px 16px;
  background: transparent;
  color: var(--textSecondary);
  font-size: var(--Font-size-text-100);
  letter-spacing: 0; text-transform: uppercase;
  font-weight: 500; white-space: normal; overflow-wrap: anywhere;
  border-bottom: 1px solid var(--divider);
}
.cs-table td { padding: 14px 16px; border-bottom: 1px solid var(--divider); color: var(--textPrimaryMuted); vertical-align: middle; overflow-wrap: anywhere; }
.cs-table tbody tr:last-child td { border-bottom: 0; }
.cs-table tbody tr:hover td { background: var(--white04); }
.cs-table .cs-num { font-family: var(--font-display); text-align: right; }
.cs-table .cs-mono { font-family: var(--font-mono); font-size: var(--Font-size-text-100); }
.cs-table .cs-badge { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
.cs-table--compact td { padding: 10px 14px; }

.cs-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px; border-radius: 999px;
  font-size: var(--Font-size-text-100); line-height: 18px;
  background: var(--white08); color: var(--textPrimaryMuted);
  white-space: nowrap;
}
.cs-badge--new { background: var(--backGroundBadgePrimary); color: var(--badgePrimary); }
.cs-badge--ok { background: var(--primaryTransparent); color: var(--primary); }
.cs-badge--warn { background: var(--warningTertiary); color: var(--lightYellow); }
.cs-badge--danger { background: var(--errorBackgroundLight); color: var(--coral); }
.cs-badge--soon { background: var(--white04); color: var(--textSecondary); }
.cs-badge--high { background: var(--errorBackgroundLight); color: var(--coral); }
.cs-badge--medium { background: var(--warningTertiary); color: var(--lightYellow); }
.cs-badge--low { background: var(--primaryTransparent); color: var(--primary); }
.cs-badge--info { background: var(--backGroundBadgePrimary); color: var(--badgePrimary); }
.cs-badge__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.cs-copy { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; background: transparent; border: 0; color: inherit; font: inherit; padding: 0; }
.cs-copy:hover { color: var(--primary); }
.cs-copy svg { width: 13px; height: 13px; opacity: .6; }

.cs-empty { padding: 56px 24px; text-align: center; color: var(--textSecondary); }
.cs-empty svg { width: 40px; height: 40px; margin: 0 auto 16px; color: var(--textSecondary); opacity: .6; }
.cs-empty strong { display: block; color: var(--textPrimary); font-size: var(--Font-size-text-300); margin-bottom: 6px; font-weight: 500; }
.cs-empty p { font-size: var(--Font-size-text-200); margin-bottom: 20px; }
.cs-empty__title { color: var(--textPrimary); font-size: var(--Font-size-text-300); font-weight: 500; margin: 0 0 6px; }
.cs-empty__hint { color: var(--textSecondary); font-size: var(--Font-size-text-200); margin: 0; }
.cs-empty__list {
  list-style: none; margin: 0 auto 20px; padding: 0;
  display: flex; flex-direction: column; gap: 8px; align-items: center;
  max-width: 420px;
}
.cs-empty__list li {
  display: flex; align-items: center; gap: 8px; text-align: left;
  font-size: var(--Font-size-text-200); color: var(--textSecondary);
}
.cs-empty__list li::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--primary); flex: none; }
.cs-empty__actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 10px; }
/* 卡片内嵌空态：结果页常有三四块，56px 留白叠起来就是一屏空白 */
.cs-empty--compact { padding: 32px 20px; }
.cs-empty--compact svg { width: 32px; height: 32px; margin-bottom: 12px; }
.cs-empty--compact strong { font-size: var(--Font-size-text-200); }
.cs-empty--compact p { margin-bottom: 14px; font-size: var(--Font-size-text-100); }
.cs-empty .cs-btn svg { width: 16px; height: 16px; margin: 0; opacity: 1; }

/* 说明性内容列表（隐私授权页等）：圆点跟随主色，行距放宽便于阅读 */
.cs-list {
  margin: 0; padding-left: 20px;
  display: flex; flex-direction: column; gap: 10px;
  color: var(--textPrimaryMuted);
  font-size: var(--Font-size-text-200); line-height: 1.8;
}
.cs-list li::marker { color: var(--primary); }
.cs-list b { color: var(--textPrimary); font-weight: 500; }

.cs-progress { height: 6px; border-radius: 999px; background: var(--backgroundSurface); overflow: hidden; }
.cs-progress__bar { height: 100%; background: var(--primary); border-radius: 999px; transition: width .3s ease; }
.cs-progress__bar--warn { background: var(--warning); }
/* 还没有任何一条链完成时用流动条纹：停在 0% 的实心条看起来像卡住了，
   而进度本身是真实的（按已落库链数算），不能为了好看去编百分比。 */
.cs-progress.is-indeterminate .cs-progress__bar {
  width: 100% !important;
  background: repeating-linear-gradient(90deg,
    var(--primary) 0 28px, transparent 28px 56px);
  background-size: 56px 100%;
  animation: cs-stripe 1.1s linear infinite;
  opacity: .55;
}
@keyframes cs-stripe { from { background-position: 0 0; } to { background-position: 56px 0; } }
@media (prefers-reduced-motion: reduce) {
  .cs-progress.is-indeterminate .cs-progress__bar { animation: none; }
}
.cs-progress__bar--danger { background: var(--error); }

/* 【为什么标签列用百分比而不是固定 200px】同一套 .cs-defs 既出现在整页宽的
   详情页，也出现在链目录的卡片里。固定 200px 在 230px 宽的卡片中会把
   值列压到 30px，像「26331325」这样的区块高度直接被切掉。 */
.cs-defs { display: grid; grid-template-columns: minmax(88px, 40%) minmax(0, 1fr); gap: 0; border: 1px solid var(--border); border-radius: var(--Radius-400); overflow: hidden; }
.cs-defs dt { padding: 14px 16px; background: var(--backgroundTertiary); color: var(--textSecondary); font-size: var(--Font-size-text-200); border-bottom: 1px solid var(--divider); }
.cs-defs dd { margin: 0; padding: 14px 16px; border-bottom: 1px solid var(--divider); font-size: var(--Font-size-text-200); color: var(--textPrimaryMuted); overflow-wrap: anywhere; }
.cs-defs dt:last-of-type, .cs-defs dd:last-of-type { border-bottom: 0; }

.cs-urlbar {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: var(--Radius-300);
  background: var(--inputBackgroundHex);
}
.cs-urlbar > code {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--textPrimaryMuted);
  font-size: var(--Font-size-text-100);
  overflow-wrap: anywhere;
  word-break: break-word;
}
.cs-urlbar__act {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: none;
  border: 1px solid var(--border);
  border-radius: var(--Radius-200);
  color: var(--textSecondaryBright);
  cursor: pointer;
}
.cs-urlbar__act:hover { border-color: var(--borderSecondaryWhite); color: var(--primary); }
.cs-urlbar-hint { margin-top: 8px; color: var(--textSecondary); font-size: var(--Font-size-text-100); line-height: 1.6; overflow-wrap: anywhere; }

/* ============================ ⑦ 反馈 ===================================== */
/* 提示条容器铺在右下角，窄屏时会盖住页面按钮、把点击吃掉（验收里表现为「点不动」）。
   容器本身不接触摸，只有真正的提示条可点。 */
.cs-toast-host { position: fixed; right: 20px; bottom: 20px; z-index: 200; display: flex; flex-direction: column; gap: 10px; max-width: min(400px, calc(100vw - 40px)); pointer-events: none; }
.cs-toast { pointer-events: auto; }
.cs-toast {
  display: flex; gap: 12px; align-items: flex-start;
  background: var(--backgroundSecondary);
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: var(--Radius-400);
  padding: 14px 16px;
  box-shadow: var(--boxShadow);
  animation: cs-toast-in .2s ease;
}
.cs-toast--error { border-left-color: var(--error); }
.cs-toast--warn { border-left-color: var(--warning); }
.cs-toast strong { display: block; font-size: var(--Font-size-text-200); font-weight: 500; }
.cs-toast p { font-size: var(--Font-size-text-100); color: var(--textSecondary); margin-top: 2px; }
@keyframes cs-toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.cs-modal-mask { position: fixed; inset: 0; background: var(--modalOverlay); backdrop-filter: blur(3px); z-index: 150; display: grid; place-items: center; padding: 20px; }
.cs-modal {
  background: var(--backgroundSecondary);
  border: 1px solid var(--border);
  border-radius: var(--Radius-500);
  width: min(560px, 100%);
  max-height: calc(100vh - 40px);
  max-height: calc(100dvh - 40px);
  overflow-y: auto;
  box-shadow: var(--boxShadow);
}
.cs-modal--wide { width: min(880px, 100%); }
.cs-modal__hd { padding: 20px 24px; border-bottom: 1px solid var(--divider); display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.cs-modal__hd h3 { font-size: var(--Font-size-text-500, 20px); }
.cs-modal__bd { padding: 24px; }
.cs-modal__ft { padding: 16px 24px; border-top: 1px solid var(--divider); display: flex; justify-content: flex-end; gap: 10px; flex-wrap: wrap; }
.cs-modal__close { background: transparent; border: 0; color: var(--textSecondary); cursor: pointer; width: 32px; height: 32px; border-radius: var(--Radius-300); }
.cs-modal__close:hover { background: var(--white08); color: var(--textPrimary); }

/* ===== 连接钱包弹窗（WP-120：逐项对齐 Reown AppKit 的连接弹窗） =====
   规格来源（2026-11-02 实测，可复核）：
     · 源码 reown-com/appkit → packages/ui/src/utils/ThemeConstantsUtil.ts（令牌表）
       packages/ui/src/composites/wui-*（组件样式）
       packages/scaffold-ui/src/modal/w3m-modal/styles.ts（弹窗容器）
     · 运行结果 lab.reown.com 真实弹窗的计算样式与 DOM 尺寸
   照抄的数值（改这里之前请先回上游核对）：
     弹窗宽 370px、卡片圆角 32px、卡片内边距 4px、头部高 60px、
     内容左右内边距 12px、纵向间距 8px、行高 56px、行内边距 12px、行圆角 16px、
     钱包图标 32x32（圆角 4px）、网格图标 56x56、tag 高 20px 字号 12px、
     动效 200ms cubic-bezier(.23,.09,.08,1.13)。
   颜色不走 AppKit 的蓝色系：按硬规矩 A 取本站 tokens（品牌绿 --primary）。 */
.cs-auth-mask { background: rgba(10,10,11,.66); backdrop-filter: blur(6px) saturate(1.08); }
/* 焦点交给容器只是为了让读屏/键盘有个落点，容器本身不画焦点环（画了会是一整圈贴边的绿框）。 */
.cs-auth:focus { outline: none; }
.cs-auth {
  display: flex;
  flex-direction: column;
  width: min(384px, 100%);
  max-height: min(672px, calc(100dvh - 40px));
  padding: 4px;
  border: 1px solid rgba(255,255,255,.07);
  border-radius: 30px;
  /* 顶部一点点提亮：纯 --backgroundSecondary 在大屏上像一块塑料板，
     竖向渐变让弹窗有「面」的方向感，和 drpc 的深色卡片是同一套做法。
     用半透明白叠在 token 底色上，不引入新的十六进制色值（F-05 门禁）。 */
  background: linear-gradient(180deg, rgba(255,255,255,.035) 0%, rgba(255,255,255,0) 34%), var(--backgroundSecondary);
  box-shadow: 0 24px 64px -16px rgba(0,0,0,.7), 0 2px 8px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.05);
  overflow: hidden;
  animation: cs-auth-enter 220ms cubic-bezier(.23,.09,.08,1.13);
}
@keyframes cs-auth-enter {
  from { opacity: 0; transform: translateY(10px) scale(.985); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .cs-auth { animation: none; }
}
/* 头部：58px 高，标题居中；左侧返回、右侧关闭各 32x32 ——
   28px 在触屏上太难点，32px 与下方 58px 行形成清晰的层级。
   头部不加分隔线：弹窗整体已经用间距区分层级，多一条线反而更碎。 */
.cs-auth__hd { position: relative; flex: none; display: flex; align-items: center; justify-content: center; min-height: 60px; padding: 0 14px; }
.cs-auth__title { font-size: var(--Font-size-text-400); font-weight: 600; letter-spacing: -.01em; line-height: 1.35; color: var(--textPrimary); text-align: center; }
.cs-auth__back, .cs-auth__close {
  position: absolute; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center; width: 32px; height: 32px; padding: 0;
  border: 0; border-radius: 10px; background: transparent; color: var(--textSecondary); cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease;
}
.cs-auth__back { left: 12px; }
.cs-auth__close { right: 12px; }
.cs-auth__back:hover, .cs-auth__close:hover { background: var(--white08); color: var(--textPrimary); }
.cs-auth__back:focus-visible, .cs-auth__close:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.cs-auth__back[hidden] { display: none; }
/* 内容区：左右 10px、纵向 8px 间距，超高时自身滚动。
   滚动条单独收窄：默认的 15px 宽滚动条会把 384px 的弹窗挤出一道明显的灰边。 */
.cs-auth__bd {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 0 10px 12px;
  scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.14) transparent;
}
.cs-auth__bd::-webkit-scrollbar { width: 6px; }
.cs-auth__bd::-webkit-scrollbar-track { background: transparent; }
.cs-auth__bd::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border-radius: 999px; }
.cs-auth__bd::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.24); }
.cs-auth__view { display: grid; gap: 8px; }
.cs-auth__view[hidden] { display: none; }
/* 钱包行容器：与视图同样的 8px 纵向节奏，嵌套一层只为便于局部刷新 */
.cs-auth__list { display: grid; gap: 8px; }

/* ---- 列表行：钱包 / 邮箱入口 / 搜索入口，统一 58px 高、圆角 16px ----
   行只有「悬停才亮」这一层反馈，不做位移：位移会让整列文字在鼠标移动时抖动。 */
.cs-auth__row {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 58px; padding: 10px;
  text-align: left; text-decoration: none; background: transparent; border: 0; border-radius: var(--Radius-500);
  color: var(--textPrimary); cursor: pointer;
  transition: background-color 160ms ease;
}
.cs-auth__row:hover:not(:disabled) { background: var(--white05); }
.cs-auth__row:active:not(:disabled) { background: var(--white08); }
.cs-auth__row:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.cs-auth__row:disabled { opacity: .5; cursor: not-allowed; }
/* 「搜索全部钱包」用比钱包行更暗的底：它是入口，不是某一个钱包，
   底色一深就和上面的钱包行拉开层级，用户不会误以为这里也是一款钱包。 */
.cs-auth__row--all { background: var(--white04); border: 1px solid rgba(255,255,255,.06); }
.cs-auth__row--all:hover:not(:disabled) { background: var(--white08); }

/* ---- 钱包图标：34x34 圆角 9px ----
   内描边（inset ring）是这里最关键的细节：本地补录的图标里有一部分是透明底图形，
   在深色容器上原本只剩一片深灰；有了这圈 1px 描边，透明底图标也有清晰的边界，
   而满底图标看不出描边，两者在视觉上是同一种「方块」。 */
.cs-auth__icon {
  flex: none; display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 9px; background: rgba(255,255,255,.05); color: var(--textPrimaryMuted);
  font-family: var(--font-display); font-size: var(--Font-size-text-200); font-weight: 600;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.08);
  transition: box-shadow 160ms ease;
}
.cs-auth__row:hover .cs-auth__icon, .cs-auth__grid-item:hover .cs-auth__icon { box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }
.cs-auth__icon img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* WalletConnect 的品牌标是横长形（viewBox 约 1.63:1），cover 会把左右两侧裁掉，
   于是那个标志性的双弧只剩中间一段。它是唯一的非方形图标，单独放行 contain；
   其余钱包图标都是方形，继续 cover 铺满，不留白边。 */
.cs-auth__icon img[src$="walletconnect.svg"] { object-fit: contain; }
/* 邮箱入口：品牌绿底 + 绿线图标，整个弹窗里只此一处用绿色实底，
   它同时也是列表里唯一的「非钱包」入口，颜色就是它的身份。 */
.cs-auth__icon--brand { background: var(--primaryLight); color: var(--primary); box-shadow: inset 0 0 0 1px rgba(65,226,120,.22); }
/* 手机钱包 / 搜索：线条图标，比钱包图标亮一档，否则 1.6 描边在深灰底上会糊成一片。 */
.cs-auth__icon--glyph { background: rgba(255,255,255,.06); color: var(--textPrimaryMuted); }
.cs-auth__name { flex: 1 1 auto; min-width: 0; font-size: var(--Font-size-text-300); font-weight: 500; letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-auth__sub { display: block; font-size: var(--Font-size-text-100); color: var(--textSecondary); }
/* 标签：22px 高的胶囊。「已安装」「扫码」用绿色，「8」「101+」这类计数用中性灰。 */
.cs-auth__tag {
  flex: none; display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 999px;
  background: var(--primary08); color: var(--primary); font-size: var(--Font-size-text-100); font-weight: 500;
  white-space: nowrap;
}
.cs-auth__tag--muted { background: var(--white05); color: var(--textSecondary); }
/* 右侧箭头：默认压得很淡，鼠标移到行上才提亮并右移 1px，形成「可以点」的暗示。 */
.cs-auth__caret { flex: none; display: grid; place-items: center; color: rgba(255,255,255,.28); transition: color 160ms ease, transform 160ms ease; }
.cs-auth__row:hover .cs-auth__caret { color: var(--textPrimaryMuted); transform: translateX(1px); }
.cs-auth__row:disabled .cs-auth__caret, .cs-auth__row:disabled .cs-auth__name { opacity: .7; }

/* ---- 分隔线「或」 ---- */
.cs-auth__sep { display: flex; align-items: center; gap: 10px; margin: 6px 0; font-size: var(--Font-size-text-100); letter-spacing: .04em; color: var(--textSecondary); }
/* 两侧的线用渐变淡出：直接画一条 1px 实线，会在贴近弹窗边缘处突然断掉，像没画完。 */
.cs-auth__sep::before, .cs-auth__sep::after { content: ''; flex: 1 1 auto; height: 1px; }
.cs-auth__sep::before { background: linear-gradient(90deg, transparent, var(--divider)); }
.cs-auth__sep::after { background: linear-gradient(90deg, var(--divider), transparent); }

/* ---- 搜索框：48px 高、圆角 14px ----
   高度从 52 收到 48：它下面紧接着就是 56px 的钱包网格，
   52 的输入框会跟首行图标抢视觉重量。 */
.cs-auth__search {
  position: sticky; top: 0; z-index: 2;
  /* 贴顶时用和弹窗同色的实底挡住滚过的图标；底部再淡化 10px，
     滚动的图标从搜索框下面钻出来时不会有一条硬边。
     padding-top 必须留在搜索框自己身上（而不是内容区的 padding）：内容区一旦有
     padding-top，滚动内容就会从那段 padding 里露出一条彩色图标边。 */
  padding: 10px 0;
  background: linear-gradient(180deg, var(--backgroundSecondary) 84%, rgba(27,27,28,0));
}
.cs-auth__search-icon { position: absolute; left: 14px; top: 34px; transform: translateY(-50%); color: var(--textSecondary); pointer-events: none; }
.cs-auth__search input {
  width: 100%; height: 48px; padding: 0 14px 0 40px; border-radius: 14px;
  background: var(--white04); border: 1px solid rgba(255,255,255,.07); color: var(--textPrimary);
  font-family: inherit; font-size: var(--Font-size-text-200);
  transition: border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;
}
.cs-auth__search input::placeholder { color: var(--inputPlaceholder); }
.cs-auth__search input:hover { background: var(--white05); }
.cs-auth__search input:focus { outline: none; border-color: rgba(65,226,120,.55); background: var(--white05); box-shadow: 0 0 0 2px rgba(65,226,120,.14); }
/* 搜索框自带清除按钮（type=search），默认那个蓝色 X 与深色弹窗完全不搭，收掉它。 */
.cs-auth__search input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* ---- 全量钱包网格：4 列、图标 56x56 ----
   名称用 textPrimaryMuted 而不是纯白：一屏 20 个纯白名字会盖过图标本身。 */
.cs-auth__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px 2px; }
.cs-auth__grid-item {
  display: grid; gap: 8px; justify-items: center; padding: 10px 4px 8px; border: 0; border-radius: 14px;
  background: transparent; color: var(--textPrimary); cursor: pointer; font: inherit;
  transition: background-color 160ms ease;
}
.cs-auth__grid-item:hover { background: var(--white05); }
.cs-auth__grid-item:active { background: var(--white08); }
.cs-auth__grid-item:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.cs-auth__grid-item .cs-auth__icon { width: 56px; height: 56px; border-radius: 14px; font-size: var(--Font-size-text-500); }
.cs-auth__grid-name { width: 100%; font-size: var(--Font-size-text-100); text-align: center; color: var(--textPrimaryMuted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- 邮箱表单：字段与主按钮同 AppKit 的 52px / 圆角 16px ---- */
.cs-auth__form { display: grid; gap: 12px; }
.cs-auth__form .cs-field { display: grid; gap: 6px; }
.cs-auth__form .cs-label { font-size: var(--Font-size-text-100); color: var(--textSecondary); }
.cs-auth__form .cs-input {
  height: 52px; padding: 0 16px; border-radius: var(--Radius-500);
  background: var(--white05); border: 1px solid var(--border); color: var(--textPrimary);
  font-family: inherit; font-size: var(--Font-size-text-300, 16px);
}
.cs-auth__form .cs-input:focus { outline: none; border-color: var(--inputBorderActive); }
.cs-auth__form .cs-input::placeholder { color: var(--inputPlaceholder); }
.cs-auth__form .cs-btn { width: 100%; height: 52px; min-height: 52px; border-radius: var(--Radius-500); font-size: var(--Font-size-text-300, 16px); }
.cs-auth__switch { font-size: var(--Font-size-text-100); color: var(--textSecondary); text-align: center; }
.cs-auth__switch button { padding: 4px; border: 0; background: none; color: var(--primary); font: inherit; cursor: pointer; }
.cs-auth__switch button:hover { text-decoration: underline; }
.cs-auth__switch button:disabled { opacity: .5; cursor: not-allowed; }

/* ---- 图形验证码：一行「输入框 + 验证码图片」 ----
   图片本身就是一个大按钮：点它可以换一张，但不再在它旁边写「点击刷新验证码」——
   一行里塞三段字，用户的第一反应是「这里是不是坏了」。
   加载中图标旋转、加载失败变成可点的静态刷新图标；文字说明只保留在读屏里。 */
.cs-auth__captcha-row {
  display: grid; grid-template-columns: minmax(0, 1fr) 132px; gap: 8px; align-items: center;
}
.cs-auth__captcha {
  position: relative; display: grid; place-items: center;
  width: 132px; height: 44px; padding: 0; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--white05); color: var(--textSecondary);
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease;
}
.cs-auth__captcha:hover:not(:disabled) { border-color: var(--inputBorderActive); color: var(--primary); }
.cs-auth__captcha:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.cs-auth__captcha:disabled { cursor: progress; }
/* 按钮是 3:1（与验证码 SVG 的 120×40 同比例），图片 contain 后正好铺满，
   不再出现白底 + 留白那一圈白边。圆角由按钮裁切，图片自己不带边框。 */
.cs-auth__captcha img { display: block; width: 100%; height: 100%; object-fit: contain; }
.cs-auth__captcha img[hidden] { display: none; }
/* 有图时按钮自身完全退让：边框和底色都去掉，只剩那张圆角验证码。 */
.cs-auth__captcha.is-ready { background: transparent; border-color: transparent; }
/* 有图时图标让位；没图（加载中/失败）时它就是按钮的全部内容 */
.cs-auth__captcha.is-ready .cs-auth__captcha-icon { display: none; }
.cs-auth__captcha-icon { position: absolute; inset: 0; display: grid; place-items: center; }
.cs-auth__captcha.is-loading .cs-auth__captcha-icon { animation: cs-auth-spin 900ms linear infinite; }
.cs-auth__captcha.is-error { border-color: rgba(248,124,116,.35); color: var(--coral); }
@keyframes cs-auth-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .cs-auth__captcha.is-loading .cs-auth__captcha-icon { animation: none; }
}

/* ---- 扫码面板：配对成功后才展开 ---- */
.cs-auth__wc { display: grid; gap: 12px; padding: 12px; background: var(--backgroundTertiary); border-radius: var(--Radius-500); text-align: center; }
.cs-auth__wc[hidden] { display: none; }
.cs-auth__wc-title { font-size: var(--Font-size-text-200); color: var(--textPrimary); }
/* 二维码底必须是纯白：它是给摄像头读的图形，不是装饰。
   深色底或半透明底会让一部分钱包扫不出来，因此这里保留 #ffffff 而不取 tokens 里的浅色。 */
.cs-auth__qr { display: grid; place-items: center; min-height: 208px; padding: 12px; background: #ffffff; border-radius: var(--Radius-400); }
.cs-auth__qr svg { display: block; width: 100%; max-width: 208px; height: auto; }
.cs-auth__wc-open { width: 100%; }
/* 移动端「把配对 URI 交给钱包」的钱包列表：手机上一列铺开，够大好点；
   桌面端两列，避免把弹窗撑得过高。用 grid 自适应，不写死宽度。 */
.cs-auth__wc-wallets { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 8px; }
.cs-auth__wc-wallets .cs-btn { width: 100%; justify-content: center; }
.cs-auth__wc-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.cs-auth__wc .cs-hint { text-align: left; }
.cs-auth__relay-note { padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--Radius-300); background: var(--backgroundSecondary); }

.cs-auth__empty { padding: 24px 16px; text-align: center; font-size: var(--Font-size-text-100); color: var(--textSecondary); line-height: 1.7; }
.cs-auth__msg { margin-top: 6px; font-size: var(--Font-size-text-200); line-height: 1.6; }
/* 失败与成功都做成「一块提示条」而不是一行裸文字：
   裸红字贴在列表底下，用户扫一眼会以为是列表项；加了底色和描边才有「这是结果」的分量。 */
.cs-auth__msg--err {
  padding: 10px 12px; border-radius: 12px;
  background: rgba(248,124,116,.08); border: 1px solid rgba(248,124,116,.22);
  color: var(--coral);
}
.cs-auth__msg--ok {
  padding: 10px 12px; border-radius: 12px;
  background: var(--primary08); border: 1px solid rgba(65,226,120,.22);
  color: var(--primary);
}
.cs-auth__msg--busy { color: var(--textSecondary); }

/* ---- 窄屏（手机）----
   弹窗在 390px 宽的手机上必须铺满可用宽度：370px 的固定宽度会左右各留 10px 的白边，
   而每一行都是 56px 高的点击区，能多给 20px 就多给。 */
@media (max-width: 480px) {
  .cs-auth { width: 100%; max-height: calc(100dvh - 24px); border-radius: 24px; }
  .cs-auth__hd { min-height: 60px; padding: 0 10px; }
  .cs-auth__bd { padding: 0 8px 10px; }
  .cs-auth__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}


/* =============================================================
 * ⑫ 现代化组件系统补充（提示框/KPI卡/筛选栏/代码块/步骤条/边距）
 * ============================================================= */

/* 1. 全局边距工具类 (Spacing Utilities) */
.cs-mt-0 { margin-top: 0 !important; }
.cs-mt-4 { margin-top: 4px !important; }
.cs-mt-8 { margin-top: 8px !important; }
.cs-mt-12 { margin-top: 12px !important; }
.cs-mt-16 { margin-top: 16px !important; }
.cs-mt-24 { margin-top: 24px !important; }
.cs-mt-32 { margin-top: 32px !important; }
.cs-mt-48 { margin-top: 48px !important; }

.cs-mb-0 { margin-bottom: 0 !important; }
.cs-mb-8 { margin-bottom: 8px !important; }
.cs-mb-12 { margin-bottom: 12px !important; }
.cs-mb-16 { margin-bottom: 16px !important; }
.cs-mb-24 { margin-bottom: 24px !important; }
.cs-mb-32 { margin-bottom: 32px !important; }

.cs-gap-12 { gap: 12px !important; }
.cs-gap-24 { gap: 24px !important; }

/* 2. 状态提示框 (.cs-alert) */
.cs-alert {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 18px;
  border-radius: var(--Radius-400);
  background: var(--backgroundSecondary);
  border: 1px solid var(--border);
  color: var(--textPrimaryMuted);
  font-size: var(--Font-size-text-100);
  line-height: 1.6;
  box-sizing: border-box;
}

.cs-alert svg {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 2px;
}

.cs-alert strong {
  color: var(--textPrimary);
  display: block;
  margin-bottom: 4px;
}

.cs-alert p {
  margin: 0;
}

.cs-alert--info {
  background: var(--backgroundTertiary);
  border-color: var(--borderSecondaryWhite);
  color: var(--textPrimaryMuted);
}
.cs-alert--info svg {
  color: var(--blueMarketing);
}

.cs-alert--ok {
  background: var(--primary08);
  border-color: var(--primaryLight);
  color: var(--textPrimary);
}
.cs-alert--ok svg {
  color: var(--primary);
}

.cs-alert--warn {
  /* G-17：原来写死 rgba(232,207,71,…)，与 tokens 的警告阶梯（--warning*）不同源 */
  background: var(--warningQuaternary);
  border-color: var(--warning015);
  color: var(--textPrimary);
}
.cs-alert--warn svg {
  color: var(--lightYellow);
}

.cs-alert--danger {
  /* G-17：同上，改用 --error* 阶梯，全站危险色只剩一套 */
  background: var(--errorQuaternary);
  border-color: var(--errorQuinary);
  color: var(--textPrimary);
}
.cs-alert--danger svg {
  color: var(--coral);
}

/* 3. 筛选侧栏与工具布局 (.cs-toolgrid, .cs-sidepanel, .cs-filter-list) */
.cs-toolgrid {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
  min-width: 0;
}
.cs-toolgrid > * { min-width: 0; }
/* 没有数据时整块收起筛选侧栏，别让四个空筛选框占掉版面 */
.cs-toolgrid.is-empty { grid-template-columns: minmax(0, 1fr); }
.cs-toolgrid.is-empty .cs-sidepanel { display: none; }
@media (max-width: 1048px) {
  .cs-toolgrid { grid-template-columns: minmax(0, 1fr); }
}

.cs-sidepanel {
  background: var(--backgroundSecondary);
  border: 1px solid var(--border);
  border-radius: var(--Radius-500);   /* G-06：卡级容器统一 16px */
  padding: 20px;
  box-sizing: border-box;
}

/* 文档翻页：三篇文档原来读完就没有下一步，只能回侧栏再点一次 */
.cs-pager { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; border-top: 1px solid var(--divider); padding-top: 24px; }
.cs-pager__item {
  display: flex; flex-direction: column; gap: 4px;
  padding: 16px 18px; border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundSecondary); text-decoration: none;
  transition: border-color .15s ease, background .15s ease;
}
/* G-16：原来写的是 `--primaryTertiary`（tokens 里没有这个变量），整条 background 失效，
   hover 只剩边框变绿。改用真实存在的 --primaryLight（rgba(65,226,120,.1)）。 */
.cs-pager__item:hover { border-color: var(--primary); background: var(--primaryLight); }
.cs-pager__item--next { text-align: right; }
.cs-pager__dir { font-size: var(--Font-size-text-100); color: var(--textSecondary); }
.cs-pager__title { font-size: var(--Font-size-text-300); color: var(--textPrimary); }
@media (max-width: 600px) { .cs-pager { grid-template-columns: minmax(0, 1fr); } .cs-pager__item--next { text-align: left; } }

/* 文档页左栏跟随滚动：内容有几千像素，侧栏滚走以后左下角就剩一条空带 */
.cs-sidepanel--contents {
  position: sticky;
  top: calc(var(--landing-header-height-desktop) + 16px);
  max-height: calc(100vh - var(--landing-header-height-desktop) - 32px);
  overflow-y: auto;
}
@media (max-width: 1048px) { .cs-sidepanel--contents { position: static; max-height: none; } }

.cs-sidepanel h4 {
  font-size: var(--Font-size-text-200);
  font-weight: 500;
  color: var(--textPrimary);
  margin: 0 0 10px 0;
}

.cs-filter-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.cs-filter-list button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 8px 12px;
  border-radius: var(--Radius-200);
  background: var(--backgroundTertiary);
  border: 1px solid var(--divider);
  color: var(--textSecondary);
  font-size: var(--Font-size-text-100);
  text-align: left;
  cursor: pointer;
  transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
  box-sizing: border-box;
}

.cs-filter-list button:hover {
  background: var(--backgroundSurface);
  color: var(--textPrimary);
  border-color: var(--borderSecondaryWhite);
}

.cs-filter-list button[aria-pressed="true"] {
  background: var(--primary08);
  color: var(--primary);
  border-color: var(--primaryLight);
  font-weight: 500;
}

/* 计数徽标是要读的数字（「全部 12」），10px 只允许装饰用途，这里回到 12px */
.cs-filter-list button span {
  font-family: var(--font-mono);
  font-size: var(--Font-size-text-100);
  background: var(--white05);
  padding: 2px 6px;
  border-radius: 999px;
  color: var(--textSecondary);
}
.cs-filter-list button[aria-pressed="true"] span {
  background: var(--primaryTransparent);
  color: var(--primary);
}

.cs-filter-placeholder {
  font-size: var(--Font-size-text-100);
  color: var(--textSecondary);
  padding: 8px 12px;
  background: var(--backgroundTertiary);
  border-radius: var(--Radius-200);
  border: 1px dashed var(--divider);
  margin: 0;
  text-align: center;
}

/* 4. 仪表盘与核心 KPI 徽章 (.cs-kpi, .cs-grid--metrics) */
.cs-grid--metrics {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
@media (max-width: 768px) {
  .cs-grid--metrics { grid-template-columns: 1fr; }
}

.cs-kpi {
  background: var(--backgroundSecondary);
  border: 1px solid var(--border);
  /* G-06：卡级容器统一 --Radius-500（规范 §2.2），与相邻的 .cs-card 同圆角 */
  border-radius: var(--Radius-500);
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
  box-sizing: border-box;
}

/* G-12：KPI 卡多数不是链接。纯展示卡只允许边框/底色变化，
   位移只留给真的能点的卡（<a> 或带 data-href），否则是「假交互」。 */
.cs-kpi:hover {
  border-color: var(--borderSecondaryWhite);
  box-shadow: var(--shadow-card-subtle);
}
a.cs-kpi:hover, [data-href].cs-kpi:hover { transform: translateY(-2px); }

.cs-kpi__label {
  font-size: var(--Font-size-text-100);
  color: var(--textSecondary);
  text-transform: uppercase;
  letter-spacing: 0;
}

/* G-07：控制台的「大数字」原来是 26/28/30px 三种，同一屏里三个主角三种大小。
   统一成 24→28 的 clamp（token 阶梯里 24 与 28 之间没有档位，取这一档保住视觉重量）。 */
.cs-kpi__value {
  font-family: var(--font-display);
  font-size: clamp(var(--Font-size-header-100), 2.2vw, var(--Font-size-header-200));
  font-weight: 600;
  color: var(--textPrimary);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.cs-kpi__delta {
  font-size: var(--Font-size-text-100);
  color: var(--textSecondary);
  margin-top: 4px;
}

/* 5. 提示便签 (.cs-sticky-note) */
.cs-sticky-note {
  font-size: var(--Font-size-text-100);
  color: var(--textSecondary);
  line-height: 1.6;
  padding: 12px 14px;
  border-radius: var(--Radius-300);
  background: var(--backgroundTertiary);
  border-left: 3px solid var(--primary);
  box-sizing: border-box;
}

/* 6. 授权记录卡片与主操作区 (.cs-approval) */
.cs-approval {
  background: var(--backgroundSecondary);
  border: 1px solid var(--border);
  border-radius: var(--Radius-500);   /* G-06：卡级容器统一 16px */
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
  box-sizing: border-box;
}

/* G-12：授权卡本身不可点，只给边框/底色反馈；选中态才是交互信号 */
.cs-approval:hover {
  border-color: var(--borderSecondaryWhite);
}

.cs-approval__main {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.cs-approval__title {
  font-size: var(--Font-size-text-200);
  font-weight: 500;
  color: var(--textPrimary);
  display: flex;
  align-items: center;
  gap: 10px;
}

.cs-approval__meta {
  font-size: var(--Font-size-text-100);
  color: var(--textSecondary);
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.cs-approval__actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 6.6 免费工具信任条：三个事实摆出来，别让用户猜「要不要注册、收不收费」 */
.cs-trust {
  display: flex; flex-wrap: wrap; gap: 8px 20px; margin: 14px 0 0;
}
.cs-trust span {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--Font-size-text-100);
  color: var(--textSecondary);
}
.cs-trust b {
  color: var(--primary); font-weight: 600;
  padding: 1px 7px; border-radius: 999px;
  background: var(--primary08);
  font-size: var(--Font-size-text-50);
}

/* 6.7 侧栏「需登录」标记：游客点进去只能看空壳，先在这里说明 */
.cs-side__lock {
  margin-left: auto; font-style: normal; font-size: var(--Font-size-text-50);
  color: var(--textSecondary); background: var(--backgroundSurface);
  border: 1px solid var(--border); border-radius: 999px; padding: 0 6px; line-height: 16px;
}
/* 6.8 游客提示条：需要登录的页面，进来第一句话就说清楚 */
.cs-guest-notice {
  display: flex; gap: 16px; align-items: center; justify-content: space-between;
  flex-wrap: wrap;
  padding: 14px 16px; margin: 0 0 20px;
  border: 1px solid var(--border); border-radius: var(--Radius-300);
  background: var(--backgroundSecondary);
}
.cs-guest-notice strong { font-size: var(--Font-size-text-200); }
.cs-guest-notice p {
  margin: 6px 0 0; font-size: var(--Font-size-text-100); color: var(--textSecondary);
  max-width: 62ch;
}
.cs-guest-notice__acts { display: flex; gap: 8px; flex: none; }
@media (max-width: 640px) {
  .cs-guest-notice__acts { width: 100%; }
  .cs-guest-notice__acts .cs-btn { flex: 1; justify-content: center; }
}

/* 6.1 授权卡片（新版）：勾选框 | 主体；撤销按钮固定在右上角。
   旧结构 .cs-approval__main/__title/__meta 仍被 revoke.html / preview.html /
   auto-revoke.html 使用，所以新版只加修饰类，不改基础类的布局。 */
.cs-approval--card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0 14px;
  align-items: start;
  padding: 16px 18px;
}
.cs-approval--nopick { grid-template-columns: minmax(0, 1fr); }
.cs-approval__pick { padding-top: 2px; display: flex; }
.cs-approval__pick input { width: 16px; height: 16px; accent-color: var(--primary); cursor: pointer; }
.cs-approval__body { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.cs-approval__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
}
.cs-approval__id {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: var(--Font-size-text-300); min-width: 0;
}
.cs-approval__id strong {
  font-weight: 500; color: var(--textPrimary);
  overflow-wrap: anywhere;
}
/* 元信息改成分组的小格子：之前四个值挤在一行用空格分隔，扫读时找不到边界 */
.cs-approval__facts {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px 16px; margin: 0; padding: 12px 14px;
  background: var(--backgroundTertiary);
  border: 1px solid var(--divider);
  border-radius: var(--Radius-300);
}
.cs-approval__facts > div { min-width: 0; }
.cs-approval__facts dt {
  font-size: var(--Font-size-text-50); color: var(--textSecondary);
  margin: 0 0 4px; letter-spacing: .02em;
}
.cs-approval__facts dd {
  margin: 0; font-size: var(--Font-size-text-200); color: var(--textPrimary);
  overflow-wrap: anywhere;
}
.cs-approval__facts dd.is-warn { color: var(--warning); }
.cs-approval__who {
  display: flex; flex-wrap: wrap; gap: 6px 20px;
  font-size: var(--Font-size-text-100); color: var(--textSecondary);
}
.cs-approval__who b {
  color: var(--textPrimaryMuted); font-weight: 500; font-family: var(--font-mono);
}
.cs-approval__why summary {
  cursor: pointer; color: var(--textSecondary);
  font-size: var(--Font-size-text-100); list-style: none;
}
.cs-approval__why summary::-webkit-details-marker { display: none; }
.cs-approval__why summary::before { content: "▸ "; color: var(--textSecondary); }
.cs-approval__why[open] summary::before { content: "▾ "; }
.cs-approval__why summary:hover { color: var(--textPrimary); }

@media (max-width: 720px) {
  .cs-approval__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cs-approval__head { flex-direction: column; }
  .cs-approval__head .cs-btn { align-self: flex-end; }
}

/* 6.2 移动端筛选面板：默认收起，避免首屏被四组筛选占满 */
.cs-filterbar {
  display: none;
  align-items: center; justify-content: space-between;
  gap: 12px; padding: 10px 14px; margin-bottom: 16px;
  background: var(--backgroundSecondary);
  border: 1px solid var(--border);
  border-radius: var(--Radius-300);
  font-size: var(--Font-size-text-100); color: var(--textSecondary);
}
.cs-filterbar b { color: var(--textPrimary); font-weight: 500; }
@media (max-width: 1048px) {
  .cs-filterbar { display: flex; }
  /* 文档导航和筛选侧栏不一样：筛选侧栏可以收起（有 cs-filterbar 按钮），
     文档导航收起以后手机上就再也点不到别的文档页了，所以它必须一直在。 */
  .cs-sidepanel:not(.cs-sidepanel--contents) { display: none; }
  .cs-sidepanel.is-open { display: block; margin-bottom: 16px; }
  .cs-sidepanel--contents { margin-bottom: 20px; }
}

/* 6.3 空态里的三步引导（安全中心首屏） */
.cs-wizard { padding: 24px; }
.cs-wizard__head { display: flex; align-items: flex-start; gap: 14px; }
.cs-wizard__head svg { width: 32px; height: 32px; color: var(--primary); flex: none; }
.cs-wizard__head strong { display: block; color: var(--textPrimary); font-size: var(--Font-size-text-300); font-weight: 500; }
.cs-wizard__head p { margin: 6px 0 0; color: var(--textSecondary); font-size: var(--Font-size-text-100); }
.cs-wizard__steps {
  list-style: none; margin: 20px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px;
}
.cs-wizard__steps li {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 14px; background: var(--backgroundTertiary);
  border: 1px solid var(--divider); border-radius: var(--Radius-300);
  min-width: 0;
}
.cs-wizard__steps b {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--primary08); color: var(--primary);
  display: grid; place-items: center; font-size: var(--Font-size-text-50); font-weight: 600;
}
.cs-wizard__steps strong { display: block; color: var(--textPrimary); font-size: var(--Font-size-text-200); font-weight: 500; }
.cs-wizard__steps span { display: block; margin-top: 4px; color: var(--textSecondary); font-size: var(--Font-size-text-100); line-height: 1.6; }
.cs-wizard__foot { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 20px; }
@media (max-width: 720px) {
  .cs-wizard { padding: 18px; }
  .cs-wizard__steps { grid-template-columns: minmax(0, 1fr); }
  .cs-wizard__foot .cs-btn { width: 100%; justify-content: center; }
}

/* 6.4 最近检查过的地址 */
.cs-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.cs-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px;
  background: var(--backgroundTertiary); border: 1px solid var(--divider);
  color: var(--textSecondary); font-size: var(--Font-size-text-100);
  font-family: var(--font-mono); cursor: pointer;
  transition: all .2s cubic-bezier(.16,1,.3,1);
}
.cs-chip:hover { color: var(--textPrimary); border-color: var(--borderSecondaryWhite); background: var(--backgroundSurface); }

/* 6.5 自绘复选框：原生方框在暗色底上是系统白描边 + 浏览器蓝勾，和整站不搭。
   同时覆盖 .cs-check 标签里的 input，keys/webhooks/auto-revoke 一起变。
   （.cs-check 本身是既有的「标签+复选」布局类，这里只改里面的 input，不动布局） */
.cs-cbx,
.cs-check input[type=checkbox] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px; height: 16px; flex: none;
  margin: 0;
  border: 1px solid var(--borderSecondaryWhite);
  border-radius: 4px;
  background: var(--backgroundTertiary);
  cursor: pointer;
  position: relative;
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.cs-cbx:hover, .cs-check input[type=checkbox]:hover { border-color: var(--primary); }
.cs-cbx:focus-visible, .cs-check input[type=checkbox]:focus-visible {
  outline: none; box-shadow: 0 0 0 3px var(--primary08);
}
.cs-cbx:checked, .cs-cbx:indeterminate,
.cs-check input[type=checkbox]:checked, .cs-check input[type=checkbox]:indeterminate {
  background: var(--primary); border-color: var(--primary);
}
.cs-cbx:checked::after, .cs-check input[type=checkbox]:checked::after {
  content: "";
  position: absolute; left: 4.5px; top: 1.5px;
  width: 5px; height: 9px;
  border: solid var(--Content-primary_button_text);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.cs-cbx:indeterminate::after, .cs-check input[type=checkbox]:indeterminate::after {
  content: "";
  position: absolute; left: 3px; top: 6px;
  width: 8px; height: 2px; background: var(--Content-primary_button_text); border-radius: 1px;
}
.cs-cbx:disabled, .cs-check input[type=checkbox]:disabled { opacity: .45; cursor: not-allowed; }

/* 6.6 免费工具入口（未登录时替代项目切换器） */
.cs-side__free {
  margin: 10px 12px 6px;
  padding: 8px 10px;
  display: flex; align-items: center; gap: 8px;
  border: 1px dashed var(--divider);
  border-radius: var(--Radius-300);
  background: var(--backgroundTertiary);
  color: var(--textSecondary);
  font-size: var(--Font-size-text-100);
  text-decoration: none;
  transition: border-color .2s ease, color .2s ease;
}
.cs-side__free:hover { border-color: var(--primaryTransparent); color: var(--textPrimary); }
.cs-side__free-dot {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--primary); box-shadow: 0 0 0 3px var(--primary08);
}
.cs-side__free b { color: var(--primary); font-weight: 500; }


/* 7. 代码展示容器与头部 (.cs-code-wrap, .cs-code__hd) */
.cs-code-wrap {
  background: var(--backgroundTertiary);
  border: 1px solid var(--border);
  border-radius: var(--Radius-400);
  overflow: hidden;
  box-sizing: border-box;
}

.cs-code__hd {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  background: var(--backgroundSecondary);
  border-bottom: 1px solid var(--divider);
  font-size: var(--Font-size-text-100);
  color: var(--textSecondary);
}

.cs-code-wrap pre {
  margin: 0;
  padding: 16px;
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: var(--Font-size-text-100);
  color: var(--textPrimary);
  line-height: 1.5;
}

/* 8. 步骤指示器 (.cs-steps, .cs-step) */
.cs-steps {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.cs-step {
  display: flex;
  gap: 16px;
  position: relative;
  padding-bottom: 24px;
}
.cs-step:last-child {
  padding-bottom: 0;
}

.cs-step__rail {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 24px;
  flex-shrink: 0;
}

.cs-step__dot {
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: var(--primary08);
  border: 1px solid var(--primary);
  color: var(--primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: var(--Font-size-text-50);   /* 步骤序号属装饰性标记，规范 §1.2 只允许这一档用 10px */
  font-weight: 600;
  flex-shrink: 0;
}

.cs-step__line {
  flex: 1;
  width: 2px;
  background: var(--divider);
  margin: 6px 0;
}

.cs-step__body {
  flex: 1;
  min-width: 0;
  padding-top: 2px;
}
/* 步骤标题与说明是两个相邻标签：中文靠标点就能断开，英文会粘成
   "Confirm targetVerify the contract"。标题独立成行，说明另起一行。 */
.cs-step__body > strong {
  display: block;
  margin-bottom: 2px;
}
.cs-step__body > span {
  display: block;
}

/* 9. 骨架屏占位动画 (.cs-skeleton) */
.cs-skeleton {
  background: linear-gradient(90deg, var(--backgroundSecondary) 25%, var(--backgroundSurface) 37%, var(--backgroundSecondary) 63%);
  background-size: 400% 100%;
  animation: cs-skeleton-loading 1.4s ease infinite;
  border-radius: var(--Radius-200);
}

.cs-skeleton--block {
  width: 100%;
  height: 64px;
}

.cs-skeleton--line {
  width: 100%;
  height: 16px;
}

@keyframes cs-skeleton-loading {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

/* 10. 全局暗色滚动条精致化（杜绝原生刺眼白灰色条） */
:root {
  color-scheme: dark;
}

::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--borderSecondaryWhite);
  border-radius: 999px;
  transition: background 0.2s ease;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--borderMuted);
}
* {
  scrollbar-width: thin;
  scrollbar-color: var(--borderSecondaryWhite) transparent;
}

/* =============================================================
 * ⑭ 定价页 / 营销页共用组件（G-10 / P-08）
 * -------------------------------------------------------------
 * `.cs-btn--white` 与 `.cs-planpick*` 原来只写在 console.css 里，营销页
 * pricing.html 为了用它们不得不引入整套控制台样式表，连带把「表格带底卡」
 * 这类控制台外观带进了营销页。定义搬到这里后，营销页只引
 * tokens.css + app.css 即可，外观与引入 console.css 时一致。
 * 颜色全部走 token（白底按钮用 --backgroundNegative，不用 #fff 字面量）。
 * ============================================================= */
.cs-btn--white {
  background: var(--backgroundNegative);
  color: var(--textNegative);
  border: 1px solid var(--backgroundNegative);
  font-weight: 500;
}
.cs-btn--white:hover {
  background: var(--backgroundLandingLight);
  border-color: var(--backgroundLandingLight);
  color: var(--textNegative);
}
.cs-btn--white:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.cs-planpick { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.cs-planpick__card {
  display: flex; flex-direction: column; gap: 6px; padding: 16px;
  border: 1px solid var(--border); border-radius: var(--Radius-500);
  background: var(--backgroundSecondary); min-width: 0;
}
.cs-planpick__card.is-on { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.cs-planpick__name { font-size: var(--Font-size-text-300); font-weight: 500; }
.cs-planpick__fee {
  font-family: var(--font-display);
  font-size: var(--Font-size-header-100);
  font-variant-numeric: tabular-nums;
}
.cs-planpick__meta { font-size: var(--Font-size-text-100); color: var(--textSecondary); line-height: 1.6; }
.cs-planpick__list { margin: 6px 0 0; padding-left: 16px; font-size: var(--Font-size-text-100); color: var(--textSecondary); line-height: 1.7; }
/* 套餐卡里的按钮文案长短不一（「免费开始」vs「余额不足 · 差 ¥12,948.00」），
   统一不换行，避免卡片被撑成两行按钮 */
.cs-planpick__card .cs-btn { white-space: nowrap; }
@media (max-width: 560px) {
  .cs-planpick { grid-template-columns: minmax(0, 1fr); }
}

/* =============================================================
 * ⑬ 响应式断点统一标准 (对齐 1048px / 768px / 390px 验收门禁)
 * ============================================================= */
@media (max-width: 1048px) {
  .cs-container { max-width: 100%; }
}
@media (max-width: 768px) {
  .cs-grid--2, .cs-grid--3, .cs-grid--4 { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 390px) {
  .cs-container { padding-left: 12px; padding-right: 12px; }
}

/* 手机上把宽表摊成卡片：ui.js 早就在给 .cs-table 加 cs-table--mobile-records 和
   data-label，但全站没有一条对应的样式 —— 窄屏上表还是五列横着挤，
   右边几列直接滑出屏幕，没有任何「可以左右滑」的提示。 */
@media (max-width: 640px) {
  .cs-table-wrap--mobile-records { overflow: visible; }
  .cs-table--mobile-records thead { display: none; }
  /* 宽表原来靠 inline min-width（如状态页 700px）撑出横向滚动；
     摊成卡片以后这个 min-width 会把卡片撑出屏幕，必须归零 */
  .cs-table.cs-table--mobile-records { min-width: 0 !important; width: 100%; }
  /* 两列表（状态页「组件 / 内容」这类）本来就放得下，摊成卡片反而把值挤成两截 */
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs),
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) tbody,
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) tr,
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) td { display: block; width: 100%; }
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) tr {
    border: 1px solid var(--border); border-radius: var(--Radius-300);
    background: var(--backgroundSecondary); padding: 12px 14px; margin-bottom: 10px;
  }
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) td {
    border: 0 !important; padding: 5px 0;
    display: grid; grid-template-columns: 84px minmax(0, 1fr);
    gap: 4px 10px; align-items: start; justify-items: start;
  }
  /* 徽章、按钮这类 inline 元素在 grid 单元格里会被拉满整列，这里让它们保持自身宽度 */
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) td > * { max-width: 100%; }
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) td::before {
    content: attr(data-label); color: var(--textSecondary);
    font-size: var(--Font-size-text-100); line-height: 1.6;
  }
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) td[data-label=""]::before { content: none; }
  .cs-table.cs-table--mobile-records:not(.cs-table--mobile-pairs) td[data-label=""] { grid-template-columns: minmax(0, 1fr); }
}

/* 指标卡在手机上两列排，不要一张一行堆成一屏半 */
@media (max-width: 600px) {
  .cs-grid--3:has(> .cs-kpi), .cs-grid--4:has(> .cs-kpi) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* =============================================================
 * ⑬ 活动运营（WP-160）：活动卡、倒计时、阶梯、任务清单、领取条
 * -------------------------------------------------------------
 * 只新增组件，不改既有规则；配色与圆角一律走 tokens（drpc 基线），
 * 不写死色值（门禁 F-05 会查 app.css 里的硬编码颜色）。
 * ============================================================= */

/* ---- 活动卡片封面：按类型给一条渐变带 + 图标 ----
   不塞照片：活动没有真实主图，用图库照会变成「看起来像别人的活动」。
   渐变 + 类型图标同样一眼能分出四种活动，而且中英文、任意宽度都不会错位。 */
.cs-campaign-card__cover {
  position: relative; display: flex; align-items: flex-end; justify-content: space-between;
  height: 96px; margin: -22px -22px 0; padding: 14px 18px;
  border-radius: var(--Radius-500) var(--Radius-500) 0 0;
  border-bottom: 1px solid var(--divider);
  background: linear-gradient(135deg, var(--backgroundSurface), var(--backgroundTertiary));
  overflow: hidden;
}
.cs-campaign-card__cover::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(120px 90px at 82% 18%, var(--primaryLight), transparent 70%);
  pointer-events: none;
}
.cs-campaign-card__cover .cs-icon { position: relative; z-index: 1; opacity: .9; }
.cs-campaign-card__cover--onboarding { background: linear-gradient(135deg, var(--backgroundSurface), var(--primaryLight)); }
.cs-campaign-card__cover--security_week { background: linear-gradient(135deg, var(--backgroundSurface), var(--blueMarketingLight, var(--primaryLight))); }
.cs-campaign-card__cover--usage_ladder { background: linear-gradient(135deg, var(--backgroundSurface), var(--backgroundLandingDark)); }
.cs-campaign-card__cover--topup_bonus { background: linear-gradient(135deg, var(--backgroundSurface), var(--primaryLight)); }
.cs-campaign-card__cover--referral, .cs-campaign-card__cover--migration, .cs-campaign-card__cover--hackathon {
  background: linear-gradient(135deg, var(--backgroundSurface), var(--backgroundLandingDark));
}
.cs-campaign-card__cover span { position: relative; z-index: 1; font-size: var(--Font-size-text-100); color: var(--textSecondary); letter-spacing: .02em; }

/* 卡片金额：docs/160 §5.5 要求 30px（比标题大一档，一眼看到钱） */
.cs-campaign-card__reward b { font-size: clamp(var(--Font-size-header-100), 2.2vw, 30px); }

/* 人群/门槛标签：小胶囊，和 meta 文字区分开 */
.cs-campaign-card__tags { display: flex; flex-wrap: wrap; gap: 6px; }
.cs-campaign-card__tag {
  padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border);
  font-size: var(--Font-size-text-50); color: var(--textSecondary);
}

/* 领取条吸顶：滚到条款区时按钮还在视野里（docs/160 §3.2「sticky 领取按钮」） */
.cs-claimbar {
  position: sticky; top: 0; z-index: 30;
  backdrop-filter: blur(8px);
  background: color-mix(in srgb, var(--backgroundSurface) 92%, transparent);
}
@media (max-width: 640px) {
  .cs-claimbar { position: static; }
  .cs-campaign-card__cover { height: 80px; }
}

/* ---- 精选横滑条 ---- */
.cs-feature-strip {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(260px, 300px);
  gap: 14px; overflow-x: auto; padding: 4px 2px 12px;
  scroll-snap-type: x mandatory; scrollbar-width: thin;
}
.cs-feature-strip > * { scroll-snap-align: start; }
.cs-feature-strip::-webkit-scrollbar { height: 8px; }
.cs-feature-strip::-webkit-scrollbar-thumb { background: var(--white10, var(--border)); border-radius: 999px; }

/* ---- 价值主张 3-4 格 ---- */
.cs-value-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1024px) { .cs-value-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .cs-value-grid { grid-template-columns: minmax(0, 1fr); } }
.cs-value {
  padding: 16px 18px; border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundTertiary); display: grid; gap: 6px;
}
.cs-value b { font-family: var(--font-display); font-size: var(--Font-size-text-400); color: var(--textPrimary); }
.cs-value span { font-size: var(--Font-size-text-100); color: var(--textSecondary); line-height: 1.6; }

/* ---- 社会证明 ---- */
.cs-proof {
  display: flex; flex-wrap: wrap; gap: 10px 28px; align-items: baseline;
  padding: 16px 20px; border: 1px dashed var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundTertiary);
}
.cs-proof b { font-family: var(--font-display); font-size: var(--Font-size-header-100); color: var(--primary); font-variant-numeric: tabular-nums; }
.cs-proof span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }

/* ---- 规则分块（每块右侧「查看规则」） ---- */
.cs-terms { display: grid; gap: 0; border: 1px solid var(--border); border-radius: var(--Radius-400); overflow: hidden; }
.cs-terms__row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center;
  padding: 14px 18px; border-bottom: 1px solid var(--divider); background: var(--backgroundTertiary);
}
.cs-terms__row:last-child { border-bottom: 0; }
.cs-terms__row b { font-size: var(--Font-size-text-200); color: var(--textPrimary); }
.cs-terms__row .cs-small { display: block; margin-top: 4px; color: var(--textSecondary); }
.cs-terms__row[hidden] { display: none; }
.cs-terms__body { grid-column: 1 / -1; font-size: var(--Font-size-text-100); color: var(--textSecondary); line-height: 1.75; }

/* ---- 活动卡片网格 ---- */
.cs-campaign-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 1180px) { .cs-campaign-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 768px) { .cs-campaign-grid { grid-template-columns: minmax(0, 1fr); } }

.cs-campaign-card {
  display: flex; flex-direction: column; gap: 12px;
  padding: 22px; min-width: 0;
  border: 1px solid var(--border); border-radius: var(--Radius-500);
  background: var(--backgroundSecondary);
  transition: border-color .18s ease, transform .18s ease;
}
.cs-campaign-card:hover { border-color: var(--primaryLighter); transform: translateY(-2px); }
.cs-campaign-card__hd { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.cs-campaign-card__title { font-family: var(--font-display); font-size: var(--Font-size-text-300); line-height: 1.4; margin: 0; }
.cs-campaign-card__desc { flex: 1; margin: 0; color: var(--textSecondary); font-size: var(--Font-size-text-200); line-height: 1.65; }
.cs-campaign-card__reward { display: flex; align-items: baseline; gap: 6px; font-family: var(--font-display); }
/* G-07：26px 不在 token 阶梯上（24/28 之间），用 clamp 保住「奖励数字比标题大一档」的层级 */
.cs-campaign-card__reward b { font-size: clamp(var(--Font-size-header-100), 2vw, var(--Font-size-header-200)); line-height: 1.1; color: var(--primary); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.cs-campaign-card__reward span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }
.cs-campaign-card__meta {
  display: flex; flex-wrap: wrap; gap: 4px 14px;
  font-size: var(--Font-size-text-100); color: var(--textSecondary);
}
.cs-campaign-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 2px; }

/* ---- 倒计时（只由服务端时间驱动，样式不做假动画） ---- */
.cs-countdown { display: inline-flex; align-items: center; gap: 8px; font-variant-numeric: tabular-nums; }
.cs-countdown b { font-family: var(--font-display); font-size: var(--Font-size-text-400); color: var(--primary); letter-spacing: .01em; }
.cs-countdown.is-urgent b { color: var(--coral); }
.cs-countdown.is-over b { color: var(--textSecondary); }

/* ---- 活动详情信息条：时间 + 倒计时 + 领取按钮（桌面吸顶，窄屏跟随） ---- */
.cs-claimbar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 14px 20px; border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundSurface);
}
.cs-claimbar__info { display: flex; align-items: center; gap: 10px 20px; flex-wrap: wrap; font-size: var(--Font-size-text-200); color: var(--textSecondary); }
.cs-claimbar__actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cs-claimbar__reason { font-size: var(--Font-size-text-100); color: var(--textSecondary); }

/* ---- 阶梯奖励 ---- */
.cs-tier-list { display: grid; gap: 12px; }
.cs-tier {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 14px; align-items: center;
  padding: 16px 18px; border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundTertiary);
}
.cs-tier.is-reached { border-color: var(--primaryLighter); background: var(--primaryLight); }
.cs-tier__dot {
  width: 30px; height: 30px; flex: none; border-radius: 50%;
  display: grid; place-items: center; font-size: var(--Font-size-text-100); font-weight: 600;
  background: var(--white04); color: var(--textSecondary);
}
.cs-tier.is-reached .cs-tier__dot { background: var(--primary); color: var(--background); }
.cs-tier__body { min-width: 0; }
.cs-tier__body b { display: block; font-size: var(--Font-size-text-200); color: var(--textPrimary); }
.cs-tier__body span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }
.cs-tier__amount { font-family: var(--font-display); font-size: var(--Font-size-text-400); color: var(--primary); white-space: nowrap; font-variant-numeric: tabular-nums; }
.cs-tier__amount small { font-size: var(--Font-size-text-50); color: var(--textSecondary); font-family: var(--font-sans); margin-left: 2px; }

/* ---- 任务清单（新用户引导） ---- */
.cs-tasklist { display: grid; gap: 10px; }
.cs-task {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundTertiary);
}
.cs-task.is-done { border-color: var(--primaryLighter); }
.cs-task__check {
  width: 20px; height: 20px; flex: none; margin-top: 1px; border-radius: 50%;
  display: grid; place-items: center; border: 1px solid var(--border);
  color: transparent; font-size: var(--Font-size-text-50);
}
.cs-task.is-done .cs-task__check { background: var(--primary); border-color: var(--primary); color: var(--background); }
.cs-task__body { min-width: 0; flex: 1; }
.cs-task__body b { display: block; font-size: var(--Font-size-text-200); color: var(--textPrimary); }
.cs-task__body span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }
.cs-task__amount { font-family: var(--font-display); color: var(--primary); white-space: nowrap; }

/* ---- 我的权益条（活动中心顶部，登录态才显示） ---- */
.cs-campaign-wallet {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px;
  padding: 18px 20px; border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundSecondary);
}
@media (max-width: 768px) { .cs-campaign-wallet { grid-template-columns: minmax(0, 1fr); } }
.cs-campaign-wallet__item { display: grid; gap: 4px; min-width: 0; }
.cs-campaign-wallet__item b { font-family: var(--font-display); font-size: var(--Font-size-text-500); color: var(--textPrimary); font-variant-numeric: tabular-nums; }
.cs-campaign-wallet__item span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }

/* ---- 活动筛选标签 ---- */
.cs-campaign-tabs { display: flex; gap: 8px; flex-wrap: wrap; }
.cs-campaign-tabs a, .cs-campaign-tabs button {
  padding: 8px 14px; border-radius: 999px; border: 1px solid var(--border);
  background: transparent; color: var(--textSecondary);
  font-size: var(--Font-size-text-200); cursor: pointer;
}
.cs-campaign-tabs a.is-active, .cs-campaign-tabs button.is-active {
  border-color: var(--primaryLighter); background: var(--primaryLight); color: var(--primary);
}

/* =============================================================
 * ⑭ 全站补齐：UI 审计查出的「类名在用但没有定义」
 * -------------------------------------------------------------
 * 这三类此前在 15 个页面里被引用、样式表里却查不到定义，表现为
 * 「登录页的隐私说明是裸文字」「撤销五步看不出进度」「行内代码和正文一样」。
 * ============================================================= */

/* 说明条：一段带左侧强调线的提示（活动页、登录页、法律页都在用） */
.cs-note {
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: var(--Radius-300);
  background: var(--backgroundTertiary);
  color: var(--textSecondary);
  font-size: var(--Font-size-text-200);
  line-height: 1.75;
}
.cs-note b, .cs-note strong { color: var(--textPrimary); }
.cs-note ol, .cs-note ul { margin: 0; }

/* 行内代码：地址、方法名、参数值 —— 必须能和正文区分开，长串要能断行 */
.cs-code--inline {
  display: inline;
  padding: 1px 6px;
  border-radius: var(--Radius-200);
  background: var(--white04);
  border: 1px solid var(--divider);
  color: var(--textPrimary);
  font-family: var(--font-mono);
  font-size: .92em;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* 步骤条状态：撤销工作台与文档页会切换 is-done / is-active，之前没有对应样式 */
.cs-step.is-done .cs-step__dot {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--background);
}
.cs-step.is-done .cs-step__line { background: var(--primaryLighter); }
.cs-step.is-active .cs-step__dot {
  background: var(--primaryLight);
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primaryTransparent);
}
.cs-step.is-active .cs-step__body > strong { color: var(--textPrimary); }

/* 页内锚点：顶部导航是 sticky 的，之前锚点跳转后标题被压在导航下面 */
[id] { scroll-margin-top: calc(var(--landing-header-height-desktop) + 16px); }
@media (max-width: 768px) { [id] { scroll-margin-top: 72px; } }

/* =============================================================
 * ⑮ 活动页视觉强化（硬规矩 C：必须好看）
 * -------------------------------------------------------------
 * ⑬ 段只做到"能用"，这一层负责"好看"：
 *   · 活动中心要有主推位（否则一屏四张同权重卡片，像后台列表）
 *   · 奖励数字是主角，必须明显大于说明文字
 *   · 卡片底部对齐、按钮全宽、悬停有反馈
 * ============================================================= */

/* ---- 主推活动大卡（活动中心首屏焦点） ---- */
.cs-campaign-hero {
  position: relative; overflow: hidden;
  display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 28px; align-items: center;
  padding: 32px 34px;
  border: 1px solid var(--primaryTransparent);
  border-radius: var(--Radius-500);
  background:
    radial-gradient(120% 140% at 100% 0%, var(--primaryLight) 0%, transparent 58%),
    var(--backgroundSecondary);
}
/* 右侧一层极淡的品牌光晕，让主推卡"亮"起来但不抢文字 */
.cs-campaign-hero::after {
  content: ''; position: absolute; right: -80px; top: -80px;
  width: 320px; height: 320px; border-radius: 50%;
  background: radial-gradient(circle, var(--primaryTransparent) 0%, transparent 68%);
  pointer-events: none;
}
.cs-campaign-hero__main { position: relative; z-index: 1; min-width: 0; }
.cs-campaign-hero__eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: var(--Font-size-text-100); color: var(--primary);
  letter-spacing: .06em; text-transform: uppercase;
}
.cs-campaign-hero h2 {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(24px, 2.6vw, 34px); line-height: 1.25;
  margin: 12px 0 10px; color: var(--textPrimary);
}
.cs-campaign-hero p { margin: 0 0 20px; color: var(--textSecondary); font-size: var(--Font-size-text-300); line-height: 1.7; max-width: 56ch; }
.cs-campaign-hero__side {
  position: relative; z-index: 1; display: grid; gap: 18px;
  padding-left: 26px; border-left: 1px solid var(--divider); min-width: 0;
}
.cs-campaign-hero__reward { display: grid; gap: 4px; }
.cs-campaign-hero__reward b {
  font-family: var(--font-display); font-weight: 500;
  font-size: clamp(38px, 4.6vw, 58px); line-height: 1; letter-spacing: -.03em;
  color: var(--primary); font-variant-numeric: tabular-nums;
}
.cs-campaign-hero__reward span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }
.cs-campaign-hero__meta { display: grid; gap: 6px; font-size: var(--Font-size-text-100); color: var(--textSecondary); font-variant-numeric: tabular-nums; }
.cs-campaign-hero__meta b { color: var(--textPrimary); font-family: var(--font-display); font-size: var(--Font-size-text-300); }
@media (max-width: 900px) {
  .cs-campaign-hero { grid-template-columns: minmax(0, 1fr); padding: 24px 22px; gap: 20px; }
  .cs-campaign-hero__side { padding-left: 0; padding-top: 18px; border-left: 0; border-top: 1px solid var(--divider); }
}

/* ---- 卡片升级：类型图标 + 更大奖励 + 全宽按钮 + 底部对齐 ---- */
.cs-campaign-card { padding: 20px; gap: 13px; }
.cs-campaign-card__head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cs-campaign-card__icon {
  width: 36px; height: 36px; flex: none; border-radius: var(--Radius-300);
  display: grid; place-items: center;
  background: var(--primaryLight); color: var(--primary);
}
.cs-campaign-card__badges { display: flex; align-items: center; gap: 6px; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
.cs-campaign-card__title { font-size: var(--Font-size-text-300); margin: 0; }
.cs-campaign-card__desc { font-size: var(--Font-size-text-100); line-height: 1.65; }
.cs-campaign-card__reward b { letter-spacing: -.02em; }   /* 字号见上一条 clamp，避免两处打架 */
.cs-campaign-card__reward span { font-size: var(--Font-size-text-50); }
.cs-campaign-card__foot { gap: 8px; }
.cs-campaign-card__foot .cs-btn { flex: 1; justify-content: center; }
.cs-campaign-card__foot .cs-small { flex: none; }

/* ---- 筛选：分段控件（比一排裸按钮更像一个整体） ---- */
.cs-campaign-tabs {
  display: inline-flex; gap: 2px; padding: 4px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--backgroundSecondary);
}
.cs-campaign-tabs button { border: 0; background: transparent; padding: 7px 16px; border-radius: 999px; }
.cs-campaign-tabs button:hover { color: var(--textPrimary); }
.cs-campaign-tabs button.is-active { background: var(--primaryLight); color: var(--primary); }
@media (max-width: 560px) {
  .cs-campaign-tabs { width: 100%; overflow-x: auto; }
  .cs-campaign-tabs button { flex: none; padding: 7px 13px; }
}

/* ---- 我的权益：三个独立数字卡（跟控制台 KPI 同构） ---- */
.cs-campaign-wallet { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; padding: 0; border: 0; background: none; }
.cs-campaign-wallet__item {
  padding: 16px 18px; border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundSecondary); display: grid; gap: 4px;
}
.cs-campaign-wallet__item b { font-size: clamp(var(--Font-size-header-100), 2vw, var(--Font-size-header-200)); font-family: var(--font-display); font-variant-numeric: tabular-nums; }
.cs-campaign-wallet__item span { font-size: var(--Font-size-text-100); color: var(--textSecondary); }

/* ---- 详情页：进度卡与阶梯的视觉重量 ---- */
.cs-campaign-progress {
  display: grid; gap: 10px; padding: 20px 22px;
  border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundSecondary);
}
.cs-campaign-progress__hd { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.cs-campaign-progress__pct { font-family: var(--font-display); font-size: var(--Font-size-header-200); color: var(--primary); line-height: 1; font-variant-numeric: tabular-nums; }
.cs-campaign-progress .cs-progress { height: 8px; }

.cs-tier { padding: 18px 20px; gap: 16px; }
.cs-tier__dot { width: 34px; height: 34px; font-size: var(--Font-size-text-100); }
.cs-tier__amount { font-size: var(--Font-size-header-100); }
.cs-tier__amount small { font-size: var(--Font-size-text-50); display: block; margin: 2px 0 0; }

.cs-task { padding: 16px 18px; }
.cs-task__amount { font-size: var(--Font-size-text-400); }

/* 【≤640px：所有 hero 变体统一 36px】原来这里把 h1 压到 28–34px，于是同一个站点
   在 390px 下「大标题」出现第三档尺寸（G-13）。现在统一到规范 §2.8 的移动端 36px，
   并且把两栏 hero 的 40px 分支也拉回 36px —— 40px 时 390 宽度下
   「Wallet sign-in,」会被连字符折成「Wallet sign-」/「in,」，读起来像断字错字
   （实测 36px 能整词放下，仍是两行，视觉重量足够）。 */
@media (max-width: 640px) {
  .cs-hero h1, .cs-h1, .cs-hero__inner--split h1 {
    font-size: var(--Font-size-header-400);   /* 36px = 规范 §2.8 的移动端 H1 档 */
    line-height: 1.1;
  }
}

/* ---- 详情页细节：任务金额是"钱"，要够显眼；长文本限宽，避免一行扫不完 ---- */
.cs-task__amount {
  font-family: var(--font-display);
  font-size: var(--Font-size-text-400);
  font-variant-numeric: tabular-nums;
  min-width: 56px; text-align: right;
}
.cs-task.is-done .cs-task__amount { color: var(--textSecondary); font-size: var(--Font-size-text-200); }
/* 规则与说明段落限宽：英文一行超过 90 字符就很难读，中文超过 40 字同样 */
#campaignDetail .cs-note, #campaignDetail .cs-card > p { max-width: 78ch; }
#campaignDetail .cs-h1 { font-size: clamp(26px, 3.2vw, 40px); line-height: 1.2; }
@media (max-width: 640px) {
  /* 26px 不在 token 阶梯上：用 clamp 落在 24（text 最大档）与 28（header-200）之间 */
  #campaignDetail .cs-h1 { font-size: clamp(var(--Font-size-header-100), 6.6vw, var(--Font-size-header-200)); }
  .cs-claimbar { padding: 14px 16px; }
  .cs-claimbar__actions, .cs-claimbar__actions .cs-btn { width: 100%; }
  .cs-claimbar__actions .cs-btn { justify-content: center; }
}

/* ===========================================================================
 * ⑯ 移动端间距收敛（G-08）
 * ---------------------------------------------------------------------------
 * --cs-section-y 是 96px、.cs-hero 上方 120px，两处原来都没有移动端覆盖：
 * 390×844 下 57px 导航 + 120px 上间距 = 首屏 21% 是空白，相邻两个 .cs-section
 * 之间 192px（半屏），手机上一屏只放得下一个区块。
 * 这里按 768 / 560 / 390 三档收；数值仍走 token（只在媒体查询里重写
 * --cs-section-y，tokens.css 不动）。
 * =========================================================================== */
@media (max-width: 768px) {
  :root { --cs-section-y: 56px; }
  .cs-hero { padding-top: 64px; padding-bottom: 40px; }
  .cs-hero--center { padding-bottom: 36px; }
  .cs-section--tight { padding-top: 40px; padding-bottom: 40px; }
  .cs-section-head { margin-bottom: 28px; }
}
@media (max-width: 560px) {
  :root { --cs-section-y: 48px; }
  .cs-hero { padding-top: 48px; padding-bottom: 32px; }
  .cs-hero--center { padding-bottom: 28px; }
  .cs-section--tight { padding-top: 32px; padding-bottom: 32px; }
  .cs-section-head { margin-bottom: 22px; }
}
@media (max-width: 390px) {
  :root { --cs-section-y: 44px; }
  .cs-hero { padding-top: 40px; padding-bottom: 28px; }
}

/* ---------------------------------------------------------------------------
 * [hidden] 必须真的隐藏
 * 组件类（.cs-alert / .cs-card 等）都设了 display，会覆盖浏览器默认的
 * [hidden]{display:none}，于是「隐藏的错误提示」在页面上留一个空框。
 * 上面那些 .cs-xxx[hidden] 是逐个补的；这里统一兜一层，新组件不必再补。
 * ------------------------------------------------------------------------- */
[hidden] { display: none !important; }

/* ---------------------- 通知铃铛（控制台顶栏） ---------------------- */
.cs-bell {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; flex: none;
  border: 1px solid var(--border); border-radius: var(--Radius-300);
  background: transparent; color: var(--text-secondary); cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.cs-bell:hover { background: var(--backgroundSurface); color: var(--text-primary); }
.cs-bell:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.cs-bell__dot {
  position: absolute; top: -6px; right: -6px; min-width: 16px; height: 16px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; background: var(--primary); color: var(--Content-primary_button_text);
  font-family: var(--font-display); font-size: 10px; font-weight: 700; line-height: 1;
}
.cs-bell__panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  width: min(360px, calc(100vw - 32px));
  border: 1px solid var(--border); border-radius: var(--Radius-400);
  background: var(--backgroundSecondary); box-shadow: 0 16px 40px rgba(0,0,0,.45);
  overflow: hidden;
}
.cs-bell__hd {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 10px 12px; border-bottom: 1px solid var(--divider);
}
.cs-bell__list { list-style: none; margin: 0; padding: 0; max-height: 360px; overflow-y: auto; }
.cs-bell__item { padding: 10px 12px; border-bottom: 1px solid var(--divider); cursor: pointer; }
.cs-bell__item:last-child { border-bottom: 0; }
.cs-bell__item:hover { background: var(--backgroundSurface); }
.cs-bell__item.is-unread { box-shadow: inset 3px 0 0 var(--primary); }
.cs-bell__title { font-size: var(--Font-size-text-100); font-weight: 600; color: var(--text-primary); }
.cs-bell__body { margin-top: 4px; font-size: var(--Font-size-text-50); color: var(--text-tertiary); line-height: 1.5; }
.cs-bell__meta { margin-top: 4px; font-size: var(--Font-size-text-50); color: var(--text-tertiary); }
.cs-bell__empty { margin: 0; padding: 16px 12px; font-size: var(--Font-size-text-100); color: var(--text-tertiary); }
@media (max-width: 560px) {
  .cs-bell__panel { position: fixed; top: auto; bottom: 12px; left: 12px; right: 12px; width: auto; }
}

/* 浮层挂 body 后需要自己限制高度并可滚动：否则长标题在窄屏会把按钮顶出屏幕 */
.cs-bell__panel { max-height: min(70vh, 420px); display: flex; flex-direction: column; }
@media (max-width: 560px) {
  .cs-bell__panel { top: auto !important; right: 12px; left: 12px; bottom: 12px; width: auto; }
}

/* 行内定位会压过媒体查询：窄屏必须 !important 才能落成底部抽屉 */
@media (max-width: 560px) {
  .cs-bell__panel { left: 12px !important; right: 12px !important; bottom: 12px; width: auto; }
}

/* 窄屏顶栏：文档与官网在侧边菜单里都有入口，顶栏这两颗按钮先让位给「通知 / 语言 / 退出」，
   否则右侧一组会折成两行，把首屏往下推一屏（真机 390 截图确认过）。 */
@media (max-width: 560px) {
  .cs-topbar__right > a.cs-btn--ghost[href*="pages/docs/"],
  .cs-topbar__right > a.cs-btn--ghost[href$="index.html"] { display: none; }
  .cs-topbar__right { gap: 6px; }
}


/* =====================================================================
 * ⑭ 从页面收编的公共组件（审计 D-05 / impl-ui-pages 请求 §5）
 * ---------------------------------------------------------------------
 * 这三组样式此前各在页面内联 <style> 里抄了一份（security/app.html、login.html、
 * docs/index.html）。同一个旋转环三个名字、三种关键帧，改一个忘两个 ——
 * 收进公共表后页面只留"这页特有的部分"，不再各养一套。
 * ===================================================================== */

/* 加载环：16px、0.8s 一圈；系统要求减动效时改为呼吸而不是彻底静止（静止＝看不出在跑） */
@keyframes cs-spin { to { transform: rotate(360deg); } }
@keyframes cs-spin-pulse { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
.cs-loading { display: inline-flex; align-items: center; gap: 10px; }
.cs-spinner {
  display: inline-block; flex: none;
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--border);
  border-top-color: var(--primary);
  animation: cs-spin .8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .cs-spinner { animation: cs-spin-pulse 1.2s ease-in-out infinite; }
}

/* 风险三段条：高=珊瑚、中=黄、低=绿，与徽章颜色一一对应 */
.cs-riskbar {
  display: flex; width: 100%; height: 10px; overflow: hidden;
  border-radius: 999px; background: var(--backgroundSecondary);
  border: 1px solid var(--border);
}
.cs-riskbar i { display: block; height: 100%; transition: width .3s ease; }
.cs-riskbar i:nth-child(1) { background: var(--coral); }
.cs-riskbar i:nth-child(2) { background: var(--lightYellow); }
.cs-riskbar i:nth-child(3) { background: var(--primary); }

/* 筛选侧栏里的链接：与同容器里的 button 必须是同一套观感（此前 a 是裸文字） */
.cs-filter-list > a {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; padding: 8px 12px; box-sizing: border-box;
  border-radius: var(--Radius-200);
  background: var(--backgroundTertiary);
  border: 1px solid var(--divider);
  color: var(--textSecondary);
  font-size: var(--Font-size-text-100);
  text-align: left;
  transition: background .2s cubic-bezier(0.16, 1, 0.3, 1), color .2s, border-color .2s;
}
.cs-filter-list > a:hover {
  background: var(--backgroundSurface);
  color: var(--textPrimary);
  border-color: var(--borderSecondaryWhite);
}
.cs-filter-list > a[aria-current="page"] {
  background: var(--primary08);
  border-color: var(--primaryLight);
  color: var(--primary);
  font-size: var(--Font-size-text-200);
}

/* 点击目标：≤560px 时小按钮低于 40px 的手指友好下限（审计 D-06） */
@media (max-width: 560px) {
  .cs-btn--sm { height: 40px; padding: 0 14px; }
}
@media (prefers-reduced-motion: reduce) {
  /* 动画停住后 track 仍是 width:max-content，后半段永远滚不出来 */
  .cs-logos__track { animation: none; flex-wrap: wrap; width: auto; transform: none; }
}
