/* =====================================================================
   龙渊智库 Kronos Nexus — 全站样式
   品牌意象：龙纹环绕的六边形罗盘，中心为碎片形状
   ===================================================================== */

:root {
    --kn-bg: #0a0e16;
    --kn-bg-2: #0f1521;
    --kn-panel: #141b2b;
    --kn-panel-2: #1a2336;
    --kn-border: #24304a;
    --kn-border-2: #2f3d5c;
    --kn-text: #e6ecf7;
    --kn-text-dim: #9aa8c2;
    --kn-muted: #6b7a96;
    --kn-primary: #4fd1c5;
    --kn-primary-2: #38b2ac;
    --kn-accent: #c9a227;
    --kn-danger: #ef5350;
    --kn-warn: #f5a623;
    --kn-ok: #48bb78;
    --kn-radius: 10px;
    --kn-radius-sm: 6px;
    --kn-shadow: 0 6px 24px rgba(0, 0, 0, .35);
    --kn-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
    --kn-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC", sans-serif;
}

* {
    box-sizing: border-box;
}

html, body {
    margin: 0;
    padding: 0;
}

body.kn-body {
    background:
            radial-gradient(1200px 600px at 12% -8%, rgba(79, 209, 197, .10), transparent 60%),
            radial-gradient(900px 500px at 92% 4%, rgba(201, 162, 39, .08), transparent 55%),
            var(--kn-bg);
    color: var(--kn-text);
    font-family: var(--kn-sans);
    font-size: 14px;
    line-height: 1.6;
    min-height: 100vh;
}

a {
    color: var(--kn-primary);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

/* ---------------------------------------------------------------- 页头 */

.kn-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: rgba(10, 14, 22, .92);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--kn-border);
}

.kn-header-inner {
    max-width: 1440px;
    margin: 0 auto;
    padding: 10px 20px;
    display: flex;
    align-items: center;
    gap: 24px;
    /*
     * 不换行：品牌 / 导航 / 账号区必须在同一行。
     *
     * 原来这里是 flex-wrap: wrap，而「数据 + 对战 + 工具 + 运维」四组导航（管理员才看得到运维组）
     * 的最大宽度比 1440 容器的可用宽度多出约 1px —— flex 会按最大内容宽度先断行，
     * 于是账号区被挤到第二行，且因为容器有 max-width，窗口再宽也一样换行。
     * 现在让导航自己去收缩 + 内部换行（.kn-nav 自带 flex-wrap），账号区永远留在第一行右侧。
     */
    flex-wrap: nowrap;
}

.kn-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--kn-text);
    flex: 0 0 auto;
}

.kn-brand:hover {
    text-decoration: none;
}

.kn-brand-mark {
    color: var(--kn-primary);
    display: flex;
    filter: drop-shadow(0 0 6px rgba(79, 209, 197, .45));
}

.kn-brand-text {
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* 行高有意压紧（CJK 不需要西文那样的行距），但两行必须留出可辨认的间隙：
       两行行盒紧贴时「龙渊智库」与「Kronos Nexus」会糊成一块。 */
    gap: 4px;
    line-height: 1.15;
}

.kn-brand-text strong {
    font-size: 16px;
    letter-spacing: .08em;
}

.kn-brand-text small {
    font-size: 10.5px;
    color: var(--kn-muted);
    letter-spacing: .22em;
    text-transform: uppercase;
}

.kn-nav {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    /* 占据品牌与账号区之间的剩余空间；空间不够时自己内部换行，而不是把账号区顶到下一行 */
    flex: 1 1 auto;
    min-width: 0;
}

.kn-nav-group {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px 4px 4px;
    border-radius: var(--kn-radius-sm);
    background: rgba(255, 255, 255, .025);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .04);
}

.kn-nav-label {
    color: var(--kn-muted);
    font-size: 11px;
    letter-spacing: .16em;
    padding: 0 6px;
    text-transform: uppercase;
    border-right: 1px solid var(--kn-border);
    line-height: 1.4;
    align-self: stretch;
    display: flex;
    align-items: center;
}

.kn-nav-links {
    display: flex;
    align-items: center;
    gap: 3px;
    flex-wrap: wrap;
}

.kn-nav a {
    color: var(--kn-text-dim);
    padding: 6px 10px;
    border-radius: var(--kn-radius-sm);
    font-size: 13.5px;
    transition: all .16s ease;
    white-space: nowrap;
}

.kn-nav a:hover {
    background: var(--kn-panel-2);
    color: var(--kn-text);
    text-decoration: none;
}

.kn-nav a.is-active {
    background: linear-gradient(180deg, rgba(79, 209, 197, .18), rgba(79, 209, 197, .06));
    color: var(--kn-primary);
    box-shadow: inset 0 0 0 1px rgba(79, 209, 197, .3);
}

/* ---------------------------------------------------------------- 主区域 */

.kn-main {
    max-width: 1440px;
    margin: 0 auto;
    padding: 20px;
    min-height: 60vh;
}

.kn-page-title {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    margin: 8px 0 18px;
}

.kn-page-title h1 {
    font-size: 22px;
    margin: 0;
    letter-spacing: .03em;
}

.kn-page-title .kn-sub {
    color: var(--kn-muted);
    font-size: 12.5px;
    margin-top: 2px;
}

.kn-section {
    margin-bottom: 22px;
}

.kn-section-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: .06em;
    margin: 0 0 10px;
    color: var(--kn-text);
}

.kn-section-title::before {
    content: "";
    width: 4px;
    height: 14px;
    background: var(--kn-primary);
    border-radius: 2px;
    box-shadow: 0 0 8px rgba(79, 209, 197, .6);
}

/* ---------------------------------------------------------------- 卡片 */

.kn-card {
    background: linear-gradient(180deg, var(--kn-panel), var(--kn-bg-2));
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius);
    padding: 16px;
    box-shadow: var(--kn-shadow);
}

.kn-grid {
    display: grid;
    gap: 14px;
}

