:root{
  --accent:#FAAA3C;            /* 选中标签顶条/主强调 */
  --border:#D1D1D1;
  --btn-bg:#E0E0E0;
  --btn-hover-a:#FFFFFF; --btn-hover-b:#E0E0E0;
  --selection:#8A5E21;
  --panel:#EDEDED;
  --panel2:#FFFFFF;
  --text:#111214;
  --text-weak:#757677;
  --hl-row:#FEF1E0;
  --hlw:#FFEB3B;
  --tab-bg:#E6E6E6; --tab-bg-active:#FFFFFF;
  --danger:#C0392B;
  /* 滚动条（自绘）：尺寸固定不可主题化，颜色由 themes.js 按主题写入；这里的颜色只是首屏兜底（= Default 主题） */
  --sb-track:transparent; --sb-thumb:#A8A8A8; --sb-thumb-hover:#808080; --sb-size:12px;
  /* 以下变量由 themes.js 按主题写入 <html> 内联样式；这里的值只是首屏兜底（= Default 主题） */
  --ed-bg:#FFFFFF; --ed-fg:#111214;
  --ed-line-num:#808080; --ed-gutter-bg:#f0f0f0;
  --ed-caret:#111214;
  --ed-selection:rgba(0,204,255,.30);
  --ed-active-line:rgba(17,18,20,.05);
  --ed-fold-fg:#888;
}
*{box-sizing:border-box}
/* 圆角刻度（全局唯一来源，新增样式请对号入座，不要再引入第 5 种取值）：
   0   无缝：菜单栏按钮、表格、编辑器与各视图
   2   输入类与列表项：input/select/textarea、色块、文件列表项、编辑器高亮块
   3   控件：按钮、工具栏图标按钮、菜单项与子菜单面板、toast、快捷键帽
   4   容器：模态对话框 */
html,body{height:100%;margin:0}
body{font:13px/1.45 "Microsoft YaHei","PingFang SC","Noto Sans CJK SC",system-ui,sans-serif;
     color:var(--text);background:var(--panel);overflow:hidden}
button{font:inherit;color:inherit;background:var(--btn-bg);border:1px solid var(--border);
       border-radius:3px;padding:2px 8px;cursor:pointer}
button:hover{background:linear-gradient(180deg,var(--btn-hover-a),var(--btn-hover-b))}
/* 按下时 1px 下移，模拟物理按压（系统开启"减少动态效果"时在文件末尾关掉） */
button:active{transform:translateY(1px)}
button:disabled{opacity:.45;cursor:default}
select,input[type=text],input[type=number],textarea{font:inherit;color:var(--text);
  background:var(--panel2);border:1px solid var(--border);border-radius:2px;padding:2px 4px}
label{user-select:none}

/* ---------- 滚动条：统一自绘，跨平台一致 ----------
   原生滚动条各平台绘制差得远：Windows/Chromium 是常驻槽位且带上下步进箭头，macOS 是 overlay 会在
   停止滚动后淡出，Linux 随 GTK 主题走；同一个页面在三处看起来是三种东西。这里统一自绘：
   颜色由 themes.js 按主题推导后写入 <html> 内联样式（:root 里的只是首屏兜底 = Default 主题），
   粗细固定为 --sb-size，垂直/水平同一套，箭头与交汇方块一律不画。
   分工：Chrome/Edge/Safari 用下面的 ::-webkit-scrollbar 精确绘制；Firefox 不支持该伪元素，
   在紧随其后的 @supports 里退回标准属性。 */
::-webkit-scrollbar{width:var(--sb-size);height:var(--sb-size);background:transparent}
::-webkit-scrollbar-track{background:var(--sb-track)}
/* 滑块用透明边框 + background-clip 内缩：视觉比槽位窄，可拖动的热区仍是整条 */
::-webkit-scrollbar-thumb{background-color:var(--sb-thumb);background-clip:content-box;
  border:2px solid transparent;border-radius:3px}
