:root { --bg: #1e1e1e; --panel: #252526; --panel-2: #2d2d30; --text: #e6e6e6; --text-dim: #9d9d9d; --accent: #4fc1ff; --border: #3c3c3c; --error: #f14c4c; /* 悬浮层填充与滚动条配色。Eagle 内置 Electron 22 / Chromium 108 不支持 color-mix(), 这些必须写成 rgba(),否则整条颜色声明会被丢弃。 */ --hover-fill: rgba(255, 255, 255, .07); --scroll-thumb: rgba(255, 255, 255, .34); --scroll-thumb-hover: rgba(255, 255, 255, .55); --scroll-thumb-active: rgba(255, 255, 255, .72); --scroll-track: rgba(255, 255, 255, .07); --panel-glass: rgba(37, 37, 38, .92); /* #toolbar / #animationPanel / #timelineBar 底色 */ --active-item-fill: rgb(45, 68, 81); /* .animation-item.active 底色 */ --list-thumb: rgba(157, 157, 157, .58); /* 动画列表滚动条,与预览区各自独立 */ --list-thumb-hover: rgba(157, 157, 157, .82); } [data-theme="light"] { --bg: #f3f4f6; --panel: #ffffff; --panel-2: #f0f0f0; --text: #1f1f1f; --text-dim: #6b6b6b; --accent: #0078d4; --border: #ddd; --error: #d13438; --hover-fill: rgba(0, 0, 0, .06); --scroll-thumb: rgba(0, 0, 0, .30); --scroll-thumb-hover: rgba(0, 0, 0, .46); --scroll-thumb-active: rgba(0, 0, 0, .62); --scroll-track: rgba(0, 0, 0, .06); --panel-glass: rgba(255, 255, 255, .92); --active-item-fill: rgb(204, 228, 246); --list-thumb: rgba(107, 107, 107, .58); --list-thumb-hover: rgba(107, 107, 107, .82); } * { box-sizing: border-box; -webkit-user-select: none; user-select: none; } html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; background: var(--bg); color: var(--text); font-size: 13px; } #app { position: relative; height: 100%; --toolbar-height: 46px; --timeline-height: 68px; } #toolbar { position: absolute; top: 12px; left: 12px; right: 12px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 8px 12px; background: var(--panel-glass); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 5px 18px rgba(0, 0, 0, .25); backdrop-filter: blur(8px); z-index: 10; } #toolbar .spacer { flex: 1; } #toolbar label { color: var(--text-dim); display: flex; align-items: center; gap: 4px; } select, input[type="range"] { background: var(--panel-2); color: var(--text); border: 1px solid var(--border); border-radius: 4px; padding: 4px 6px; } button { background: var(--panel-2); color: var(--text); border: 1px solid var(--border); border-radius: 4px; padding: 5px 10px; cursor: pointer; white-space: nowrap; } button:hover { background: var(--border); } button.active { background: var(--accent); color: #fff; border-color: var(--accent); } button.primary { background: var(--accent); color: #fff; border-color: var(--accent); } button:disabled { cursor: default; opacity: .55; } .thumb-dialog { position: absolute; inset: 0; z-index: 40; display: flex; align-items: center; justify-content: center; padding: 24px; background: rgba(0, 0, 0, .58); } .thumb-dialog.hidden { display: none; } .thumb-dialog-card { width: min(620px, 92vw); max-height: min(680px, 88vh); display: flex; flex-direction: column; gap: 12px; padding: 18px; background: var(--panel); border: 1px solid var(--border); border-radius: 10px; box-shadow: 0 16px 48px rgba(0, 0, 0, .45); } .thumb-dialog-title { font-size: 16px; font-weight: 600; } .thumb-dialog-summary, .thumb-dialog-note { color: var(--text-dim); line-height: 1.5; } .thumb-dialog-list { min-height: 60px; overflow: auto; border: 1px solid var(--border); border-radius: 6px; background: var(--bg); } .thumb-dialog-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-bottom: 1px solid var(--border); } .thumb-dialog-row:last-child { border-bottom: 0; } .thumb-dialog-check { width: 17px; height: 17px; margin: 0; flex: none; accent-color: var(--accent); } .thumb-dialog-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .thumb-dialog-state { flex: none; color: var(--accent); font-size: 12px; } .thumb-dialog-row.skipped .thumb-dialog-name, .thumb-dialog-row.skipped .thumb-dialog-state { color: var(--text-dim); } .thumb-dialog-actions { display: flex; justify-content: flex-end; gap: 8px; } .thumb-dialog-input { background: var(--panel-2); color: var(--text); border: 1px solid var(--border); border-radius: 4px; padding: 7px 9px; } .thumb-dialog-input.hidden { display: none; } .thumb-dialog-error { color: var(--error); min-height: 18px; } /* 收窄下拉,避免在窄窗口下把右侧按钮挤到第二行(展开后的选项不受影响)*/ #toolbar #suffixSelect { max-width: 140px; } #stage { position: absolute; inset: 0; display: flex; overflow: hidden; } #animationPanel { position: absolute; top: calc(22px + var(--toolbar-height)); left: 12px; z-index: 9; width: max-content; min-width: 128px; max-width: min(260px, 34vw); max-height: calc(100% - var(--toolbar-height) - var(--timeline-height) - 56px); display: none; flex-direction: column; overflow: hidden; background: var(--panel-glass); border: 1px solid var(--border); border-radius: 7px; box-shadow: 0 5px 18px rgba(0, 0, 0, .28); backdrop-filter: blur(8px); } #animationPanelTitle { padding: 8px 10px; color: var(--text-dim); font-size: 12px; border-bottom: 1px solid var(--border); flex: none; } #animationList { width: max-content; min-width: 100%; max-width: 100%; min-height: 0; overflow: auto; padding: 5px; scrollbar-width: thin; scrollbar-color: var(--list-thumb) transparent; } #animationList::-webkit-scrollbar { width: 8px; height: 8px; } #animationList::-webkit-scrollbar-track { background: transparent; } #animationList::-webkit-scrollbar-thumb { min-height: 28px; border: 2px solid transparent; border-radius: 999px; background: var(--list-thumb); background-clip: padding-box; } #animationList::-webkit-scrollbar-thumb:hover { background: var(--list-thumb-hover); background-clip: padding-box; } #animationList::-webkit-scrollbar-corner { background: transparent; } .animation-item { display: block; width: 100%; min-width: 116px; max-width: 248px; padding: 6px 8px; margin: 0 0 2px; border: 0; border-radius: 4px; background: transparent; color: var(--text); text-align: left; overflow: hidden; text-overflow: ellipsis; cursor: pointer; } .animation-item:hover { background: var(--panel-2); } .animation-item.active { background: var(--active-item-fill); color: var(--accent); box-shadow: inset 3px 0 0 var(--accent); } #viewport { position: relative; width: 100%; min-width: 0; flex: 1; overflow: hidden; } canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; } #status { position: absolute; bottom: calc(22px + var(--timeline-height)); left: 12px; color: var(--text-dim); font-size: 12px; pointer-events: none; text-shadow: 0 1px 2px rgba(0,0,0,.3); } #timelineBar { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 10; display: flex; align-items: center; gap: 10px; padding: 6px 12px; background: var(--panel-glass); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 -4px 18px rgba(0, 0, 0, .22); backdrop-filter: blur(8px); } #timelineLabels { display: flex; flex-direction: column; justify-content: space-between; align-self: stretch; min-width: 136px; padding: 8px 0 1px; } #timelineBar .tl-label { color: var(--text-dim); font-size: 12px; white-space: nowrap; } #keyframeLegend { display: flex; align-items: center; gap: 6px; color: var(--text-dim); font-size: 11px; white-space: nowrap; cursor: help; } #keyframeLegend::before { content: ''; width: 10px; height: 7px; border-radius: 1px; background: var(--accent); opacity: .7; } #timelineBar .tl-wrap { position: relative; flex: 1; padding-top: 20px; } #timelineBar input[type="range"] { display: block; width: 100%; margin: 0; accent-color: var(--accent); outline: none; box-shadow: none; -webkit-tap-highlight-color: transparent; } #timelineBar input[type="range"]:focus, #timelineBar input[type="range"]:focus-visible { outline: none; box-shadow: none; border-color: var(--border); } #timeRuler { position: absolute; top: 0; left: 7px; right: 7px; height: 19px; } #timeRuler .tick { position: absolute; bottom: 0; width: 1px; height: 5px; background: var(--border); transform: translateX(-.5px); } #timeRuler .tick.major { height: 9px; background: var(--text-dim); } #timeRuler .tick-label { position: absolute; bottom: 8px; color: var(--text-dim); font-size: 10px; font-variant-numeric: tabular-nums; transform: translateX(-50%); white-space: nowrap; } #timeRuler .tick-label.first { transform: none; } #timeRuler .tick-label.last { transform: translateX(-100%); } #keyframes { position: relative; height: 8px; margin-top: 2px; } #keyframes span { position: absolute; top: 0; width: 3px; height: 8px; background: var(--accent); opacity: .62; transform: translateX(-1.5px); cursor: help; transition: opacity .12s, transform .12s; } #keyframes span:hover { opacity: 1; transform: translateX(-1.5px) scaleY(1.35); } #timeLabel { color: var(--text-dim); font-size: 12px; min-width: 178px; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; } #overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: var(--bg); z-index: 5; text-align: center; } #overlay .box { max-width: 520px; padding: 20px; } #overlay .title { font-size: 16px; margin-bottom: 8px; color: var(--error); } #overlay .msg { color: var(--text-dim); white-space: pre-wrap; word-break: break-all; } #overlay.text-preview { align-items: stretch; justify-content: stretch; text-align: left; } #overlay.text-preview .box { width: 100%; max-width: none; padding: 24px; overflow: auto; } #overlay.text-preview .title { color: var(--text); font-size: 13px; font-weight: 600; } #overlay.text-preview .msg { font: 12px/1.6 "SFMono-Regular", Consolas, "Liberation Mono", monospace; color: var(--text-dim); white-space: pre; word-break: normal; } /* 纯文本 / 普通 JSON 预览允许拖动选择与 Ctrl+C 复制;画布与查看器控件仍保持不可选中 */ #overlay.text-preview .title, #overlay.text-preview .msg { -webkit-user-select: text; user-select: text; } #overlay.text-preview .msg { cursor: text; } /* 预览区滚动条:不使用原生样式。宽度 14px、滑块可见 8px,保证看得清。 颜色走 --scroll-* 变量(rgba 写死),不能用 color-mix():Eagle 内置 Chromium 108 不支持该函数,声明会整条失效,滑块就变成看不见。也不要写 scrollbar-width / scrollbar-color,那两个标准属性在 108 上无效且易与 ::-webkit-scrollbar 混淆。 */ #overlay.text-preview .box::-webkit-scrollbar { width: 14px; height: 14px; } #overlay.text-preview .box::-webkit-scrollbar-track { background: var(--scroll-track); } #overlay.text-preview .box::-webkit-scrollbar-thumb { min-height: 36px; border: 3px solid transparent; border-radius: 999px; background: var(--scroll-thumb); background-clip: padding-box; } #overlay.text-preview .box::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: padding-box; } #overlay.text-preview .box::-webkit-scrollbar-thumb:active { background: var(--scroll-thumb-active); background-clip: padding-box; } #overlay.text-preview .box::-webkit-scrollbar-corner { background: transparent; } /* JSON 字段树:折叠标记与计数只用符号 / 数字,无需新增界面文案 */ #overlay.json-preview .msg { white-space: normal; } .jt-node > summary { list-style: none; cursor: pointer; border-radius: 4px; } .jt-node > summary::-webkit-details-marker { display: none; } .jt-node > summary:hover { background: var(--hover-fill); } .jt-node > summary::before { content: '▾'; display: inline-block; width: 14px; color: var(--text-dim); } .jt-node:not([open]) > summary::before { content: '▸'; } .jt-children { margin-left: 7px; padding-left: 11px; border-left: 1px solid var(--border); } .jt-leaf { padding-left: 14px; } .jt-key { color: var(--accent); } .jt-str { color: var(--text); } .jt-brace, .jt-count { color: var(--text-dim); } .jt-count { margin: 0 3px; font-size: 11px; } #overlay.hidden { display: none; } #loading { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 4; background: var(--bg); } #loading.hidden { display: none; } .spinner { width: 34px; height: 34px; border: 3px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } #hideOthers { display: none; }