/* ============================================================
   TO DO WOKER · app.css
   严格遵循 MASTER.md（StyleKit: corporate-clean 企业简洁风）
   卡片无阴影·纯描边 #EBEBEB·主色 #3670F7·圆角 8/12/16
   ============================================================ */

:root {
    --primary: #3670F7;
    --primary-hover: #2560E0;
    --primary-light: #EEF3FF;
    --primary-bg: #F3F5FB;
    --primary-a08: rgba(54,112,247,0.08);
    --primary-a12: rgba(54,112,247,0.12);
    --primary-a14: rgba(54,112,247,0.14);
    --primary-a20: rgba(54,112,247,0.2);
    --bg: #FAFAFA;
    --surface: #FFFFFF;
    --surface-hover: #F5F5F5;
    --border: #EBEBEB;
    --border-hover: #D9D9D9;
    --t1: #252525;
    --t2: #7D7D7D;
    --t3: #B0B0B0;
    --icon: #111111;
    --green: #10b981;   --green-bg: #E8F5E9;  --green-t: #2E7D32;
    --red: #ef4444;     --red-bg: #FFEBEE;    --red-t: #C62828;
    --orange: #f59e0b;  --orange-bg: #FFF3E0; --orange-t: #E65100;
    --topbar-bg: rgba(250, 250, 250, 0.85);
    --paper: #FFFFFF;
    --paper-border: #E0E0E0;
    --paper-bg: #EDEDED;
    --r: 8px;
    --r-lg: 12px;
    --r-xl: 16px;
    --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.06);
    --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.08);
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { font-size: 14px; }
body {
    font-family: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI',
        'PingFang SC', 'Microsoft YaHei', sans-serif;
    color: var(--t1);
    background: var(--bg);
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

a { color: var(--primary); text-decoration: none; }
a:hover { color: var(--primary-hover); text-decoration: underline; }
h1, h2, h3, h4 { font-weight: 600; letter-spacing: -0.025em; }
h1 { font-size: 22px; }
h2 { font-size: 18px; }
h3 { font-size: 16px; }

/* ---------------- 布局：侧边栏 + 顶栏 + 内容区 ---------------- */
.sidebar {
    position: fixed; inset-block: 0; left: 0; width: 256px;
    background: var(--bg); border-right: 1px solid var(--border);
    display: flex; flex-direction: column;
    z-index: 100; transition: transform 200ms var(--ease);
}
.sidebar-logo {
    height: 64px; display: flex; align-items: center; gap: 10px;
    padding: 0 20px; border-bottom: 1px solid var(--border);
    font-weight: 700; font-size: 16px; color: var(--t1); white-space: nowrap;
}
.sidebar-logo .logo-mark {
    width: 30px; height: 30px; border-radius: var(--r);
    background: var(--primary); color: #fff;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 12px; font-weight: 700; flex: none;
}
.sidebar-logo small { display: block; font-size: 10px; color: var(--t3); font-weight: 400; }
/* 产品 Logo（图片形态）：透明背景、保持比例 */
img.logo-mark { background: none; padding: 0; object-fit: contain; }

.sidebar-nav { flex: 1; overflow-y: auto; padding: 12px; }
/* 隐藏滚动条（保留滚动能力）—— Firefox + Webkit + IE/Edge */
.sidebar-nav { scrollbar-width: none; -ms-overflow-style: none; }
.sidebar-nav::-webkit-scrollbar { width: 0; height: 0; display: none; }

.nav-group-title {
    font-size: 11px; color: var(--t3); padding: 12px 14px 6px;
    text-transform: uppercase; letter-spacing: 0.05em;
}

/* 可折叠组：toggle 按钮 + body 容器 */
.nav-group-toggle {
    display: flex; align-items: center; gap: 8px;
    width: calc(100% - 8px);
    padding: 10px 12px; margin: 12px 4px 4px;
    border: none; background: none; cursor: pointer;
    font-size: 11px; color: var(--t3);
    text-transform: uppercase; letter-spacing: 0.05em;
    font-weight: 600;
    border-radius: var(--r);
    transition: background 120ms var(--ease), color 120ms var(--ease);
    text-align: left;
}
.nav-group-toggle:first-child { margin-top: 0; }
.nav-group-toggle:hover { background: var(--surface-hover); color: var(--t1); }
.nav-group-toggle svg { width: 14px; height: 14px; flex: none; color: var(--icon); }
.nav-group-toggle .label { flex: 1; }
.nav-group-toggle .caret {
    transition: transform 200ms var(--ease);
    width: 12px; height: 12px;
}
.nav-group-toggle[aria-expanded="true"] .caret { transform: rotate(180deg); }

/* body 容器：用 max-height 过渡（兼容性最好，grid 0fr→1fr Chrome 117+ 才支持） */
.nav-group-body {
    max-height: 0;
    overflow: hidden;
    transition: max-height 240ms var(--ease);
}
.nav-group-body.open {
    max-height: 1200px;  /* 足够大；展开时 JS 会用真实高度覆盖，关闭时回 0 */
}
.nav-item {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 14px; margin-bottom: 2px; border-radius: var(--r);
    color: var(--t1); font-weight: 500; text-decoration: none;
    transition: all 150ms var(--ease);
}
.nav-item svg { width: 14px; height: 14px; color: var(--icon); flex: none; }
.nav-item:hover { background: var(--surface-hover); text-decoration: none; }
.nav-item.active { background: var(--primary-light); color: var(--primary); font-weight: 500; }
.nav-item.active svg { color: var(--primary); }

.sidebar-footer { padding: 12px; border-top: 1px solid var(--border); }

/* 顶栏搜索框（紧凑胶囊样式） */
.topbar-search {
    display: flex; align-items: center; gap: 6px;
    background: var(--surface-hover);
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 4px 12px;
    width: 260px;
    transition: border-color 120ms var(--ease), background 120ms var(--ease);
}
.topbar-search:focus-within { border-color: var(--primary); background: var(--surface); }
.topbar-search svg { width: 14px; height: 14px; color: var(--t3); flex: none; }
.topbar-search input {
    flex: 1; border: none; outline: none; background: transparent;
    font-size: 13px; color: var(--t1); padding: 6px 0;
}
.topbar-search input::placeholder { color: var(--t3); }
@media (max-width: 720px) { .topbar-search { display: none; } }

.topbar {
    position: fixed; top: 0; right: 0; left: 256px; height: 64px;
    background: var(--topbar-bg);
    backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border);
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 28px; z-index: 90;
}
.topbar-title { font-weight: 600; font-size: 15px; display: flex; align-items: center; gap: 8px; }
.topbar-right { display: flex; align-items: center; gap: 16px; margin-left: auto; }
/* 顶栏单行布局：左（菜单+标题）· 中（广播横幅，可伸缩截断）· 右（铃铛/搜索/用户） */
.topbar-row { display: flex; align-items: center; gap: 14px; width: 100%; min-width: 0; }
.topbar-left { display: flex; align-items: center; gap: 14px; flex: none; }
.topbar-banner {
    flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px;
    background: var(--primary-a08); color: var(--primary);
    font-size: 12px; line-height: 1.4; padding: 6px 12px; border-radius: 999px;
    border: 1px solid var(--primary-a20);
    white-space: nowrap; overflow: hidden; text-decoration: none;
    transition: background 150ms var(--ease);
}
.topbar-banner svg { width: 13px; height: 13px; flex: none; }
.topbar-banner span { overflow: hidden; text-overflow: ellipsis; }
.topbar-banner:hover { background: var(--primary-a14); color: var(--primary); text-decoration: none; }
.topbar-user { display: flex; align-items: center; gap: 10px; }
.topbar-user .u-name { font-weight: 500; }
.topbar-user .u-sub { font-size: 12px; color: var(--t2); }
#menu-btn {
    display: none; border: 1px solid var(--border); background: var(--surface);
    border-radius: var(--r); width: 36px; height: 36px; align-items: center; justify-content: center;
    cursor: pointer; color: var(--t1);
}

