/* Project console — Visual-Studio-style 3-pane IDE. Builds on app.css brand tokens. */

html, body { height:100%; }
body.ide { margin:0; overflow:hidden; background:#f4f6f8; }
.ide { display:flex; flex-direction:column; height:100vh; }

/* Startup loader overlay */
.boot-overlay { position:fixed; inset:0; z-index:10000; display:flex; align-items:center; justify-content:center;
    background:radial-gradient(1200px 600px at 50% 30%, #16324f 0%, #0d1b2a 60%, #0a1420 100%); transition:opacity .4s ease; }
.boot-overlay.boot-hide { opacity:0; pointer-events:none; }
.boot-card { width:min(440px,82vw); text-align:center; color:#e8eef6; }
.boot-brand { font-weight:800; letter-spacing:1.5px; font-size:24px; margin-bottom:8px; }
.boot-brand span { opacity:.55; font-weight:600; }
.boot-brand i { color:#5b8cff; margin-right:9px; }
.boot-ai { font-size:17px; font-weight:600; letter-spacing:1px; color:#9db8e8; margin-bottom:26px; display:inline-flex; align-items:center; gap:7px; }
.boot-ai i { color:#43d6a0; }
.boot-bar { height:9px; border-radius:6px; background:rgba(255,255,255,.13); overflow:hidden; box-shadow:inset 0 1px 2px rgba(0,0,0,.25); }
.boot-bar-fill { height:100%; width:0; border-radius:6px; background:linear-gradient(90deg,#5b8cff,#43d6a0); transition:width .3s ease; }
.boot-row { display:flex; justify-content:space-between; align-items:center; margin-top:12px; font-size:12.5px; }
.boot-label { color:#9fb6cf; }
.boot-pct { color:#c9d6e6; font-variant-numeric:tabular-nums; font-weight:600; }

.ide-top { display:flex; align-items:center; gap:12px; background:var(--brand); color:#fff; height:46px; padding:0 12px; flex-shrink:0; }
.ide-top .brand { font-weight:800; letter-spacing:.5px; font-size:15px; }
.ide-top .brand span { opacity:.7; font-weight:600; }
.ide-proj { margin-left:6px; }
.ide-proj select { background:rgba(255,255,255,.14); color:#fff; border:1px solid rgba(255,255,255,.25); border-radius:7px; padding:5px 9px; font:inherit; font-size:13px; }
.ide-proj select option { color:#111; }
.edit-badge { background:#16a34a; color:#fff; font-size:11px; font-weight:700; padding:3px 9px; border-radius:999px; }
.preview-btn { margin-left:6px; background:#fff; color:#1e326c; border:0; border-radius:999px; font-size:11px; font-weight:700; padding:4px 11px; cursor:pointer; display:inline-flex; align-items:center; gap:6px; }
.preview-btn:hover { background:#eef2ff; }
.ide-spacer { margin-left:auto; }
.ide-user { display:flex; align-items:center; gap:10px; font-size:13px; }
.ide-user button { background:rgba(255,255,255,.14); color:#fff; border:1px solid rgba(255,255,255,.25); border-radius:7px; padding:5px 10px; cursor:pointer; font:inherit; }
.ide-user button:hover { background:rgba(255,255,255,.25); }

.ide-body { display:flex; flex:1; min-height:0; }
.explorer { width:var(--exp-w,250px); min-width:160px; max-width:640px; background:#fff; border-right:1px solid #e3e7ec; overflow:auto; flex-shrink:0; }
.props { width:var(--props-w,300px); min-width:200px; max-width:720px; background:#fff; border-left:1px solid #e3e7ec; overflow:auto; flex-shrink:0; }
.splitter { flex:0 0 6px; width:6px; cursor:col-resize; background:transparent; position:relative; z-index:5; }
.splitter::before { content:""; position:absolute; top:0; bottom:0; left:2px; width:2px; background:transparent; transition:background .12s; }
.splitter:hover::before, .splitter.dragging::before { background:var(--brand); }
.splitter.dragging { background:rgba(0,0,0,.02); }
body.explorer-collapsed #splitL { display:none; }
body.props-collapsed #splitR { display:none; }
body.col-resizing { cursor:col-resize; user-select:none; }
body.col-resizing iframe { pointer-events:none; }

.nav-btn { background:none; border:0; color:#6b7280; cursor:pointer; padding:3px 6px; border-radius:5px; font-size:12px; }
.nav-btn:hover:not(:disabled) { background:#eef0f3; color:var(--brand); }
.nav-btn:disabled { opacity:.35; cursor:default; }
.pane-collapse { margin-left:auto; background:none; border:0; color:#9aa7b5; cursor:pointer; padding:3px 5px; border-radius:5px; font-size:12px; }
.pane-collapse:hover { background:#eef0f3; color:var(--brand); }

/* Collapsed restore rail (VS-style vertical tab) */
.rail { display:none; width:30px; flex-shrink:0; background:#fff; cursor:pointer; flex-direction:column; align-items:center; gap:10px; padding-top:12px; color:#6b7280; }
.rail:hover { background:#f3f5f8; color:var(--brand); }
.rail span { writing-mode:vertical-rl; text-transform:uppercase; letter-spacing:.6px; font-size:11px; font-weight:700; }
#railL { border-right:1px solid #e3e7ec; }
#railR { border-left:1px solid #e3e7ec; }

@media (min-width:861px) {
    body.explorer-collapsed .explorer { display:none; }
    body.explorer-collapsed #railL { display:flex; }
    body.props-collapsed .props { display:none; }
    body.props-collapsed #railR { display:flex; }
}
.editor { flex:1; min-width:0; display:flex; flex-direction:column; background:#fbfcfd; }

.pane-title { display:flex; align-items:center; font-size:11px; text-transform:uppercase; letter-spacing:.6px; color:#6b7280; font-weight:700;
              padding:8px 8px 8px 12px; border-bottom:1px solid #eef0f3; position:sticky; top:0; background:#fff; z-index:2; }

/* Tree */
.tree { padding:4px 0; user-select:none; }
.node { display:flex; align-items:center; gap:6px; padding:5px 10px; font-size:13.5px; color:#33404f; cursor:pointer; white-space:nowrap; }
.node:hover { background:#f3f5f8; }
.node.cat { font-weight:600; }
.node.sel { background:var(--brand-50); color:var(--brand); }
.node .chev { width:12px; font-size:11px; color:#9aa7b5; transition:transform .12s; }
.node.open > .chev { transform:rotate(90deg); }
.node .ico { width:16px; text-align:center; color:var(--brand); }
.node .count { margin-left:auto; font-size:11px; color:#9aa7b5; background:#eef0f3; border-radius:999px; padding:0 7px; }
.node .add { margin-left:auto; opacity:0; color:#6b7280; padding:0 4px; }
.node.cat:hover .add { opacity:1; }
.children { margin-left:14px; border-left:1px solid #eef0f3; }
.children .node { padding-left:18px; }
.children .ico { color:#7c8aa0; font-size:12px; }
.node.cat.subcat { font-weight:600; font-size:12.5px; color:#475569; }
.node.cat.subcat .ico { color:#94a3b8; }
.empty-node { padding:6px 10px 6px 28px; color:#9aa7b5; font-size:12px; }

/* Context menu */
.ctx { position:fixed; z-index:200; background:#fff; border:1px solid #e3e7ec; border-radius:8px; box-shadow:0 12px 34px rgba(0,0,0,.18); padding:6px; min-width:160px; display:none; }
.ctx.open { display:block; }
.ctx button { display:flex; align-items:center; gap:9px; width:100%; text-align:left; background:none; border:0; font:inherit; font-size:13px; color:#374151; padding:8px 10px; border-radius:6px; cursor:pointer; }
.ctx button:hover { background:#f3f5f8; }
.ctx button.danger { color:#b42318; }
.ctx .sep { height:1px; background:#eef0f3; margin:5px 4px; }

/* Editor */
.editor-tabs { display:flex; align-items:center; gap:2px; padding:8px 10px 0; border-bottom:1px solid #eef0f3; background:#fff; }
.editor-tabs .tab { font-size:13px; font-weight:600; color:#6b7280; padding:8px 14px; border-radius:8px 8px 0 0; cursor:pointer; border:1px solid transparent; border-bottom:none; }
.editor-tabs .tab.active { color:var(--brand); background:#fbfcfd; border-color:#eef0f3; }
.editor-tabs .sp { margin-left:auto; }
.editor-tabs button.act { font:inherit; font-size:13px; font-weight:600; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:6px 12px; cursor:pointer; margin:0 0 8px 6px; display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.editor-tabs button.act:hover:not(:disabled) { background:#f4f6fa; border-color:#d7dde5; }
.editor-tabs button.act.danger { color:#dc2626; border-color:#f1b6b6; }
.editor-tabs button.act.danger:hover:not(:disabled) { background:#fef2f2; border-color:#e79a9a; }
/* Node-help panel action buttons (Functions/VBA/Python group help) */
.nh-actions .act { font:600 13px system-ui,Arial; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:8px; padding:8px 14px; cursor:pointer; display:inline-flex; align-items:center; gap:8px; white-space:nowrap; }
.nh-actions .act:hover { background:#f4f6fa; }
.nh-actions .act.primary { background:linear-gradient(135deg,var(--brand),var(--brand-700)); color:#fff; border-color:transparent; }
.nh-actions .act.primary:hover { filter:brightness(1.06); }
.editor-tabs button.act.primary { background:linear-gradient(135deg,var(--brand),var(--brand-700)); color:#fff; border-color:transparent; }
.editor-main { flex:1; min-height:0; display:flex; flex-direction:column; padding:12px; }
.code { flex:1; width:100%; box-sizing:border-box; resize:none; font-family:ui-monospace,Menlo,Consolas,monospace; font-size:13px;
        border:1px solid #e3e7ec; border-radius:10px; padding:12px; background:#0f1b22; color:#d6e4e2; line-height:1.5; }
.code.light { background:#fff; color:#1f2937; }
/* Syntax-highlighted code editor: a coloured <pre> layer behind a transparent textarea. Both layers
   share identical font/padding/line-height and no-wrap so the caret sits exactly over the text. */
.code-ide { position:relative; flex:1; min-height:0; border:1px solid #e3e7ec; border-radius:10px; overflow:hidden; background:#0f1b22; }
.code-ide .ide-hl, .code-ide .ide-ta { margin:0; padding:12px; font-family:ui-monospace,Menlo,Consolas,monospace; font-size:13px; line-height:1.5; tab-size:2; white-space:pre; word-wrap:normal; border:0; box-sizing:border-box; }
.code-ide .ide-hl { position:absolute; inset:0; overflow:auto; color:#d6e4e2; pointer-events:none; }
.code-ide .ide-hl code { font:inherit; }
.code-ide .ide-ta { position:absolute; inset:0; width:100%; height:100%; resize:none; overflow:auto; background:transparent; color:transparent; caret-color:#e6edf6; outline:none; }
.code-ide .ide-ta::selection { background:rgba(120,160,255,.35); color:transparent; }
/* Token colours (GitHub-dark inspired). */
.ide-hl .t-com  { color:#8b949e; font-style:italic; }
.ide-hl .t-str  { color:#a5d6ff; }
.ide-hl .t-kw   { color:#ff7b72; }
.ide-hl .t-num  { color:#ffcb6b; }
.ide-hl .t-tag  { color:#7ee787; }
.ide-hl .t-attr { color:#79c0ff; }
.ide-hl .t-punc { color:#8b949e; }
.ide-hl .t-prop { color:#79c0ff; }
.ide-hl .t-sel  { color:#d2a8ff; }
.editor-hint { color:#6b7280; font-size:13px; padding:24px; }
.welcome { padding:40px; color:#6b7280; max-width:560px; }
.welcome h2 { color:var(--brand); margin:0 0 8px; }

/* Controls Editor */
#editorContent { flex:1; min-height:0; display:flex; flex-direction:column; }
.ce-toolbar { display:flex; align-items:center; gap:8px; flex-wrap:wrap; padding:8px 10px; border-bottom:1px solid #eef0f3; background:#fff; }
.ce-toolbar .sp { flex:1; }
.ce-title { font-weight:700; color:var(--brand); }
.ce-name { font-weight:600; color:#1f2937; }
.ce-select { padding:6px 10px; border:1px solid #e5e7eb; border-radius:7px; font:inherit; }
.ce-palette { display:flex; gap:6px; flex-wrap:wrap; }
.ce-palette-label, .ce-muted { font-size:12px; color:#9aa7b5; }
.ce-chip { display:inline-flex; align-items:center; gap:6px; padding:5px 10px; border:1px solid #e5e7eb; border-radius:999px; background:#fff; cursor:pointer; font:600 12px system-ui,Arial; color:#374151; }
.ce-chip:hover { border-color:var(--brand); color:var(--brand); }
.ce-toolbar button.act { font:600 13px system-ui,Arial; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:6px 12px; cursor:pointer; }
.ce-toolbar button.act.primary { background:linear-gradient(135deg,var(--brand),var(--brand-700)); color:#fff; border-color:transparent; }
.ce-pane .act { font:600 13px system-ui,Arial; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:6px 12px; cursor:pointer; display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.ce-pane .act:hover { background:#f4f6fa; }
.ce-pane .act.primary { background:linear-gradient(135deg,var(--brand),var(--brand-700)); color:#fff; border-color:transparent; }
.ce-pane .act.primary:hover { filter:brightness(1.06); background:linear-gradient(135deg,var(--brand),var(--brand-700)); }
.ce-grid { display:grid; grid-template-columns:1fr 1fr; grid-template-rows:1fr 1fr; gap:10px; padding:10px; flex:1; min-height:0; }
.ce-grid.one { grid-template-columns:1fr; grid-template-rows:1fr; }
.fn-run-out { margin:0 10px 10px; padding:10px 12px; background:#0f172a; color:#e2e8f0; border-radius:8px; font:12px/1.5 ui-monospace,Menlo,Consolas,monospace; white-space:pre-wrap; max-height:140px; overflow:auto; }
.fn-help { margin:0 14px 12px; border:1px solid #e3e7ec; background:#f8fafc; border-radius:10px; overflow:hidden; }
.fn-help-h { display:flex; align-items:center; gap:7px; padding:8px 12px; font:600 13px system-ui,Arial; color:var(--brand); background:#eef1f8; border-bottom:1px solid #e3e7ec; }
.fn-help-body { padding:10px 12px; color:#475569; font:13.5px/1.5 system-ui,Arial; white-space:pre-wrap; }
.fn-help-exlabel { padding:2px 12px 0; font:700 11px system-ui,Arial; letter-spacing:.03em; text-transform:uppercase; color:#94a3b8; }
.fn-help-ex { margin:6px 12px 12px; background:#0b1220; color:#e5e7eb; border-radius:8px; padding:10px 12px; font:12.5px/1.5 ui-monospace,Menlo,Consolas,monospace; overflow:auto; white-space:pre; }
.ce-side { display:flex; flex-direction:column; min-height:0; gap:8px; }
.ce-side .ce-pane { min-height:0; }
.fn-help-scroll { flex:1; min-height:0; overflow:auto; }
.props-sep { height:1px; background:#e3e7ec; margin:12px 0; }
.ce-pane { display:flex; flex-direction:column; border:1px solid #e5e7eb; border-radius:10px; overflow:hidden; background:#fff; min-height:0; }
.ce-pane-h { font:700 11px system-ui,Arial; letter-spacing:.5px; text-transform:uppercase; color:#6b7280; padding:6px 10px; border-bottom:1px solid #eef0f3; display:flex; align-items:center; gap:8px; }
.ce-code { flex:1; border:none; resize:none; padding:10px; font:13px ui-monospace,Menlo,Consolas,monospace; outline:none; min-height:0; }
.ce-frame { flex:1; border:none; background:#fff; width:100%; }
.ce-refresh { margin-left:auto; border:none; background:none; color:#9aa7b5; cursor:pointer; }
.ce-refresh:hover { color:var(--brand); }
@media (max-width:980px) { .ce-grid { grid-template-columns:1fr; grid-template-rows:none; } .ce-pane { height:220px; } }

/* Page design canvas */
.dz-hint { font:13px system-ui,Arial; color:#6b7280; padding:8px 12px; background:#f8fafc; border-bottom:1px solid #eef0f3; }
.dz-hint i { color:var(--brand); margin-right:6px; }

/* Device view */
.dev-status { max-width:680px; }
.dev-two { display:flex; gap:16px; align-items:stretch; min-height:calc(100vh - 210px); }
.dev-card { background:#fff; border:1px solid #e9edf2; border-radius:12px; padding:16px 18px; overflow:auto; }
.dev-card.dev-left { flex:1 1 33.333%; min-width:0; }
.dev-card.dev-right { flex:2 1 66.667%; min-width:0; }
.dev-card > h3 { margin:0 0 12px; font-size:14px; font-weight:700; color:#111827; display:flex; align-items:center; gap:8px; }
.dev-card > h3 i { color:var(--brand); }
.dev-left .dev-k { width:130px; }
.dev-left code { word-break:break-all; }
.dev-help h4 { margin:18px 0 6px; font-size:12px; font-weight:700; color:#374151; text-transform:uppercase; letter-spacing:.5px; }
.dev-help h4:first-child { margin-top:0; }
.dev-help p { margin:0 0 8px; font-size:13px; color:#4b5563; line-height:1.55; }
.dev-help code { background:#f3f4f6; padding:1px 5px; border-radius:5px; font-size:12px; }
.dev-help table { width:100%; border-collapse:collapse; font-size:12.5px; margin:4px 0 6px; }
.dev-help th, .dev-help td { text-align:left; padding:6px 8px; border-bottom:1px solid #eef0f3; vertical-align:top; }
.dev-help th { color:#6b7280; font-weight:700; }
.dev-help .tagname { font-family:ui-monospace,monospace; color:#0f766e; white-space:nowrap; }
@media (max-width:900px) { .dev-two { flex-direction:column; min-height:0; } }
.dev-row { display:flex; gap:12px; padding:10px 2px; border-bottom:1px solid #eef0f3; }
.dev-k { width:170px; flex:none; color:#6b7280; font-weight:600; font-size:13px; }
.dev-v { flex:1; min-width:0; color:#1f2937; font-size:13.5px; word-break:break-word; }
.dev-v code { background:#f1f3f6; padding:2px 6px; border-radius:5px; font-size:12.5px; }
/* A short explanation beside a status word, so the word does not have to carry the meaning. */
.dev-note { display:block; margin-top:3px; color:#6b7280; font-size:12px; line-height:1.45; max-width:520px; }
.dev-badge { display:inline-block; padding:2px 10px; border-radius:999px; font:700 11px system-ui,Arial; text-transform:uppercase; letter-spacing:.4px; }
.dev-badge.on { background:#dcfce7; color:#16a34a; }
.dev-badge.off { background:#f1f3f6; color:#9aa7b5; }
.dev-token { display:flex; align-items:center; gap:8px; }
.dev-token code { flex:1; word-break:break-all; }
.dev-token .act { flex:none; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:6px 9px; cursor:pointer; }
.dev-tbl { width:100%; border-collapse:collapse; font-size:13.5px; }
.rt-sum { font-size:12px; color:#6b7280; padding:0 2px 10px; }
.rt-sum b { color:#1f2937; font-size:13.5px; }
.dev-tbl th { text-align:left; color:#6b7280; font-size:11px; text-transform:uppercase; letter-spacing:.4px; padding:8px 10px; border-bottom:1px solid #e3e7ec; }
.dev-tbl td { padding:8px 10px; border-bottom:1px solid #eef0f3; color:#1f2937; }
.editor-tabs .act { font:600 13px system-ui,Arial; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:5px 11px; cursor:pointer; }
.dev-sub { margin:18px 0 8px; font:700 11px system-ui,Arial; text-transform:uppercase; letter-spacing:.5px; color:#9aa7b5; }
.tl-status { display:flex; gap:18px; flex-wrap:wrap; padding:10px 12px; margin-bottom:12px; background:#f5f7fa; border:1px solid #e3e7ec; border-radius:8px; font:13px system-ui,Arial; color:#374151; }
.tl-status b { color:#1f2937; }
.view-toggle { display:inline-flex; border:1px solid #e5e7eb; border-radius:7px; overflow:hidden; }
.view-toggle .vt { border:none; background:#fff; color:#6b7280; padding:6px 11px; cursor:pointer; font-size:13px; }
.view-toggle .vt + .vt { border-left:1px solid #e5e7eb; }
.view-toggle .vt.on { background:var(--brand); color:#fff; }
.cv-search { display:inline-flex; align-items:center; gap:6px; border:1px solid #e5e7eb; border-radius:7px; background:#fff; padding:0 8px; margin:0 8px 8px 0; height:31px; transition:border-color .15s,box-shadow .15s; }
.cv-search:focus-within { border-color:var(--brand); box-shadow:0 0 0 3px rgba(30,50,108,.10); }
.cv-search > i { color:#9aa7b5; font-size:12px; }
.cv-search input { border:none; outline:none; background:transparent; font:inherit; font-size:13px; color:#374151; width:180px; padding:5px 0; }
.cv-search input::placeholder { color:#9aa7b5; }
.cv-search button { border:none; background:transparent; color:#9aa7b5; cursor:pointer; padding:2px 4px; font-size:12px; border-radius:5px; display:flex; align-items:center; }
.cv-search button:hover { color:#ef4444; background:#f3f4f6; }
.cv-list { display:flex; flex-direction:column; }
.cv-row { display:flex; align-items:center; gap:10px; padding:9px 10px; border-bottom:1px solid #eef0f3; cursor:pointer; border-radius:6px; }
.cv-row:hover { background:#f5f7fa; }
.cv-row .ico { color:var(--brand); width:18px; text-align:center; }
.cv-row .nm { font:14px system-ui,Arial; color:#1f2937; }
.cv-row .sb { margin-left:auto; color:#9aa7b5; font-size:12px; }
.cv-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(110px,1fr)); gap:12px; }
.cv-grid.large { grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); }
.cv-tile { display:flex; flex-direction:column; align-items:center; gap:8px; padding:16px 10px; border:1px solid #e3e7ec; border-radius:10px; cursor:pointer; text-align:center; background:#fff; }
.cv-tile:hover { border-color:var(--brand); box-shadow:0 2px 8px rgba(30,50,108,.08); }
.ctrlgrid { grid-template-columns:repeat(auto-fill,minmax(132px,1fr)); }
.ctrlgrid.large { grid-template-columns:repeat(auto-fill,minmax(176px,1fr)); }
.ctrltile { padding:10px; gap:8px; }
.ctrltile .ctrl-prev { position:relative; width:100%; height:84px; background:#f6f8fb; border:1px solid #eef0f3; border-radius:8px; overflow:hidden; }
.ctrlgrid.large .ctrltile .ctrl-prev { height:118px; }
.ctrltile .ctrl-prev iframe { position:absolute; top:0; left:0; width:100%; height:100%; border:0; pointer-events:none; background:transparent; }
.ctrltile .nm { font:13px system-ui,Arial; color:#1f2937; line-height:1.2; word-break:break-word; }
.cv-tile .ico { font-size:28px; color:var(--brand); }
.cv-grid.large .cv-tile .ico { font-size:42px; }
.cv-tile .nm { font:13px system-ui,Arial; color:#1f2937; word-break:break-word; }
.cv-tile .sb { font-size:11px; color:#9aa7b5; }
.dev-addcmd { display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.dev-addcmd input, .dev-addcmd select { border:1px solid #e5e7eb; border-radius:7px; padding:6px 9px; font:13px system-ui,Arial; }
.dev-tbl input, .dev-tbl select { border:1px solid #e5e7eb; border-radius:6px; padding:5px 8px; font:13px system-ui,Arial; width:100%; box-sizing:border-box; }
.dev-tbl td .act, .dev-status .act { cursor:pointer; }
/* A toggle sitting in a crowded toolbar must not be squeezed: without this the buttons
   shrink until the icon wraps onto a line of its own under the label. */
/* Matched to .editor-tabs button.act in EVERY box property, not just padding. That button
   carries margin:0 0 8px 6px, and in a flex row with align-items:center a bottom margin lifts
   the box - so a toggle without it centres 4px lower than the buttons either side of it. */
.editor-tabs .view-toggle { flex:none; margin:0 0 8px 6px; align-self:center; }
.editor-tabs .view-toggle .vt { padding:6px 12px; font:600 13px system-ui,Arial; }
.editor-tabs .view-toggle .vt:hover:not(.on) { background:#f3f5f8; color:#374151; }
/* Emptying a table is destructive: it should not look like Export. */
.editor-tabs .act.danger { color:#b91c1c; border-color:#f0d0d0; }
.editor-tabs .act.danger:hover { background:#fef2f2; border-color:#e5b4b4; }
.editor-tabs .view-toggle .vt { display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
/* The meters filter row. .cv-search carries an 8px bottom margin for the layouts it was built
   for, which lifts it above anything centred beside it; it is zeroed here and the two controls
   are given the same height so they read as one row. */
.wm-bar { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:10px; }
.wm-bar .cv-search { margin:0; height:29px; }
.wm-bar .view-toggle .vt { padding:6px 12px; }

/* Runtime tab, meters view. A meter row carries its identity, its signal, its readings and its
   raw frame, so the table is wide by nature: cells never wrap, and the wrapper scrolls sideways
   rather than squeezing every column to nothing. Columns that are empty on every row are
   dropped by the renderer, which is what usually brings it back inside the pane. */
.wm-wrap { border:1px solid #e3e7ec; border-radius:8px; overflow:auto; background:#fff; }
.wm-wrap::-webkit-scrollbar { height:9px; width:9px; }
.wm-wrap::-webkit-scrollbar-thumb { background:#cbd5e1; border-radius:6px; }
.wm-wrap::-webkit-scrollbar-thumb:hover { background:#94a3b8; }
.wm-wrap::-webkit-scrollbar-track { background:transparent; }

.wm-mtbl { font-size:12.5px; white-space:nowrap; }
.wm-mtbl th, .wm-mtbl td { padding:6px 10px; }
.wm-mtbl td { vertical-align:middle; border-bottom:1px solid #f1f3f6; }
/* Sticky, so the column names stay put while a long list is scrolled. */
.wm-mtbl thead th { position:sticky; top:0; z-index:1; background:#f7f9fc; border-bottom:1px solid #e3e7ec; }
.wm-mtbl tbody tr:last-child td { border-bottom:0; }
.wm-mtbl tbody tr:nth-child(even) { background:#fcfdfe; }
.wm-mtbl tbody tr:hover { background:#f3f7fd; }
.wm-mtbl .wm-num { text-align:right; font-variant-numeric:tabular-nums; }
.wm-mtbl .wm-mono { font-family:ui-monospace,"Cascadia Mono",Consolas,monospace; font-size:11px; color:#64748b; letter-spacing:-.2px; }
.wm-mtbl .wm-bad { color:#b91c1c; }
.wm-mtbl .wm-warn { color:#b45309; }
/* A blank cell reads as an oversight; a dash reads as "nothing to show". */
.wm-mtbl .wm-dash { color:#c3cad4; }
/* Short verdicts as badges, so they read at a glance in a row of numbers. */
.wm-mtbl .wm-pill { display:inline-block; padding:1px 8px; border-radius:999px; font-size:11px; font-weight:600;
                    background:#f1f3f6; color:#6b7280; }
.wm-mtbl .wm-pill-warn { background:#fef3c7; color:#92400e; }
/* A row opens in place. The detail is not squeezed into the table's column widths, so the long
   values - the problem text and the raw frame - are readable without scrolling sideways. */
.wm-mtbl tbody tr.wm-row { cursor:pointer; }
.wm-mtbl tbody tr.wm-row.open { background:#eef4fd; }
.wm-mtbl tbody tr.wm-row.open td { border-bottom-color:transparent; font-weight:600; }
.wm-mtbl tbody tr.wm-detail:hover { background:transparent; }
.wm-mtbl tbody tr.wm-detail > td { padding:0; background:#f7f9fc; white-space:normal; }
/* Pinned to the left edge of the visible pane and sized to it, so an open row is readable
   whatever the table's own width is. Without this the detail sat inside a cell as wide as the
   table and its last column was cut off by exactly the scroll the detail exists to avoid. */
.wm-detail-in { padding:12px 14px 14px; border-top:1px solid #e3e7ec;
                position:sticky; left:0; box-sizing:border-box; width:var(--wm-pane, 100%); }
/* Wide enough that a timestamp and "Frames with a problem" both sit on one line. */
.wm-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(310px,1fr)); gap:3px 18px; }
/* Label and value ride together in one grid cell, so the pairs line up down each column
   however many of them there are. */
.wm-pair { display:flex; gap:10px; align-items:baseline; padding:2px 0; min-width:0; }
.wm-pair .wm-dt { color:#6b7280; font-size:12px; flex:0 0 118px; }
.wm-pair .wm-dd { color:#1f2937; font-size:12.5px; min-width:0; word-break:break-word; }
.wm-sec { margin:12px 0 5px; font:700 10.5px system-ui,Arial; text-transform:uppercase; letter-spacing:.5px; color:#9aa7b5; }
.wm-pre { background:#fff; border:1px solid #e3e7ec; border-radius:6px; padding:8px 10px; font-size:12px;
          white-space:pre-wrap; word-break:break-word; line-height:1.5; }
.wm-pre.wm-mono { font-family:ui-monospace,"Cascadia Mono",Consolas,monospace; font-size:11px; color:#4b5563; }
.wm-rec { border-collapse:collapse; background:#fff; border:1px solid #e3e7ec; border-radius:6px; }
.wm-rec th { text-align:left; font:600 11px system-ui,Arial; color:#6b7280; padding:5px 10px; border-bottom:1px solid #e3e7ec; }
.wm-rec td { padding:5px 10px; font-size:12.5px; border-top:1px solid #f1f3f6; }

/* Clipped rather than wrapped: the full value is on the cell's tooltip, and whole in the CSV.
   The raw frame is reference data and gets the narrowest allowance of the three. */
.wm-mtbl .wm-clip { max-width:210px; overflow:hidden; text-overflow:ellipsis; }
.wm-mtbl td.wm-mono.wm-clip { max-width:130px; }
.dz-canvas-wrap { flex:1; min-width:0; overflow:auto; padding:16px; background:#f1f3f6; }
/* user-select:none so marquee/multi-select dragging never paints the browser's native blue
   selection highlight over the control overlays/labels. The canvas has no selectable text. */
.dz-canvas { position:relative; min-height:600px; background:#fff; border:1px solid #e3e7ec; border-radius:8px; user-select:none; -webkit-user-select:none; }
.dz-grid { position:absolute; inset:0; pointer-events:none; z-index:0; border-radius:8px; }
.dz-item { position:absolute; border:1px solid transparent; border-radius:6px; box-sizing:border-box; z-index:1; }
.dz-item.sel { border-color:var(--brand); box-shadow:0 0 0 3px rgba(30,50,108,.14); }
.dz-frame { width:100%; height:100%; border:0; background:transparent; pointer-events:none; border-radius:6px; }
.dz-overlay { position:absolute; inset:0; cursor:move; }
.dz-label { position:absolute; top:-18px; left:0; font:600 10px system-ui,Arial; color:var(--brand); background:#fff; padding:1px 5px; border-radius:5px 5px 0 0; opacity:0; white-space:nowrap; }
.dz-item:hover .dz-label, .dz-item.sel .dz-label { opacity:1; }
.dz-del { position:absolute; top:-10px; right:-10px; width:20px; height:20px; border:none; border-radius:50%; background:#ef4444; color:#fff; cursor:pointer; font-size:11px; line-height:20px; padding:0; display:none; }
.dz-item:hover .dz-del, .dz-item.sel .dz-del { display:block; }
.dz-resize { position:absolute; right:-4px; bottom:-4px; width:12px; height:12px; border:2px solid var(--brand); background:#fff; border-radius:3px; cursor:nwse-resize; display:none; }
.dz-item:hover .dz-resize, .dz-item.sel .dz-resize { display:block; }
.dz-item.sel { border-color:var(--brand); box-shadow:0 0 0 3px rgba(30,50,108,.14); }
.dz-item.primary { box-shadow:0 0 0 3px rgba(30,50,108,.30); }
.dz-toolbar { display:flex; align-items:center; gap:4px; padding:6px 10px; background:#f8fafc; border-bottom:1px solid #eef0f3; flex-wrap:wrap; }
.dz-tbtn { display:inline-flex; align-items:center; gap:5px; height:28px; padding:0 9px; border:1px solid #d7dde5; background:#fff; border-radius:7px; cursor:pointer; color:#374151; font:13px system-ui,Arial; }
.dz-tbtn:hover { border-color:var(--brand); color:var(--brand); }
.dz-tlabel { font-size:12px; color:#6b7280; margin:0 4px 0 2px; }
.dz-sep { width:1px; height:20px; background:#e3e7ec; margin:0 5px; }
.dz-selinfo { font-size:12px; font-weight:600; color:var(--brand); }
.dz-rotinfo { font-size:12px; font-weight:600; color:#374151; min-width:34px; text-align:center; font-variant-numeric:tabular-nums; }
.dz-tip { font-size:11px; color:#9aa7b5; }
/* Layers */
.dz-layers { display:inline-flex; align-items:center; gap:4px; }
.dz-layer-sel { height:28px; max-width:180px; padding:0 8px; border:1px solid #d7dde5; background:#fff; border-radius:7px; color:#374151; font:13px system-ui,Arial; cursor:pointer; }
.dz-layer-sel:focus { outline:none; border-color:var(--brand); }
.dz-layer-eye { width:32px; padding:0; justify-content:center; }
.dz-layer-lock { width:32px; padding:0; justify-content:center; }
.dz-layer-lock.on { border-color:#e0a90b; color:#b45309; background:#fffbeb; }
/* Locked controls on the canvas: visible but inert, with a corner lock badge. */
.dz-item.dz-locked { outline:1px dashed rgba(180,83,9,.5); outline-offset:0; }
.dz-lockbadge { position:absolute; top:-9px; left:-9px; width:18px; height:18px; border-radius:50%; background:#b45309; color:#fff; display:flex; align-items:center; justify-content:center; font-size:9px; box-shadow:0 1px 3px rgba(0,0,0,.3); z-index:2; }
.dz-layer-panel { position:fixed; z-index:9999; background:#fff; border:1px solid #e3e7ec; border-radius:11px; box-shadow:0 18px 44px rgba(0,0,0,.18); padding:10px; width:308px; }
.dz-layer-panel .lp-head { font:700 12px system-ui,Arial; color:#1f2937; display:flex; align-items:center; justify-content:space-between; margin:0 2px 8px; }
.dz-layer-panel .lp-hint { font:500 10.5px system-ui,Arial; color:#9aa7b5; text-transform:none; letter-spacing:0; }
.dz-layer-panel .lp-list { display:flex; flex-direction:column; gap:4px; max-height:300px; overflow:auto; }
.lp-row { display:flex; align-items:center; gap:5px; padding:5px 6px; border:1px solid #eef0f3; border-radius:8px; background:#fbfcfe; cursor:pointer; }
.lp-row:hover { border-color:#dce2ea; }
.lp-row.active { border-color:var(--brand); background:#eef1f8; box-shadow:inset 0 0 0 1px rgba(30,50,108,.15); }
.lp-row .lp-name { flex:1; min-width:0; height:26px; padding:0 7px; border:1px solid transparent; background:transparent; border-radius:6px; font:13px system-ui,Arial; color:#1f2937; }
.lp-row .lp-name:focus { outline:none; border-color:var(--brand); background:#fff; }
.lp-row .lp-count { font:600 11px system-ui,Arial; color:#6b7280; min-width:18px; text-align:center; }
.lp-eye, .lp-btn { width:26px; height:26px; flex:none; display:inline-flex; align-items:center; justify-content:center; border:1px solid #d7dde5; background:#fff; border-radius:6px; color:#374151; cursor:pointer; font-size:12px; }
.lp-eye:hover, .lp-btn:hover:not(:disabled) { border-color:var(--brand); color:var(--brand); }
.lp-btn:disabled { opacity:.35; cursor:default; }
.lp-del:hover:not(:disabled) { border-color:#f3b4b4; color:#b91c1c; }
.lp-lock.on { border-color:#e0a90b; color:#b45309; background:#fffbeb; }
.dz-layer-panel .lp-add { margin-top:8px; width:100%; height:32px; display:inline-flex; align-items:center; justify-content:center; gap:7px; border:1px dashed #cdd5df; background:#fff; border-radius:8px; color:var(--brand); font:600 13px system-ui,Arial; cursor:pointer; }
.dz-layer-panel .lp-add:hover:not(:disabled) { background:#f5f7fb; border-color:var(--brand); }
.dz-layer-panel .lp-add:disabled { opacity:.45; cursor:default; }
.dz-layer-panel .lp-tip { margin-top:8px; font-size:11px; color:#9aa7b5; line-height:1.4; }
.dz-zoom { position:relative; }
.dz-zoom-menu { position:absolute; top:32px; left:0; z-index:30; background:#fff; border:1px solid #e3e7ec; border-radius:9px; box-shadow:0 14px 36px rgba(0,0,0,.16); padding:6px; min-width:190px; }
.dz-zoom-menu button { display:flex; align-items:center; gap:9px; width:100%; text-align:left; background:none; border:0; font:13px system-ui,Arial; color:#374151; padding:8px 10px; border-radius:6px; cursor:pointer; }
.dz-zoom-menu button:hover { background:#f3f5f8; color:var(--brand); }
.dz-zoom-menu button i { width:16px; text-align:center; color:var(--brand); }
.dz-marquee { position:absolute; z-index:5; border:1px solid var(--brand); background:rgba(30,50,108,.10); pointer-events:none; border-radius:2px; }
.dz-sizer { position:relative; }
.ctx-menu { position:fixed; z-index:9999; background:#fff; border:1px solid #e3e7ec; border-radius:10px; box-shadow:0 16px 40px rgba(0,0,0,.18); padding:6px; min-width:210px; }
.ctx-item { display:flex; align-items:center; gap:10px; width:100%; text-align:left; background:none; border:0; font:13px system-ui,Arial; color:#374151; padding:8px 10px; border-radius:7px; cursor:pointer; }
.ctx-item:hover { background:#f3f5f8; color:var(--brand); }
.ctx-item:disabled { color:#c2c8d0; cursor:default; }
.ctx-item:disabled:hover { background:none; color:#c2c8d0; }
.ctx-item i { width:16px; text-align:center; color:var(--brand); }
.ctx-item:disabled i { color:#c2c8d0; }
.ctx-item span { flex:1; }
.ctx-item kbd { font:11px ui-monospace,Menlo,Consolas,monospace; color:#9aa7b5; background:#f3f5f8; border:1px solid #e3e7ec; border-radius:5px; padding:1px 6px; }
.ctx-item.danger { color:#b91c1c; } .ctx-item.danger i { color:#b91c1c; }
.ctx-item.danger:hover { background:#fdecec; color:#b91c1c; }
.ctx-sep { height:1px; background:#eef0f3; margin:5px 4px; }
.mp-align-row { display:flex; gap:5px; flex-wrap:wrap; }
.mp-align { width:30px; height:30px; border:1px solid #d7dde5; background:#fff; border-radius:7px; cursor:pointer; color:#374151; }
.mp-align:hover { border-color:var(--brand); color:var(--brand); }
.preview-frame { flex:1; width:100%; border:1px solid #e3e7ec; border-radius:10px; background:#fff; }

/* Properties */
.props-body { padding:10px 12px; }
.prop { margin-bottom:11px; }
.prop label { display:block; font-size:12px; font-weight:600; color:#6b7280; margin-bottom:5px; }
.prop input, .prop select, .prop textarea { width:100%; box-sizing:border-box; padding:8px 10px; border:1.5px solid #e5e7eb; border-radius:7px; font:inherit; font-size:13.5px; background:#f9fafb; }
.prop input:focus, .prop select:focus, .prop textarea:focus { outline:none; border-color:var(--brand); background:#fff; }
.prop input[readonly] { background:#f1f3f6; color:#6b7280; }
.prop input[type=color] { height:38px; padding:3px; cursor:pointer; }
.img-field { display:flex; gap:6px; align-items:center; }
.img-field input[type=text], .img-field > input:not([type]) { flex:1; }
.img-up { flex:none; border:1.5px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:8px 10px; cursor:pointer; }
.img-up:hover { border-color:var(--brand); color:var(--brand); }
.img-thumb { margin-top:8px; max-width:100%; max-height:90px; border:1px solid #e5e7eb; border-radius:7px; object-fit:cover; }
.props-sub { font:700 11px system-ui,Arial; letter-spacing:.4px; text-transform:uppercase; color:#9aa7b5; margin:6px 0 8px; padding-top:8px; border-top:1px solid #eef0f3; }
.props-sub:first-of-type { border-top:none; padding-top:0; }
/* Grouped-control property tree: one collapsible node per member control. */
.grp-member { border:1px solid #e7ebf0; border-radius:8px; margin-bottom:8px; background:#fbfcfe; overflow:hidden; }
.grp-member > summary { list-style:none; cursor:pointer; display:flex; align-items:center; gap:8px; padding:9px 11px; font-size:13px; font-weight:700; color:#374151; background:#f3f6fb; user-select:none; }
.grp-member > summary::-webkit-details-marker { display:none; }
.grp-member > summary::before { content:"\f054"; font-family:"Font Awesome 6 Free"; font-weight:900; font-size:10px; color:#9aa7b5; transition:transform .15s; }
.grp-member[open] > summary::before { transform:rotate(90deg); }
.grp-member > summary i.fa-cube { color:var(--brand); font-size:12px; }
.grp-member > summary:hover { background:#eef2f8; }
.grp-member-name { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.grp-count { font-weight:600; font-size:11px; color:#9aa7b5; background:#fff; border:1px solid #e5e7eb; border-radius:10px; padding:1px 7px; }
.grp-member-body { padding:11px 11px 3px; border-top:1px solid #eef0f3; }
.grp-member-body .prop:last-child { margin-bottom:8px; }
.grp-sec { font:700 10px system-ui,Arial; letter-spacing:.4px; text-transform:uppercase; color:#9aa7b5; margin:4px 0 7px; padding-top:7px; border-top:1px dashed #e7ebf0; }
.grp-sec:first-child { border-top:none; padding-top:0; }
.prop-actions { display:flex; gap:1px; margin-left:auto; }
.prop-actions button { border:none; background:none; color:#9aa7b5; cursor:pointer; padding:3px 6px; border-radius:5px; font-size:12.5px; }
.prop-actions button:hover:not(:disabled) { background:#eef0f3; color:var(--brand); }
.prop-actions button:disabled { opacity:.35; cursor:default; }
.prop-actions + .pane-collapse { margin-left:6px; }
/* Properties panel: keep the fold/unfold button first (leftmost) so it stays visible even when
   the panel is narrowed. `order` moves it visually without changing the left panel's collapse. */
#collapseR { order:-1; margin-left:0; margin-right:8px; flex:none; }
.props .rtabs { order:0; }
.props .prop-actions { order:0; }
/* When the Properties panel is narrowed, let the header items wrap to the next line instead of
   overflowing/clipping — so the tabs and action buttons stay reachable at any width. */
.props .pane-title { flex-wrap:wrap; row-gap:6px; }
.rtabs { display:flex; gap:2px; }
.rtab { border:none; background:none; font:700 11px system-ui,Arial; letter-spacing:.3px; text-transform:uppercase; color:#9aa7b5; cursor:pointer; padding:4px 7px; border-radius:6px; }
.rtab.active { color:var(--brand); background:#eef1f8; }
.rtab:hover:not(.active) { color:#6b7280; }
.ev-row { margin-bottom:15px; }
.ev-name { font:700 13px system-ui,Arial; color:#1f2937; }
.ev-desc { font-size:12px; color:#9aa7b5; margin:2px 0 6px; }
.ev-row select { width:100%; box-sizing:border-box; padding:8px 10px; border:1.5px solid #e5e7eb; border-radius:7px; font:inherit; font-size:13.5px; background:#f9fafb; }
.ev-row select:focus { outline:none; border-color:var(--brand); background:#fff; }
.ev-props { margin:-7px 0 16px; padding:10px 12px; background:#f8fafc; border:1px solid #eef0f3; border-left:3px solid var(--brand); border-radius:0 8px 8px 0; }
.ev-props .prop { margin-bottom:9px; }
.ev-props .prop:last-child { margin-bottom:0; }
.ev-props label { font-size:12px; color:#6b7280; }
.btn-danger { border:1px solid #fecaca !important; background:#fff !important; color:#dc2626 !important; }
.btn-danger:hover { background:#fef2f2 !important; }

/* Top Menu items editor */
.mn-editor { display:flex; flex-direction:column; gap:4px; }
.mn-node { display:flex; flex-direction:column; gap:4px; }
.mn-row { display:flex; align-items:center; gap:4px; padding:4px; border:1px solid #eef0f3; border-radius:8px; background:#fbfcfe; }
.mn-row .mn-label { flex:1 1 60px; min-width:52px; height:28px; padding:0 7px; border:1.5px solid #e5e7eb; border-radius:6px; font:13px system-ui,Arial; background:#fff; }
.mn-row .mn-page { flex:1 1 74px; min-width:64px; height:28px; padding:0 4px; border:1.5px solid #e5e7eb; border-radius:6px; font:12px system-ui,Arial; background:#fff; }
.mn-row .mn-icon { flex:0 1 92px; min-width:70px; height:28px; padding:0 7px; border:1.5px solid #e5e7eb; border-radius:6px; font:12px ui-monospace,Menlo,monospace; background:#fff; }
.mn-row input:focus, .mn-row select:focus { outline:none; border-color:var(--brand); }
.mn-btn { width:26px; height:26px; flex:none; display:inline-flex; align-items:center; justify-content:center; border:1px solid #d7dde5; background:#fff; border-radius:6px; color:#374151; cursor:pointer; font-size:11px; }
.mn-btn:hover { border-color:var(--brand); color:var(--brand); }
.mn-del:hover { border-color:#f3b4b4; color:#b91c1c; }
.mn-add { margin-top:4px; height:30px; display:inline-flex; align-items:center; justify-content:center; gap:6px; border:1px dashed #cdd5df; background:#fff; border-radius:8px; color:var(--brand); font:600 13px system-ui,Arial; cursor:pointer; }
.mn-add:hover { background:#f5f7fb; border-color:var(--brand); }
.mn-empty { padding:8px; color:#9aa7b5; font-size:12.5px; }
.mn-tip { margin-top:6px; font-size:11px; color:#9aa7b5; line-height:1.4; }
.mn-tip code { background:#f3f5f8; border:1px solid #e3e7ec; border-radius:4px; padding:0 4px; font-size:10.5px; }
.prop.check { display:flex; align-items:center; gap:8px; }
.prop.check label { margin:0; }
.props-empty { padding:24px 14px; color:#9aa7b5; font-size:13px; }
.props-save { padding:12px; border-top:1px solid #eef0f3; position:sticky; bottom:0; background:#fff; }
.props-save button { width:100%; font:inherit; font-weight:700; border:0; border-radius:8px; padding:10px; cursor:pointer;
                     background:linear-gradient(135deg,var(--brand),var(--brand-700)); color:#fff; }
.kindtag { display:inline-block; font-size:11px; font-weight:700; color:var(--brand); background:var(--brand-50); border:1px solid #dbe3ff; border-radius:6px; padding:2px 8px; margin-bottom:10px; }

.toast { position:fixed; bottom:18px; left:50%; transform:translateX(-50%); background:#111827; color:#fff; padding:10px 16px; border-radius:9px; font-size:13px; box-shadow:0 10px 30px rgba(0,0,0,.3); display:none; z-index:300; }
.toast.show { display:block; }

.ide-mobile-tabs { display:none; }
@media (max-width:860px) {
    .ide-body { flex-direction:column; }
    .explorer, .props { width:auto; min-width:0; max-width:none; max-height:38vh; border:none; border-bottom:1px solid #e3e7ec; }
    .explorer.hide, .props.hide { display:none; }
    .splitter { display:none; }
    .ide-mobile-tabs { display:flex; gap:6px; padding:8px; background:#fff; border-bottom:1px solid #e3e7ec; }
    .ide-mobile-tabs button { flex:1; font:inherit; font-size:12.5px; font-weight:600; border:1px solid #e5e7eb; background:#fff; border-radius:7px; padding:7px; cursor:pointer; }
    .ide-mobile-tabs button.active { background:var(--brand-50); color:var(--brand); border-color:#dbe3ff; }
    .ide-proj select { max-width:130px; }
}

/* ---- Gateway driver configuration editor ---- */
.gw-cfg { display:flex; flex-direction:column; gap:12px; height:100%; min-height:420px; }
.gw-cfg-bar { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.gw-cfg-bar .gw-lbl { font-size:12px; font-weight:700; color:#6b7280; }
.gw-cfg-bar .gw-sel { padding:7px 10px; border:1.5px solid #e5e7eb; border-radius:7px; font:inherit; font-size:13px; background:#fff; min-width:160px; }
.gw-cfg .act { font:600 13px system-ui,Arial; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:6px 12px; cursor:pointer; display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
.gw-cfg .act:hover { background:#f4f6fa; }
.gw-cfg .act.primary { background:linear-gradient(135deg,var(--brand),var(--brand-700)); color:#fff; border-color:transparent; }
.gw-cfg .act.primary:hover { filter:brightness(1.05); }
/* device/gateway tab bodies (Status, Runtime, Commands, Configuration) */
#devBody .act { font:600 13px system-ui,Arial; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:6px 12px; cursor:pointer; display:inline-flex; align-items:center; gap:6px; white-space:nowrap; }
#devBody .act:hover { background:#f4f6fa; }
#devBody .act.primary { background:linear-gradient(135deg,var(--brand),var(--brand-700)); color:#fff; border-color:transparent; }
#devBody .dev-token .act { padding:6px 9px; }
.gw-toggle { display:inline-flex; border:1.5px solid #e5e7eb; border-radius:8px; overflow:hidden; }
.gw-toggle button { border:0; background:#fff; padding:7px 14px; font:inherit; font-size:12.5px; font-weight:600; color:#6b7280; cursor:pointer; }
.gw-toggle button + button { border-left:1.5px solid #e5e7eb; }
.gw-toggle button.on { background:var(--brand); color:#fff; }
.gw-status { font-size:12px; color:#6b7280; }
.gw-status.ok { color:#0a7d33; font-weight:600; }
.gw-status.err { color:#c0392b; font-weight:600; }
.gw-hint { font-size:11.5px; color:#9aa7b5; }
.gw-hint code { background:#eef2f8; padding:1px 5px; border-radius:4px; color:#374151; }

/* form view */
.gw-form { flex:1; overflow:auto; display:flex; flex-direction:column; gap:14px; }
.gw-group { border:1px solid #e9edf3; border-radius:10px; padding:12px 14px; background:#fcfdfe; }
/* Nested points table, opened from the caret on a slave or device row. */
.gw-subrow > td { padding:0 0 10px 20px; background:#f7f9fc; }
.gw-subgroup { margin:0; border-left:3px solid #c7d2fe; background:#fff; }
/* The inputs in this table are width:100%, so a caret placed beside one would be pushed onto
   its own line. The cell becomes a flex row instead, and the input takes the remaining space. */
.gw-table td.gw-first { display:flex; align-items:center; gap:2px; }
.gw-table td.gw-first > input, .gw-table td.gw-first > select { flex:1 1 auto; min-width:0; }
.gw-subtog { flex:0 0 auto; border:0; background:none; cursor:pointer; color:#4f46e5;
             font-size:11px; line-height:1; padding:2px 3px; border-radius:4px; }
.gw-subtog:hover { color:#3730a3; background:#eef2ff; }
.gw-gtitle { font-size:12px; font-weight:700; color:#42506b; text-transform:uppercase; letter-spacing:.03em; margin-bottom:10px; display:flex; align-items:center; gap:10px; }
.gw-gtitle .gw-cnt { background:#eef2f8; color:#1e326c; border-radius:10px; padding:0 8px; font-size:11px; }
.gw-gtitle .gw-addrow { margin-left:auto; font-size:12px; padding:4px 10px; }
.gw-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); gap:10px 14px; }
.gw-fld { display:flex; flex-direction:column; gap:4px; font-size:12px; font-weight:600; color:#6b7280; }

/* Keep the controls on a row lined up with each other, whatever their labels do.

   Every field is a column of label-then-control, and a grid item stretches to the tallest field
   on its row. So a label that wrapped onto a second line - "Bit rate (SLCAN only; SocketCAN
   takes it from ip)" - pushed its OWN control down while its neighbours' stayed put, and the
   row came out as a staircase. Shortening the labels is not the answer: they say something.

   margin-top:auto puts the free space ABOVE the control instead, so labels sit at the top of
   the row and every control sits on the bottom edge - which is the same edge for all of them.
   Measured across the driver forms, this takes the worst misalignment on a row from 16px to 1px.

   A checkbox field is a row, not a column, so it is placed at the bottom of the grid row
   instead and padded to put its box on the same line. A toggle switch is shorter than an input
   (24px against 35), so bottom-aligning it leaves its centre low; the 4px lifts it back. */
.gw-fld > input:not([type=checkbox]), .gw-fld > select, .gw-fld > .portsel, .gw-fld > .gw-sw { margin-top:auto; }
.gw-fld > .gw-sw { margin-bottom:4px; }
.gw-fld input:not([type=checkbox]), .gw-fld select { padding:7px 9px; border:1.5px solid #e5e7eb; border-radius:7px; font:inherit; font-size:13px; background:#fff; font-weight:400; color:#1f2937; }
.gw-fld input[type=datetime-local] { min-width:0; }
/* action button rendered as a form field (e.g. Read load profile): align with the inputs */
.gw-actfld { justify-content:flex-end; }
.gw-cfg .gw-actfld .act { width:100%; justify-content:center; padding:8px 12px; }
.gw-cfg .gw-actfld .act.primary { background:linear-gradient(135deg,var(--brand),var(--brand-700)); color:#fff; border-color:transparent; }
.gw-cfg .gw-actfld .act.primary:hover { filter:brightness(1.06); }
.gw-fld.gw-bool { flex-direction:row; align-items:flex-end; align-self:end; gap:8px; padding-bottom:9px; }
.gw-fld.gw-bool input { width:auto; margin-bottom:1px; }
.gw-fld.gw-swfld { flex-direction:column; align-items:flex-start; gap:6px; }
.gw-sw { position:relative; display:inline-block; width:42px; height:24px; flex:none; }
.gw-sw input { opacity:0; width:0; height:0; position:absolute; margin:0; }
.gw-sl { position:absolute; inset:0; background:#cbd5e1; border-radius:999px; transition:.2s; cursor:pointer; }
.gw-sl::after { content:''; position:absolute; top:3px; left:3px; width:18px; height:18px; background:#fff; border-radius:50%; transition:.2s; }
.gw-sw input:checked + .gw-sl { background:#16a34a; }
.gw-sw input:checked + .gw-sl::after { transform:translateX(18px); }
.gw-table { overflow:auto; border:1px solid #eef1f5; border-radius:8px; }
.gw-table table { border-collapse:collapse; width:100%; font-size:12.5px; }
.gw-table th { text-align:left; background:#f4f6fa; color:#6b7280; font-weight:700; padding:6px 8px; position:sticky; top:0; white-space:nowrap; }
.gw-table td { padding:4px 6px; border-top:1px solid #f0f2f6; }
.gw-table input, .gw-table select { width:100%; box-sizing:border-box; padding:5px 7px; border:1px solid #e5e7eb; border-radius:6px; font:inherit; font-size:12.5px; background:#fff; }
.gw-table input[type=checkbox] { width:auto; }
.gw-delrow { border:0; background:#fbeaea; color:#c0392b; width:24px; height:24px; border-radius:6px; cursor:pointer; font-size:15px; line-height:1; }
.gw-delrow:hover { background:#f3c9c9; }
.gw-noform { color:#6b7280; font-size:13px; padding:16px; background:#fbfcfe; border:1px dashed #d8dee8; border-radius:10px; }

/* json view: highlighted overlay over a transparent textarea */
.gw-json-wrap { position:relative; flex:1; min-height:340px; border:1.5px solid #e5e7eb; border-radius:9px; background:#0f1729; overflow:hidden; }
.gw-json-hl, .gw-json-ta { margin:0; padding:12px 14px; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:13px; line-height:1.55; tab-size:2; white-space:pre; word-wrap:normal; border:0; }
.gw-json-hl { position:absolute; inset:0; overflow:auto; color:#e6edf6; pointer-events:none; }
.gw-json-ta { position:absolute; inset:0; width:100%; height:100%; box-sizing:border-box; resize:none; overflow:auto; background:transparent; color:transparent; caret-color:#e6edf6; outline:none; }
.gw-json-hl .gw-key { color:#7fb2ff; }
.gw-json-hl .gw-str { color:#9ee6a0; }
.gw-json-hl .gw-num { color:#ffcb6b; }
.gw-json-hl .gw-bool { color:#f78c6c; }
.gw-json-hl .gw-null { color:#c792ea; }

/* ---- Device/gateway enable toggle ---- */
.dev-switch { position:relative; display:inline-block; width:42px; height:23px; vertical-align:middle; }
.dev-switch input { opacity:0; width:0; height:0; position:absolute; }
.dev-knob { position:absolute; inset:0; background:#c9d2de; border-radius:999px; transition:.18s; cursor:pointer; }
.dev-knob::before { content:''; position:absolute; left:3px; top:3px; width:17px; height:17px; background:#fff; border-radius:50%; transition:.18s; box-shadow:0 1px 2px rgba(0,0,0,.25); }
.dev-switch input:checked + .dev-knob { background:#22a559; }
.dev-switch input:checked + .dev-knob::before { transform:translateX(19px); }
.dev-enlbl { margin-left:10px; font-weight:700; font-size:12.5px; vertical-align:middle; }
.dev-enlbl.on { color:#0a7d33; }
.dev-enlbl.off { color:#9aa3af; }
.node.dim > span { opacity:.5; }
.node.dim .ico { opacity:.4; }

/* ---- MobileApp (PWA) settings view — scoped to #mobileAppView ---- */
#mobileAppView .ma-row { display:flex; gap:22px; flex-wrap:wrap; }
#mobileAppView .ma-col { flex:1; min-width:300px; }
#mobileAppView .ma-grp { margin-bottom:13px; }
#mobileAppView .ma-grp label { display:block; color:#6b7280; font-size:12px; margin-bottom:5px; }
#mobileAppView .ma-grp input { width:100%; border:1px solid #e5e7eb; border-radius:8px; padding:9px 11px; font:inherit; font-size:13.5px; color:#1f2937; }
#mobileAppView .ma-grp input[type=color] { padding:3px; height:38px; cursor:pointer; }
#mobileAppView .ma-two { display:flex; gap:12px; }
#mobileAppView .ma-two .ma-grp { flex:1; }
#mobileAppView .ma-tip { color:#6b7280; font-size:12px; margin:6px 2px 0; }
#mobileAppView .ma-qr-row { display:flex; gap:14px; flex-wrap:wrap; }
#mobileAppView .ma-qr-card { flex:1; min-width:200px; background:#f8fafc; border:1px solid #e5e7eb; border-radius:14px; padding:14px; text-align:center; }
#mobileAppView .ma-qr-card h3 { margin:0 0 4px; font-size:14px; color:#1f2937; display:flex; align-items:center; justify-content:center; gap:7px; }
#mobileAppView .ma-qr-box { background:#fff; border:1px solid #eef0f3; border-radius:12px; padding:10px; display:inline-block; margin:8px 0; }
#mobileAppView .ma-qr-box svg { display:block; width:150px; height:150px; }
#mobileAppView .ma-steps { text-align:left; color:#6b7280; font-size:11.5px; margin:6px 0 0; padding-left:16px; }
#mobileAppView .ma-steps li { margin:2px 0; }
#mobileAppView .ma-link { font-size:10.5px; color:#1e326c; word-break:break-all; background:#eef2f8; border-radius:7px; padding:6px 8px; margin-top:7px; }
#mobileAppView .ma-pages-hd { display:flex; align-items:center; gap:10px; margin:24px 0 10px; padding-top:16px; border-top:1px solid #eef0f3; }
#mobileAppView .ma-pages-hd button { margin-left:auto; }
#mobileAppView .ma-pitem { display:flex; align-items:center; gap:11px; background:#fff; border:1px solid #e5e7eb; border-radius:10px; padding:10px 13px; margin-bottom:8px; }
#mobileAppView .ma-pitem .ico { color:#1e326c; }
#mobileAppView .ma-pitem .nm { font-weight:600; color:#1f2937; }
#mobileAppView .ma-pitem .sp { flex:1; }
#mobileAppView .act { font:600 13px system-ui,Arial; border:1px solid #e5e7eb; background:#fff; color:#374151; border-radius:7px; padding:6px 12px; cursor:pointer; }
#mobileAppView .act.sm { padding:5px 10px; font-size:12px; }
#mobileAppView .act:hover { border-color:#cbd5e1; }

/* ---- DLMS load-profile runtime table ---- */
.lp-wrap{display:flex;flex-direction:column;height:100%;min-height:calc(100vh - 210px);gap:10px}
.lp-bar{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.lp-meta{color:#6b7280;font-size:12px;margin-left:auto}
.lp-table-wrap{flex:1;overflow:auto;border:1px solid #e9edf2;border-radius:10px;background:#fff}
.lp-table{width:100%;border-collapse:collapse;font-size:12.5px}
.lp-table th,.lp-table td{padding:6px 10px;border-bottom:1px solid #eef0f3;text-align:left;white-space:nowrap}
.lp-table thead th{position:sticky;top:0;background:#f8fafc;font-weight:700;color:#374151;z-index:1}
.lp-table tbody tr:hover{background:#f9fbfd}
.lp-empty{padding:22px;color:#6b7280}

/* ---- Tags browser: filter, multi-select, bulk bar ---- */
.tag-filter { display:inline-flex; border:1px solid #e5e7eb; border-radius:7px; overflow:hidden; margin-left:10px; }
.tag-filter .vt { border:none; background:#fff; color:#6b7280; padding:6px 11px; cursor:pointer; font-size:13px; }
.tag-filter .vt + .vt { border-left:1px solid #e5e7eb; }
.tag-filter .vt.on { background:var(--brand); color:#fff; }
.cv-row .tg-cb { width:15px; height:15px; cursor:pointer; accent-color:var(--brand); flex-shrink:0; }
.cv-row.head { background:#f8fafc; cursor:default; position:sticky; top:0; z-index:1; }
.cv-row.head:hover { background:#f8fafc; }
.cv-row.sel { background:var(--brand-50); }
.tag-bar { display:none; align-items:center; gap:8px; padding:8px 14px; background:var(--brand-50); border-bottom:1px solid #e5e7eb; }
.tag-bar.on { display:flex; }
.tag-bar .cnt { font-size:13px; color:#374151; }
.tag-bar .sp { flex:1; }
.tag-bar select { font:inherit; font-size:13px; padding:5px 8px; border:1px solid #d7dde5; border-radius:6px; background:#fff; }
.btn.sm { padding:5px 10px; font-size:13px; }

/* ---- AI helper chat ---- */
.ai-hint { color:#94a3b8; font-size:13px; max-width:640px; margin:8px auto; text-align:center; }
.ai-msg { display:flex; gap:10px; margin:0 0 14px; max-width:820px; }
.ai-msg .ai-who { flex:none; width:34px; height:34px; border-radius:50%; display:flex; align-items:center; justify-content:center; font-size:11px; font-weight:700; text-transform:uppercase; }
.ai-you { flex-direction:row-reverse; margin-left:auto; }
.ai-you .ai-who { background:var(--brand,#1e326c); color:#fff; }
.ai-bot .ai-who { background:#e0e7ff; color:#3730a3; }
.ai-msg .ai-body { padding:10px 13px; border-radius:12px; font-size:13.5px; line-height:1.6; color:#1f2937; }
.ai-bot .ai-body { background:#fff; border:1px solid #e5e7eb; border-top-left-radius:3px; }
.ai-you .ai-body { background:var(--brand-50,#eef2ff); border:1px solid #dbe4f7; border-top-right-radius:3px; }
.ai-body pre, .ai-body code { font-family:ui-monospace,Menlo,monospace; }
.ai-acts { margin-top:8px; display:flex; flex-direction:column; gap:4px; }
.ai-act { font-size:11.5px; color:#15803d; background:#f0fdf4; border:1px solid #bbf7d0; border-radius:6px; padding:2px 8px; display:inline-flex; gap:6px; align-items:center; width:fit-content; }

/* ---- Reports Manager: Excel viewer + selection ---- */
.cv-tile { position:relative; }
.cv-row.rm-on, .cv-tile.rm-on { background:var(--brand-50,#eef2ff); border-color:#c7d2fe; }
.rm-check { width:15px; height:15px; cursor:pointer; accent-color:var(--brand,#1e326c); }
.editor-tabs .act:disabled { opacity:.4; cursor:not-allowed; }
/* Per-file row/tile action buttons (download / delete) — clean icon buttons instead of default boxes. */
.rm-dl, .rm-del, button[data-delrep] { border:1px solid #e5e7eb; background:#fff; color:#475569; border-radius:6px; padding:4px 8px; cursor:pointer; font-size:12.5px; line-height:1; display:inline-flex; align-items:center; }
.rm-dl:hover { background:#f4f6fa; border-color:#d7dde5; color:var(--brand,#1e326c); }
.rm-del, button[data-delrep] { color:#dc2626; }
.rm-del:hover, button[data-delrep]:hover { background:#fef2f2; border-color:#e79a9a; }
.xls-tabs { flex:none; display:flex; gap:2px; padding:6px 10px 0; border-bottom:1px solid #e5e7eb; background:#f8fafc; overflow-x:auto; }
.xls-tab { border:1px solid #e5e7eb; border-bottom:none; background:#eef2f7; color:#475569; padding:5px 12px; border-radius:6px 6px 0 0; font-size:12.5px; cursor:pointer; white-space:nowrap; }
.xls-tab.on { background:#fff; color:var(--brand,#1e326c); font-weight:600; }
.xls-view { border-collapse:collapse; font-size:12.5px; color:#1f2937; background:#fff; }
.xls-view th, .xls-view td { border:1px solid #e2e8f0; padding:3px 8px; text-align:left; white-space:nowrap; max-width:360px; overflow:hidden; text-overflow:ellipsis; }
.xls-view td { background:#fff; }
.xls-view tr:first-child th { background:#eef2f7; color:#64748b; font-weight:600; text-align:center; position:sticky; top:0; z-index:2; }
.xls-view th.xls-rownum { background:#f1f5f9; color:#94a3b8; text-align:center; min-width:36px; position:sticky; left:0; z-index:1; }
.xls-view th.xls-corner { background:#e9edf3; position:sticky; left:0; top:0; z-index:3; min-width:36px; }

/* ---- AI helper "thinking" indicator while waiting for a reply ---- */
.ai-thinking { display:inline-flex; align-items:center; gap:8px; color:#64748b; }
.ai-thinking .fa-circle-notch { color:var(--brand,#1e326c); }
.ai-dots { display:inline-flex; gap:3px; align-items:flex-end; }
.ai-dots i { width:5px; height:5px; border-radius:50%; background:#94a3b8; display:inline-block; animation:aiDot 1.2s infinite ease-in-out; }
.ai-dots i:nth-child(2) { animation-delay:.2s; }
.ai-dots i:nth-child(3) { animation-delay:.4s; }
@keyframes aiDot { 0%,60%,100% { opacity:.25; transform:translateY(0); } 30% { opacity:1; transform:translateY(-3px); } }

/* ---- AI helper attachments (attach button + file chips) ---- */
.ai-chips { display:flex; flex-wrap:wrap; gap:6px; }
.ai-chips:empty { display:none; }
.ai-chip { display:inline-flex; align-items:center; gap:6px; background:#eef2ff; border:1px solid #dbe4f7; border-radius:999px; padding:3px 6px 3px 10px; font-size:12px; color:#334155; max-width:220px; }
.ai-chip i.fa-fw { color:#6366f1; font-size:12px; }
.ai-chip .ai-chip-name { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ai-chip button { border:none; background:none; color:#94a3b8; cursor:pointer; font-size:14px; line-height:1; padding:0 2px; border-radius:50%; }
.ai-chip button:hover { color:#ef4444; }
.ai-compose-row { display:flex; align-items:flex-end; gap:8px; }
#aiAttach { flex:none; width:38px; height:38px; border:1px solid #d7dde5; border-radius:9px; background:#fff; color:#64748b; cursor:pointer; font-size:15px; }
#aiAttach:hover { background:var(--brand-50); border-color:var(--brand); color:var(--brand); }

/* ---- Tags search + sort toolbar ---- */
.tag-tools { display:flex; align-items:center; gap:12px; padding:8px 14px; border-bottom:1px solid #eef0f3; background:#fff; }
.tag-search { position:relative; flex:1; min-width:0; display:flex; align-items:center; }
.tag-search .fa-magnifying-glass { position:absolute; left:11px; color:#9aa7b5; font-size:13px; pointer-events:none; }
.tag-search input { width:100%; box-sizing:border-box; padding:8px 32px 8px 32px; border:1px solid #d7dde5; border-radius:8px; font:14px system-ui,Arial; color:#1f2937; background:#fbfcfe; outline:none; }
.tag-search input:focus { border-color:var(--brand); background:#fff; box-shadow:0 0 0 3px var(--brand-50); }
.tag-search .ts-clear { position:absolute; right:6px; border:none; background:transparent; color:#9aa7b5; cursor:pointer; padding:4px 7px; border-radius:6px; font-size:13px; }
.tag-search .ts-clear:hover { background:#f1f5f9; color:#475569; }
.tag-sort { display:inline-flex; align-items:center; gap:7px; color:#64748b; font-size:13px; white-space:nowrap; }
.tag-sort select { font:inherit; font-size:13px; padding:7px 9px; border:1px solid #d7dde5; border-radius:8px; background:#fff; color:#334155; cursor:pointer; outline:none; }
.tag-sort select:focus { border-color:var(--brand); box-shadow:0 0 0 3px var(--brand-50); }

/* ---- Tags pagination footer ---- */
.tag-pager { display:flex; align-items:center; gap:8px; padding:8px 14px; border-top:1px solid #e5e7eb; background:#fafbfc; font-size:13px; color:#475569; }
.tag-pager .sp { flex:1; }
.tag-pager .pg-size { display:inline-flex; align-items:center; gap:6px; color:#64748b; }
.tag-pager .pg-size select { font:inherit; padding:4px 7px; border:1px solid #d7dde5; border-radius:6px; background:#fff; color:#334155; cursor:pointer; }
.tag-pager .pg-info { min-width:110px; text-align:center; color:#334155; }
.tag-pager .pg-btn { display:inline-flex; align-items:center; justify-content:center; width:30px; height:30px; border:1px solid #d7dde5; border-radius:7px; background:#fff; color:#475569; cursor:pointer; }
.tag-pager .pg-btn:hover:not(:disabled) { background:var(--brand-50); border-color:var(--brand); color:var(--brand); }
.tag-pager .pg-btn:disabled { opacity:.4; cursor:not-allowed; }

/* ---- Purge report ---- */
.purge-intro { font-size:13px; color:#374151; margin-bottom:12px; line-height:1.5; }
.purge-intro .ok { color:#059669; font-weight:600; }
#purge-list { max-height:52vh; overflow:auto; }
.pg-row { display:flex; gap:10px; padding:11px 12px; border:1px solid #e5e7eb; border-left-width:3px; border-radius:8px; margin-bottom:8px; background:#fff; }
.pg-row.error { border-left-color:#dc2626; }
.pg-row.warning { border-left-color:#f59e0b; }
.pg-cb { padding-top:2px; }
.pg-cb input { width:15px; height:15px; cursor:pointer; accent-color:var(--brand); }
.pg-cb .fa-circle-info { color:#9aa7b5; }
.pg-main { flex:1; min-width:0; }
.pg-title { font-weight:700; color:#1f2937; font-size:14px; display:flex; align-items:center; gap:8px; }
.pg-badge { font-size:10px; text-transform:uppercase; letter-spacing:.04em; padding:1px 6px; border-radius:999px; font-weight:700; }
.pg-badge.error { background:#fee2e2; color:#b91c1c; }
.pg-badge.warning { background:#fef3c7; color:#92400e; }
.pg-detail { font-size:12.5px; color:#6b7280; margin:4px 0 6px; line-height:1.5; }
.pg-tags { font-size:12px; color:#374151; word-break:break-word; }
.pg-tags code { background:#f1f5f9; padding:1px 5px; border-radius:4px; }
.pg-tags .dv { color:#9aa7b5; }
.pg-fix { margin-top:7px; font-size:12.5px; color:#047857; font-weight:600; }
.pg-fix.none { color:#9aa7b5; font-weight:500; }

/* ---- Tag import preview ---- */
.purge-intro.err { color:#b91c1c; font-weight:600; }
.purge-intro .dv, .imp-warn .dv { color:#9aa7b5; }
.purge-intro code, .imp-warn code { background:#f1f5f9; padding:1px 5px; border-radius:4px; }
.imp-modes { display:flex; flex-direction:column; gap:7px; margin:12px 0; }
.imp-modes label { display:flex; align-items:baseline; gap:7px; font-size:13px; color:#374151; cursor:pointer; }
.imp-modes .dv { color:#6b7280; }
.imp-counts { display:flex; flex-wrap:wrap; gap:8px; margin:12px 0; }
.imp-counts .ic { font-size:12.5px; padding:3px 10px; border-radius:999px; background:#f1f5f9; color:#374151; }
.imp-counts .ic.create { background:#dcfce7; color:#166534; }
.imp-counts .ic.update { background:#dbeafe; color:#1e40af; }
.imp-counts .ic.delete { background:#fee2e2; color:#b91c1c; }
.imp-counts .ic.fail { background:#fee2e2; color:#b91c1c; }
.imp-danger { background:#fef2f2; border:1px solid #fecaca; color:#b91c1c; border-radius:8px; padding:10px 12px; font-size:12.5px; margin-bottom:10px; line-height:1.5; }
.imp-warn { border:1px solid #fde68a; background:#fffbeb; border-radius:8px; padding:10px 12px; margin-bottom:10px; }
.imp-warn.big { border-color:#fca5a5; background:#fef2f2; }
.imp-warn .wh { font-weight:700; font-size:13px; color:#92400e; display:flex; align-items:center; gap:7px; }
.imp-warn.big .wh { color:#b91c1c; }
.imp-warn .wd { font-size:12.5px; color:#7f1d1d; margin:5px 0 0; line-height:1.5; }
.imp-warn ul { margin:7px 0 0; padding-left:18px; font-size:12px; color:#374151; line-height:1.6; }
.imp-warn li { word-break:break-word; }
#imp-body { max-height:60vh; overflow:auto; }

/* ---- Pages / Functions import preview ---- */
.pi-cols { border:1px solid #e5e7eb; border-radius:8px; padding:10px 12px; margin-bottom:10px; }
.pi-col { display:flex; align-items:center; gap:10px; padding:4px 0; font-size:12.5px; }
.pi-col code { background:#f1f5f9; padding:1px 5px; border-radius:4px; flex:1; }
.pi-col select { font:inherit; font-size:12.5px; padding:4px 7px; border:1px solid #d7dde5; border-radius:6px; background:#fff; }

/* ---- Project management ---- */
.pm-card { border:1px solid #e5e7eb; border-radius:10px; padding:16px 18px; margin-bottom:16px; background:#fff; }
.pm-card h3 { margin:0 0 6px; font-size:15px; color:#1f2937; display:flex; align-items:center; gap:8px; }
.pm-sub { font-size:13px; color:#6b7280; line-height:1.55; margin:0 0 12px; }
.pm-sub2 { display:block; font-size:12px; color:#6b7280; line-height:1.5; margin-top:2px; }
.pm-opt { display:flex; gap:9px; align-items:flex-start; margin:0 0 12px; cursor:pointer; font-size:13px; color:#374151; }
.pm-opt input { margin-top:3px; width:15px; height:15px; accent-color:var(--brand); flex-shrink:0; }
.pm-warn { display:block; font-size:12px; color:#b91c1c; background:#fef2f2; border:1px solid #fecaca; border-radius:6px; padding:7px 9px; margin-top:5px; line-height:1.5; }

/* Tags table: same shape as the device runtime table, plus a live value column */
.tag-tbl tbody tr { cursor:pointer; }
.tag-tbl tbody tr:hover { background:#f5f7fa; }
.tag-tbl tbody tr.sel { background:#eef4ff; }
.tag-tbl .c-cb { width:34px; padding-right:0; }
.tag-tbl .c-cb input { cursor:pointer; }
.tag-tbl .c-nm { font-weight:600; white-space:nowrap; }
.tag-tbl .c-nm .ico { color:var(--brand); margin-right:4px; }
.tag-tbl .ico-s { color:#9aa7b5; font-size:11px; }
.tag-tbl .mut { color:#c3cbd4; }
.tag-tbl .c-val { width:150px; text-align:right; font:13px ui-monospace,Consolas,
  "DejaVu Sans Mono",monospace; font-weight:600; color:#111827;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
th.c-val { text-align:right; }
.tgval-hit { animation:tgvalFlash .55s ease-out; }
@keyframes tgvalFlash { from { background:#fde68a; } to { background:transparent; } }

/* Colour property: swatch + opacity slider, hidden input carries the value */
.clr-field { display:flex; align-items:center; gap:8px; }
.clr-field .clr-sw { width:38px; height:28px; padding:0; border:1px solid #cbd5e1;
  border-radius:5px; background:#fff; cursor:pointer; flex:none; }
.clr-field .clr-a { flex:1; min-width:60px; height:20px; cursor:pointer; accent-color:var(--brand); }
.clr-field .clr-pct { font:11px ui-monospace,Consolas,monospace; color:#6b7280;
  min-width:34px; text-align:right; flex:none; }
/* checkerboard behind the swatch so a low opacity is visible at a glance */
.clr-field .clr-sw { background-image:
  linear-gradient(45deg,#d8dee5 25%,transparent 25%,transparent 75%,#d8dee5 75%),
  linear-gradient(45deg,#d8dee5 25%,transparent 25%,transparent 75%,#d8dee5 75%);
  background-size:8px 8px; background-position:0 0,4px 4px; }
.clr-field.clr-inline { flex:none; width:132px; }
.clr-field.clr-inline .clr-a { min-width:40px; }

/* Series editor: per-value scaling block */
.st-sub { margin:8px 0 4px; font-size:11px; font-weight:600; letter-spacing:.4px;
  text-transform:uppercase; color:#6b7280; display:flex; gap:8px; align-items:baseline; }
.st-sub .st-hint { font-weight:400; text-transform:none; letter-spacing:0;
  font-size:10.5px; color:#9aa7b5; }
.st-grid.st-scale { grid-template-columns:repeat(3,1fr); }
.st-grid.st-scale input { width:100%; }
.st-grid.st-scale .st-act { display:flex; align-items:flex-end; }
.st-grid.st-scale .st-reset { width:100%; justify-content:center; gap:5px; font-size:11px; }
.st-warn { margin-top:6px; padding:5px 8px; border-radius:5px; background:#fff7ed;
  border:1px solid #fdba74; color:#9a3412; font-size:11px; }

/* Page events: "every N seconds" row under OnTimer */
.ev-every { display:flex; align-items:center; gap:6px; margin-top:6px;
  font-size:12px; color:#6b7280; }
.ev-every input { border:1px solid #d1d5db; border-radius:6px; padding:4px 6px;
  font-size:12px; color:#1f2937; }

/* Device Status/Runtime auto-refresh selector.
   Sits in .editor-tabs beside the Export/Import/Refresh buttons, so it matches
   button.act there: same height, border, radius and baseline. */
.editor-tabs .dev-auto { font:600 13px system-ui,Arial; border:1px solid #e5e7eb;
  background:#fff; color:#374151; border-radius:7px; padding:6px 10px; cursor:default;
  margin:0 0 8px 6px; display:inline-flex; align-items:center; gap:7px;
  white-space:nowrap; }
.editor-tabs .dev-auto > span { color:#9aa7b5; font-weight:600; font-size:12px;
  text-transform:uppercase; letter-spacing:.3px; }
.editor-tabs .dev-auto select { font:600 13px system-ui,Arial; color:#374151;
  border:0; background:transparent; padding:0 2px; cursor:pointer; outline:none; }
.editor-tabs .dev-auto:hover { border-color:#d1d5db; }

/* Serial port selector: reported ports + Custom.
   Stacked, not side by side: the gateway form is a grid of ~190px cells, so a two-column
   row overflowed its cell and made this field wider than every other one. */
.portsel { display:flex; flex-direction:column; gap:6px; width:100%; min-width:0; }
.portsel .ps-list, .portsel .ps-text { width:100%; min-width:0; box-sizing:border-box; }
.portsel .ps-text { display:none; }
.portsel.custom .ps-text { display:block; }
.fld-hint { margin-top:4px; font-size:11.5px; color:#9aa7b5; font-weight:400; }

/* Multi-step events: an event can run several functions, in order.
   The "+" sits on the title line, and each step is a numbered row whose parameters use the
   existing .ev-props panel, so this reads like the rest of the properties panel. */
.ev-head { display:flex; align-items:center; gap:8px; }
.ev-head .ev-name { flex:1; }
.ev-add { flex:0 0 auto; width:26px; height:26px; border:1.5px solid #e5e7eb; border-radius:7px;
  background:#fff; color:var(--brand); font-size:12px; line-height:1; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; }
.ev-add:hover { background:#f5f8ff; border-color:var(--brand); }

.ev-steps { margin-top:2px; }
.ev-step { margin-bottom:10px; }
.ev-step:last-child { margin-bottom:0; }
.ev-step-head { display:flex; align-items:center; gap:6px; }
.ev-step-n { flex:0 0 auto; width:20px; height:20px; border-radius:50%; background:#eef2f7;
  color:#6b7280; font:700 10.5px/20px system-ui,Arial; text-align:center; }
/* Beat .ev-row select's width:100%, which would push the buttons onto the next line. */
.ev-step-head select { flex:1 1 auto; width:auto; min-width:0; }
.ev-btn { flex:0 0 auto; width:26px; height:26px; border:1.5px solid #e5e7eb; border-radius:7px;
  background:#fff; color:#9aa7b5; font-size:11px; line-height:1; cursor:pointer;
  display:inline-flex; align-items:center; justify-content:center; }
.ev-btn:hover:not(:disabled) { background:#f9fafb; color:#4b5563; border-color:#d1d5db; }
.ev-btn.ev-del:hover:not(:disabled) { background:#fef2f2; color:#dc2626; border-color:#fecaca; }
.ev-btn:disabled { opacity:.3; cursor:default; }

/* The panel is shared with single-function events, where it tucks under the select; inside a
   step it needs its own spacing and to line up with the number badge. */
.ev-step .ev-props { margin:6px 0 0 26px; border-radius:8px; }
.ev-empty { margin:2px 0 0 26px; font-size:12px; color:#9aa7b5; }


/* Built-in control help, shown in the control view and in the properties panel. */
.ch-help{border:1px solid #e9edf3;border-radius:10px;background:#fcfdfe;padding:12px 14px;margin:0 0 12px}
.ch-intro{margin:0 0 10px;font-size:13px;line-height:1.55;color:#334155}
.ch-h{font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:#64748b;margin:10px 0 4px}
.ch-list{margin:0;padding-left:18px;font-size:12.5px;line-height:1.6;color:#475569}
.ch-list li{margin:2px 0}
.ch-help b{color:#1e293b}
.props-body .ch-help{margin:10px 0 12px;padding:10px 12px}
.props-body .ch-intro{font-size:12.5px}


/* Build notes: the renderer emits <code> and <b> inline. The text uses the full width of the
   panel - an earlier version capped the column at 110ch for readability, which just left a
   band of empty space on a wide window. */
#wnBody code{background:#f1f5f9;border:1px solid #e2e8f0;border-radius:4px;padding:0 4px;font:12px ui-monospace,Consolas,monospace;color:#0f172a}
#wnBody ul{margin-bottom:12px}
#wnBody h3,#wnBody h4{border-bottom:1px solid #eef2f7;padding-bottom:4px}


/* "dbtable" property: a table picker with a type-it-instead escape hatch. */
.dbt-field{display:flex;align-items:center;gap:4px}
.dbt-field .dbt-select,.dbt-field .dbt-manual{flex:1 1 auto;min-width:0}
.dbt-toggle{flex:0 0 auto;border:1px solid #e5e7eb;background:#fff;color:#475569;cursor:pointer;
            border-radius:6px;padding:4px 7px;font-size:12px;line-height:1}
.dbt-toggle:hover{background:#f1f5f9;color:#1e293b}
