/* ==================================================================
   AuthLink 管理端样式 · 浅色「暖纸 + 靛蓝×青瓷」主题
   ------------------------------------------------------------------
   设计决策：
   · 底色 #faf9f6 暖白纸感，卡面 #fffefb 略偏奶白，杜绝纯白刺眼；
   · 主色为「靛蓝 #46549b → 青瓷 #63a58f」的低饱和双色体系，
     点缀一律用这两色及其浅色变体，不做大面积渐变横幅；
   · 卡片大圆角（16px）+ 极轻双层阴影，hover 抬升 2px；
   · 指纹 / 授权码 / IP / app_key 一律等宽字体；
   · 界面全部中文，留白慷慨（面板内边距 22~28px）。
   ================================================================== */

:root {
  --paper: #faf9f6;
  --paper-2: #f3f1ea;
  --card: #fffefb;
  --ink: #33373d;
  --ink-2: #6f7480;
  --ink-3: #a2a7b0;
  --line: #ebe7dd;
  --line-soft: #f1eee6;

  --indigo: #46549b;
  --indigo-deep: #36427e;
  --indigo-soft: #edeff8;
  --celadon: #4f9b83;
  --celadon-soft: #e7f3ed;
  --grad: linear-gradient(120deg, #46549b 0%, #56719f 55%, #4f9b83 100%);

  --amber: #c07a1e;
  --amber-soft: #fbf1df;
  --red: #bb5148;
  --red-soft: #f9e9e7;
  --green: #3e9b6d;

  --radius: 16px;
  --radius-sm: 10px;
  --shadow: 0 10px 28px rgba(72, 66, 50, .07), 0 2px 6px rgba(72, 66, 50, .05);
  --shadow-lift: 0 16px 36px rgba(72, 66, 50, .11), 0 3px 8px rgba(72, 66, 50, .06);

  --mono: "JetBrains Mono", "SFMono-Regular", "Cascadia Mono", Consolas,
          "Courier New", monospace;
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100%;
}

body {
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink);
  background:
    radial-gradient(1100px 480px at 88% -10%, rgba(79, 155, 131, .07), transparent 62%),
    radial-gradient(900px 420px at -8% 108%, rgba(70, 84, 155, .07), transparent 60%),
    var(--paper);
  -webkit-font-smoothing: antialiased;
}

.mono {
  font-family: var(--mono);
  font-size: .92em;
  letter-spacing: .02em;
}

/* ==================== 通用按钮（v1.5.1：三档层次 + 动效） ====================
   层次从强到弱：
     .btn-primary       渐变实底 + 投影 + 悬停上浮 + 流光扫过 —— 每个面板/弹窗只有一颗主操作；
     .btn / .btn-ghost  卡片底 + 描边次级 —— 悬停描边染色 + 上浮
                        （旧版裸 .btn 无底无描边，被吐槽「像一段灰字」，本版补齐）；
     .btn-danger-ghost  危险动作 —— 平时只有红字，悬停才浮出红底。
   动效统一走 transform / box-shadow（不触发重排）；prefers-reduced-motion 整体降级。 */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 9px 18px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  background: var(--card);
  color: var(--ink-2);
  box-shadow: 0 1px 2px rgba(15, 23, 42, .06);
  transition: transform .18s cubic-bezier(.2, .8, .3, 1.2), box-shadow .18s ease,
              background .18s ease, border-color .18s ease, color .18s ease;
  user-select: none;
}
.btn:hover {
  transform: translateY(-1px);
  border-color: var(--celadon);
  color: var(--ink);
  box-shadow: 0 5px 14px rgba(15, 23, 42, .10);
}
.btn:active { transform: translateY(1px); box-shadow: 0 1px 2px rgba(15, 23, 42, .08); }
.btn:focus-visible { outline: 2px solid var(--indigo); outline-offset: 2px; }
.btn[disabled] { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }

.btn-primary {
  background: var(--grad);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 6px 16px rgba(70, 84, 155, .28);
  overflow: hidden;
}
/* 主按钮流光：悬停时一道高光从左扫到右（transform 实现，不触发重排） */
.btn-primary::after {
  content: '';
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: -45%;
  width: 34%;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, .38), transparent);
  transform: skewX(-18deg);
  transition: left .5s ease;
  pointer-events: none;
}
.btn-primary:hover {
  box-shadow: 0 9px 22px rgba(70, 84, 155, .34);
  transform: translateY(-1px);
}
.btn-primary:hover::after { left: 125%; }
.btn-primary[disabled] { opacity: .6; cursor: wait; transform: none; }
.btn-primary[disabled]::after { display: none; }

.btn-ghost {
  background: var(--card);
  border-color: var(--line);
  color: var(--ink-2);
}
.btn-ghost:hover {
  border-color: var(--celadon);
  color: var(--celadon);
  transform: translateY(-1px);
}

.btn-danger-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--red);
}
.btn-danger-ghost:hover {
  background: var(--red-soft);
  border-color: #efcfc9;
  transform: translateY(-1px);
}

.btn-sm { padding: 5px 12px; font-size: 13px; border-radius: 8px; }
.btn-block { width: 100%; }

/* ==================== 登录视图 ==================== */

.login-wrap {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
  overflow: hidden;
}

.login-deco {
  position: absolute;
  border-radius: 50%;
  filter: blur(6px);
  pointer-events: none;
}
.login-deco-a {
  width: 340px; height: 340px;
  right: -90px; top: -110px;
  background: radial-gradient(circle at 35% 35%, rgba(79, 155, 131, .16), rgba(79, 155, 131, 0) 70%);
}
.login-deco-b {
  width: 420px; height: 420px;
  left: -140px; bottom: -160px;
  background: radial-gradient(circle at 60% 40%, rgba(70, 84, 155, .14), rgba(70, 84, 155, 0) 70%);
}

.login-card {
  position: relative;
  width: 100%;
  max-width: 400px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 36px 34px 26px;
  animation: rise-in .38s ease both;
}

@keyframes rise-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