.content { margin-left: 256px; padding: 88px 28px 40px; min-height: 100vh; }
.page-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; gap: 12px; }
.page-head .sub { color: var(--t2); margin-top: 4px; font-size: 13px; }

/* ---------------- 组件 ---------------- */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    padding: 8px 16px; border-radius: var(--r); font-size: 14px; font-weight: 500;
    border: 1px solid transparent; cursor: pointer; text-decoration: none;
    transition: all 150ms var(--ease); font-family: inherit; line-height: 1.4;
    user-select: none;
}
.btn:active { transform: scale(0.97); }
.btn svg { width: 14px; height: 14px; }
.btn-pri { background: var(--primary); color: #fff; }
.btn-pri:hover { background: var(--primary-hover); color: #fff; text-decoration: none; }
.btn-sec { background: var(--surface); color: var(--t2); border-color: var(--border); }
.btn-sec:hover { border-color: var(--border-hover); color: var(--t1); text-decoration: none; }
.btn-danger { background: var(--red-bg); color: var(--red-t); }
.btn-danger:hover { text-decoration: none; filter: brightness(0.97); }
.btn-green { background: var(--green-bg); color: var(--green-t); }
.btn-green:hover { text-decoration: none; filter: brightness(0.97); }
.btn-sm { padding: 4px 10px; font-size: 12px; border-radius: 6px; }
.btn-block { width: 100%; }
.btn[disabled] { opacity: 0.55; cursor: not-allowed; }

.card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-xl); padding: 24px; margin-bottom: 16px;
}
.card:hover { border-color: var(--border-hover); }
.card-title { font-size: 15px; font-weight: 600; margin-bottom: 16px; display: flex; align-items: center; justify-content: space-between; }
.card-title svg { width: 16px; height: 16px; }

.input, .select, .textarea {
    padding: 8px 12px; border: 1px solid var(--border); border-radius: var(--r);
    font-size: 14px; background: var(--surface); color: var(--t1);
    font-family: inherit; width: 100%; transition: border-color 150ms var(--ease), box-shadow 150ms var(--ease);
}
.input:focus, .select:focus, .textarea:focus {
    outline: none; border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-a12);
}
.textarea { min-height: 90px; resize: vertical; }
.label { display: block; font-size: 13px; font-weight: 500; margin-bottom: 6px; color: var(--t1); }
.label .req { color: var(--red-t); }
.form-item { margin-bottom: 16px; }
.form-hint { font-size: 12px; color: var(--t3); margin-top: 4px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

.table-wrap { overflow-x: auto; }
table.table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.table th {
    text-align: left; font-size: 12px; color: var(--t2); font-weight: 500;
    padding: 10px 12px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.table td { padding: 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.table tr:last-child td { border-bottom: none; }
.table tr:hover td { background: var(--surface-hover); }
.table .num { font-variant-numeric: tabular-nums; }
/* 拥挤列保底宽度：避免多列挤成一团 */
.table td.nowrap, .table th.nowrap { white-space: nowrap; }
.table td.date-col { white-space: nowrap; min-width: 130px; }
.table td.title-col { min-width: 180px; }
.table td.mid-col  { white-space: nowrap; min-width: 110px; }

.badge {
    display: inline-flex; align-items: center; padding: 2px 10px;
    border-radius: 6px; font-size: 12px; font-weight: 500; white-space: nowrap;
}
.badge-blue   { background: var(--primary-light); color: var(--primary); }
.badge-green  { background: var(--green-bg);   color: var(--green-t); }
.badge-red    { background: var(--red-bg);     color: var(--red-t); }
.badge-orange { background: var(--orange-bg);  color: var(--orange-t); }
.badge-gray   { background: var(--surface-hover); color: var(--t2); }

.avatar {
    border-radius: 50%; border: 1px solid var(--border);
    object-fit: cover; background: var(--primary-light);
    display: inline-flex; align-items: center; justify-content: center; flex: none;
}
.avatar-24 { width: 24px; height: 24px; }
.avatar-32 { width: 32px; height: 32px; }
.avatar-40 { width: 40px; height: 40px; }
.avatar-56 { width: 56px; height: 56px; }

.flash {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 16px; border-radius: var(--r); margin-bottom: 16px;
    font-size: 13.5px; border: 1px solid transparent;
}
.flash svg { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.flash-success { background: var(--green-bg); color: var(--green-t); border-color: rgba(46, 125, 50, 0.15); }
.flash-error   { background: var(--red-bg);   color: var(--red-t);   border-color: rgba(198, 40, 40, 0.15); }
.flash .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 700; }

.errors-list {
    background: var(--red-bg); color: var(--red-t); border: 1px solid rgba(198, 40, 40, 0.15);
    border-radius: var(--r); padding: 12px 16px; margin-bottom: 16px; font-size: 13.5px;
}
.errors-list li { margin-left: 18px; }

.empty {
    text-align: center; color: var(--t3); padding: 40px 0; font-size: 13px;
}
.empty svg { width: 28px; height: 28px; margin-bottom: 8px; color: var(--t3); }

.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 16px; }
.stat-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-lg); padding: 20px;
}
.stat-card .s-label { font-size: 12px; color: var(--t2); margin-bottom: 8px; }
.stat-card .s-value { font-size: 24px; font-weight: 700; font-variant-numeric: tabular-nums; }
.stat-card .s-icon {
    width: 34px; height: 34px; border-radius: var(--r-lg);
    background: var(--primary-light); color: var(--primary);
    display: inline-flex; align-items: center; justify-content: center; margin-bottom: 10px;
}
.stat-card .s-icon svg { width: 16px; height: 16px; }