/* 栅格项默认 min-width:auto，会被内容（尤其窄列里的大表格）顶宽，
   于是卡片冲出轨道压到相邻列上。统一允许收缩，过宽的内容交给 .kn-table-wrap 横向滚动。 */
.kn-grid > * {
    min-width: 0;
}

.kn-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kn-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kn-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.kn-grid-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }

@media (max-width: 1100px) {
    .kn-grid-4, .kn-grid-6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .kn-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 720px) {
    .kn-grid-2, .kn-grid-3, .kn-grid-4, .kn-grid-6 { grid-template-columns: 1fr; }
    .kn-main { padding: 12px; }
}

.kn-stat {
    text-align: left;
}

.kn-stat-label {
    color: var(--kn-text-dim);
    font-size: 12px;
    letter-spacing: .06em;
}

.kn-stat-value {
    font-family: var(--kn-mono);
    font-size: 26px;
    font-weight: 600;
    color: var(--kn-primary);
    line-height: 1.2;
    margin-top: 4px;
    word-break: break-all;
}

.kn-stat-hint {
    color: var(--kn-muted);
    font-size: 11.5px;
    margin-top: 2px;
}

.kn-chart {
    width: 100%;
    min-height: 200px;
}

/* ---------------------------------------------------------------- 新鲜度状态栏 */

.kn-freshness {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    background: var(--kn-panel);
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius);
    padding: 8px 14px;
    margin-bottom: 18px;
}

.kn-freshness-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 12.5px;
    color: var(--kn-text-dim);
    letter-spacing: .06em;
    padding-right: 14px;
    border-right: 1px solid var(--kn-border);
}

.kn-freshness-items {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    flex: 1;
}

.kn-freshness-item {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
}

.kn-freshness-item .kn-fi-label {
    color: var(--kn-text-dim);
}

.kn-freshness-item .kn-fi-age {
    font-family: var(--kn-mono);
}

.kn-freshness-msg {
    font-size: 12px;
    color: var(--kn-muted);
    width: 100%;
}

.kn-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
}

.kn-dot-green { background: var(--kn-ok); box-shadow: 0 0 8px rgba(72, 187, 120, .8); }
.kn-dot-yellow { background: var(--kn-warn); box-shadow: 0 0 8px rgba(245, 166, 35, .8); }
.kn-dot-red { background: var(--kn-danger); box-shadow: 0 0 8px rgba(239, 83, 80, .8); }
.kn-dot-gray { background: var(--kn-muted); }
.kn-dot-running { background: var(--kn-primary); animation: kn-pulse 1.1s infinite; }

@keyframes kn-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: .35; transform: scale(1.35); }
}

.kn-local-freshness {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--kn-text-dim);
    background: var(--kn-panel);
    border: 1px solid var(--kn-border);
    border-radius: 999px;
    padding: 4px 10px;
}

.kn-local-freshness .kn-local-age {
    font-family: var(--kn-mono);
}

/* ---------------------------------------------------------------- 按钮 */

.kn-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border: 1px solid var(--kn-border-2);
    background: linear-gradient(180deg, var(--kn-panel-2), var(--kn-panel));
    color: var(--kn-text);
    padding: 7px 14px;
    border-radius: var(--kn-radius-sm);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    transition: all .16s ease;
    white-space: nowrap;
}

.kn-btn:hover:not(:disabled) {
    border-color: var(--kn-primary);
    color: var(--kn-primary);
}

.kn-btn:disabled {
    opacity: .5;
    cursor: not-allowed;
}

.kn-btn-primary {
    background: linear-gradient(180deg, var(--kn-primary), var(--kn-primary-2));
    border-color: var(--kn-primary);
    color: #04231f;
    font-weight: 600;
}

.kn-btn-primary:hover:not(:disabled) {
    color: #04231f;
    filter: brightness(1.08);
}

.kn-btn-ghost {
    background: transparent;
}

.kn-btn-sm { padding: 5px 10px; font-size: 12px; }
.kn-btn-xs { padding: 3px 8px; font-size: 11.5px; }

/* ---------------------------------------------------------------- 表单 */

.kn-form {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 12px;
}

.kn-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.kn-field > label {
    font-size: 12px;
    color: var(--kn-text-dim);
    letter-spacing: .04em;
}

/*
 * 字段网格里的「按钮格」：与相邻**控件**底边对齐（而不是和 label 一样顶端对齐）。
 *
 * 背景：.kn-field 是「label + 控件」的纵向 flex，按钮格没有 label，
 * 默认会顶到栅格行的最上面，看起来比旁边的输入框高一大截。
 * align-self: end 让这一格贴住行底 —— 行的底边就是控件的底边，
 * 而 .kn-btn 与 .kn-input / .kn-select 的内边距、字号、边框完全一致，高度相同，
 * 因此按钮与下拉框在同一条水平线上。
 *
 * 用于「几个下拉框 + 一个按钮」同排的卡片（英雄对战 / 公会战阵容）。
 * 字段较多的筛选卡片仍然把按钮放在独立的 .kn-form-actions 行里。
 */
.kn-field-actions {
    align-self: end;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.kn-input, .kn-select, .kn-textarea {
    background: var(--kn-bg-2);
    border: 1px solid var(--kn-border);
    color: var(--kn-text);
    padding: 7px 10px;
    border-radius: var(--kn-radius-sm);
    font-size: 13px;
    font-family: inherit;
    width: 100%;
    outline: none;
    transition: border-color .16s ease;
}

/*
 * 原生 <select> 的固有高度比同款 <input> 高 2px（实测 35 vs 33），并排时肉眼可见地不齐，
 * 所以把两者钉成同一个高度。textarea 不在此列（它要高）。
 */
.kn-input, .kn-select {
    height: 33px;
}

/* 按钮里可能是 <button> 也可能是 <a>，两者默认行高不同（实测 33 vs 36.8），
   钉住行高后才能保证同一排按钮一样高。 */
.kn-btn {
    line-height: 1.3;
}

.kn-textarea {
    min-height: 110px;
    resize: vertical;
    font-family: var(--kn-mono);
    font-size: 12.5px;
}

.kn-input:focus, .kn-select:focus, .kn-textarea:focus {
    border-color: var(--kn-primary);
    box-shadow: 0 0 0 3px rgba(79, 209, 197, .12);
}

.kn-form-actions {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 12px;
}

/* ---------------------------------------------------------------- 表格 */

.kn-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius);
    background: var(--kn-panel);
}

