/* web-ui-kit v10：组件共用页面 tokens；日志视图提供查询与维护交互。 */
/* ---- <ui-float-panel>：居中浮窗壳 ---- */
ui-float-panel {
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
  z-index: 55; width: 360px; max-height: calc(100vh - 48px); overflow-y: auto;
  background: var(--card-bg, #fff); border: 1px solid var(--border, #E5E7EB);
  border-radius: 14px; box-shadow: 0 24px 60px rgba(19, 27, 46, .25);
  padding: 16px; display: none;
}
ui-float-panel[open] { display: block; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.panel-title { font-size: 15px; }
.panel-close {
  border: 0; background: transparent; font-size: 18px; line-height: 1;
  color: var(--text-sub, #6B7280); cursor: pointer; padding: 0 2px;
}
.panel-close:hover { color: var(--error, #EF4444); }
/* 内容区通用行/节（浮窗内排版原语，随壳一并分发） */
.panel-section { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border, #E5E7EB); }
.panel-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.panel-row .k { flex: 0 0 64px; color: var(--text-sub, #6B7280); font-size: 12px; }

/* ---- 大表单浮窗（v2）：wide 变量 + .wide 修饰 ----
 * 变量页面可覆盖；.wide 生效时 [open] 转 flex 纵列，内容区配 .panel-scroll
 * 内滚、操作行配 .panel-foot 固定在滚动区外（保存键始终可见）。 */
:root {
  --panel-wide-w: min(760px, calc(100vw - 32px));
  --panel-wide-h: min(620px, calc(100vh - 32px));
}
ui-float-panel.wide { width: var(--panel-wide-w); height: var(--panel-wide-h); }
ui-float-panel.wide[open] { display: flex; flex-direction: column; }
.panel-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.panel-foot {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border, #E5E7EB);
}

/* ---- 通用 action-menu：body 级下拉菜单 ----
 * 菜单元素由 UI.openMenu() 运行期移挂 document.body——transform 祖先
 * （如 ui-float-panel 的 translate）会成为 position:fixed 后代的包含块，
 * 挂在浮窗内的菜单会被带偏；body 级 + fixed 才真正按视口定位。
 * z-index 62（v3 修订）：浮窗(55)与 modal(60) 之上、toast(99) 之下——
 * modal 内字段（编辑表单）的下拉必须盖过 modal 遮罩，57 会把弹层
 * 压在半透明遮罩后面（不可点、视觉变暗）。 */
.action-menu {
  position: fixed; z-index: 62; min-width: 120px;
  background: var(--card-bg, #fff); border: 1px solid var(--border, #E5E7EB);
  border-radius: 10px; box-shadow: 0 12px 32px rgba(19, 27, 46, .18); padding: 6px;
  display: flex; flex-direction: column;
}
.action-menu[hidden] { display: none; }
.menu-item {
  border: 0; background: transparent; text-align: left; padding: 8px 12px;
  border-radius: 6px; color: var(--text-main, #131B2E); font-size: 13px;
}
.menu-item:hover { background: var(--primary-tint, #EEF2FF); color: var(--primary, #2563EB); }
.menu-item.danger { color: var(--error, #EF4444); }
.menu-item.danger:hover { background: var(--error-bg, #FEE2E2); color: #B91C1C; }

/* ---- UI.dropdown（v3）：卡片下拉 ----
 * 按钮/包裹留在原位（页面 CSS 可正常覆盖 .ui-dd-btn）；弹层由 UI.openMenu()
 * 移挂 document.body，层级随 action-menu（z-index 62，modal 之上），
 * 样式覆盖需走 opts.menuClass 附加类（按容器/id 选择器在移挂后失配）。
 * .ui-dd-item.selected 必须在 .menu-item:hover 之后（同特异性，选中态优先）。 */
.ui-dd-source { display: none !important; }
.ui-dd { position: relative; }
.ui-dd-btn {
  width: 100%; height: 40px; padding: 0 12px; display: flex; align-items: center;
  justify-content: space-between; gap: 8px; text-align: left; cursor: pointer;
  border: 1px solid var(--border, #E5E7EB); border-radius: 8px;
  background: var(--card-bg, #fff); color: var(--text-main, #131B2E); font-size: 13px;
}
.ui-dd-btn:hover { border-color: var(--primary-border, rgba(37, 99, 235, .4)); }
.ui-dd-btn:focus {
  border-color: var(--primary, #2563EB);
  box-shadow: 0 0 0 3px var(--primary-ring, rgba(37, 99, 235, .3)); outline: none;
}
.ui-dd-btn .ui-dd-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-dd-btn .ui-dd-caret { color: var(--text-weak, #9CA3AF); font-size: 11px; flex: 0 0 auto; }
.ui-dd-menu { width: 340px; max-height: 340px; overflow-y: auto; }
.ui-dd-group { padding: 8px 12px 4px; font-size: 12px; font-weight: 600; color: var(--text-weak, #9CA3AF); }
.ui-dd-empty { padding: 6px 12px 8px; font-size: 12px; color: var(--text-weak, #9CA3AF); }
.ui-dd-item { padding: 7px 12px; font-size: 13px; }
.ui-dd-item.selected { background: var(--primary-tint, #EEF2FF); color: var(--primary, #2563EB); font-weight: 600; }

/* ---- UI.combo（v3）：建议输入 ----
 * 输入框原样保留（自由输入），外包 ▾ 提示；建议层复用 .ui-dd-menu 条目
 * 体系，默认 220px 窄于 dropdown（预设通常短）。 */
.ui-combo { position: relative; display: block; }
.ui-combo input { padding-right: 28px; }
.ui-combo .ui-combo-caret {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  pointer-events: none; color: var(--text-weak, #9CA3AF); font-size: 11px;
}
.ui-combo-menu { width: 220px; max-height: 264px; overflow-y: auto; }

/* ---- 按钮族（v3）：.btn / .btn-primary / .btn-secondary / .btn-danger / .btn-sm ----
 * 三型：primary=实心主操作，secondary=白底描边次要操作（列表行/工具栏通用），
 * danger=红字描边 destructive；.btn-sm=30px 小尺寸（行内/紧凑区）。
 * 页面直接用类名，无需额外接线；尺寸按需用页面选择器覆盖。 */
.btn {
  height: 40px; padding: 0 18px; border-radius: 8px; font-weight: 600;
  border: 1px solid transparent; display: inline-flex; align-items: center; gap: 6px;
  font-size: 13px; cursor: pointer;
}
.btn-primary { background: var(--primary, #2563EB); color: #fff; }
.btn-primary:hover { background: var(--primary-deep, #004BCA); }
.btn-secondary {
  background: var(--card-bg, #fff); color: var(--text-sub, #6B7280);
  border-color: var(--border, #E5E7EB);
}
.btn-secondary:hover { color: var(--primary, #2563EB); border-color: var(--primary-border, rgba(37, 99, 235, .4)); }
.btn-danger {
  background: var(--card-bg, #fff); color: var(--error, #EF4444);
  border-color: var(--border, #E5E7EB);
}
.btn-danger:hover { border-color: var(--error, #EF4444); }
.btn-sm { height: 30px; padding: 0 10px; font-size: 12px; border-radius: 6px; }
.btn:disabled { opacity: .55; cursor: wait; }

/* ---- <ui-toast>：顶部居中堆叠容器 + 单条样式 ---- */
ui-toast {
  position: fixed; top: 18px; left: 50%; transform: translateX(-50%);
  z-index: 99; display: flex; flex-direction: column; gap: 8px; align-items: center;
  pointer-events: none;
}
ui-toast .toast {
  background: #131B2E; color: #fff; padding: 10px 18px; border-radius: 10px;
  font-size: 13px; box-shadow: 0 12px 32px rgba(19, 27, 46, .28);
  transition: opacity .25s ease; opacity: 1; max-width: calc(100vw - 48px);
}
ui-toast .toast.fade { opacity: 0; }
ui-toast .toast-ok { background: var(--success, #10B981); }
ui-toast .toast-error { background: var(--error, #EF4444); }

/* ---- <ui-lua-editor>（v6）：Lua 源码高亮编辑器 ----
 * overlay 关键：.lua-ed-hl（pre）与 .lua-ed-ta（textarea）同字体/行高/
 * padding/border-radius，textarea 文字透明 caret 可见；pre 不接交互事件，
 * 滚动由组件 JS 以 textarea 为源单向同步。行号栏 .lua-ed-gut 与内容层
 * 同 font/line-height/padding-top（逐行对齐），宽度与内容层 padding-left
 * 由组件 JS 按行数位数设置。token 色：.le-c 注释 / .le-s 字符串 /
 * .le-n 数字 / .le-k 关键字 / .le-ct 常量 / .le-fn 调用名。 */
ui-lua-editor { display: block; }
.lua-ed {
  position: relative; height: 320px; overflow: hidden;
  border: 1px solid var(--border, #E5E7EB); border-radius: 8px;
  background: #0F1729;
}
.lua-ed:focus-within {
  border-color: var(--primary-border, rgba(37, 99, 235, .4));
}
.lua-ed-hl, .lua-ed-ta {
  position: absolute; inset: 0; margin: 0; border: 0; padding: 10px 12px;
  font: 12px/1.55 "Cascadia Mono", Consolas, Menlo, "Courier New", monospace;
  white-space: pre; tab-size: 2; box-sizing: border-box;
}
.lua-ed-hl { overflow: hidden; color: #C7D2E4; pointer-events: none; }
.lua-ed-ta {
  overflow: auto; background: transparent; color: transparent;
  caret-color: #FFFFFF; resize: none; outline: none;
}
.lua-ed-ta::selection { background: rgba(96, 165, 250, .35); }
.lua-ed-ta::placeholder { color: #64748B; }
.le-c  { color: #7C8AA0; font-style: italic; }
.le-s  { color: #7DD3A8; }
.le-n  { color: #F0B86E; }
.le-k  { color: #C084FC; font-weight: 600; }
.le-ct { color: #F87171; }
.le-fn { color: #7CB2F8; }
/* 行号栏（v6）：盖在内容层上方挡住横向滚动溢出，不接交互；宽度 JS 设置 */
.lua-ed-gut {
  position: absolute; top: 0; bottom: 0; left: 0; z-index: 2;
  overflow: hidden; box-sizing: border-box;
  padding: 10px 8px 10px 4px; text-align: right; white-space: pre;
  font: 12px/1.55 "Cascadia Mono", Consolas, Menlo, "Courier New", monospace;
  color: #52627E; background: #0B1220; border-right: 1px solid #1D2A47;
  pointer-events: none; user-select: none;
}
/* 内置查找条（v6）：编辑区右上浮层（Ctrl+F 打开） */
.lua-ed-find {
  position: absolute; top: 8px; right: 14px; z-index: 3;
  display: flex; align-items: center; gap: 4px;
  padding: 5px 6px; border-radius: 8px;
  background: #0B1220; border: 1px solid #24344F;
  box-shadow: 0 8px 24px rgba(2, 6, 18, .5);
}
.lua-ed-find[hidden] { display: none; }
.lua-ed-find input {
  width: 168px; box-sizing: border-box; padding: 4px 8px; border-radius: 6px;
  border: 1px solid #2A3B5C; background: #0F1729; color: #C7D2E4;
  font-size: 12px; outline: none;
}
.lua-ed-find input:focus { border-color: #3B517E; }
.lua-ed-find .le-cnt {
  min-width: 44px; text-align: center; font-size: 11px; color: #7C8AA0;
  white-space: nowrap;
}
.lua-ed-find .le-btn {
  border: 0; background: transparent; color: #93A5C0; cursor: pointer;
  font-size: 12px; line-height: 1; padding: 5px 7px; border-radius: 6px;
}
.lua-ed-find .le-btn:hover { background: #1B2A47; color: #E2E8F0; }
/* 查找匹配高亮（v7）：mark 覆盖默认黄底；零 padding 不破坏双层对齐 */
mark.le-m {
  background: rgba(96, 165, 250, .30); color: inherit;
  padding: 0; border-radius: 2px;
}
mark.le-m-cur {
  background: #F0B86E; color: #10192E; font-weight: 600;
  padding: 0; border-radius: 2px;
}

  ui-log-view { display: block; color: var(--text-main, #131B2E); }
  ui-log-view[hidden] { display: none !important; }
  ui-log-view [hidden] { display: none !important; }
  .ulv-toolbar, .ulv-filters, .ulv-clean-filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
  .ulv-toolbar { padding: 16px; border-bottom: 1px solid var(--border, #E5E7EB); }
  .ulv-toolbar label, .ulv-policy label, .ulv-job-search { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--text-sub, #6B7280); }
  .ulv-toolbar input:not([type="checkbox"]), .ulv-toolbar select, .ulv-policy input[type="number"], .ulv-job-search input {
    height: 34px; max-width: 220px; padding: 0 8px; border: 1px solid var(--border, #E5E7EB); border-radius: 8px;
    background: var(--card-bg, #fff); color: var(--text-main, #131B2E); font: inherit;
  }
  .ulv-toolbar input[type="number"] { width: 100px; }
  .ulv-toolbar .ulv-live { flex-direction: row; align-items: center; align-self: center; }
  .ulv-status, .ulv-notice { margin: 12px 16px; font-size: 13px; color: var(--text-sub, #6B7280); }
  .ulv-notice { padding: 10px; background: var(--warning-bg, #FFFBEB); border-radius: 8px; color: var(--warning, #92400E); }
  .ulv-error { color: var(--error, #B91C1C); }
  .ulv-rows table { min-width: 980px; table-layout: fixed; }
  .ulv-rows td { vertical-align: top; overflow-wrap: anywhere; white-space: pre-wrap; }
  .ulv-message { border: 0; background: transparent; padding: 0; color: var(--primary, #2563EB); cursor: pointer; text-align: left; white-space: pre-wrap; overflow-wrap: anywhere; font: inherit; }
  .ulv-message:focus-visible { outline: 2px solid var(--primary, #2563EB); outline-offset: 3px; }
  .ulv-pager { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; padding: 16px; font-size: 12px; color: var(--text-sub, #6B7280); }
  .ulv-detail { width: min(900px, calc(100vw - 32px)); }
  .ulv-detail pre, .ulv-preview, .ulv-job { white-space: pre-wrap; overflow-wrap: anywhere; font-family: var(--mono, monospace); font-size: 12px; line-height: 1.6; max-height: 55vh; overflow: auto; }
  .ulv-maintenance { padding: 16px; }
  .ulv-maintenance .ulv-toolbar { padding: 0 0 16px; }
  .ulv-maintenance h3 { margin: 24px 0 10px; font-size: 15px; }
  .ulv-storage-head { display: flex; gap: 12px; justify-content: space-between; align-items: center; flex-wrap: wrap; }
  .ulv-storage-note, .ulv-storage-time { color: var(--text-sub, #6B7280); font-size: 12px; line-height: 1.6; }
  .ulv-storage-table { min-width: 1320px; }
  .ulv-storage-table td { white-space: pre-wrap; overflow-wrap: anywhere; }
  .ulv-policy-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; margin-bottom: 12px; }
  .ulv-policy label { flex-direction: row; align-items: center; }
  .ulv-policy input[type="number"] { width: 85px; }
  .ulv-job-search { flex-direction: row; align-items: center; flex-wrap: wrap; }
  .ulv-job, .ulv-preview { background: var(--page-bg, #F9FAFB); border: 1px solid var(--border, #E5E7EB); border-radius: 8px; padding: 12px; }