.pagination { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin-top: 16px; font-size: 13px; }
.pagination li a, .pagination li span {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 32px; height: 32px; padding: 0 8px;
    border: 1px solid var(--border); border-radius: var(--r);
    background: var(--surface); color: var(--t2);
}
.pagination li.active span { background: var(--primary); border-color: var(--primary); color: #fff; }
.pagination li.disabled span { color: var(--t3); background: var(--bg); }
.pagination li a:hover { border-color: var(--border-hover); color: var(--primary); text-decoration: none; }

.filter-bar { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin-bottom: 16px; }
.filter-bar .f-item label { display: block; font-size: 12px; color: var(--t2); margin-bottom: 4px; }
.filter-bar .input, .filter-bar .select { width: auto; min-width: 140px; }

pre.log-detail {
    background: var(--primary-bg); border: 1px solid var(--border);
    border-radius: var(--r); padding: 12px; font-size: 12px;
    overflow-x: auto; line-height: 1.6; margin-top: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
details.summary-row summary { cursor: pointer; color: var(--t2); font-size: 12px; user-select: none; }

.perm-module { border: 1px solid var(--border); border-radius: var(--r-lg); padding: 16px; margin-bottom: 12px; }
.perm-module h4 { font-size: 13px; color: var(--t1); margin-bottom: 12px; display: flex; align-items: center; gap: 6px; }
.perm-module h4 svg { width: 14px; height: 14px; }
.perm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; }
.perm-check { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; cursor: pointer; padding: 6px 8px; border-radius: 6px; }
.perm-check:hover { background: var(--surface-hover); }
.perm-check input { margin-top: 3px; accent-color: var(--primary); }
.perm-check .p-name { font-weight: 500; }
.perm-check .p-desc { font-size: 11.5px; color: var(--t3); }
.perm-item { border: 1px dashed transparent; border-radius: var(--r); }
.perm-item:has(.scope-box) { border-color: var(--border); padding: 6px 8px; }

/* 权限作用域（全部 / 指定资源） */
.scope-box { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 8px; padding: 8px 10px; background: var(--primary-bg); border-radius: 6px; }
.scope-box .scope-label { font-size: 12px; color: var(--t2); }
.radio-line { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; cursor: pointer; color: var(--t1); }
.radio-line input { accent-color: var(--primary); width: 14px; height: 14px; }
.radio-line.disabled { color: var(--t3); cursor: not-allowed; }
.scope-targets { flex-basis: 100%; }
.scope-targets select[multiple] { min-height: 84px; }

.checkbox-line { display: flex; align-items: center; gap: 8px; font-size: 13.5px; cursor: pointer; }
.checkbox-line input { accent-color: var(--primary); width: 15px; height: 15px; }

/* ---------------- 认证页（登录/注册/安装） ---------------- */
.auth-wrap {
    min-height: 100vh; display: flex; align-items: center; justify-content: center;
    padding: 24px; background: var(--bg);
}
.auth-card {
    width: 100%; max-width: 420px; background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--r-xl); padding: 32px;
    max-height: calc(100vh - 48px); overflow-y: auto;
}
/* 隐藏 auth 卡片内部滚动条 */
.auth-card { scrollbar-width: none; }
.auth-card::-webkit-scrollbar { display: none; }
.auth-card.wide { max-width: 520px; }
.auth-logo { display: flex; align-items: center; gap: 12px; margin-bottom: 24px; }
.auth-logo .logo-mark {
    width: 40px; height: 40px; border-radius: var(--r-lg);
    background: var(--primary); color: #fff; font-weight: 700; font-size: 14px;
    display: flex; align-items: center; justify-content: center; flex: none;
}
.auth-logo .a-title { font-size: 17px; font-weight: 700; }
.auth-logo .a-sub { font-size: 11px; color: var(--t3); }
.auth-foot { text-align: center; font-size: 13px; color: var(--t2); margin-top: 16px; }
.auth-announce {
    background: var(--primary-light); border-radius: var(--r);
    padding: 10px 14px; font-size: 12.5px; color: var(--primary); margin-bottom: 16px;
}

.step-dots { display: flex; gap: 8px; margin-bottom: 20px; }
.step-dots .dot {
    flex: 1; height: 4px; border-radius: 2px; background: var(--border);
}
.step-dots .dot.on { background: var(--primary); }

/* ---------------- 响应式 ---------------- */
@media (max-width: 1024px) {
    .stat-grid { grid-template-columns: repeat(2, 1fr); }
    .form-row { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
    .sidebar { transform: translateX(-100%); box-shadow: var(--shadow-lg); }
    body.sidebar-open .sidebar { transform: translateX(0); }
    body.sidebar-open .sidebar-mask {
        display: block; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.3); z-index: 99;
    }
    .topbar { left: 0; padding: 0 16px; }
    #menu-btn { display: inline-flex; }
    .content { margin-left: 0; padding: 84px 16px 32px; }
    .stat-grid { grid-template-columns: repeat(2, 1fr); }
    .form-row { grid-template-columns: 1fr; }
    .topbar-user .u-sub { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { transition: none !important; animation: none !important; }
}

@keyframes fadeInUp {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
}
.content > * { animation: fadeInUp 350ms var(--ease); }

/* ---------------- 全局模态弹窗（弹入弹出） ---------------- */
body.modal-open { overflow: hidden; }
.modal-mask {
    position: fixed; inset: 0; background: rgba(0, 0, 0, 0.35);
    z-index: 900; opacity: 0; animation: modalFadeIn 220ms var(--ease) forwards;
}
.modal-mask.closing { animation: modalFadeOut 200ms var(--ease) forwards; }
.modal-box {
    position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
    width: min(92vw, 420px); background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--r-xl);
    padding: 24px; z-index: 901; box-shadow: var(--shadow-lg);
    opacity: 0; animation: modalPopIn 300ms cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}
.modal-box.closing { animation: modalPopOut 200ms var(--ease) forwards; }
.modal-title { font-size: 16px; font-weight: 600; margin-bottom: 10px; }
.modal-msg { font-size: 13.5px; color: var(--t2); line-height: 1.7; white-space: pre-wrap; word-break: break-word; }
.modal-input { margin-top: 14px; }
.modal-content { font-size: 13.5px; color: var(--t2); max-height: 60vh; overflow-y: auto; }
.modal-content .form-item { margin-bottom: 10px; }
.modal-content .form-item label { display:block; font-size:12px; color:var(--t3); margin-bottom:4px; }
.modal-content .modal-actions { display:flex; justify-content:flex-end; gap:10px; margin-top:16px; padding-top:14px; border-top:1px solid var(--border); }
.modal-btns { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }
@keyframes modalFadeIn { to { opacity: 1; } }
@keyframes modalFadeOut { from { opacity: 1; } to { opacity: 0; } }
@keyframes modalPopIn { from { opacity: 0; transform: translate(-50%, -46%) scale(0.92); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@keyframes modalPopOut { from { opacity: 1; transform: translate(-50%, -50%) scale(1); } to { opacity: 0; transform: translate(-50%, -48%) scale(0.95); } }
@media (prefers-reduced-motion: reduce) {
    .modal-mask, .modal-box { animation-duration: 1ms !important; }
}

/* ---------------- 沉浸阅读（A4 纸张模式） ---------------- */
.reading-exit { display: none; }
/* ============================================================
   沉浸阅读模式（A4 容器 + 浮动目录）
   - 整个页面变成一个垂直居中的 A4 卡片容器
   - 卡片本身保持 1:√2 比例
   - 超出 A4 的内容在卡片内滚动
   - 左侧悬浮显示目录卡片
   ============================================================ */
body.reading-mode { background: var(--paper-bg); }
body.reading-mode .sidebar,
body.reading-mode .topbar,
body.reading-mode .page-head { display: none; }
/* 沉浸主区域：占满视口，flex 居中 A4 */
body.reading-mode > .layout,
body.reading-mode > main,
body.reading-mode main {
    margin-left: 0 !important;
    padding: 0 !important;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--paper-bg);
    width: 100%;
}
/* 沉浸模式：让 doc-content 撑出 grid 容器限制（不依赖父级 grid） */
body.reading-mode .doc-edit-layout,
body.reading-mode .kb-entry-layout { display: contents; }
/* A4 容器：固定 1:√2 比例 —— 哪怕一行字也保持 A4 形状
   高度 = 宽度 × 1.4142，超出 A4 的内容在卡片内滚动 */
body.reading-mode .doc-content,
body.reading-mode .reading-stage {
    width: min(92vw, 720px);
    aspect-ratio: 1 / 1.4142;  /* A4 210:297 */
    background: var(--paper);
    border: 1px solid var(--paper-border);
    border-radius: 4px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.09);
    padding: 56px 64px;
    overflow-y: auto;
    overflow-x: hidden;
    position: relative;
    box-sizing: border-box;
}
/* A4 太高时（短屏）整体缩小 —— 仍然严格保持 1:√2 */
@media (max-height: 700px) {
    body.reading-mode .doc-content {
        width: min(70vw, 480px);
        padding: 32px 40px;
    }
}
@media (max-width: 700px) {
    body.reading-mode .doc-content { width: 96vw; padding: 24px 20px; }
}
/* 沉浸模式下的章节标题 */
body.reading-mode .doc-chapter-title {
    font-size: 24px; margin-bottom: 28px;
    padding-bottom: 16px; border-bottom: 1px solid var(--border);
}
body.reading-mode .markdown-body { font-size: 15px; line-height: 1.9; }
/* 沉浸模式下的浮动目录卡片（左侧 fixed） */
body.reading-mode #kb-auto-toc-aside,
body.reading-mode .kb-auto-toc-aside,
body.reading-mode .doc-tree {
    position: fixed !important;
    left: 24px !important;
    top: 50% !important;
    transform: translateY(-50%) !important;
    width: 240px;
    max-height: 80vh;
    overflow-y: auto;
    z-index: 5;
    background: rgba(255, 255, 255, 0.96) !important;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 16px;
    margin: 0;
}
/* 沉浸退出按钮（右上角） */
body.reading-mode .reading-exit {
    display: inline-flex;
    position: fixed;
    top: 16px; right: 16px;
    z-index: 950;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(8px);
    box-shadow: var(--shadow-md);
}
/* 沉浸模式隐藏其他卡片：标签行 / 危险操作 / 页头内的按钮等 */
body.reading-mode .kb-tag-row,
body.reading-mode .danger-card,
body.reading-mode .doc-edit-toolbar { display: none !important; }
/* 视口太窄时收起目录 */
@media (max-width: 1100px) {
    body.reading-mode #kb-auto-toc-aside,
    body.reading-mode .kb-auto-toc-aside,
    body.reading-mode .doc-tree { display: none !important; }
}
/* ============================================================
   自动目录（H1-H6 解析）—— 通用样式（沉浸模式不另设）
   ============================================================ */