::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background-color:var(--sb-thumb-hover)}
/* 平台差异最大的两处：步进箭头按钮、垂直与水平的交汇方块，都不画 */
::-webkit-scrollbar-button{display:none}
::-webkit-scrollbar-corner{background:transparent}
/* 编辑区与大文件视口：轨道铺一层编辑区底色，免得下方「不滚动的高亮文本层」从透明槽位里透出来 */
.ed-input::-webkit-scrollbar-track,.bg-viewport::-webkit-scrollbar-track{background:var(--ed-bg)}
/* Firefox 没有 ::-webkit-scrollbar，退回标准属性：颜色同样跟随主题（滑块 / 轨道），
   粗细只有 thin 一档可收窄，hover 态无法自定义 —— 已尽量贴近自绘观感 */
@supports not (selector(::-webkit-scrollbar)){
  *{scrollbar-width:thin;scrollbar-color:var(--sb-thumb) var(--sb-track)}
}
/* 自绘滚动条（js/scrollbar.js）：给内容可能极长的容器兜住滑块的最小可点长度。
   原生滑块按「视口/内容」等比缩，Chromium 又忽略 ::-webkit-scrollbar-thumb 的 min-height
   （实测内容 44 万 px、视口 441px 时仍是 13px），所以这些容器隐藏原生滚动条，
   改用下面这层 overlay 滑块：长度 = max(48px, 视口/内容 × 轨道)。 */
.sb-native-hidden{scrollbar-width:none}
.sb-native-hidden::-webkit-scrollbar{width:0;height:0}
.sb-track{position:absolute;z-index:3}
.sb-track.off{display:none}
.sb-track.sb-v{top:0;right:0;bottom:0;width:var(--sb-size)}
.sb-track.sb-h{left:0;right:0;bottom:0;height:var(--sb-size)}
/* 内缩 2px：视觉宽度 = --sb-size - 4 = 8px，与上面 ::-webkit-scrollbar-thumb 的方案一致 */
.sb-thumb{position:absolute;background-color:var(--sb-thumb);border-radius:3px;touch-action:none}
.sb-track.sb-v .sb-thumb{left:2px;right:2px;top:0}
.sb-track.sb-h .sb-thumb{top:2px;bottom:2px;left:0}
.sb-thumb:hover,.sb-thumb.dragging{background-color:var(--sb-thumb-hover)}
/* 编辑区与大文件视口：overlay 压在内容之上，轨道要铺编辑区底色，免得下面的高亮层从槽位透出来 */
.ed-main .sb-track,.bigview .sb-track{background:var(--ed-bg)}
/* 触屏（安卓/iOS）：轨道不拦事件，整片区域照旧触摸滚动，只有滑块可拖；
   滑块热区往外放大 8px（视觉不变，命中区 8+16 = 24px），手指才按得住 */
.sb-touch .sb-track{pointer-events:none}
.sb-touch .sb-thumb{pointer-events:auto}
.sb-touch .sb-thumb::after{content:"";position:absolute;inset:-8px}
/* 让位（滚动元素让出 --sb-size 宽的槽位，滑块不盖内容）由 js/scrollbar.js 写成内联样式：
   容器普遍带 #id{margin:0} 这类高特异性规则，放在 CSS 类里会被压掉。 */

#app{display:flex;flex-direction:column;height:100vh}

/* ---------- 菜单栏 ---------- */
#topbar{flex:0 0 auto;border-bottom:1px solid var(--border);background:var(--panel)}
#menubar{display:flex;flex-wrap:wrap;min-height:26px;user-select:none}
.menu-root{position:relative}
.menu-root>button.menu-caption{border:0;background:none;border-radius:0;padding:3px 9px}
.menu-root.open>button.menu-caption,.menu-root>button.menu-caption:hover{background:var(--btn-hover-a)}
.dropdown{position:absolute;top:100%;left:0;min-width:210px;max-height:75vh;overflow:auto;
  background:var(--panel2);border:1px solid var(--border);z-index:800;box-shadow:0 4px 12px rgba(38,40,44,.22)}