.login-brand {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 26px;
}
.brand-mark {
  display: inline-flex;
  border-radius: 12px;
  box-shadow: 0 6px 14px rgba(70, 84, 155, .22);
}
.brand-mark-sm { border-radius: 9px; }
.brand-title {
  margin: 0;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: .04em;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.brand-sub {
  margin: 1px 0 0;
  font-size: 12.5px;
  color: var(--ink-3);
  letter-spacing: .06em;
}

.field { display: block; margin-bottom: 16px; }
.field-label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  margin-bottom: 6px;
}
.field input {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--ink);
  font: inherit;
  padding: 10px 14px;
  transition: border-color .16s ease, box-shadow .16s ease;
}
.field input:focus {
  outline: none;
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px rgba(70, 84, 155, .13);
}
.field input::placeholder { color: var(--ink-3); }

.login-msg {
  margin: 14px 0 0;
  padding: 9px 13px;
  border-radius: var(--radius-sm);
  background: var(--red-soft);
  border: 1px solid #efcfc9;
  color: var(--red);
  font-size: 13px;
}

.login-foot {
  margin: 20px 0 0;
  text-align: center;
  font-size: 12px;
  color: var(--ink-3);
}

/* ==================== 应用骨架 ==================== */

.app-shell {
  display: grid;
  grid-template-columns: 232px 1fr;
  min-height: 100vh;
}

.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--card);
  border-right: 1px solid var(--line);
  padding: 22px 16px 18px;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 2px 8px 18px;
  border-bottom: 1px dashed var(--line);
}
.sidebar-brand-name {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: .05em;
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.side-nav {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 16px;
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  border: none;
  background: transparent;
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font: inherit;
  font-weight: 600;
  color: var(--ink-2);
  cursor: pointer;
  text-align: left;
  position: relative;
  transition: background .16s ease, color .16s ease;
}
.nav-item:hover { background: var(--paper-2); color: var(--ink); }
.nav-item.is-active {
  background: var(--indigo-soft);
  color: var(--indigo-deep);
}
.nav-item.is-active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 18px;
  border-radius: 0 3px 3px 0;
  background: var(--grad);
}
.nav-ico { font-size: 15px; width: 18px; text-align: center; }

.sidebar-foot { margin-top: auto; }
/* v1.2.5：左下角新增「版本」行，与「应用标识」行之间留呼吸间距 */
.sidebar-foot .side-meta + .side-meta { margin-top: 8px; }
.side-version { color: var(--ink-2); font-size: 12px; }
.side-meta {
  background: var(--paper-2);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
}
.side-meta-label {
  display: block;
  font-size: 11.5px;
  color: var(--ink-3);
  letter-spacing: .05em;
  margin-bottom: 3px;
}
.side-appkey {
  color: var(--celadon);
  font-size: 12px;
  word-break: break-all;
}

/* 顶栏 */
.main-col { display: flex; flex-direction: column; min-width: 0; }

.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 30px;
  background: rgba(250, 249, 246, .88);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line-soft);
}
.topbar-title {
  margin: 0;
  font-size: 17px;
  font-weight: 700;
}
.topbar-tools {
  display: flex;
  align-items: center;
  gap: 12px;
}
.health-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ink-3);
  box-shadow: 0 0 0 3px rgba(0, 0, 0, .04);
  transition: background .3s ease;
}
.health-dot.is-ok { background: var(--green); box-shadow: 0 0 0 3px rgba(62, 155, 109, .16); }
.health-dot.is-bad { background: var(--red); box-shadow: 0 0 0 3px rgba(187, 81, 72, .16); }
.health-text { font-size: 12.5px; color: var(--ink-2); }

/* 内容区 */
.content { padding: 26px 30px 46px; }

.view { animation: fade-view .24s ease both; }
@keyframes fade-view {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ==================== 仪表盘 ==================== */

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px;
  margin-bottom: 22px;
}
.stat-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px 22px 17px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  transition: transform .18s ease, box-shadow .18s ease;
}
.stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.stat-num {
  font-size: 30px;
  font-weight: 800;
  font-family: var(--mono);
  line-height: 1.2;
}
.stat-label { font-size: 12.5px; color: var(--ink-3); letter-spacing: .04em; }
.stat-ok .stat-num { color: var(--celadon); }
.stat-warn .stat-num { color: var(--amber); }
.stat-bad .stat-num { color: var(--red); }

/* ==================== 面板与表格 ==================== */

.panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 17px 22px 15px;
  border-bottom: 1px solid var(--line-soft);
}
.panel-title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
}