/* 沉浸模式下，KB 阅读页的标签 chips 与危险操作卡片都不应出现 */
body.reading-mode .kb-tag-row,
body.reading-mode .card.danger-card { display: none; }

/* KB 阅读沉浸：A4 纸张模式微调（KB 没有左侧章节树，所以铺满更纯净） */
body.reading-mode .doc-content {
    max-width: 820px; margin: 0 auto; background: #fff;
    border: 1px solid #E0E0E0; border-radius: 4px;
    padding: 72px 76px; min-height: 100vh;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.09);
}

/* ---------------- 编辑器沉浸全屏 ---------------- */
body.editor-fullscreen { overflow: hidden; }
body.editor-fullscreen .doc-edit-main {
    position: fixed; inset: 10px; z-index: 800; margin: 0;
    box-shadow: var(--shadow-lg); background: var(--surface);
}
body.editor-fullscreen .doc-edit-tree,
body.editor-fullscreen .page-head { display: none; }
body.editor-fullscreen #editor-md { height: calc(100vh - 110px) !important; }

/* KB 编辑全屏：再隐藏元数据行，只留工具栏 + 编辑器 */
body.kb-edit-fullscreen .doc-edit-toolbar .kb-meta { display: none; }
body.kb-edit-fullscreen .doc-edit-toolbar { margin-bottom: 8px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }

/* ---------------- 文档列表：筛选与归档折叠 ---------------- */
.archived-group { margin-top: 8px; }
.archived-group > summary {
    cursor: pointer; user-select: none; color: var(--t2); font-size: 13px;
    padding: 10px 14px; border: 1px dashed var(--border); border-radius: var(--r);
    display: flex; align-items: center; gap: 8px;
}
.archived-group > summary:hover { border-color: var(--border-hover); color: var(--t1); }
.archived-group[open] > summary { border-style: solid; margin-bottom: 12px; }
.archived-group > summary svg { width: 14px; height: 14px; }

/* ---------------- 文档系统 ---------------- */
.doc-layout { display: grid; grid-template-columns: 260px 1fr; gap: 16px; align-items: start; }
.doc-edit-layout { display: grid; grid-template-columns: 280px 1fr; gap: 16px; align-items: stretch; }

.doc-tree { padding: 16px; position: sticky; top: 80px; }
.doc-tree .card-title { margin-bottom: 10px; }
.doc-tree-item { display: flex; align-items: center; justify-content: space-between; gap: 6px;
                 padding: 7px 10px; border-radius: 6px; font-size: 13px; }
.doc-tree-item + .doc-tree-item { margin-top: 2px; }
.doc-tree-item a { color: var(--t1); text-decoration: none; }
.doc-tree-item:hover { background: var(--surface-hover); }
.doc-tree-item.active { background: var(--primary-light); }
.doc-tree-item.active a { color: var(--primary); font-weight: 500; }