/* ---------------------------------------------------------------- 表单 */

/* 勾选项（记住我 / 其它开关）：与字段网格留出同样的呼吸感 */
.kn-check {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: 10px;
    font-size: 12.5px;
    color: var(--kn-text-dim);
    cursor: pointer;
    user-select: none;
}

.kn-check input[type="checkbox"] {
    width: 14px;
    height: 14px;
    accent-color: var(--kn-primary);
    cursor: pointer;
    flex: 0 0 auto;
}

/* ---------------------------------------------------------------- 标签页 */

.kn-tabs {
    display: flex;
    gap: 4px;
    border-bottom: 1px solid var(--kn-border);
    margin-bottom: 14px;
}

.kn-tab {
    appearance: none;
    border: none;
    background: transparent;
    color: var(--kn-muted);
    font-family: inherit;
    font-size: 13px;
    padding: 8px 14px;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color .16s ease, border-color .16s ease;
}

.kn-tab:hover {
    color: var(--kn-text);
}

.kn-tab.is-active {
    color: var(--kn-primary);
    border-bottom-color: var(--kn-primary);
    font-weight: 600;
}

/* 必须显式声明：面板是块级元素，自定义 display 会盖掉 [hidden] */
.kn-tab-panel[hidden] {
    display: none;
}

/* ---------------------------------------------------------------- 可搜索下拉框 */

/* 原生 select 被隐藏但仍留在 DOM 里作为数据源（见 KN.searchableSelect）
 *
 * 注意：这个类名是「可搜索下拉框的外层容器」。页面上另有一个「组合结果卡片」
 * 曾经也命名为 .kn-combo，导致卡片的内边距 / 边框 / 背景套到下拉框上
 * （下拉框外面多出一个框，且比同排的其他输入框高一大截、右侧箭头被挤成一个小点）。
 * 组合卡片现在叫 .kn-combo-card，两者不得再同名。
 */
.kn-combo {
    position: relative;
}

.kn-combo > select {
    display: none;
}

.kn-combo-input {
    padding-right: 26px;
}

/* 用 CSS 三角形而不是 ▾ 字形：11px 的字形在多数字体里糊成一个小点，看不出是「下拉」 */
.kn-combo-caret {
    position: absolute;
    right: 10px;
    top: 50%;
    width: 0;
    height: 0;
    margin-top: -2px;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid var(--kn-muted);
    cursor: pointer;
}

.kn-combo-list {
    position: absolute;
    left: 0;
    right: 0;
    top: calc(100% + 4px);
    max-height: 280px;
    overflow-y: auto;
    z-index: 90;
    background: var(--kn-panel);
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius-sm);
    box-shadow: var(--kn-shadow);
}

/* 同 [hidden] 一起必须显式声明：块级元素默认值不会盖住上面的样式 */
.kn-combo-list[hidden] {
    display: none;
}

.kn-combo-option {
    padding: 7px 10px;
    font-size: 13px;
    cursor: pointer;
    border-bottom: 1px solid rgba(255, 255, 255, .03);
}

.kn-combo-option:last-child {
    border-bottom: none;
}

.kn-combo-option:hover,
.kn-combo-option.is-active {
    background: var(--kn-panel-2);
}

.kn-combo-option.is-selected {
    color: var(--kn-primary);
}

.kn-combo-empty {
    padding: 10px;
}

/* ---------------------------------------------------------------- 登录态与模态框 */

.kn-header-right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
    /* 账号区按内容宽度，不参与压缩，也不许内部折行 */
    flex: 0 0 auto;
    white-space: nowrap;
}

.kn-user {
    position: relative;
}

.kn-user-dot {
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: 6px;
    border-radius: 50%;
    background: var(--kn-primary);
    vertical-align: middle;
}

.kn-user-menu {
    position: absolute;
    right: 0;
    top: calc(100% + 6px);
    min-width: 210px;
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    background: var(--kn-panel);
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius);
    box-shadow: var(--kn-shadow);
    z-index: 60;
}

/* 必须显式关掉：.kn-user-menu 自己写了 display:flex，会盖掉 [hidden] 的 UA 样式，
   否则 hidden 属性失效 —— 下拉菜单会一直挂在右上角关不掉。 */
.kn-user-menu[hidden] {
    display: none;
}

.kn-user-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-bottom: 8px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--kn-border);
    font-size: 12.5px;
}

body.kn-modal-open {
    overflow: hidden;
}

.kn-modal {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.kn-modal[hidden] {
    display: none;
}

.kn-modal-mask {
    position: absolute;
    inset: 0;
    background: rgba(6, 10, 16, .72);
}

.kn-modal-box {
    position: relative;
    width: 100%;
    max-width: 420px;
    max-height: 90vh;
    overflow-y: auto;
    padding: 20px;
    background: var(--kn-panel);
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius);
    box-shadow: var(--kn-shadow);
}

/* 字段较多的表单（新建 / 编辑账号）：放宽到 720px，字段网格自然排成 2~3 列 */
.kn-modal-lg {
    max-width: 720px;
    padding: 24px 26px;
}

.kn-modal-lg .kn-form {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}

.kn-modal-lg .kn-section-title {
    margin-bottom: 4px;
}

