  /* ============ 设计令牌（浅色） ============ */
  :root{
    --bg:#E8F1FB; --surface:#FFFFFF; --surface-2:#E2ECF9; --surface-translucent:rgba(255,255,255,.85);
    --border:#D6E3F4; --border-strong:#B9CBEA;
    --text:#1B2230; --muted:#55657D;
    --primary:#2A5C99; --primary-hover:#234E85; --primary-soft:#D9E8FA; --primary-text:#1C4574; --primary-border:#9FBFE2;
    --success:#2A5C99; --success-soft:#D9E8FA; --success-text:#1C4574;
    /* 状态语言（v120）：色相收敛为单色后，warning 不再等于 --muted（那会让“告警”看起来像“禁用”），
       改为同一主色族的 60% 明度档；warning-text 用正文色保证可读。success 仍与主色同值，
       靠 ✓ 图标 / 实心点 / 常驻文字区分（见文件末尾 v120 段）。 */
    --warning:#6E9CD6; --warning-soft:#E7F1FC; --warning-text:#1B2230;
    --danger:#E11D48; --danger-soft:#FDEBEE; --danger-text:#BE123C; --danger-hover:#BE123C; --danger-border:#F7C1C1;
    --actionbar-bg:#1B2230; --actionbar-text:#FFFFFF; --actionbar-btn:rgba(255,255,255,.14); --actionbar-btn-hover:rgba(255,255,255,.24);
    --overlay:rgba(23,42,82,.42);
    --switch-off:#BDCCE8; --placeholder:#8A9BBB;
    --skeleton-a:#E8F1FB; --skeleton-b:#DCE9F8;
    /* 文件类型图标 */
    --ic-image:transparent; --ic-image-fg:#2A5C99; --ic-doc:transparent; --ic-doc-fg:#2A5C99;
    --ic-sheet:transparent; --ic-sheet-fg:#2A5C99; --ic-video:transparent; --ic-video-fg:#2A5C99;
    --ic-audio:transparent; --ic-audio-fg:#2A5C99; --ic-zip:transparent; --ic-zip-fg:#2A5C99;
    --ic-folder:transparent; --ic-folder-fg:#2A5C99;
    /* 存储占用分类色（同蓝系深浅阶） */
    --cat-image:#2A5C99; --cat-video:#3F6FAF; --cat-audio:#6390C8; --cat-text:#A6C4E4; --cat-other:#CBDDF0;
    /* 层级 */
    --z-view:5; --z-topbar:20; --z-actionbar:30; --z-tabbar:35; --z-sidebar:40; --z-menu:45; --z-modal:50; --z-overlay:55; --z-download:60; --z-toast:70;
    --z-dock:28; --z-drawer:46;
    --side-w:216px; --side-w-min:64px; --top-h:56px; --view-max:100%;
    --r-lg:16px; --r:12px; --r-sm:8px;
    --shadow-sm:0 1px 2px rgba(31,55,99,.06);
    --shadow:0 4px 16px rgba(31,55,99,.08);
    --shadow-lg:0 16px 48px rgba(31,55,99,.16);
    --vp-bg:#05080F; --vp-surface:#0B1322; --vp-bar:#0E1729; --vp-fg:#C2CBE0; --vp-fg-strong:#fff; --vp-accent:#85B7EB; --vp-ok:#85B7EB; --vp-warn:#F0A6B4; --vp-meta:#7E8DA8;
    --pv-bg:#0B1322; --pv-fg:#A8B4CC;
  }
  /* ============ 深色模式（html[data-theme=dark] 覆盖） ============ */
  [data-theme="dark"]{
    --ic-image:transparent; --ic-image-fg:#A6C4E4; --ic-doc:transparent; --ic-doc-fg:#A6C4E4;
    --ic-sheet:transparent; --ic-sheet-fg:#A6C4E4; --ic-video:transparent; --ic-video-fg:#A6C4E4;
    --ic-audio:transparent; --ic-audio-fg:#A6C4E4; --ic-zip:transparent; --ic-zip-fg:#A6C4E4;
    --ic-folder:transparent; --ic-folder-fg:#A6C4E4;
    --cat-image:#C9DDF4; --cat-video:#A6C4E4; --cat-audio:#6390C8; --cat-text:#96C0E8; --cat-other:#3F6FAF;
    --bg:#0E1526; --surface:#16203A; --surface-2:#1C2840; --surface-translucent:rgba(22,32,58,.85);
    --border:#28334D; --border-strong:#374466;
    --text:#E6EBF5; --muted:#93A1BD;
    --primary:#7FB0E4; --primary-hover:#9CC4ED; --primary-soft:#17273E; --primary-text:#C9DDF4; --primary-border:#2F4E77;
    --success:#7FB0E4; --success-soft:#17273E; --success-text:#C9DDF4;
    --warning:#A9C9EC; --warning-soft:#1B2B42; --warning-text:#E6EBF5;
    --danger:#FB7185; --danger-soft:#341A1F; --danger-text:#FCA5B4; --danger-hover:#F43F5E; --danger-border:#5A2E35;
    --actionbar-bg:#E6EBF5; --actionbar-text:#0E1526; --actionbar-btn:rgba(0,0,0,.10); --actionbar-btn-hover:rgba(0,0,0,.18);
    --overlay:rgba(8,14,30,.6);
    --switch-off:#374466; --placeholder:#74849F;
    --skeleton-a:#1C2840; --skeleton-b:#29395C;
    --shadow-sm:0 1px 2px rgba(0,0,0,.3);
    --shadow:0 4px 16px rgba(0,0,0,.35);
    --shadow-lg:0 16px 48px rgba(0,0,0,.5);
  }
  *{box-sizing:border-box} html,body{height:100%}
  body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"PingFang SC","Microsoft YaHei",sans-serif;
    background:var(--bg);color:var(--text);-webkit-font-smoothing:antialiased;line-height:1.5}
  button{font:inherit;cursor:pointer;border:none} input,select{font:inherit}
  .hidden{display:none!important} .muted{color:var(--muted)}
  /* SVG 图标体系：stroke 继承文字色（暗色自动适配），尺寸随字号 */
  .ic{width:1em;height:1em;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;vertical-align:-0.14em;display:inline-block;flex:none}
  /* 各容器内的图标尺寸适配 */
  .mini .ic{width:15px;height:15px}
  .ficon .ic{width:15px;height:15px}
  .act-ic .ic{width:13px;height:13px}
  .pm-del .ic{width:12px;height:12px}
  .fm-item .ic{width:14px;height:14px;margin-right:2px}
  .side-link .ic{width:16px;height:16px}
  .tab .ic{width:16px;height:16px}
  .pm-cloud .ic{width:11px;height:11px}
  .pm-due .ic,.pm-fstats .ic{width:12px;height:12px}
  .file-menu .ic{width:14px;height:14px}
  .view-err .ic{width:16px;height:16px}
  .up-cancel .ic{width:12px;height:12px}
  .pm-row-t .ic{width:11px;height:11px;vertical-align:-0.1em}

  /* ============ S1 视图框架（侧栏折叠 + 整页视图 + 沉浸预览） ============ */
  .sidebar{transition:width .16s ease}
  body.side-min .sidebar{width:var(--side-w-min)}
  body.side-min .sidebar .sl-txt,body.side-min .sidebar .side-brand-t,body.side-min .sidebar .side-usage-tx{display:none}
  body.side-min .sidebar .side-link{justify-content:center;padding:9px 0}
  body.side-min .sidebar .side-brand{justify-content:center;padding:0 0 14px}
  body.side-min .sidebar .side-usage{text-align:center;padding:10px 4px 2px}
  .view{display:none}
  .view.on{display:block;animation:viewIn .16s ease-out}
  /* 视图化后内容区铺满：强制覆盖旧模态遗留的内联 max-width（admin 520/photo 900 等） */
  .view > .modal-card{max-width:var(--view-max)!important;margin:0 auto;box-shadow:none;border:none;background:transparent;padding:0;max-height:none;overflow:visible;width:100%}
  .view > .modal-card .modal-head{padding:0 2px 14px;border-bottom:1px solid var(--border);margin-bottom:16px}
  .view > .modal-card .modal-head h3{font-size:20px}
  #view-files.container{padding:20px 24px 28px;width:100%} /* width:100% 防止 flex 父级下退化为内容宽度（margin:auto 会取消 stretch） */
  .view:not(.container){padding:20px 24px 28px}
  /* S1 视图（body 直接子级：回收站/管理/照片墙/动态/远程/项目）定位到主区——贴在顶栏下、侧栏右侧，独立滚动。
     修复：此前它们是普通 block，会渲染在 app-view(100vh) 之后的页面下方，切视图后主区一片空白 */
  .view:not(#view-files){position:fixed;left:var(--side-w);right:0;top:var(--top-h);bottom:0;overflow-y:auto;background:var(--bg);z-index:var(--z-view)}
  body.side-min .view:not(#view-files){left:var(--side-w-min)}
  @media(max-width:900px){.view:not(#view-files){left:0;padding:16px 14px calc(24px + 68px)}} /* 底部预留 Tab 栏高度，避免末行被遮挡 */
  @media(max-width:900px){#view-files.container{padding:16px 14px 24px}.view:not(.container){padding:16px 14px 24px}}
  /* 列表视图：固定布局（auto 会被长文件名撑到 700px+ 导致整页横向滚动）；列宽由 CSS 决定，窄屏只保留勾选/名称/操作 */
  #fileList{width:100%;table-layout:fixed}
  #fileList th,#fileList td{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #fileList th:nth-child(1),#fileList td:nth-child(1){width:40px}
  #fileList th:nth-child(3),#fileList td:nth-child(3){width:88px}
  #fileList th:nth-child(4),#fileList td:nth-child(4){width:76px}
  #fileList th:nth-child(5),#fileList td:nth-child(5){width:146px}
  @media(max-width:640px){
    #fileList th:nth-child(1),#fileList td:nth-child(1){width:36px}
    #fileList th:nth-child(3),#fileList td:nth-child(3){display:none} /* 隐藏「大小」 */
    #fileList th:nth-child(4),#fileList td:nth-child(4){display:none} /* 隐藏「权限」 */
    #fileList th:nth-child(5),#fileList td:nth-child(5){width:86px}
    #fileList .ficon{display:none} /* 让出图标宽度给文件名 */
    #fileList .mini{width:24px;height:24px;font-size:12px}
    #fileList .row-acts{gap:2px}
  }
  @keyframes viewIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
  .view-err{display:flex;align-items:center;gap:9px;padding:10px 14px;border-radius:var(--r-sm);background:var(--danger-soft);color:var(--danger-text);font-size:12px;margin-bottom:14px}
  .view-err button{margin-left:auto;padding:4px 11px;font-size:12px;border-radius:6px;border:1px solid var(--danger-border);background:var(--surface);color:var(--danger-text);font-weight:500}
  /* 沉浸全屏预览 */
  .pv-card.pv-full{max-width:100vw;max-height:100vh;border-radius:0;border:none}
  .pv-card.pv-full .pv-body img,.pv-card.pv-full .pv-body video{max-width:calc(100vw - 48px);max-height:calc(100vh - 148px)}
  .pv-card.pv-full .pv-body iframe{width:100%;height:calc(100vh - 128px)}
  .pv-card.pv-full .pv-body pre{width:100%;height:calc(100vh - 128px);max-height:calc(100vh - 128px)}
  .pv-bar .pv-idx{color:var(--text);font-weight:500}
  .pv-card.pv-full .pv-head{transition:opacity .25s}
  .pv-card.pv-full.hid-ui .pv-head,.pv-card.pv-full.hid-ui .pv-bar{opacity:0;pointer-events:none}
  .pv-card.pv-full .pv-body{background:var(--pv-bg)}
  .pv-card.pv-full .pv-body .muted{color:var(--pv-fg)}
  .pv-card.pv-full .pv-body img,.pv-card.pv-full .pv-body video{background:var(--pv-bg)}
  /* 用户菜单 */
  .user-menu{min-width:168px}
  .user-menu .um-head{padding:9px 12px;border-bottom:0.5px solid var(--border);margin-bottom:4px}
  .user-menu .um-name{font-weight:500;font-size:13px;display:block}
  .user-menu .um-role{font-size:11px;color:var(--muted)}
  .btn-primary{padding:9px 15px;border-radius:var(--r-sm);background:var(--primary-soft);color:var(--primary-text);border:1px solid var(--primary-border);font-weight:500;font-size:13px;transition:.18s;display:inline-flex;align-items:center;gap:7px}
  .btn-primary:hover{border-color:var(--primary)} .btn-primary:disabled{opacity:.6;cursor:default}
  /* 主按钮改淡蓝底+蓝字软风格，不再有实心浓蓝的突兀感与对比度问题 */
  .btn-ghost{padding:8px 13px;border-radius:var(--r-sm);background:transparent;color:var(--text);font-weight:500;font-size:13px;border:1px solid var(--border-strong);transition:.18s}
  .btn-ghost:hover{background:var(--surface-2)} .btn-danger{background:transparent;color:var(--danger-text);border:1px solid var(--danger-border)}
  .btn-danger:hover{background:var(--danger-soft);border-color:var(--danger-text)}
  /* 小尺寸按钮统一规格：此前散落 5px10px / 5px12px / 6px12px / 6px14px 四种内联 padding，
     与 .seg.sm / .modal-card.sm 的小规格约定保持一致。放在基线按钮之后以确保覆盖生效。 */
  .btn-sm{padding:5px 12px;font-size:12px;min-height:0;border-radius:var(--r-sm)}

  /* ============ A-P2 应用框架（侧栏 + 顶栏 + 移动端 Tab） ============ */
  .app-view{display:flex;min-height:100vh}
  .sidebar{width:216px;flex:none;position:sticky;top:0;height:100vh;height:100dvh;display:flex;flex-direction:column;background:var(--surface);border-right:1px solid var(--border);padding:18px 12px 12px;z-index:var(--z-sidebar)}
  .side-brand{display:flex;align-items:center;gap:10px;padding:2px 8px 14px;border-bottom:1px solid var(--border);margin-bottom:8px}
  .side-name{font-weight:500;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .side-nav{display:flex;flex-direction:column;gap:2px;flex:1;overflow-y:auto}
  .side-label{font-size:11px;color:var(--muted);letter-spacing:.08em;padding:10px 10px 4px}
  .side-link{display:flex;align-items:center;gap:8px;width:100%;text-align:left;padding:9px 10px;border-radius:var(--r-sm);background:none;color:var(--text);font-size:13px;transition:.15s}
  .side-link:hover{background:var(--surface-2)}
  .side-link.active{background:var(--primary-soft);color:var(--primary-text);font-weight:500}
  .side-usage{padding:12px 10px 10px;border-top:1px solid var(--border);margin-top:auto}
  .side-usage-tx{display:flex;justify-content:space-between;font-size:11px;color:var(--muted);margin-bottom:6px;white-space:nowrap;overflow:hidden}
  .usage-bar{height:5px;border-radius:99px;background:var(--border);overflow:hidden}
  .usage-fill{height:100%;width:0%;border-radius:99px;background:var(--primary);transition:width .3s ease}
  .usage-fill.warn{background:var(--warning)}
  .side-foot{padding:10px 10px 2px;font-size:11px;color:var(--muted)}
  .side-mask{display:none}
  .burger{display:none;padding:8px 10px}
  .main-wrap{flex:1;min-width:0;display:flex;flex-direction:column}
  .tabbar{display:none}

  @media(max-width:900px){
    .sidebar{position:fixed;left:0;top:0;bottom:0;height:100vh;height:100dvh;width:246px;transform:translateX(-105%);transition:transform .22s ease;box-shadow:var(--shadow-lg)}
    body.side-open .sidebar{transform:none}
    .side-mask{display:none;position:fixed;inset:0;background:var(--overlay);z-index:calc(var(--z-sidebar) - 1)}
    body.side-open .side-mask{display:block}
    .burger{display:inline-flex}
    .tabbar{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:var(--z-tabbar);background:var(--surface-translucent);backdrop-filter:blur(10px);border-top:1px solid var(--border);padding:6px 4px calc(6px + env(safe-area-inset-bottom))}
    .tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;background:none;color:var(--muted);font-size:11px;padding:4px 0;border-radius:var(--r-sm)}
    .tab .tab-ic{font-size:18px;line-height:1.2}
    .tab.active{color:var(--primary-text);font-weight:500}
    .container{padding-bottom:96px}
    .actionbar{bottom:76px}
    @media(max-width:400px){.actionbar{gap:6px;padding:9px 10px}.actionbar button{padding:8px 9px;font-size:12px}.actionbar .cnt{padding:0 2px;font-size:12px}}
    .topbar{padding:10px 14px}
    .side-name{display:none}
  }

  /* auth */
  .auth-view{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:24px}
  .auth-card{width:100%;max-width:380px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow);padding:34px 30px 26px;text-align:center}
  .brand-badge{width:58px;height:58px;border-radius:var(--r-lg);background:var(--primary);display:flex;align-items:center;justify-content:center;margin:0 auto 14px}
  .brand-badge.sm{width:34px;height:34px;border-radius:10px;margin:0}
  .auth-card h1{font-size:22px;font-weight:500;margin:0 0 4px} .auth-card .sub{margin:0 0 22px;color:var(--muted);font-size:13px}
  .seg{display:flex;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-sm);padding:4px;margin-bottom:22px}
  .seg button{flex:1;padding:9px 0;border-radius:7px;background:transparent;color:var(--muted);font-weight:500;font-size:14px;transition:.18s;white-space:nowrap}
  .seg button.active{background:var(--surface);color:var(--primary-text);box-shadow:var(--shadow-sm)}
  .seg.sm button{padding:7px 14px;font-size:13px}
  /* 行内分段控件（共享弹窗权限）：不参与 flex 收缩，避免被输入框挤到「文字宽度+零内边距」 */
  .share-form .seg{flex:0 0 auto}
  .field{text-align:left;margin-bottom:14px} .field label{display:block;font-size:12px;font-weight:500;color:var(--muted);margin:0 0 6px 2px}
  .field input{width:100%;padding:12px 13px;border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);transition:border-color .15s,box-shadow .15s;color:var(--text)}
  .field input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
  .field input:focus{outline:none;border-color:var(--primary);background:var(--surface);box-shadow:0 0 0 3px var(--primary-soft)}
  .form-err{color:var(--danger-text);font-size:12px;min-height:16px;margin:2px 2px 10px;text-align:left}
  .hint{margin:16px 0 0;font-size:12px;color:var(--muted)}

  /* topbar */
  .topbar{position:sticky;top:0;z-index:var(--z-topbar);display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px 22px;background:var(--surface-translucent);backdrop-filter:blur(10px);border-bottom:1px solid var(--border)}
  .brand{display:flex;align-items:center;gap:10px;min-width:0}
  .breadcrumb{display:flex;align-items:center;gap:4px;font-size:13px;overflow:hidden;flex:1;min-width:0}
  .crumb{padding:4px 9px;border-radius:7px;background:var(--surface-2);color:var(--text);font-weight:500;white-space:nowrap;max-width:160px;overflow:hidden;text-overflow:ellipsis}
  .crumb:hover{background:var(--primary-soft);color:var(--primary-text)} .crumb.current{background:var(--primary-soft);color:var(--primary-text);cursor:default}
  .crumb-sep{color:var(--muted)}
  .user{display:flex;align-items:center;gap:9px;flex:none}
  .avatar{width:32px;height:32px;border-radius:50%;background:var(--primary-soft);color:var(--primary-text);display:flex;align-items:center;justify-content:center;font-weight:500;font-size:13px}
  .user-btn{display:flex;align-items:center;gap:8px;background:none;border:0;border-radius:99px;padding:3px 10px 3px 3px;cursor:pointer;transition:.15s}
  .user-btn:hover{background:var(--surface-2)}
  .uname{font-size:13px;font-weight:500}
  #themeToggle{width:34px;padding:8px 0;justify-content:center}
  #themeToggle .i-sun{display:none} #themeToggle .i-moon{display:block}
  [data-theme="dark"] #themeToggle .i-sun{display:block} [data-theme="dark"] #themeToggle .i-moon{display:none}

  /* 主内容区铺满侧栏右侧（原 max-width:1040 在 1920 屏左右各留 332px，用户反馈"没满页"） */
  .container{width:100%;padding:22px 18px 90px}
  .toolbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:16px}
  .toolbar .spacer{flex:1}
  .toggle{display:flex;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-sm);padding:3px}
  .toggle button{padding:6px 11px;border-radius:7px;background:transparent;color:var(--muted);font-weight:500;font-size:13px}
  .toggle button.active{background:var(--surface);color:var(--primary-text);box-shadow:var(--shadow-sm)}

  /* upload */
  .upload-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow);padding:18px;margin-bottom:18px}
  .dropzone{border:2px dashed var(--border-strong);border-radius:var(--r);padding:24px 18px;text-align:center;background:var(--surface-2);transition:.18s;cursor:pointer}
  .dropzone:hover{border-color:var(--primary);background:var(--primary-soft)} .dropzone.drag{border-color:var(--primary);background:var(--primary-soft)}
  .dropzone p{margin:4px 0;font-size:14px} .dropzone .link{color:var(--primary-text);font-weight:500}
  /* 传输队列改为右下角浮层：项目页/粘贴上传时也能看到（原先藏在文件视图里） */
  .upload-progress{position:fixed;right:16px;bottom:24px;width:380px;max-width:calc(100vw - 24px);max-height:46vh;overflow:auto;display:flex;flex-direction:column;gap:8px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow-lg);padding:10px 12px;z-index:var(--z-download)}
  @media(max-width:900px){.upload-progress{right:12px;left:12px;width:auto;bottom:76px;max-height:38vh}}
  .up-item{font-size:13px;display:flex;align-items:center;gap:10px}
  .up-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} .up-bar{flex:2;height:6px;border-radius:99px;background:var(--surface-2);overflow:hidden;border:1px solid var(--border)}
  .up-bar i{display:block;height:100%;width:0;background:var(--primary);transition:width .2s}
  .up-state{width:auto;min-width:60px;text-align:right;color:var(--muted);font-size:12px;white-space:nowrap}
  .up-cancel{flex:none;border:none;background:none;color:var(--muted);font-size:13px;padding:2px 5px;border-radius:6px;cursor:pointer;line-height:1}
  .up-cancel:hover{color:var(--danger);background:var(--danger-soft)}
  /* A-P3 传输队列：总进度 + 失败重试 + 手动清空 */
  .up-head{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted);padding-bottom:2px}
  .up-overall{color:var(--primary-text);font-variant-numeric:tabular-nums;white-space:nowrap}
  .up-item.failed .up-bar i{background:var(--danger)}
  .up-item.failed{cursor:pointer}
  .up-item.failed:hover .up-state{color:var(--primary-text)}
  /* A-P3 预览增强（模态内 img/iframe/video/audio/pre） */
  .pv-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);width:100%;max-width:920px;max-height:92vh;display:flex;flex-direction:column;overflow:hidden}
  /* S2 全屏文本编辑器 */
  .editor-card{background:var(--surface);width:100%;height:100vh;height:100dvh;display:flex;flex-direction:column}
  .editor-head{display:flex;align-items:center;gap:10px;padding:10px 18px;border-bottom:1px solid var(--border);background:var(--surface)}
  .editor-name{font-weight:500;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ed-dot{width:9px;height:9px;border-radius:50%;background:var(--muted);flex:none}
  .ed-dot.dirty{background:var(--warning)}
  .ed-dot.saved{background:var(--success)}
  .editor-area{flex:1;width:100%;border:none;outline:none;resize:none;padding:20px 26px;font-family:ui-monospace,SFMono-Regular,Consolas,"Courier New",monospace;font-size:13px;line-height:1.7;background:var(--surface);color:var(--text)}
  .pv-head{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid var(--border)}
  .pv-name{font-weight:500;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pv-body{padding:14px 16px;overflow:auto;display:flex;align-items:center;justify-content:center;min-height:120px}

  /* ============ 历史版本管理弹窗 ============ */
  .vm-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);width:100%;max-width:560px;max-height:88vh;display:flex;flex-direction:column;overflow:hidden;animation:pop .18s ease}
  .vm-head{display:flex;align-items:center;gap:10px;padding:13px 18px;border-bottom:1px solid var(--border)}
  .vm-title{flex:1;min-width:0}
  .vm-fname{font-weight:500;font-size:15px;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .vm-sub{font-size:12px;color:var(--muted)}
  .vm-body{padding:13px 18px;overflow:auto;display:flex;flex-direction:column;gap:4px}
  .vm-foot{display:flex;align-items:center;gap:10px;padding:11px 18px;border-top:1px solid var(--border);background:var(--surface-2);font-size:12px;color:var(--muted)}
  .vm-sec{font-size:11px;font-weight:500;color:var(--muted);letter-spacing:.4px;margin:8px 0 2px}
  .vm-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:var(--r-sm);background:var(--surface)}
  .vm-dot{width:8px;height:8px;border-radius:50%;flex:none}
  .vm-lbl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .vm-size{color:var(--muted);font-size:12px;width:74px;text-align:right;flex:none}
  .vm-ops{display:flex;gap:5px;flex:none}
  .vm-tag{font-size:11px;font-weight:500;padding:2px 8px;border-radius:99px;flex:none;white-space:nowrap}
  .vm-src{font-size:11px;font-weight:500;padding:2px 8px;border-radius:99px;flex:none;white-space:nowrap}
  .vm-note-row{display:flex;gap:8px;align-items:center;padding:10px 16px;border-top:1px solid var(--border)}
  .vm-cur{border-left:3px solid var(--primary);background:var(--primary-soft)}
  .vm-cur .vm-dot{background:var(--primary)} .vm-cur .vm-tag{background:transparent;color:var(--primary-text);border:1px solid var(--primary-border)}
  .vm-bk{border-left:3px solid var(--warning)}
  .vm-bk .vm-dot{border-radius:2px;background:var(--warning)} .vm-bk .vm-tag.delta{background:var(--surface-2);color:var(--muted);border:0.5px solid var(--border)}
  .vm-hl{border-left-color:var(--success);background:var(--success-soft)}
  .vm-hl .vm-dot{background:var(--success)} .vm-hl .vm-tag.new{background:transparent;color:var(--success-text);border:1px solid var(--primary-border)}
  [data-theme="dark"] .vm-hl .vm-tag.new{color:var(--success-text)}
  .vm-notice{display:flex;align-items:center;gap:8px;padding:8px 12px;margin:6px 0 2px;border-radius:var(--r-sm);background:var(--success-soft);color:var(--success-text);font-size:12px}
  .vm-empty{text-align:center;padding:30px 18px 26px}
  .vm-empty-ic{color:var(--muted);margin-bottom:12px}
  .vm-empty-t{font-weight:500;font-size:15px;margin-bottom:6px}
  .vm-empty-d{color:var(--muted);font-size:12px;line-height:1.7;max-width:380px;margin:0 auto 18px}
  @media(max-width:560px){.vm-size{display:none}.vm-tag.delta{display:none}}
  .pv-body img{max-width:100%;max-height:70vh;border-radius:var(--r);object-fit:contain}
  .pv-body iframe{width:100%;height:70vh;border:none;border-radius:var(--r);background:var(--surface-2)}
  .pv-body video{max-width:100%;max-height:70vh;border-radius:var(--r)}
  .pv-body pre{width:100%;max-height:70vh;overflow:auto;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r);padding:12px 14px;font-size:12px;line-height:1.55;white-space:pre-wrap;word-break:break-all;margin:0}
  /* A-P3 照片墙月份分节 */
  .photo-month{grid-column:1/-1;font-size:12px;font-weight:500;color:var(--muted);padding:14px 2px 6px;border-bottom:1px solid var(--border);margin-bottom:4px}
  /* A-P4 照片墙真图懒加载（视口内 fetch blob → objectURL） */
  .ph-box{position:relative;width:100%;height:110px;border-radius:var(--r-sm);background:var(--surface-2);overflow:hidden;display:flex;align-items:center;justify-content:center}
  .ph-ph{color:var(--placeholder);font-size:12px;letter-spacing:.12em}
  .ph-thumb{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .25s}
  .ph-thumb.ok{opacity:1}
  .card-file:hover .ph-thumb.ok{transform:scale(1.04)}
  /* 媒体馆：分类 chips / 视频播放角标 / 文档来源徽标 */
  #photoChips .pch{padding:6px 16px;border-radius:var(--r-sm);border:1px solid var(--border);background:var(--surface-2);color:var(--text);font-size:13px;font-weight:500;cursor:pointer;transition:.15s}
  #photoChips .pch:hover{background:var(--border)}
  #photoChips .pch.active{background:var(--primary-soft);border-color:var(--primary-border);color:var(--primary-text)}
  .ph-play{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}
  .ph-play::before{content:'';width:0;height:0;border-left:14px solid rgba(31,55,99,.55);border-top:9px solid transparent;border-bottom:9px solid transparent}
  .ph-path{display:inline-block;max-width:100%;font-size:11px;color:var(--muted);border:1px solid var(--border);border-radius:99px;padding:1px 8px;margin-top:6px;background:var(--surface-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* 媒体馆列表视图：容器由 grid 切换为纵向列表行 */
  .grid.as-list{display:flex;flex-direction:column;gap:6px}
  .ph-list-row{display:flex;align-items:center;gap:10px;padding:6px 10px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface);transition:.15s}
  .ph-list-row:hover{background:var(--surface-2);border-color:var(--border-strong)}
  .ph-list-ic{position:relative;flex:0 0 auto;width:32px;height:32px;border-radius:8px;overflow:hidden;background:var(--surface-2);display:flex;align-items:center;justify-content:center}
  .ph-list-ic .ph-thumb{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .25s}
  .ph-list-ic .ph-thumb.ok{opacity:1}
  .ph-list-ic .card-ic{width:28px;height:28px;border-radius:7px;font-size:11px;margin:0}
  .ph-list-main{flex:1;min-width:0}
  .ph-list-main .card-name{text-align:left}
  .ph-list-path{display:block;margin-top:1px;font-size:11px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ph-list-side{flex:0 0 auto;font-size:11px;color:var(--muted);white-space:nowrap;text-align:right}

  /* files */
  .files-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg);box-shadow:var(--shadow);padding:16px 16px 8px;min-height:200px}
  .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(176px,1fr));gap:12px;padding:6px}
  @media(max-width:560px){.grid{grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:10px}} /* 375 宽可排 2 列，此前只能 1 列 */
  .card-file{position:relative;border:1px solid var(--border);border-radius:var(--r);padding:14px;background:var(--surface);transition:.15s;cursor:pointer}
  .card-file:hover{background:var(--surface-2);border-color:var(--border-strong)}
  .card-file.sel{border-color:var(--primary);background:var(--primary-soft)}
  .card-file .chk{position:absolute;top:8px;left:8px}
  .chk{width:18px;height:18px;accent-color:var(--primary);cursor:pointer}
  .card-ic{width:46px;height:46px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-weight:500;font-size:11px;margin:6px auto 10px}
  .card-name{font-size:13px;font-weight:500;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .card-meta{text-align:center;font-size:11px;color:var(--muted);margin-top:3px}
  .card-acts{display:flex;justify-content:center;gap:5px;margin-top:9px}
  .mini{width:30px;height:30px;border-radius:8px;background:var(--surface-2);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;color:var(--muted);transition:.15s}
  .mini:hover{background:var(--border);color:var(--text)} .mini.danger:hover{background:var(--danger-soft);color:var(--danger-text);border-color:var(--danger-border)} .mini.share:hover{background:var(--primary-soft);color:var(--primary-text);border-color:var(--primary-border)}

  table.list{width:100%;border-collapse:collapse}
  table.list th,table.list td{text-align:left;padding:11px 10px;border-bottom:1px solid var(--border);font-size:13px}
  table.list th{color:var(--muted);font-weight:500;font-size:12px}
  table.list tr:hover{background:var(--surface-2)} table.list tr.sel{background:var(--primary-soft)}
  .row-acts{display:flex;gap:6px;justify-content:flex-end}
  /* 2026-10-22：重命名按钮改为**常驻**（原 .act-rn 默认 visibility:hidden，仅 hover/选中时出现，
     用户反馈"鼠标一离开就消失，太别扭"）。全站行内操作现在一致常显：播放/预览/下载/重命名/更多/锁定，
     不再保留唯一的悬停门控例外；行内宽度由 flex 自适应，不再需要"占位防抖动"。 */
  .empty{text-align:center;padding:42px 20px;color:var(--muted)}

  .badge{font-size:11px;font-weight:500;padding:2px 9px;border-radius:99px;white-space:nowrap}
  .b-owner{background:transparent;color:var(--success-text);border:1px solid var(--primary-border)} .b-write{background:transparent;color:var(--primary-text);border:1px solid var(--primary-border)} .b-read{background:transparent;color:var(--warning-text);border:1px solid var(--border)}

  .ficon{width:38px;height:38px;border-radius:10px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;font-size:11px;flex:none}
  /* 文件类型图标配色：深色模式下换成深底浅字（原先硬编码浅色 pastel） */
  .ficon.f-image,.card-ic.f-image{background:var(--ic-image);color:var(--ic-image-fg)}
  .ficon.f-doc,.card-ic.f-doc{background:var(--ic-doc);color:var(--ic-doc-fg)}
  .ficon.f-sheet,.card-ic.f-sheet{background:var(--ic-sheet);color:var(--ic-sheet-fg)}
  .ficon.f-video,.card-ic.f-video{background:var(--ic-video);color:var(--ic-video-fg)}
  .ficon.f-audio,.card-ic.f-audio{background:var(--ic-audio);color:var(--ic-audio-fg)}
  .ficon.f-zip,.card-ic.f-zip{background:var(--ic-zip);color:var(--ic-zip-fg)}
  .ficon.f-file,.card-ic.f-file{background:var(--ic-zip);color:var(--ic-zip-fg)}
  .ficon.f-folder,.card-ic.f-folder{background:var(--ic-folder);color:var(--ic-folder-fg)}
  /* 存储占用条形图与图例 */
  /* 存储占用条：单蓝堆叠 + 白缝分隔（收敛 5 蓝阶为单一主蓝） */
  .st-bar i{background:var(--primary);border-right:2px solid var(--surface)}
  .st-bar i:last-child{border-right:0}
  /* 版本来源徽章：按语义五类，不再每种来源一套浅色 */
  .vm-src-sync{background:transparent;color:var(--primary-text);border:1px solid var(--primary-border)}
  .vm-src-manual{background:transparent;color:var(--warning-text);border:1px solid var(--border)}
  .vm-src-edit{background:transparent;color:var(--primary-text);border:1px solid var(--primary-border)}
  .vm-src-restore{background:transparent;color:var(--success-text);border:1px solid var(--primary-border)}
  .vm-src-upload{background:var(--surface-2);color:var(--muted);border:0.5px solid var(--border)}
  /* 动态流图标：五类语义色 */
  .act-ic.act-t-ok{background:transparent;color:var(--success-text)}
  .act-ic.act-t-warn{background:transparent;color:var(--warning-text)}
  .act-ic.act-t-danger{background:transparent;color:var(--danger-text)}
  .act-ic.act-t-info{background:transparent;color:var(--primary-text)}
  .act-ic.act-t-neutral{background:transparent;color:var(--muted)}
  .fmeta-min{display:flex;align-items:center;gap:11px;min-width:0}
  .fn{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* 历史备份徽章（可点击，零新增操作位宽度） */
  .vbadge{flex:none;font-size:11px;font-weight:500;color:var(--warning-text);background:transparent;border:0.5px solid var(--border);border-radius:99px;padding:2px 9px;cursor:pointer;white-space:nowrap;transition:.15s}
  .vbadge:hover{border-color:var(--warning-text)}
  /* 文件行「⋯ 更多」浮动菜单 */
  .file-menu{position:absolute;z-index:var(--z-menu);min-width:124px;background:var(--surface);border:0.5px solid var(--border);border-radius:var(--r-sm);box-shadow:var(--shadow-lg);padding:5px;display:flex;flex-direction:column;gap:2px}
  .file-menu button{text-align:left;padding:8px 11px;font-size:13px;color:var(--text);background:none;border:0;border-radius:var(--r-sm);cursor:pointer;font-family:inherit}
  .file-menu button:hover{background:var(--surface-2)}

  /* action bar */
  /* 水平居中用 left/right+margin:auto（left:50% 会让可用宽度只剩一半，flex-wrap 会塌成竖条） */
  .actionbar{position:fixed;bottom:24px;left:0;right:0;margin:0 auto;width:max-content;max-width:calc(100vw - 16px);flex-wrap:wrap;justify-content:center;background:var(--actionbar-bg);color:var(--actionbar-text);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:10px 14px;display:flex;align-items:center;gap:10px;z-index:var(--z-actionbar)}
  .actionbar .cnt{font-weight:500;padding:0 6px} .actionbar button{background:var(--actionbar-btn);color:var(--actionbar-text);padding:8px 13px;border-radius:9px;font-weight:500;font-size:13px}
  .actionbar button:hover{background:var(--actionbar-btn-hover)} .actionbar .x{margin-left:4px;color:var(--actionbar-text)}
  /* actionbar 是反色容器，全局 .x 的 --muted 落在这里两套主题都撞色（曾 2.14~2.74:1） */
  .actionbar .x:hover{color:var(--actionbar-text);background:var(--actionbar-btn-hover)}

  /* modal */
  .modal{position:fixed;inset:0;background:var(--overlay);display:flex;align-items:center;justify-content:center;padding:20px;z-index:var(--z-modal);backdrop-filter:blur(2px)}
  .modal-card{background:var(--surface);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);width:100%;max-width:440px;padding:22px;max-height:88vh;overflow:auto;scrollbar-gutter:stable;animation:pop .18s ease}
  .modal-card.sm{max-width:360px}
  /* 中等宽度模态（搜索/移动/批量重命名等）：此前散落 3 处内联 max-width:420px */
  .modal-card.md{max-width:420px}
  /* 通用布局工具：取代散落的内联 flex:1 / width:100% */
  .grow{flex:1}
  .w-full{width:100%}
  /* 开关/徽章旁的说明文字（此前 3 处内联 margin-left:8px;font-size:12px） */
  .side-hint{margin-left:8px;font-size:12px}
  @keyframes pop{from{transform:translateY(8px) scale(.98);opacity:0}to{transform:none;opacity:1}}
  .modal-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
  .modal-head h3{margin:0;font-size:15px;font-weight:500} .x{background:none;font-size:22px;line-height:1;color:var(--muted);padding:0 4px;min-width:32px;min-height:32px;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--r-sm)} .x:hover{color:var(--text);background:var(--surface-2)}
  .tabs{display:flex;gap:6px;margin:12px 0}
  .tabs button{flex:1;padding:9px;border-radius:var(--r-sm);background:var(--surface-2);color:var(--muted);font-weight:500;font-size:13px}
  .tabs button.active{background:var(--primary-soft);color:var(--primary-text)}
  /* 允许换行：窄屏下整行放不下时按元素换行，而不是把中文压成竖排 */
  .share-form{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:6px 0}
  /* 「数字输入 + 单位说明」作为一个整体，不允许被压缩变形 */
  .sf-field{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;min-width:0}
  .share-form input{flex:1;padding:10px 12px;border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);color:var(--text)}
  .share-form input:focus{outline:none;border-color:var(--primary);background:var(--surface);box-shadow:0 0 0 3px var(--primary-soft)}
  .share-list{display:flex;flex-direction:column;gap:8px;margin-top:8px}
  .share-item{display:flex;align-items:center;justify-content:space-between;padding:9px 12px;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-sm);font-size:13px}
  .share-item .rm{color:var(--danger-text);font-weight:500;font-size:12px;background:none;padding:2px 6px}
  .link-box{display:flex;gap:8px;margin:10px 0} .link-box input{flex:1;padding:9px 11px;border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);color:var(--text);font-size:12px}
  .opt{display:flex;gap:10px;flex-wrap:wrap;margin:6px 0}
  .opt label{font-size:12px;color:var(--muted);display:flex;flex-direction:column;gap:4px}
  .opt input{padding:8px 10px;border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);color:var(--text);width:130px}
  .modal-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:16px}
  /* 共享弹窗：长文件名/长链接不撑破卡片；移动端用户表单纵向排列 */
  #shareFileName{overflow-wrap:anywhere;word-break:break-all}
  #linkList .share-item>span{min-width:0;overflow-wrap:anywhere;word-break:break-all}
  @media(max-width:560px){
    #shareModal .share-form{flex-direction:column;align-items:stretch}
    #shareModal .share-form input{flex:none;width:100%}
    #shareModal .share-form .seg,#shareModal .share-form .btn-primary{width:100%!important}
    #shareModal .opt label,#shareModal .opt input{width:100%}
  }

  /* admin */
  .admin-table{width:100%;border-collapse:collapse;margin-top:10px}
  /* M4 存储管理区块 */
  .st-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:8px;align-items:start}
  .st-item{display:flex;flex-direction:column;align-items:flex-start;gap:3px;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-sm);padding:8px 12px;font-size:12px}
  .st-k{color:var(--muted);flex:none;font-size:11px;line-height:1.3}
  /* 数值列：正常 LTR + 允许换行显示完整（路径和容量不被截断） */
  .st-v{font-weight:500;font-size:13px;min-width:0;width:100%;direction:ltr;unicode-bidi:plaintext;overflow-wrap:anywhere;word-break:break-word;line-height:1.35}
  .st-k{color:var(--muted);flex:0 0 auto}
  /* 磁盘容量单行显示（满宽下 6 格一行，格宽约 180px，用短文案 + 「磁盘」标签保证不折行） */
  #stDisk{white-space:nowrap}
  @media(max-width:768px){#stDisk{white-space:normal}}
  /* 仅路径需要头截断（长路径显示尾部） */
  #stPath{direction:rtl;unicode-bidi:plaintext}
  .st-bar{display:flex;height:8px;border-radius:99px;overflow:hidden;background:var(--surface-2);margin-top:10px}
  .st-bar-line{display:flex;align-items:center;gap:10px;margin-top:10px}
  .st-bar-line .st-bar{flex:1;margin-top:0}
  .st-bar-num{font-size:12px;color:var(--text);white-space:nowrap;font-variant-numeric:tabular-nums}
  .st-bar i{display:block;height:100%}
  .st-legend{display:flex;gap:14px;flex-wrap:wrap;font-size:11px;color:var(--muted);margin-top:6px}
  .st-legend b{display:inline-block;width:8px;height:8px;border-radius:2px;margin-right:5px;vertical-align:middle}
  .st-migrate summary{cursor:pointer;font-size:13px;font-weight:500}
  .pm-toolbar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:2px 0 14px}
  .pm-toolbar input[type=search]{flex:1;min-width:180px;max-width:340px;padding:9px 12px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface);color:var(--text);outline:none;transition:.15s}
  .pm-toolbar input[type=search]:focus{border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
  .pm-toolbar select{padding:9px 30px 9px 12px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface-2);color:var(--text);appearance:none;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888780' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;cursor:pointer}
  /* data URI 无法用 CSS 变量着色，深色模式单独提供浅色箭头 */
  [data-theme="dark"] .pm-toolbar select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23A8ADB8' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E")}
  .pm-due{font-size:11px;color:var(--muted);white-space:nowrap}
  .pm-due.over{color:var(--danger);font-weight:500}
  .pm-fstats{font-size:12px;color:var(--muted);display:flex;gap:6px;align-items:center;flex-wrap:wrap}
  .admin-table th,.admin-table td{padding:10px;border-bottom:1px solid var(--border);font-size:13px;text-align:left}
  /* 窄屏把用户表卡片化：原来 5 列硬挤，每列的中文被压成竖排 */
  @media(max-width:640px){
    .admin-table thead{display:none}
    .admin-table tbody tr{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;padding:12px;border-bottom:1px solid var(--border)}
    .admin-table td{border:none;padding:0;font-size:13px}
    .admin-table td:nth-child(1){flex:1 1 100%;font-weight:500}
    .admin-table td:nth-child(2)::before{content:'角色 ';color:var(--muted);font-size:11px}
    .admin-table td:nth-child(3)::before{content:'状态 ';color:var(--muted);font-size:11px}
    .admin-table td:nth-child(4)::before{content:'占用 ';color:var(--muted);font-size:11px}
    .admin-table td:nth-child(5){margin-left:auto;flex:0 0 auto}
  }
  .admin-table th{color:var(--muted);font-weight:500;font-size:12px}
  .switch{position:relative;display:inline-block;width:42px;height:24px;flex:none}
  /* 用视觉隐藏而不是 display:none —— 后者会让复选框退出 Tab 序列，键盘无法操作任何开关 */
  .switch input{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}
  .switch:focus-within .slider{box-shadow:0 0 0 3px var(--primary-soft)}
  /* 关闭态：浅底 + 实边框，比纯灰填充更干净；开启态：绿色轨道，滑块平滑滑动 */
  .slider{position:absolute;inset:0;background:var(--surface);border:1px solid var(--border-strong);border-radius:99px;transition:background .2s,border-color .2s;cursor:pointer}
  .slider:before{content:"";position:absolute;width:18px;height:18px;left:2px;top:2px;background:var(--surface);border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.28);transition:transform .2s}
  input:checked + .slider{background:var(--success);border-color:var(--success)}
  input:checked + .slider:before{transform:translateX(18px)}

  /* toast */
  #toast-wrap{position:fixed;top:18px;left:50%;transform:translateX(-50%);z-index:var(--z-toast);display:flex;flex-direction:column;gap:10px;align-items:center}
  .toast{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--border);border-radius:var(--r-sm);box-shadow:var(--shadow);padding:11px 16px;font-size:13px;font-weight:500;min-width:220px;animation:tin .25s ease;max-width:90vw;overflow-wrap:anywhere}
  .toast .dot{width:9px;height:9px;border-radius:50%;flex:none} .toast.ok .dot{background:var(--success)} .toast.err .dot{background:var(--danger)} .toast.info .dot{background:var(--primary)}
  .toast .msg{min-width:0;overflow-wrap:anywhere}
  .toast .cnt{flex:none;font-size:12px;color:var(--muted);padding:0 2px}
  @keyframes tin{from{transform:translateY(-12px);opacity:0}to{transform:none;opacity:1}}
  .spinner{width:15px;height:15px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:spin .7s linear infinite;opacity:.85}
  @keyframes spin{to{transform:rotate(360deg)}}
  .skeleton{height:64px;border-radius:var(--r);background:linear-gradient(90deg,var(--skeleton-a) 25%,var(--skeleton-b) 37%,var(--skeleton-a) 63%);background-size:400% 100%;animation:sk 1.2s infinite;margin:8px 0}
  @keyframes sk{0%{background-position:100% 0}100%{background-position:-100% 0}}
  /* search + activity */
  .search-input{padding:9px 13px;border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);color:var(--text);min-width:190px;max-width:240px;font-size:13px;transition:border-color .15s,box-shadow .15s}
  .search-input:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
  .search-input:focus{outline:none;border-color:var(--primary);background:var(--surface);box-shadow:0 0 0 3px var(--primary-soft)}
  .act-item{display:flex;align-items:center;gap:11px;padding:10px 2px;border-bottom:1px solid var(--border);font-size:13px}
  .act-item:last-child{border-bottom:none}
  .act-ic{width:32px;height:32px;border-radius:9px;display:flex;align-items:center;justify-content:center;font-size:15px;flex:none}
  .act-main{flex:1;min-width:0}
  .act-main .a-line{display:flex;align-items:baseline;gap:6px}
  .act-main .a-name{font-weight:500}
  .act-main .a-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .act-main .a-time{font-size:11px;color:var(--muted);margin-top:2px}
  code{background:var(--surface-2);padding:2px 6px;border-radius:6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
  /* ===== AI 项目模块（pm-*） ===== */
  .b-gray{background:var(--surface-2);color:var(--muted)}
  .pm-metrics{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:14px}
  .pm-metric{background:var(--surface-2);border-radius:var(--r);padding:10px 12px}
  .pm-metric i{font-style:normal;font-size:11px;color:var(--muted);display:block}
  .pm-metric b{font-size:20px;font-weight:500;font-variant-numeric:tabular-nums}
  .pm-metric.ok b{color:var(--success-text)}
  .pm-metric.warn b{color:var(--warning-text)}
  .pm-group-h{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:500;margin:18px 0 8px}
  .pm-group-h .ic{color:var(--muted)}
  .pm-group-h span{font-size:11px;font-weight:500;color:var(--muted);background:var(--surface-2);border-radius:99px;padding:1px 8px}
  .pm-bkline{display:flex;gap:10px;align-items:center;font-size:12px;color:var(--muted);margin:7px 0 0;min-width:0;flex-wrap:wrap}
  .pm-bk-path{display:inline-flex;align-items:center;gap:5px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:58%}
  .pm-bk-meta{flex:none;font-variant-numeric:tabular-nums}
  .pm-empty-lg{text-align:center;padding:46px 0 30px}
  .pm-empty-lg .ic{width:34px;height:34px;stroke-width:1.2;opacity:.35}
  .pm-empty-lg p{margin:10px 0 0;font-size:14px}
  .pm-empty-lg p.muted{font-size:12px;max-width:420px;margin:6px auto 0}
  .pm-tabs{display:flex;gap:2px;border-bottom:1px solid var(--border);margin:14px 0 16px}
  .pm-tab{border:none;background:none;padding:9px 14px;font-size:13px;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent;display:inline-flex;gap:6px;align-items:center}
  .pm-tab.on{color:var(--primary-text);border-bottom-color:var(--primary)}
  .pm-tab-n{font-size:11px;background:var(--surface-2);border-radius:99px;padding:0 7px;line-height:18px}
  .bk-hero{display:flex;gap:12px;align-items:center;justify-content:space-between;flex-wrap:wrap;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-lg);padding:14px 16px;margin-bottom:14px}
  .bk-hero.ok{border-left:3px solid var(--success)}
  .bk-hero.stale{border-left:3px solid var(--warning)}
  .bk-hero.none{border-left:3px solid var(--border)}
  .bk-hero-stats{font-size:13px;color:var(--muted);margin-top:6px}
  .bk-hero-r{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
  .bk-vlist{display:flex;flex-direction:column;gap:6px}
  .bk-vrow{display:flex;gap:10px;align-items:center;background:var(--surface-2);border-radius:var(--r-sm);padding:8px 12px;font-size:12px}
  .bk-vname{display:inline-flex;gap:6px;align-items:center;min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .bk-how{margin:6px 0 0;padding-left:20px;font-size:13px;color:var(--muted);display:flex;flex-direction:column;gap:5px}
  .admin-tabs{display:flex;flex-wrap:nowrap;gap:2px;border-bottom:1px solid var(--border);margin:4px 0 16px;overflow-x:auto;scrollbar-width:none}
  .admin-tabs::-webkit-scrollbar{display:none}
  .admin-tab{flex:0 0 auto;white-space:nowrap;border:none;background:none;padding:9px 14px;font-size:13px;color:var(--muted);cursor:pointer;border-bottom:2px solid transparent;transition:color .15s}
  .admin-tab:hover{color:var(--text)}
  .admin-tab.on{color:var(--primary-text);border-bottom-color:var(--primary);font-weight:500}

  /* ============ 运行控制（管理页 · 运行控制） ============ */
  .ops-hero{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--border-strong);border-radius:var(--r);padding:14px 18px;margin-bottom:14px}
  .ops-hero.ok{border-left-color:var(--success)}
  .ops-hero.warn{border-left-color:var(--warning)}
  .ops-hero.err{border-left-color:var(--danger)}
  .ops-hero-l{display:flex;align-items:center;gap:11px;min-width:0}
  .ops-hero-txt{min-width:0}
  .ops-hero-title{font-size:15px;font-weight:500;color:var(--text);line-height:1.35}
  .ops-hero.ok .ops-hero-title{color:var(--success-text)}
  .ops-hero.warn .ops-hero-title{color:var(--warning-text)}
  .ops-hero.err .ops-hero-title{color:var(--danger-text)}
  .ops-hero-sub{font-size:12px;color:var(--muted);margin-top:3px;line-height:1.5;word-break:break-all}
  .ops-hero-r{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
  .ops-dot{width:14px;height:14px;border-radius:50%;background:var(--switch-off);flex:none;box-shadow:0 0 0 4px var(--surface-2)}
  .ops-hero.ok .ops-dot{background:var(--success);box-shadow:0 0 0 3px var(--success-soft)}
  .ops-hero.warn .ops-dot{background:var(--warning);box-shadow:0 0 0 3px var(--warning-soft)}
  .ops-hero.err .ops-dot{background:var(--danger);box-shadow:0 0 0 3px var(--danger-soft)}

  .ops-meta{display:grid;grid-template-columns:repeat(4,1fr);gap:10px 12px;margin-bottom:14px}
  .ops-meta-i{background:var(--surface-2);border-radius:var(--r-sm);padding:9px 12px;min-width:0}
  .ops-meta-i>span{display:block;font-size:11px;color:var(--muted);margin-bottom:2px}
  .ops-meta-i>b{font-size:13px;font-weight:500;color:var(--text);font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}

  .ops-tag{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:500;line-height:1;padding:4px 12px;border-radius:99px;background:var(--surface-2);color:var(--muted);border:1px solid var(--border);margin-left:10px;vertical-align:middle}
  .ops-tag::before{content:'';width:7px;height:7px;border-radius:50%;background:currentColor;opacity:.9}
  .ops-tag.on{background:transparent;color:var(--success-text);border-color:var(--primary-border)}
  .ops-tag.on::before{background:var(--success)}
  .ops-tag.err{background:transparent;color:var(--danger-text);border-color:var(--danger-border)}
  .ops-tag.err::before{background:var(--danger)}
  /* 子系统卡片：开启态用绿色左边框，配合徽标与单开关按钮（红=关闭动作/蓝=开启动作），一眼看出当前状态 */
  .sp-card.ops-on{border-left:3px solid var(--success)}
  .ops-url-row.active{border-color:var(--success);background:var(--success-soft)}

  .ops-url-row{display:flex;gap:8px;align-items:center;background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-sm);padding:8px 10px;margin-bottom:12px}
  .ops-url{flex:1;min-width:0;font-size:12px;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Consolas,monospace}
  .ops-url.is-empty{color:var(--muted);font-family:inherit}

  .ops-result{display:none;margin-top:12px;padding:9px 12px;border-radius:var(--r-sm);font-size:12px;line-height:1.6;word-break:break-all}
  .ops-result.show{display:block}
  .ops-result.ok{background:var(--success-soft);color:var(--success-text)}
  .ops-result.err{background:var(--danger-soft);color:var(--danger-text)}
  .ops-result.info{background:var(--surface-2);color:var(--muted)}

  /* 管理页统一操作状态条：所有按钮点击后都在这里留下「进行中 / 成功(带时间) / 失败原因」，
     不再只靠 3 秒即逝的 toast；滚动时吸顶，切标签页仍可见 */
  .adm-status{display:none;align-items:center;gap:9px;margin:-6px 0 14px;padding:9px 12px;border-radius:10px;
    font-size:12px;line-height:1.55;border:1px solid transparent;word-break:break-word;
    position:sticky;top:0;z-index:3;background:var(--surface)}
  .adm-status.show{display:flex}
  .adm-status .adm-ic{flex:none;width:16px;height:16px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500}
  .adm-status .adm-tx{flex:1;min-width:0}
  .adm-status .adm-tm{flex:none;font-size:11px;opacity:.7;font-variant-numeric:tabular-nums}
  .adm-status.is-busy{background:var(--surface-2);border-color:var(--border);color:var(--text)}
  .adm-status.is-busy .adm-ic{color:var(--primary)}
  .adm-status.is-ok{background:var(--success-soft);border-color:var(--success-soft);color:var(--success-text)}
  .adm-status.is-err{background:var(--danger-soft);border-color:var(--danger-soft);color:var(--danger-text)}
  .adm-status.is-info{background:var(--surface-2);border-color:var(--border);color:var(--muted)}

  .ops-checks{list-style:none;margin:0;padding:0;display:grid;gap:7px}
  .ops-checks li{display:flex;gap:9px;align-items:flex-start;font-size:12px;line-height:1.55;padding:8px 11px;background:var(--surface-2);border-radius:var(--r-sm)}
  .ops-checks .ic-ok{color:var(--success);flex:none}
  .ops-checks .ic-no{color:var(--danger);flex:none}
  .ops-checks .ic-info{color:var(--muted);flex:none}
  .ops-checks li.x-info{background:transparent;border:1px dashed var(--border)}
  .ops-checks b{font-weight:500;color:var(--text)}
  .ops-checks span{color:var(--muted);word-break:break-all}

  @media(max-width:768px){.ops-meta{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:560px){.ops-hero-r{width:100%}.ops-hero-r .btn-ghost{flex:1}}

  /* ===== 管理页整体密度：满宽布局下收紧间距（不缩页面宽度） ===== */
  .admin-pane .sp-card{padding:14px 16px;margin-bottom:12px}
  .admin-pane .sp .sp-title{margin-bottom:10px}
  .admin-pane .sp-help{margin-top:8px}
  .admin-pane .sp-row{gap:10px 12px}
  .admin-pane .sp .btn-primary,.admin-pane .sp .btn-ghost,.admin-pane .sp .btn-danger{min-height:34px;padding:7px 13px}
  /* 「输入框 + 按钮」型表单：一行铺满，按钮紧跟字段 */
  .admin-pane .sp-row--compact{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}
  .admin-pane .sp-row--compact .sp-field{flex:1 1 260px;min-width:200px}
  .admin-pane .sp-row--compact .sp-actions{grid-column:auto;justify-content:flex-start;margin-top:0}
  .admin-pane .sp .btn-primary,.admin-pane .sp .btn-ghost,.admin-pane .sp .btn-danger{min-height:34px;padding:7px 13px}

  /* 主服务：信息与操作同一行 */
  .ops-svc{display:flex;flex-direction:column;gap:14px}
  .ops-svc .ops-meta{margin-bottom:0}
  .ops-svc-actions{display:flex;gap:12px;align-items:center;flex-wrap:wrap;justify-content:flex-start}
  .ops-svc-actions .btn-ghost,.ops-svc-actions .btn-danger{min-width:118px}
  .ops-svc-actions .btn-danger{margin-left:auto}
  /* 临时分享 / 自用远程：并排两列 */
  /* 2026-10-22：改回单列。设置行需要「标签 ~150px + 地址 ~340px + 按钮」，两列各 ~400px 放不下，
     右侧地址会被挤出卡片（实测溢出）。单列后与通用设置页同一视觉节奏。 */
  .ops-grid{display:grid;grid-template-columns:1fr;gap:12px;margin-bottom:12px}
  .ops-grid .sp-card{margin-bottom:0;display:flex;flex-direction:column}
  .ops-grid .sp-actions{margin-top:auto}
  .ops-grid .sp-help{margin-top:10px}
  .ops-url-row{padding:6px 9px;margin-bottom:10px}
  .ops-url-row .btn-ghost{min-height:28px;padding:4px 11px;font-size:12px}
  .ops-checks{grid-template-columns:1fr 1fr}
  @media(max-width:900px){.ops-grid{grid-template-columns:1fr}.ops-checks{grid-template-columns:1fr}}
  .admin-pane h4{margin:16px 0 6px;font-size:13px}
  .admin-pane h4:first-child{margin-top:0}
  .pm-more summary{cursor:pointer;font-size:13px;color:var(--muted);margin:4px 0 2px}
  .disk-warn{display:flex;align-items:center;gap:8px;background:var(--danger-soft);color:var(--danger-text);font-size:13px;padding:8px 16px;border-bottom:1px solid var(--border)}
  .ex-chips{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
  .ex-chip{display:inline-flex;align-items:center;gap:5px;font-size:12px;background:var(--surface-2);border:1px solid var(--border);border-radius:99px;padding:3px 6px 3px 11px}
  .ex-chip button{border:none;background:none;color:var(--muted);cursor:pointer;font-size:13px;line-height:1;padding:0 3px;border-radius:99px}
  .ex-chip button:hover{color:var(--danger);background:var(--danger-soft)}
  .st-click{cursor:pointer}
  .st-click:hover{border-color:var(--primary);background:var(--primary-soft)}
  .admin-pane .share-list .share-item{font-size:12px}
  .pm-chips{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:6px;align-items:center}
  .pm-chip{border:1px solid var(--border);border-radius:6px;padding:3px 10px;font-size:11px;color:var(--muted);background:var(--surface)}
  .pm-chip.on{background:transparent;border-color:var(--primary);color:var(--primary-text)}
  .pm-chip.pm-new{margin-left:auto;background:transparent;border-color:var(--primary);color:var(--primary-text);font-weight:500}
  .pm-chip.pm-new:hover{background:var(--primary-soft)}
  .pm-card{border:1px solid var(--border);border-radius:var(--r);padding:12px;margin-top:9px;background:var(--surface);cursor:pointer;transition:.15s}
  .pm-card:hover{background:var(--surface-2);border-color:var(--border-strong)}
  .pm-card-h{display:flex;align-items:center;gap:8px;min-width:0}
  .pm-ic{width:26px;height:26px;border-radius:8px;background:transparent;color:var(--primary-text);border:1px solid var(--primary-border);display:flex;align-items:center;justify-content:center;font-weight:500;font-size:12px;flex:none}
  .pm-name{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pm-tech-row{display:flex;gap:4px;flex-wrap:wrap;margin-top:7px}
  .pm-tech{font-size:11px;color:var(--primary-text);background:transparent;border:1px solid var(--primary-border);border-radius:5px;padding:2px 6px}
  /* S5 远程项目 */
  .pm-cloud{font-size:11px;font-weight:500;color:var(--primary-text);background:transparent;border:1px solid var(--primary-border);border-radius:99px;padding:2px 8px;white-space:nowrap;flex:none}
  .pm-cfg{background:var(--surface-2);border:0.5px solid var(--border);border-radius:var(--r-sm);padding:12px 14px;font-family:ui-monospace,Consolas,monospace;font-size:11px;line-height:1.7;overflow:auto;max-height:300px;white-space:pre;color:var(--text)}
  .pm-loc{display:flex;gap:8px;flex-wrap:wrap}
  .pm-loc-opt{display:flex;align-items:center;gap:7px;font-size:12px;border:1px solid var(--border);border-radius:var(--r-sm);padding:9px 12px;cursor:pointer;flex:1;min-width:180px;transition:.15s}
  .pm-loc-opt:has(input:checked){border-color:var(--primary);background:var(--primary-soft)}
  .pm-loc-opt:has(input:disabled){opacity:.65;cursor:default}
  .pg2 i{display:block;height:100%;background:var(--primary);border-radius:3px}
  .pm-detail-h{display:flex;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap}
  .pm-detail-h .spacer{flex:1}
  .pm-summary{font-size:13px;color:var(--muted);margin:2px 0 8px}
  .pm-info{display:flex;gap:10px;flex-wrap:wrap;font-size:12px;margin-bottom:8px}
  .pm-info-i{background:var(--surface-2);border-radius:6px;padding:4px 9px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
  .pm-info-i a{color:var(--primary-text)}
  .pm-sec{margin-top:14px;border-top:1px solid var(--border);padding-top:10px}
  .pm-sec-h{font-size:13px;font-weight:500;margin-bottom:6px;display:flex;align-items:center}
  .pm-git{display:flex;align-items:center;flex-wrap:wrap;gap:4px;padding:8px 0;min-height:20px}
  .pm-sec-h .muted{font-weight:400;font-size:11px}
  .pm-row{display:flex;align-items:center;gap:8px;padding:7px 2px;border-bottom:1px solid var(--border);font-size:13px;min-width:0}
  .pm-row:last-child{border-bottom:none}
  .pm-row-t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pm-row-t.done{text-decoration:line-through;color:var(--muted)}
  .pm-state{width:20px;height:20px;border-radius:6px;border:1.5px solid var(--border-strong);display:flex;align-items:center;justify-content:center;font-size:11px;cursor:pointer;flex:none;color:var(--muted)}
  .pm-state.doing{border-color:var(--primary);color:var(--primary-text)}
  .pm-state.done{background:transparent;border-color:var(--primary);color:var(--primary-text)}
  .pm-chk{width:15px;height:15px;flex:none}
  .pm-pr{font-size:11px;border-radius:5px;padding:1px 6px;font-weight:500;flex:none}
  .pm-pr.P1{background:transparent;color:var(--danger-text);border:1px solid var(--danger-border)}
  .pm-pr.P2{background:transparent;color:var(--warning-text);border:1px solid var(--border)}
  .pm-pr.P3{background:transparent;color:var(--muted);border:1px solid var(--border)}
  .pm-due{font-size:11px;color:var(--muted);flex:none}
  .pm-url{color:var(--primary-text);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
  .pm-del{background:none;color:var(--muted);font-size:12px;padding:2px 6px}
  .pm-del:hover{color:var(--danger-text)}
  .pm-empty{font-size:12px;padding:2px}
  .pm-add{display:flex;gap:6px;margin-top:8px;flex-wrap:wrap}
  .pm-add input{flex:1;min-width:110px;padding:7px 10px;border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);color:var(--text)}
  .pm-add input:focus{outline:none;border-color:var(--primary)}
  .pm-add select{padding:7px 8px;border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);color:var(--text)}
  .pm-add .btn-ghost{padding:7px 12px}
  @media(max-width:560px){.uname{display:none}.card-meta .ms{display:none}.search-input{max-width:none;width:100%}.pm-metrics{grid-template-columns:repeat(2,1fr)}}

/* ===== 视频播放器 ===== */
.vp-modal{padding:0;background:var(--vp-bg)}
.vp-wrap{display:flex;flex-direction:column;height:100%;background:var(--vp-surface);color:var(--vp-fg-strong)}
.vp-top{display:flex;align-items:center;gap:10px;padding:8px 12px;background:var(--vp-bar);flex:none}
.vp-title{font-size:14px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.vp-icon{background:none;border:none;color:var(--vp-fg);width:34px;height:34px;border-radius:8px;display:flex;align-items:center;justify-content:center;cursor:pointer}
.vp-icon:hover{background:rgba(255,255,255,.12);color:var(--vp-fg-strong)}
.vp-stage{position:relative;flex:1;min-height:0;background:var(--vp-bg);display:flex;align-items:center;justify-content:center;overflow:hidden}
.vp-stage video{width:100%;height:100%;object-fit:contain;background:var(--vp-bg)}
.vp-badges{position:absolute;left:12px;top:12px;display:flex;gap:6px}
.vp-badge{background:rgba(255,255,255,.16);color:var(--vp-ok);font-size:11px;padding:3px 9px;border-radius:99px}
.vp-badge.warn{color:var(--vp-warn)}
.vp-badge.dim{color:var(--vp-fg)}
.vp-center{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}
.vp-spin{width:38px;height:38px;border:3px solid rgba(255,255,255,.25);border-top-color:var(--vp-accent);border-radius:50%;animation:vpSpin .8s linear infinite}
@keyframes vpSpin{to{transform:rotate(360deg)}}
.vp-fallback{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;background:var(--vp-surface);color:var(--vp-fg);padding:24px;text-align:center;font-size:13px;line-height:1.7}
.vp-fallback .btn-primary{padding:8px 16px}
.vp-controls{flex:none;background:var(--vp-bar);padding:8px 14px 10px}
.vp-progress{position:relative;height:5px;border-radius:99px;background:rgba(255,255,255,.2);cursor:pointer;margin-bottom:10px}
.vp-progress:hover{height:7px}
.vp-buffered{position:absolute;left:0;top:0;height:100%;border-radius:99px;background:rgba(255,255,255,.32);width:0}
.vp-played{position:absolute;left:0;top:0;height:100%;border-radius:99px;background:var(--vp-accent);width:0}
.vp-knob{position:absolute;top:50%;transform:translate(-50%,-50%);width:13px;height:13px;border-radius:50%;background:var(--vp-fg-strong);border:.5px solid rgba(0,0,0,.3);left:0;opacity:0;transition:opacity .15s}
.vp-progress:hover .vp-knob{opacity:1}
.vp-row{display:flex;align-items:center;gap:12px}
.vp-time{font-size:12px;color:var(--vp-fg);font-variant-numeric:tabular-nums}
.vp-btn-txt{background:none;border:.5px solid rgba(255,255,255,.35);color:var(--vp-fg);font-size:12px;border-radius:6px;padding:3px 8px;cursor:pointer}
.vp-btn-txt:hover{color:var(--vp-fg-strong);border-color:var(--vp-fg-strong)}
.vp-vol{display:flex;align-items:center;gap:6px}
.vp-vol input[type=range]{width:74px;accent-color:var(--vp-accent)}
.vp-meta{margin-top:8px;font-size:12px;color:var(--vp-meta)}
@media(max-width:560px){.vp-vol input[type=range]{width:48px}.vp-meta{display:none}}

  /* ============ 批量备份到文件夹（ex-*）============ */
  /* 注意：这块位于「系统管理 → 存储」内，容器只有 440px（.modal-card 默认宽度），
     所以按窄容器设计：目标独占一行、下拉各半行、操作按钮独占一行右对齐 */
  .ex-block{border:1px solid var(--border);border-radius:var(--r);background:var(--surface-2);padding:14px 16px;margin:2px 0 4px}
  .ex-form .ex-grow{flex:1 1 240px;min-width:0}
  .ex-form input[type=text],.ex-form input:not([type]),.ex-form input[type=number],.ex-form select{padding:10px 12px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--surface);color:var(--text);font:inherit}
  .ex-form input:focus,.ex-form select:focus{outline:none;border-color:var(--primary);box-shadow:0 0 0 3px var(--primary-soft)}
  .ex-form input[type=number]{width:72px;flex:0 0 auto;text-align:center}
  .ex-form select{flex:0 1 168px;min-width:120px;max-width:100%;padding-right:30px;appearance:none;cursor:pointer;
    background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888780' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat:no-repeat;background-position:right 10px center}
  [data-theme="dark"] .ex-form select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23A8ADB8' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E")}
  .ex-bar{height:8px;border-radius:99px;background:var(--surface-2);border:1px solid var(--border);overflow:hidden;margin-top:12px}
  .ex-bar>i{display:block;height:100%;background:var(--primary);transition:width .25s}
  /* 次要说明：放在卡片底部、字号更小，不再抢占主流程视线 */
  .ex-note{margin:10px 0 0;padding-top:8px;border-top:1px solid var(--border);font-size:11px;line-height:1.6;color:var(--muted)}
  .ex-result{margin:10px 0 0;font-size:12px;word-break:break-all}
  .ex-ok{color:var(--success-text)} .ex-err{color:var(--danger-text)}
  @media(max-width:640px){
    .ex-form .ex-grow{min-width:100%}
    .ex-form select{flex:1 1 100%}
    .ex-actions{margin-left:0;width:100%}
  }
  /* 窄容器里「开始备份」按钮独占一行右对齐，避免和开关/份数挤在一起 */
  @media(max-width:560px){.ex-actions{width:100%;margin-left:0}}

/* ============ 系统设置 · 存储页 统一重构（.sp 作用域）============ */
/* 思路：原先存储页把 share-form / sf-field / ex-block 复用成一长列，按钮与输入框
   全靠内联 style 兜底，导致样式不统一、隐藏元素（取消/进度）游离。
   这里抽出一套与全局令牌一致的表单/卡片组件，分区清晰、控件统一。 */
.sp{padding:2px 0}
.sp-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:16px 18px;margin-bottom:14px}
.sp-card:last-child{margin-bottom:0}
.sp .sp-title{margin:0 0 14px;font-size:14px;font-weight:500;color:var(--text);line-height:1.3}
.sp-sub{display:block;margin-top:3px;font-weight:400;font-size:12px;color:var(--muted);line-height:1.5}

/* 统一栅格：四等分，每格约 200px —— 既统一又不过长；路径类占 2 格保证可读 */
.sp-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px 14px;align-items:end}
.sp-row--middle{align-items:center}
.sp-row>.badge{justify-self:start}
.sp-field{display:flex;flex-direction:column;gap:6px;min-width:0}
.sp-field>label{font-size:12px;color:var(--muted);font-weight:500}
.sp-field--primary{grid-column:span 2}

/* 所有输入框 / 下拉框：统一外观、统一填满栅格 → 长度完全一致 */
.sp-input,.sp-select{width:100%;padding:9px 12px;border:1px solid var(--border-strong);border-radius:var(--r-sm);background:var(--surface);color:var(--text);font:inherit;font-size:13px;transition:border-color .15s,box-shadow .15s,background .15s}
.sp-input:focus,.sp-select:focus{outline:none;border-color:var(--primary);background:var(--surface);box-shadow:0 0 0 3px var(--primary-soft)}
.sp-select{appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:30px;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23888780' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center}
[data-theme="dark"] .sp-select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23A8ADB8' stroke-width='1.5' fill='none' stroke-linecap='round'/%3E%3C/svg%3E")}

/* 操作区：所有按钮统一在整行右对齐，作为一致的动作标准 */
.sp-actions{grid-column:1/-1;display:flex;gap:8px;justify-content:flex-end;align-items:center;flex-wrap:wrap;margin-top:2px}
.sp-actions--inline{grid-column:auto;min-width:0}
.sp-check{display:inline-flex;align-items:center;gap:8px;font-size:12px;color:var(--text);white-space:nowrap;padding-bottom:9px}

.sp-help{font-size:12px;color:var(--muted);line-height:1.6;margin:10px 0 0}
.sp-help.sp-inline{margin:0}
.sp-list:empty{display:none}
.sp-progress{margin-top:14px}
.sp-note{margin:14px 0 0;padding-top:10px;border-top:1px solid var(--border);font-size:12px;line-height:1.7;color:var(--muted)}
.sp-card--danger{border-left:3px solid var(--danger-border)}
.sp-card--danger .sp-title{color:var(--danger-text)}
.sp-bar-wrap{margin-top:12px}
.sp .st-grid{margin:0}
.sp .st-bar{margin-top:0}

/* 通用设置页：两列网格——简单项并排、复杂项跨整行，纵向空间减半 */
.sp-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:start}
.sp-grid>.sp-card{margin-bottom:0;padding:14px 15px}
.sp-grid .sp-title{margin-bottom:9px}
.sp-grid .sp-help{margin-top:7px;font-size:11px;line-height:1.55}
/* 行内布局改 flex 连续流：输入框伸展、按钮紧跟，杜绝 4 列栅格的断裂感 */
.sp-grid .sp-row{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}
.sp-grid .sp-row--middle{align-items:center}
.sp-grid .sp-row .sp-field{flex:1 1 180px;min-width:150px}
.sp-grid .sp-row--middle .side-hint{flex:1;min-width:120px}
.sp-grid .sp-actions{margin-top:0}
.sp-card--wide{grid-column:1/-1}
@media(max-width:860px){.sp-grid{grid-template-columns:1fr}.sp-card--wide{grid-column:auto}}
/* 统一按钮：卡片内三类按钮等高、同内边距、内容居中，消除原先内联 padding 造成的参差 */
.sp .btn-primary,.sp .btn-ghost,.sp .btn-danger{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:9px 15px;min-height:38px;font-size:13px}
/* 列表 / 表格内的小按钮保持紧凑，不被统一大按钮规则抬高 */
.sp .sp-list .btn-primary,.sp .sp-list .btn-ghost,.sp .sp-list .btn-danger,
.sp .share-list .btn-primary,.sp .share-list .btn-ghost,.sp .share-list .btn-danger,
.sp .admin-table .btn-primary,.sp .admin-table .btn-ghost,.sp .admin-table .btn-danger{min-height:0}
/* 按下/禁用反馈：避免点击后毫无变化的感觉 */
.sp .btn-primary:active,.sp .btn-ghost:active,.sp .btn-danger:active{transform:translateY(1px)}
.sp .btn-primary:disabled,.sp .btn-ghost:disabled,.sp .btn-danger:disabled{opacity:.6;cursor:default;transform:none}
/* ===== 2026-10-22：设置行语言（通用设置 / 用户管理）=====
   一行一件事：左=标签+副说明，右=控件与按钮；行间 1px 分隔线，段内不再逐项套卡片。
   即时生效的开关在副说明里标「· 即时生效」。 */
.set-row{display:flex;gap:18px;align-items:center;justify-content:space-between;padding:13px 0;border-top:1px solid var(--border)}
.set-row:first-of-type{border-top:0;padding-top:2px}
.set-k{min-width:150px}
.set-k b{display:block;font-size:13px;font-weight:500;color:var(--text);line-height:1.4}
.set-k span{display:block;font-size:12px;color:var(--muted);margin-top:2px;line-height:1.45}
.set-v{display:flex;gap:8px;align-items:center;flex:0 1 auto;flex-wrap:wrap;justify-content:flex-end;min-width:0}
.set-v .sp-input{width:210px}
.set-v .sp-input--xs{width:88px}
.set-lbl{font-size:12px;color:var(--muted)}
.set-state{font-size:12px;color:var(--muted)}
.set-chips{display:flex;gap:6px;flex-wrap:wrap;padding:0 0 12px}
.set-v .ops-url{flex:0 1 auto;max-width:340px}
@media(max-width:640px){
  .set-row{flex-direction:column;align-items:stretch;gap:9px}
  .set-v{justify-content:flex-start}
  .set-v .sp-input,.set-v .sp-input--xs{width:100%}
  .set-v .ops-url{max-width:100%}
}
@media(max-width:560px){
  .sp-row{grid-template-columns:1fr}
  .sp-field--primary{grid-column:1/-1}
  .sp-actions{grid-column:1/-1}
  .sp-actions .btn-primary,.sp-actions .btn-ghost,.sp-actions .btn-danger{flex:1 1 auto;justify-content:center}
}

/* 无障碍：尊重系统「减少动态效果」偏好 */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
}

/* ============ 备份页 bk-*（S3a）· 布局口径见 BACKUP-FINAL-PLAN.md §8 ============ */
.bk-sub{font-size:12px;color:var(--muted)}
.bk-status{display:inline-flex;align-items:center;gap:5px;font-size:11px;padding:3px 8px;border-radius:99px;white-space:nowrap;background:var(--surface-2)}
.bk-dot{width:8px;height:8px;border-radius:99px;flex:none;display:inline-block}
.bk-dot-green{background:var(--success)}.bk-dot-amber{background:var(--warning)}.bk-dot-red{background:var(--danger)}.bk-dot-gray{background:var(--placeholder)}
.bk-green{color:var(--success-text)}.bk-amber{color:var(--warning-text)}.bk-red{color:var(--danger-text)}.bk-gray{color:var(--muted)}
.bk-banner{display:flex;align-items:center;gap:8px;margin:10px 0;padding:7px 10px;border-radius:var(--r-sm);background:var(--danger-soft);color:var(--danger-text);font-size:12px}
.bk-banner-stale{display:flex;align-items:center;gap:8px;margin:10px 0;padding:9px 12px;border-radius:var(--r-sm);background:var(--warning-soft);color:var(--warning-text);font-size:12px;flex-wrap:wrap}
.bk-toolbar{display:flex;align-items:center;gap:8px;margin:12px 0 6px}
.bk-toolbar .spacer{flex:1}
.bk-seg{padding:2px 7px;font-size:11px;border-radius:var(--r-sm);background:var(--surface-2);color:var(--muted);border:1px solid transparent}
.bk-seg.on{background:var(--primary-soft);color:var(--primary-text);border-color:var(--primary-border)}
.bk-section{margin-top:14px}
.bk-sec-head{display:flex;align-items:baseline;gap:8px;margin-bottom:6px;font-size:13px;font-weight:500}
.bk-list{border:1px solid var(--border);border-radius:var(--r);overflow:hidden}
.bk-row{display:grid;grid-template-columns:14px minmax(0,1.5fr) minmax(0,0.8fr) minmax(0,0.6fr) auto;gap:8px;align-items:center;padding:10px 12px;border-top:1px solid var(--border);cursor:pointer}
.bk-list .bk-row:first-child{border-top:none}
.bk-row:hover{background:var(--surface-2)}
.bk-name{font-size:13px;font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bk-tag{font-size:11px;font-weight:500;padding:1px 6px;border-radius:99px;background:var(--surface-2);border:1px solid var(--border)}
.bk-tag-archive{background:var(--primary-soft);color:var(--primary-text);border-color:var(--primary-border)}
.bk-stat{font-size:12px;color:var(--muted)}
.bk-time{font-size:12px}
.bk-acts{display:flex;gap:5px;justify-content:flex-end}
.bk-path{grid-column:2 / -1;font-size:11px;color:var(--muted);font-family:ui-monospace,Menlo,Consolas,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:2px}
.bk-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(248px,1fr));gap:12px}
@media(max-width:560px){.bk-grid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}}
.bk-card{border:1px solid var(--border);border-radius:var(--r);padding:14px;background:var(--surface);cursor:pointer}
.bk-card:hover{background:var(--surface-2);border-color:var(--border-strong)}
.bk-card-top{display:flex;align-items:flex-start;justify-content:space-between}
.bk-card-ic{width:44px;height:44px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:11px;background:var(--surface-2)}
.bk-card-ic.f-folder{background:var(--ic-folder);color:var(--ic-folder-fg)}
.bk-card-ic.f-zip{background:var(--ic-zip);color:var(--ic-zip-fg)}
.bk-card-name{font-size:13px;font-weight:500;margin-top:8px}
.bk-card-meta{font-size:12px;color:var(--muted);margin-top:2px}
.bk-card-path{font-size:11px;color:var(--muted);font-family:ui-monospace,Menlo,Consolas,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:4px}
.bk-card-acts{display:flex;gap:5px;margin-top:10px}
.bk-empty{border:1px dashed var(--border-strong);border-radius:var(--r);padding:28px 16px;text-align:center;color:var(--muted);font-size:13px}
.bk-empty p{margin:0 0 10px}
.bk-foot{margin-top:14px;font-size:12px;color:var(--muted)}
.bk-orphan{margin:12px 0 0;padding:8px 11px;border-radius:var(--r-sm);background:var(--surface-2);color:var(--muted);font-size:12px;line-height:1.6}
.bk-skel{height:44px;border-radius:var(--r);margin-bottom:10px;background:var(--skeleton-a)}
@media(max-width:768px){
  .bk-row{grid-template-columns:14px minmax(0,1fr) auto;gap:6px}
  .bk-name{grid-column:2}
  .bk-stat,.bk-time{grid-column:2;font-size:12px}
  .bk-path{grid-column:2 / -1}
}