.doc-edit-tree .t-acts { display: none; gap: 6px; flex: none; }
.doc-edit-tree .doc-tree-item:hover .t-acts { display: inline-flex; }
.doc-edit-tree .t-btn { width: 14px; height: 14px; cursor: pointer; color: var(--t2); }
.doc-edit-tree .t-btn.t-danger { color: var(--red-t); }
.doc-edit-tree .t-btn:hover { color: var(--primary); }
.doc-edit-tree .t-open { cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ================================================================
   树形拖拽（通用：文档章节 / KB 分类）
   ================================================================ */
.tree-drag { list-style: none; margin: 0; padding: 0; }
.tree-drag ul { list-style: none; margin: 0; padding: 0 0 0 20px; }
/* 子 ul 必须在 li 内独立成行（flex 父容器下强制换行）。
   只对"含子 ul 的 li"启用 wrap，避免 actions 误换行。 */
.tree-node:has(> ul) { flex-wrap: wrap; }
.tree-node > ul { flex-basis: 100%; width: 100%; min-width: 0; }
.tree-drag > li { margin: 0; }
.tree-node { display: flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: 6px; font-size: 13px; transition: background 120ms var(--ease); }
.tree-node:hover { background: var(--surface-hover); }
.tree-node.dragging { opacity: 0.5; background: var(--primary-light); }
.tree-node .drag-handle { flex: none; width: 18px; height: 18px; cursor: grab; display: flex; align-items: center; justify-content: center; color: var(--t2); }
.tree-node .drag-handle svg { width: 14px !important; height: 14px !important; }
.tree-node .drag-handle:hover { color: var(--primary); }
.tree-node.dragging .drag-handle { cursor: grabbing; }
.tree-node .node-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tree-node .node-title a { color: var(--t1); text-decoration: none; }
.tree-node .node-title a:hover { color: var(--primary); }
.tree-node .node-actions { display: none; gap: 2px; flex: none; }
.tree-node:hover .node-actions { display: inline-flex; }
.tree-node .node-action { width: 22px; height: 22px; display: flex; align-items: center; justify-content: center; border-radius: 4px; color: var(--t2); cursor: pointer; }
.tree-node .node-action svg { width: 14px !important; height: 14px !important; }
/* Lucide 把 <i class="node-action"> 替换成 <svg ... class="node-action" width=24 height=24>，
   SVG 自身就是 .node-action（没有外层 22x22 容器），把 SVG 拉到 14x14 + padding 撑出 22x22 点击区 */
.tree-node svg.node-action {
    width: 14px !important; height: 14px !important;
    padding: 4px;
    box-sizing: content-box;
}
.tree-node .node-action:hover { background: var(--surface-hover); color: var(--primary); }
.tree-node .node-action.t-danger:hover { color: var(--red-t); }
.tree-node .node-depth { flex: none; width: 16px; }
.tree-node .node-folder { width: 14px !important; height: 14px !important; }

.tree-node.collapsed > ul { display: none; }
.tree-node .toggle-btn {
    flex: none;
    width: 20px; height: 20px;
    display: flex; align-items: center; justify-content: center;
    color: var(--t2);
    cursor: pointer;
    border-radius: 4px;
    background: transparent;
    border: none;
    padding: 0;
    transition: transform 120ms var(--ease), color 120ms var(--ease);
}
.tree-node .toggle-btn svg { width: 14px !important; height: 14px !important; transform-origin: center; }
.tree-node .toggle-btn:hover { background: var(--surface-hover); color: var(--primary); }
/* 展开状态：箭头向下旋转 90°（向下）；折叠：向右 */
.tree-node:not(.collapsed) > .toggle-btn svg { transform: rotate(90deg); }
.tree-node.collapsed > .toggle-btn svg { transform: rotate(0deg); }

/* KB 分类树特有样式（复用 tree-drag，仅额外配色） */
.tree-node .node-title .badge { font-size: 10px; padding: 1px 5px; margin-left: 6px; }

/* KB 侧栏统一：让分类树节点与顶部"全部" nav-item 高度/内边距一致 */
.kb-category-tree .tree-node {
    position: relative;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
    margin: 1px 0;
    border-radius: var(--r);
    color: var(--t1);
    font-weight: 500;
    font-size: 13px;
    line-height: 1.4;
}
/* 根级节点：与"全部"对齐（左侧预留一个图标的宽度，让 folder 与"全部"的 layers 图标对齐） */
.kb-category-tree > li.tree-node {
    padding-left: 10px;
}
.kb-category-tree > li.tree-node > .drag-handle { display: none; }
.kb-category-tree .tree-node:hover { background: var(--surface-hover); }
.kb-category-tree .tree-node.dragging { opacity: 0.6; background: var(--primary-light); }
.kb-category-tree .tree-node .drag-handle {
    opacity: 0;
    transition: opacity 120ms var(--ease);
    margin-right: -4px;
}
.kb-category-tree .tree-node:hover .drag-handle { opacity: 0.55; }
.kb-category-tree .tree-node .drag-handle:hover { opacity: 1; color: var(--primary); }
.kb-category-tree .tree-node .node-icon {
    flex: none;
    width: 16px; height: 16px;
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer;
    color: var(--t3);
    border-radius: 3px;
    transition: color 120ms var(--ease), background 120ms var(--ease);
}
.kb-category-tree .tree-node .node-icon:hover { color: var(--primary); background: var(--surface-hover); }
.kb-category-tree .tree-node .node-folder { width: 14px !important; height: 14px !important; }
.kb-category-tree .tree-node .node-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-category-tree .tree-node .node-title a { color: var(--t1); text-decoration: none; }
.kb-category-tree .tree-node .node-title a:hover,
.kb-category-tree .tree-node .node-title a.active { color: var(--primary); }
.kb-category-tree .tree-node .node-count { flex: none; font-size: 10px; padding: 1px 6px; margin-left: auto; }
/* 默认隐藏；只有悬停"包含自身"的 li 才显示，避免父级 hover 连带子级一起亮 */
.kb-category-tree .tree-node .node-actions { display: none; gap: 2px; flex: none; }
/* 用 :has() 让 hover 范围限定到指针真正所在的 li（hover 在 node-title / node-icon / drag-handle 都算） */
.kb-category-tree .tree-node:has(> .node-title:hover) > .node-actions,
.kb-category-tree .tree-node:has(> .node-icon:hover) > .node-actions,
.kb-category-tree .tree-node:has(> .drag-handle:hover) > .node-actions,
.kb-category-tree .tree-node:has(> .node-actions:hover) > .node-actions { display: inline-flex; }
.kb-category-tree .tree-node .node-action {
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 4px; color: var(--t2); cursor: pointer;
    flex: none;
}
/* Lucide 把 <i class="node-action"> 直接替换成 <svg ... class="node-action" width=24 height=24>，
   元素自身就是 SVG（没有外层 22x22 容器），所以直接把 SVG 拉到 14x14 + padding 撑出 22x22 点击区 */
.kb-category-tree .tree-node svg.node-action {
    width: 14px !important; height: 14px !important;
    padding: 4px;
    box-sizing: content-box;
}
.kb-category-tree .tree-node .node-action:hover { background: var(--surface-hover); color: var(--primary); }
.kb-category-tree .tree-node .node-action.t-danger:hover { color: var(--red-t); }
/* 子 ul 占满一行（flex 父容器下不与图标横排） */
.kb-category-tree .tree-node > ul { flex-basis: 100%; width: 100%; min-width: 0; margin: 0; padding: 0 0 0 16px; list-style: none; }
.kb-category-tree .tree-node.collapsed > ul { display: none; }

.doc-edit-main { display: flex; flex-direction: column; overflow: hidden; }
.doc-edit-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
#editor-md { flex: 1; min-height: 480px; height: calc(100vh - 240px); }
#editor-md .editormd { height: 100%; border-radius: var(--r); border-color: var(--border); }

/* 阅读态 markdown 渲染 */
.markdown-body { font-size: 14.5px; line-height: 1.8; word-break: break-word; }
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4 { margin: 1.2em 0 .5em; letter-spacing: -0.02em; }
.markdown-body h1 { font-size: 22px; border-bottom: 1px solid var(--border); padding-bottom: .3em; }
.markdown-body h2 { font-size: 19px; } .markdown-body h3 { font-size: 16px; }
.markdown-body p { margin: .6em 0; }
.markdown-body ul, .markdown-body ol { padding-left: 1.6em; margin: .6em 0; }
.markdown-body code { background: var(--primary-bg); border-radius: 4px; padding: 2px 6px; font-size: .92em;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.markdown-body pre { background: #2d2d2d; color: #f8f8f2; padding: 14px 16px; border-radius: var(--r);
    overflow-x: auto; margin: .8em 0; }
.markdown-body pre code { background: none; color: inherit; padding: 0; }
.markdown-body blockquote { border-left: 3px solid var(--primary); background: var(--primary-bg);
    margin: .8em 0; padding: 8px 16px; border-radius: 0 var(--r) var(--r) 0; color: var(--t2); }
.markdown-body table { border-collapse: collapse; margin: .8em 0; width: 100%; }
.markdown-body th, .markdown-body td { border: 1px solid var(--border); padding: 6px 12px; }
.markdown-body img { max-width: 100%; border-radius: var(--r); }
.markdown-body a { color: var(--primary); }

/* 版本对比 */
.diff-out pre { margin: 0; padding: 8px 14px; font-size: 12.5px; line-height: 1.6; white-space: pre-wrap;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.diff-out .d-add { background: var(--green-bg); color: var(--green-t); }
.diff-out .d-del { background: var(--red-bg); color: var(--red-t); text-decoration: line-through; }
.diff-out .d-ctx { background: var(--surface); color: var(--t2); }

/* ================================================================
   滚动条：弱化自定义
   ================================================================ */
* { scrollbar-width: thin; scrollbar-color: #c8c8c8 transparent; }
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: #c8c8c8; border-radius: 3px; }
*::-webkit-scrollbar-thumb:hover { background: #aaa; }

/* 表格横向滚动容器 */
.table-wrap { scrollbar-width: thin; }

@media (max-width: 1024px) {
    .doc-layout, .doc-edit-layout { grid-template-columns: 1fr; }
    .doc-tree { position: static; }
}

/* ================================================================
   M3 新增组件：项目 / 任务 / 知识库 / 通知
   ================================================================ */

/* ---------------- nav-tabs / pill ---------------- */
.nav-tabs {
    display: flex; gap: 4px; padding: 4px;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r); margin-bottom: 16px; width: fit-content;
}
.nav-tabs a {
    padding: 6px 14px; border-radius: 6px; color: var(--t2);
    font-size: 13.5px; font-weight: 500; text-decoration: none;
    transition: all 150ms var(--ease);
}
.nav-tabs a:hover { color: var(--t1); background: var(--surface-hover); text-decoration: none; }
.nav-tabs a.active { background: var(--primary); color: #fff; }

/* ---------------- 优先级色条（任务卡片左侧） ---------------- */
.priority-bar { display: inline-block; width: 4px; height: 14px; border-radius: 2px; margin-right: 6px; vertical-align: middle; }
.priority-low    .priority-bar, .priority-low    { color: var(--t2); }
.priority-mid    .priority-bar, .priority-mid    { color: var(--primary); }
.priority-high   .priority-bar, .priority-high   { color: var(--orange-t); }
.priority-urgent .priority-bar, .priority-urgent { color: var(--red-t); }
.priority-low    .priority-bar { background: var(--t3); }
.priority-mid    .priority-bar { background: var(--primary); }
.priority-high   .priority-bar { background: var(--orange); }
.priority-urgent .priority-bar { background: var(--red); }

/* ---------------- 任务看板 ---------------- */
.kanban {
    display: grid; grid-template-columns: repeat(4, minmax(240px, 1fr));
    gap: 12px; align-items: start;
}
.kanban-col {
    background: var(--bg); border: 1px solid var(--border);
    border-radius: var(--r-lg); padding: 12px; min-height: 320px;
}
.kanban-col-head {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--border);
    font-weight: 600; font-size: 13.5px;
}
.kanban-col-head .count { color: var(--t2); font-size: 12px; font-weight: 400; }
.kanban-list { display: flex; flex-direction: column; gap: 8px; min-height: 80px; }
.kanban-empty { color: var(--t3); font-size: 12px; text-align: center; padding: 20px 0; }
.task-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r); padding: 12px; cursor: grab;
    transition: border-color 150ms var(--ease), box-shadow 150ms var(--ease);
}
.task-card:hover { border-color: var(--border-hover); box-shadow: var(--shadow-md); }
.task-card:active { cursor: grabbing; }
.task-card.sortable-ghost { opacity: 0.4; border-style: dashed; }
.task-card.sortable-chosen { box-shadow: var(--shadow-lg); }
.task-card .tc-title { font-size: 13.5px; font-weight: 500; color: var(--t1); margin-bottom: 6px; line-height: 1.4; }
.task-card .tc-title a { color: var(--t1); text-decoration: none; }
.task-card .tc-title a:hover { color: var(--primary); }
.task-card .tc-meta {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 11.5px; color: var(--t2); gap: 6px;
}
.task-card .tc-meta-left { display: flex; align-items: center; gap: 6px; min-width: 0; }
.task-card .tc-meta-right { display: flex; align-items: center; gap: 4px; flex: none; }
.task-card .tc-tag {
    display: inline-block; padding: 1px 6px; border-radius: 4px;
    background: var(--primary-bg); color: var(--primary); font-size: 11px;
    max-width: 80px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.task-card .tc-due { color: var(--t2); white-space: nowrap; }
.task-card .tc-due.overdue { color: var(--red-t); font-weight: 500; }
.task-card .tc-due.today { color: var(--orange-t); font-weight: 500; }
.task-card .avatar { vertical-align: middle; }

/* ---------------- 项目卡片网格 ---------------- */
.project-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px;
}
.project-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-lg); padding: 18px;
    transition: border-color 150ms var(--ease), transform 150ms var(--ease);
}
.project-card:hover { border-color: var(--border-hover); }
.project-card .pc-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.project-card .pc-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12px; color: var(--t3); }
.project-card .pc-title { font-size: 15px; font-weight: 600; margin-bottom: 6px; color: var(--t1); }
.project-card .pc-title a { color: var(--t1); text-decoration: none; }
.project-card .pc-title a:hover { color: var(--primary); }
.project-card .pc-desc { font-size: 13px; color: var(--t2); line-height: 1.6; margin-bottom: 12px;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.project-card .pc-meta { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--t3); }

