/* ============================================================
   EVCC 皮肤编辑器 —— 所有 widget / chart 样式都用 CSS 变量绑定,
   Vue 把 tokens map 写到 .preview-frame 的 style 里, 一改即时生效.
   变量命名和 Android 侧 ColorScheme slot key 一致, 两边字典对齐.
   ============================================================ */

/* -------- 色板 / 预设 -------- */
:root {
  --editor-bg: #0d1117;
  --editor-panel: #161b22;
  --editor-border: #2d333b;
  --editor-text: #c9d1d9;
  --editor-text-dim: #8b949e;
  --editor-accent: #58a6ff;
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0;
  height: 100%; width: 100%;
  background: var(--editor-bg);
  color: var(--editor-text);
  font: 13px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
}
[v-cloak] { display: none; }
button { cursor: pointer; font-family: inherit; }
button:disabled { cursor: not-allowed; opacity: 0.45; }

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

/* -------- Top bar -------- */
.topbar {
  display: flex; align-items: center;
  padding: 10px 16px;
  background: var(--editor-panel);
  border-bottom: 1px solid var(--editor-border);
  gap: 20px;
}
.brand {
  font-weight: 600; font-size: 15px;
  color: var(--editor-text);
}
.mode-tabs {
  display: flex; gap: 8px; align-items: center;
}
.mode-tabs button {
  padding: 6px 14px; border: 1px solid var(--editor-border);
  background: transparent; color: var(--editor-text-dim);
  border-radius: 16px; font-size: 12px;
}
.mode-tabs button.active {
  background: var(--editor-accent); color: #fff; border-color: var(--editor-accent);
}
.actions { margin-left: auto; display: flex; gap: 8px; }
.actions button {
  padding: 6px 12px; border: 1px solid var(--editor-border);
  background: transparent; color: var(--editor-text);
  border-radius: 6px; font-size: 12px;
}
.actions button.primary {
  background: var(--editor-accent); border-color: var(--editor-accent); color: #fff;
}
.actions button.active {
  background: #f59e0b; border-color: #f59e0b; color: #fff;
  animation: pulseActive 1.8s ease-in-out infinite;
}
@keyframes pulseActive {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.6); }
  50% { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0); }
}
.actions button:hover:not(:disabled) { border-color: var(--editor-accent); }

/* 组件选择模式 —— 预览框加描边和十字光标, 鼠标悬停任意组件/子元素时轻微提亮 */
.preview-frame.inspecting {
  outline: 2px dashed #f59e0b;
  outline-offset: -2px;
  cursor: crosshair;
}
.preview-frame.inspecting [data-inspect]:hover,
.preview-frame.inspecting [data-inspect-chart]:hover {
  outline: 2px solid #f59e0b !important;
  outline-offset: 1px;
  cursor: crosshair;
}
/* 限制 hover 只高亮**最内层**有 data-inspect 的元素, 不让外层 card 也一起亮 */
.preview-frame.inspecting [data-inspect]:has([data-inspect]:hover),
.preview-frame.inspecting [data-inspect]:has([data-inspect-chart]:hover),
.preview-frame.inspecting [data-inspect-chart]:has([data-inspect]:hover),
.preview-frame.inspecting [data-inspect-chart]:has([data-inspect-chart]:hover) {
  outline: none !important;
}
.inspect-popup {
  /* 横贯视口顶部的大条 —— 以前 absolute / 小 fixed 都有被裁切或被遮挡的风险, 直接铺满上方保证可见 */
  position: fixed;
  top: 56px; left: 16px; right: 16px;
  max-height: 50vh;
  background: #1a1208;
  border: 3px solid #f59e0b;
  border-radius: 10px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.7), 0 0 0 6px rgba(245, 158, 11, 0.25);
  z-index: 99999;
  display: flex; flex-direction: column;
  overflow: hidden;
  animation: popupFadeIn 0.25s ease-out;
}
@keyframes popupFadeIn {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}
.inspect-popup-head {
  display: flex; align-items: center;
  padding: 14px 18px;
  background: linear-gradient(90deg, rgba(245,158,11,0.6), rgba(245,158,11,0.2));
  font-size: 15px; color: #fff;
  font-weight: 700;
  border-bottom: 1px solid #f59e0b;
}
.inspect-popup-head > span { flex: 1; }
.inspect-popup-head button {
  background: #fff;
  color: #1a1208;
  border: none;
  padding: 6px 14px;
  border-radius: 6px;
  font-weight: bold;
  font-size: 13px;
  cursor: pointer;
}
.inspect-popup-body {
  padding: 14px 18px;
  overflow: auto;
  display: flex; flex-wrap: wrap; gap: 8px;
  background: #2a1e10;
}
.inspect-popup-body .hint {
  width: 100%; color: #ffd98f; font-size: 13px;
  margin: 0 0 4px 0;
}
.inspect-slot-btn {
  padding: 8px 16px;
  background: #f59e0b;
  border: none;
  color: #1a1208;
  border-radius: 8px;
  font-size: 13px; font-weight: 600;
  font-family: "SF Mono", Menlo, monospace;
  cursor: pointer;
  transition: all 0.15s;
  box-shadow: 0 2px 6px rgba(245, 158, 11, 0.4);
}
.inspect-slot-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(245, 158, 11, 0.6);
}
.inspect-slot-btn.chart {
  background: #10b981;
  color: #fff;
  box-shadow: 0 2px 6px rgba(16, 185, 129, 0.4);
}
.inspect-slot-btn.chart:hover {
  box-shadow: 0 4px 12px rgba(16, 185, 129, 0.6);
}