/* ============ S3b：抽屉 / 弹窗 / 传输 dock（§8.7–8.10）============ */
/* 关键：hidden 属性必须赢。
   .bk-drawer / .bk-modal-host 都声明了 display:flex，而 [hidden] 的 display:none 来自 UA 样式表，
   作者样式的 display 优先级更高 → hidden 失效 → 抽屉与「半透明遮罩」从页面加载起就常驻，
   表现就是整片内容区发灰、点不动。 */
.bk-drawer[hidden],.bk-modal-host[hidden],.bk-overlay[hidden],.bk-dock[hidden]{display:none!important}
.bk-overlay{position:fixed;inset:0;background:var(--overlay);z-index:var(--z-menu);opacity:0;pointer-events:none;transition:opacity .2s}
.bk-overlay.on{opacity:1;pointer-events:auto}
.bk-drawer{position:fixed;top:0;right:0;bottom:0;width:420px;max-width:100vw;background:var(--surface);border-left:1px solid var(--border);z-index:var(--z-drawer);display:flex;flex-direction:column;transform:translateX(100%);transition:transform .2s ease;box-shadow:var(--shadow-lg)}
.bk-drawer.on{transform:none}
@media(max-width:560px){
  .bk-drawer{top:auto;left:0;width:auto;height:88vh;border-left:none;border-top:1px solid var(--border);border-radius:16px 16px 0 0;transform:translateY(100%)}
  .bk-drawer.on{transform:none}
}
.bk-drawer-head{display:flex;align-items:center;gap:8px;padding:12px 14px;border-bottom:1px solid var(--border);flex:none}
.bk-drawer-title{font-size:15px;font-weight:500;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bk-drawer-body{flex:1;overflow-y:auto;padding:14px}
.bk-drawer-foot{flex:none;padding:12px 14px;border-top:1px solid var(--border);text-align:right}
.bk-kv{display:flex;gap:8px;padding:4px 0;font-size:12px}
.bk-kv-k{color:var(--muted);width:40px;flex:none;white-space:nowrap}
.bk-kv-v{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.bk-kv-a{color:var(--primary-text);cursor:pointer;flex:none;font-size:12px}
/* 可换行内容区：覆盖 .bk-kv-v 的单行省略（否则 chips+输入框被 ellipsis 裁掉） */
.bk-kv-wrap{overflow:visible;text-overflow:clip;white-space:normal;display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.bk-metrics{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-bottom:12px}
.bk-metric{background:var(--surface-2);border-radius:var(--r-sm);padding:8px}
.bk-metric-l{font-size:11px;color:var(--muted)}
.bk-metric-v{font-size:15px;font-weight:500}
.bk-fold{border:1px solid var(--border);border-radius:var(--r);margin-top:10px;overflow:hidden}
.bk-fold-h{display:flex;align-items:center;gap:6px;padding:8px 10px;font-size:13px;cursor:pointer;background:var(--surface-2)}
.bk-fold-b{padding:8px 10px;font-size:12px;border-top:1px solid var(--border)}
.bk-fold-b.hidden{display:none}
.bk-err{display:flex;gap:6px;padding:3px 0;font-size:12px}
.bk-err-msg{color:var(--danger-text)}
.bk-acts{display:flex;gap:6px;flex-wrap:wrap;margin:10px 0}
.bk-modal-host{position:fixed;inset:0;background:var(--overlay);z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;padding:20px}
.bk-modal{background:var(--surface);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);width:100%;max-width:480px;max-height:88vh;overflow:auto}
.bk-modal.wide{max-width:560px}
.bk-modal-h{display:flex;align-items:center;gap:8px;padding:12px 14px;border-bottom:1px solid var(--border)}
.bk-modal-t{font-size:15px;font-weight:500;flex:1;min-width:0}
.bk-modal-b{padding:14px}
.bk-modal-f{display:flex;gap:8px;justify-content:flex-end;padding:12px 14px;border-top:1px solid var(--border)}
.bk-modes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:10px}
.bk-mode{border:1px solid var(--border);border-radius:var(--r-sm);padding:10px;cursor:pointer}
.bk-mode.on{border-color:var(--primary);background:var(--primary-soft)}
.bk-mode-t{font-size:13px;font-weight:500}
.bk-mode-d{font-size:11px;color:var(--muted);margin-top:2px}
.bk-mode-warn{font-size:11px;color:var(--warning-text);margin-top:5px;line-height:1.45}
.bk-mode-hint{font-size:11px;color:var(--muted);margin-top:5px;line-height:1.45}
.bk-mode-note{margin:0 0 12px;padding:7px 10px;border-radius:var(--r-sm);background:var(--warning-soft);color:var(--warning-text);font-size:12px;line-height:1.5}
.bk-mode-hint-box{margin:0 0 12px;padding:7px 10px;border-radius:var(--r-sm);background:var(--surface-2);color:var(--muted);font-size:12px;line-height:1.5}
.bk-pre{display:flex;padding:5px 0;font-size:12px}
.bk-pre-k{width:132px;flex:none;color:var(--muted)}
.bk-pre-v{flex:1;min-width:0}
.bk-arch{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,0.8fr) auto;gap:8px;padding:7px 9px;font-size:12px;align-items:center;border-top:1px solid var(--border)}
.bk-arch:first-child{border-top:none;background:var(--surface-2)}
.bk-dock{position:fixed;left:50%;transform:translateX(-50%);right:auto;width:max-content;max-width:calc(100vw - 24px);bottom:20px;z-index:var(--z-dock);background:var(--surface-translucent);border:1px solid var(--border);border-radius:var(--r);padding:10px 12px;margin-top:12px}
.bk-dock-h{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:500}
.bk-menu{position:absolute;z-index:var(--z-menu);min-width:200px;background:var(--surface);border:0.5px solid var(--border);border-radius:var(--r-sm);box-shadow:var(--shadow-lg);padding:5px;display:flex;flex-direction:column;gap:2px}
.bk-menu button{display:flex;align-items:center;gap:8px;text-align:left;padding:8px 11px;font-size:13px;color:var(--text);background:none;border:0;border-radius:var(--r-sm);cursor:pointer;font-family:inherit}
.bk-menu button:hover{background:var(--surface-2)}
.bk-menu .ic{width:14px;height:14px;flex:none}
.bk-crumb{font-size:12px;color:var(--muted);margin-bottom:10px}
.bk-crumb b{color:var(--text)}
/* S7：手动备份详情页头（此前 bk-head/bk-title 在 JS 里使用但从未定义样式） */
.bk-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.bk-title{font-size:18px;font-weight:500;line-height:1.3}
/* S6：文件页中的备份子树只读提示 */
.bk-readonly{display:flex;align-items:center;gap:8px;margin:0 0 10px;padding:7px 10px;border-radius:var(--r-sm);background:var(--warning-soft);color:var(--warning-text);font-size:12px}
.bk-tag-readonly{background:var(--warning-soft);color:var(--warning-text);border-color:var(--warning-soft)}
.bk-dock-i{display:flex;align-items:center;gap:8px;margin-top:6px;font-size:12px}
.bk-bar{flex:1;height:4px;border-radius:99px;background:var(--border);overflow:hidden}
.bk-bar-i{height:4px;border-radius:99px;background:var(--primary);display:block}