/* ---------------- 知识库卡片网格 ---------------- */
.kb-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 16px;
}
.kb-card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-lg); padding: 18px;
    transition: border-color 150ms var(--ease);
}
.kb-card:hover { border-color: var(--border-hover); }
.kb-card .kb-title { font-size: 15px; font-weight: 600; margin-bottom: 6px; }
.kb-card .kb-title a { color: var(--t1); text-decoration: none; }
.kb-card .kb-title a:hover { color: var(--primary); }
.kb-card .kb-summary { font-size: 13px; color: var(--t2); line-height: 1.6; margin-bottom: 12px;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.kb-card .kb-meta { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 11.5px; color: var(--t3); }
.kb-card .kb-tag {
    display: inline-block; padding: 1px 7px; border-radius: 4px;
    background: var(--primary-bg); color: var(--primary); font-size: 11px;
}

/* ---------------- 通知中心 ---------------- */
.bell-wrap { position: relative; }
.bell-btn {
    position: relative; width: 36px; height: 36px;
    border: 1px solid var(--border); background: var(--surface);
    border-radius: var(--r); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--t1); transition: border-color 150ms var(--ease);
}
.bell-btn:hover { border-color: var(--border-hover); }
.bell-btn svg { width: 14px; height: 14px; }
.bell-dot {
    position: absolute; top: -6px; right: -6px; z-index: 2;
    min-width: 16px; height: 16px; padding: 0 4px;
    background: var(--red); color: #fff; border-radius: 8px;
    font-size: 10px; font-weight: 600; line-height: 16px;
    text-align: center; border: 2px solid var(--bg);
}
.notif-dropdown {
    position: absolute; top: calc(100% + 8px); right: 0;
    width: 360px; max-height: 480px; overflow-y: auto;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
    z-index: 200;
}
.notif-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 12px 14px; border-bottom: 1px solid var(--border);
    font-weight: 600; font-size: 13.5px;
}
.notif-list { max-height: 380px; overflow-y: auto; }
.notif-item {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 10px 14px; border-bottom: 1px solid var(--border);
    color: var(--t1); text-decoration: none; transition: background 150ms var(--ease);
}
.notif-item:hover { background: var(--surface-hover); text-decoration: none; }
.notif-item.unread { background: var(--primary-bg); }
.notif-item .ni-body { flex: 1; min-width: 0; }
.notif-item .ni-title { font-size: 13px; font-weight: 500; margin-bottom: 4px; }
.notif-item .ni-meta { font-size: 11px; color: var(--t3); }
.notif-item .ni-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--primary); margin-right: 6px; vertical-align: middle; }
.notif-foot {
    display: block; padding: 10px 14px; text-align: center;
    border-top: 1px solid var(--border); color: var(--primary);
    font-size: 12.5px;
}