.kn-modal-close {
    position: absolute;
    right: 10px;
    top: 8px;
    width: 28px;
    height: 28px;
    border: none;
    background: transparent;
    color: var(--kn-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

.kn-modal-close:hover {
    color: var(--kn-text);
}

.kn-auth-pane[hidden] {
    display: none;
}

.kn-auth-pane .kn-form {
    grid-template-columns: 1fr;
}

/* ---------------------------------------------------------------- 管理端（系统管理） */

/* 品牌旁的「管理端」角标：一眼能看出当前在管理端，不会误以为是用户端 */
.kn-console-badge {
    align-self: center;
    margin-left: 8px;
    padding: 2px 7px;
    border: 1px solid var(--kn-primary);
    border-radius: 999px;
    color: var(--kn-primary);
    font-size: 11px;
    letter-spacing: .06em;
    white-space: nowrap;
}

/* 用户菜单里的「切换到管理端 / 用户端」：虚线框，比普通按钮显眼 */
.kn-end-switch {
    display: block;
    padding: 7px 10px;
    border: 1px dashed var(--kn-border-2);
    border-radius: var(--kn-radius-sm);
    color: var(--kn-primary);
    font-size: 12.5px;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
}

.kn-end-switch:hover {
    background: rgba(79, 209, 197, .08);
    text-decoration: none;
}

/* 管理端首页的功能入口 */
.kn-admin-entries {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.kn-admin-entry {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 10px 12px;
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius-sm);
    background: var(--kn-panel-2);
    text-decoration: none;
}

.kn-admin-entry:hover {
    border-color: var(--kn-primary);
    text-decoration: none;
}

.kn-admin-entry strong {
    color: var(--kn-text);
    font-size: 13.5px;
}

.kn-admin-entry span {
    color: var(--kn-muted);
    font-size: 12px;
}

.kn-auth-divider {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0 12px;
    color: var(--kn-muted);
    font-size: 12px;
}

.kn-auth-divider::before,
.kn-auth-divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--kn-border);
}

.kn-auth-qr {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    text-align: center;
}

/* ---------------------------------------------------------------- 登录页（手机端宽度） */

/*
 * 登录卡片按手机端宽度做（380px 居中）。
 *
 * 回归：之前登录页直接用整宽 `.kn-card`，在 1440 宽下卡片 1400px、输入框却只有 185px，
 * 二维码固定 190px 孤零零挂在中间，整页又空又乱。登录表单本来就是窄表单，
 * 按手机宽度收窄既好看也顺手（浏览器密码管理器、移动端都是这个宽度）。
 */
.kn-login-wrap {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 36px 16px 56px;
    min-height: calc(100vh - 240px);
}

.kn-login-card {
    width: 100%;
    max-width: 380px;
    padding: 22px 20px 24px;
}

/* 表单永远单列：卡片只有 380px，一列才不会被挤成 185px 的窄输入框 */
.kn-login-card .kn-form {
    grid-template-columns: 1fr;
}

.kn-login-head {
    text-align: center;
    margin-bottom: 18px;
}

.kn-login-mark {
    display: flex;
    justify-content: center;
    color: var(--kn-primary);
    filter: drop-shadow(0 0 6px rgba(79, 209, 197, .45));
    margin-bottom: 8px;
}

.kn-login-title {
    font-size: 17px;
    letter-spacing: .04em;
}

.kn-login-sub {
    color: var(--kn-muted);
    font-size: 12.5px;
    margin-top: 5px;
}

.kn-login-submit {
    width: 100%;
    margin-top: 14px;
}

.kn-login-tip {
    margin-top: 12px;
    line-height: 1.7;
}

/* 注册引导：二维码在登录卡片里收小到 148px */
.kn-login-card .kn-auth-qr img {
    width: 148px;
    height: 148px;
}

/*
 * 登录页不显示主导航：未登录时 10 个导航项点哪个都回到登录页，纯属噪音；
 * 账号区在未登录时只有一个「登录」按钮（本页就是登录页，也是多余的）。
 */
body[data-page="login"] .kn-nav {
    display: none;
}

body[data-page="login"][data-logged-in="false"] .kn-header-right {
    display: none;
}

@media (max-width: 480px) {
    .kn-login-wrap {
        padding: 20px 12px 40px;
    }

    .kn-login-card {
        padding: 18px 14px 20px;
    }
}

.kn-auth-qr img {
    width: 190px;
    height: 190px;
    object-fit: contain;
    background: #fff;
    border-radius: 10px;
    padding: 6px;
}

.kn-scope-hint {
    margin-top: 6px;
}

/* 行内操作反馈（如「已重置」）：贴在按钮旁边，用户视线就在这一行上 */
.kn-row-flash {
    display: inline-block;
    margin-left: 8px;
    vertical-align: middle;
}


table.kn-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    min-width: 640px;
}

table.kn-table th, table.kn-table td {
    padding: 9px 12px;
    text-align: left;
    border-bottom: 1px solid var(--kn-border);
    white-space: nowrap;
}

table.kn-table th {
    background: var(--kn-panel-2);
    color: var(--kn-text-dim);
    font-weight: 600;
    font-size: 12px;
    letter-spacing: .05em;
    position: sticky;
    top: 0;
}

/*
 * Top 榜表格（仪表盘「Top 20 …」）：并排的两张榜要像同一套网格。
 *
 * 浏览器默认的自动布局会按内容摊开宽度 —— 实测「Top 20 英雄」的 # 列 48px，
 * 而「Top 20 碎片持有地址」的 # 列被撑到 122px，两张表的分隔线毫无关系，看着很乱。
 * 这里改成固定布局，并把首列（#）、末列（数值列）钉成同一宽度：
 * 左右两张表的 # 列、数值列边界就对齐了，中间的文字列再按剩余宽度均分。
 * 同时把继承来的 min-width: 640px 收小，避免在 2 列栅格里横向滚动。
 */
table.kn-table.kn-table-top {
    table-layout: fixed;
    min-width: 420px;
}

table.kn-table.kn-table-top col,
table.kn-table.kn-table-top th:first-child,
table.kn-table.kn-table-top td:first-child {
    width: 48px;
}

table.kn-table.kn-table-top th:last-child,
table.kn-table.kn-table-top td:last-child {
    width: 132px;
}

table.kn-table.kn-table-top td.kn-ellipsis,
table.kn-table.kn-table-top th.kn-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Top 榜里所有单元格都裁切 + 省略号：固定布局下 nowrap 的长文本（英雄名）
   不裁切就会压到相邻列上（实测「The Plagued Hero #1373」直接盖住阵营列）。 */