.menu-root>.dropdown{display:none}
.menu-root.open>.dropdown{display:block}
.dropdown.hidden,.hidden{display:none!important}
.menu-pop{position:fixed;z-index:950;min-width:210px;max-width:80vw;max-height:70vh;overflow:auto;
  background:var(--panel2);border:1px solid var(--border);padding:3px;
  box-shadow:0 6px 18px rgba(38,40,44,.24)}
.mi .sw{display:inline-block;width:15px;height:12px;border:1px solid #999;border-radius:2px;vertical-align:-1px;flex:0 0 auto}
.mi{display:flex;align-items:center;gap:8px;padding:3px 10px;cursor:pointer;white-space:nowrap}
/* 只有「能点的条目」才给 hover 高亮：分隔线与置灰项不该看起来像可选中/可焦点 */
.mi:not(.sep):not(.disabled):hover{background:var(--selection);color:#fff}
.mi .accel{margin-left:auto;color:var(--text-weak);font-size:11px}
.mi:not(.sep):not(.disabled):hover .accel{color:#eee}
/* 分隔线：不可点、不参与 hover（鼠标划过去时上一项的高亮保持不变，与系统菜单一致） */
.mi.sep{border-top:1px solid var(--border);margin:3px 4px;padding:0;cursor:default;pointer-events:none}
.mi.disabled{opacity:.4;cursor:not-allowed}
.iconbt.disabled{opacity:.45;cursor:not-allowed}
.mi .caret{margin-left:6px}

/* ---------- 工具栏 ---------- */
#toolbar{display:flex;align-items:center;gap:2px;padding:3px 6px;border-top:1px solid var(--border);
  background:var(--panel2);min-height:34px;flex-wrap:wrap}
#toolbar .tbsep{width:1px;height:22px;background:var(--border);margin:0 4px}
#toolbar .iconbt{width:28px;height:28px;padding:0;border:0;background:none;border-radius:3px;
  display:inline-flex;align-items:center;justify-content:center;font-size:14px}
#toolbar .iconbt:hover{background:var(--btn-hover-a)}
#toolbar .iconbt.on{background:var(--selection);color:#fff}
#toolbar .iconbt svg{width:20px;height:20px;display:block}

/* ---------- 工作区 ---------- */
#workbench{flex:1;display:flex;min-height:0}
#editorCol{flex:1;display:flex;flex-direction:column;min-width:0;background:var(--panel2)}
#tabbar{display:flex;align-items:center;background:var(--panel);border-bottom:1px solid var(--border);min-height:30px}
#tabstrip{display:flex;overflow-x:auto;flex:1}
.tab{display:inline-flex;align-items:center;gap:5px;padding:3px 8px 3px 10px;cursor:pointer;
  border-right:1px solid var(--border);background:var(--tab-bg);min-width:80px;max-width:220px;
  white-space:nowrap;color:var(--text-weak)}
.tab.active{background:var(--tab-bg-active);color:var(--text);box-shadow:inset 0 3px 0 var(--accent)}
.tab .ttitle{overflow:hidden;text-overflow:ellipsis}
.tab .dirty{color:var(--danger);font-weight:bold}
.tab .tx{margin-left:3px;color:var(--text-weak)}
.tab .tx:hover{color:var(--danger)}
#newTabBt{margin:0 4px;border:0;background:none;font-size:16px}

#editorZone{flex:1;position:relative;min-height:0;background:var(--ed-bg)}
.page{position:absolute;inset:0;display:none;flex-direction:column}
.page.active{display:flex}
.ed-wrap{flex:1;display:flex;min-height:0;position:relative}
.ed-gutter{width:52px;flex:0 0 auto;overflow:hidden;background:var(--ed-gutter-bg);
  border-right:1px solid var(--border);position:relative}
.ed-glines{position:absolute;top:0;left:0;width:100%;padding-top:4px;will-change:transform;
  font-family:ui-monospace,Consolas,Menlo,monospace;font-size:14px;line-height:1.55}
.ln{white-space:pre;text-align:right;padding-right:6px;color:var(--ed-line-num);
    font-family:ui-monospace,Consolas,Menlo,monospace;font-size:inherit;line-height:inherit}
.ln.bm{color:#c0392b;font-weight:bold}
.ln.bm::after{content:"◆";color:#e74c3c;margin-left:4px}
.ed-main{flex:1;position:relative;overflow:hidden;min-width:0}
.ed-mover{position:absolute;top:0;left:0;z-index:1;will-change:transform;transform-origin:0 0}
.ed-rowhl{position:absolute;left:0;top:0;height:21.7px;background:var(--ed-active-line);pointer-events:none}
.ed-hl,.ed-input{margin:0;border:0;outline:none;background:transparent;
  font-family:ui-monospace,Consolas,Menlo,"Courier New",monospace;font-size:14px;line-height:1.55;
  white-space:pre;tab-size:4;overflow-wrap:normal;word-break:normal}
.ed-hl{padding:4px 6px;color:var(--ed-fg);pointer-events:none;white-space:pre}
.ed-hl .c-def{color:var(--ed-fg)}
.ed-hl .c-key{color:var(--tok-key,#0000cc);font-weight:bold}
.ed-hl .c-kw2{color:var(--tok-kw2,#0000cc)}
.ed-hl .c-str{color:var(--tok-str,#cc0000)}
.ed-hl .c-com{color:var(--tok-com,#7f7f7f);font-style:italic}
.ed-hl .c-num{color:var(--tok-num,#0000ff)}
.ed-hl .c-fn{color:var(--tok-fn,#795e26)}
.ed-hl .c-ty{color:var(--tok-ty,#267f99)}
.ed-hl .c-pp{color:var(--tok-pp,#af00db)}
.ed-hl .c-tag{color:var(--tok-tag,#800000)}
.ed-hl .c-attr{color:var(--tok-attr,#e50000)}
.ed-hl .c-meta{color:var(--tok-meta,#800080)}
.ed-hl mark{background:var(--hlw,#FFEB3B);color:inherit;border-radius:2px}
.ed-hl .rowhl{background:var(--ed-active-line);display:block}
.ed-input{position:absolute;inset:0;width:100%;height:100%;resize:none;padding:4px 6px;
  color:transparent;caret-color:var(--ed-caret);z-index:2;background:transparent;overflow:auto}
.ed-input.solid{color:var(--ed-fg)}
.ed-input::selection{background:var(--ed-selection)}
.ed-input:disabled{color:transparent}

/* ---------- 停靠 ---------- */
.dockhead{display:flex;align-items:center;justify-content:space-between;background:var(--panel);
  border-bottom:1px solid var(--border);padding:2px 6px;user-select:none;position:relative}
/* 查找进度：标题右侧一行文字 + 贴在标题栏下沿的 2px 进度条（颜色跟随主题 accent） */
.dockprog{flex:1;margin-left:10px;font-size:12px;color:var(--text-weak);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.dockprogbar{position:absolute;left:0;bottom:-1px;height:2px;width:0;background:var(--accent)}
/* 停靠窗正文：与里层滚动容器等大，自绘滚动条（js/scrollbar.js）以它为定位基准叠滑块。
   不加 overflow，滚动交给里层的 #fileList / #resultView，触摸滚动与键盘翻页都不受影响。 */
.dockbody{flex:1;min-height:0;position:relative;display:flex}
.dockclean{border:0;background:none;font-size:14px;padding:0 6px}
#fileDock{width:230px;flex:0 0 auto;border-left:1px solid var(--border);background:var(--panel2);
  display:flex;flex-direction:column;min-height:0}
#fileDock.hidden,#bottomDock.hidden{display:none}
#fileList{list-style:none;margin:0;padding:2px;overflow:auto;flex:1}
#fileList li{padding:3px 6px;cursor:pointer;border-radius:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#fileList li:hover{background:var(--btn-hover-a)}
#fileList li.cur{background:var(--selection);color:#fff}
#bottomDock{height:170px;flex:0 0 auto;background:var(--panel2);
  display:flex;flex-direction:column}
#dockSplit.dock-split{flex:0 0 auto;height:8px;cursor:row-resize;background:var(--panel);
  border-top:1px solid var(--border);position:relative;z-index:3}
#dockSplit.dock-split:hover,#dockSplit.dock-split.dragging{background:var(--btn-hover-a)}
#resultView{flex:1;overflow:auto;font-family:ui-monospace,Consolas,Menlo,monospace;font-size:12.5px}
.res-sec{font-weight:bold;padding:4px 6px;background:var(--panel);border-bottom:1px solid var(--border);cursor:pointer;user-select:none}
.res-sec:hover{background:var(--btn-hover-a)}
.res-group.collapsed .res-body{display:none}
.res-row{padding:1px 6px;cursor:pointer;white-space:pre}
.res-row:hover{background:var(--btn-hover-a)}
.res-row .lnn{color:var(--text-weak);margin-right:8px}
.res-row .hit{background:var(--selection);color:#fff}

/* ---------- 状态栏 ---------- */
#statusbar{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;
  min-height:24px;background:var(--panel);border-top:1px solid var(--border);padding:0 8px;
  font-size:12px;user-select:none;gap:8px}
.st-msg{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-weak)}
.st-right{display:flex;gap:6px;align-items:center}
.st-cell{min-width:70px;white-space:nowrap;color:var(--text)}
#eolSel{border:0;background:transparent}

/* ---------- 模态 ---------- */
#modalHost{position:fixed;inset:0;z-index:900;pointer-events:none}
#modalHost.show{pointer-events:auto}
.mask{position:absolute;inset:0;background:rgba(20,22,26,.35);display:flex;align-items:center;justify-content:center}
.dialog{background:var(--panel2);border:1px solid var(--border);border-radius:4px;
  min-width:360px;max-width:92vw;max-height:88vh;display:flex;flex-direction:column;box-shadow:0 10px 30px rgba(38,40,44,.26)}
.dialog .dhead{padding:8px 12px;font-weight:bold;background:var(--panel);border-bottom:1px solid var(--border);
  display:flex;justify-content:space-between;align-items:center}
.dialog .dbody{padding:10px 12px;overflow:auto}
.dialog .dfoot{padding:8px 12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid var(--border)}
.dialog table.tbl{border-collapse:collapse;width:100%;font-size:12.5px}
.dialog table.tbl td,.dialog table.tbl th{border:1px solid var(--border);padding:2px 6px;vertical-align:top}
.dialog table.captbl td.capcell,.dialog table.captbl th+th{text-align:center;white-space:nowrap}
.dialog table.captbl td.yes{color:var(--accent);font-weight:bold}
.dialog table.captbl td.no{color:var(--text-weak)}
.dialog h4{margin:10px 0 4px}
.formrow{display:flex;align-items:center;gap:8px;margin:5px 0;flex-wrap:wrap}
.formrow label{min-width:90px}
.findrow{display:flex;gap:6px;margin:6px 0;flex-wrap:wrap}
.findrow input[type=text]{flex:1;min-width:180px}
.optgrid{display:flex;gap:8px;flex-wrap:wrap}

/* ---------- 大文件只读视图 ---------- */
/* 行号列宽的唯一来源：行号 span（以及它在 JS 里对应的横向滚动预留）都读它。
   注意 *{box-sizing:border-box}，所以这里 64px 是「含 padding 的 border box」，
   行号 span 实际占位就是 64px、正文紧接其后；两边同源后不会各写一个数值而互相错位 */
.bigview{--bg-ln-w:64px}
/* 行号栏：每行自带底色与分割线，并用 position:sticky 钉在左侧 ——
   横向滚动查看长行时，行号列必须保持可见（与文本视图 .ed-gutter 的行为一致）。
   1px 线落在本条宽度内（border-box），因此永远在正文左侧 4px 处，不会压到首字符。
   注意：行节点上不能有 overflow:hidden，否则最近裁剪祖先变成行节点、sticky 会失效。 */
.bg-ln{display:inline-block;position:sticky;left:0;z-index:1;
  width:var(--bg-ln-w);padding-right:8px;text-align:right;box-sizing:border-box;
  color:var(--ed-line-num);user-select:none;
  background:var(--ed-gutter-bg);border-right:1px solid var(--border)}

/* ---------- 其它 ---------- */
.hex-view{font-family:ui-monospace,Consolas,Menlo,monospace;font-size:13px;line-height:1.5;
  overflow:auto;flex:1;white-space:pre;padding:6px}
.hexviewer .off{color:var(--text-weak)}
.hexviewer .hb{color:var(--ed-fg)}
.hexviewer .ha{color:var(--text-weak)}
#toasts{position:fixed;bottom:34px;right:10px;z-index:1000;display:flex;flex-direction:column;gap:6px}
.toast{background:var(--panel2);border:1px solid var(--border);border-left:4px solid var(--accent);
  padding:6px 12px;border-radius:3px;box-shadow:0 4px 12px rgba(38,40,44,.26);max-width:420px}
#ctxmenu{position:fixed;z-index:950;background:var(--panel2);border:1px solid var(--border);
  box-shadow:0 6px 16px rgba(38,40,44,.26);min-width:170px;max-height:80vh;overflow:auto;padding:3px}
#ctxmenu .mi{padding:4px 12px}
/* 上面的内边距不能落到分隔线上（否则它会变成一条带内边距的粗条，像可选中项） */
#ctxmenu .mi.sep{padding:0}
/* 键盘导航高亮与 :hover 同款（菜单打开后焦点在 #ctxmenu 上，方向键移动） */
#ctxmenu .mi.kb:not(.sep):not(.disabled){background:var(--selection);color:#fff}
#ctxmenu .mi.kb:not(.sep):not(.disabled) .accel{color:#eee}
.hint{color:var(--text-weak);font-size:12px;margin:2px 0}
.about-head{display:flex;align-items:baseline;gap:10px}
.about-name{font-size:16px;font-weight:bold;color:var(--text)}
.about-ver{font-size:12.5px;color:var(--text-weak)}
.about-desc{margin:6px 0 2px;font-size:12.5px;color:var(--text)}
/* 关于对话框里的仓库地址/联系方式：两行，排在「功能特性」之前；链接用正文色 + 下划线，
   保证在 15 套主题下都达到正文对比度（强调色在浅色底上不足以承担文字） */
.about-meta{font-size:12.5px;line-height:1.7;color:var(--text);margin:1px 0}
.about-meta a{color:var(--text);text-decoration:underline;word-break:break-all}
.about-meta a:hover{background:var(--selection);color:#fff;text-decoration:none;border-radius:2px}
.about-sec{font-weight:bold;font-size:13px;color:var(--text);margin:10px 0 4px}
.about-li{font-size:12.5px;line-height:1.55;color:var(--text);padding-left:13px;position:relative;margin:1px 0}
.about-li::before{content:"•";position:absolute;left:0;color:var(--accent)}
.btn-group button{margin-right:6px}
#fileInput,#dirInput{display:none}

/* 无障碍：系统开启「减少动态效果」时去掉按下位移与任何动效
   （当前仓库没有 transition/animation，这里作为以后新增动效的统一兜底） */
@media (prefers-reduced-motion: reduce){
  *{transition:none !important;animation:none !important}
  button:active{transform:none}
}