/* 通知 type 图标（铃铛 dropdown + 中心页共用） */
.ni-icon {
    flex: none; width: 28px; height: 28px; border-radius: 6px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--surface-hover); color: var(--t2);
    margin-top: 2px;
}
.ni-icon svg { width: 14px; height: 14px; }
.ni-icon.ni-task     { background: var(--primary-bg); color: var(--primary); }
.ni-icon.ni-warn     { background: #FFF3E0;            color: #E07B00; }
.ni-icon.ni-project  { background: #E8F5E9;            color: #2E7D32; }
.ni-icon.ni-doc      { background: #E3F2FD;            color: #1565C0; }
.ni-icon.ni-announce { background: #FCE4EC;            color: #C2185B; }
.ni-icon.ni-meta     { background: #F5F5F5;            color: #616161; }
@media (max-width: 480px) {
    .notif-dropdown { width: calc(100vw - 24px); right: -8px; }
}

/* ---------------- Toast 非阻塞提示 ---------------- */
.toast-stack {
    position: fixed; bottom: 24px; right: 24px;
    display: flex; flex-direction: column-reverse; gap: 10px;
    z-index: 950; pointer-events: none;
}
.toast {
    pointer-events: auto;
    min-width: 200px; max-width: 360px;
    padding: 10px 14px; border-radius: var(--r);
    background: var(--surface); border: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
    font-size: 13.5px; color: var(--t1);
    opacity: 0; transform: translateX(20px);
    animation: toastIn 200ms var(--ease) forwards;
}
.toast.toast-success { border-left: 3px solid var(--green); }
.toast.toast-error   { border-left: 3px solid var(--red); }
.toast.toast-info    { border-left: 3px solid var(--primary); }
.toast.closing { animation: toastOut 200ms var(--ease) forwards; }
@keyframes toastIn  { to { opacity: 1; transform: translateX(0); } }
@keyframes toastOut { to { opacity: 0; transform: translateX(20px); } }

/* ---------------- 宽模态（项目编辑/任务详情） ---------------- */
.modal-box.wide { width: min(92vw, 720px); }
.modal-box.large { width: min(92vw, 900px); }

/* ============================================================
   全站移动端适配（2026-08-29）
   壳层抽屉/遮罩/汉堡见上方 768px 块；此处补模块层。
   断点：768px（手机/平板分界）、480px（小屏收紧）。
   ============================================================ */

/* —— 从内联样式迁入的响应式栅格（桌面定义）—— */
.kb-two-col { display: grid; grid-template-columns: 240px 1fr; gap: 16px; align-items: start; }
.side-main-grid { display: grid; grid-template-columns: 1fr 300px; gap: 16px; align-items: start; }

@media (max-width: 768px) {
    /* 壳层细节 */
    body.sidebar-open { overflow: hidden; }            /* 抽屉打开时锁定背景滚动 */
    .sidebar { width: min(82vw, 280px); }
    .topbar { padding: 0 12px; }
    .topbar-row { gap: 8px; }
    .content { padding: 76px 12px 28px; }
    .page-head h1 { font-size: 18px; }

    /* 输入 16px：防 iOS Safari 聚焦时自动放大页面 */
    .input, select.input, textarea.input, .topbar-search input,
    input[type="text"], input[type="password"], input[type="email"], input[type="search"],
    input[type="number"], input[type="date"], input[type="datetime-local"], select, textarea {
        font-size: 16px !important;
    }

    /* 表格密度压缩（容器本身已 overflow-x:auto） */
    .table th, .table td { padding: 9px 8px; }

    /* 卡片与表单 */
    .card { padding: 16px; }
    .form-row { gap: 10px; }

    /* 任务看板：固定 4 列栅格 → 横向滑动列（触摸滚动 + 吸附） */
    .kanban {
        display: flex; overflow-x: auto; gap: 10px;
        margin: 0 -12px; padding: 0 12px 8px;
        scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
    }
    .kanban-col { flex: 0 0 78vw; max-width: 320px; min-height: 240px; scroll-snap-align: start; }

    /* 双栏页单列堆叠（KB 列表 / KB 条目 / 任务详情） */
    .kb-two-col, .side-main-grid, .kb-entry-layout { grid-template-columns: 1fr !important; }

    /* Markdown 编辑器：窄屏隐藏预览栏，编辑区占满 */
    .editormd .editormd-preview { display: none !important; }
    .editormd .CodeMirror { width: 100% !important; }
    .doc-edit-toolbar { flex-wrap: wrap; gap: 8px; }
    .doc-edit-toolbar .kb-meta { flex-wrap: wrap; gap: 8px; }
    .doc-edit-toolbar .kb-meta .input { min-width: 0; }

    /* 顶栏收紧：用户只留头像，铃铛/退出保持可点 */
    .topbar-user > div { display: none; }
    .topbar-right { gap: 10px; }

    /* 分页/操作按钮触控尺寸 */
    .pager .btn { padding: 8px 12px; }
    .tdw-actions .btn { padding: 6px 10px; font-size: 12px; }

    /* 评论区操作换行防溢出 */
    .cmt-actions { flex-wrap: wrap; }

    /* Toast 贴底居中，避开手势条 */
    .toast-stack { left: 12px; right: 12px; bottom: 16px; }
    .toast { max-width: none; width: 100%; }
}

@media (max-width: 480px) {
    .stat-grid { gap: 10px; }
    .stat-card { padding: 12px; }
    .stat-card .s-value { font-size: 20px; }
    .topbar-banner { padding: 4px 10px; font-size: 11px; }
    .project-grid, .kb-grid, .contact-grid { gap: 10px; }
    .project-card, .kb-card { padding: 14px; }
    .modal-box { width: calc(100vw - 16px); max-height: 92dvh; overflow-y: auto; padding: 16px; }
    .pc-meta, .cmt-actions { gap: 6px; }
}

/* ---------------- 团队主题色色板（团队设置页） ---------------- */
.theme-swatch {
    width: 30px; height: 30px; border-radius: 999px;
    border: 2px solid #fff; outline: 1px solid var(--border);
    cursor: pointer; padding: 0; flex: none;
    transition: transform 150ms var(--ease), outline-color 150ms var(--ease);
}
.theme-swatch:hover { transform: scale(1.12); }
.theme-swatch.current { outline: 2px solid var(--primary); outline-offset: 2px; }

/* ---------------- 侧边栏团队切换器（多团队） ---------------- */
.team-switch { padding: 10px 12px 4px; position: relative; }
.team-switch-btn {
    width: 100%; display: flex; align-items: center; gap: 10px;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
    padding: 8px 10px; cursor: pointer; text-align: left; font-family: inherit;
    transition: border-color 150ms var(--ease), background 150ms var(--ease);
}
.team-switch-btn:hover { border-color: var(--border-hover); }
.team-switch-btn.open { border-color: var(--primary); }
.ts-avatar {
    width: 30px; height: 30px; flex: none; border-radius: 8px;
    background: var(--primary-light); color: var(--primary);
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 14px;
}
.team-switch .ts-body { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.ts-name { font-weight: 600; font-size: 13px; color: var(--t1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.team-switch-btn small { color: var(--t3); font-size: 11px; }
.ts-caret { width: 14px; height: 14px; flex: none; color: var(--t3); transition: transform 150ms var(--ease); }
.team-switch-btn.open .ts-caret { transform: rotate(180deg); }
.team-switch-panel {
    position: absolute; left: 12px; right: 12px; top: calc(100% - 2px); z-index: 60;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg); padding: 6px; max-height: 70vh; overflow-y: auto;
    animation: tsPopIn 180ms var(--ease);
}
/* 注意：不能用 modalPopIn（终帧含 translate(-50%,-50%) 且 forwards，会把面板永久平移出边界） */
@keyframes tsPopIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.ts-head { font-size: 11px; color: var(--t3); padding: 6px 10px 4px; }
.ts-item {
    width: 100%; display: flex; align-items: center; gap: 10px;
    background: none; border: 0; border-radius: var(--r); padding: 8px 10px;
    cursor: pointer; text-align: left; font-family: inherit; text-decoration: none;
    transition: background 150ms var(--ease);
}
.ts-item:hover { background: var(--surface-hover); text-decoration: none; }
.ts-item .ts-body { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.35; }
.ts-item b { font-size: 13px; color: var(--t1); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-item small { color: var(--t3); font-size: 11px; }
.ts-item .ts-check { width: 14px; height: 14px; flex: none; color: var(--primary); opacity: 0; }
.ts-item.current { background: var(--primary-light); }
.ts-item.current .ts-check { opacity: 1; }
.ts-item .ts-icon { width: 16px; height: 16px; flex: none; color: var(--t2); }
.ts-divider { height: 1px; background: var(--border); margin: 6px 4px; }
.ts-empty { color: var(--t3); font-size: 12px; padding: 10px 12px; }

/* 团队选择页卡片（button 元素重置） */
.select-team-card {
    appearance: none; -webkit-appearance: none; display: block;
    transition: border-color 150ms var(--ease), transform 150ms var(--ease);
}
.select-team-card:hover { border-color: var(--primary); transform: translateY(-2px); }

/* 团队切换器/选择页：真实 logo 填充（无 logo 回退首字母） */
.ts-logo { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }

/* ============================================================
   深色模式（2026-08-29）—— html[data-theme="dark"]，PLAN §8 配色
   主色不变；顶栏切换 + localStorage 记忆（tdw_theme）。
   ============================================================ */
[data-theme="dark"] {
    --bg: #17181C;
    --surface: #1F2025;
    --surface-hover: #262830;
    --border: #2E3038;
    --border-hover: #3C3F4A;
    --t1: #E8E9ED;
    --t2: #A6ADB8;
    --t3: #6E7681;
    --icon: #C9CDD4;
    --topbar-bg: rgba(23, 24, 28, 0.82);
    --paper: #23242B;
    --paper-border: #2E3038;
    --paper-bg: #131418;
    /* 主色衍生（团队主题色的 dark 适配由 ThemeService 双规则集输出覆盖） */
    --primary-light: #1B2A4A;
    --primary-bg: #161E31;
    --primary-a08: rgba(91, 148, 246, 0.10);
    --primary-a12: rgba(91, 148, 246, 0.16);
    --primary-a14: rgba(91, 148, 246, 0.18);
    --primary-a20: rgba(91, 148, 246, 0.28);
    --green-bg: #122B1E;  --green-t: #4FC79A;
    --red-bg: #38191D;    --red-t: #F0959E;
    --orange-bg: #382A12; --orange-t: #E6AB5F;
    --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.55);
    color-scheme: dark;
}

/* 通知图标色板（浅色为粉彩底，深色换暗底亮字） */
[data-theme="dark"] .ni-icon.ni-task     { background: rgba(54, 112, 247, 0.16); color: #7FAAF8; }
[data-theme="dark"] .ni-icon.ni-warn     { background: #382A12; color: #E6AB5F; }
[data-theme="dark"] .ni-icon.ni-project  { background: #122B1E; color: #4FC79A; }
[data-theme="dark"] .ni-icon.ni-doc      { background: #14243A; color: #6FA8F5; }
[data-theme="dark"] .ni-icon.ni-announce { background: #331A26; color: #E385B0; }
[data-theme="dark"] .ni-icon.ni-meta     { background: #26272E; color: #A6ADB8; }

/* 顶栏主题切换按钮（与铃铛同款方形按钮） */
.theme-btn {
    width: 36px; height: 36px; flex: none;
    border: 1px solid var(--border); background: var(--surface);
    border-radius: var(--r); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--t1); transition: border-color 150ms var(--ease);
}
.theme-btn:hover { border-color: var(--border-hover); }
.theme-btn svg { width: 16px; height: 16px; }
/* 亮/暗图标互斥 */
.theme-btn .icon-moon { display: none; }
[data-theme="dark"] .theme-btn .icon-sun { display: none; }
[data-theme="dark"] .theme-btn .icon-moon { display: block; }

/* ============================================================
   骨架屏 + 动效统一（2026-08-29）
   ============================================================ */
@keyframes shimmer {
    0% { background-position: -200px 0; }
    100% { background-position: calc(200px + 100%) 0; }
}
.skeleton {
    background: linear-gradient(90deg, var(--surface-hover) 25%, var(--border) 37%, var(--surface-hover) 63%);
    background-size: 400px 100%;
    animation: shimmer 1.2s ease-in-out infinite;
    border-radius: var(--r);
}
.skeleton-row { display: flex; gap: 10px; align-items: center; padding: 10px 12px; }
.skeleton-row .sk-avatar { width: 28px; height: 28px; border-radius: 999px; flex: none; }
.skeleton-row .sk-lines { flex: 1; }
.skeleton-row .sk-line { height: 10px; margin: 5px 0; border-radius: 5px; }
.skeleton-row .sk-line.w60 { width: 60%; }
.skeleton-row .sk-line.w85 { width: 85%; }

/* 通知下拉开合动效（原 hidden 直切，现在淡入下滑） */
@keyframes dropIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
.notif-dropdown { animation: dropIn 160ms var(--ease); }

@media (prefers-reduced-motion: reduce) {
    .skeleton, .skeleton-row .sk-line, .sk-avatar { animation: none !important; }
}

/* 法律文本页 */
.legal-doc { font-size: 13.5px; color: var(--t1); line-height: 1.9; text-align: left; }
.legal-doc h3 { margin: 18px 0 8px; font-size: 14.5px; color: var(--t1); }
.legal-doc ol { padding-left: 20px; color: var(--t2); }
.legal-doc li { margin-bottom: 8px; }
.legal-doc .ld-meta { color: var(--t3); font-size: 12px; margin-bottom: 16px; }
.auth-card.wide { max-width: 720px; }