table.kn-table.kn-table-top th,
table.kn-table.kn-table-top td {
    overflow: hidden;
    text-overflow: ellipsis;
}

/* 英雄榜（列最多）把宽度让给英雄名，阵营 / 所属公会窄一些，
   否则 6 列均分后名字会被截成「The Plagued Hero #1…」。 */
table.kn-table.kn-table-top.kn-table-top-hero th:nth-child(3),
table.kn-table.kn-table-top.kn-table-top-hero td:nth-child(3),
table.kn-table.kn-table-top.kn-table-top-hero th:nth-child(4),
table.kn-table.kn-table-top.kn-table-top-hero td:nth-child(4) {
    width: 100px;
}

table.kn-table.kn-table-top.kn-table-top-hero th:nth-child(5),
table.kn-table.kn-table-top.kn-table-top-hero td:nth-child(5) {
    width: 108px;
}

/*
 * 公会维度的榜单（仪表盘「Top 20 公会英雄」）：列与公会列表页一致
 * （# / 公会 / 派系 / Leader / 成员数 / 英雄数 / 剩余碎片数），比另外三张 4~6 列的榜多两列，
 * 需要把数值列收紧、把宽度让给公会列（徽章 + 公会名 + 联盟），否则公会名会被截成两三个字。
 * 列宽合计：40 + 公会(自动 ≈211) + 76 + 84 + 74 + 74 + 98 = 657px（两列栅格里的实测可用宽度）。
 * 末列给到 98px：「剩余碎片数」这 5 个字 + 表头的 letter-spacing 在 88px 里会被省略成「剩余碎片…」。
 */
table.kn-table.kn-table-top.kn-table-top-guild th:nth-child(1),
table.kn-table.kn-table-top.kn-table-top-guild td:nth-child(1) {
    width: 40px;
}

table.kn-table.kn-table-top.kn-table-top-guild th:nth-child(3),
table.kn-table.kn-table-top.kn-table-top-guild td:nth-child(3) {
    width: 76px;
}

table.kn-table.kn-table-top.kn-table-top-guild th:nth-child(4),
table.kn-table.kn-table-top.kn-table-top-guild td:nth-child(4) {
    width: 84px;
}

table.kn-table.kn-table-top.kn-table-top-guild th:nth-child(5),
table.kn-table.kn-table-top.kn-table-top-guild td:nth-child(5),
table.kn-table.kn-table-top.kn-table-top-guild th:nth-child(6),
table.kn-table.kn-table-top.kn-table-top-guild td:nth-child(6) {
    width: 74px;
}

table.kn-table.kn-table-top.kn-table-top-guild th:nth-child(7),
table.kn-table.kn-table-top.kn-table-top-guild td:nth-child(7) {
    width: 98px;
}

/*
 * Top 榜里的公会单元格要比公会列表页紧凑：徽章缩到 20px。
 * 20px 正好不超过单元格的行盒（line-height 20.8px），行高因此仍是 40px ——
 * 徽章与缩略图这类 inline-block 只要高过行盒，就会把这一张榜的行高顶起来（见上面 .kn-badge 的注释）。
 */
table.kn-table-top .kn-guild-cell {
    min-width: 0;
    gap: 6px;
}

table.kn-table-top .kn-emblem {
    width: 20px;
    height: 20px;
    border-radius: 4px;
}

table.kn-table-top .kn-emblem-fallback {
    font-size: 11px;
}

table.kn-table-top .kn-guild-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 紧凑表是键值表 / 小统计表（两三列），不应继承大表的 min-width: 640px。
   否则一旦放进 .kn-grid-2 / .kn-grid-3 的窄列里，单张表就要求 640px，
   多列相加必然把卡片撑破（公会战「阵容评估」与英雄对战的属性表都曾溢出）。 */table.kn-table.kn-table-compact {
    min-width: 0;
}

/* 合计行：与数据行区分开，但仍在同一张表里读 */
table.kn-table tfoot td {
    background: var(--kn-panel-2);
    color: var(--kn-text);
    font-weight: 600;
    border-top: 1px solid var(--kn-border);
    border-bottom: none;
}

/* ---------------------------------------------------------------- 公会单元格（徽章 + 名称） */

.kn-guild-cell {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 190px;
}

/* 公会名 +（联盟）：窄列里要能收缩并省略，否则会把徽章挤出单元格 */
.kn-guild-name {
    min-width: 0;
}

.kn-emblem {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 6px;
    overflow: hidden;
    background: var(--kn-bg-2);
    border: 1px solid var(--kn-border);
    display: flex;
    align-items: center;
    justify-content: center;
}

.kn-emblem img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.kn-emblem-fallback {
    display: none;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: var(--kn-muted);
    font-size: 13px;
}

.kn-emblem-lg {
    width: 56px;
    height: 56px;
    border-radius: 10px;
}

/* ---------------------------------------------------------------- 碎片缩略图 */

td.kn-part-thumb {
    width: 42px;
    padding: 4px 6px;
}

td.kn-part-thumb img {
    width: 34px;
    height: 34px;
    object-fit: contain;
    display: block;
    background: rgba(255, 255, 255, .04);
    border: 1px solid var(--kn-border);
    border-radius: 6px;
    image-rendering: -webkit-optimize-contrast;
}

td.kn-part-thumb .kn-emblem-fallback {
    display: none;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    color: var(--kn-muted);
    font-size: 14px;
    background: rgba(255, 255, 255, .04);
    border: 1px solid var(--kn-border);
    border-radius: 6px;
}

/* ---------------------------------------------------------------- 英雄立绘 */

.kn-hero-portrait-card {
    display: flex;
    align-items: center;
    gap: 18px;
    flex-wrap: wrap;
}

.kn-hero-portrait {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 132px;
    height: 132px;
    flex: 0 0 auto;
    background: rgba(255, 255, 255, .04);
    border: 1px solid var(--kn-border);
    border-radius: 12px;
    overflow: hidden;
}

.kn-hero-portrait img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    display: block;
}