.chk {
  display: flex; align-items: center; gap: 4px;
  font-size: 12px; color: var(--editor-text-dim);
}

/* -------- Main 三栏 -------- */
.main {
  flex: 1; display: grid;
  grid-template-columns: 340px 1fr 360px;
  grid-template-rows: minmax(0, 1fr);
  min-height: 0;
}
.panel {
  overflow: auto;
  min-height: 0;
  background: var(--editor-panel);
  border-right: 1px solid var(--editor-border);
}
.panel-left { min-width: 280px; }
.panel-right {
  border-right: none;
  border-left: 1px solid var(--editor-border);
  display: flex; flex-direction: column;
}
.panel-preview {
  background: #0a0e14;
  border-right: 1px solid var(--editor-border);
  display: flex; flex-direction: column;
  overflow: hidden;
}

/* -------- Tab row -------- */
.tab-row {
  display: flex; gap: 4px;
  padding: 8px 8px 0 8px;
  border-bottom: 1px solid var(--editor-border);
}
.tab-row button {
  flex: 1; padding: 8px 6px;
  background: transparent; color: var(--editor-text-dim);
  border: none; border-bottom: 2px solid transparent;
  font-size: 12px;
}
.tab-row button.active {
  color: var(--editor-accent);
  border-bottom-color: var(--editor-accent);
}

.tab-body {
  padding: 12px 14px;
}

/* -------- Color editor -------- */
.preset-row {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  margin-bottom: 12px;
}
.preset-label { font-size: 11px; color: var(--editor-text-dim); }
.preset-chip {
  padding: 4px 10px; border-radius: 12px;
  border: 1px solid; font-size: 11px;
  position: relative;
  cursor: pointer;
  transition: transform 0.1s;
}
.preset-chip:hover { transform: translateY(-1px); }
.preset-chip.user {
  padding-right: 22px;
}
.preset-chip.user .preset-del {
  position: absolute;
  right: 4px; top: 50%;
  transform: translateY(-50%);
  width: 14px; height: 14px;
  border-radius: 50%;
  background: rgba(0,0,0,0.3);
  color: #fff;
  display: inline-flex;
  align-items: center; justify-content: center;
  font-size: 11px; line-height: 1;
  cursor: pointer;
  opacity: 0.6;
}
.preset-chip.user:hover .preset-del { opacity: 1; }
.preset-chip.preset-save {
  background: transparent !important;
  border: 1px dashed var(--editor-border) !important;
  color: var(--editor-accent) !important;
  font-weight: 600;
}
.cat { margin-bottom: 10px; }
.cat summary {
  cursor: pointer; padding: 6px 0;
  font-size: 12px; font-weight: 500;
  color: var(--editor-text);
  user-select: none;
}
.color-grid { display: grid; gap: 6px; margin-top: 4px; }
.color-row {
  display: grid; grid-template-columns: minmax(0,1fr) 28px 72px 60px 22px;
  gap: 4px; align-items: center;
  font-size: 11px;
  padding: 3px 4px;
  border-radius: 4px;
}
/* 被 inspect jumpToSlot 命中的那一行 —— 橙色背景 + 外描边 + 箭头 tooltip, 6 秒持续可见,
   头 2.4 秒还有额外脉冲动画吸引注意 */