.table-scroll { overflow-x: auto; }

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  min-width: 760px;
}
.data-table th {
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
  letter-spacing: .05em;
  padding: 11px 16px;
  background: var(--paper-2);
  border-bottom: 1px solid var(--line-soft);
  white-space: nowrap;
}
.data-table td {
  padding: 13px 16px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.data-table tbody tr { transition: background .14s ease; }
.data-table tbody tr:hover { background: #fcfbf6; }
.data-table tbody tr:last-child td { border-bottom: none; }
.th-act { text-align: right; }
.td-act { text-align: right; white-space: nowrap; }
/* v1.5.2：购买订单的「操作」列（补发 / 编辑 / 删除 三枚小按钮并排）。
   用相邻兄弟选择器出间距 —— 不依赖每行渲染几个按钮，也不会在首枚按钮左侧多出空隙。 */
.order-acts { text-align: right; white-space: nowrap; }
.order-acts .btn + .btn { margin-left: 6px; }
.table-empty {
  text-align: center;
  color: var(--ink-3);
  padding: 34px 16px !important;
}

.cell-domain { font-weight: 600; }
.cell-dim { color: var(--ink-3); }
.cell-mono {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-2);
  word-break: break-all;
}

/* ==================== 徽标与开关 ==================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: 999px;
  padding: 3px 11px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
.badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
.badge-on  { background: var(--celadon-soft); color: var(--celadon); }
.badge-off { background: var(--paper-2); color: var(--ink-3); }
.badge-warn { background: var(--amber-soft); color: var(--amber); }
.badge-bad { background: var(--red-soft); color: var(--red); }

.expire-warn {
  color: var(--amber);
  font-weight: 600;
}

/* 启停开关 */
.switch {
  position: relative;
  display: inline-block;
  width: 42px;
  height: 24px;
  vertical-align: middle;
}
.switch input {
  position: absolute;
  opacity: 0;
  /* v1.2.9：热区内缩 4px。原先铺满整个 label（z-index:2），而右侧紧邻「编辑」按钮，
     点按钮左缘会命中开关 —— 这正是「点编辑误触启停」的根因。
     内缩后热区只覆盖轨道中心，边界清晰；轨道本身仍整体可点（label 兜底）。 */
  inset: 4px 5px;
  width: auto;
  height: auto;
  margin: 0;
  cursor: pointer;
  z-index: 2;
}
.switch-track {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #ddd8cc;
  transition: background .22s ease, box-shadow .22s ease;
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(40, 36, 24, .3);
  transition: transform .26s cubic-bezier(.34, 1.4, .5, 1);
}
/* 按下时轨道轻微内缩 —— 给「点到了」的即时手感（配合 bug 修复，用户敢连续点） */
.switch input:active + .switch-track{box-shadow: inset 0 0 0 2px rgba(70, 84, 155, .22)}
.switch input:checked + .switch-track { background: var(--celadon); box-shadow: 0 0 0 3px rgba(70, 84, 155, .08); }
.switch input:checked + .switch-track::after { transform: translateX(18px); }
.switch input:focus-visible + .switch-track {
  outline: 2px solid var(--indigo);
  outline-offset: 2px;
}
.switch.is-busy { opacity: .55; pointer-events: none; }
/* v1.2.8：请求进行中的旋转指示（原来只有变淡，看不出在忙） */
.switch.is-busy .switch-track::before{
  content:"";position:absolute;inset:0;border-radius:999px;
  background:conic-gradient(from 0deg,transparent 0 62%,rgba(255,255,255,.75) 78%,transparent 100%);
  animation:actSpin .7s linear infinite;
}
@keyframes actSpin{to{transform:rotate(360deg)}}

/* v1.4.4：异常行开关的外观提示（与「请求忙」的 is-busy 彻底分离）。
   is-busy = 请求进行中，短暂 pointer-events:none；is-abn = 异常状态提示，
   只做视觉（半透明 + 红调轨道 + 虚线描边），**必须保持可点击** ——
   点击语义 = 恢复启用（服务端 adminSetStatus 支持 2→1）。
   曾经两者共用 is-busy，导致异常行看起来像坏了且永远点不了。 */
.switch.is-abn { opacity: .72; }
.switch.is-abn .switch-track { background: var(--red-soft); box-shadow: inset 0 0 0 1px var(--red); }
.switch.is-abn:hover .switch-track { box-shadow: inset 0 0 0 1px var(--red), 0 0 0 3px var(--red-soft); }
.switch.is-abn input:checked + .switch-track { background: var(--celadon); box-shadow: none; }

/* 动效降级：系统开启「减弱动态效果」时，以上所有动画/过渡一律静止 */
@media (prefers-reduced-motion: reduce) {
  .act-btn, .act-btn::after, .switch-track, .switch-track::after { transition: none; }
  .act-btn:hover, .act-btn:active { transform: none; }
  .act-btn:hover::after { transform: none; }
  .act-btn.is-del:hover { animation: none; }
  .switch.is-busy .switch-track::before { animation: none; }
}

/* ==================== 最近动态列表 ==================== */

.recent-list {
  list-style: none;
  margin: 0;
  padding: 6px 22px;
}
.recent-list li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px dashed var(--line-soft);
}
.recent-list li:last-child { border-bottom: none; }
.recent-empty { color: var(--ink-3); justify-content: center; }
.recent-time { margin-left: auto; color: var(--ink-3); font-size: 12.5px; white-space: nowrap; }

/* ==================== Toast ==================== */

.toast-box {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 999;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
.toast {
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 3px solid var(--celadon);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lift);
  padding: 10px 18px;
  font-size: 13.5px;
  animation: toast-in .22s ease both;
}
.toast.is-err { border-left-color: var(--red); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: none; }
}

/* ==================== 响应式 ==================== */

@media (max-width: 860px) {
  .app-shell { grid-template-columns: 1fr; }
  .sidebar {
    position: static;
    height: auto;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    border-right: none;
    border-bottom: 1px solid var(--line);
  }
  .sidebar-brand { border-bottom: none; padding-bottom: 0; }
  .side-nav { flex-direction: row; margin-top: 0; }
  .sidebar-foot { display: none; }
  .topbar, .content { padding-left: 16px; padding-right: 16px; }
}

/* ==================== hidden 语义强制 ====================
   .login-wrap(display:flex) 与 .app-shell(display:grid) 会覆盖 hidden 属性
   ⇒ 登录页与主界面同时常驻、视图切换全部失灵（点登录「没反应」的根因）。
   此规则让 hidden 属性在一切自定义 display 之下仍然生效。 */
[hidden] { display: none !important; }

/* ==================== 授权码 生成/编辑 弹层 ==================== */
.lic-modal{border:0;border-radius:16px;padding:0;width:min(460px,92vw);
           box-shadow:0 18px 50px rgba(40,45,80,.25)}