.kn-hero-portrait .kn-emblem-fallback {
    display: none;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: var(--kn-muted);
    font-size: 32px;
}

.kn-hero-portrait-meta {
    min-width: 0;
    flex: 1 1 220px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* ---------------------------------------------------------------- 英雄对战分析 */

.kn-battle-verdict {
    margin: 12px 0 6px;
    padding: 10px 14px;
    border-radius: var(--kn-radius-sm);
    background: linear-gradient(90deg, rgba(79, 209, 197, .14), rgba(79, 209, 197, .02));
    box-shadow: inset 0 0 0 1px rgba(79, 209, 197, .25);
    font-size: 14px;
}

.kn-battle-hero {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 10px;
}

.kn-battle-portrait {
    width: 72px;
    height: 72px;
    object-fit: contain;
    flex: 0 0 auto;
    background: rgba(255, 255, 255, .04);
    border: 1px solid var(--kn-border);
    border-radius: 10px;
}

.kn-battle-hero-meta {
    min-width: 0;
    font-size: 13px;
    line-height: 1.7;
}

.kn-battle-quick {
    margin-top: 4px;
    padding: 6px 8px;
    border-radius: 6px;
    background: rgba(255, 255, 255, .03);
    font-size: 12.5px;
    line-height: 1.6;
}

.kn-table-compact th,
.kn-table-compact td {
    padding: 4px 8px;
    font-size: 12.5px;
}

.kn-table-compact th {
    color: var(--kn-muted);
    font-weight: 500;
    white-space: nowrap;
}

/* 角色卡片 */
.kn-role-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.kn-role-name {
    font-weight: 600;
    font-size: 14.5px;
}

.kn-role-factions {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

/* 阵营对位矩阵 */
.kn-battle-matrix td,
.kn-battle-matrix th {
    text-align: center;
    font-size: 12.5px;
}

.kn-matrix-cell {
    line-height: 1.35;
}

.kn-matrix-cell b {
    display: block;
    font-size: 13.5px;
}

.kn-matrix-rel {
    font-size: 11px;
    color: var(--kn-muted);
}

.kn-matrix-counter {
    background: rgba(79, 209, 197, .13);
    box-shadow: inset 0 0 0 1px rgba(79, 209, 197, .28);
}

.kn-matrix-weak {
    background: rgba(239, 108, 108, .11);
    box-shadow: inset 0 0 0 1px rgba(239, 108, 108, .25);
}

.kn-matrix-neutral {
    background: rgba(255, 255, 255, .02);
}

.kn-matrix-self {
    color: var(--kn-muted);
    background: rgba(255, 255, 255, .015);
}

.kn-code {
    margin: 0;
    padding: 10px 12px;
    overflow-x: auto;
    font-family: var(--kn-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--kn-text-dim);
    background: rgba(0, 0, 0, .28);
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius-sm);
}

.kn-list {
    margin: 6px 0 0;
    padding-left: 18px;
    font-size: 13px;
    line-height: 1.75;
    color: var(--kn-text-dim);
}

/* 规则核对标记：满足 / 未满足（阵容推荐的蓝图条款勾选） */
.kn-ok {
    color: var(--kn-ok);
    font-weight: 700;
}

.kn-danger {
    color: var(--kn-danger);
    font-weight: 700;
}

/*
 * 派系徽标。
 *
 * 这里必须写成 `.kn-badge.kn-faction-*`（两个类）—— `.kn-badge` 自身也设了 color，
 * 与本段选择器**特异性相同**，因此谁在后面谁赢：`.kn-badge` 定义在文件后面（徽章那一节），
 * 结果派系的紫 / 金配色一直没生效，实测 `kn-badge kn-faction-dark` 的 color 是
 * `rgb(154, 168, 194)`（徽章的灰）而不是 `rgb(192, 132, 252)`。
 * 加一个类把特异性提上去，两段谁前谁后都对。
 */
.kn-badge.kn-faction-dark {
    color: #c084fc;
    border-color: #6b46c1;
    background: rgba(107, 70, 193, .16);
}

.kn-badge.kn-faction-light {
    color: #f6c445;
    border-color: #b7791f;
    background: rgba(183, 121, 31, .16);
}

.kn-badge.kn-faction-neutral {
    color: #9aa8c2;
}

/* ---------------------------------------------------------------- 排序表头 */

table.kn-table th[data-sort] {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    transition: color .14s ease, background .14s ease;
}

table.kn-table th[data-sort]:hover {
    color: var(--kn-primary);
    background: rgba(79, 209, 197, .10);
}

table.kn-table th[data-sort]:focus-visible {
    outline: 2px solid var(--kn-primary);
    outline-offset: -2px;
}

/* 未排序：弱化提示；已排序：高亮 + 箭头 */
table.kn-table th[data-sort]::after {
    content: "⇅";
    margin-left: 5px;
    opacity: .32;
    font-size: 10px;
    display: inline-block;
}

table.kn-table th.kn-sortable-active {
    color: var(--kn-primary);
    background: rgba(79, 209, 197, .12);
}

table.kn-table th.kn-sort-asc::after {
    content: "▲";
    opacity: 1;
    font-size: 9px;
}

table.kn-table th.kn-sort-desc::after {
    content: "▼";
    opacity: 1;
    font-size: 9px;
}

/* 排序说明条 */
.kn-sort-hint {
    font-size: 11.5px;
    color: var(--kn-muted);
    margin-left: 8px;
}

.kn-sort-hint b {
    color: var(--kn-primary);
    font-weight: 600;
}

/* 列表表头内的统计信息
   —— 公会 / 碎片 / 英雄三张列表统一把统计卡片取消，改为在表头一行展示 */
.kn-stat-inline {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 3px 16px;
    margin-left: 10px;
    font-size: 11.5px;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--kn-muted);
}

.kn-stat-inline > span {
    white-space: nowrap;
}

.kn-stat-inline b {
    font-family: var(--kn-mono);
    font-size: 12.5px;
    font-weight: 600;
    color: var(--kn-text);
}