.color-row.focused {
  background: rgba(245, 158, 11, 0.28) !important;
  box-shadow: 0 0 0 2px #f59e0b, 0 4px 16px rgba(245, 158, 11, 0.35) !important;
  position: relative;
  z-index: 2;
  animation: slotPulse 0.6s ease-in-out 0s 4 alternate;
}
/* 原先"👉 就是这里"角标已移除 —— 用户要求直接跳转到色槽, 不要附加提示. */
@keyframes slotPulse {
  0% {
    background: rgba(245, 158, 11, 0.2) !important;
    transform: scale(1);
  }
  100% {
    background: rgba(245, 158, 11, 0.6) !important;
    transform: scale(1.02);
  }
}
.color-row label {
  color: var(--editor-text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* alpha 滑块 —— 背景是棋盘格 + 当前色渐变, 让 0/100% 视觉立即可见 */
.alpha-range {
  -webkit-appearance: none;
  appearance: none;
  height: 16px;
  background:
    linear-gradient(to right, transparent, #fff),
    conic-gradient(#888 25%, #444 0 50%, #888 0 75%, #444 0) 0 0/6px 6px;
  border-radius: 4px;
  border: 1px solid var(--editor-border);
  cursor: pointer;
  margin: 0;
  padding: 0;
}
.alpha-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 10px; height: 14px;
  background: var(--editor-accent); border-radius: 2px;
  border: 1px solid #fff;
  cursor: pointer;
}
.alpha-range::-moz-range-thumb {
  width: 10px; height: 14px;
  background: var(--editor-accent); border-radius: 2px;
  border: 1px solid #fff;
  cursor: pointer;
}
input[type="color"] {
  width: 32px; height: 24px; padding: 0;
  border: 1px solid var(--editor-border);
  background: transparent; border-radius: 4px;
  cursor: pointer;
}
input[type="text"].hex, input[type="text"] {
  background: var(--editor-bg);
  border: 1px solid var(--editor-border);
  border-radius: 4px;
  color: var(--editor-text);
  padding: 4px 6px; font-size: 11px;
  font-family: "SF Mono", Menlo, monospace;
}
.reset-slot, .mini-btn {
  background: transparent; color: var(--editor-text-dim);
  border: 1px solid var(--editor-border);
  border-radius: 4px;
  padding: 2px 6px; font-size: 11px; min-width: 22px;
}
.reset-slot:hover, .mini-btn:hover { color: var(--editor-accent); border-color: var(--editor-accent); }
.mini-btn.add { color: var(--editor-accent); }

/* -------- Slider row (shapes) -------- */
.slider-row {
  margin-bottom: 16px;
  display: grid; grid-template-columns: 1fr 32px;
  gap: 4px 8px; align-items: center;
}
.slider-row label {
  grid-column: 1 / -1;
  font-size: 12px; color: var(--editor-text);
}
.slider-row input[type="range"] { width: 100%; }
.hint {
  font-size: 11px; color: var(--editor-text-dim);
  line-height: 1.6; margin: 8px 0;
}

/* -------- Chart token editor -------- */
.chart-token-row {
  display: grid; grid-template-columns: 1fr 32px 80px 24px;
  gap: 6px; align-items: center;
  margin-bottom: 6px;
  font-size: 11px;
}
.chart-token-row label { color: var(--editor-text-dim); }

.palette-editor { margin-top: 16px; }
.palette-editor > label {
  font-size: 12px; color: var(--editor-text);
  display: block; margin-bottom: 6px;
}
.palette-list {
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
}
.palette-chip {
  display: inline-flex; gap: 2px;
  border: 1px solid var(--editor-border);
  border-radius: 4px; padding: 2px;
}
.palette-chip .mini-btn { padding: 0 4px; border: none; }

/* -------- Meta tab -------- */
.meta-row { margin-bottom: 10px; }
.meta-row label {
  display: block; font-size: 12px; color: var(--editor-text-dim);
  margin-bottom: 4px;
}
.meta-row input[type="text"] { width: 100%; }

/* -------- Preview -------- */
.preview-toolbar {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px;
  background: var(--editor-panel);
  border-bottom: 1px solid var(--editor-border);
}
.preview-mode-tabs { display: flex; gap: 4px; }
.preview-mode-tabs button {
  padding: 5px 12px; border: 1px solid var(--editor-border);
  background: transparent; color: var(--editor-text-dim);
  border-radius: 4px; font-size: 12px;
}
.preview-mode-tabs button.active {
  background: var(--editor-accent); color: #fff;
  border-color: var(--editor-accent);
}
.badge {
  background: rgba(255,255,255,0.2);
  border-radius: 8px; padding: 1px 6px;
  font-size: 10px; margin-left: 4px;
}

.preview-frame {
  flex: 1; overflow: auto;
  padding: 20px;
  /* CSS 变量默认值 — Vue 把实际 token 用 inline style 覆盖到该元素 */
  --backgroundPrimary: #0D1117;
  --backgroundCard: #161B22;
  --backgroundCardElevated: #1C2128;
  --accentCyan: #00D4AA;
  --accentOrange: #FFA726;
  --accentRed: #EF5350;
  --accentGreen: #66BB6A;
  --accentAmber: #FFAB40;
  --textPrimary: #FFFFFF;
  --textSecondary: rgba(255,255,255,0.7);
  --textHint: rgba(255,255,255,0.4);
  --buttonActive: #00BFA5;
  --buttonInactive: #2D333B;
  --buttonTextActive: #0D1117;
  --buttonTextInactive: rgba(255,255,255,0.7);
  --toggleTrackOn: rgba(24,213,182,0.85);
  --toggleTrackOff: #2D333B;
  --toggleThumbOn: #FFFFFF;
  --toggleThumbOff: #8B949E;
  --sliderActive: rgba(24,213,182,0.85);
  --sliderInactive: #2D333B;
  --divider: rgba(255,255,255,0.1);
  --dangerText: #FF6B6B;
  /* 图表 token */
  --chart-ringBg: var(--divider);
  --chart-ringFg: var(--accentCyan);
  --chart-gaugeArc: var(--divider);
  --chart-gaugeNeedle: var(--accentCyan);
  --chart-gaugeTick: var(--textHint);
  --chart-lineStroke: var(--accentCyan);
  --chart-lineFill: var(--accentCyan);
  --chart-lineGrid: var(--divider);
  --chart-barFill: var(--accentCyan);
  --chart-barBg: var(--divider);
  /* shape token */
  --card-radius: 12px;
  --cell-inset: 0px;

  background: var(--backgroundPrimary);
  color: var(--textPrimary);
  transition: background 0.15s;
}

/* -------- Showcase grid -------- */
.showcase-grid {
  display: flex; flex-direction: column; gap: 20px;
  max-width: 980px; margin: 0 auto;
}
.showcase-section {
  background: transparent;
}
.section-header-preview {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 4px; margin-bottom: 4px;
}
.section-bar {
  width: 3px; height: 14px;
  background: var(--accentCyan); border-radius: 1px;
}
.section-title {
  font-size: 13px; font-weight: bold;
  color: var(--textSecondary);
}
.widget-row {
  display: grid; grid-template-columns: repeat(12, 1fr);
  gap: calc(var(--cell-inset) + 4px);
  /* 纵向间距也跟 cell-inset 走 —— 之前写死 6px, 所以滑 cellInsetPx 滑块时只有横向变化 */
  margin-bottom: calc(var(--cell-inset) + 6px);
}
.widget-cell { min-height: 60px; }
.widget-cell.tall { min-height: 140px; }
.span2 { grid-column: span 3; }
.span3 { grid-column: span 3; }
.span6 { grid-column: span 6; }

/* -------- Widget card base --------
   尺寸对齐 Android item_widget_*.xml 的默认值:
     padding horizontal=8dp vertical=6dp (INFO/TOGGLE/DROPDOWN/BUTTON_GROUP)
     padding horizontal=6dp vertical=6dp (BUTTON) / 6dp 4dp (SLIDER) 在具体 class 里再覆盖
   毛玻璃: 当 --card-blur 非 none 时, 启用 backdrop-filter, 配合半透明 backgroundCard 产生毛玻璃质感
*/
.card {
  width: 100%; height: 100%;
  background: var(--backgroundCard);
  border-radius: var(--card-radius);
  padding: calc(6px * var(--card-padding-scale, 1)) calc(8px * var(--card-padding-scale, 1));
  display: flex; flex-direction: column;
  min-height: 60px;
  overflow: hidden;
  border: var(--card-border-width, 0) solid var(--card-border-color, transparent);
  box-shadow: var(--card-elevation, none);
  font-family: "Roboto", "Noto Sans CJK SC", "PingFang SC", sans-serif;
  backdrop-filter: var(--card-blur, none);
  -webkit-backdrop-filter: var(--card-blur, none);
}

/* -------- INFO —— 对应 item_widget_info.xml, 垂直排列 label + (value unit) -------- */
.w-info { justify-content: center; }
.w-info .label {
  font-size: calc(9px * var(--font-scale-mul, 1)); color: var(--textHint);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 1.2;
}
.w-info .value-row {
  display: flex; align-items: flex-end; margin-top: 2px;
}
.w-info .value {
  flex: 1; font-size: calc(18px * var(--font-scale-mul, 1));
  font-weight: bold; color: var(--textPrimary);
  font-feature-settings: "tnum";
  line-height: 1.1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.w-info .unit {
  font-size: calc(9px * var(--font-scale-mul, 1)); color: var(--textHint);
  margin-left: 2px; margin-bottom: 2px; line-height: 1;
}

/* -------- TOGGLE —— item_widget_toggle.xml: horizontal LinearLayout, label 11sp, Switch -------- */
.w-toggle {
  flex-direction: row; align-items: center; gap: 8px;
}
.w-toggle .label {
  flex: 1; font-size: calc(11px * var(--font-scale-mul, 1));
  color: var(--textPrimary); line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Material Switch 大致尺寸: track ≈ 34dp×14dp, thumb ≈ 20dp. 贴近 Android 原生感受. */
.switch {
  width: 34px; height: 14px; border-radius: 7px;
  background: var(--toggleTrackOff); position: relative;
  transition: background 0.2s;
  flex-shrink: 0;
}
.switch.on { background: var(--toggleTrackOn); }
.switch .thumb {
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--toggleThumbOff); position: absolute;
  top: 50%; left: -2px;
  transform: translateY(-50%);
  box-shadow: 0 2px 4px rgba(0,0,0,0.3);
  transition: left 0.2s, background 0.2s;
}
.switch.on .thumb { background: var(--toggleThumbOn); left: 16px; }

/* -------- BUTTON —— item_widget_button.xml: vertical LinearLayout, icon 22sp + label 10sp -------- */
.w-button {
  align-items: center; justify-content: center;
  padding: calc(6px * var(--card-padding-scale, 1));
}
.w-button .btn-icon {
  font-size: calc(22px * var(--font-scale-mul, 1));
  color: var(--accentCyan); line-height: 1;
}
.w-button .btn-label {
  font-size: calc(10px * var(--font-scale-mul, 1));
  color: var(--textPrimary); margin-top: 3px;
  text-align: center; line-height: 1.2;
  max-width: 100%;
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* -------- SLIDER —— item_widget_slider.xml: label 9sp + value 11sp, track 6dp, thumb 18dp -------- */
.w-slider {
  padding: calc(4px * var(--card-padding-scale, 1)) calc(6px * var(--card-padding-scale, 1));
  justify-content: center;
}
.w-slider .slider-top {
  display: flex; align-items: center;
}
.w-slider .label {
  flex: 1; font-size: calc(9px * var(--font-scale-mul, 1));
  color: var(--textHint); line-height: 1.2;
}
.w-slider .value {
  font-size: calc(11px * var(--font-scale-mul, 1));
  font-weight: bold; color: var(--textPrimary); line-height: 1.2;
  font-feature-settings: "tnum";
}
.w-slider .track {
  margin-top: 4px;
  height: 6px; border-radius: 3px;
  background: var(--sliderInactive); position: relative;
}
.w-slider .track .fill {
  position: absolute; top: 0; left: 0; height: 100%;
  background: var(--sliderActive); border-radius: 3px;
}
.w-slider .track .thumb {
  position: absolute; top: 50%; width: 18px; height: 18px;
  border-radius: 50%; background: var(--toggleThumbOn);
  transform: translate(-50%, -50%);
  box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}

/* -------- DROPDOWN —— item_widget_dropdown.xml: label 9sp + value 13sp + arrow 14sp -------- */
.w-dropdown { justify-content: center; }
.w-dropdown .label {
  font-size: calc(9px * var(--font-scale-mul, 1)); color: var(--textHint); line-height: 1.2;
}
.w-dropdown .dd-row {
  display: flex; align-items: center; margin-top: 2px;
}
.w-dropdown .dd-value {
  flex: 1; font-size: calc(13px * var(--font-scale-mul, 1));
  font-weight: bold; color: var(--textPrimary); line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.w-dropdown .dd-arrow {
  font-size: calc(14px * var(--font-scale-mul, 1));
  color: var(--accentCyan); margin-left: 4px; line-height: 1;
}

/* -------- BUTTON GROUP —— item_widget_button_group.xml: label 9sp, dynamic buttons -------- */
.w-bg {
  padding: calc(4px * var(--card-padding-scale, 1)) calc(6px * var(--card-padding-scale, 1));
  justify-content: center;
}
.w-bg .label {
  font-size: calc(9px * var(--font-scale-mul, 1));
  color: var(--textHint); margin-bottom: 3px; line-height: 1.2;
}
.w-bg .bg-opts { display: flex; gap: 3px; }
.w-bg .bg-opts button {
  flex: 1; padding: 4px 0; border-radius: 6px; border: none;
  background: var(--buttonInactive); color: var(--textSecondary);
  font-size: calc(10px * var(--font-scale-mul, 1));
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.w-bg .bg-opts button.active {
  background: var(--accentCyan); color: var(--buttonTextActive); font-weight: bold;
}

/* -------- MUSIC -------- */
.w-music {
  padding: 10px; flex-direction: row; gap: 10px; align-items: center;
}
.w-music .cover {
  width: 48px; height: 48px; border-radius: 6px;
  background: linear-gradient(135deg, var(--accentCyan), var(--accentAmber));
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; color: rgba(0,0,0,0.4);
}
.w-music .mus-info { flex: 1; min-width: 0; }
.w-music .title {
  font-size: calc(12px * var(--font-scale-mul, 1)); color: var(--textPrimary); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.w-music .artist {
  font-size: calc(10px * var(--font-scale-mul, 1)); color: var(--textHint); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.w-music .mus-ctl { display: flex; gap: 6px; margin-top: 4px; }
.w-music .mus-ctl button {
  background: transparent; border: none;
  color: var(--textSecondary); font-size: 14px;
  padding: 0; line-height: 1; cursor: pointer;
}
.w-music .mus-ctl button:hover { color: var(--accentCyan); }
.w-music .progress {
  margin-top: 4px; height: 2px; background: rgba(255,255,255,0.1);
  border-radius: 1px; position: relative;
}
.w-music .progress .pbar {
  position: absolute; top: 0; left: 0; height: 100%;
  background: var(--accentCyan); border-radius: 1px;
}

/* -------- Section header preview as widget -------- */
.w-section {
  background: transparent; padding: 6px 4px 2px 4px;
  flex-direction: row; align-items: center; gap: 6px;
  min-height: 24px;
}
.w-section .sec-bar { width: var(--section-bar-width, 3px); height: 14px; background: var(--accentCyan); border-radius: 1px; }
.w-section .sec-title { font-size: calc(13px * var(--font-scale-mul, 1)); font-weight: bold; color: var(--textSecondary); }

/* showcase section header inside preview */
.section-header-preview .section-bar { width: var(--section-bar-width, 3px); }
.section-header-preview .section-title { font-size: calc(13px * var(--font-scale-mul, 1)); }

/* -------- Charts (SVG) -------- */
.chart-host {
  width: 100%; height: 100%; position: relative;
  display: flex; align-items: center; justify-content: center;
}
.chart-host svg { width: 100%; height: 100%; display: block; }
.chart-host .chart-value {
  position: absolute;
  font-size: 13px; font-weight: bold; color: var(--textPrimary);
  text-align: center; pointer-events: none;
}

/* -------- Real dashboard grid -------- */
.real-grid {
  display: grid; gap: calc(var(--cell-inset) + 4px);
  max-width: 1000px; margin: 0 auto;
}
.real-cell { min-height: 40px; }

/* -------- JSON editor -------- */
.json-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px; border-bottom: 1px solid var(--editor-border);
  font-size: 12px; color: var(--editor-text-dim);
}
.json-editor {
  flex: 1;
  background: var(--editor-bg);
  color: var(--editor-text);
  border: none; outline: none;
  font-family: "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px; line-height: 1.5;
  padding: 10px 12px;
  resize: none;
}
.json-error {
  background: rgba(239,83,80,0.15);
  color: #ff8f8a;
  padding: 8px 12px; font-size: 11px;
  border-top: 1px solid rgba(239,83,80,0.3);
}

/* -------- Status bar -------- */
.statusbar {
  padding: 6px 16px;
  background: var(--editor-panel);
  border-top: 1px solid var(--editor-border);
  font-size: 11px; color: var(--editor-text-dim);
}
.statusbar b { color: var(--editor-text); font-weight: 500; }

/* -------- Shapes tab group title -------- */
.group-title {
  font-size: 11px; color: var(--editor-text-dim);
  text-transform: uppercase; letter-spacing: 0.5px;
  margin: 12px 0 6px 0;
  border-bottom: 1px solid var(--editor-border);
  padding-bottom: 4px;
}
.group-title:first-child { margin-top: 0; }
.preset-chip.active { background: var(--editor-accent); color: #fff; border-color: var(--editor-accent); }

/* -------- Background preset grid -------- */
.bg-preset-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  margin-bottom: 12px;
}
.bg-preset-chip {
  position: relative;
  aspect-ratio: 1.4;
  border-radius: 8px;
  color: rgba(255, 255, 255, 0.95);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  font-size: 11px;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.15s;
}
.bg-preset-chip:hover { transform: translateY(-1px); }
.bg-preset-icon { font-size: 20px; line-height: 1; margin-bottom: 2px; }
.bg-preset-name { font-size: 11px; white-space: nowrap; }

/* -------- Spec modal -------- */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.65); z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.modal {
  background: var(--editor-panel);
  border: 1px solid var(--editor-border);
  border-radius: 8px;
  width: 100%; max-width: 960px;
  max-height: 90vh;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.modal-header {
  padding: 14px 18px;
  display: flex; align-items: center; gap: 12px;
  border-bottom: 1px solid var(--editor-border);
}
.modal-header h2 { margin: 0; font-size: 16px; color: var(--editor-text); flex: 1; }
.modal-header button {
  padding: 6px 12px;
  background: var(--editor-bg);
  border: 1px solid var(--editor-border);
  color: var(--editor-text);
  border-radius: 4px; font-size: 12px;
}
.modal-header button.primary {
  background: var(--editor-accent); border-color: var(--editor-accent); color: #fff;
}
.modal-body {
  flex: 1; overflow: auto;
  padding: 16px 20px;
  font-family: "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px; line-height: 1.6;
  white-space: pre-wrap;
  color: var(--editor-text);
  background: var(--editor-bg);
}
.modal-footer {
  padding: 10px 18px;
  border-top: 1px solid var(--editor-border);
  font-size: 11px; color: var(--editor-text-dim);
}

/* -------- Preview screen tabs -------- */
.preview-screen-tabs { display: flex; gap: 4px; margin-right: 12px; }
.preview-screen-tabs button {
  padding: 5px 10px; border: 1px solid var(--editor-border);
  background: transparent; color: var(--editor-text-dim);
  border-radius: 4px; font-size: 12px;
}
.preview-screen-tabs button.active {
  background: var(--editor-accent); color: #fff; border-color: var(--editor-accent);
}

/* -------- Mock 系统状态栏 + EVCC Tab 栏 —— 所有 preview 界面共用顶部 chrome --------
   scope=mainui 时: `--topbar-base-bg` = transparent → 下层 preview-frame 的背景图/mesh 直接透过来
                   `--topbar-darken` / `--topbar-brighten` 作为"可调增黑/增白蒙层", 让顶栏与正文区产生视觉区分
                   `--topbar-blur` backdrop-filter 毛玻璃, 让背景看起来像有纵深
   scope=console 时: `--topbar-base-bg` = backgroundPrimary (老行为), 其他三个都为 0 / none. */
.mock-statusbar {
  margin: -20px -20px 0 -20px;
  background: linear-gradient(var(--topbar-darken, transparent), var(--topbar-darken, transparent)),
              linear-gradient(var(--topbar-brighten, transparent), var(--topbar-brighten, transparent)),
              var(--topbar-base-bg, var(--statusBar, var(--backgroundPrimary)));
  -webkit-backdrop-filter: var(--topbar-blur, none);
  backdrop-filter: var(--topbar-blur, none);
  color: var(--textPrimary);
  display: flex; align-items: center;
  padding: 4px 14px;
  font-size: 11px;
  font-weight: 500;
  font-feature-settings: "tnum";
  min-height: 22px;
  opacity: 0.95;
}
.mock-status-time { flex: 1; }
.mock-status-right { display: flex; gap: 10px; font-size: 11px; }

.mock-tabbar {
  margin: 0 -20px 16px -20px;
  background: linear-gradient(var(--topbar-darken, transparent), var(--topbar-darken, transparent)),
              linear-gradient(var(--topbar-brighten, transparent), var(--topbar-brighten, transparent)),
              var(--topbar-base-bg, var(--backgroundPrimary));
  -webkit-backdrop-filter: var(--topbar-blur, none);
  backdrop-filter: var(--topbar-blur, none);
  display: flex; align-items: stretch;
  padding: 0 8px;
  border-bottom: 1px solid var(--divider);
  overflow-x: auto;
}
.mock-tab {
  background: transparent;
  border: none;
  padding: 12px 16px 10px;
  font-size: calc(13px * var(--font-scale-mul, 1));
  color: var(--tabUnselected);
  cursor: pointer;
  position: relative;
  white-space: nowrap;
  font-family: inherit;
  transition: color 0.15s;
}
.mock-tab:hover { color: var(--tabSelected); }
.mock-tab.active {
  color: var(--tabSelected);
  font-weight: 600;
}
.mock-tab.active::after {
  content: "";
  position: absolute;
  bottom: 0; left: 10%; right: 10%;
  height: 2px;
  background: var(--tabSelected);
  border-radius: 1px;
}
.mock-tab-action {
  background: transparent;
  border: none;
  padding: 8px 14px;
  font-size: 16px;
  color: var(--accentCyan);
  cursor: pointer;
  align-self: center;
  border-radius: 6px;
  transition: background 0.15s;
}
.mock-tab-action:hover { background: var(--buttonInactive); }
.mock-tab-action.active { background: var(--accentCyan); color: var(--buttonTextActive); }

/* -------- Mock screens (shared styles) -------- */
.mock-settings, .mock-automation, .mock-property, .mock-dialog-host {
  max-width: 600px; margin: 0 auto;
  padding: 16px; color: var(--textPrimary);
  font-family: "Roboto", "Noto Sans CJK SC", "PingFang SC", sans-serif;
}
.mock-title {
  font-size: calc(18px * var(--font-scale-mul, 1));
  font-weight: bold;
  margin-bottom: 16px;
  color: var(--textPrimary);
}
.mock-section {
  background: var(--backgroundCard);
  border-radius: var(--card-radius);
  padding: calc(12px * var(--card-padding-scale, 1));
  margin-bottom: 12px;
  border: var(--card-border-width, 0) solid var(--card-border-color, transparent);
  box-shadow: var(--card-elevation, none);
}
.mock-section-title {
  font-size: calc(11px * var(--font-scale-mul, 1));
  color: var(--textHint);
  text-transform: uppercase; letter-spacing: 0.5px;
  margin-bottom: 8px;
}
.mock-row {
  display: flex; align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--divider);
  font-size: calc(14px * var(--font-scale-mul, 1));
}
.mock-row:last-child { border-bottom: none; }
.mock-row-label { flex: 1; color: var(--textPrimary); }
.mock-row-val { color: var(--textSecondary); font-feature-settings: "tnum"; }
.mock-row-val.accent { color: var(--accentCyan); }
.mock-btn {
  width: 100%;
  padding: 10px;
  background: var(--buttonActive); color: var(--buttonTextActive);
  border: none; border-radius: calc(var(--card-radius) / 2);
  font-size: calc(13px * var(--font-scale-mul, 1));
  font-weight: 500; cursor: pointer;
  margin-top: 8px;
}
.mock-btn.secondary {
  background: var(--buttonInactive); color: var(--buttonTextInactive);
}

/* automation */
.mock-rule {
  background: var(--backgroundCard);
  border-radius: var(--card-radius);
  padding: calc(12px * var(--card-padding-scale, 1));
  margin-bottom: 10px;
  border: var(--card-border-width, 0) solid var(--card-border-color, transparent);
  box-shadow: var(--card-elevation, none);
}
.mock-rule-head {
  display: flex; align-items: center;
  margin-bottom: 6px;
}
.mock-rule-name {
  flex: 1; font-weight: bold;
  font-size: calc(14px * var(--font-scale-mul, 1));
  color: var(--textPrimary);
}
.mock-rule-desc {
  font-size: calc(12px * var(--font-scale-mul, 1));
  color: var(--textSecondary);
  margin-bottom: 6px;
}
.mock-rule-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.mock-chip {
  background: var(--buttonInactive); color: var(--textSecondary);
  padding: 2px 8px; border-radius: 10px;
  font-size: calc(10px * var(--font-scale-mul, 1));
}

/* property */
.mock-search {
  display: flex; align-items: center; gap: 6px;
  background: var(--backgroundCard); padding: 10px 14px;
  border-radius: var(--card-radius); margin-bottom: 12px;
  color: var(--textHint);
  font-size: calc(13px * var(--font-scale-mul, 1));
}
.mock-prop {
  display: flex; align-items: center;
  padding: 10px 14px;
  background: var(--backgroundCard);
  border-radius: var(--card-radius);
  margin-bottom: 6px;
  border: var(--card-border-width, 0) solid var(--card-border-color, transparent);
}
.mock-prop-name {
  font-weight: 500;
  font-size: calc(13px * var(--font-scale-mul, 1));
  color: var(--textPrimary);
}
.mock-prop-id {
  font-size: calc(10px * var(--font-scale-mul, 1));
  color: var(--textHint); font-feature-settings: "tnum";
}
.mock-prop-value {
  margin-left: auto;
  font-weight: bold;
  font-size: calc(14px * var(--font-scale-mul, 1));
  color: var(--accentCyan);
  font-feature-settings: "tnum";
}

/* dialog */
.mock-dialog-host {
  display: flex; align-items: center; justify-content: center;
  min-height: 100%;
  background: var(--overlayScrim, rgba(0,0,0,0.5));
  padding: 40px 20px;
}
.mock-dialog {
  background: var(--backgroundCardElevated);
  border-radius: var(--card-radius);
  padding: 20px;
  width: 100%; max-width: 360px;
  border: var(--card-border-width, 0) solid var(--card-border-color, transparent);
  box-shadow: var(--card-elevation, 0 4px 20px rgba(0,0,0,0.3));
}
.mock-dialog-title {
  font-size: calc(16px * var(--font-scale-mul, 1));
  font-weight: bold;
  color: var(--textPrimary);
  margin-bottom: 12px;
}
.mock-dialog-content { margin-bottom: 12px; }
.mock-dialog-opt {
  display: flex; align-items: center;
  padding: 10px;
  border-radius: calc(var(--card-radius) / 2);
  color: var(--textSecondary);
  font-size: calc(13px * var(--font-scale-mul, 1));
}
.mock-dialog-opt.active {
  background: color-mix(in srgb, var(--accentCyan) 15%, transparent);
  color: var(--accentCyan); font-weight: 500;
}
.mock-dialog-opt .check { margin-left: auto; color: var(--accentCyan); }
.mock-dialog-btns {
  display: flex; gap: 8px; justify-content: flex-end;
}
.mock-dialog-btns .mock-btn { width: auto; padding: 8px 16px; margin: 0; }

/* -------- Widget override panel -------- */
.widget-override-panel {
  position: absolute;
  bottom: 0; right: 0;
  width: 380px; max-width: 45%;
  max-height: 60%;
  background: var(--editor-panel);
  border-top-left-radius: 8px;
  border-left: 1px solid var(--editor-border);
  border-top: 1px solid var(--editor-border);
  box-shadow: -4px -4px 20px rgba(0,0,0,0.4);
  display: flex; flex-direction: column;
  z-index: 50;
}
.wop-head {
  display: flex; align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--editor-border);
  font-size: 12px;
  color: var(--editor-text);
  gap: 8px;
}
.wop-head > span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wop-head small { color: var(--editor-text-dim); }
.wop-body { flex: 1; overflow: auto; padding: 10px 14px; }
.wop-group { margin-bottom: 12px; }
.wop-title {
  font-size: 11px; color: var(--editor-text-dim);
  text-transform: uppercase; letter-spacing: 0.5px;
  margin-bottom: 6px;
  padding-bottom: 3px; border-bottom: 1px solid var(--editor-border);
}

/* preview-frame needs relative positioning for the override panel */
.panel-preview { position: relative; }