.lic-modal::backdrop{background:rgba(43,43,51,.4);backdrop-filter:blur(2px)}
.lic-modal form{padding:24px 26px;display:flex;flex-direction:column;gap:12px}
.lic-modal h3{margin:0 0 4px;font-size:17px;color:#2b2b33}
.lic-modal .field{display:flex;flex-direction:column;gap:5px;font-size:12.5px;color:#6b6b78}
.lic-modal .field input,.lic-modal .field select{border:1px solid #e9e5dc;border-radius:9px;
  padding:9px 12px;font-size:13.5px;background:#fff;outline:none;font-family:inherit}
.lic-modal .field input:focus,.lic-modal .field select:focus{border-color:#46549b}
.lic-plain{margin:2px 0 0;background:#eef4f1;border:1px solid #cfe3da;border-radius:9px;
  padding:9px 12px;font-family:'JetBrains Mono',Consolas,monospace;font-size:14px;
  letter-spacing:.05em;color:#2f6f5c;word-break:break-all}
.lic-msg{margin:0;color:#b3403a;font-size:12.5px}
.lic-actions{display:flex;justify-content:flex-end;gap:9px;margin-top:6px}
.panel-tools{display:flex;gap:8px;align-items:center}
/* v1.2.9：授权行「已被拉黑」视觉标记 —— 整行左侧红条 + 绑定列下方红标 */
tr.is-blacklisted > td{background:rgba(179,64,58,.035)}
tr.is-blacklisted > td:first-child{box-shadow:inset 3px 0 0 var(--red)}
.bl-flag{
  display:inline-block;margin-top:5px;padding:2px 8px;border-radius:999px;
  font-size:11px;font-weight:500;line-height:1.6;
  color:var(--red);background:var(--red-soft);border:1px solid rgba(179,64,58,.22);
  white-space:nowrap;
}
/* v1.2.9：面板内搜索框（黑名单/离线授权列表筛选） */
.panel-search{
  border:1px solid #e6e2d8;background:#fff;border-radius:8px;
  padding:5px 10px;font-size:12.5px;color:#2b2b33;outline:none;
  min-width:170px;font-family:inherit;transition:border-color .18s ease,box-shadow .18s ease;
}
.panel-search:focus{border-color:#46549b;box-shadow:0 0 0 3px rgba(70,84,155,.10)}
.panel-search::placeholder{color:#a2a7b0}
html[data-theme="apple"] .panel-search,
html[data-theme="glass"] .panel-search{border-color:rgba(120,130,170,.30)}
.row-act{display:inline-flex;gap:8px;align-items:center}
/* v1.2.8 行内动作按钮重做：语义色 + 悬停位移 + 光泽扫过 + 按压回弹。
   要点：① 每种动作一个语义色（编辑靛蓝 / 拉黑琥珀 / 删除砖红），不再一律灰；
        ② hover 上浮 1px + 阴影，active 回弹下沉（真实反馈，不是纯变色）；
        ③ ::after 高光斜切扫过 —— 悬停时从左划到右一次，克制不循环；
        ④ 全部走 prefers-reduced-motion 降级（系统开减弱动效时全部静止）。
   v1.2.9 追加（站长反馈「点编辑误触开关、按钮挤在一起」）：
        ⑤ 开关与按钮组之间加**竖分隔线 + 留白**，物理隔开「启停区」与「操作区」；
        ⑥ 开关透明热区内缩（见 .switch input），不再与右侧按钮抢点击。 */
.row-act .switch{margin-right:4px}
.row-act .switch + .act-btn{position:relative;margin-left:8px}
.row-act .switch + .act-btn::before{
  content:"";position:absolute;left:-5px;top:50%;transform:translateY(-50%);
  width:1px;height:16px;background:#e6e2d8;pointer-events:none;
}
.act-btn{
  position:relative;overflow:hidden;
  display:inline-flex;align-items:center;gap:4px;
  border:1px solid #e6e2d8;background:#fff;border-radius:8px;
  padding:4px 10px;font-size:12px;line-height:1.6;
  color:#6b6b78;cursor:pointer;white-space:nowrap;
  transition:color .18s ease,border-color .18s ease,background .18s ease,
             transform .18s cubic-bezier(.2,.9,.3,1),box-shadow .18s ease;
}
.act-btn::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(115deg,transparent 38%,rgba(255,255,255,.85) 50%,transparent 62%);
  transform:translateX(-130%);
  transition:transform .5s cubic-bezier(.3,.8,.3,1);
}
.act-btn:hover{transform:translateY(-1px)}
.act-btn:active{transform:translateY(0) scale(.96)}
.act-btn:hover::after{transform:translateX(130%)}
.act-btn:focus-visible{outline:2px solid var(--indigo);outline-offset:2px}
.act-btn[disabled]{opacity:.55;cursor:not-allowed;transform:none}
/* 编辑：靛蓝 */
.act-edit:hover{color:#fff;background:#46549b;border-color:#46549b;
  box-shadow:0 6px 14px -6px rgba(70,84,155,.65)}
/* 拉黑：琥珀（警示但不报 destructive，避免与删除抢注意力） */
.act-bl:hover{color:#8a5a12;background:#fdf3e0;border-color:#e8c98a;
  box-shadow:0 6px 14px -6px rgba(180,130,40,.55)}
/* v1.2.9：已拉黑态 —— 按钮变「解除」语义（砖红实心），一眼可辨当前是拉黑中 */
.act-bl.is-on{color:#b3403a;border-color:#e6bfbc;background:#fdf4f3}
.act-bl.is-on:hover{color:#fff;background:#b3403a;border-color:#b3403a;
  box-shadow:0 6px 14px -6px rgba(179,64,58,.6)}
/* 删除：砖红 + 悬停微横向抖动（危险动作的语义提示） */
.act-btn.is-del:hover{color:#fff;background:#b3403a;border-color:#b3403a;
  box-shadow:0 6px 14px -6px rgba(179,64,58,.6);animation:actShake .32s ease}
@keyframes actShake{
  0%,100%{transform:translateX(0)}
  25%{transform:translateX(-2px)}
  75%{transform:translateX(2px)}
}
/* 拉黑开关命中态：开关本体染色，一眼看出该站已被拉黑 */
.row-act.is-bl .switch-track{background:#d98b2b}
.row-act.is-bl .switch input:checked + .switch-track{background:#b3403a}

/* ==================== v1.1.0 新增组件 ==================== */

/* ---- 批量工具条（勾选授权码后出现） ---- */
.batch-bar{display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  padding:11px 18px;background:#eef2fb;border-bottom:1px solid #dfe5f4}
.batch-info{font-size:13px;color:#46549b;font-weight:600}
.batch-info b{font-family:var(--mono);font-size:14px}
.td-check,.th-check{width:36px;text-align:center}
.td-check input,.th-check input{width:15px;height:15px;cursor:pointer;accent-color:#4f9b83}
.lic-code{font-size:12px;color:#2f5d4e;word-break:break-all}

/* ---- 系统设置 ---- */
.settings-panel{max-width:760px}
.settings-body{padding:20px 24px 24px}
.settings-body .field{margin-bottom:18px}
/* v1.2.5：黑名单视图 —— 说明条 + 表单网格（复用 field/按钮令牌，无新色板） */
.hint-text{
  margin:0 0 18px;padding:11px 14px;border-radius:var(--radius-sm);
  font-size:12.5px;line-height:1.7;color:var(--ink-2);
  background:var(--paper-2);border:1px solid var(--line-soft);
}
.hint-text b{color:var(--ink);font-weight:600}
.bl-form{display:flex;flex-wrap:wrap;align-items:flex-end;gap:14px}
.bl-form .field{flex:1 1 260px;margin-bottom:0}
.bl-form .field-label{font-size:12.5px}
/* v1.5.1：用户列表筛选栏 —— 与 .field / .settings-body 同一套控件观感；
   主题覆盖（glass / tech）见文件尾部对应主题块的选择器列表。 */
.user-filter-bar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:14px}
.user-filter-bar input[type="text"]{
  flex:1 1 220px;min-width:0;font:inherit;font-size:13px;color:var(--ink);
  border:1px solid var(--line);border-radius:var(--radius-sm);background:#fff;
  padding:8px 12px;outline:none;
  transition:border-color .16s ease,box-shadow .16s ease}
.user-filter-bar input[type="text"]:focus{
  border-color:var(--indigo);box-shadow:0 0 0 3px rgba(70,84,155,.13)}
.user-filter-bar select{
  font:inherit;font-size:13px;color:var(--ink);border:1px solid var(--line);
  border-radius:var(--radius-sm);background:#fff;padding:8px 10px;cursor:pointer}
.settings-body select,.settings-body textarea{
  width:100%;border:1px solid var(--line);border-radius:var(--radius-sm);
  background:#fff;color:var(--ink);font:inherit;padding:10px 14px;
  transition:border-color .16s ease,box-shadow .16s ease}
.settings-body select:focus,.settings-body textarea:focus{
  outline:none;border-color:var(--indigo);
  box-shadow:0 0 0 3px rgba(70,84,155,.13)}
.settings-body textarea{resize:vertical;font-family:var(--mono);font-size:13px}
.field-switch{display:flex;align-items:flex-start;justify-content:space-between;gap:18px}
.field-switch .field-label{flex:1;margin-bottom:0}
.field-switch em{display:block;font-style:normal;font-weight:400;
  font-size:12px;color:var(--ink-3);margin-top:4px}
/* v1.5.0：普通字段的副说明（与开关字段的 em 同一套观感） */
.field-label em{display:block;font-style:normal;font-weight:400;
  font-size:11.5px;line-height:1.6;color:var(--ink-3);margin-top:3px}
.settings-hint{margin:6px 0 0;font-size:12px;color:var(--ink-3);
  padding-top:14px;border-top:1px dashed var(--line-soft)}

/* v1.3.0：系统设置分组（注册验证 / 邮件服务）—— 组间虚线分隔，组内复用 field 令牌 */
.settings-group{margin:22px 0 0;padding-top:18px;border-top:1px dashed var(--line-soft)}
.settings-group-title{margin:0 0 14px;font-size:13px;font-weight:700;
  letter-spacing:.04em;color:var(--ink-2)}
.field-row{display:flex;gap:14px}
.field-row .field{flex:1 1 0;min-width:0}
/* v1.5.1：同一行字段的输入控件**底对齐** ——
   .field-row 是 flex，各 .field 等宽；但每个 .field-label 的副说明（<em>）行数不同
   （「免费领取数量」两行 / 「免费码有效期」没有），旧版两列的输入框一个被顶下去、
   一个留在上方，看起来就是「错位」（站长截图反馈）。
   修法：.field 变纵向 flex 容器，输入控件 margin-top:auto 沉底 ——
   副说明无论几行，同一行的输入框永远共享同一条底线。 */
.field-row{align-items:stretch}
.field-row .field{display:flex;flex-direction:column}
.field-row .field>input,.field-row .field>select{margin-top:auto}

/* ==================== v1.5.0：系统设置重排 ====================
   原状：15+ 个控件平铺成一列（内容高 ≈1.5~2 屏），找「邮箱」「阻断」只能一路滚。
   现为：左侧分类导航（sticky） + 右侧单板块显示 —— 任何一项最多两次点击可达，
   且左侧永远显示「当前在哪一类」。
   全部用既有令牌（--card / --line / --paper-2 / --indigo-… / --radius-…），四套主题自动跟随。
   ⚠⚠ 这条注释里**绝不能出现「星号紧跟斜杠」那两个字符**（注释的结束符本身）：
     原来写 `--indigo` + 结束符 + `--radius*`，那个结束符把注释**提前终止**了，
     剩下半行变成非法 CSS；浏览器的错误恢复会顺势吃掉紧随其后的
     `.settings-layout{display:grid;…}` 整条规则 ——
     表现是「左导航 + 右舞台」直接退化成上下堆叠，而 computedStyle 只告诉你
     `display:block`，看不出是注释惹的祸。真机探针 check 7 抓到的就是这个。 */
.settings-layout{display:grid;grid-template-columns:238px minmax(0,1fr);gap:20px;align-items:start}
.settings-nav{
  position:sticky;top:16px;
  display:flex;flex-direction:column;gap:4px;
  padding:14px 12px;border-radius:var(--radius);
  background:var(--card);border:1px solid var(--line);box-shadow:var(--shadow)}
.settings-nav-head{
  margin:2px 8px 8px;font-size:10.5px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-3)}
.snav-item{
  position:relative;display:flex;align-items:center;gap:10px;width:100%;
  padding:10px 12px;border:1px solid transparent;border-radius:var(--radius-sm);
  background:transparent;color:var(--ink-2);font:inherit;text-align:left;cursor:pointer;
  transition:background .16s ease,color .16s ease,border-color .16s ease,transform .16s ease}
.snav-item:hover{background:var(--paper-2);color:var(--ink);transform:translateX(2px)}
.snav-item.is-active{
  background:var(--indigo-soft);color:var(--indigo-deep);
  border-color:var(--line-soft)}
/* 选中态左侧竖条：一眼看出「当前在哪一类」，且不靠颜色单独承载语义 */
.snav-item.is-active::before{
  content:'';position:absolute;left:-12px;top:7px;bottom:7px;width:3px;
  border-radius:0 3px 3px 0;background:var(--indigo)}
.snav-ico{
  flex:none;width:26px;height:26px;display:grid;place-items:center;
  border-radius:8px;background:var(--paper-2);font-size:13px;line-height:1}
.snav-item.is-active .snav-ico{background:var(--card)}
.snav-tx{display:flex;flex-direction:column;gap:2px;min-width:0}
.snav-tx b{font-size:13px;font-weight:600}
.snav-tx i{
  font-style:normal;font-size:11px;color:var(--ink-3);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.snav-foot{
  display:flex;flex-direction:column;gap:8px;margin-top:10px;padding-top:12px;
  border-top:1px dashed var(--line-soft)}
.snav-hint{margin:0;font-size:11px;line-height:1.55;color:var(--ink-3)}
.settings-stage{min-width:0}
.settings-section{
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  box-shadow:var(--shadow);animation:secIn .22s ease}
@keyframes secIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.sec-head{
  display:flex;align-items:flex-start;justify-content:space-between;gap:14px;
  padding:18px 24px 15px;border-bottom:1px solid var(--line-soft)}
.sec-title{margin:0;font-size:15px;font-weight:700;color:var(--ink)}
.sec-sub{margin:6px 0 0;font-size:12.5px;line-height:1.65;color:var(--ink-3)}
.sec-chip{
  flex:none;padding:4px 11px;border-radius:999px;font-size:11.5px;font-weight:600;
  background:var(--paper-2);color:var(--ink-2);border:1px solid var(--line-soft);
  white-space:nowrap}
.sec-chip.is-on{background:var(--indigo-soft);color:var(--indigo-deep);border-color:transparent}
.sec-chip.is-warn{background:var(--amber-soft);color:#8a5a00;border-color:transparent}
.sec-notes{
  margin:14px 0 0;padding-left:18px;font-size:12.5px;line-height:1.9;color:var(--ink-2)}
.sec-notes li{margin-bottom:2px}
.sec-notes b{color:var(--ink);font-weight:600}
.pay-entry{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  margin-top:18px;padding:14px 16px;border-radius:var(--radius-sm);
  background:var(--paper-2);border:1px solid var(--line-soft)}
.pay-entry b{font-size:13px;color:var(--ink)}
.pay-entry p{margin:4px 0 0;font-size:12px;color:var(--ink-3)}
@media (max-width:1100px){
  .settings-layout{grid-template-columns:1fr}
  .settings-nav{position:static;flex-direction:row;flex-wrap:wrap}
  .snav-item{width:auto}
  .snav-tx i{display:none}
  .snav-foot{flex:1 1 100%;flex-direction:row;align-items:center;justify-content:flex-end}
}
@media (prefers-reduced-motion:reduce){
  .settings-section{animation:none}
  .snav-item{transition:none}
  /* v1.5.1：按钮动效一并降级（流光直接不渲染） */
  .btn{transition:none}
  .btn:hover,.btn-ghost:hover,.btn-danger-ghost:hover,.btn-primary:hover{transform:none}
  .btn-primary::after{display:none}
}

/* ==================== 主题：🍎 苹果风 ====================
   设计语言：更亮的冷白底、纯蓝主色、超大圆角、几乎无边的柔和阴影、
   SF 系字体栈优先 —— 贴近 macOS / iOS 系统偏好设置面板的气质。 */
html[data-theme="apple"] {
  --paper: #f5f6f8;
  --paper-2: #eceef2;
  --card: #ffffff;
  --ink: #1d1d1f;
  --ink-2: #6e6e73;
  --ink-3: #a1a1a6;
  --line: #e5e5ea;
  --line-soft: #f0f0f3;
  --indigo: #0a84ff;
  --indigo-deep: #0060df;
  --indigo-soft: #e8f1ff;
  --celadon: #30a46c;
  --celadon-soft: #e6f6ee;
  --grad: linear-gradient(135deg, #0a84ff 0%, #5e5ce6 100%);
  --amber: #b8860b;
  --amber-soft: #fdf3d8;
  --red: #e5484d;
  --red-soft: #fdebec;
  --green: #30a46c;
  --radius: 20px;
  --radius-sm: 12px;
  --shadow: 0 8px 24px rgba(0, 0, 0, .06), 0 1px 2px rgba(0, 0, 0, .04);
  --shadow-lift: 0 14px 34px rgba(0, 0, 0, .10), 0 2px 6px rgba(0, 0, 0, .05);
}
html[data-theme="apple"] body {
  background:
    radial-gradient(1000px 460px at 85% -12%, rgba(10, 132, 255, .06), transparent 60%),
    radial-gradient(820px 400px at -6% 106%, rgba(94, 92, 230, .05), transparent 58%),
    var(--paper);
}
html[data-theme="apple"] .brand-title,
html[data-theme="apple"] .sidebar-brand-name {
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
}
html[data-theme="apple"] .brand-title {
  -webkit-text-fill-color: transparent;
}

/* ==================== 主题：🧊 毛玻璃 ====================
   设计语言：彩色柔光渐变打底 + 半透明卡面 + backdrop blur ——
   玻璃拟态（glassmorphism），边框高光、阴影更飘。 */
html[data-theme="glass"] {
  --paper: #eef0f7;
  --paper-2: rgba(255, 255, 255, .55);
  --card: rgba(255, 255, 255, .62);
  --ink: #2a2d3a;
  --ink-2: #5d6273;
  --ink-3: #9aa0b4;
  --line: rgba(255, 255, 255, .65);
  --line-soft: rgba(120, 130, 170, .14);
  --indigo: #5b6bd6;
  --indigo-deep: #4353b8;
  --indigo-soft: rgba(91, 107, 214, .16);
  --celadon: #3aa186;
  --celadon-soft: rgba(58, 161, 134, .16);
  --grad: linear-gradient(120deg, #5b6bd6 0%, #9a5bd6 55%, #3aa186 100%);
  --amber: #b07a18;
  --amber-soft: rgba(214, 164, 60, .18);
  --red: #d05353;
  --red-soft: rgba(208, 83, 83, .14);
  --green: #3aa186;
  --radius: 18px;
  --radius-sm: 12px;
  --shadow: 0 10px 30px rgba(60, 70, 120, .12), inset 0 1px 0 rgba(255, 255, 255, .55);
  --shadow-lift: 0 16px 40px rgba(60, 70, 120, .18), inset 0 1px 0 rgba(255, 255, 255, .6);
}
html[data-theme="glass"] body {
  background:
    radial-gradient(720px 520px at 12% 8%, rgba(91, 107, 214, .20), transparent 60%),
    radial-gradient(680px 480px at 88% 18%, rgba(154, 91, 214, .16), transparent 62%),
    radial-gradient(760px 560px at 55% 100%, rgba(58, 161, 134, .18), transparent 60%),
    linear-gradient(160deg, #eef0f7 0%, #e8ebf5 100%);
  background-attachment: fixed;
}
html[data-theme="glass"] .panel,
html[data-theme="glass"] .stat-card,
html[data-theme="glass"] .login-card,
html[data-theme="glass"] .lic-modal {
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  border: 1px solid rgba(255, 255, 255, .65);
}
html[data-theme="glass"] .sidebar {
  background: rgba(255, 255, 255, .5);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  border-right: 1px solid rgba(255, 255, 255, .65);
}
html[data-theme="glass"] .topbar {
  background: rgba(238, 240, 247, .55);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
html[data-theme="glass"] .data-table th { background: rgba(255, 255, 255, .4); }
html[data-theme="glass"] .data-table tbody tr:hover { background: rgba(255, 255, 255, .45); }
html[data-theme="glass"] .side-meta { background: rgba(255, 255, 255, .45); }
html[data-theme="glass"] .settings-body select,
html[data-theme="glass"] .settings-body textarea,
html[data-theme="glass"] .field input,
html[data-theme="glass"] .user-filter-bar input[type="text"],
html[data-theme="glass"] .user-filter-bar select {
  background: rgba(255, 255, 255, .7);
}
html[data-theme="glass"] .brand-title,
html[data-theme="glass"] .sidebar-brand-name {
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
html[data-theme="glass"] .switch-track { background: rgba(120, 130, 170, .35); }

/* ==================== 主题：🛰 科技风（任务控制台） ====================
   finesse · register=product · A=cyan/phosphor on deep-blue-black · B=700/400
   C=sidebar+table shell · D=Canvas particle-net（唯一重特效）+CSS beats
   E=mission-control · SOUL=7 SPECTACLE=6 DENSITY=7
   语言：深空蓝黑底 + 青色荧光主色 + 等宽数据高亮；表格保持高密度可读，
   特效只出现在「氛围层」（粒子网络 / 流光描边 / 扫描光），不进数据层。 */
html[data-theme="tech"] {
  --paper: #0a0f1a;
  --paper-2: #111a2c;
  --card: #0e1626;
  --ink: #d7e4f5;
  --ink-2: #8aa0bd;
  --ink-3: #5a7091;
  --line: rgba(34, 211, 238, .14);
  --line-soft: rgba(34, 211, 238, .08);
  --indigo: #22d3ee;
  --indigo-deep: #67e8f9;
  --indigo-soft: rgba(34, 211, 238, .10);
  --celadon: #34d399;
  --celadon-soft: rgba(52, 211, 153, .12);
  --grad: linear-gradient(120deg, #22d3ee 0%, #34d399 100%);
  --amber: #fbbf24;
  --amber-soft: rgba(251, 191, 36, .12);
  --red: #fb7185;
  --red-soft: rgba(251, 113, 133, .12);
  --green: #34d399;
  --radius: 14px;
  --radius-sm: 9px;
  --shadow: 0 10px 30px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(34, 211, 238, .08);
  --shadow-lift: 0 16px 40px rgba(0, 0, 0, .55), 0 0 0 1px rgba(34, 211, 238, .18);
  --mono: "JetBrains Mono", "SFMono-Regular", "Cascadia Mono", Consolas, monospace;
}
html[data-theme="tech"] body {
  background: var(--paper);
  color-scheme: dark;
}
/* 氛围层：粒子网络画布（admin.js 渲染）+ 网格 + 暗角 */
html[data-theme="tech"] #tech-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  display: block;
  pointer-events: none;
}
html[data-theme="tech"] .app-shell,
html[data-theme="tech"] .login-wrap { position: relative; z-index: 1; }
html[data-theme="tech"] .panel,
html[data-theme="tech"] .stat-card,
html[data-theme="tech"] .login-card,
html[data-theme="tech"] .lic-modal {
  background: rgba(14, 22, 38, .82);
  border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
html[data-theme="tech"] .sidebar {
  background: rgba(10, 15, 26, .78);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-right: 1px solid var(--line);
}
html[data-theme="tech"] .topbar {
  background: rgba(10, 15, 26, .72);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
html[data-theme="tech"] .brand-title,
html[data-theme="tech"] .sidebar-brand-name {
  background: var(--grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
html[data-theme="tech"] .data-table th {
  background: rgba(34, 211, 238, .05);
  color: #67e8f9;
  text-transform: uppercase;
  letter-spacing: .09em;
  line-height: 1.4;
}
html[data-theme="tech"] .data-table tbody tr:hover { background: rgba(34, 211, 238, .06); }
html[data-theme="tech"] .side-meta { background: rgba(34, 211, 238, .06); }
html[data-theme="tech"] .side-appkey { color: #67e8f9; }
html[data-theme="tech"] .field input,
html[data-theme="tech"] .field select,
html[data-theme="tech"] .settings-body select,
html[data-theme="tech"] .settings-body textarea,
html[data-theme="tech"] .user-filter-bar input[type="text"],
html[data-theme="tech"] .user-filter-bar select,
html[data-theme="tech"] .lic-modal .field input,
html[data-theme="tech"] .lic-modal .field select {
  background: rgba(10, 15, 26, .85);
  border-color: var(--line);
  color: var(--ink);
}
html[data-theme="tech"] .field input:focus {
  border-color: var(--indigo);
  box-shadow: 0 0 0 3px rgba(34, 211, 238, .18);
}
html[data-theme="tech"] .lic-plain {
  background: rgba(52, 211, 153, .08);
  border-color: rgba(52, 211, 153, .3);
  color: #6ee7b7;
}

/* beat② 侧栏激活项：流动霓虹描边（CSS beat，conic 旋转边框） */
html[data-theme="tech"] .nav-item { color: var(--ink-2); }
html[data-theme="tech"] .nav-item:hover { background: rgba(34, 211, 238, .07); color: var(--ink); }
html[data-theme="tech"] .nav-item.is-active {
  background: var(--indigo-soft);
  color: #a5f3fc;
}
html[data-theme="tech"] .nav-item.is-active::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(from var(--nav-spin, 0deg),
    rgba(34, 211, 238, 0) 0deg, rgba(34, 211, 238, .85) 60deg,
    rgba(52, 211, 153, .55) 120deg, rgba(34, 211, 238, 0) 200deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: nav-spin 4.5s linear infinite;
  pointer-events: none;
}
@keyframes nav-spin { to { --nav-spin: 360deg; } }
@property --nav-spin { syntax: '<angle>'; inherits: false; initial-value: 0deg; }

/* beat③ 统计卡：扫描光扫过 + 数字荧光 */
html[data-theme="tech"] .stat-card { position: relative; overflow: hidden; }
html[data-theme="tech"] .stat-card::after {
  content: "";
  position: absolute;
  left: -60%;
  top: 0;
  width: 45%;
  height: 100%;
  background: linear-gradient(105deg, transparent 0%, rgba(34, 211, 238, .10) 50%, transparent 100%);
  animation: stat-scan 5.2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes stat-scan {
  0%, 55% { left: -60%; }
  85%, 100% { left: 130%; }
}
html[data-theme="tech"] .stat-num { text-shadow: 0 0 22px rgba(34, 211, 238, .35); }
html[data-theme="tech"] .stat-ok .stat-num { color: #34d399; }
html[data-theme="tech"] .stat-warn .stat-num { color: #fbbf24; }
html[data-theme="tech"] .stat-bad .stat-num { color: #fb7185; }

/* beat④ 登录卡：呼吸光环 + 顶部扫描线 */
html[data-theme="tech"] .login-card {
  animation: rise-in .38s ease both, login-halo 3.6s ease-in-out 0.4s infinite;
}
html[data-theme="tech"] .login-card::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 2px;
  background: var(--grad);
  opacity: .85;
  animation: login-scanline 3.2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes login-halo {
  0%, 100% { box-shadow: 0 0 40px rgba(34, 211, 238, .12), var(--shadow); }
  50% { box-shadow: 0 0 64px rgba(34, 211, 238, .28), var(--shadow); }
}
@keyframes login-scanline {
  0%, 100% { opacity: .25; }
  50% { opacity: .95; }
}
html[data-theme="tech"] .btn-primary {
  background: var(--grad);
  color: #06121c;
  box-shadow: 0 6px 18px rgba(34, 211, 238, .30);
}
html[data-theme="tech"] .btn-ghost {
  background: rgba(34, 211, 238, .05);
  border-color: var(--line);
  color: var(--ink-2);
}
html[data-theme="tech"] .btn-ghost:hover { border-color: var(--indigo); color: #a5f3fc; }
html[data-theme="tech"] .badge-on { color: #34d399; }
html[data-theme="tech"] .badge-bad { color: #fb7185; }
/* v1.4.4：tech 主题下「禁用」徽标原用 --ink-3(#5a7091) 对 #111a2c 只有 3.4:1，
   在深底上发灰难认（站长反馈「状态显示异常」的视觉部分）。提亮一档到 ≥4.5:1。 */
html[data-theme="tech"] .badge-off { color: #93a7c8; }
html[data-theme="tech"] .toast {
  background: rgba(14, 22, 38, .95);
  border-color: var(--line);
  color: var(--ink);
}
html[data-theme="tech"] .health-dot.is-ok { box-shadow: 0 0 0 3px rgba(52, 211, 153, .25), 0 0 12px rgba(52, 211, 153, .6); }
html[data-theme="tech"] .health-dot.is-bad { box-shadow: 0 0 0 3px rgba(251, 113, 133, .25), 0 0 12px rgba(251, 113, 133, .6); }

/* 动效弱化：全部特效冻结为静帧（氛围层保留暗色底，不闪不扫） */
@media (prefers-reduced-motion: reduce) {
  html[data-theme="tech"] .nav-item.is-active::after,
  html[data-theme="tech"] .stat-card::after,
  html[data-theme="tech"] .login-card::before { animation: none; }
  html[data-theme="tech"] .login-card { animation: rise-in .38s ease both; }
}

/* ---------- v1.1.4 日志分页 ---------- */
.pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding: 12px 4px 2px;
}
.pager:empty { display: none; }
.pager-btn {
  appearance: none;
  font: inherit;
  font-size: 13px;
  color: var(--ink-2);
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 5px 12px;
  cursor: pointer;
  transition: border-color .15s, color .15s;
}
.pager-btn:hover:not(:disabled) { color: var(--celadon); border-color: var(--celadon); }
.pager-btn:disabled { opacity: .4; cursor: default; }
.pager-info { font-size: 12.5px; color: var(--ink-3); }

/* ---------- v1.4.0 版本指纹 / 防篡改视图 ----------
   复用现有令牌与控件样式（.panel / .settings-body / .field / .data-table /
   .btn / .hint-text），这里只补三样新东西：说明表单宽度、等宽文本域、行内消息。
   刻意不引入新色板 —— 颜色一律走 var(--*)，三套主题自动跟随。 */
.ig-form { max-width: 820px; }
.ig-form .field-label { font-size: 12.5px; }

/* 等宽文本域：粘清单、看凭据都用它。覆盖 .settings-body textarea 的 #fff，
   改用 var(--card)/var(--ink)，否则深色主题下会是白底黑字的「补丁块」。 */
.ig-textarea {
  font-family: var(--mono);
  font-size: 12.5px;
  line-height: 1.65;
  letter-spacing: .01em;
  background: var(--card);
  color: var(--ink);
  resize: vertical;
  word-break: break-all;
}
.ig-textarea[readonly] { background: var(--paper-2); cursor: text; }

.ig-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.ig-actions .btn { flex: 0 0 auto; }

.ig-msg { font-size: 12.5px; line-height: 1.6; color: var(--ink-2); }
.ig-msg.is-ok { color: var(--green); }
.ig-msg.is-err { color: var(--red); }

/* 指纹单元格：整包指纹 64 位，等宽 + 紧凑，避免撑破表格 */
.ig-fp {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-2);
  word-break: break-all;
}
