/* ============ 激浪 · 速度定制版 · 应用内样式（登录后加载） ============ */
a:hover { text-decoration: underline; }
input, select, button, textarea { font-family: var(--font); }
.brand-name {
  display: inline-block;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--ink);
}
/* 侧边栏 logo：后台 logo 可能是方形图标也可能是横版字标，
   统一用限高 + contain 等比缩放（不能再用固定 38x38 的 cover，会把字标裁成一竖条）；
   传了 logo 就不再显示旁边的站名文字，避免「激浪速度」出现两遍
   宽度铺满侧边栏内容区（240-28=212px），与下方菜单项、分隔线左右对齐 */
.sidebar-logo-img {
  width: 100%;
  height: auto;
  max-width: 100%;
  border-radius: 10px;
  object-fit: contain;
  flex: 0 0 auto;
  display: block;
}
.sidebar {
  width: 240px;
  background: #fafdfb;
  border-right: 1px solid rgba(20, 32, 27, 0.06);
  padding: 24px 14px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}
.sidebar .logo {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 0 20px;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 16px;
}
.sidebar .logo-text { font-weight: 750; font-size: 20px; letter-spacing: -0.02em; }
.sidebar .nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 14px;
  border-radius: 10px;
  /* 15px / 500：14px/400 在 240px 侧栏里偏轻——文字只占约 60px，右边大片空白，字却压得小；
     汉字笔画密，同字号下比拉丁字母更糊，所以字重也提到 500。
     line-height 必须显式锁成 20px：行高本来是 20px 图标盒撑起来的
     （20 + 上下 22 padding + 2 透明边框 = 44），一旦让文字自己撑行高，
     15px × 默认行距会把 44px 顶到 48px，10 个菜单项就白白多占 40px。
     15px 不在内容区的 5 级表（12/14/16/20/28）里，属于侧栏专用档：
     固定宽度、短标签、需要更强的可点性，和内容区不是同一类语境。 */
  font-size: 15px;
  font-weight: 500;
  line-height: 20px;
  /* 比 --muted(#5a6b62) 深一档：9 个未激活项 + 4 个分组标签 + 退出登录原本全是同一个
     muted 灰，导航整体发虚、扫描时没有锚点，汉字笔画密时尤其糊。
     加深到 #45564d（7.6:1）后菜单项变实，而分组标签仍用 --muted，
     靠色差自然退到后面——层级比继续调标签字重更有效。
     激活态 .nav-item.active 的 #1a3324 特异性更高，不受这里影响。 */
  color: #45564d;
  cursor: pointer;
  transition: all 0.18s ease;
  text-decoration: none;
  border: 1px solid transparent;
}
.sidebar .nav-item:hover {
  background: rgba(47, 92, 58, 0.06);
  color: var(--ink);
}
.sidebar .nav-item.active {
  background: linear-gradient(90deg, #e8f2eb, #f3f8f4);
  color: #1a3324;
  border-color: transparent;
  box-shadow: inset 3px 0 0 var(--accent);
  font-weight: 650;
}
.sidebar .nav-icon {
  width: 20px; height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  transition: transform 0.18s;
}
.sidebar .nav-item:hover .nav-icon { transform: scale(1.08); }
.sidebar .nav-icon svg { width: 18px; height: 18px; }
/* 分组标签是中文（订阅 / 财务 / 用户 / 支持），原先那条规则是从英文小标题模板抄来的：
   text-transform: uppercase 对中文是无效声明，letter-spacing: 0.06em 则会把两个汉字
   撑开到 0.72px 字距，和下方菜单项的节奏对不上。字重也从 600 降到 500——
   标签要比菜单项往后退，而不是靠更粗的字重抢在前面。 */
.sidebar .nav-label {
  font-size: 12px;
  color: var(--muted);
  padding: 16px 14px 6px;
  letter-spacing: 0.01em;
  font-weight: 500;
}
/* 导航角标（U 方案）：红底直角小方块，只给「购买订阅 / 我的邀请」两处引导入口用。
   有底色之后对比度不再是问题——白字压 #c4232a 是 5.79:1，够 AA；
   真正的风险是汉字在小屏 1x 下笔画会糊，所以字重拉到 700，字号用 11px
   （10px 在 1x 屏幕上笔画贴着实心边缘，11px 明显更清楚）。
   只放文案、不加箭头：11px 下的 › 会缩成一条细线，反而脏。
   margin-left:auto 负责把角标推到行尾：菜单项是 flex 容器，标签文字是匿名 flex item，
   用 auto 外边距就能贴到右边缘，不必给文字再包一层 span。 */
.sidebar .nav-badge {
  flex: none;
  margin-left: auto;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  background: var(--nav-badge-bg, #c4232a);
  padding: 3px 6px;
  border-radius: 2px;
  white-space: nowrap;
}
/* 两个角标各用一种颜色：热销=红（热），返利=琥珀（钱）。
   同色会让人以为是同一类提示，分开之后一眼能区分；两色都在暖色系内，
   不会像凭空插进来的第二套调色板。琥珀 #b45309 白字对比度 5.02:1，过 AA。 */
.sidebar .nav-item[data-page="invite"] .nav-badge { --nav-badge-bg: #b45309; }
.sidebar-foot { margin-top: auto; border-top: 1px solid var(--rule); padding-top: 10px; }
/* ============ 页脚 ============ */
.app-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  flex-wrap: wrap;
  margin-top: 32px;
  padding: 18px 2px 4px;
  border-top: 1px solid var(--rule);
  font-size: 12px;
  color: var(--muted);
}
.app-foot .foot-links { display: inline-flex; align-items: center; gap: 8px; }
.app-foot .foot-dot { color: rgba(90, 107, 98, 0.4); }
@media (max-width: 600px) {
.app-foot { justify-content: center; text-align: center; }
}
.main {
  flex: 1;
  /* 纵向 flex：让 .page.active 吃掉剩余高度，页脚被顶到容器底部。
     原来 .main 是普通块级容器，页脚只是跟在内容后面，
     内容少的页面（工单/订单/节点…）页脚会悬在屏幕中间，下方留一大片空白。 */
  display: flex;
  flex-direction: column;
  padding: 28px 32px 40px;
  max-width: 1240px;
  margin: 0 auto;
  width: 100%;
}
/* 当前页撑满剩余空间，页脚自然贴底；内容超长时 flex-grow 不生效，行为与原来一致。
   flex-basis:auto + flex-shrink:0 保证长内容不会被压缩。 */
.main > .page.active { flex: 1 0 auto; }
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 26px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--rule);
}
.topbar-right { display: flex; align-items: center; gap: 14px; }
.breadcrumb { font-size: 13px; color: var(--muted); }
.breadcrumb b { color: var(--ink); font-weight: 600; }
.user-chip {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 6px 14px 6px 6px;
  background: var(--bg3);
  border-radius: 24px;
  border: 1px solid var(--rule);
  font-size: 13px;
  color: var(--ink);
  font-weight: 500;
}
/* 名称位显示完整邮箱，长邮箱自动省略，避免撑破胶囊 */
.user-chip #user-email {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.avatar {
  width: 28px; height: 28px;
  border-radius: 50%;
  background: linear-gradient(145deg, #3a6b47, #1e3d28);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  box-shadow: 0 2px 8px rgba(30, 61, 40, 0.2);
}
/* ============ 卡片 ============ */
.card {
  background: var(--bg2);
  border: 1px solid rgba(20, 32, 27, 0.06);
  border-radius: var(--radius);
  padding: 22px;
  box-shadow: var(--shadow-card);
}
.section-title {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.35;
  margin-bottom: 14px;
  margin-top: 4px;
  letter-spacing: -0.01em;
}
.section-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 4px;
  margin-bottom: 14px;
}
.section-title-row .section-title { margin: 0; }
.section-title-actions { display: flex; gap: 8px; }
.qr-sub-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.qr-sub-tab {
  flex: 1 1 calc(33.333% - 6px);
  min-width: 0;
  padding: 8px 4px;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: all 0.18s;
}
.qr-sub-tab.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
.qr-sub-body { text-align: center; }
.qr-sub-box {
  display: inline-block;
  padding: 14px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  background: var(--bg2);
  margin-bottom: 12px;
  box-shadow: 0 4px 16px rgba(20, 32, 27, 0.04);
}
.qr-sub-box img, .qr-sub-box canvas { display: block; }
.qr-sub-link {
  font-size: 12px;
  color: var(--muted);
  word-break: break-all;
  margin-bottom: 12px;
  background: var(--bg3);
  padding: 10px 12px;
  border-radius: 10px;
  text-align: left;
}
/* 默认隐藏，只有当前页显示：避免首屏渲染时各页内容同时可见 */
.page { display: none; }
.page.active { display: block; }
.page-title { font-size: 20px; margin-bottom: 18px; font-weight: 700; letter-spacing: -0.02em; }
.page-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
.page-header h3 { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.filter-bar { display: flex; align-items: center; gap: 8px; }
.filter-sep { color: var(--muted); font-size: 13px; }
/* 页面级说明文案（如流量明细仅返回本月数据） */
.page-hint { color: var(--muted); font-size: 12.5px; margin: -6px 0 16px; }
.input-sm {
  padding: 8px 12px;
  font-size: 13px;
  background: var(--bg3);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  color: var(--ink);
  outline: none;
}
.input-sm:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(47, 92, 58, 0.12); }
.card-desc { font-size: 13px; color: var(--muted); margin-bottom: 16px; line-height: 1.7; }
.empty-tip { color: var(--muted); font-size: 13px; text-align: center; padding: 36px 0; }
/* ============ 仪表盘 ============ */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  margin-bottom: 24px;
}
.stat-card {
  background: var(--bg2);
  border: 1px solid rgba(20, 32, 27, 0.06);
  border-radius: var(--radius);
  padding: 22px 22px 20px;
  box-shadow: var(--shadow-card);
  transition: transform 0.22s ease, box-shadow 0.22s ease;
  /* 常驻合成层：hover 进出时不再反复提升/回收图层，避免 34px 大字重新栅格化造成"卡一下" */
  will-change: transform;
}
.stat-card:hover {
  transform: translateY(-2px);
  /* 模糊半径与静止态保持 28px 不变，浏览器可复用已缓存的阴影遮罩，
     只改偏移与透明度，避免逐帧重新生成 40px 大模糊阴影（掉帧主因） */
  box-shadow: 0 20px 28px rgba(20, 32, 27, 0.08);
}
.stat-card .label {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 8px;
  font-weight: 500;
  letter-spacing: 0.02em;
}
.stat-card .value {
  font-size: 34px;
  font-weight: 750;
  letter-spacing: -0.03em;
  line-height: 1.15;
  color: var(--ink);
}
.stat-card .value .vunit {
  font-size: 14px;
  color: var(--muted);
  font-weight: 500;
  letter-spacing: 0;
}
.stat-card .sub {
  font-size: 13px;
  color: var(--muted);
  margin-top: 8px;
  line-height: 1.5;
}
/* 卡片右上角快捷入口：与「已用流量」的重置入口同风格，不增加卡片高度 */
.stat-links { display: flex; align-items: center; justify-content: flex-end; gap: 2px; flex-wrap: wrap; }
.stat-link {
  border: 0;
  background: none;
  border-radius: 6px;
  padding: 3px 6px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--accent);
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.18s;
}
.stat-link:hover { background: var(--accent-soft); }
/* 纯图标入口：方形贴合、图标垂直居中 */
.stat-link-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 4px 6px;
}
.stat-link-ico svg { display: block; }
/* 到期日同一行内的剩余天数着色 */
.stat-card .sub .days-ok { color: var(--accent); font-weight: 600; }
.stat-card .sub .days-warn { color: var(--warning); font-weight: 600; }
.stat-card .sub .days-danger { color: var(--danger); font-weight: 600; }
/* 余额卡片：「已邀请 N 人」小药丸标签（accent 配色），让数字从灰色信息里跳出来 */
.stat-card .sub .inv-count {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 1px 8px;
  border-radius: 99px;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  font-size: 12px;
  line-height: 1.45;
  letter-spacing: 0.01em;
  vertical-align: 1px;
}
/* 卡片数字统一 accent 着色：佣金金额走这一套 */
.stat-card .sub .num-on { color: var(--accent); font-weight: 600; }
.usage-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
}
.usage-bar {
  flex: 1;
  min-width: 0;
  height: 6px;
  background: rgba(20, 32, 27, 0.07);
  border-radius: 99px;
  overflow: hidden;
}
.usage-fill {
  height: 100%;
  background: linear-gradient(90deg, #2f5c3a, #4a8a5c);
  border-radius: 99px;
  transition: width 0.6s ease;
  box-shadow: 0 0 12px rgba(47, 92, 58, 0.35);
}
.usage-fill.warn { background: linear-gradient(90deg, #b45309, #d97706); box-shadow: 0 0 12px rgba(180, 83, 9, 0.32); }
.usage-fill.danger { background: linear-gradient(90deg, #a01c22, #c4232a); box-shadow: 0 0 12px rgba(196, 35, 42, 0.32); }
.usage-pct {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 650;
  color: var(--muted);
  white-space: nowrap;
}
.usage-pct.warn { color: var(--warning); }
.usage-pct.danger { color: var(--danger); }
/* ============ 我的订阅 ============ */
.sub-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 8px;
}
/* 订阅说明脚注：解释「节点齐全」徽标与节点数差异，避免被当成故障 */
.sub-note {
  margin-top: 10px;
  font-size: 12px;
  line-height: 1.7;
  color: var(--muted);
}
.sub-row {
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--bg2);
  border: 1px solid rgba(20, 32, 27, 0.06);
  border-radius: var(--radius-sm);
  padding: 16px 20px;
  box-shadow: var(--shadow-card);
  /* 原来 transition: all 会连带插值所有变动属性，收敛成只过渡会变的三个 */
  transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
  /* 常驻合成层：hover 进出不再反复提升/回收图层，避免内容重新栅格化造成"卡一下" */
  will-change: transform;
}
.sub-row:hover {
  border-color: rgba(47, 92, 58, 0.22);
  /* 模糊半径与静止态保持 28px 不变（原来 40px），可复用已缓存的阴影遮罩，避免逐帧重算大模糊 */
  box-shadow: 0 20px 28px rgba(20, 32, 27, 0.08);
  transform: translateY(-2px);
}
/* 说明：原 .sub-row:has(.btn-import:hover) 会在鼠标移到行内「导入」按钮时把抬升撤销，
   而行一落一抬会让按钮跟着移动，指针正好落在按钮上边缘附近时状态反复翻转（抖动）。
   现在统一由 .sub-row:hover 处理，与行内「复制」按钮行为一致。 */
.sub-icon {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 17px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.sub-icon svg { width: 24px; height: 24px; display: block; }
.sub-icon .sub-logo { width: 36px; height: 36px; border-radius: 10px; object-fit: cover; display: block; }
/* 旧版客户端入口：同款图标降饱和处理，视觉上区分「兼容保留」与「主推」 */
.sub-icon .sub-logo-muted { filter: grayscale(1); opacity: 0.72; }
.sub-info { flex: 1; min-width: 0; }
.sub-name { font-size: 15px; font-weight: 650; color: var(--ink); line-height: 1.4; }
/* 「全协议」标识：标出能下发全部节点类型的格式，和只支持部分协议的旧客户端区分开 */
.sub-badge {
  display: inline-block;
  margin-left: 7px;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--success);
  background: rgba(35, 122, 62, 0.1);
  border-radius: 6px;
  vertical-align: 1px;
  white-space: nowrap;
}
.sub-desc { font-size: 13px; color: var(--muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sub-row .btn-copy[disabled],
.sub-row .btn-import[disabled] { opacity: 0.5; cursor: not-allowed; }
.sub-actions { display: flex; gap: 8px; flex: none; }
.dash-banner {
  background: var(--bg2);
  border: 1px solid rgba(47, 92, 58, 0.18);
  border-radius: var(--radius-sm);
  padding: 16px 20px;
  margin-bottom: 20px;
  font-size: 13px;
  line-height: 1.7;
  box-shadow: 0 4px 16px rgba(47, 92, 58, 0.05);
}
.dash-banner.accent {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  background: linear-gradient(135deg, var(--accent-soft) 0%, #fbfdfb 100%);
  border-color: rgba(47, 92, 58, 0.35);
  font-size: 14px;
  font-weight: 650;
  color: var(--ink);
  line-height: 1.6;
  box-shadow: 0 10px 26px rgba(47, 92, 58, 0.14);
}
.dash-banner.accent.warn {
  background: linear-gradient(135deg, #fdf4e8 0%, #fffbf4 100%);
  border-color: rgba(180, 83, 9, 0.45);
  box-shadow: 0 10px 26px rgba(180, 83, 9, 0.14);
}
.dash-banner.accent.danger {
  background: linear-gradient(135deg, #fdf0f0 0%, #fffafa 100%);
  border-color: rgba(196, 35, 42, 0.45);
  box-shadow: 0 10px 26px rgba(196, 35, 42, 0.13);
}
.dash-banner.accent.muted {
  background: linear-gradient(135deg, #f4f6f5 0%, #fcfdfc 100%);
  border-color: rgba(20, 32, 27, 0.22);
  box-shadow: 0 8px 20px rgba(20, 32, 27, 0.07);
}
.dash-banner-ico {
  flex: 0 0 36px;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(30, 61, 40, 0.25);
}
.dash-banner.accent.warn .dash-banner-ico {
  background: linear-gradient(145deg, #c96a10, var(--warning));
  box-shadow: 0 4px 12px rgba(180, 83, 9, 0.32);
}
.dash-banner.accent.danger .dash-banner-ico {
  background: linear-gradient(145deg, #d8323a, var(--danger));
  box-shadow: 0 4px 12px rgba(196, 35, 42, 0.3);
}
.dash-banner.accent.muted .dash-banner-ico {
  background: #e9eceb;
  color: var(--ink);
  box-shadow: none;
}
.dash-banner-text { flex: 1; min-width: 180px; }
.dash-banner.accent .btn { text-decoration: none; white-space: nowrap; }
.dash-banner.accent .btn:hover { text-decoration: none; }
/* ============ 仪表盘顶部品牌条 ============ */
.dash-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 20px 24px;
  border-radius: var(--radius);
  background: linear-gradient(135deg, #3a6b47 0%, var(--accent2) 100%);
  color: #fff;
  margin-bottom: 18px;
  box-shadow: 0 16px 34px rgba(30, 61, 40, 0.22);
  position: relative;
  overflow: hidden;
}
.dash-hero::after {
  content: "";
  position: absolute;
  right: -60px;
  top: -70px;
  width: 220px;
  height: 220px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.16), transparent 65%);
  pointer-events: none;
}
.dash-hero-main { position: relative; min-width: 0; }
.dash-hero-greet { display: flex; align-items: baseline; flex-wrap: wrap; gap: 3px 10px; font-size: 20px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.3; }
.hero-greet-side { font-size: 12px; font-weight: 500; color: rgba(255, 255, 255, 0.66); letter-spacing: 0.01em; }
.dash-hero-sub { font-size: 13px; color: rgba(255, 255, 255, 0.78); margin-top: 5px; line-height: 1.6; }
.dash-hero-chip {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 650;
  letter-spacing: 0.02em;
  white-space: nowrap;
  background: rgba(255, 255, 255, 0.24);
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: #fff;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
/* 状态点：使用中为呼吸白点，未开通为静态灰点，过期/异常为静态红点 */
.dash-hero-chip::before {
  content: "";
  width: 6px;
  height: 6px;
  flex: 0 0 6px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.18);
  animation: chipPulse 2s ease-in-out infinite;
}
.dash-hero-chip.off { background: transparent; border-style: dashed; color: rgba(255, 255, 255, 0.92); }
.dash-hero-chip.off::before { background: rgba(255, 255, 255, 0.55); box-shadow: none; animation: none; }
.dash-hero-chip.alert { background: #fff; border-color: #fff; color: var(--red); }
.dash-hero-chip.alert::before { background: var(--red); box-shadow: 0 0 0 3px rgba(196, 35, 42, 0.16); animation: none; }
/* ============ 套餐 ============ */
.plans-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
.plan-card {
  background: var(--bg2);
  border: 1px solid rgba(20, 32, 27, 0.06);
  border-radius: var(--radius);
  padding: 28px 24px;
  position: relative;
  /* 竖排 flex：说明行数不再固定（后台写几条就显示几条），
     靠 ul 吃掉多余高度，让几张卡的按钮始终对齐在同一条线上 */
  display: flex;
  flex-direction: column;
  /* 原来 transition: all 0.25s ease 会让所有变动属性都参与插值，收敛为只过渡会变的三个 */
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
  cursor: pointer;
  box-shadow: var(--shadow-card);
  /* 常驻合成层：hover 进出不再反复提升/回收图层，避免 34px 大字重新栅格化造成"卡一下" */
  will-change: transform;
}
.plan-card:hover {
  /* 模糊半径与静止态保持 28px 不变（原来 40px），阴影遮罩可复用，只改偏移与透明度 */
  box-shadow: 0 20px 28px rgba(20, 32, 27, 0.08);
  border-color: rgba(47, 92, 58, 0.28);
  transform: translateY(-5px);
}
.plan-card.featured {
  border-color: rgba(20, 32, 27, 0.06);
  transform: translateY(-6px);
  box-shadow: 0 22px 46px rgba(20, 32, 27, 0.12);
}
.plan-card.featured:hover {
  border-color: rgba(20, 32, 27, 0.06);
  transform: translateY(-10px);
  /* 模糊半径与 .featured 静止态保持 46px 一致（原来 58px），避免逐帧重算超大模糊 */
  box-shadow: 0 28px 46px rgba(20, 32, 27, 0.16);
}
.plan-card.featured .price { color: var(--accent); }
.plan-card .badge {
  position: absolute;
  top: -11px;
  right: 18px;
  background: linear-gradient(135deg, var(--accent), var(--accent2));
  color: #fff;
  padding: 4px 14px;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  box-shadow: 0 4px 12px rgba(30, 61, 40, 0.25);
}
.plan-card h3 { font-size: 20px; margin-bottom: 4px; font-weight: 700; letter-spacing: -0.01em; }
.plan-card .tags { margin: 6px 0 10px; display: flex; gap: 6px; flex-wrap: wrap; }
.plan-card .price { font-size: 34px; font-weight: 750; margin: 12px 0; letter-spacing: -0.03em; }
.plan-card .price span { font-size: 14px; color: var(--muted); font-weight: 500; letter-spacing: 0; }
.plan-card .desc { font-size: 13px; color: var(--muted); margin-bottom: 16px; line-height: 1.7; }
.plan-card ul { list-style: none; margin-bottom: 20px; flex: 1 1 auto; }
.plan-card li {
  font-size: 13px;
  padding: 5px 0;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 9px;
}
.plan-card li::before { content: "✓"; color: rgba(20, 32, 27, 0.4); font-weight: 700; font-size: 14px; }
.plan-card.featured li::before { color: var(--accent); }
/* 骨架卡片：首屏拉套餐列表时占住网格。原来是 box.innerHTML = 一行灰字，
   整块区域会塌成一条细线，视觉上像"页面挂了"。
   尺寸按真实卡片反推：套餐网格是 stretch 对齐，六张卡实测都是 370px，
   骨架必须同样高，数据回来时才不会整块往上/往下跳（实测 CLS 从 0.0059 降到 0.0001）。 */
.plan-skeleton { pointer-events: none; cursor: default; }
.plan-skeleton:hover { transform: none; box-shadow: none; border-color: rgba(20, 32, 27, 0.06); }
.plan-skeleton .sk {
  background: linear-gradient(90deg, var(--bg3) 25%, #e8f1ea 37%, var(--bg3) 63%);
  background-size: 400% 100%;
  border-radius: 6px;
  animation: sk-shine 1.5s ease-in-out infinite;
}
.plan-skeleton .sk-title { width: 44%; height: 24px; margin-bottom: 18px; }
.plan-skeleton .sk-price { width: 58%; height: 40px; margin-bottom: 22px; }
.plan-skeleton .sk-line { height: 15px; margin-bottom: 14px; }
.plan-skeleton .sk-short { width: 62%; }
.plan-skeleton .sk-btn { height: 51px; margin-top: 26px; border-radius: var(--radius-sm); }
@keyframes sk-shine {
  0% { background-position: 100% 0; }
  100% { background-position: 0 0; }
}
@media (prefers-reduced-motion: reduce) { .plan-skeleton .sk { animation: none; } }
/* ============ 节点 ============ */
.node-list { display: flex; flex-direction: column; gap: 12px; }
.node-row {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 20px;
  background: var(--bg2);
  border: 1px solid rgba(20, 32, 27, 0.06);
  border-radius: var(--radius-sm);
  /* 原来 transition: all 会连带插值所有变动属性，收敛成只过渡会变的三个 */
  transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
  box-shadow: var(--shadow-card);
  /* 常驻合成层：hover 进出不再反复提升/回收图层，避免内容重新栅格化造成"卡一下" */
  will-change: transform;
}
.node-row::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  border-radius: 0 3px 3px 0;
  background: var(--success);
  box-shadow: 0 0 10px rgba(35, 122, 62, 0.45);
}
.node-row.offline::before { background: rgba(20, 32, 27, 0.18); box-shadow: none; }
.node-row.offline { background: var(--bg3); }
.node-row:hover {
  border-color: rgba(47, 92, 58, 0.22);
  transform: translateY(-2px);
  /* 模糊半径与静止态保持 28px 不变（原来 40px），阴影遮罩可复用，只改偏移与透明度 */
  box-shadow: 0 20px 28px rgba(20, 32, 27, 0.08);
}
.node-flag {
  position: relative;
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg3);
  box-shadow: inset 0 0 0 1px rgba(20, 32, 27, 0.1);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--muted);
}
.node-flag-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.node-flag.has-file .node-flag-fb { display: none; }
.node-flag-ch { font-size: 15px; font-weight: 700; color: var(--ink); }
.node-row.offline .node-flag { filter: grayscale(1); opacity: 0.72; }
.node-info { flex: 1; }
.node-name { font-size: 15px; font-weight: 650; }
.node-meta { font-size: 13px; color: var(--muted); margin-top: 3px; }
.node-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.node-rate {
  padding: 4px 11px;
  background: var(--bg3);
  border: 1px solid var(--rule);
  border-radius: 8px;
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
  font-weight: 600;
}
.node-rate.discount {
  background: rgba(35, 122, 62, 0.1);
  border-color: rgba(35, 122, 62, 0.22);
  color: var(--success);
}
.node-rate.mild {
  background: rgba(180, 83, 9, 0.06);
  border-color: rgba(180, 83, 9, 0.16);
  color: var(--warning);
}
.node-rate.premium {
  background: rgba(180, 83, 9, 0.1);
  border-color: rgba(180, 83, 9, 0.22);
  color: var(--warning);
}
.node-status {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--success);
  white-space: nowrap;
  font-weight: 500;
}
.node-status.offline { color: var(--muted); }
.status-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px rgba(35, 122, 62, 0.18);
}
.status-dot.offline { background: var(--muted); box-shadow: none; }
/* 节点空态：按「未订阅 / 已过期 / 无可用节点」三种情况给出对应引导 */
.node-empty { padding: 4px 0; }
.node-empty-card {
  background: var(--bg2);
  border: 1px dashed rgba(47, 92, 58, 0.24);
  border-radius: var(--radius);
  padding: 46px 24px;
  text-align: center;
  box-shadow: var(--shadow-card);
}
.node-empty-ico {
  width: 58px; height: 58px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 17px;
  background: var(--accent-soft);
  color: var(--accent);
  margin-bottom: 16px;
}
.node-empty-title { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; margin-bottom: 8px; }
.node-empty-desc { font-size: 13px; color: var(--muted); line-height: 1.8; max-width: 360px; margin: 0 auto; }
.node-empty-cta { margin-top: 22px; }
/* .btn 基础是 display:block + width:100%，空态按钮改为内容宽度并居中 */
.node-empty-cta .btn { width: auto; display: inline-block; min-width: 148px; padding: 11px 22px; }
/* ============ 个人中心 ============ */
.profile-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}
.profile-card h3 {
  font-size: 16px;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
  font-weight: 700;
}
/* 个人中心 · 通栏卡片（Telegram 绑定） */
.profile-card-wide { grid-column: 1 / -1; }
.tg-wrap { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.tg-info { flex: 1 1 280px; min-width: 0; }
.tg-status { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tg-id { font-size: 12.5px; color: var(--muted); }
.tg-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.wallet-amount {
  font-size: 28px;
  font-weight: 750;
  letter-spacing: -0.03em;
  background: linear-gradient(145deg, #3a6b47, #1e3d28);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}
.wallet-label { font-size: 13px; color: var(--muted); margin-top: 6px; }
.switch-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 0;
  font-size: 14px;
}
.switch {
  width: 42px; height: 24px;
  background: #d0d9d3;
  border-radius: 12px;
  position: relative;
  cursor: pointer;
  display: block;
  transition: background 0.2s;
}
.switch input { display: none; }
.switch::after {
  content: "";
  position: absolute;
  width: 18px; height: 18px;
  background: var(--bg2);
  border-radius: 50%;
  top: 3px; left: 3px;
  transition: left 0.2s;
  box-shadow: 0 1px 4px rgba(0,0,0,0.18);
}
.switch:has(input:checked) { background: var(--accent); }
.switch:has(input:checked)::after { left: 21px; }
/* ============ 数据表格 ============ */
.data-table { width: 100%; }
.table-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  align-items: center;
  padding: 14px 18px;
  border-bottom: 1px solid var(--rule);
  font-size: 13px;
  transition: background 0.15s;
}
.table-row:last-child { border-bottom: none; }
.table-row:not(.table-head):hover { background: rgba(47, 92, 58, 0.04); }
.table-head {
  font-weight: 600;
  color: var(--muted);
  font-size: 13px;
  background: var(--bg3);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  border-bottom: 1px solid var(--rule);
}
.table-row .num { text-align: right; font-variant-numeric: tabular-nums; }
.table-row .mono { font-family: 'SF Mono', 'Consolas', monospace; font-size: 13px; }
#page-order .table-row { grid-template-columns: 1.3fr 1.2fr 0.8fr 0.8fr 0.7fr 1fr 0.7fr; }
#page-ticket .table-row { grid-template-columns: 1.2fr 1.5fr 0.8fr 0.7fr 1fr 0.7fr; }
#page-traffic .table-row { grid-template-columns: 1.2fr 0.8fr 0.8fr 0.8fr 0.7fr; }
#page-invite .table-row { grid-template-columns: 1.3fr 0.8fr 0.8fr 1fr; }
.tag {
  display: inline-block;
  padding: 3px 11px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 550;
}
.tag-success { background: rgba(35, 122, 62, 0.12); color: var(--success); }
.tag-warning { background: rgba(180, 83, 9, 0.12); color: var(--warning); }
.tag-muted { background: rgba(90, 107, 98, 0.12); color: var(--muted); }
.tag-danger { background: rgba(196, 35, 42, 0.1); color: var(--danger); }
.tag-session { background: var(--accent-soft); color: var(--accent); }
.link-btn {
  color: var(--accent);
  font-size: 13px;
  text-decoration: none;
  margin-right: 12px;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  font-weight: 500;
}
.link-btn:hover { text-decoration: underline; }
.link-btn.danger { color: var(--danger); }
/* ============ 迷你统计 ============ */
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 18px; }
.mini-stat {
  padding: 16px 20px;
  background: var(--bg2);
  border: 1px solid rgba(20, 32, 27, 0.06);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
}
.mini-label { font-size: 13px; color: var(--muted); margin-bottom: 6px; font-weight: 500; }
.mini-value { font-size: 24px; font-weight: 750; color: var(--ink); letter-spacing: -0.02em; }
.mini-value.accent { color: var(--accent); }
/* ============ 邀请 ============ */
.invite-hero { display: grid; grid-template-columns: 1fr 1.5fr; gap: 18px; margin-bottom: 18px; }
.invite-code-box, .invite-link-box {
  padding: 24px;
  background: var(--bg2);
  border: 1px solid rgba(20, 32, 27, 0.06);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
}
.invite-label { font-size: 13px; color: var(--muted); margin-bottom: 10px; font-weight: 500; }
.invite-code {
  font-size: 32px;
  font-weight: 750;
  letter-spacing: 3px;
  color: var(--accent);
  margin-bottom: 14px;
  font-family: 'SF Mono', 'Consolas', monospace;
}
.invite-link {
  font-size: 13px;
  color: var(--ink);
  background: var(--bg3);
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  margin-bottom: 14px;
  word-break: break-all;
  font-family: 'SF Mono', 'Consolas', monospace;
}
.invite-actions { display: flex; gap: 10px; }
/* 没有未使用的邀请码时（一次性码被消耗掉，后端就只返回空数组）：
   原来的「--」是 32px 等宽 + 3px 字距，两个短横在视觉上像内容没加载出来。
   降级成 15px 的说明文案，同时把「生成新邀请码」提成主按钮引导用户点它。 */
.invite-code.is-empty {
  font-size: 15px; font-weight: 500; letter-spacing: 0;
  color: var(--muted); font-family: inherit;
}
.invite-link.is-empty { color: var(--muted); }
.btn.is-cta {
  background: var(--accent); border-color: var(--accent);
  color: #fff; opacity: 1;
}
.btn.is-cta:hover { background: var(--accent2); border-color: var(--accent2); }
/* 套餐详情 / 支付 */
.pay-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: 18px; }
.plan-info-card { padding: 28px; }
.plan-info-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 22px; }
.plan-info-head h3 { font-size: 20px; margin-bottom: 6px; font-weight: 700; letter-spacing: -0.02em; }
.period-tabs { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; }
.period-tab {
  position: relative;
  flex: 1 1 120px;
  min-width: 0;
  min-height: 76px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 14px 12px;
  border-radius: 12px;
  background: var(--bg3);
  border: 1px solid var(--rule);
  color: var(--muted);
  cursor: pointer;
  transition: all 0.18s;
  font-weight: 500;
}
/* 套餐详情弹窗的字号统一收敛到 5 级：12 / 14 / 16 / 20 / 28。
   原来 11~20 之间有 8 个相邻档位（11/12/13/14/15/16/17/18/20），相差 1px 的两级肉眼分不出，
   只会让层级变糊。这里按「辅助 12 / 正文 14 / 强调 16 / 标题 20 / 金额 28」归并。 */
.period-name { font-size: 14px; color: var(--muted); }
.period-price { font-size: 16px; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
.period-tab.active {
  background: linear-gradient(145deg, #3a6b47, #1e3d28);
  color: #fff;
  border-color: transparent;
  font-weight: 600;
}
/* 选中态卡片内文字换浅色（徽标浮在卡外，配色不受选中态影响） */
.period-tab.active .period-name { color: rgba(255, 255, 255, 0.78); }
.period-tab.active .period-price { color: #fff; }
/* 「省X%」不占卡内一行：做成悬浮在卡片右上角外的徽标，白描边制造脱离卡框的浮起感 */
.period-save {
  position: absolute;
  top: -9px;
  right: -6px;
  background: var(--success);
  color: #fff;
  border: 2px solid var(--bg2);
  border-radius: 999px;
  padding: 2px 9px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  box-shadow: 0 4px 10px rgba(35, 122, 62, 0.25);
}
/* 「已用流量」卡片右上角的流量重置包入口：幽灵链接式（无底色无边框，纯绿字），位置仍在卡片右上角 */
.stat-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.stat-head .label { margin-bottom: 0; }
.stat-reset {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 6px;
  border: 0;
  background: none;
  border-radius: 6px;
  color: var(--accent);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.5;
  cursor: pointer;
  transition: background 0.18s;
}
.stat-reset-ico { display: inline-flex; color: var(--accent); }
.stat-reset-price { font-weight: 700; }
.stat-reset:hover { background: var(--accent-soft); }
/* 流量重置包「重置专用」弹窗内的信息块 */
.reset-only {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 20px;
  border-radius: 12px;
  background: var(--accent-soft);
  border: 1px solid rgba(47, 92, 58, 0.16);
}
.reset-only-ico { color: var(--accent); flex-shrink: 0; display: flex; }
.reset-only-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.reset-only-body b { font-size: 16px; font-weight: 600; color: var(--ink); }
.reset-only-body em { font-size: 12px; font-style: normal; color: var(--muted); }
.reset-only-price { font-size: 20px; font-weight: 700; color: var(--accent); letter-spacing: -0.01em; }
.plan-specs { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 20px; }
/* 一次性套餐的规则提示：紧贴周期卡下方，别让用户把「一次性」当成年付之类的周期 */
.period-note {
  margin: -10px 0 18px;
  padding-left: 11px;
  border-left: 2px solid var(--accent);
  font-size: 13px;
  line-height: 1.6;
  color: var(--muted);
}
.spec-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  background: var(--bg3);
  border-radius: var(--radius-sm);
}
.spec-icon { font-size: 28px; }
.spec-val { font-size: 16px; font-weight: 700; }
.spec-label { font-size: 12px; color: var(--muted); margin-top: 2px; }
/* 权益列表：跟上面 2×2 规格卡同一套栅格节奏，双列排布比竖排 4 行更省高度、更好扫读。
   顶部一条细分割线把它和规格卡分成「数字」与「权益」两段。 */
.plan-features {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 11px 14px;
  margin-top: 2px;
  padding-top: 16px;
  border-top: 1px solid var(--rule);
}
.feat-item { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
/* 勾选做成淡绿圆底徽标：纯文字 ✓ 和大段正文混在一起时辨识度太低 */
.feat-ico {
  flex: 0 0 16px;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.feat-ico svg { display: block; stroke-width: 3; }
.feat-txt { font-size: 13.5px; line-height: 1.55; color: var(--ink); min-width: 0; }
/* 窄屏双列会把中文挤成竖条，退回单列 */
@media (max-width: 560px) {
  .plan-features { grid-template-columns: minmax(0, 1fr); gap: 10px; }
}
/* 支付卡换成淡绿底，与白色弹窗/左侧套餐卡拉开层次，双栏结构一眼可辨 */
.pay-card { padding: 28px; display: flex; flex-direction: column; background: var(--bg3); }
.pay-card h3 {
  font-size: 16px;
  margin-bottom: 18px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
  font-weight: 700;
}
.pay-row { display: flex; justify-content: space-between; padding: 9px 0; font-size: 14px; color: var(--muted); }
/* 只认直接子元素：应付金额那一行里还嵌套了「划线原价 + 实付价」，
   用后代选择器会连带命中它们——划线价被顶成 16px 粗体、实付价的 750 字重被压成 500，
   两个数字挤在一起分不出主次。 */
.pay-row > span:last-child { color: var(--ink); font-weight: 500; }
.pay-row.total { border-top: 1px solid var(--rule); margin-top: 10px; padding-top: 16px; }
.pay-row.total > span:first-child { font-size: 16px; font-weight: 700; color: var(--ink); }
.pay-amount { font-size: 28px; font-weight: 750; color: var(--accent) !important; letter-spacing: -0.02em; }
.strike { text-decoration: line-through; color: var(--muted) !important; }
/* 应付金额区：原价（划线）+ 实付价并排 */
.pay-total-val { display: inline-flex; align-items: baseline; gap: 8px; }
/* 划线原价定档 16px：与 28px 实付价拉开两级，既不抢视线也不至于小到看不清 */
.pay-total-val .strike { font-size: 16px; font-weight: 500; }
/* 用券后应付金额转为促销红，与左侧绿色的「产品价」区分开；无优惠时保持绿色，两处数值一致 */
.pay-amount.discounted { color: var(--red) !important; }
.pay-row .accent { color: var(--accent) !important; }
/* 支付方式区与「余额已全额抵扣」提示是互斥的两块，叠在同一个网格单元里：
   行高恒等于较高的一方（支付方式区），所以切换计费周期、余额是否够付，
   弹窗高度都不会跟着变——否则每次切换整页内容都要位移一次。
   支付方式区的高度取决于后台配了几个通道，写死 min-height 不可靠，叠格最稳。 */
.pay-settle { display: grid; margin: 16px 0; }
.pay-settle > * { grid-area: 1 / 1; }
.pay-methods { margin: 0; }
.pay-label { font-size: 14px; font-weight: 650; margin-bottom: 12px; }
/* 支付方式行（F 方案）：图标 32px 在左、渠道名居中、单选圈推到行尾。
   单选圈原来紧挨着图标，两个圆形挤在同一侧；挪到右边之后左侧是干净的
   「图标 + 名称」一组，扫视顺序和收银台一致。行高 50 → 62px，
   两个渠道合计让弹窗长 12px，608 → 620，远没有到需要滚动的高度。 */
.pay-option {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  margin-bottom: 10px;
  cursor: pointer;
  transition: all 0.2s;
  font-size: 14px;
  background: var(--bg2);
}
.pay-option:hover { border-color: rgba(47, 92, 58, 0.3); background: #fafdfb; }
.pay-option input { display: none; }
.pay-radio {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2px solid var(--rule);
  position: relative; flex: 0 0 18px;
  /* 推到行尾：整行宽度固定，单选圈靠右后左边两组元素才能对齐 */
  margin-left: auto;
  transition: border-color 0.2s;
}
.pay-option input:checked ~ .pay-radio { border-color: var(--accent); }
.pay-option input:checked ~ .pay-radio::after {
  content: ""; position: absolute; inset: 3px;
  border-radius: 50%; background: var(--accent);
  transform: scale(1); transition: transform 0.2s;
}
.pay-radio::after {
  content: ""; position: absolute; inset: 3px;
  border-radius: 50%; background: var(--accent);
  transform: scale(0); transition: transform 0.2s;
}
/* 图标盒定死 32×32：img 与内置 svg 都拉满，不会被各自的行高/基线带着走。
   原来靠 img 上的内联 vertical-align:middle 硬撑，换尺寸就得改 JS。 */
.pay-icon {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; flex: none;
  color: var(--muted);
}
.pay-icon img { display: block; width: 32px; height: 32px; border-radius: 6px; object-fit: contain; }
.pay-icon svg { display: block; width: 32px; height: 32px; }
.pay-name { line-height: 1.4; }
.pay-option em { font-style: normal; color: var(--muted); font-size: 12px; }
.coupon-row { display: flex; gap: 10px; margin-bottom: 14px; }
/* 支付卡已改为淡绿底，输入框改用白底才不至于和卡片糊在一起 */
.coupon-row input { flex: 1; background: var(--bg2); }
/* 窄屏（390px）下「使用」按钮会被 flex 压到比内容还窄，"使用"两个字竖着折成两行。
   .btn 是 display:block，作为 flex 子项默认允许收缩；这里禁止收缩并禁止换行。 */
.coupon-row .btn { flex: none; white-space: nowrap; }
.coupon-tip { font-size: 14px; color: var(--success); margin: 6px 0; font-weight: 500; }
/* 余额已全额抵扣时的说明：与支付方式区同占一格（见 .pay-settle），
   高度被拉满时文字自动垂直居中，看起来像一块有意留出的确认面板而不是一块空白 */
.balance-note {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 14px; color: var(--accent); font-weight: 500;
  background: rgba(47, 92, 58, 0.08);
  border-radius: var(--radius-sm);
  padding: 10px 12px; margin: 0;
}
.balance-note svg { flex: none; }
/* 工单详情 */
.msg-list { display: flex; flex-direction: column; gap: 16px; margin-bottom: 20px; }
.msg-item { display: flex; flex-direction: column; gap: 6px; }
.msg-item.me { align-items: flex-end; }
.msg-meta { font-size: 12px; color: var(--muted); }
.msg-bubble {
  max-width: 85%;
  padding: 13px 16px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  line-height: 1.7;
  background: var(--bg3);
  border: 1px solid var(--rule);
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-word;
}
.msg-item.me .msg-bubble {
  background: linear-gradient(145deg, rgba(47,92,58,0.1), rgba(30,61,40,0.07));
  border-color: rgba(47, 92, 58, 0.2);
}
/* 知识文章 */
.kb-article-body { font-size: 14px; line-height: 1.9; color: var(--ink); }
.kb-article-body img { max-width: 100%; border-radius: var(--radius-sm); }
.kb-article-body pre { background: var(--bg3); padding: 14px; border-radius: 10px; overflow-x: auto; }
.kb-article-body code { background: #eef4ef; padding: 2px 6px; border-radius: 5px; font-size: 13px; }
/* 支付二维码 */
.qr-box { text-align: center; padding: 12px 0 8px; }
.qr-box img { max-width: 260px; border-radius: var(--radius-md); border: 1px solid var(--rule); }
.qr-tip { font-size: 13px; color: var(--muted); margin-top: 12px; }
.qr-status { font-size: 14px; color: var(--success); font-weight: 650; margin-top: 8px; }
/* ============ Toast ============ */
#toast-root { position: fixed; top: 24px; right: 24px; z-index: 2000; display: flex; flex-direction: column; gap: 10px; }
/* 响应式（≤900px）规则统一收敛至文件末尾，避免被后续基础规则覆盖 */
/* ============ 仪表盘公告横条 ============ */
/* 公告条加载态：以骨架形态先占住高度，数据回来只换文字，不改变布局高度。
   之前它是 display:none，数据一到突然插入，把下方内容整体推下 91px（CLS 主因）。 */
.dash-notice.is-loading .notice-title { color: var(--muted); font-weight: 500; }
.dash-notice.is-loading .notice-more { visibility: hidden; }
/* 确实没有公告时才隐藏；此时会塌陷，但只发生在「零公告」的账号上 */
.dash-notice.is-empty { display: none; }
.dash-notice {
  display: flex;
  align-items: center;
  gap: 14px;
  background: linear-gradient(135deg, #f7f9f7 0%, #ffffff 100%);
  border: 1px solid rgba(20, 32, 27, 0.08);
  border-left: 4px solid rgba(20, 32, 27, 0.14);
  border-radius: var(--radius-md);
  padding: 16px 20px;
  margin-bottom: 22px;
  cursor: pointer;
  transition: box-shadow 0.2s, transform 0.2s;
  box-shadow: 0 4px 16px rgba(47, 92, 58, 0.05);
  /* 常驻合成层：hover 进出不再反复提升/回收图层，避免内容重新栅格化造成"卡一下" */
  will-change: transform;
}
.dash-notice:hover {
  /* 模糊半径与静止态保持 16px 不变（原来 20px），阴影遮罩可复用，只改偏移与透明度 */  box-shadow: 0 6px 16px rgba(47, 92, 58, 0.08);
  transform: translateY(-1px);
}
.dash-notice .notice-icon { font-size: 20px; flex-shrink: 0; }
.dash-notice .notice-body { flex: 1; min-width: 0; }
.dash-notice .notice-title { font-size: 15px; font-weight: 650; color: var(--ink); line-height: 1.4; }
.dash-notice .notice-meta {
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-size: 13px;
  color: var(--muted);
  margin-top: 4px;
}
.dash-notice .notice-desc {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 55%;
}
.dash-notice .notice-more {
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
  flex-shrink: 0;
  font-weight: 550;
}
/* ============ 订阅区 + 右侧置顶公告 ============ */
.dash-sub-row {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 18px;
  align-items: start;
}
.dash-notice-side {
  position: sticky;
  top: 20px;
  background: var(--bg2);
  border: 1px solid var(--rule);
  border-top: 3px solid rgba(20, 32, 27, 0.12);
  border-radius: var(--radius-md);
  padding: 18px;
  min-height: 170px;
  box-shadow: var(--shadow-card);
  cursor: pointer;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.dash-notice-side:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow-card), 0 0 0 3px var(--accent-soft);
}
.dash-notice-side .notice-side-tag {
  display: inline-block;
  font-size: 12px;
  font-weight: 650;
  color: var(--muted);
  background: var(--bg3);
  border: 1px solid var(--rule);
  padding: 3px 10px;
  border-radius: 999px;
  margin-bottom: 12px;
  letter-spacing: 0.02em;
}
.dash-notice-side .notice-side-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.45;
  margin-bottom: 6px;
  letter-spacing: -0.01em;
}
.dash-notice-side .notice-side-time {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 12px;
}
.dash-notice-side .notice-side-content {
  font-size: 13px;
  color: var(--ink);
  line-height: 1.7;
  word-break: break-word;
  /* 高度随内容自适应：不再固定 210px 截断，长公告完整展开 */
  max-height: none;
  overflow: visible;
}
.dash-notice-side .notice-side-content p {
  margin: 0 0 6px;
}
.dash-notice-side .notice-side-content p:last-child {
  margin-bottom: 0;
}
.dash-notice-side .notice-side-content a {
  color: var(--accent);
  text-decoration: none;
}
.dash-notice-side .notice-side-content a:hover {
  text-decoration: underline;
}
/* ============ 使用教程 ============ */
.tut-head h3 { font-size: 20px; font-weight: 750; color: var(--ink); letter-spacing: -0.02em; }
.tut-head p { font-size: 14px; color: var(--muted); margin-top: 6px; }
.tut-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-top: 20px;
}
.tut-card {
  position: relative;
  border: none;
  border-radius: var(--radius);
  background: var(--grad, linear-gradient(145deg, #2f5c3a, #4a7a58));
  color: #fff;
  padding: 32px 26px;
  cursor: pointer;
  overflow: hidden;
  box-shadow: 0 10px 28px rgba(20, 32, 27, 0.1);
  transition: transform 0.22s ease, box-shadow 0.22s ease;
  /* 常驻合成层：hover 进出不再反复提升/回收图层，避免内容重新栅格化造成"卡一下" */
  will-change: transform;
}
.tut-card:hover {
  transform: translateY(-5px);
  /* 模糊半径与静止态保持 28px 不变（原来 40px），阴影遮罩可复用，只改偏移与透明度 */
  box-shadow: 0 18px 28px rgba(20, 32, 27, 0.16);
}
.tut-card svg {
  position: absolute;
  right: 22px;
  top: 50%;
  transform: translateY(-50%);
  width: 76px;
  height: 76px;
  opacity: 0.9;
}
.tut-name { font-size: 20px; font-weight: 750; letter-spacing: 0.01em; }
.tut-sub { font-size: 13px; opacity: 0.85; margin-top: 8px; }
.tut-detail { margin-top: 20px; }
.tut-back {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font-size: 14px;
  font-weight: 650;
  cursor: pointer;
  margin-bottom: 16px;
}
.tut-back:hover { text-decoration: underline; }
.tut-detail-title { font-size: 20px; font-weight: 750; color: var(--ink); letter-spacing: -0.01em; }
.tut-detail-desc { font-size: 14px; color: var(--muted); margin-top: 6px; }
/* ---- 分步式教程：左侧序号 + 连接线，右侧内容 ---- */
/* 教程是长文阅读，宽屏下不铺满整行，否则每行字数过多很难读 */
.tut-detail.tut-step-mode { max-width: 860px; margin-left: auto; margin-right: auto; }
.tut-flow { margin-top: 24px; display: flex; flex-direction: column; gap: 28px; }
.tut-step { position: relative; padding-left: 46px; }
.tut-step:not(:last-child)::before {
  content: '';
  position: absolute;
  left: 15px;
  top: 40px;
  bottom: -28px;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, rgba(47, 92, 58, 0.22), rgba(47, 92, 58, 0.05));
}
.tut-step-head { display: flex; align-items: center; min-height: 32px; }
.tut-step-no {
  position: absolute;
  left: 0;
  top: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(47, 92, 58, 0.24);
}
.tut-step-title { font-size: 16px; font-weight: 750; color: var(--ink); letter-spacing: -0.01em; }
.tut-step-body { margin-top: 14px; }
/* 第一步的软件卡：图标 + 名称 + 下载按钮（外观对齐首页「快速上手教程」的磁贴） */
.tut-dl-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  background: var(--bg3);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
}
.tut-dl-icon {
  flex: none;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg2);
  display: flex;
  align-items: center;
  justify-content: center;
}
.tut-dl-icon img { width: 48px; height: 48px; object-fit: cover; display: block; }
.tut-dl-info { flex: 1; min-width: 0; }
.tut-dl-name { font-size: 15px; font-weight: 700; color: var(--ink); }
.tut-dl-desc { font-size: 13px; color: var(--muted); margin-top: 4px; }
/* iOS 付费应用没有直链，同一个按钮位置改成 <button> 弹获取说明 */
button.btn-dl-solid { border: none; cursor: pointer; font-family: inherit; }
.tut-step-note {
  margin-top: 10px;
  font-size: 13px;
  line-height: 1.8;
  color: var(--muted);
}
/* 步骤内的编号条目 */
.tut-item { display: flex; gap: 10px; margin-top: 14px; }
.tut-item:first-child { margin-top: 0; }
.tut-item-no {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 4px;
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.tut-item-body { flex: 1; min-width: 0; font-size: 14px; line-height: 1.85; color: #42504a; }
.tut-item-body b { color: var(--ink); font-weight: 650; }
.tut-item-act { margin-top: 10px; display: flex; gap: 10px; flex-wrap: wrap; }
/* 备用方法提示条 */
.tut-alt {
  margin: 18px 0 6px;
  padding: 9px 13px;
  border-left: 3px solid rgba(180, 83, 9, 0.5);
  background: rgba(180, 83, 9, 0.06);
  border-radius: 0 8px 8px 0;
  font-size: 13px;
  line-height: 1.7;
  color: #8a5a1f;
}
/* 注意事项 */
.tut-warn {
  margin-top: 16px;
  padding: 12px 14px;
  border: 1px solid rgba(180, 83, 9, 0.22);
  background: rgba(180, 83, 9, 0.07);
  border-radius: var(--radius-sm);
  font-size: 13px;
  line-height: 1.8;
  color: #7c4a12;
}
.tut-warn b { margin-right: 6px; color: #b45309; font-weight: 700; }
.tut-foot {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px dashed var(--rule);
  font-size: 13px;
  line-height: 1.8;
  color: var(--muted);
}
.tut-note { margin-top: 10px; font-size: 12px; line-height: 1.7; color: var(--muted); }
/* iOS 付费应用获取说明弹窗 */
.tut-tip-body p { font-size: 14px; line-height: 1.8; color: var(--ink); margin-bottom: 12px; }
.tut-tip-body ol { padding-left: 20px; font-size: 13px; line-height: 2; color: var(--muted); }
.tut-tip-body ol b { color: var(--ink); }
.tut-tip-note { font-size: 12px; line-height: 1.7; color: var(--muted); margin-top: 12px; }
/* iOS 获取方式弹窗：共享账号 / 自己注册 两条路径分段 */
.ios-plan { margin-top: 20px; padding-top: 18px; border-top: 1px dashed var(--rule); }
.ios-plan:first-of-type { margin-top: 14px; padding-top: 0; border-top: none; }
.ios-plan-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.ios-plan-tag {
  flex: none;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--accent);
}
.ios-plan-head b { font-size: 14px; color: var(--ink); }
.ios-plan-head em { font-size: 12px; font-style: normal; color: var(--muted); margin-left: auto; }
.ios-links { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.ios-links a {
  flex: 1 1 0;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font-size: 13px;
  font-weight: 650;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.2s;
}
.ios-links a:hover { background: var(--accent2); }
.ios-warn {
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid rgba(180, 83, 9, 0.22);
  background: rgba(180, 83, 9, 0.07);
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  line-height: 1.75;
  color: #8a5a1f;
}
.ios-warn b { display: block; margin-bottom: 4px; font-size: 13px; color: #b45309; }
/* 窄屏标题行放不下时，「免费·最快」换行后改为左对齐，避免孤零零贴在右边 */
@media (max-width: 600px) {
.ios-plan-head em { margin-left: 0; font-size: 11px; }
}
/* 更窄的屏幕（如 360px）两个入口并排会挤，改为上下排列 */
@media (max-width: 380px) {
.ios-links a { flex: 1 1 100%; }
}
/* 礼品卡兑换 */
.gift-input-row { display: flex; gap: 12px; }
.gift-card {
  border: 1px solid var(--rule);
  border-radius: var(--radius-md);
  padding: 16px 18px;
  margin-bottom: 6px;
  background: linear-gradient(145deg, rgba(47, 92, 58, 0.05), rgba(47, 92, 58, 0.1));
}
.gift-card-name { font-size: 16px; font-weight: 700; color: var(--ink); }
.gift-card-type {
  display: inline-block;
  font-size: 12px;
  padding: 3px 10px;
  border-radius: 20px;
  background: var(--bg3);
  border: 1px solid var(--rule);
  color: var(--muted);
  margin: 8px 0;
  font-weight: 550;
}
.gift-card-desc { font-size: 13px; color: var(--muted); line-height: 1.7; margin-bottom: 12px; }
.gift-rewards { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 0 12px; }
.gift-rw {
  font-size: 13px;
  padding: 5px 12px;
  border-radius: 20px;
  background: var(--bg3);
  border: 1px solid var(--rule);
  color: var(--ink);
}
.gift-rw-balance { color: var(--accent); border-color: rgba(47, 92, 58, 0.3); font-weight: 550; }
.gift-rw-empty { font-size: 13px; color: var(--muted); }
.gift-ok {
  font-size: 14px;
  color: var(--accent);
  font-weight: 650;
  padding-top: 10px;
  border-top: 1px dashed var(--rule);
}
.gift-no {
  font-size: 14px;
  color: var(--danger);
  padding: 10px 0;
  line-height: 1.6;
}
.gift-history {
  border-top: 1px solid var(--rule);
  margin-top: 8px;
  padding-top: 14px;
}
.gift-history h4 { font-size: 14px; font-weight: 650; color: var(--ink); margin-bottom: 12px; }
.gift-his-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px dashed var(--rule);
  font-size: 14px;
}
.gift-his-row:last-child { border-bottom: none; }
.gift-his-reward {
  flex: none;
  font-size: 13px;
  color: var(--accent);
  white-space: nowrap;
  font-weight: 550;
}
@media (max-width: 720px) {
.tut-grid { grid-template-columns: 1fr; }
}
/* ============ 平台快速教程入口（浅色描边版） ============ */
.tut-quick {
  margin-bottom: 22px;
  padding: 18px 20px;
  background: var(--bg2);
  border: 1px solid rgba(20,32,27,0.06);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
}
.tut-quick-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
}
.tut-quick-icon { font-size: 16px; line-height: 1; }
.tut-quick-title { font-size: 14px; font-weight: 600; color: var(--ink); }
.tut-quick-btns { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.tut-quick-btn {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 11px 14px;
  background: var(--bg3);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s;
  cursor: pointer;
  font-family: inherit;
}
.tut-quick-ico {
  flex: 0 0 34px;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--bg2);
  box-shadow: inset 0 0 0 1px rgba(20, 32, 27, 0.09);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: box-shadow 0.2s ease, transform 0.15s ease;
}
.tut-quick-ico svg { width: 18px; height: 18px; display: block; }
.tut-quick-ico.android { color: #2f9e5f; }
.tut-quick-ico.windows { color: #1a73c8; }
.tut-quick-ico.ios, .tut-quick-ico.macos { color: var(--ink); }
.tut-quick-btn:hover .tut-quick-ico {
  transform: translateY(-1px);
  box-shadow: inset 0 0 0 1px rgba(20, 32, 27, 0.14), 0 4px 10px rgba(20, 32, 27, 0.1);
}
.tut-quick-name { max-width: 100%; }
.tut-quick-btn:hover {
  background: var(--bg2);
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 2px 8px rgba(47,92,58,0.08);
  transform: translateY(-1px);
}
@media (max-width: 768px) {
/* 手机端：回到方形瓷砖（图标在上、文字在下），一排 4 个 */
.tut-quick-btns { gap: 8px; }
.tut-quick-btn {
    min-width: 0;
    flex-direction: column;
    gap: 6px;
    aspect-ratio: 1 / 1;
    padding: 10px 4px;
    font-size: 12px;
    line-height: 1.25;
    text-align: center;
    white-space: normal;
  }
.tut-quick-ico { flex: 0 0 30px; width: 30px; height: 30px; border-radius: 9px; }
.tut-quick-ico svg { width: 16px; height: 16px; }
}
/* ============ 移动端抽屉导航 ============ */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px; height: 36px;
  flex: none;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--bg2);
  color: var(--ink);
  cursor: pointer;
  transition: background 0.18s, border-color 0.18s;
}
.nav-toggle:hover { background: var(--bg3); border-color: rgba(47, 92, 58, 0.25); }
.topbar-left { display: flex; align-items: center; gap: 12px; min-width: 0; }
.nav-mask { display: none; position: fixed; inset: 0; background: rgba(20, 32, 27, 0.38); opacity: 0; visibility: hidden; transition: opacity 0.25s ease, visibility 0.25s ease; z-index: 55; }
@media (max-width: 900px) {
.stats-grid, .plans-grid, .profile-grid { grid-template-columns: 1fr; }
.dash-sub-row { grid-template-columns: 1fr; gap: 16px; }
.dash-notice-side { position: static; top: auto; min-height: 0; }
.stat-row { grid-template-columns: repeat(2, 1fr); }
.invite-hero, .pay-grid { grid-template-columns: 1fr; }
.main { padding: 18px 16px 32px; }
/* 数据表格：小屏改为外层横向滚动，保持原列数，避免列被压扁换行与表头错位 */
.data-table { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.data-table > div,
  .data-table .table-row { min-width: 520px; }
.data-table .table-row > div { white-space: nowrap; }
#page-traffic .data-table > div,
  #page-traffic .table-row { min-width: 620px; }
#page-order .data-table > div,
  #page-order .table-row { min-width: 720px; }
#page-ticket .data-table > div,
  #page-ticket .table-row { min-width: 660px; }
/* 筛选栏：窄屏允许换行，不再横向溢出 */
.page-header { flex-wrap: wrap; row-gap: 10px; }
.filter-bar { flex-wrap: wrap; }
/* 订阅行窄屏换行：名称 + 操作按钮优雅折行 */
.sub-row { flex-wrap: wrap; }
.sub-row .sub-actions { width: 100%; justify-content: flex-end; }
/* 订阅说明窄屏允许折行，避免被省略号截断（客户端名是用户判断选哪个的关键信息） */
.sub-desc { white-space: normal; overflow: visible; text-overflow: clip; }
/* 分步教程窄屏：序号缩小，下载按钮独占一行，避免挤压客户端名 */
.tut-step { padding-left: 40px; }
.tut-step:not(:last-child)::before { left: 13px; top: 36px; }
.tut-step-no { width: 28px; height: 28px; font-size: 14px; }
.tut-step-head { min-height: 28px; }
.tut-dl-card { flex-wrap: wrap; row-gap: 14px; padding: 14px; }
/* macOS 两个芯片按钮窄屏下也各占一行，避免跟客户端名/简介挤成窄条导致文字逐字换行 */
.tut-item-act .btn-act { flex: 1 1 auto; }
/* 公告横条窄屏不再硬截断 */
.dash-notice .notice-desc { white-space: normal; max-width: 100%; }
.dash-notice .notice-meta { flex-wrap: wrap; }
/* 移动端抽屉导航 */
.nav-toggle { display: flex; }
.nav-mask { display: block; }
.sidebar {
    display: flex;
    position: fixed;
    top: 0; left: 0; bottom: 0;
    height: 100vh;
    width: 268px;
    z-index: 60;
    transform: translateX(-100%);
    transition: transform 0.26s ease;
    box-shadow: 0 0 40px rgba(20, 32, 27, 0.16);
  }
.nav-open .sidebar { transform: translateX(0); }
.nav-open .nav-mask { opacity: 1; visibility: visible; }
body.nav-open { overflow: hidden; }
/* 卡片右上角入口在触屏上放大点击区域（图标同步放大，避免视觉变小） */
.stat-link { padding: 6px 9px; }
.stat-link-ico { padding: 8px; }
.stat-link-ico svg { width: 18px; height: 18px; }
.stat-reset { padding: 6px 8px; }
.breadcrumb { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
@media (max-width: 480px) {
.main { padding: 14px 12px 28px; }
.tut-quick-btns { grid-template-columns: repeat(4, 1fr); gap: 6px; }
.tut-quick-btn { padding: 6px 3px; gap: 5px; }
.tut-quick-ico { flex: 0 0 26px; width: 26px; height: 26px; border-radius: 8px; }
.tut-quick-ico svg { width: 14px; height: 14px; }
.section-title { font-size: 14px; }
/* 日期筛选栏：极窄屏纵向堆叠，输入与按钮占满整行，杜绝横向溢出 */
.filter-bar { width: 100%; flex-direction: column; align-items: stretch; gap: 8px; }
.filter-bar .input-sm,
  .filter-bar .btn { width: 100%; min-width: 0; box-sizing: border-box; }
.filter-sep { text-align: center; }
.node-row { flex-wrap: wrap; }
/* 品牌欢迎卡在极窄屏收紧内边距与问候语字号，首屏更紧凑 */
.dash-hero { padding: 16px 18px; }
.dash-hero-greet { font-size: 18px; }
.dash-hero-sub { font-size: 12.5px; }
.dash-hero-chip { padding: 5px 12px; }
}
/* ============ 购买订阅：套餐分类筛选（全部 / 按周期 / 按流量） ============ */
.plan-filter { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.plan-tabs { display: inline-flex; align-items: center; gap: 8px; }
.plan-tab {
  padding: 7px 16px;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--bg2);
  color: var(--muted);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
  cursor: pointer;
  transition: border-color 0.18s, background 0.18s, color 0.18s;
}
.plan-tab:hover { border-color: rgba(47, 92, 58, 0.3); color: var(--accent); }
.plan-tab.active { border-color: rgba(47, 92, 58, 0.6); background: var(--accent-soft); color: var(--accent); }
.plan-count { font-size: 13px; color: var(--muted); white-space: nowrap; }
@media (max-width: 900px) {
.plan-filter { margin-bottom: 14px; }
.plan-tab { padding: 6px 14px; font-size: 12.5px; }
}