/* 关键指标（命中数 / 匹配数）用主色突出 */
.kn-stat-inline b.kn-stat-strong {
    color: var(--kn-primary);
}

/* 统计项之间的分隔符 */
.kn-stat-inline .kn-stat-sep {
    color: var(--kn-border-2);
    margin: 0 -8px;
}

table.kn-table tbody tr:hover {
    background: rgba(79, 209, 197, .05);
}

table.kn-table td.kn-mono, .kn-mono {
    font-family: var(--kn-mono);
    font-size: 12.2px;
}

.kn-num {
    font-family: var(--kn-mono);
    text-align: right;
}

/* ---------------------------------------------------------------- 徽章 */

.kn-badge {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 11.5px;
    line-height: 1.7;
    border: 1px solid var(--kn-border-2);
    background: rgba(255, 255, 255, .03);
    color: var(--kn-text-dim);
    white-space: nowrap;
}

/*
 * 表格里的徽章不得影响行高。
 *
 * 徽章是 inline-block + 上下各 1px 内边距 + 上下各 1px 边框，实测整颗 23.55px，
 * 而单元格的行盒只有 line-height: 20.8px —— 徽章把行盒顶高 2.75px：
 * 同一个列表里「有徽章的行 43px、纯文本行 40px」。
 * 回归现场：仪表盘「Top 20 英雄」「Top 20 公会英雄」的阵营列是徽章，每行 43px，
 * 旁边的「Top 20 碎片持有地址」「Top 20 英雄持有地址」是纯文本、每行 40px，
 * 20 行就差 55px，左右两张榜的底部永远对不齐（碎片检索页的 Bonus 徽章同理，
 * 同一张表里带 Bonus 的行与不带的行高度不同）。
 *
 * 改成 inline：上下内边距与边框照常绘制（胶囊外观不变，单元格自带 4px 以上内边距，
 * 够容纳这点溢出），但不再参与行盒高度计算 —— 行高只由 line-height 决定，
 * 同一张表内、不同表之间都一致。
 */
table.kn-table .kn-badge {
    display: inline;
}