/* U13 触控目标（审计 U13）：移动端可点元素统一 ≥32px（WCAG 2.5.5） */
@media(max-width:900px){
  .mini,.up-cancel,.share-item .rm,.ex-chip button,.pm-state,.pm-chk,.pm-del,.bk-seg,.bk-kv-a,.x{min-width:32px;min-height:32px}
}

/* 备份页视觉对齐文件页：区块内容在 .files-card 内，空状态去掉双层边框（与文件页 emptyState 同款） */
.files-card .bk-empty{border:none;background:none;padding:36px 8px}

/* ==========================================================================
   v120 · 状态语言 + 布局修正（可整块回滚：删除本段即回到 v119）
   依据 UIUX-AUDIT-2026-10-21.md 的 P0-1 / P1-1 / P1-5 / P1-7 / P1-8 / P1-10
   原则：不新增色相。状态靠「图标符号 + 填充样式 + 同色明度 + 常驻文字」承载。
   ========================================================================== */

/* ---- 1. Toast 三态三形状：成功=✓+主色条 / 提示=i+中性条 / 失败=✕+红条 ---- */
.toast{padding:10px 16px 10px 12px;border-left:3px solid var(--border-strong)}
.toast .ic{width:15px;height:15px;flex:none}
.toast.ok{border-left-color:var(--success)}
.toast.ok .ic{color:var(--success)}
.toast.info{border-left-color:var(--border-strong)}
.toast.info .ic{color:var(--muted)}
.toast.err{border-left-color:var(--danger)}
.toast.err .ic{color:var(--danger)}
.toast .dot{display:none} /* 旧版结构兜底：新渲染用 .ic，占位点不再显示 */

