  :root {
    --bg: #141414;
    --bg-elev: #1c1c1c;
    --bg-row: #191919;
    --border: #2c2c2c;
    --border-soft: #232323;
    --t1: #e8e8e8;
    --t2: #a8a8a8;
    --t3: #6f6f6f;
    --accent: #4a9eff;
    --warn: #e0a341;
    --ok: #4bb87c;
    --bad: #e06c5f;
    /* 搜索条件的区分色，深色底上取较亮的一档 */
    --c1: #5b9dff;
    --c2: #f5a05a;
    --c3: #4ec48c;
    --c4: #b58ae8;
    --c5: #ee8a8a;
    --c6: #4dbcc9;
    --c7: #d9b552;
    --c8: #8f9cf2;
    /* 背景网格线和星点，两套主题各一份 */
    --grid-line: rgba(255,255,255,.055);
    --star: 255,255,255;
    /* 卡片底色。比 --bg-elev 透一点，好让背景的光晕透上来。
       表格和 sticky 表头不能用它，那些地方必须实心才看得清数字。 */
    --panel-bg: rgba(28,28,28,.66);
  }
  html[data-theme="light"] {
    --bg: #fbfbfb;
    --bg-elev: #ffffff;
    --bg-row: #f5f5f5;
    --border: #dedede;
    --border-soft: #ebebeb;
    --t1: #1a1a1a;
    --t2: #555555;
    --t3: #8a8a8a;
    --accent: #0a66d0;
    --warn: #a86a00;
    --ok: #1f7a4d;
    --bad: #c0392b;
    /* 浅色底上要压暗，否则同样的色号会糊成一片 */
    --c1: #1565d8;
    --c2: #b4650c;
    --c3: #12784d;
    --c4: #7433ac;
    --c5: #c0392b;
    --c6: #0b7285;
    --c7: #8a6d0b;
    --c8: #3f4fc9;
    --grid-line: rgba(20,30,60,.05);
    --star: 40,70,130;
    --panel-bg: rgba(255,255,255,.74);
  }
  * { box-sizing: border-box; }
  body {
    margin: 0;
    background: var(--bg);
    color: var(--t1);
    font: 14px/1.55 -apple-system, BlinkMacSystemFont, "PingFang SC",
      "Hiragino Sans GB", "Microsoft YaHei", "Segoe UI", sans-serif;
  }

  /* ---------- 站点导航 ---------- */
  .portalbar {
    position: sticky; top: 0; z-index: 100;
    display: flex; align-items: center; gap: 18px; min-height: 58px;
    padding: 8px max(14px, calc((100% - 1560px) / 2 + 22px));
    border-bottom: 1px solid var(--border);
    background: color-mix(in srgb, var(--bg) 88%, transparent);
    backdrop-filter: blur(16px) saturate(140%);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
  }
  .portalbrand {
    display: inline-flex; align-items: center; gap: 9px; flex: 0 0 auto;
    color: var(--t1); text-decoration: none;
  }
  .portalbrand:hover { text-decoration: none; }
  .portalbrand__mark {
    display: grid; place-items: center; width: 36px; height: 36px;
    border: 1px solid color-mix(in srgb, var(--accent) 70%, var(--border));
    border-radius: 7px; color: #fff; background: var(--accent);
    font: 750 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  }
  .portalbrand__text {
    display: flex; align-items: baseline; gap: 7px;
    font-size: 14px; font-weight: 650; white-space: nowrap;
  }
  .portalbrand__text small {
    color: var(--t3); font: 600 9px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  }
  .portaltabs {
    display: flex; align-items: center; gap: 3px; min-width: 0;
    padding: 3px; border: 1px solid var(--border);
    border-radius: 8px; background: var(--bg-elev);
  }
  .portal-load {
    display: grid; grid-template-columns: minmax(120px, auto) 72px;
    align-items: center; gap: 9px; min-width: 210px; margin-left: auto;
    color: var(--t2); font-size: 11px; white-space: nowrap;
  }
  .portal-auth {
    display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  }
  .portal-auth button {
    min-height: 34px; padding: 6px 12px;
  }
  .portal-user {
    max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: var(--t1); font-size: 13px; font-weight: 600; letter-spacing: .02em;
  }
  .portal-user::before {
    content: ""; display: inline-block; width: 7px; height: 7px; margin-right: 7px;
    border-radius: 50%; background: var(--ok); vertical-align: 1px;
  }
  .portal-user[hidden] { display: none; }
  .trial-dialog {
    margin: auto; padding: 0; border: 1px solid var(--border);
    border-radius: 10px; background: var(--bg-elev); color: var(--t1);
    box-shadow: 0 24px 70px rgba(0, 0, 0, .45);
  }
  .trial-dialog::backdrop {
    background: rgba(8, 10, 12, .62);
    backdrop-filter: blur(4px);
  }
  .trial-dialog__card {
    display: grid; gap: 12px; width: min(92vw, 380px); padding: 22px 22px 18px;
  }
  .trial-dialog__card h2 {
    margin: 0; font-size: 18px; font-weight: 650;
  }
  .trial-dialog__card p {
    margin: 0; color: var(--t2); line-height: 1.55;
  }
  .trial-dialog__actions {
    display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px;
  }
  .trial-dialog__actions .ghost {
    background: transparent; color: var(--t2);
  }
  .trial-dialog__actions .primary {
    background: var(--accent); color: #fff; border-color: transparent;
  }
  .promo-dialog {
    margin: auto; padding: 0; border: 1px solid var(--border);
    border-radius: 10px; background: var(--bg-elev); color: var(--t1);
    box-shadow: 0 24px 70px rgba(0, 0, 0, .45);
    max-width: min(92vw, 440px);
  }
  .promo-dialog::backdrop {
    background: rgba(8, 10, 12, .62);
    backdrop-filter: blur(4px);
  }
  .promo-dialog__card {
    display: grid; gap: 10px; width: min(92vw, 440px); padding: 22px 22px 18px;
  }
  .promo-dialog__card h2 {
    margin: 0; font-size: 18px; font-weight: 650;
  }
  .promo-dialog__card h3 {
    margin: 8px 0 0; font-size: 14px; font-weight: 650; color: var(--t2);
  }
  .promo-code-line { margin: 0; color: var(--t1); font-size: 15px; }
  .promo-code-line strong {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    letter-spacing: .08em; color: var(--accent);
  }
  .promo-note {
    margin: 0; color: var(--t2); font-size: 12px; line-height: 1.55;
  }
  .promo-events {
    max-height: min(48vh, 320px); overflow: auto;
    border: 1px solid var(--border); border-radius: 8px;
    background: rgba(255,255,255,.02);
  }
  .promo-event {
    display: flex; justify-content: space-between; gap: 10px;
    padding: 9px 12px; border-bottom: 1px solid var(--border);
    font-size: 13px; line-height: 1.4;
  }
  .promo-event:last-child { border-bottom: 0; }
  .promo-event__main { color: var(--t1); }
  .promo-event__meta { color: var(--t2); font-size: 11px; white-space: nowrap; }
  .promo-events__empty {
    padding: 18px 12px; color: var(--t2); text-align: center; font-size: 13px;
  }
  .promo-dialog__actions {
    display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px;
  }
  .promo-dialog__actions .primary {
    background: var(--accent); color: #fff; border-color: transparent;
  }
  .portal-load__track {
    height: 4px; overflow: hidden; border-radius: 2px;
    background: var(--border);
  }
  .portal-load__track i {
    display: block; width: 100%; height: 100%; transform: scaleX(0);
    transform-origin: left; background: var(--accent);
    transition: transform .2s ease;
  }
  .portal-load.is-done { color: var(--ok); }
  .portal-load.is-done .portal-load__track i { background: var(--ok); }
  button.portaltab {
    min-height: 34px; padding: 6px 13px; border: 0; border-radius: 5px;
    background: transparent; color: var(--t2); font-weight: 600;
    transition: color .16s ease, background .16s ease, box-shadow .16s ease;
  }
  button.portaltab:hover { color: var(--t1); background: var(--bg-row); }
  button.portaltab.on {
    color: #fff; background: var(--accent);
    box-shadow: 0 3px 12px color-mix(in srgb, var(--accent) 28%, transparent);
  }
  button.portaltab:focus-visible, .portalbrand:focus-visible {
    outline: 2px solid var(--accent); outline-offset: 2px;
  }
  .portalview { width: 100%; min-height: 0; }
  .portalview[hidden], .bg[hidden] { display: none; }
  .portalframe { display: block; width: 100%; height: 100%; border: 0; background: var(--bg); }
  body.portal-frame-open {
    display: flex; flex-direction: column; height: 100dvh; min-height: 480px;
    overflow: hidden;
  }
  body.portal-frame-open .portalbar { position: relative; flex: 0 0 auto; }
  body.portal-frame-open .portalview:not([hidden]) { display: block; flex: 1 1 auto; }

  @media (max-width: 620px) {
    .portalbar {
      align-items: stretch; flex-direction: column; gap: 6px; padding: 7px 10px 8px;
    }
    .portalbrand { align-self: center; }
    .portalbrand__mark { width: 30px; height: 30px; }
    .portalbrand__text small { display: none; }
    .portaltabs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .portal-load {
      grid-template-columns: minmax(0, 1fr) 96px;
      width: 100%; min-width: 0; margin-left: 0;
    }
    .portal-auth { width: 100%; justify-content: flex-end; }
    button.portaltab {
      min-width: 0; min-height: 36px; padding: 5px 4px;
      white-space: normal; line-height: 1.2;
    }
  }
  @media (pointer: coarse) {
    button.portaltab { min-height: 44px; }
  }

  /* ---------- 背景 ----------
     跟登录页同一套：三团缓慢漂移的光晕打底，一层细网格给结构，
     再盖一层 canvas 星点。整体比登录页压得淡不少——那边只有一张卡片，
     这边底下是表格和散点图，背景抢戏就看不清数字了。

     固定在视口上，既不参与文档流也不跟着滚，长页面滚动时不会有色块跑动。 */
  .bg { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
  .wrap { position: relative; z-index: 1; max-width: 1560px; margin: 0 auto; padding: 26px 22px 72px; }

  .orb { position: absolute; border-radius: 50%; filter: blur(100px); opacity: .34; will-change: transform; }
  .orb.a { width: 44vmax; height: 44vmax; left: -14vmax; top: -16vmax;
           background: radial-gradient(circle, #1e6fff 0%, transparent 68%);
           animation: drift1 30s ease-in-out infinite; }
  .orb.b { width: 38vmax; height: 38vmax; right: -13vmax; top: 6vmax;
           background: radial-gradient(circle, #9b4dff 0%, transparent 68%);
           animation: drift2 36s ease-in-out infinite; }
  .orb.c { width: 36vmax; height: 36vmax; left: 26vmax; bottom: -20vmax;
           background: radial-gradient(circle, #00d4c8 0%, transparent 68%);
           animation: drift3 42s ease-in-out infinite; }
  @keyframes drift1 { 0%,100% { transform: translate3d(0,0,0) scale(1); }
                      50% { transform: translate3d(12vmax,9vmax,0) scale(1.12); } }
  @keyframes drift2 { 0%,100% { transform: translate3d(0,0,0) scale(1.06); }
                      50% { transform: translate3d(-10vmax,12vmax,0) scale(.94); } }
  @keyframes drift3 { 0%,100% { transform: translate3d(0,0,0) scale(1); }
                      50% { transform: translate3d(-9vmax,-10vmax,0) scale(1.1); } }

  .grid {
    position: absolute; inset: 0; opacity: .5;
    background-image: linear-gradient(var(--grid-line) 1px, transparent 1px),
                      linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 58px 58px;
    mask-image: radial-gradient(ellipse 80% 65% at 50% 30%, #000 20%, transparent 100%);
    -webkit-mask-image: radial-gradient(ellipse 80% 65% at 50% 30%, #000 20%, transparent 100%);
  }
  #bgStars { position: absolute; inset: 0; width: 100%; height: 100%; }

  /* 浅色底扛不住那么重的光晕，压到勉强能看出一点颜色就够 */
  html[data-theme="light"] .orb { opacity: .17; filter: blur(120px); }
  html[data-theme="light"] .grid { opacity: .8; }

  /* 卡片底色用 --panel-bg（见各自的定义）透出背后的光晕，这里补上毛玻璃。
     表格容器和 sticky 表头不在里面，那些地方保持实心才看得清数字。 */
  .panel, .gcard, .stat {
    backdrop-filter: blur(9px) saturate(130%);
    -webkit-backdrop-filter: blur(9px) saturate(130%);
  }

  @media (prefers-reduced-motion: reduce) {
    .orb { animation: none; }
    input.filter-active, select.filter-active, .fld.filter-filled { animation: none; }
  }
  h1 { font-size: 23px; font-weight: 600; margin: 0 0 6px; letter-spacing: -0.01em; }
  h2 { font-size: 18px; font-weight: 600; margin: 34px 0 12px; }
  h3 { font-size: 14px; font-weight: 600; margin: 0 0 10px; }
  .lede { color: var(--t2); max-width: 980px; margin: 0; }
  .lede.alert { color: var(--bad); font-weight: 700; font-size: 15px; }

  .home-wrap { max-width: 820px; }
  .home-guide { line-height: 1.7; font-size: 15px; color: var(--t2); }
  .home-guide p { margin: 0 0 14px; }
  .home-guide h2 {
    margin: 22px 0 10px; font-size: 17px; color: var(--t1); font-weight: 700;
  }
  .home-list { margin: 0 0 14px; padding-left: 1.35em; }
  .home-list li { margin: 0 0 8px; }
  .home-cta {
    display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
    margin: 18px 0 8px; padding: 14px 16px;
    border: 1px solid var(--border); border-radius: 8px;
    background: color-mix(in srgb, var(--c1) 10%, transparent);
  }
  .home-support-qr {
    display: flex; justify-content: center; align-items: center;
    min-height: 180px; margin: 8px 0 4px;
  }
  .home-support-qr img {
    width: min(240px, 70vw); height: auto; border-radius: 8px;
    background: #fff; padding: 8px;
  }
  .home-guide .hl { font-weight: 700; }
  .home-guide .hl-ok { color: var(--ok); }
  .home-guide .hl-warn { color: var(--warn); }
  .home-guide .hl-accent { color: var(--accent); }
  .home-guide .hl-bad { color: var(--bad); }
  .home-guide .hl-feat { color: var(--c3); }
  .river-form {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  }
  .river-form input[type="url"] { width: min(720px, 100%); flex: 1 1 280px; }
  .river-status { min-height: 1.4em; margin: 10px 0 0; color: var(--t2); }
  .river-status.is-error { color: var(--bad); }
  .river-loading {
    display: flex; align-items: center; justify-content: center; gap: 14px;
    margin-top: 14px; padding: 16px; border-radius: 10px;
    min-height: min(78vh, 980px);
    border: 1px solid var(--border); background: #070b12; color: #f8fafc;
  }
  .river-loading[hidden] { display: none; }
  .river-loading strong { display: block; font-size: 18px; font-weight: 600; }
  .river-loading__spinner {
    width: 28px; height: 28px; border-radius: 50%;
    border: 3px solid rgba(106, 168, 255, .25);
    border-top-color: var(--accent);
    animation: river-spin 0.8s linear infinite;
  }
  @keyframes river-spin { to { transform: rotate(360deg); } }
  .river-frame {
    display: block; width: 100%; height: min(78vh, 980px); margin-top: 12px;
    border: 1px solid var(--border); background: #070b12;
  }
  .river-frame[hidden] { display: none; }
  .muted { color: var(--t3); font-size: 12px; }
  .hint { font-size: 15px; font-weight: 600; color: var(--t1); margin: -2px 0 14px; }
  .hint a { border-bottom: 1px dashed currentColor; }
  .hint a:hover { text-decoration: none; }
  a { color: var(--accent); text-decoration: none; }
  a:hover { text-decoration: underline; }
  code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }

  /* 标题走一道很慢的流光。两套主题都用自己的强调色，浅色下不会糊成灰 */
  .topbar h1 {
    background: linear-gradient(92deg, var(--t1) 8%, var(--accent) 36%, var(--c4) 64%, var(--t1) 92%);
    background-size: 220% 100%;
    -webkit-background-clip: text; background-clip: text; color: transparent;
    animation: sheen 9s linear infinite;
  }
  @keyframes sheen { to { background-position: -220% 0; } }
  @media (prefers-reduced-motion: reduce) {
    .topbar h1 { animation: none; }
  }
  .topbar { display: flex; align-items: flex-start; gap: 16px; }
  .topbar > div:first-child { flex: 1; min-width: 0; }
  .topact { display: flex; gap: 8px; flex-shrink: 0; align-items: center; }
  .trialtip {
    padding: 4px 9px; border-radius: 6px; font-size: 12.5px; white-space: nowrap;
    color: var(--bad); border: 1px solid var(--bad); background: color-mix(in srgb, var(--bad) 10%, transparent);
  }

  button, select, input {
    font-family: inherit; font-size: 12.5px; color: var(--t1);
    background: var(--bg-elev); border: 1px solid var(--border); border-radius: 6px;
    padding: 5px 9px;
  }
  button { cursor: pointer; color: var(--t2); white-space: nowrap; }
  button:hover:not(:disabled) { color: var(--t1); border-color: var(--t3); }
  button:disabled { opacity: .45; cursor: not-allowed; }
  button.primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 500; padding: 6px 18px; }
  button.primary:hover:not(:disabled) { color: #fff; filter: brightness(1.1); }
  button.danger { color: var(--bad); border-color: var(--bad); }
  input[type=number] { width: 92px; }
  input[type=text] { width: 160px; }
  input:focus, select:focus { outline: none; border-color: var(--accent); }
  input.filter-active, select.filter-active {
    border-color: var(--fc, var(--accent));
    background: color-mix(in srgb, var(--fc, var(--accent)) 10%, var(--bg-elev));
    animation: filter-breathe 1.8s ease-in-out infinite;
  }
  @keyframes filter-breathe {
    0%, 100% {
      box-shadow: inset 3px 0 var(--fc, var(--accent)),
        0 0 0 1px color-mix(in srgb, var(--fc, var(--accent)) 25%, transparent);
    }
    50% {
      box-shadow: inset 3px 0 var(--fc, var(--accent)),
        0 0 0 4px color-mix(in srgb, var(--fc, var(--accent)) 18%, transparent),
        0 0 15px color-mix(in srgb, var(--fc, var(--accent)) 22%, transparent);
    }
  }
  label.chk { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--t2); cursor: pointer; }
  label.chk input { padding: 0; }

  /* ---- 搜索面板 ---- */
  .panel { border: 1px solid var(--border); border-radius: 8px; background: var(--panel-bg); padding: 16px 18px; margin: 18px 0; }

  .fgroup + .fgroup { margin-top: 18px; }
  /* 攻击/高级属性：对齐缝号专属场 attribute-panel 的分区标题 */
  .fgroup--collapsible {
    margin-top: 14px;
    padding-top: 4px;
    border-top: 1px solid var(--border-soft);
  }
  .fgroup--collapsible > summary.ftitle {
    list-style: none; cursor: pointer; user-select: none;
    min-height: 36px; margin-bottom: 0;
    font-size: 14px; font-weight: 700; letter-spacing: .04em;
    color: var(--warn);
  }
  .fgroup--collapsible > summary.ftitle::-webkit-details-marker { display: none; }
  .fgroup--collapsible > summary.ftitle::before {
    content: "＋";
    flex: 0 0 auto;
    font: 700 16px/1 ui-monospace, Menlo, Consolas, monospace;
    color: inherit;
  }
  .fgroup--collapsible[open] > summary.ftitle::before { content: "－"; }
  .fgroup--collapsible > summary.ftitle .ftoggle {
    margin-left: 0; color: var(--t3); font-size: 12px; font-weight: 600;
  }
  .fgroup--collapsible > summary.ftitle .ftoggle .c { display: none; }
  .fgroup--collapsible[open] > summary.ftitle .ftoggle .o { display: none; }
  .fgroup--collapsible[open] > summary.ftitle .ftoggle .c { display: inline; }
  .fgroup--collapsible > .fgrid {
    --attr-label: 8.6em;
    container-type: inline-size;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    margin-top: 10px;
    padding-top: 4px;
  }
  .fgroup--collapsible > .fgrid > .fld {
    flex: 0 0 auto;
    width: max-content;
    max-width: 100%;
  }
  .ftitle {
    display: flex; align-items: center; gap: 10px; margin-bottom: 10px;
    font-size: 13px; font-weight: 600; letter-spacing: .04em; color: var(--t2);
  }
  .ftitle::after { content: ""; flex: 1; height: 1px; background: var(--border-soft); }
  .fhint { color: var(--t3); font-size: 11.5px; margin: 9px 0 0; }

  /* 一行三个，等宽对齐 */
  .fgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px 14px; }

  /* 每个条件一张卡片，左侧色条 + 同色标签，靠颜色区分 */
  .fld {
    display: flex; align-items: center; gap: 8px; min-width: 0;
    background: var(--bg-row); border: 1px solid var(--border-soft);
    border-left: 3px solid var(--fc, var(--t3));
    border-radius: 6px; padding: 7px 11px;
  }
  .fld:focus-within { border-color: var(--fc, var(--accent)); }
  .fld.filter-filled {
    border-color: var(--fc, var(--accent));
    background: color-mix(in srgb, var(--fc, var(--accent)) 8%, var(--bg-row));
    animation: filter-breathe 1.8s ease-in-out infinite;
  }
  .fld.filter-filled input.filter-active,
  .fld.filter-filled select.filter-active {
    animation: none;
    box-shadow: inset 3px 0 var(--fc, var(--accent));
  }
  .fld > .nm {
    flex: 0 0 auto; min-width: 56px;
    color: var(--fc, var(--t2)); font-size: 12.5px; font-weight: 600;
  }
  .fld.wide > .nm { min-width: 82px; }
  .fld input, .fld select { flex: 1 1 0; width: auto; min-width: 0; }
  .fld .sep, .fld .unit { flex: 0 0 auto; color: var(--t3); font-size: 11.5px; }

  /* ---- 门派多选 ----
     按钮长得跟原来的 select 一样，省得这一格在一排里显得特殊。
     面板浮在上层，不占位，所以不会把三列网格顶开。 */
  .msel { position: relative; flex: 1 1 0; min-width: 0; }
  .msel > button {
    display: flex; align-items: center; gap: 6px; width: 100%;
    text-align: left; color: var(--t1);
  }
  .msel > button > span { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .msel > button.on { color: var(--fc, var(--accent)); border-color: var(--fc, var(--accent)); }
  .caret {
    flex: 0 0 auto; width: 0; height: 0; border: 4px solid transparent;
    border-top-color: currentColor; border-bottom: none; opacity: .7;
  }
  .mspop {
    position: absolute; z-index: 30; top: calc(100% + 5px); left: 0; min-width: 100%;
    padding: 8px; border: 1px solid var(--border); border-radius: 7px;
    background: var(--bg-elev); box-shadow: 0 12px 32px rgba(0,0,0,.4);
    display: grid; grid-template-columns: repeat(3, minmax(58px, 1fr)); gap: 2px 6px;
  }
  /* 上面这条 display 会盖掉浏览器给 [hidden] 的 display:none——类选择器比它优先。
     少了这行，面板从一进页面就是摊开的，而且点按钮也收不起来。 */
  .mspop[hidden] { display: none; }
  html[data-theme="light"] .mspop { box-shadow: 0 12px 32px rgba(0,0,0,.16); }
  .msact { grid-column: 1 / -1; display: flex; gap: 6px; margin-bottom: 4px; }
  .msact button { flex: 1; padding: 3px 0; font-size: 11.5px; }
  .msopt {
    display: flex; align-items: center; gap: 5px; padding: 3px 4px; border-radius: 4px;
    font-size: 12.5px; color: var(--t2); cursor: pointer; white-space: nowrap; user-select: none;
  }
  .msopt:hover { background: var(--bg-row); color: var(--t1); }
  .msopt input { flex: 0 0 auto; padding: 0; margin: 0; }
  .msopt:has(input:checked) { color: var(--fc, var(--accent)); font-weight: 600; }

  /* 属性条件标签长短不一。标签列固定并右对齐，输入框左边缘才能上下对齐，短标签仍贴着输入框。
     字号与缝号专属场 filter-block 标题对齐，比基础条件更醒目 */
  .fld.attr {
    --attr-input: calc((100cqi - 112px) / 12);
    display: grid;
    grid-template-columns: var(--attr-label) var(--attr-input) 1.2em;
    column-gap: 8px;
    align-items: center;
    width: max-content;
    max-width: 100%;
    padding: 9px 12px;
  }
  .fld.attr::after { content: ""; }
  .fld.attr:has(.unit)::after { content: none; }
  .fld.attr > .nm {
    min-width: 0;
    width: auto;
    text-align: right;
    white-space: nowrap;
    font-size: 13px; font-weight: 700; letter-spacing: .02em;
  }
  /* 在原先半格上再缩短一半。卡片只包住标签和输入，后面的字段往前靠。 */
  .fld.attr input {
    flex: 0 0 auto;
    width: var(--attr-input);
    max-width: 100%;
    min-width: 0;
    font-size: 13px;
  }
  .fgroup--collapsible > .fgrid > .fld:not(.attr) {
    display: grid;
    grid-template-columns: var(--attr-label) max-content;
    column-gap: 8px;
    align-items: center;
    padding: 9px 12px;
  }
  .fgroup--collapsible > .fgrid > .fld:not(.attr) > .nm {
    min-width: 0;
    text-align: right;
  }
  .fgroup--collapsible > .fgrid > .fld:not(.attr) select {
    flex: 0 0 auto;
    width: max-content;
    min-width: 8.5em;
  }
  /* 基础条件仍是三列拉满。门派下拉收到原来格子的一半；价格、修为、装评的每个数字框收到自己当前宽度的一半。卡片靠左排。
     这一行不再缩短。攻击/高级属性的输入框在上面单独再减半。 */
  .fgroup:not(.fgroup--collapsible) .fgrid {
    container-type: inline-size;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }
  .fgroup:not(.fgroup--collapsible) .fld {
    flex: 0 0 auto;
    width: max-content;
    max-width: 100%;
  }
  .fgroup:not(.fgroup--collapsible) .fld .msel {
    flex: 0 0 auto;
    width: calc((100cqi - 112px) / 6);
    max-width: 100%;
    min-width: 8em;
  }
  .fgroup:not(.fgroup--collapsible) .fld .msel > button {
    width: 100%;
  }
  .fgroup:not(.fgroup--collapsible) .fld input {
    flex: 0 0 auto;
    width: calc((100cqi - 112px) / 12);
    max-width: 9em;
    min-width: 4.75em;
  }
  .fld.req > .nm > i { font-style: normal; color: var(--bad); margin-left: 1px; }
  input.bad, input.bad:focus { border-color: var(--bad); }

  /* 已填条件在上，开始搜索 / 停止 / 重置条件在条件下面靠左。
     整条冻在站点导航下方；顶距跟门户栏实际高度走。 */
  #view-cbg > .cbg-search-actions {
    position: sticky;
    top: var(--cbg-sticky-top, 58px);
    z-index: 40;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    gap: 8px;
    margin: -26px -22px 14px;
    padding: 10px 22px;
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    box-shadow: 0 8px 20px color-mix(in srgb, #000 18%, transparent);
  }
  .cbg-filled-tags {
    display: flex;
    flex: 0 0 auto;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    width: 100%;
    min-width: 0;
  }
  .cbg-filled-tags:empty { display: none; }
  .cbg-filled-tag {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    max-width: 100%;
    padding: 3px 10px;
    border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--border));
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent) 14%, var(--bg-elev));
    color: var(--t1);
    font-size: 12.5px;
    line-height: 1.45;
    white-space: nowrap;
    cursor: default;
    user-select: text;
  }
  .cbg-filled-tag .k { color: var(--t2); font-weight: 600; }
  .cbg-filled-tag .v { font-weight: 650; font-variant-numeric: tabular-nums; }
  .cbg-search-actions__btns {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 9px;
    margin-left: 0;
  }
  .cbg-search-status {
    margin: 0;
    color: var(--t2);
    font-size: 12px;
    line-height: 1.35;
  }
  .cbg-search-status.err { color: var(--bad); }
  .cbg-search-status[hidden] { display: none; }
  #view-cbg[hidden] { display: none; }

  .factions { display: flex; align-items: center; gap: 9px; margin-top: 18px; }
  .factions .grow { flex: 1; }
  details.adv > summary { cursor: pointer; color: var(--t2); font-size: 12.5px; list-style: none; user-select: none; }
  details.adv > summary::-webkit-details-marker { display: none; }
  details.adv > summary::before { content: "▸ "; color: var(--t3); }
  details.adv[open] > summary::before { content: "▾ "; }
  details.adv > div { margin-top: 12px; }

  /* ---- 进度 ---- */
  #progress { display: none; margin-top: 14px; }
  #progress.on { display: block; }
  .bar { height: 4px; background: var(--border); border-radius: 2px; overflow: hidden; }
  .bar > i { display: block; height: 100%; width: 0; background: var(--accent); transition: width .25s; }
  #progText { font-size: 12px; color: var(--t2); margin-top: 7px; font-variant-numeric: tabular-nums; }
  #progText.err { color: var(--bad); }

  /* 被验证码拦停时给出口：去藏宝阁手动过一次，回来就能接着搜 */
  #cdHelp { font-size: 12px; line-height: 1.7; margin-top: 8px; padding: 9px 12px;
            border: 1px solid var(--border); border-left: 3px solid var(--warn);
            border-radius: 6px; background: var(--bg-elev); color: var(--t2); }
  #cdHelp b { color: var(--t1); }
  #cdHelp a { color: var(--accent); font-weight: 600; }
  /* [hidden] 的默认 display:none 权重低于上面那条，不兜一下藏不住 */
  #cdHelp[hidden] { display: none; }

  .note { border: 1px solid var(--border); border-left: 3px solid var(--t3); border-radius: 6px;
          padding: 11px 15px; margin: 14px 0; background: var(--bg-elev); color: var(--t2); font-size: 13px; }
  .note.warn { border-left-color: var(--warn); }

  .note.info { border-left-color: var(--accent); }
  .note b { color: var(--t1); font-weight: 600; }

  /* ---- 概览 ---- */
  .stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin: 18px 0; }
  .stat { border: 1px solid var(--border); border-radius: 8px; padding: 12px 15px; background: var(--panel-bg); }
  .stat .v { font-size: 24px; font-weight: 600; line-height: 1.15; font-variant-numeric: tabular-nums; }
  .stat .l { color: var(--t3); font-size: 12px; margin-top: 3px; }

  .groups { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
  .gcard { border: 1px solid var(--border); border-radius: 8px; background: var(--panel-bg); padding: 12px 14px; cursor: pointer; }
  .gcard:hover { border-color: var(--t3); }
  .gcard.on { border-color: var(--accent); }
  .gcard .gh { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
  .gcard .gn { font-weight: 600; font-size: 14px; }
  .gcard .gc { color: var(--accent); font-weight: 600; font-variant-numeric: tabular-nums; }
  .gcard .kv { display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; margin-top: 9px;
               border-top: 1px solid var(--border-soft); padding-top: 9px; font-size: 12px; }
  .gcard .kv span { color: var(--t3); }
  .gcard .kv b { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }

  /* ---- 散点图 ---- */
  /* 散点图：一张大图 + 上方切换条 */
  .chartctl {
    border: 1px solid var(--border); border-radius: 8px 8px 0 0;
    background: var(--bg-elev); border-bottom: none; padding: 10px 14px;
  }
  .ccrow { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; }
  .ccrow + .ccrow { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border-soft); }
  .ccrow > .lbl { flex: 0 0 auto; color: var(--t3); font-size: 12px; }
  .ccp { display: flex; flex-wrap: wrap; gap: 6px; }
  .ccrow select { font-size: 12px; padding: 3px 7px; }

  .chartone {
    border: 1px solid var(--border); border-radius: 0 0 8px 8px;
    background: var(--bg-elev); padding: 12px 14px 6px;
  }
  .chartone > .cht { font-size: 14px; font-weight: 600; margin-bottom: 6px; }
  .chartone > .cht span { color: var(--t3); font-weight: 400; font-size: 12px; margin-left: 8px; }
  .chartone svg { width: 100%; display: block; }
  circle.dot { cursor: pointer; }
  circle.dot:hover { stroke-width: 3; }
  #tip {
    position: fixed; pointer-events: none; opacity: 0; background: var(--bg);
    border: 1px solid var(--border); border-radius: 6px; padding: 8px 11px;
    font-size: 12px; line-height: 1.55; white-space: nowrap; z-index: 50; color: var(--t1);
    box-shadow: 0 4px 18px rgba(0,0,0,.35);
  }

  /* ---- 表格 ---- */
  .controls { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; margin: 10px 0; }
  .controls .lbl { color: var(--t3); font-size: 12px; }
  .pill {
    border: 1px solid var(--border); background: transparent; color: var(--t2);
    border-radius: 999px; padding: 4px 12px; font-size: 12.5px; cursor: pointer;
  }
  .pill:hover { color: var(--t1); border-color: var(--t3); }
  .pill.on { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 500; }

  /* 自定义列：整条做成可点的卡片，比一行小字更容易被看见 */
  .colwrap {
    border: 1px solid var(--border); border-left: 3px solid var(--accent);
    border-radius: 8px; background: var(--bg-elev); margin: 10px 0 12px;
  }
  .colwrap > summary {
    display: flex; align-items: center; gap: 10px; padding: 10px 14px;
    cursor: pointer; list-style: none; user-select: none; border-radius: 6px;
  }
  .colwrap > summary::-webkit-details-marker { display: none; }
  .colwrap > summary:hover { background: var(--bg-row); }
  .cwi { flex: 0 0 auto; color: var(--accent); font-size: 14px; line-height: 1; }
  .cwt { flex: 0 0 auto; font-size: 13.5px; font-weight: 700; color: var(--t1); }
  .cwn {
    flex: 0 0 auto; font-size: 11.5px; color: var(--accent);
    border: 1px solid var(--accent); border-radius: 10px; padding: 1px 8px;
    font-variant-numeric: tabular-nums;
  }
  .cwd { flex: 1; min-width: 0; font-size: 11.5px; color: var(--t3);
         overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .cwx { flex: 0 0 auto; font-size: 11.5px; color: var(--t2); }
  .cwx > .c, .colwrap[open] .cwx > .o { display: none; }
  .colwrap[open] .cwx > .c { display: inline; }
  .cwx::after { content: " ▾"; }
  .colwrap[open] .cwx::after { content: " ▴"; }
  .cwbody { padding: 0 14px 14px; }

  .colpick { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 5px 14px; margin-top: 10px; }
  .colgrp { grid-column: 1 / -1; color: var(--t3); font-size: 11px; margin-top: 8px;
            border-bottom: 1px solid var(--border-soft); padding-bottom: 3px; }

  .tablewrap { border: 1px solid var(--border); border-radius: 8px; overflow: auto; max-height: 720px; }
  table { border-collapse: collapse; width: 100%; font-size: 13px; font-variant-numeric: tabular-nums; }
  thead th {
    position: sticky; top: 0; z-index: 2; background: var(--bg-elev); color: var(--t2);
    font-weight: 500; font-size: 12px; text-align: right; white-space: nowrap;
    padding: 8px 10px; border-bottom: 1px solid var(--border); cursor: pointer; user-select: none;
  }
  thead th:hover { color: var(--t1); background: var(--border-soft); }
  thead th.l, tbody td.l { text-align: left; }
  thead th.c, tbody td.c { text-align: center; }
  thead th .si { margin-left: 4px; color: var(--t3); font-size: 10px; }
  thead th.act { color: var(--t1); }
  thead th.act .si { color: var(--accent); font-size: 11px; }
  tbody td { padding: 7px 10px; text-align: right; border-bottom: 1px solid var(--border-soft); white-space: nowrap; }
  tbody tr:nth-child(even) { background: var(--bg-row); }
  tbody tr:hover { background: var(--border-soft); }
  td.price { font-weight: 600; }
  td.nm { max-width: 280px; overflow: hidden; text-overflow: ellipsis; }
  .dim { color: var(--t3); }
  .yes { color: var(--ok); }
  .tag { display: inline-block; border: 1px solid var(--border); border-radius: 4px;
         padding: 0 6px; font-size: 11px; color: var(--t2); }
  .empty { padding: 40px; text-align: center; color: var(--t3); }

  /* 手动标红行：底色压在 td 上才盖得住斑马纹和 hover；明暗主题都走 --bad */
  tbody tr.marked td { background: color-mix(in srgb, var(--bad) 18%, transparent); }
  tbody tr.marked:hover td { background: color-mix(in srgb, var(--bad) 30%, transparent); }
  .markbtn, .notebtn {
    padding: 0 6px; margin-right: 4px; font-size: 11px; line-height: 19px;
    border-radius: 4px; color: var(--t3); vertical-align: baseline;
  }
  .markbtn:hover:not(:disabled) { color: var(--bad); border-color: var(--bad); }
  .markbtn.on { background: var(--bad); border-color: var(--bad); color: #fff; }
  .notebtn:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
  .notebtn.on { color: var(--accent); border-color: var(--accent); }
  .roleopen {
    padding: 0; color: var(--accent); border: 0; background: transparent;
    line-height: inherit; vertical-align: baseline;
  }
  .roleopen:hover { color: var(--accent); text-decoration: underline; }

  /* 备注作为紧邻角色行的附加行，不参与斑马纹和标红底色 */
  tbody tr.note-row td {
    padding: 0; white-space: normal; text-align: left; background: var(--bg-elev);
  }
  tbody tr.note-row:hover td { background: var(--bg-elev); }
  .note-view, .note-editor {
    display: flex; align-items: center; gap: 10px; padding: 10px 14px 10px 24px;
    border-left: 3px solid var(--bad);
  }
  .note-view strong, .note-view span { color: var(--bad); }
  .note-view span { flex: 1; white-space: pre-wrap; overflow-wrap: anywhere; }
  .note-view button, .note-actions button {
    padding: 3px 9px; font-size: 11px; border-radius: 4px;
  }
  .note-editor { align-items: flex-end; }
  .note-editor label { display: grid; flex: 1; gap: 6px; color: var(--bad); font-size: 12px; }
  .note-input {
    width: 100%; min-height: 64px; resize: vertical; padding: 8px 10px;
    color: var(--t1); border: 1px solid var(--border); border-radius: 5px;
    background: var(--bg); font: inherit;
  }
  .note-input:focus { outline: 2px solid var(--bad); outline-offset: 1px; }
  .note-actions { display: flex; gap: 6px; }
  .note-save { color: #fff; background: var(--bad); border-color: var(--bad); }
  .note-delete { color: var(--bad); }
  @media (max-width: 1100px) { .stats { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 980px)  { .fgrid { grid-template-columns: repeat(2, 1fr); } }
  @media (max-width: 640px)  { .fgrid { grid-template-columns: 1fr; } }