.kn-q-common { color: #b6c2d4; border-color: #47536b; }
.kn-q-uncommon { color: #6ee7a8; border-color: #2f855a; background: rgba(47, 133, 90, .12); }
.kn-q-rare { color: #63b3ed; border-color: #2b6cb0; background: rgba(43, 108, 176, .14); }
.kn-q-epic { color: #c084fc; border-color: #6b46c1; background: rgba(107, 70, 193, .16); }
.kn-q-legendary { color: #f6c445; border-color: #b7791f; background: rgba(183, 121, 31, .16); }

.kn-f-knight { color: #93c5fd; }
.kn-f-adventurer { color: #86efac; }
.kn-f-wizard { color: #a5b4fc; }
.kn-f-grum { color: #fca5a5; }
.kn-f-the-plagued { color: #a3e635; }
.kn-f-nightspawn { color: #c084fc; }
.kn-f-mithia { color: #5eead4; }

.kn-tag {
    display: inline-block;
    padding: 2px 8px;
    margin: 2px 4px 2px 0;
    border-radius: var(--kn-radius-sm);
    background: var(--kn-panel-2);
    border: 1px solid var(--kn-border);
    font-size: 12px;
    font-family: var(--kn-mono);
}

.kn-status {
    font-size: 11.5px;
    padding: 1px 7px;
    border-radius: 999px;
    border: 1px solid var(--kn-border-2);
}

.kn-status-free { color: #6ee7a8; border-color: #2f855a; }
.kn-status-forged { color: #f6c445; border-color: #b7791f; }
.kn-status-unknown { color: var(--kn-muted); }

/* ---------------------------------------------------------------- 分页 */

.kn-pager {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 12px;
    font-size: 12.5px;
    color: var(--kn-text-dim);
}

.kn-pager button.kn-current {
    border-color: var(--kn-primary);
    color: var(--kn-primary);
    font-weight: 600;
}

/* ---------------------------------------------------------------- 空 / 提示 */

.kn-empty {
    text-align: center;
    padding: 40px 16px;
    color: var(--kn-muted);
}

.kn-empty-icon {
    font-size: 30px;
    color: var(--kn-border-2);
    margin-bottom: 6px;
}

.kn-muted { color: var(--kn-muted); }
.kn-small { font-size: 11.5px; }
.kn-dim { color: var(--kn-text-dim); }
.kn-right { text-align: right; }
.kn-center { text-align: center; }
.kn-mt { margin-top: 14px; }
.kn-mb { margin-bottom: 14px; }

.kn-alert {
    border-radius: var(--kn-radius-sm);
    padding: 10px 14px;
    font-size: 13px;
    border: 1px solid;
    margin-bottom: 14px;
}

.kn-alert-error { border-color: var(--kn-danger); background: rgba(239, 83, 80, .1); color: #ffb4b2; }
.kn-alert-warn { border-color: var(--kn-warn); background: rgba(245, 166, 35, .1); color: #ffd79a; }
.kn-alert-ok,
.kn-alert-success { border-color: var(--kn-ok); background: rgba(72, 187, 120, .1); color: #b6f0cd; }
.kn-alert-info { border-color: var(--kn-border-2); background: rgba(79, 209, 197, .07); color: var(--kn-text); }

.kn-loading {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid rgba(255, 255, 255, .2);
    border-top-color: var(--kn-primary);
    border-radius: 50%;
    animation: kn-spin .7s linear infinite;
    vertical-align: -2px;
    margin-right: 6px;
}

@keyframes kn-spin {
    to { transform: rotate(360deg); }
}

/* ---------------------------------------------------------------- 组合结果 */

/* 类名必须区别于「可搜索下拉框」的容器 .kn-combo（见上方），否则卡片样式会漏到下拉框上。 */
.kn-combo-card {
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius);
    background: linear-gradient(180deg, var(--kn-panel), var(--kn-bg-2));
    padding: 14px 16px;
    margin-bottom: 14px;
}

.kn-combo-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    border-bottom: 1px dashed var(--kn-border);
    padding-bottom: 10px;
    margin-bottom: 10px;
}

.kn-combo-power {
    font-family: var(--kn-mono);
    font-size: 24px;
    color: var(--kn-primary);
    font-weight: 700;
}

.kn-combo-meta {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
    font-size: 12.5px;
    color: var(--kn-text-dim);
}

.kn-combo-parts {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 8px;
    margin-top: 10px;
}

.kn-part {
    border: 1px solid var(--kn-border);
    border-radius: var(--kn-radius-sm);
    background: var(--kn-bg-2);
    padding: 7px 9px;
    font-size: 12px;
}

.kn-part-type {
    color: var(--kn-muted);
    font-size: 11px;
    letter-spacing: .04em;
}

.kn-part-id {
    font-family: var(--kn-mono);
    font-size: 13px;
    color: var(--kn-text);
}

.kn-part-detail {
    color: var(--kn-text-dim);
    font-size: 11.5px;
}

.kn-part.kn-part-bonus {
    border-color: var(--kn-accent);
    box-shadow: inset 0 0 0 1px rgba(201, 162, 39, .25);
}

/* 已合成进英雄的碎片（全网推荐模式②）：整块描红，一眼能看出这套里有几件其实已经用掉了 */
.kn-part.kn-part-forged {
    border-color: var(--kn-danger);
    box-shadow: inset 0 0 0 1px rgba(229, 107, 111, .22);
}

.kn-part.kn-part-forged .kn-part-type {
    color: var(--kn-danger);
}

.kn-stat-row {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    font-family: var(--kn-mono);
    font-size: 12.5px;
    margin-top: 8px;
}

.kn-stat-row span b {
    color: var(--kn-primary);
}

.kn-address-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}

.kn-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--kn-panel-2);
    border: 1px solid var(--kn-border);
    border-radius: 999px;
    padding: 3px 8px 3px 10px;
    font-family: var(--kn-mono);
    font-size: 11.5px;
}

.kn-chip button {
    background: none;
    border: none;
    color: var(--kn-muted);
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
    padding: 0 2px;
}

.kn-chip button:hover { color: var(--kn-danger); }

/* ---------------------------------------------------------------- 详情列表 */

.kn-kv {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 6px 14px;
    font-size: 13px;
}

.kn-kv dt {
    color: var(--kn-muted);
    font-size: 12px;
}

.kn-kv dd {
    margin: 0;
    font-family: var(--kn-mono);
    font-size: 12.5px;
    word-break: break-all;
}

/* ---------------------------------------------------------------- 页脚 */

.kn-footer {
    max-width: 1440px;
    margin: 30px auto 0;
    padding: 18px 20px 30px;
    border-top: 1px solid var(--kn-border);
    display: flex;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    font-size: 12.5px;
}

/* ---------------------------------------------------------------- 点击复制 */

/*
 * 带 data-copy 的元素点一下即复制完整值（成员地址 / 碎片编号 / 英雄编号）。
 * 图标用 ::after + box-shadow 画两个叠起来的小方框（复制图标），不用字形 ——
 * 小字号下的 ⧉ / ▾ 这类字符在很多字体里会糊成一个点（本项目踩过）。
 */
.kn-copy {
    cursor: copy;
    border-bottom: 1px dashed transparent;
}

.kn-copy:hover,
.kn-copy:focus {
    border-bottom-color: var(--kn-border-2);
    color: var(--kn-primary);
    outline: none;
}

.kn-copy::after {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-left: 4px;
    border: 1px solid currentColor;
    border-radius: 1px;
    box-shadow: 2px -2px 0 -1px currentColor;
    opacity: 0;
    transition: opacity .15s ease;
    vertical-align: middle;
}

.kn-copy:hover::after,
.kn-copy:focus::after {
    opacity: .75;
}

/* 小图标复制按钮：给「本身是链接」的值用，不抢跳转的点击 */
.kn-copy-btn {
    display: inline-block;
    width: 14px;
    height: 14px;
    margin-left: 5px;
    padding: 0;
    border: none;
    background: none;
    color: var(--kn-muted);
    cursor: copy;
    vertical-align: middle;
    position: relative;
    opacity: .55;
    transition: opacity .15s ease, color .15s ease;
}

.kn-copy-btn::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 4px;
    width: 7px;
    height: 7px;
    border: 1px solid currentColor;
    border-radius: 1px;
    box-shadow: 3px -3px 0 -1px currentColor;
}

.kn-copy-btn:hover,
.kn-copy-btn:focus {
    opacity: 1;
    color: var(--kn-primary);
    outline: none;
}

/* 复制反馈：右下角短暂浮层 */
.kn-toast {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 200;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    pointer-events: none;
}

.kn-toast-item {
    background: var(--kn-panel-2);
    border: 1px solid var(--kn-border-2);
    color: var(--kn-text);
    border-radius: var(--kn-radius-sm);
    padding: 8px 12px;
    font-size: 12.5px;
    box-shadow: var(--kn-shadow);
    opacity: 0;
    transform: translateY(6px);
    transition: opacity .18s ease, transform .18s ease;
}

.kn-toast-item.is-show {
    opacity: 1;
    transform: none;
}

.kn-toast-item.is-error {
    border-color: var(--kn-danger);
    color: #ffb4b2;
}

/* ---------------------------------------------------------------- 窄屏 */

/*
 * 顶栏默认 flex-wrap: nowrap（保证账号区不被挤到第二行）。
 * 窗口很窄时品牌 + 导航 + 账号区已经在同一条线上放不下，此时恢复成可换行，
 * 并让导航独占整行，避免出现横向滚动条。
 */
@media (max-width: 860px) {
    .kn-header-inner {
        flex-wrap: wrap;
    }

    .kn-nav {
        order: 3;
        flex: 1 1 100%;
    }

    .kn-header-right {
        margin-left: auto;
    }
}

/* ---------------------------------------------------------------- 打印 */

@media print {
    .kn-header, .kn-freshness, .kn-footer, .kn-btn { display: none !important; }
    body.kn-body { background: #fff; color: #000; }
}