/* ---- 2. 开关：关闭=空心轨道+深色滑块 / 开启=实心主色+白滑块+✓ ---- */
.slider{background:transparent;border:1.5px solid var(--border-strong)}
.slider:before{background:var(--muted);box-shadow:0 1px 2px rgba(0,0,0,.16)}
input:checked+.slider{background:var(--primary);border-color:var(--primary)}
input:checked+.slider:before{background:var(--surface)}
input:checked+.slider:after{content:"";position:absolute;left:24px;top:9px;width:9px;height:5px;
  border-left:2px solid var(--primary);border-bottom:2px solid var(--primary);transform:rotate(-45deg)}

/* ---- 3. 勾选框：弃用原生外观（深色下原生=纯白块）---- */
.chk{appearance:none;-webkit-appearance:none;width:18px;height:18px;border:1.5px solid var(--border-strong);
  border-radius:5px;background:var(--surface);cursor:pointer;position:relative;flex:none;transition:border-color .15s,background .15s}
.chk:hover{border-color:var(--primary)}
.chk:checked{background:var(--primary);border-color:var(--primary)}
.chk:checked::after{content:"";position:absolute;left:4px;top:3.5px;width:8px;height:4.5px;
  border-left:2px solid #fff;border-bottom:2px solid #fff;transform:rotate(-45deg)}

/* ---- 4. 键盘焦点环（此前全站无 :focus-visible，深色下靠浏览器黑描边≈不可见）---- */
:focus-visible{outline:2px solid var(--primary);outline-offset:2px;border-radius:inherit}
input:focus-visible,textarea:focus-visible,select:focus-visible{outline:none} /* 已用 3px 光晕替代，避免双环 */

/* ---- 5. 主次按钮：主按钮描边用主色，次按钮保持中性（不加填充面积）---- */
.btn-primary{border:1px solid var(--primary)}
.btn-primary:hover{border-color:var(--primary-text);background:var(--primary-soft)}

/* ---- 6. 图标尺寸：46px 容器里的字形从 11px 提到 22px（占位从 24% → 48%）---- */
#fileGrid .card-ic .ic{width:22px;height:22px}
#fileList .ficon .ic{width:17px;height:17px}

/* ---- 7. 移动端底部：恢复为 Tab 栏预留的 96px（原被 ID 规则压成 24px，遮挡 36px）---- */
@media(max-width:900px){#view-files.container{padding-bottom:calc(24px + 68px)}}

/* ---- 8. 视图宽度：全部铺满（--view-max 保持 :root 的 100%）
   v120 曾给各视图设 1100/1120/920/980/820 上限，实测是"右侧一大片留白"，
   与既有口径（v112 注释：原 max-width:1040 在 1920 下两侧各留 332px，用户反馈"没满页"）冲突。
   v124 全部回退为铺满；长文本可读性改由第 9 节的 72ch 承担，不动容器宽度。 */

/* ---- 9. 说明文字行宽：v124 取消 72ch 限制
   原意是控制长句可读性，但在铺满布局下会让卡片右半边整片空着，观感反而像"没铺满"。
   现改为随容器宽度铺满；若日后觉得单行过长，只对 .sp-note（长段落）单独限制即可。 */

/* ---- 10. 容量告警：灰色 → 同色斜纹（单色体系里最不易误读的“异常”纹理）---- */
.usage-fill.warn{background:repeating-linear-gradient(135deg,var(--warning) 0 4px,var(--primary) 4px 8px)}

/* ---- 11. 备份健康度：形状优先，颜色只做强化 ---- */
.bk-dot{width:9px;height:9px}
.bk-dot-amber{background:transparent;border:2px solid var(--warning);border-top-color:transparent;transform:rotate(45deg);width:10px;height:10px}
.bk-dot-red{box-shadow:0 0 0 3px var(--danger-soft)}
.bk-st{font-size:11px;font-weight:500;margin-right:5px}
.bk-time{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ---- 12. 管理页/运行控制的状态左边框：warning 已有独立明度档，无需再改 ---- */
.ops-hero.warn{border-left-color:var(--warning)}
.bk-hero.stale{border-left-color:var(--warning)}

/* v120 · 存储占用条改为纯总量条（方案①）：分段在单色体系下不传达信息，白缝只造成"细纹"误读 */
.st-bar i{border-right:0}

/* ==========================================================================
   v121 · 交互层修正（可整块回滚）
   依据 UIUX-AUDIT-2026-10-21.md 的 I3 / I6 / M4 / L4（部分）
   ========================================================================== */

/* ---- 1. 复制地址行：code 可横向滚动、按钮不缺位（远程访问页） ---- */
.addr-row{display:flex;align-items:center;gap:8px;margin-top:4px;min-width:0}
.addr-row code{flex:1;min-width:0;overflow-x:auto;white-space:nowrap;padding:5px 8px}
.addr-row .btn-ghost{flex:none;min-width:56px;justify-content:center}

/* ---- 2. 移动端抽屉打开时锁定背景滚动（此前触摸滚动会穿透到下层页面） ---- */
body.side-open{overflow:hidden}

/* ---- 3. 媒体馆网格：大屏给足缩略图（原内联 130px 在 1440 下只占 130px，右侧全空）---- */
#photoGrid{grid-template-columns:repeat(auto-fill,minmax(180px,1fr))!important}
@media(max-width:560px){#photoGrid{grid-template-columns:repeat(auto-fill,minmax(124px,1fr))!important}}

/* ---- 4. 搜索：主搜索框的就地结果面板（不弹模态、不抢焦点）---- */
.toolbar{position:relative}
.search-pop{position:absolute;top:calc(100% + 6px);left:0;z-index:var(--z-menu);
  width:min(420px,calc(100vw - 32px));max-height:52vh;overflow:auto;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  box-shadow:var(--shadow-lg);padding:6px}
.search-pop .share-item{background:transparent;border:0;border-radius:6px;margin:0 0 2px;padding:8px 10px}
.search-pop .share-item:last-child{margin-bottom:0}
.search-pop .share-item:hover{background:var(--surface-2)}
@media(max-width:900px){.search-pop{width:100%;left:0;right:0}}

/* ==========================================================================
   v123 · 批次 C（剩余可见项，可整块回滚）
   依据 UIUX-AUDIT-2026-10-21.md 的 P1-2 / P1-11 / I7 / P2-10
   ========================================================================== */

/* ---- 1. 搜索结果键盘高亮（↑↓ 移动、Enter 打开） ---- */
.search-pop .share-item.on{background:var(--surface-2);box-shadow:inset 2px 0 0 var(--primary)}
.search-pop .share-item:focus-visible{outline-offset:-2px}

/* ---- 2. 动态流日期分组 ---- */
.act-day{font-size:11px;color:var(--muted);padding:12px 2px 6px;border-bottom:1px solid var(--border);margin-bottom:2px}
.act-day:first-child{padding-top:0}

/* ---- 3. 列表视图（窄屏）：操作列加宽，避免 3 个按钮向左挤出压住文件名 ---- */
@media(max-width:640px){
  #fileList th:nth-child(5),#fileList td:nth-child(5){width:100px}
  #fileList .row-acts{gap:2px}
}

/* ==========================================================================
   v125 · 收敛主色滥用（可整块回滚）
   问题：v114 单色化后主色同时承担「品牌/操作/状态/装饰」四种角色，
   运行控制页一屏出现 5 处主色强调（hero 边框+光晕点、徽章紫框、地址框紫框紫底、卡片紫左边框），
   导致强调通胀——什么都强调 = 什么都不强调。
   规则：主色只给「可点击的主操作」和「当前选中项」；状态一律中性 + 小圆点 + 文字。
   ========================================================================== */

/* ---- 1. 运行控制：状态徽章去掉紫框紫字，只留一个小圆点 ---- */
.ops-tag.on{color:var(--text);border-color:var(--border-strong);background:transparent}
.ops-tag.on::before{background:var(--success);opacity:1}

/* ---- 2. 地址框：有内容时不铺紫框紫底（那只是"显示值"，不是可操作强调）---- */
.ops-url-row.active{border-color:var(--border-strong);background:var(--surface)}

/* ---- 3. 子系统卡片：去掉 3px 主色左边框（状态已由徽章+按钮表达）---- */
.sp-card.ops-on{border-left:none}

/* ---- 4. 主服务状态灯：光晕改中性，避免紫色光环扩散 ---- */
.ops-hero.ok .ops-dot{box-shadow:0 0 0 3px var(--surface-2)}
.ops-hero.warn .ops-dot{box-shadow:0 0 0 3px var(--surface-2)}
.ops-hero.err .ops-dot{box-shadow:0 0 0 3px var(--surface-2)}

/* ---- 5. 存储占用条：高度收敛（仅在设了配额时才由 JS 渲染为进度条）---- */
.st-bar{height:6px}

/* v125 · 补：常驻的「正常/成功」态不再上色——颜色只留给异常。
   hero 边框在 ok 时用中性（点仍为主色，作为“活着”的指示），warn/err 才出现色相。 */
.ops-hero.ok{border-left-color:var(--border-strong)}
.bk-hero.ok{border-left-color:var(--border-strong)}

/* v125 · 存储分类图例：从「一行挤在一起」改为栅格，每类独占一格，一眼能数清有几类 */
.st-legend{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:5px 18px;margin-top:8px}
.st-legend span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* v125 · 补：「运行正常」标题不该是紫色（紫色留给主操作），正常态用正文色 */
.ops-hero.ok .ops-hero-title{color:var(--text)}

/* ==========================================================================
   v126 · 工程债收敛
   1) 字号：13 种 → 8 种（11/12/13/14/15/18/20/22），合并 0.5px 档（12.5→12、11.5→11、13.5→13）
      与两处近邻（16→15 弹窗标题、17→18 tab 图标）
   2) 断点：10 个 → 6 个（400/560/640/768/860/900），合并 520→560、720→768、760→768、960→900
      各断点所管辖的选择器无重叠，合并不产生覆盖冲突；上移 40–60px 只会让"窄屏形态"提前触发
   3) 内联：只收敛"逐字重复"的片段（等价替换，零视觉变化），其余一次性布局微调保留
   ========================================================================== */

/* 密码/路径输入框：原本 4 处逐字相同的内联样式 */
.inp-block{width:100%;margin:8px 0;padding:8px 10px;border:1px solid var(--border);border-radius:8px;background:var(--surface);color:var(--text)}

/* 备份抽屉里的小字说明：原本 9 处 class="bk-gray" + 同一段内联 */
.bk-note{margin:8px 0 0;font-size:11px}

/* ==========================================================================
   v127 · 批量操作条改成"浮层卡片"（可整块回滚）
   问题：它是页面上唯一的大块纯黑（--actionbar-bg #1B2230），在浅色卡片体系里极突兀；
   6 个半透明白按钮各自成为一个灰块，视觉噪音大；共享/删除没有图标，和带图标的三个不齐。
   处理：白底 + 描边（用 inset 阴影代替 border，不动尺寸）+ 透明按钮 + 悬停浅底；
        删除用红字表达破坏性；图标补齐。
   ========================================================================== */
.actionbar{background:var(--surface);color:var(--text);box-shadow:var(--shadow-lg),0 0 0 1px var(--border)}
.actionbar .ab-lead{color:var(--muted);white-space:nowrap}
.actionbar .ab-lead .cnt{color:var(--text);font-weight:500;padding:0 2px}
.actionbar button{background:transparent;color:var(--text);border:0;display:inline-flex;align-items:center;gap:5px}
.actionbar button:hover{background:var(--surface-2);color:var(--text)}
.actionbar .x{color:var(--muted)}
.actionbar .x:hover{background:var(--surface-2);color:var(--text)}
/* 破坏性操作只上文字色，不加底色面积 */
#batchDelete{color:var(--danger-text)}
#batchDelete:hover{background:var(--danger-soft);color:var(--danger-text)}

/* v127 · 移动端：操作条只留图标，保证一行放得下（原来 6 个按钮换行后第二行被 Tab 栏遮住，重命名/删除点不到） */
@media(max-width:560px){
  .actionbar{gap:4px;padding:8px 10px}
  .actionbar .ab-lead{font-size:12px}
  .actionbar button{font-size:0;gap:0;padding:9px 10px}
  .actionbar button .ic{width:18px;height:18px}
  .actionbar .x .ic{width:15px;height:15px}
}

/* ==========================================================================
   v128 · 表面层级（方案二）+ 主色降饱和（可整块回滚）
   1) chrome 层：侧栏/顶栏不再复用 --surface（白），改为独立的 --chrome，
      使「框架—画布—卡片」三层可辨（侧栏 vs 内容区 1.14:1 → 1.31:1）。
   2) 主色：#4F46E5（H243 S75% L59%）→ #4B47BE（H242 S48% L51%），降饱和 27 点、
      明度降 8 点，对白对比反而从 6.29 提到 7.13——更沉，但仍清晰，不发灰。
      深色 #6366F1 → #6262CE，hover #818CF8 → #7474DE。
      （注：v131 起主色再改为同蓝系 #2A5C99 / #7FB0E4，本段仅作变更史保留。）
   3) 侧栏联动 6 处：hover / active / 分组标题 / 用量条轨道 / 两条分隔线 / 顶栏透明度。
   注：--surface-2 本轮不动——它同时承担「内嵌块」与「控件底/悬停」两种职责，
      直接改会波及 mini/seg/toggle/crumb/up-bar 等 10+ 处，需单独一轮拆分 --inset。
   ========================================================================== */
:root{
  --chrome:#C2D5EE; --chrome-line:#AEC6E6; --chrome-hover:#B5CBE8; --chrome-active:#E2EBF8;
  --surface-translucent:rgba(255,255,255,.90);
}
[data-theme="dark"]{
  --chrome:#0A1220; --chrome-line:#2A3A5C; --chrome-hover:#121C31; --chrome-active:#18324F;
  --surface-translucent:rgba(22,32,58,.92);
}

/* 侧栏 */
.sidebar{background:var(--chrome);border-right:1px solid var(--chrome-line)}
.side-brand{border-bottom:1px solid var(--chrome-line)}
.side-usage{border-top:1px solid var(--chrome-line)}
.side-link:hover{background:var(--chrome-hover)}
.side-link.active{background:var(--chrome-active);color:var(--primary-text)}
.side-label,.side-usage-tx,.side-foot{color:#4A5A72}
[data-theme="dark"] .side-label,[data-theme="dark"] .side-usage-tx,[data-theme="dark"] .side-foot{color:var(--muted)}
.usage-bar{background:var(--chrome-line)}

/* ==========================================================================
   v129 · 远程访问页地址区去掉填充（可整块回滚）
   问题：这一段借用了 .share-item（共享链接列表组件：--surface-2 填充 + 边框），
   直接坐在画布 #E8F1FB 上，而 --surface-2(#E2ECF9) 与画布只差 1.05:1；
   内层 <code> 又是同一个 --surface-2 —— 两层填充叠在一起，实际效果是一块多余灰板。
   处理：删掉填充与边框，改为「标签 + 等宽地址 + 复制按钮」平铺；
        两组之间靠 18px 间距 + 小号标签区分（不画分隔线——满宽细线右侧留 900px 空区，
        反而成为新的视觉干扰）。长地址允许换行，不横向滚动，不做省略号截断。
   注：不是“忘了上色”，是列表组件用在了非列表场景；.share-item 本身保持不动。
   ========================================================================== */
.addr-block{display:flex;flex-direction:column;margin:2px 0 4px}
.addr-item + .addr-item{margin-top:18px}
.addr-label{font-size:12px;color:var(--muted);margin-bottom:5px}
.addr-row{margin-top:0;justify-content:flex-start}
.addr-row code{flex:0 1 auto;min-width:0;background:transparent;padding:0;font-size:13px;color:var(--text);line-height:1.5;
  white-space:normal;overflow-wrap:anywhere;overflow:visible}
.addr-row .btn-ghost{flex:none;min-width:60px}

/* ==========================================================================
   v130 · 运行控制页地址行去掉填充（可整块回滚）
   问题：.ops-url-row 用 --surface-2 铺底 + 1px 边框，坐在白色 .sp-card 上。
   它只是"显示一个地址"，既不是列表行也不是可操作控件，这块填充不表达任何信息；
   而且 .active 状态（白底）只在 refreshOps 里才被加，其它赋值路径漏掉时就会
   停在有填充的默认态——同一处界面出现两种底色。改法：基态即无填充，
   不再依赖 active 切换底色，状态缺失也不会露馅。
   ========================================================================== */
.ops-url-row{background:transparent;border:0;padding:0;margin-bottom:10px}
.ops-url-row.active{background:transparent;border:0;padding:0}
/* 地址是 <code>，会吃到全局 code 的 --surface-2 底与 6px 内边距——行底色去掉后才露出来，一并归零 */
.ops-url{background:transparent;padding:0;border-radius:0;
  font-size:13px;line-height:1.5;white-space:normal;overflow-wrap:anywhere;overflow:visible;text-overflow:clip}


/* v133 · 按钮型链接去掉浏览器默认下划线（全站唯一一处：运行控制的「下载证书」是 <a download>） */
a.btn-ghost,a.btn-primary,a.btn-danger,a.btn-sm{text-decoration:none}
