/* Theme tokens — Light (default), Dark, Sand.
   Switch via html[data-theme="…"] (set from settings.theme). */
:root,
[data-theme="light"] {
  color-scheme: light;
  --bg0: #f7f8fb;
  --bg1: #eef1f6;
  --bg2: #ffffff;
  --bg: var(--bg0);
  --panel: rgba(255, 255, 255, 0.94);
  --line: rgba(20, 30, 50, 0.09);
  --ink: #121826;
  --muted: #64748b;
  --accent: #2563eb;
  --accent-hot: #1d4ed8;
  --accent-2: #f59e0b;
  --accent-rgb: 37, 99, 235;
  --accent-2-rgb: 245, 158, 11;
  --online: #12c97a;
  --offline: #ff3b5c;
  --unknown: #8090a8;
  --danger: #ff3b5c;
  --cancel-0: #14b8a6;
  --cancel-1: #0d9488;
  --cancel-2: #0f766e;
  --cancel-ink: #ffffff;
  --cancel-border: rgba(13, 148, 136, 0.4);
  --cancel-rgb: 13, 148, 136;
  --rescan-0: #8b5cf6;
  --rescan-1: #7c3aed;
  --rescan-2: #6d28d9;
  --rescan-ink: #ffffff;
  --rescan-border: rgba(109, 40, 217, 0.4);
  --rescan-rgb: 124, 58, 237;
  --shadow: 0 12px 28px rgba(15, 23, 42, 0.08);
  --font: "Sora", sans-serif;
  --mono: "JetBrains Mono", monospace;
  --display: "Oxanium", sans-serif;
  --radius: 12px;
  --node-bg: #ffffff;
  --node-ink: #121826;
  --node-muted: #64748b;
  --canvas-dot: rgba(37, 99, 235, 0.07);
  --chip: #f1f5f9;
  --surface: #ffffff;
  --surface-2: #f8fafc;
  --surface-3: #f1f5f9;
  --topbar-0: #6b7280;
  --topbar-1: #4b5563;
  --topbar-2: #374151;
  --topbar-border: rgba(55, 65, 81, 0.4);
  --body-glow-1: rgba(37, 99, 235, 0.1);
  --body-glow-2: rgba(245, 158, 11, 0.08);
  --body-base-0: #ffffff;
  --body-base-1: #e8edf5;
  --stage-glow: rgba(255, 255, 255, 0.98);
  --stage-0: #f4f6fa;
  --stage-1: #e9eef6;
  --brand-title-0: #ffffff;
  --brand-title-1: #e5e7eb;
  --settings-section-bg: linear-gradient(180deg, #ffffff, #f8fafc);
  --settings-section-border: rgba(20, 30, 50, 0.1);
  --settings-h3: #0f172a;
  --modal-scrim: rgba(8, 16, 34, 0.38);
  --modal-card-bg: linear-gradient(180deg, #ffffff, #f8fafc);
  --dock-bg: rgba(255, 255, 255, 0.96);
  --toast-bg: #0a1628;
  --toast-ink: #f4f7ff;
  --palette-item-bg: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
  --palette-item-border: rgba(20, 30, 50, 0.09);
  --live-box-bg: linear-gradient(180deg, #f8fafc, #f1f5f9);
  --unsaved-bg: rgba(245, 158, 11, 0.12);
  --unsaved-border: rgba(245, 158, 11, 0.28);
  --table-head-bg: #f1f5f9;
  --table-sorted: #1d4ed8;
  --table-sorted-bg: #e2e8f0;
  --table-hover-bg: #e8eef6;
  --input-disabled-bg: #f1f5f9;
  --progress-track: #e2e8f0;
  --soft-amber: #fffbeb;
  --stage-copy-ink: rgba(18, 24, 38, 0.72);
  --stage-copy-border: #c5d0e0;
}

[data-theme="dark"] {
  color-scheme: dark;
  --bg0: #030508;
  --bg1: #080b10;
  --bg2: #0e1218;
  --bg: var(--bg0);
  --panel: rgba(12, 16, 24, 0.94);
  --line: rgba(140, 170, 220, 0.12);
  --ink: #dce6f5;
  --muted: #7a8aa0;
  --accent: #6b9fff;
  --accent-hot: #8fb4ff;
  --accent-2: #4fc3f7;
  --accent-rgb: 107, 159, 255;
  --accent-2-rgb: 79, 195, 247;
  --canvas-dot: rgba(107, 159, 255, 0.1);
  --chip: #10151e;
  --surface: #0c1018;
  --surface-2: #10151e;
  --surface-3: #080b10;
  --node-bg: #0c1018;
  --node-ink: #dce6f5;
  --node-muted: #7a8aa0;
  --topbar-0: #1a3a6e;
  --topbar-1: #142c54;
  --topbar-2: #0e1e3c;
  --topbar-border: rgba(0, 0, 0, 0.55);
  --body-glow-1: rgba(107, 159, 255, 0.1);
  --body-glow-2: rgba(79, 195, 247, 0.08);
  --body-base-0: #020306;
  --body-base-1: #080b10;
  --stage-glow: rgba(12, 16, 24, 0.92);
  --stage-0: #06080c;
  --stage-1: #030508;
  --brand-title-1: #b8d0ff;
  --settings-section-bg: linear-gradient(180deg, rgba(16, 22, 32, 0.96), rgba(8, 12, 18, 0.92));
  --settings-section-border: rgba(140, 170, 220, 0.12);
  --settings-h3: #b8d0ff;
  --modal-scrim: rgba(0, 0, 0, 0.65);
  --modal-card-bg: linear-gradient(180deg, #10151e, #080b10);
  --dock-bg: rgba(12, 16, 24, 0.96);
  --toast-bg: #010204;
  --toast-ink: #dce6f5;
  --palette-item-bg: linear-gradient(180deg, #10151e 0%, #080b10 100%);
  --palette-item-border: rgba(140, 170, 220, 0.1);
  --live-box-bg: linear-gradient(180deg, #10151e, #080b10);
  --unsaved-bg: rgba(79, 195, 247, 0.12);
  --unsaved-border: rgba(79, 195, 247, 0.28);
  --table-head-bg: #10151e;
  --table-sorted: #8fb4ff;
  --table-sorted-bg: #161c28;
  --table-hover-bg: #121820;
  --input-disabled-bg: #080b10;
  --progress-track: #10151e;
  --soft-amber: #121820;
  --stage-copy-ink: rgba(220, 230, 245, 0.7);
  --stage-copy-border: #1c2838;
  --cancel-0: #0d9488;
  --cancel-1: #14b8a6;
  --cancel-2: #0f766e;
  --cancel-ink: #ffffff;
  --cancel-border: rgba(45, 212, 191, 0.3);
  --cancel-rgb: 20, 184, 166;
  --rescan-0: #7c3aed;
  --rescan-1: #8b5cf6;
  --rescan-2: #6d28d9;
  --rescan-ink: #ffffff;
  --rescan-border: rgba(167, 139, 250, 0.3);
  --rescan-rgb: 139, 92, 246;
  --shadow: 0 12px 36px rgba(0, 0, 0, 0.6);
  --unknown: #5a6a80;
}

[data-theme="sand"] {
  color-scheme: light;
  /* Canvas stage: cool near-white gray (orbital chrome stays warm). */
  --bg0: #f4f5f7;
  --bg1: #eceef2;
  --bg2: #fafbfc;
  --bg: var(--bg0);
  --panel: rgba(250, 251, 252, 0.94);
  --line: rgba(60, 45, 30, 0.11);
  --ink: #2c2419;
  --muted: #7a6e60;
  --accent: #3d7a8c;
  --accent-hot: #2a5f6e;
  --accent-2: #c4783a;
  --accent-rgb: 61, 122, 140;
  --accent-2-rgb: 196, 120, 58;
  --shadow: 0 12px 28px rgba(40, 48, 60, 0.1);
  --node-bg: #fffbf5;
  --node-ink: #2c2419;
  --node-muted: #7a6e60;
  --canvas-dot: rgba(90, 100, 120, 0.14);
  --chip: #eceef2;
  --surface: #fafbfc;
  --surface-2: #f4f5f7;
  --surface-3: #eceef2;
  --topbar-0: #3d7a8c;
  --topbar-1: #2a5f6e;
  --topbar-2: #1e4a56;
  --topbar-border: rgba(20, 50, 60, 0.35);
  --body-glow-1: rgba(61, 122, 140, 0.08);
  --body-glow-2: rgba(196, 120, 58, 0.08);
  --body-base-0: #fafbfc;
  --body-base-1: #e6e8ee;
  --stage-glow: rgba(255, 255, 255, 0.98);
  --stage-0: #f5f6f8;
  --stage-1: #e9ebf0;
  --brand-title-1: #d4e8ee;
  --settings-section-bg: linear-gradient(180deg, rgba(250, 251, 252, 0.96), rgba(236, 238, 242, 0.88));
  --settings-section-border: rgba(60, 70, 90, 0.12);
  --settings-h3: #2a5f6e;
  --modal-card-bg: linear-gradient(180deg, #fafbfc, #f0f2f5);
  --dock-bg: rgba(250, 251, 252, 0.96);
  --palette-item-bg: linear-gradient(180deg, #fafbfc 0%, #f4f5f7 100%);
  --palette-item-border: rgba(60, 70, 90, 0.1);
  --live-box-bg: linear-gradient(180deg, #f4f5f7, #eceef2);
  --unsaved-bg: rgba(196, 120, 58, 0.14);
  --unsaved-border: rgba(196, 120, 58, 0.3);
  --table-head-bg: #eceef2;
  --table-sorted: #2a5f6e;
  --table-sorted-bg: #e2e5eb;
  --table-hover-bg: #e8eaef;
  --input-disabled-bg: #eceef2;
  --progress-track: #e6e8ee;
  --soft-amber: #f4f5f7;
  --stage-copy-ink: rgba(36, 42, 54, 0.72);
  --stage-copy-border: #c5cad3;
  --cancel-0: #14b8a6;
  --cancel-1: #0d9488;
  --cancel-2: #0f766e;
  --cancel-ink: #ffffff;
  --cancel-border: rgba(13, 148, 136, 0.4);
  --cancel-rgb: 13, 148, 136;
  --rescan-0: #8b5cf6;
  --rescan-1: #7c3aed;
  --rescan-2: #6d28d9;
  --rescan-ink: #ffffff;
  --rescan-border: rgba(109, 40, 217, 0.4);
  --rescan-rgb: 124, 58, 237;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: var(--font);
  color: var(--ink);
  background:
    radial-gradient(900px 520px at 0% 0%, var(--body-glow-1), transparent 55%),
    radial-gradient(800px 480px at 100% 0%, var(--body-glow-2), transparent 50%),
    linear-gradient(155deg, var(--body-base-0) 0%, var(--bg0) 42%, var(--body-base-1) 100%);
  overflow: hidden;
}

#app {
  display: grid;
  grid-template-columns: 340px 1fr;
  grid-template-rows: 76px 1fr;
  height: 100vh;
  gap: 0;
  position: relative;
  transition: grid-template-columns 0.28s ease;
}
#app.palette-collapsed {
  grid-template-columns: 1fr;
}
#app.palette-collapsed .stage-wrap {
  grid-column: 1;
  grid-row: 2;
}

.topbar {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 18px 0 16px;
  border-bottom: 1px solid var(--topbar-border);
  background: linear-gradient(135deg, var(--topbar-0) 0%, var(--topbar-1) 55%, var(--topbar-2) 100%);
  overflow: visible;
  position: relative;
  z-index: 30;
}

.topbar-left {
  display: flex;
  align-items: center;
  gap: 20px;
  min-width: 0;
  flex: 1;
  overflow: visible;
}

.brand { display: flex; gap: 12px; align-items: center; flex-shrink: 0; }
.brand-logo {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  display: block;
  border: 2px solid #fff;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.35),
    0 10px 24px rgba(var(--accent-rgb), 0.28);
  animation: pulseMark 3s ease-in-out infinite;
}
@keyframes pulseMark {
  0%, 100% { transform: translateY(0) scale(1); }
  50% { transform: translateY(-1px) scale(1.03); }
}
.brand h1 {
  margin: 0;
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 1;
  background: linear-gradient(120deg, var(--brand-title-0) 20%, var(--brand-title-1) 140%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  text-shadow: 0 1px 0 rgba(0, 25, 80, 0.2);
}
.brand p {
  margin: 5px 0 0;
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.toolbar {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 2px;
  padding: 5px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(255,255,255,.16), rgba(255,255,255,.06));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 8px 20px rgba(0,20,60,.18);
  min-width: 0;
  overflow: visible;
}

.tool-sep {
  width: 1px;
  height: 22px;
  background: rgba(255, 255, 255, 0.25);
  margin: 0 6px;
  flex-shrink: 0;
}

.icon-tool {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 0;
  background: transparent;
  color: var(--ink);
  border-radius: 11px;
  padding: 8px 11px;
  font: 600 0.74rem var(--font);
  letter-spacing: 0.01em;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease, transform .12s ease, box-shadow .15s ease;
}
.icon-tool svg {
  width: 17px;
  height: 17px;
  display: block;
  flex-shrink: 0;
  stroke-width: 1.9;
}
.icon-tool:hover:not(:disabled) {
  background: rgba(var(--accent-rgb), 0.1);
  color: var(--accent-hot);
}
.icon-tool:active:not(:disabled) { transform: translateY(1px); }
.icon-tool:disabled { opacity: 0.35; cursor: not-allowed; }
.icon-tool.open,
.icon-tool:focus-visible {
  background: linear-gradient(135deg, var(--accent), var(--accent-hot));
  color: #fff;
  box-shadow: 0 8px 18px rgba(var(--accent-rgb), 0.28);
  outline: none;
}

/* Topbar sits on the blue gradient bar; its tool buttons need light text/icons
   so they stay readable (the .palette-toggle reuses .icon-tool on a light bg,
   so overrides are scoped to .topbar to avoid affecting it). */
.topbar .icon-tool {
  color: rgba(255, 255, 255, 0.92);
}
.topbar .icon-tool:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.topbar .icon-tool:disabled {
  color: rgba(255, 255, 255, 0.85);
  opacity: 0.4;
}
.topbar .icon-tool.open,
.topbar .icon-tool:focus-visible {
  background: rgba(255, 255, 255, 0.24);
  color: #fff;
  box-shadow: 0 4px 14px rgba(0, 20, 60, 0.28);
  outline: none;
}

.file-menu-wrap {
  position: relative;
  overflow: visible;
  flex-shrink: 0;
}
.file-menu {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  z-index: 50;
  min-width: 210px;
  display: grid;
  padding: 6px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
}
/* Escapes .toolbar overflow-x scrollport (mobile) which would clip absolute flyouts. */
.file-menu.flyout-fixed {
  position: fixed;
  right: auto;
  z-index: 55;
  -webkit-overflow-scrolling: touch;
}
.file-menu button {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 0;
  background: transparent;
  text-align: left;
  padding: 10px 12px;
  border-radius: 9px;
  font: 600 0.84rem var(--font);
  color: var(--ink);
  cursor: pointer;
}
.file-menu button svg {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  display: block;
}
.file-menu button:hover { background: rgba(var(--accent-rgb), .1); color: var(--accent-hot); }
.file-menu .menu-sep {
  height: 1px;
  margin: 6px 4px;
  background: var(--line);
}
.file-menu .menu-label {
  padding: 6px 12px 4px;
  font: 700 0.68rem var(--font);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.file-menu button.on {
  background: rgba(var(--accent-rgb), .12);
  color: var(--accent-hot);
}

.reports-menu { min-width: 210px; }
.notif-menu { min-width: 200px; }
.file-submenu-wrap {
  position: relative;
}
.file-submenu-trigger {
  display: flex !important;
  align-items: center;
  gap: 8px;
  width: 100%;
}
.file-submenu-wrap:hover > .file-submenu-trigger,
.file-submenu-wrap.open > .file-submenu-trigger {
  background: rgba(var(--accent-rgb), .1);
  color: var(--accent-hot);
}
.file-submenu {
  position: absolute;
  left: calc(100% - 2px);
  top: -6px;
  z-index: 56;
  min-width: 200px;
  display: none;
  flex-direction: column;
  padding: 6px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.file-submenu-wrap:hover > .file-submenu,
.file-submenu-wrap.open > .file-submenu {
  display: flex;
}
.file-submenu-wrap.fly-left > .file-submenu {
  left: auto;
  right: calc(100% - 2px);
}
.file-submenu button {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 0;
  background: transparent;
  text-align: left;
  padding: 10px 12px;
  border-radius: 9px;
  font: 600 0.84rem var(--font);
  color: var(--ink);
  cursor: pointer;
}
.file-submenu button svg {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
}
.file-submenu button:hover {
  background: rgba(var(--accent-rgb), .1);
  color: var(--accent-hot);
}
.tg-card {
  width: min(480px, 100%);
}
.tg-modal-body {
  padding: 16px 18px 18px;
  display: grid;
  gap: 12px;
  overflow: auto;
}
.tg-modal-body textarea {
  width: 100%;
  resize: vertical;
  min-height: 52px;
  font: 500 0.86rem/1.4 var(--font);
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--chip);
  color: var(--ink);
}
.quick-menu { min-width: 220px; }
.report-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.report-header-actions .btn {
  padding: 8px 12px;
  font-size: 0.78rem;
}

.top-actions { display: flex; gap: 10px; align-items: center; flex-shrink: 0; }
.user-chip {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(10, 22, 40, 0.12);
  color: rgba(255, 255, 255, 0.92);
  font: 700 0.78rem var(--mono);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.topbar-uptime {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-shrink: 0;
  padding: 6px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(10, 22, 40, 0.12);
  color: rgba(255, 255, 255, 0.78);
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;
  user-select: none;
}
.topbar-uptime-label {
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  opacity: 0.72;
  font-weight: 600;
}
.topbar-uptime-value { color: rgba(255, 255, 255, 0.92); }
.poll-meter {
  position: relative;
  display: flex; align-items: center; gap: 8px;
  padding: 6px 12px 6px 8px; border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.32); color: rgba(255, 255, 255, 0.88); font-size: 0.78rem;
  font-family: var(--mono);
  background: linear-gradient(180deg, rgba(255,255,255,.18), rgba(255,255,255,.07));
  font-weight: 500;
  cursor: pointer;
  user-select: none;
  transition: border-color .2s ease, color .2s ease, background .2s ease, transform .12s ease;
  min-width: 8.25rem;
  overflow: hidden; /* keep pingDot / glow inside the pill */
}
.poll-meter:hover {
  background: linear-gradient(180deg, rgba(255,255,255,.26), rgba(255,255,255,.1));
}
.poll-meter:active { transform: translateY(1px); }
.poll-meter:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.4);
}
/* Scanning: HTTP poll in flight — green pulse for the whole request (not a short flash). */
.poll-meter.busy {
  border-color: rgba(120, 255, 190, 0.55);
  color: #d8ffe9;
  background: linear-gradient(180deg, rgba(120,255,190,.22), rgba(255,255,255,.08));
}
.poll-meter.off {
  border-color: rgba(255, 255, 255, 0.18);
  color: rgba(255, 255, 255, 0.55);
  background: rgba(10, 22, 40, 0.16);
}
.poll-meter.off:hover {
  background: rgba(10, 22, 40, 0.26);
}
.poll-meter.off .poll-ring-progress { stroke: rgba(255, 255, 255, 0.25); }
.poll-meter.off .dot { background: rgba(255, 255, 255, 0.4); }
.poll-ring {
  position: relative;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
}
.poll-ring svg {
  position: absolute;
  inset: 0;
  transform: rotate(-90deg);
}
.poll-ring-track {
  stroke: rgba(255, 255, 255, 0.28);
  stroke-width: 2.5;
}
.poll-ring-progress {
  stroke: #ffffff;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 69.115;
  stroke-dashoffset: 69.115;
  transition: stroke .2s ease;
}
.poll-meter.busy .poll-ring-progress {
  stroke: var(--online);
  animation: pollRingBusy 1.35s ease-in-out infinite;
}
.poll-meter .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 0 0 0 rgba(255,255,255,.4);
  position: relative;
  z-index: 1;
  transition: background .15s ease, transform .15s ease;
}
.poll-meter .dot.tick {
  animation: tickPulse 0.35s ease-out;
}
.poll-meter.busy .dot {
  animation: pingDot 1.1s ease-out infinite;
  background: var(--online);
}
@keyframes tickPulse {
  0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255,255,255,.45); }
  40% { transform: scale(1.35); box-shadow: 0 0 0 4px rgba(255,255,255,.16); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255,255,255,0); }
}
@keyframes pingDot {
  0% { box-shadow: 0 0 0 0 rgba(18,201,122,.5); }
  100% { box-shadow: 0 0 0 12px rgba(18,201,122,0); }
}
@keyframes pollRingBusy {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  border-radius: 11px;
  padding: 10px 14px;
  font: 650 0.84rem var(--font);
  cursor: pointer;
  transition: transform .12s ease, border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.btn[hidden] {
  display: none !important;
}
.btn:hover {
  transform: translateY(-1px);
  border-color: rgba(var(--accent-rgb), .35);
  box-shadow: 0 8px 18px rgba(var(--accent-rgb), .12);
}
.btn.primary {
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-hot) 100%);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 10px 22px rgba(var(--accent-rgb), .28);
  font-family: var(--display);
  letter-spacing: -0.01em;
}
.btn.primary:hover {
  box-shadow: 0 14px 28px rgba(var(--accent-rgb), .36);
  border-color: transparent;
}
.btn.save,
.btn.success {
  background: linear-gradient(135deg, #d4f08a 0%, #b5db55 48%, #9ccc3c 100%);
  border-color: rgba(90, 130, 20, 0.28);
  color: #2a3d0a;
  box-shadow: 0 8px 18px rgba(155, 190, 50, 0.28);
  font-family: var(--display);
  letter-spacing: -0.01em;
  font-weight: 700;
}
.btn.save:hover,
.btn.success:hover {
  box-shadow: 0 12px 24px rgba(155, 190, 50, 0.38);
  border-color: rgba(90, 130, 20, 0.4);
}
.btn.danger {
  background: linear-gradient(135deg, #ff5a72 0%, #e82045 100%);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 8px 18px rgba(232, 32, 69, 0.28);
  font-weight: 700;
  font-family: var(--display);
  letter-spacing: -0.01em;
}
.btn.danger:hover {
  background: linear-gradient(135deg, #ff6b80 0%, #d4163a 100%);
  border-color: transparent;
  box-shadow: 0 12px 24px rgba(232, 32, 69, 0.36);
}
.btn.cancel,
.icon-btn.cancel {
  background: linear-gradient(135deg, var(--cancel-0) 0%, var(--cancel-1) 55%, var(--cancel-2) 100%);
  border-color: var(--cancel-border);
  color: var(--cancel-ink);
  box-shadow: 0 8px 18px rgba(var(--cancel-rgb), 0.28);
  font-weight: 700;
  font-family: var(--display);
  letter-spacing: -0.01em;
}
.btn.cancel:hover,
.icon-btn.cancel:hover {
  background: linear-gradient(135deg, color-mix(in srgb, var(--cancel-0) 70%, #fff 30%) 0%, var(--cancel-0) 40%, var(--cancel-1) 100%);
  border-color: color-mix(in srgb, var(--cancel-border) 80%, var(--cancel-ink) 20%);
  box-shadow: 0 12px 24px rgba(var(--cancel-rgb), 0.36);
}
.btn.rescan {
  background: linear-gradient(135deg, var(--rescan-0) 0%, var(--rescan-1) 55%, var(--rescan-2) 100%);
  border-color: var(--rescan-border);
  color: var(--rescan-ink);
  box-shadow: 0 8px 18px rgba(var(--rescan-rgb), 0.28);
  font-weight: 700;
  font-family: var(--display);
  letter-spacing: -0.01em;
}
.btn.rescan:hover:not(:disabled) {
  background: linear-gradient(135deg, color-mix(in srgb, var(--rescan-0) 70%, #fff 30%) 0%, var(--rescan-0) 40%, var(--rescan-1) 100%);
  border-color: color-mix(in srgb, var(--rescan-border) 80%, var(--rescan-ink) 20%);
  box-shadow: 0 12px 24px rgba(var(--rescan-rgb), 0.36);
}
.btn.rescan:disabled,
.btn.rescan[disabled] {
  background: var(--input-disabled-bg);
  border-color: var(--line);
  color: var(--muted);
  box-shadow: none;
  cursor: not-allowed;
  opacity: 0.72;
  transform: none;
}
.btn.close,
.icon-btn.close {
  background: linear-gradient(135deg, #ffe082 0%, #ffc107 55%, #f5a623 100%);
  border-color: rgba(180, 120, 10, 0.35);
  color: #5a3a00;
  box-shadow: 0 6px 14px rgba(245, 166, 35, 0.28);
}
.btn.close:hover,
.icon-btn.close:hover {
  background: linear-gradient(135deg, #ffe9a0 0%, #ffca28 55%, #f0a010 100%);
  border-color: rgba(180, 120, 10, 0.45);
  box-shadow: 0 8px 18px rgba(245, 166, 35, 0.36);
}
.btn .btn-ico,
.icon-btn .btn-ico {
  width: 1em;
  height: 1em;
  flex-shrink: 0;
  display: block;
}
.btn.save .btn-ico,
.btn.success .btn-ico,
.btn.danger .btn-ico,
.btn.cancel .btn-ico,
.btn.rescan .btn-ico {
  width: 0.95em;
  height: 0.95em;
}
.btn.ghost { background: var(--chip); }
.btn.block { width: 100%; }
.btn.active {
  border-color: var(--accent-2);
  color: #c45a00;
  background: var(--soft-amber);
}

.palette {
  position: relative;
  background: var(--palette-bg, var(--panel));
  border-right: 1px solid var(--line);
  padding: 0 0 18px;
  overflow: auto;
  backdrop-filter: blur(10px);
  min-width: 0;
  transition: padding 0.28s ease, border-color 0.28s ease, background 0.22s ease;
}
#app.palette-collapsed .palette {
  position: absolute;
  top: calc(76px + 12px);
  left: 12px;
  width: auto;
  height: auto;
  z-index: 20;
  padding: 0;
  margin: 0;
  overflow: visible;
  display: block;
  background: transparent;
  border: 0;
  border-right: 0;
  backdrop-filter: none;
  box-shadow: none;
  pointer-events: none;
}
#app.palette-collapsed .palette > :not(.palette-bar) {
  display: none !important;
}
#app.palette-collapsed .palette-bar > :not(.palette-topbar),
#app.palette-collapsed .palette-doc {
  display: none !important;
}
#app.palette-collapsed .palette-bar {
  display: block;
  pointer-events: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  box-shadow: none;
}
#app.palette-collapsed .palette-topbar {
  display: block;
  pointer-events: none;
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
}
.palette-bar {
  margin: 0 0 12px;
  padding: 12px 14px 14px;
  background: linear-gradient(135deg, var(--topbar-0) 0%, var(--topbar-1) 55%, var(--topbar-2) 100%);
  border-bottom: 1px solid var(--topbar-border);
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.1);
}
.palette-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 8px;
  min-width: 0;
}
.palette-toggle {
  flex-shrink: 0;
  padding: 9px;
  margin: 0;
  color: rgba(255, 255, 255, 0.92);
}
.palette-bar .palette-toggle:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.palette-bar .palette-toggle:focus-visible,
.palette-bar .palette-toggle.open {
  background: rgba(255, 255, 255, 0.24);
  color: #fff;
  box-shadow: 0 4px 14px rgba(0, 20, 60, 0.28);
  outline: none;
}
.palette-toggle .ico-komponen { display: none; }
.palette-toggle .ico-menu { display: block; }
.palette-pin {
  flex-shrink: 0;
  padding: 9px;
  margin: 0;
  color: rgba(255, 255, 255, 0.92);
}
.palette-bar .palette-pin:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.palette-bar .palette-pin:focus-visible,
.palette-bar .palette-pin.is-pinned {
  background: rgba(255, 255, 255, 0.24);
  color: #fff;
  box-shadow: 0 4px 14px rgba(0, 20, 60, 0.28);
  outline: none;
}
.palette-pin .ico-pin-filled { display: none; }
.palette-pin .ico-pin { display: block; }
.palette-pin.is-pinned .ico-pin { display: none; }
.palette-pin.is-pinned .ico-pin-filled { display: block; }
#app.palette-collapsed .palette-pin {
  display: none !important;
}
#app.palette-collapsed .palette-toggle {
  margin: 0;
  width: 40px;
  height: 40px;
  padding: 0;
  justify-content: center;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--topbar-0) 0%, var(--topbar-1) 55%, var(--topbar-2) 100%);
  border: 1px solid var(--topbar-border);
  color: #fff;
  box-shadow: var(--shadow);
  pointer-events: auto;
}
#app.palette-collapsed .palette-toggle:hover,
#app.palette-collapsed .palette-toggle:focus-visible {
  /* Keep topbar chrome — do not flash --accent blue (esp. light theme). */
  background:
    linear-gradient(rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.16)),
    linear-gradient(135deg, var(--topbar-0) 0%, var(--topbar-1) 55%, var(--topbar-2) 100%);
  color: #fff;
  border-color: var(--topbar-border);
  box-shadow: 0 4px 14px rgba(0, 20, 60, 0.28);
  outline: none;
}

/* Always-overlay open (peek or pinned): same 340px sidebar chrome; grid stays 1fr */
#app.palette-collapsed.palette-open .palette {
  top: 76px;
  left: 0;
  width: 340px;
  height: calc(100vh - 76px);
  max-height: none;
  overflow: auto;
  padding: 0 0 18px;
  background: var(--palette-bg, var(--panel));
  border: 0;
  border-right: 1px solid var(--line);
  border-radius: 0;
  backdrop-filter: blur(10px);
  box-shadow: none;
  pointer-events: auto;
}
#app.palette-collapsed.palette-open .palette > :not(.palette-bar) {
  display: grid !important;
}
#app.palette-collapsed.palette-open .palette-list {
  display: grid !important;
  gap: 10px;
  padding: 0 14px;
  align-items: stretch;
}
#app.palette-collapsed.palette-open .palette-bar > :not(.palette-topbar),
#app.palette-collapsed.palette-open .palette-doc {
  display: revert !important;
}
#app.palette-collapsed.palette-open .palette-doc {
  display: flex !important;
}
#app.palette-collapsed.palette-open .palette-bar {
  display: block;
  pointer-events: auto;
  margin: 0 0 12px;
  padding: 12px 14px 14px;
  background: linear-gradient(135deg, var(--topbar-0) 0%, var(--topbar-1) 55%, var(--topbar-2) 100%);
  border-bottom: 1px solid var(--topbar-border);
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.1);
  border-radius: 0;
}
#app.palette-collapsed.palette-open .palette-topbar {
  display: flex;
  pointer-events: auto;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin: 0 0 8px;
  min-width: 0;
  background: transparent;
  border: 0;
  padding: 0;
}
#app.palette-collapsed.palette-open .palette-pin {
  display: inline-flex !important;
  pointer-events: auto;
  width: auto;
  height: auto;
  padding: 9px;
  margin: 0;
  border: 0;
  border-radius: 12px;
  background: transparent;
  box-shadow: none;
  color: rgba(255, 255, 255, 0.92);
}
#app.palette-collapsed.palette-open .palette-pin:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
#app.palette-collapsed.palette-open .palette-pin:focus-visible,
#app.palette-collapsed.palette-open .palette-pin.is-pinned {
  background: rgba(255, 255, 255, 0.24);
  color: #fff;
  box-shadow: 0 4px 14px rgba(0, 20, 60, 0.28);
  outline: none;
}
#app.palette-collapsed.palette-open .palette-toggle {
  width: auto;
  height: auto;
  padding: 9px;
  margin: 0;
  border-radius: 12px;
  background: transparent;
  border: 0;
  color: rgba(255, 255, 255, 0.92);
  box-shadow: none;
}
#app.palette-collapsed.palette-open .palette-toggle:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  border-color: transparent;
  box-shadow: none;
}
#app.palette-collapsed.palette-open .palette-toggle:focus-visible,
#app.palette-collapsed.palette-open .palette-toggle.open {
  background: rgba(255, 255, 255, 0.24);
  color: #fff;
  border-color: transparent;
  box-shadow: 0 4px 14px rgba(0, 20, 60, 0.28);
  outline: none;
}
#app.palette-collapsed.palette-open .palette-bar h2,
#app.palette-collapsed.palette-open .palette h2 {
  display: block !important;
}

.palette-bar h2,
.palette h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: #fff;
  text-shadow: 0 1px 0 rgba(0, 20, 40, 0.2);
}
.palette-doc {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  min-width: 0;
  flex: 1 1 auto;
}
.palette-doc-name {
  min-width: 0;
  max-width: 140px;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 600 0.72rem var(--mono);
  color: rgba(255, 255, 255, 0.92);
  text-align: right;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 4px 8px;
  margin: 0;
  outline: none;
  box-shadow: none;
  caret-color: #fff;
}
.palette-doc-name::placeholder {
  color: rgba(255, 255, 255, 0.55);
}
.palette-doc-name:hover {
  border-color: rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.06);
}
.palette-doc-name:focus {
  border-color: rgba(255, 255, 255, 0.45);
  background: rgba(255, 255, 255, 0.12);
  max-width: 180px;
}
.palette-doc-status {
  flex-shrink: 0;
  padding: 3px 8px;
  border-radius: 999px;
  font: 700 0.62rem var(--font);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.palette-doc-status.is-saved {
  color: #0f7a45;
  background: rgba(18, 183, 106, 0.14);
  border: 1px solid rgba(18, 183, 106, 0.28);
}
.palette-doc-status.is-unsaved {
  color: #9a5b00;
  background: var(--unsaved-bg);
  border: 1px solid var(--unsaved-border);
}
/* Di bar gelap (palette-bar), pakai chip kontras tinggi */
.palette-bar .palette-doc-status.is-saved {
  color: #053821;
  background: #6eecc0;
  border: 1px solid rgba(255, 255, 255, 0.35);
}
.palette-bar .palette-doc-status.is-unsaved {
  color: #4a2a00;
  background: #ffc266;
  border: 1px solid rgba(255, 255, 255, 0.4);
}
.empty-props { color: var(--muted); font-size: 0.78rem; margin: 0 0 14px; line-height: 1.45; }
.multi-note {
  display: grid; gap: 6px;
  margin: 0 0 14px; padding: 12px;
  border-radius: 12px;
  border: 1px dashed rgba(var(--accent-rgb), .35);
  background: rgba(var(--accent-rgb), .07);
  color: var(--ink);
  font-size: 0.84rem;
}
.multi-note strong { font-family: var(--display); font-size: 0.95rem; }
.multi-note span { color: var(--muted); font-size: 0.78rem; }

.palette-list { display: grid; gap: 10px; padding: 0 14px; }
.palette-item {
  position: relative;
  display: grid;
  grid-template-columns: 48px 1fr auto;
  align-items: start;
  gap: 0 12px;
  padding: 10px 12px 10px 10px;
  border-radius: 16px;
  border: 1px solid var(--palette-item-border);
  background: var(--palette-item-bg);
  cursor: grab;
  user-select: none;
  overflow: hidden;
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.palette-item:hover {
  border-color: color-mix(in srgb, var(--tone) 45%, transparent);
  transform: translateY(-2px);
  box-shadow:
    0 12px 28px rgba(10, 22, 40, 0.08),
    0 0 0 3px color-mix(in srgb, var(--tone) 12%, transparent);
}
.palette-item:active,
.palette-item.dragging {
  cursor: grabbing;
  transform: scale(0.98);
  opacity: 0.92;
}
.palette-accent {
  position: absolute;
  left: 0; top: 12px; bottom: 12px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--tone);
  box-shadow: 0 0 12px color-mix(in srgb, var(--tone) 50%, transparent);
}
.palette-item .ico-wrap {
  width: 48px; height: 48px; border-radius: 14px;
  display: grid; place-items: center; flex-shrink: 0;
  background:
    radial-gradient(circle at 30% 25%, #fff, transparent 55%),
    color-mix(in srgb, var(--tone) 14%, white);
  border: 1px solid color-mix(in srgb, var(--tone) 22%, white);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.85);
}
.palette-item .ico-img {
  width: 30px; height: 30px; display: block; pointer-events: none;
}
.palette-item .ico-meta {
  display: grid; gap: 4px; min-width: 0;
}
.palette-item .ico-meta strong {
  font-size: 0.92rem; font-weight: 700; color: var(--ink);
  font-family: var(--display); letter-spacing: -0.03em;
  line-height: 1.1;
}
.palette-item .ico-meta .ico-desc {
  display: block;
  max-width: 100%;
  font-size: 0.7rem;
  line-height: 1.35;
  color: var(--muted);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.palette-item .ico-code {
  align-self: start;
  margin-top: 2px;
  font-family: var(--mono);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: color-mix(in srgb, var(--tone) 75%, #0a1628);
  background: color-mix(in srgb, var(--tone) 12%, white);
  border: 1px solid color-mix(in srgb, var(--tone) 22%, white);
  padding: 3px 7px;
  border-radius: 999px;
}
.palette-list.is-locked {
  opacity: 0.55;
  filter: grayscale(0.15);
}
.palette-list.is-locked .palette-item {
  cursor: not-allowed;
}
.stage-wrap {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 30%, var(--stage-glow), transparent 58%),
    linear-gradient(160deg, var(--stage-0), var(--stage-1));
  background-size: auto, auto;
}
/* Grid is drawn on #stage canvas (pan/zoom aware); keep blueprint backdrop only. */
.stage-wrap.show-grid {
  background:
    radial-gradient(circle at 50% 30%, var(--stage-glow), transparent 58%),
    linear-gradient(160deg, var(--stage-0), var(--stage-1));
  background-size: auto, auto;
}
#stage { width: 100%; height: 100%; display: block; cursor: default; touch-action: none; }
#stage.connect-mode { cursor: crosshair; }
.stage-wrap.locked #stage { cursor: default; }
.stage-wrap.locked .palette-item { pointer-events: none; } /* noop if outside */

.stage-dock-host {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.stage-dock-toggle {
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--dock-bg);
  color: var(--ink);
  box-shadow: 0 10px 22px rgba(10,22,40,.12);
  backdrop-filter: blur(10px);
  display: none;
  place-items: center;
  cursor: pointer;
  padding: 0;
  transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}
.stage-dock-toggle svg {
  width: 18px;
  height: 18px;
  display: block;
}
.stage-dock-toggle:hover,
.stage-dock-toggle:focus-visible {
  background: rgba(var(--accent-rgb), .12);
  color: var(--accent-hot);
  outline: none;
}

.stage-dock {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 8px;
  border-radius: 18px;
  border: 1px solid var(--line);
  background: var(--dock-bg);
  box-shadow: 0 12px 28px rgba(10,22,40,.1);
  backdrop-filter: blur(10px);
  transform-origin: top right;
  transition: opacity 0.2s ease, transform 0.22s ease, visibility 0.22s ease;
}

/* Fine pointer (desktop): collapse to floating icon until revealed */
@media (hover: hover) and (pointer: fine) {
  .stage-dock-host:not(.dock-open) .stage-dock-toggle {
    display: grid;
  }
  .stage-dock-host:not(.dock-open) .stage-dock {
    position: absolute;
    top: 0;
    right: 0;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: scale(0.92) translateY(-4px);
  }
  .stage-dock-host.dock-open .stage-dock-toggle {
    display: none;
  }
  .stage-dock-host.dock-open .stage-dock {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }
}

/* Touch / coarse pointer: always fully visible */
@media (hover: none), (pointer: coarse) {
  .stage-dock-toggle {
    display: none !important;
  }
  .stage-dock {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
  }
}
.dock-btn {
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: var(--ink);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.dock-btn svg { width: 18px; height: 18px; display: block; }
.dock-btn:hover { background: rgba(var(--accent-rgb), .1); color: var(--accent-hot); }
.dock-btn.active,
.dock-btn[aria-pressed="true"] {
  background: linear-gradient(135deg, var(--accent), var(--accent-hot));
  color: #fff;
  box-shadow: 0 8px 16px rgba(var(--accent-rgb), .28);
}
.dock-btn .ico-lock { display: none; }
.dock-btn[aria-pressed="true"] .ico-unlock { display: none; }
.dock-btn[aria-pressed="true"] .ico-lock { display: block; }
.dock-pct {
  border: 0;
  background: var(--chip);
  color: var(--ink);
  font: 700 0.7rem var(--mono);
  padding: 6px 4px;
  border-radius: 8px;
  min-width: 42px;
  cursor: pointer;
}
.dock-pct:hover { background: rgba(var(--accent-rgb), .12); color: var(--accent-hot); }
.dock-sep {
  width: 22px;
  height: 1px;
  background: var(--line);
  margin: 2px 0;
}
.zoom-rail {
  position: relative;
  height: 120px;
  width: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.zoom-track {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 50%;
  width: 4px;
  transform: translateX(-50%);
  border-radius: 999px;
  background: var(--chip);
  border: 1px solid var(--line);
  pointer-events: none;
}
.zoom-fill {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 0%;
  border-radius: inherit;
  background: linear-gradient(180deg, var(--accent), var(--accent-hot));
}
.zoom-thumb {
  position: absolute;
  left: 50%;
  top: 100%;
  width: 14px;
  height: 14px;
  margin: -7px 0 0;
  transform: translate(-50%, 0);
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-hot));
  border: 2px solid var(--surface);
  box-shadow: 0 2px 8px rgba(var(--accent-rgb), 0.35);
  pointer-events: none;
}
.zoom-slider {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: pointer;
  writing-mode: vertical-lr;
  direction: rtl;
  -webkit-appearance: slider-vertical;
  appearance: slider-vertical;
}
.stage-copy {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  z-index: 4;
  pointer-events: none;
  font: 600 0.72rem var(--font);
  letter-spacing: 0.04em;
  color: var(--stage-copy-ink);
  white-space: nowrap;
  user-select: none;
  padding: 6px 14px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--surface) 88%, var(--accent) 6%);
  border: 1px solid color-mix(in srgb, var(--accent) 18%, var(--stage-copy-border));
  box-shadow: 0 2px 10px rgba(15, 28, 55, 0.08);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.props-card {
  width: min(440px, 100%);
  max-height: min(86vh, 760px);
  grid-template-rows: auto 1fr;
}
.props-modal-body {
  overflow: auto;
  padding: 8px 18px 18px;
  display: grid;
  gap: 12px;
}
.props-modal-body .props-form { margin: 0; }
.props-modal-body .empty-props { margin: 8px 0 0; }

.props-form { display: none; gap: 12px; }
.props-form.show { display: grid; }
.props-form label {
  display: grid; gap: 6px;
  font-size: 0.74rem; color: var(--muted); font-weight: 600;
  letter-spacing: 0.02em; text-transform: uppercase;
}
.props-form input, .props-form select, .props-form textarea {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  border-radius: 11px;
  padding: 11px 12px;
  font: 500 0.9rem var(--font);
  text-transform: none;
  letter-spacing: 0;
  user-select: text;
  -webkit-user-select: text;
}
.props-form input:focus, .props-form select:focus, .props-form textarea:focus {
  outline: none; border-color: rgba(var(--accent-rgb), .55);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .14);
}
.link-type-select-wrap {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px;
  align-items: center;
}
.link-type-swatch {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--line);
  flex-shrink: 0;
  background: var(--accent);
}
.hidden { display: none !important; }

.live-box {
  display: grid; gap: 8px;
  padding: 12px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--live-box-bg);
}
.live-box > div { display: flex; justify-content: space-between; gap: 10px; font-size: 0.84rem; }
.live-box span { color: var(--muted); font-weight: 600; font-size: 0.72rem; text-transform: uppercase; }
.live-box strong { font-family: var(--mono); font-weight: 600; }
.prop-actions { display: grid; gap: 8px; margin-top: 4px; }

.status-online { color: var(--online); }
.status-offline { color: var(--offline); }
.status-unknown { color: var(--unknown); }

.device-hover-tip {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 8;
  min-width: 176px;
  max-width: 240px;
  padding: 9px 11px 10px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: 0 10px 24px rgba(10, 22, 40, 0.16);
  backdrop-filter: blur(10px);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(2px);
  transition: opacity .12s ease, transform .12s ease;
  will-change: opacity, transform;
}
.device-hover-tip.show {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.hover-tip-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
}
.hover-tip-label {
  font-family: var(--display);
  font-size: 0.86rem;
  letter-spacing: -0.01em;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hover-tip-type {
  margin-left: auto;
  flex-shrink: 0;
  font: 700 0.62rem var(--mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.hover-tip-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  font-size: 0.76rem;
  line-height: 1.5;
}
.hover-tip-row span {
  color: var(--muted);
  font-weight: 600;
  font-size: 0.65rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  flex-shrink: 0;
}
.hover-tip-row strong {
  font-family: var(--mono);
  font-weight: 600;
  color: var(--ink);
  text-align: right;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Connector path (from→to): full names, wrap instead of ellipsis; no "Jalur" label. */
.hover-tip-row-wrap {
  align-items: flex-start;
}
.hover-tip-row-wrap strong {
  overflow: visible;
  text-overflow: unset;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.hover-tip-row-path {
  display: block;
}
.hover-tip-row-path strong {
  display: block;
  width: 100%;
  text-align: left;
}
/* Status text must beat the ink color on .hover-tip-row strong */
.hover-tip-row strong.status-online { color: var(--online); }
.hover-tip-row strong.status-offline { color: var(--offline); }
.hover-tip-row strong.status-unknown { color: var(--unknown); }
/* Device-type icon (same assets/img/devices/*.svg as cards / palette). */
.hover-tip-device-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  object-fit: contain;
  display: block;
}
/* Tali type glyph (assets/img/links/*.svg), tinted via mask (white glyphs). */
.hover-tip-type-icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  background: currentColor;
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

.ctx-menu {
  position: fixed; z-index: 50; min-width: 220px;
  max-height: calc(100vh - 16px);
  /* Keep overflow visible so absolute submenus (Rapikan/Tipe/Buka) are not clipped. */
  overflow: visible;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 6px;
  display: flex;
  flex-direction: column;
}
/* Above modals (z-index 60) so text edit menu works in Properties/Settings */
#editCtxMenu.edit-ctx-menu {
  z-index: 90;
}
.ctx-menu #ctxDeviceItems,
.ctx-menu #ctxLinkItems {
  display: flex;
  flex-direction: column;
}
.ctx-menu button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: 0; background: transparent; color: var(--ink);
  text-align: left; padding: 10px 12px; border-radius: 9px;
  font: 600 0.84rem var(--font); cursor: pointer;
}
.ctx-menu button svg {
  width: 17px;
  height: 17px;
  flex-shrink: 0;
  display: block;
}
.ctx-menu button:hover { background: rgba(var(--accent-rgb), .1); color: var(--accent-hot); }
.ctx-menu button.danger { color: #c81e3a; }
.ctx-menu button:disabled,
.ctx-menu button.disabled {
  opacity: 0.42;
  cursor: not-allowed;
  pointer-events: none;
}
.ctx-selection-info {
  padding: 6px 12px 8px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--line);
  font: 700 0.72rem var(--font);
  letter-spacing: 0.02em;
  color: var(--muted);
}
.ctx-submenu-wrap {
  position: relative;
}
.ctx-submenu-trigger {
  display: flex !important;
  align-items: center;
  gap: 8px;
}
.ctx-chevron {
  margin-left: auto;
  color: var(--muted);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
}
.ctx-submenu-wrap:hover > .ctx-submenu-trigger,
.ctx-submenu-wrap.open > .ctx-submenu-trigger {
  background: rgba(var(--accent-rgb), .1);
  color: var(--accent-hot);
}
.ctx-submenu {
  position: absolute;
  /* Overlap parent slightly so the hover bridge never collapses across a gap
     (gap made Rapikan/Type flyouts unreachable — clicks fell through to the stage). */
  left: calc(100% - 2px);
  top: -6px;
  z-index: 51;
  min-width: 248px;
  max-height: min(70vh, 520px);
  overflow: auto;
  display: none;
  flex-direction: column;
  padding: 6px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.ctx-submenu-wrap:hover > .ctx-submenu,
.ctx-submenu-wrap.open > .ctx-submenu {
  display: flex;
}
.ctx-submenu-wrap.fly-left > .ctx-submenu {
  left: auto;
  right: calc(100% - 2px);
}
.ctx-submenu-wrap.fly-up > .ctx-submenu {
  top: auto;
  bottom: -6px;
}
.ctx-submenu .menu-sep {
  height: 1px;
  margin: 6px 4px;
  background: var(--line);
}
.ctx-submenu .menu-label {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px 4px;
  font: 700 0.68rem var(--font);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.ctx-submenu .menu-label svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  opacity: 0.85;
}
.ctx-submenu button.on {
  background: rgba(var(--accent-rgb), .12);
  color: var(--accent-hot);
}
.ctx-port-badge {
  margin-left: auto;
  font: 700 0.64rem var(--mono);
  padding: 1.5px 6px;
  border-radius: 4px;
  background: rgba(var(--accent-rgb), .12);
  color: var(--accent-hot);
  letter-spacing: 0.02em;
}
.ctx-port-status {
  font: 600 0.65rem var(--mono);
  color: var(--online);
}

.modal {
  position: fixed; inset: 0; z-index: 60;
  background: var(--modal-scrim);
  display: grid; place-items: center;
  padding: 20px;
}
.modal.modal-stack-top {
  z-index: 66;
}
/* Keep native text selection / right-click edit menu in form fields */
.modal input:not([type="button"]):not([type="submit"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]),
.modal textarea,
.palette-doc-name {
  user-select: text;
  -webkit-user-select: text;
}
.modal-card {
  width: min(920px, 100%);
  max-height: min(80vh, 720px);
  overflow: hidden;
  display: grid;
  grid-template-rows: auto auto 1fr;
  background: var(--modal-card-bg);
  border: 1px solid var(--line);
  border-radius: 20px;
  box-shadow: var(--shadow);
}
.modal-card header {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--line);
}
.modal-card h2 { margin: 0; font-family: var(--display); font-size: 1.25rem; letter-spacing: -0.03em; min-width: 0; }
.props-header-actions,
.settings-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.props-header-actions .btn,
.settings-header-actions .btn {
  padding: 7px 12px;
  font-size: 0.78rem;
  border-radius: 10px;
}
.props-header-actions .btn.save,
.settings-header-actions .btn.save {
  box-shadow: 0 6px 14px rgba(155, 190, 50, 0.24);
}
.props-header-actions .btn.save:hover,
.settings-header-actions .btn.save:hover {
  box-shadow: 0 8px 18px rgba(155, 190, 50, 0.34);
}
.props-header-actions .btn.danger {
  box-shadow: 0 6px 14px rgba(232, 32, 69, 0.24);
}
.icon-btn {
  width: 36px; height: 36px; border-radius: 11px; border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); font-size: 1.3rem; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform .12s ease, border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.icon-btn.close,
.icon-btn.cancel {
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1;
}
.icon-btn.close .btn-ico,
.icon-btn.cancel .btn-ico {
  width: 18px;
  height: 18px;
}
.report-body { overflow: auto; padding: 12px 18px 18px; }
.report-period-gate {
  padding: 18px 20px 20px;
  display: grid;
  gap: 14px;
}
.report-period-desc {
  margin: 0;
  font: 500 0.9rem/1.45 var(--font);
  color: var(--muted, var(--ink));
  opacity: 0.85;
}
.report-period-fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.report-period-fields label {
  display: grid;
  gap: 6px;
  font: 600 0.78rem var(--font);
  color: var(--ink);
}
.report-period-fields input[type="date"] {
  width: 100%;
  min-height: 40px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--ink);
  font: 500 0.9rem var(--font);
}
.report-period-error {
  margin: 0;
  font: 600 0.82rem var(--font);
  color: var(--offline, #e82045);
}
.report-period-actions {
  margin-top: 4px;
}
.report-period-label {
  margin: 0 0 10px;
  font: 600 0.86rem var(--font);
  color: var(--ink);
  opacity: 0.9;
}
.report-empty-notice {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--surface);
  font: 500 0.84rem/1.4 var(--font);
  color: var(--ink);
  opacity: 0.88;
}
@media (max-width: 520px) {
  .report-period-fields {
    grid-template-columns: 1fr;
  }
}
table { width: 100%; border-collapse: collapse; font-size: 0.86rem; }
th, td { padding: 10px 8px; border-bottom: 1px solid var(--line); text-align: left; }
th { color: var(--muted); font-weight: 700; font-size: 0.72rem; text-transform: uppercase; letter-spacing: .04em; }
td { font-family: var(--mono); }
/* Report table has several numeric columns (latency/%/polling) — keep them
   from wrapping so the row stays scannable; .report-body scrolls
   horizontally on narrow viewports instead of squeezing text. */
#reportTable { min-width: 760px; border-collapse: separate; border-spacing: 0; }
#reportTable thead th,
.report-body thead th {
  background: #e8edf4;
  background-clip: padding-box;
  color: #4a5568;
  border-bottom: 1px solid #d0d7e2;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 2;
}
#reportTable th, #reportTable td { white-space: nowrap; }
#reportTable th:nth-child(2), #reportTable td:nth-child(2) { white-space: normal; }

/* Sortable report headers (Status & Latency) — subtle pointer affordance
   plus a clear hint (bg tint + arrow) on whichever column is active. */
#reportTable th.sortable {
  cursor: pointer;
  user-select: none;
  transition: color .15s ease, background-color .15s ease;
}
#reportTable th.sortable:hover { color: var(--ink); background: var(--table-hover-bg); }
#reportTable th.sortable:active { background: var(--table-sorted-bg); }
#reportTable th.sortable.sorted { color: var(--table-sorted); background: var(--table-sorted-bg); }
#reportTable th .sort-arrow { margin-left: 4px; font-size: 0.68em; letter-spacing: 0; }
#reportTable th.col-num { cursor: default; }

.settings-card {
  width: min(640px, 100%);
  grid-template-rows: auto 1fr;
  max-height: min(92vh, 900px);
}
.scan-card {
  width: min(420px, 100%);
  grid-template-rows: auto 1fr;
}
.reports-card {
  width: min(920px, 100%);
  grid-template-rows: auto 1fr;
  height: auto;
  max-height: min(80vh, 720px);
}
.confirm-card {
  width: min(420px, 100%);
  grid-template-rows: auto auto auto;
  height: auto;
  max-height: min(90vh, 720px);
  align-self: center;
}
.confirm-modal-body {
  padding: 18px 20px 8px;
}
.confirm-modal-body p {
  margin: 0;
  font: 500 0.95rem var(--font);
  color: var(--ink);
  line-height: 1.45;
}
.confirm-modal-actions {
  padding: 12px 18px 18px;
}
.settings-card > header,
.props-card > header,
.scan-card > header,
.ping-card > header,
.traceroute-card > header,
.reports-card > header,
.confirm-card > header {
  padding: 16px 18px;
  border-bottom: 1px solid var(--topbar-border);
  background: linear-gradient(135deg, var(--topbar-0) 0%, var(--topbar-1) 55%, var(--topbar-2) 100%);
  box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.12);
}
.settings-card > header h2,
.props-card > header h2,
.scan-card > header h2,
.ping-card > header h2,
.traceroute-card > header h2,
.reports-card > header h2,
.confirm-card > header h2 {
  color: #fff;
  text-shadow: 0 1px 0 rgba(0, 30, 90, 0.25);
}
/* Print/Excel buttons need light/outline treatment so they read against
   the blue header instead of blending into it; the close button stays
   yellow, which already contrasts well. Print uses an outlined
   near-white "glass" style (blue border + blue text). Excel uses the
   classic Microsoft Excel green so it stands out as its own action and
   stays visually distinct from Print. */
.reports-card > header .btn.ghost {
  background: rgba(255, 255, 255, 0.92);
  border: 1.5px solid rgba(13, 79, 214, 0.55);
  color: #0d3f9e;
}
.reports-card > header .btn.ghost:hover {
  background: #fff;
  border-color: rgba(13, 79, 214, 0.75);
  box-shadow: 0 6px 14px rgba(0, 20, 60, 0.25);
}
.reports-card > header #btnExcelReport.btn.primary {
  background: #217346;
  border: 1.5px solid #1d6f42;
  color: #fff;
  box-shadow: 0 6px 14px rgba(0, 20, 60, 0.25);
}
.reports-card > header #btnExcelReport.btn.primary:hover {
  background: #1d6f42;
  box-shadow: 0 8px 18px rgba(0, 20, 60, 0.32);
}
.scan-modal-body {
  overflow: auto;
  padding: 14px 18px 18px;
  display: grid;
  gap: 12px;
  /* When the modal card stretches (mobile), keep auto rows content-sized
     instead of distributing free height into #scanSubnetTargetInfo. */
  align-content: start;
}
.scan-target-info {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  align-self: start;
  flex: 0 0 auto;
  height: auto;
  min-height: 0;
  gap: 6px 10px;
  padding: 10px 12px;
  border-radius: 11px;
  border: 1px solid var(--line);
  background: var(--live-box-bg);
  font: 600 0.82rem var(--font);
  color: var(--ink);
}
.scan-target-info strong { color: var(--accent-hot); }
.scan-target-info .ping-target-ip {
  margin-left: auto;
  font: 700 0.8rem var(--mono);
  color: var(--muted);
}
.scan-cidr-preview {
  margin: -2px 0 0;
  font: 600 0.78rem var(--mono);
  color: var(--muted);
}
.scan-cidr-preview strong { color: var(--accent-hot); font-weight: 700; }
.scan-modal-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}
/* Beat .prop-actions { display: grid } (same element) and grid-item stretch:
   width:auto alone still fills the track under justify-items:stretch. */
.prop-actions.scan-modal-actions,
#scanSubnetForm .scan-modal-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
.scan-modal-actions > .btn,
.prop-actions.scan-modal-actions > .btn,
#scanSubnetForm .scan-modal-actions > .btn {
  width: auto;
  max-width: max-content;
  flex: 0 0 auto;
  align-self: flex-end;
  justify-self: end;
}
.ping-card {
  width: min(600px, 100%);
  grid-template-rows: auto 1fr auto;
}
.ping-modal-body {
  overflow: hidden;
  padding: 14px 18px 16px;
  display: grid;
  min-height: 0;
}
.ping-terminal {
  display: grid;
  grid-template-rows: auto 1fr;
  min-height: 0;
  height: min(52vh, 420px);
  border-radius: 10px;
  overflow: hidden;
  background: #0c0c0c;
  border: 1px solid #000;
  box-shadow:
    0 14px 32px rgba(0, 0, 0, 0.35),
    inset 0 0 0 1px rgba(255, 255, 255, 0.04);
}
.ping-terminal-titlebar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: linear-gradient(180deg, #2c2c2c, #1c1c1c);
  border-bottom: 1px solid #000;
  font: 600 0.72rem var(--font);
  color: #cfcfcf;
}
.ping-terminal-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #5b6b86;
  flex-shrink: 0;
}
.ping-terminal-dot.live {
  background: var(--online);
  box-shadow: 0 0 0 0 rgba(18, 201, 122, 0.55);
  animation: pingDotPulse 1.1s ease-in-out infinite;
}
@keyframes pingDotPulse {
  0% { box-shadow: 0 0 0 0 rgba(18, 201, 122, 0.55); }
  70% { box-shadow: 0 0 0 5px rgba(18, 201, 122, 0); }
  100% { box-shadow: 0 0 0 0 rgba(18, 201, 122, 0); }
}
.ping-terminal-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.ping-terminal-status {
  margin-left: auto;
  flex-shrink: 0;
  color: #9aa5b1;
  font-weight: 700;
  letter-spacing: .02em;
}
.ping-terminal-output {
  overflow-y: auto;
  padding: 10px 14px 14px;
  font: 400 0.82rem/1.55 var(--mono);
  color: #cccccc;
  background: #0c0c0c;
}
.ping-terminal-output::-webkit-scrollbar {
  width: 10px;
}
.ping-terminal-output::-webkit-scrollbar-track {
  background: #0c0c0c;
}
.ping-terminal-output::-webkit-scrollbar-thumb {
  background: #333;
  border-radius: 999px;
}
.ping-line {
  white-space: pre-wrap;
  word-break: break-word;
}
.ping-line--prompt {
  color: #9aa5b1;
}
.ping-line--header {
  color: #f2f2f2;
}
.ping-line--reply {
  color: var(--online);
}
.ping-line--timeout {
  color: var(--offline);
}
.ping-line--error {
  color: var(--offline);
  font-weight: 700;
}
.ping-line--stats-title {
  color: #f2f2f2;
  font-weight: 700;
}
.ping-line--stats-indent {
  color: #cccccc;
}
/* Shared with the Scan Port modal (#modalScanPorts), which reuses these
   list/row/summary classes for its port-open/closed results. */
.ping-results-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 6px;
  min-height: 0;
}
.ping-result-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  font: 600 0.8rem var(--font);
}
.ping-result-row.ok {
  border-color: rgba(52, 168, 83, 0.35);
  background: rgba(52, 168, 83, 0.08);
  color: #1e7d3a;
}
.ping-result-row.fail {
  border-color: rgba(232, 32, 69, 0.3);
  background: rgba(232, 32, 69, 0.07);
  color: #b3123a;
}
.ping-result-num {
  font-family: var(--mono);
  color: var(--muted);
  min-width: 28px;
}
.ping-result-status {
  min-width: 56px;
}
.ping-result-detail {
  margin-left: auto;
  font-family: var(--mono);
  font-weight: 700;
}
.ping-result-row.pending {
  color: var(--muted);
  background: var(--surface-3);
}
.scan-port-row {
  cursor: pointer;
  transition: filter 0.12s ease, transform 0.12s ease;
}
.scan-port-row:hover {
  filter: brightness(0.97);
  transform: translateX(1px);
}
.scan-port-row:active {
  filter: brightness(0.93);
}
.ping-summary {
  margin: 0;
  font: 700 0.82rem var(--font);
  color: var(--ink);
}
.scan-ports-card {
  width: min(440px, 100%);
  grid-template-rows: auto 1fr auto;
}
.scan-ports-body {
  overflow: hidden;
  padding: 14px 18px 12px;
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
  gap: 10px;
  min-height: 0;
}
.scan-ports-range-field {
  display: grid;
  gap: 5px;
  margin: 0;
  font: 600 0.78rem var(--font);
  color: var(--ink);
}
.scan-ports-range-field input {
  width: 100%;
  font: 600 0.9rem var(--mono);
  letter-spacing: 0.02em;
  cursor: default;
}
.scan-ports-range-field input[readonly] {
  color: var(--ink);
  opacity: 0.92;
}
.scan-ports-spinner {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid rgba(var(--accent-rgb), 0.18);
  border-top-color: var(--accent);
  animation: spin 0.75s linear infinite;
  flex-shrink: 0;
}
.scan-ports-results-wrap {
  position: relative;
  min-height: 180px;
  max-height: min(42vh, 320px);
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-2);
  padding: 8px;
}
.scan-ports-results-wrap .ping-results-list {
  gap: 5px;
}
.scan-ports-loading {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  z-index: 1;
  padding: 16px;
}
.scan-ports-loading .scan-ports-spinner {
  width: 56px;
  height: 56px;
  border-width: 6px;
  animation-duration: 1.6s;
}
.scan-ports-elapsed {
  margin-top: 12px;
  font: 600 0.9rem var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--muted);
  text-align: center;
}
.scan-ports-empty {
  margin: 0;
  padding: 28px 14px;
  text-align: center;
  font: 600 0.82rem var(--font);
  color: var(--muted);
}
.scan-ports-empty.is-error {
  color: #b3123a;
}
.scan-ports-card.is-scanning .scan-ports-results-wrap {
  overflow: hidden;
}
.traceroute-card { width: min(680px, 100%); }
.traceroute-card .ping-terminal { height: min(58vh, 480px); }
.scan-results-card {
  width: min(920px, 100%);
  grid-template-rows: auto 1fr auto;
}
.scan-results-body {
  overflow: auto;
  padding: 14px 18px 6px;
  display: grid;
  gap: 10px;
  min-height: 0;
  user-select: text;
  -webkit-user-select: text;
}
.scan-results-summary {
  margin: 0;
  font: 600 0.82rem var(--font);
  color: var(--muted);
}
.scan-results-summary strong { color: var(--accent-hot); }
.scan-results-table-wrap {
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 12px;
  max-height: min(48vh, 420px);
}
#scanResultsTable { font-size: 0.82rem; }
#scanResultsTable thead th {
  position: sticky;
  top: 0;
  background: var(--table-head-bg);
  z-index: 1;
}
#scanResultsTable th.col-check,
#scanResultsTable td.col-check { text-align: center; width: 40px; }
#scanResultsTable th.col-check,
#scanResultsTable td.col-check,
#scanResultsTable td.scan-cell-type {
  user-select: none;
  -webkit-user-select: none;
}
#scanResultsTable tbody tr.is-existing { opacity: 0.62; }
#scanResultsTable tbody tr.is-unchecked { opacity: 0.5; }
#scanResultsTable select,
#scanResultsTable input[type="text"] {
  width: 100%;
  min-width: 96px;
  padding: 5px 7px;
  border: 1px solid var(--line);
  border-radius: 8px;
  font: 600 0.78rem var(--font);
  background: var(--surface);
  color: var(--ink);
}
#scanResultsTable select:disabled,
#scanResultsTable input:disabled {
  background: var(--input-disabled-bg);
  color: var(--muted);
  cursor: not-allowed;
}
#scanResultsTable td.scan-cell-latency {
  font: 700 0.82rem var(--mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: #39ff14;
  text-shadow: 0 0 10px rgba(57, 255, 20, 0.45);
  min-width: 72px;
}
#scanResultsTable td.scan-cell-latency.is-pending,
#scanResultsTable td.scan-cell-latency.is-miss {
  color: var(--muted);
  text-shadow: none;
  font-weight: 600;
}
#scanResultsTable td.scan-cell-ports {
  font: 600 0.74rem var(--mono);
  font-variant-numeric: tabular-nums;
  max-width: 220px;
  line-height: 1.45;
  word-break: break-word;
}
#scanResultsTable td.scan-cell-ports.is-scanning {
  color: var(--muted);
  font-family: var(--font);
  font-weight: 600;
}
#scanResultsTable .scan-port-chip {
  display: inline-block;
  margin: 1px 4px 1px 0;
  white-space: nowrap;
}
#scanResultsTable .scan-port-chip.has-note {
  font-family: var(--font);
}
.scan-result-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: 999px;
  font: 700 0.68rem var(--font);
  letter-spacing: .03em;
  text-transform: uppercase;
}
.scan-result-badge.new { background: rgba(22, 163, 74, 0.14); color: #16a34a; }
.scan-result-badge.existing { background: rgba(128, 144, 168, 0.16); color: var(--muted); }
.scan-modal-actions.scan-results-actions {
  margin: 10px 18px 16px;
}

.settings-body {
  overflow: auto;
  padding: 12px 18px 18px;
  display: grid;
  gap: 14px;
}
.settings-section {
  padding: 14px 14px 16px;
  border: 1px solid var(--settings-section-border);
  border-radius: 14px;
  background: var(--settings-section-bg);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8) inset;
  display: grid;
  gap: 12px;
}
.settings-section h3 {
  margin: 0;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(var(--accent-rgb), 0.14);
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--settings-h3);
}
.settings-desc {
  margin: -2px 0 0;
  color: var(--muted);
  font-size: 0.78rem;
  line-height: 1.4;
}
.bg-sched-hint {
  margin-top: 10px;
  padding: 12px 14px;
  display: grid;
  gap: 8px;
  border: 1px solid var(--settings-section-border);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--chip) 80%, var(--surface));
}
.bg-sched-hint > .settings-desc {
  margin: 0;
}
.bg-sched-label {
  font-size: 0.68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent-hot);
}
.bg-sched-cmd-row {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}
.bg-sched-cmd {
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 10px 12px;
  overflow-x: auto;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: var(--surface);
  font: 500 0.72rem/1.45 var(--mono);
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-all;
}
.bg-sched-cmd-row .btn {
  flex-shrink: 0;
  align-self: stretch;
}
.settings-subhead {
  margin: 6px 0 0;
  padding-top: 12px;
  border-top: 1px dashed var(--line);
  color: var(--accent-hot);
  font-size: 0.68rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.settings-subhead:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}
#portScanExtras {
  display: grid;
  gap: 12px;
}
.port-table-wrap {
  display: grid;
  gap: 10px;
}
.port-table-label {
  font-size: 0.74rem;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.port-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--surface);
}
.port-table thead th {
  padding: 8px 10px;
  text-align: left;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  background: color-mix(in srgb, var(--chip) 70%, transparent);
  border-bottom: 1px solid var(--line);
}
.port-table thead th.port-table-drag-col {
  width: 2.4rem;
  padding-left: 6px;
  padding-right: 4px;
}
.port-table thead th:last-child {
  width: 2.6rem;
}
.port-table tbody td {
  padding: 6px 8px;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 80%, transparent);
  vertical-align: middle;
}
.port-table tbody tr:last-child td {
  border-bottom: 0;
}
.port-table tbody td.port-table-port-cell {
  width: 5.5rem;
}
.port-table tbody td.port-table-drag {
  width: 2.4rem;
  padding-left: 6px;
  padding-right: 4px;
  text-align: center;
  user-select: none;
}
.port-row-drag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.85rem;
  height: 1.85rem;
  min-width: 1.85rem;
  border-radius: 8px;
  color: var(--muted);
  font-size: 0.78rem;
  letter-spacing: -0.12em;
  line-height: 1;
  cursor: grab;
  touch-action: none;
}
.port-row-drag:hover,
.port-row-drag:focus-visible {
  color: var(--ink);
  background: color-mix(in srgb, var(--chip) 80%, transparent);
  outline: none;
}
.port-row-drag:active,
.port-table tbody tr.is-dragging .port-row-drag {
  cursor: grabbing;
}
.port-table tbody tr.is-dragging {
  opacity: 0.45;
}
.port-table tbody tr.drop-before td {
  box-shadow: inset 0 2px 0 0 color-mix(in srgb, var(--accent) 75%, transparent);
}
.port-table tbody tr.drop-after td {
  box-shadow: inset 0 -2px 0 0 color-mix(in srgb, var(--accent) 75%, transparent);
}
.port-table .port-table-port,
.port-table .port-table-note {
  width: 100%;
  margin: 0;
  border: 1px solid var(--line);
  background: var(--bg, var(--surface));
  color: var(--ink);
  border-radius: 8px;
  padding: 8px 10px;
  font: 500 0.85rem var(--font);
  text-transform: none;
  letter-spacing: 0;
}
.port-table .port-table-port {
  font-variant-numeric: tabular-nums;
}
.port-table-actions {
  text-align: center;
  width: 2.6rem;
  padding-left: 4px;
  padding-right: 4px;
}
.btn.port-row-del {
  width: 1.85rem;
  height: 1.85rem;
  min-width: 1.85rem;
  padding: 0;
  border-radius: 8px;
  font-size: 1.05rem;
  line-height: 1;
  font-weight: 700;
  color: var(--danger);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  border-color: color-mix(in srgb, var(--danger) 22%, var(--line));
  box-shadow: none;
}
.btn.port-row-del:hover {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  border-color: color-mix(in srgb, var(--danger) 40%, var(--line));
  color: var(--danger);
}
#btnAddCommonPort {
  justify-self: start;
  padding: 8px 12px;
  font-size: 0.82rem;
}
.settings-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.settings-body label {
  display: grid;
  gap: 6px;
  font-size: 0.74rem;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.settings-body input[type="number"],
.settings-body input[type="text"],
.settings-body input[type="password"],
.settings-body input[type="time"],
.settings-body select {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  border-radius: 11px;
  padding: 11px 12px;
  font: 500 0.9rem var(--font);
  text-transform: none;
  letter-spacing: 0;
  user-select: text;
  -webkit-user-select: text;
}
.settings-body select:disabled {
  background: var(--input-disabled-bg);
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.75;
}
.settings-range-label {
  display: grid;
  gap: 8px;
}
.settings-range-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.settings-range-val {
  font: 700 0.85rem var(--font);
  color: var(--ink);
  text-transform: none;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.settings-range-label input[type="range"] {
  width: 100%;
  margin: 0;
  accent-color: var(--accent);
  cursor: pointer;
}
.settings-range-label input[type="range"]:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}
.color-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.color-row input[type="color"] {
  width: 44px;
  height: 42px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--surface);
  cursor: pointer;
  flex-shrink: 0;
}
.color-row input[type="text"] {
  flex: 1;
  min-width: 0;
  font-family: "JetBrains Mono", ui-monospace, monospace;
  text-transform: lowercase;
}
.settings-body input:focus,
.settings-body select:focus {
  outline: none;
  border-color: rgba(var(--accent-rgb), .55);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .14);
}
.account-readonly {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--chip);
  color: var(--ink);
  border-radius: 11px;
  padding: 11px 12px;
  font: 600 0.9rem var(--mono);
  text-transform: none;
  letter-spacing: 0;
}
.account-section {
  gap: 14px;
}
.account-identity {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--line) 80%, transparent);
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(var(--accent-rgb), 0.12), transparent 55%),
    color-mix(in srgb, var(--chip) 70%, var(--surface));
}
.account-avatar {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  font: 800 1.05rem var(--display);
  color: #fff;
  background: linear-gradient(145deg, rgba(var(--accent-rgb), 0.95), rgba(var(--accent-rgb), 0.55));
  box-shadow: 0 8px 18px rgba(var(--accent-rgb), 0.22);
  text-transform: uppercase;
}
.account-identity-meta {
  min-width: 0;
  flex: 1;
  display: grid;
  gap: 2px;
}
.account-identity-label {
  font: 700 0.68rem/1.2 var(--font);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.account-identity .account-readonly {
  border: 0;
  background: transparent;
  padding: 0;
  font-size: 1rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.account-change-pill {
  flex-shrink: 0;
  padding: 5px 10px;
  border-radius: 999px;
  font: 700 0.7rem/1 var(--font);
  letter-spacing: 0.02em;
  color: rgba(var(--accent-rgb), 1);
  background: rgba(var(--accent-rgb), 0.12);
  border: 1px solid rgba(var(--accent-rgb), 0.22);
  animation: account-pill-in 0.28s ease;
}
.account-change-pill[hidden] {
  display: none !important;
}
@keyframes account-pill-in {
  from { opacity: 0; transform: translateY(4px) scale(0.96); }
  to { opacity: 1; transform: none; }
}
.account-password-grid[hidden] {
  display: none !important;
}
.account-password-grid {
  animation: account-password-in 0.28s ease;
}
@keyframes account-password-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
.account-field {
  display: grid;
  grid-template-rows: auto auto auto;
  align-content: start;
  gap: 6px;
  min-width: 0;
  width: 100%;
}
.account-input-wrap {
  position: relative;
  display: block;
  width: 100%;
  min-width: 0;
}
.account-input-wrap input {
  width: 100%;
  min-width: 0;
  height: 44px;
  box-sizing: border-box;
  padding-right: 44px;
}
.account-section .settings-grid > .account-field:not(:has(.account-visibility)) .account-input-wrap input {
  padding-right: 12px;
}
.account-visibility {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
}
.account-visibility:hover {
  color: var(--ink);
  background: color-mix(in srgb, var(--chip) 80%, transparent);
}
.account-visibility svg {
  width: 18px;
  height: 18px;
}
.account-visibility .eye-off {
  display: none;
}
.account-visibility.is-shown .eye-on {
  display: none;
}
.account-visibility.is-shown .eye-off {
  display: block;
}
.account-field-hint {
  min-height: 1.15em;
  margin: 0;
  font: 600 0.72rem/1.35 var(--font);
  color: var(--muted);
}
.account-field-hint.is-error {
  color: var(--offline);
}
.account-field-hint.is-ok {
  color: var(--online, #1f9d63);
}
.account-field.is-invalid .account-input-wrap input,
.account-field.is-invalid input {
  border-color: color-mix(in srgb, var(--offline) 55%, var(--line));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--offline) 16%, transparent);
}
.account-field.is-valid .account-input-wrap input,
.account-field.is-valid input {
  border-color: color-mix(in srgb, var(--online, #1f9d63) 45%, var(--line));
}
.account-strength {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: center;
}
.account-strength[hidden] {
  display: none !important;
}
.account-strength-bars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
.account-strength-bars span {
  height: 5px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--line) 80%, transparent);
  transition: background 0.2s ease, transform 0.2s ease;
}
.account-strength[data-level="1"] .account-strength-bars span:nth-child(1) {
  background: var(--offline);
}
.account-strength[data-level="2"] .account-strength-bars span:nth-child(-n+2) {
  background: #d39b2f;
}
.account-strength[data-level="3"] .account-strength-bars span {
  background: var(--online, #1f9d63);
}
.account-strength small {
  font: 700 0.7rem/1 var(--font);
  color: var(--muted);
  white-space: nowrap;
}
.account-checklist {
  list-style: none;
  margin: 0;
  padding: 10px 12px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 12px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--line) 85%, transparent);
  background: color-mix(in srgb, var(--chip) 55%, transparent);
}
.account-checklist[hidden] {
  display: none !important;
}
.account-checklist li {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font: 600 0.76rem/1.3 var(--font);
  color: var(--muted);
  transition: color 0.18s ease;
}
.account-check-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--muted) 55%, transparent);
  flex-shrink: 0;
  position: relative;
  transition: border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
.account-checklist li.is-done {
  color: var(--ink);
}
.account-checklist li.is-done .account-check-dot {
  border-color: var(--online, #1f9d63);
  background: var(--online, #1f9d63);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--online, #1f9d63) 18%, transparent);
}
.account-checklist li.is-done .account-check-dot::after {
  content: "";
  position: absolute;
  left: 3.5px;
  top: 1.5px;
  width: 4px;
  height: 7px;
  border: solid #fff;
  border-width: 0 1.7px 1.7px 0;
  transform: rotate(45deg);
}
.account-actions {
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.account-actions .settings-actions-left {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.account-status {
  margin: 0;
  flex: 1;
  min-width: 140px;
  text-align: right;
  font: 600 0.78rem/1.35 var(--font);
  color: var(--muted);
}
.account-status.is-error {
  color: var(--offline);
}
.account-status.is-ok {
  color: var(--online, #1f9d63);
}
.account-section #btnSaveAccount:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  filter: grayscale(0.15);
}
.account-section #btnSaveAccount.is-busy {
  pointer-events: none;
  opacity: 0.8;
}
.account-section #btnSaveAccount.is-busy .account-save-ico {
  animation: account-pulse 0.9s ease-in-out infinite;
}
@keyframes account-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.35; transform: scale(0.9); }
}
@media (max-width: 720px) {
  .account-checklist {
    grid-template-columns: 1fr;
  }
  .account-status {
    text-align: left;
    width: 100%;
  }
  .account-identity {
    flex-wrap: wrap;
  }
}
.switch-row {
  display: flex !important;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  text-transform: none !important;
  letter-spacing: 0 !important;
  font-size: 0.88rem !important;
  font-weight: 600 !important;
  color: var(--ink) !important;
  cursor: pointer;
}
.switch-row .switch-text {
  flex: 1;
  min-width: 0;
  line-height: 1.35;
}
.switch {
  position: relative;
  display: inline-block;
  width: 52px;
  height: 28px;
  flex-shrink: 0;
}
.switch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: 2;
}
.switch .slider {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: #c5cddb;
  box-shadow: inset 0 1px 2px rgba(10, 22, 40, 0.12);
  transition: background 0.18s ease, box-shadow 0.18s ease;
  pointer-events: none;
}
.switch .slider::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(10, 22, 40, 0.22);
  transition: transform 0.18s ease;
}
.switch .slider::after {
  content: "OFF";
  position: absolute;
  top: 50%;
  right: 7px;
  transform: translateY(-50%);
  font-size: 0.58rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: #5b6b86;
  line-height: 1;
  transition: opacity 0.15s ease, color 0.15s ease;
}
.switch input:checked + .slider {
  background: var(--online, #12c97a);
  box-shadow: inset 0 1px 2px rgba(10, 80, 40, 0.2);
}
.switch input:checked + .slider::before {
  transform: translateX(24px);
}
.switch input:checked + .slider::after {
  content: "ON";
  right: auto;
  left: 8px;
  color: rgba(255, 255, 255, 0.92);
}
.switch input:focus-visible + .slider {
  outline: none;
  box-shadow: 0 0 0 3px rgba(18, 201, 122, 0.28);
}
.switch input:checked:focus-visible + .slider {
  box-shadow: 0 0 0 3px rgba(18, 201, 122, 0.28);
}
.settings-actions {
  display: flex;
  justify-content: flex-start;
  gap: 10px;
  flex-wrap: wrap;
  padding-top: 12px;
  margin-top: 4px;
  border-top: 1px solid var(--line);
}
.settings-actions-left {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.toast {
  position: fixed; right: 18px; bottom: 18px; z-index: 70;
  background: var(--toast-bg); color: var(--toast-ink);
  border: 1px solid rgba(255,255,255,.08);
  padding: 12px 16px; border-radius: 12px; box-shadow: var(--shadow);
  max-width: 360px; font-size: 0.86rem; font-weight: 500;
}
/* Full-screen scan overlay — scoped to #busy so .poll-meter.busy never inherits inset:0. */
#busy {
  position: fixed; inset: 0; z-index: 80;
  background: var(--modal-scrim);
  display: grid; place-items: center;
  color: var(--ink);
  padding: 20px;
}
.busy-card {
  position: relative;
  width: min(420px, 100%);
  max-height: none;
  overflow: visible;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 20px;
  box-shadow: var(--shadow);
  padding: 22px;
  display: grid;
  justify-items: center;
  gap: 10px;
  text-align: center;
}
.busy-cancel {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
}
#busy .spinner {
  width: 42px; height: 42px; border-radius: 50%;
  border: 3px solid rgba(var(--accent-rgb), .16);
  border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}
#busy #busyText {
  margin: 0;
  font-weight: 700;
  font-family: var(--display);
  font-size: 1.1rem;
  letter-spacing: -0.02em;
}
.busy-progress {
  width: 100%;
  display: grid;
  gap: 8px;
  margin-top: 6px;
  text-align: left;
}
.busy-bar {
  height: 12px;
  border-radius: 999px;
  background: var(--progress-track);
  overflow: hidden;
  border: 1px solid var(--line);
}
.busy-bar-fill {
  height: 100%;
  width: 0%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width .25s ease;
}
:root .busy-bar-fill,
[data-theme="light"] .busy-bar-fill {
  background: linear-gradient(90deg, #ef4444, #facc15);
}
.busy-meta {
  display: flex;
  justify-content: space-between;
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--muted);
}
.busy-detail, .busy-found {
  margin: 0;
  font-size: 0.82rem;
  color: var(--muted);
  font-family: var(--mono);
  white-space: normal;
  overflow: visible;
  text-overflow: unset;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.busy-found { color: var(--accent); font-weight: 700; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Hide tool labels early so the single-row toolbar fits without overflow scrolling */
@media (max-width: 1280px) {
  .icon-tool span { display: none; }
  .icon-tool { padding: 9px; }
  .brand p { display: none; }
}

@media (max-width: 980px) {
  #app {
    grid-template-columns: 56px 1fr;
    grid-template-rows: 64px 1fr;
  }
  #app.palette-collapsed {
    grid-template-columns: 1fr;
    grid-template-rows: 64px 1fr;
  }
  .palette {
    grid-row: 2;
    grid-column: 1;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 6px;
    width: 56px;
    min-width: 56px;
    max-width: 56px;
    padding: 8px 6px;
    overflow-x: hidden;
    overflow-y: auto;
    border-right: 1px solid var(--topbar-border);
    border-bottom: 0;
    -webkit-overflow-scrolling: touch;
    background: linear-gradient(180deg, var(--topbar-0) 0%, var(--topbar-1) 55%, var(--topbar-2) 100%);
  }
  #app.palette-collapsed .palette {
    top: calc(64px + 12px);
    left: 12px;
    grid-row: auto;
    grid-column: auto;
    width: auto;
    min-width: 0;
    max-width: none;
    padding: 0;
    display: block;
    background: transparent;
    border-right: 0;
  }
  #app.palette-collapsed .stage-wrap {
    grid-column: 1;
    grid-row: 2;
  }
  .stage-wrap {
    grid-column: 2;
    grid-row: 2;
  }
  .palette-bar {
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
  }
  .palette-topbar {
    flex-direction: column;
    align-items: center;
    margin: 0 0 4px;
    gap: 0;
  }
  .palette-toggle { margin: 0; padding: 8px; }
  .palette-bar h2,
  .palette h2,
  .palette-foot,
  .palette-doc { display: none !important; }
  .palette-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: center;
    padding: 0;
  }
  .palette-item {
    min-width: 0;
    width: 44px;
    padding: 4px;
    display: grid;
    place-items: center;
    grid-template-columns: 1fr;
    gap: 0;
  }
  .palette-item .ico-meta,
  .palette-item .ico-code,
  .palette-item .palette-accent { display: none; }
  .palette-item .ico-wrap {
    width: 40px;
    height: 40px;
    border-radius: 12px;
    margin: 0;
  }
  .palette-item .ico-img { width: 22px; height: 22px; }

  .topbar {
    grid-column: 1 / -1;
    padding: 0 10px 0 8px;
    gap: 8px;
  }
  .topbar-left { gap: 8px; }
  .brand h1 { font-size: 1.2rem; }
  .brand-logo { width: 36px; height: 36px; border-radius: 11px; }
  /* Horizontal scroll for icon tools. Note: overflow-x ≠ visible forces the
     other axis to clip too — flyouts must use .flyout-fixed (position:fixed). */
  .toolbar {
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
    scrollbar-width: none;
  }
  .toolbar::-webkit-scrollbar { display: none; }
  .file-menu {
    z-index: 55;
  }
  .topbar-uptime { display: none; }
  .poll-meter #pollLabel { display: none; }
  .poll-meter { padding: 4px 8px; min-width: 0; }

  .stage-dock-host {
    top: 10px;
    right: 10px;
  }
  .stage-dock {
    flex-direction: column;
    padding: 8px 6px;
    gap: 4px;
  }
  .zoom-rail { height: 88px; }
  .stage-copy {
    bottom: 8px;
    font-size: 0.65rem;
    padding: 5px 10px;
    max-width: calc(100% - 72px);
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* Narrow: overlay open still shows full component list (not icon rail) */
@media (max-width: 980px) {
  #app.palette-collapsed.palette-open .palette {
    top: 64px;
    left: 0;
    width: 340px;
    max-width: min(340px, 100vw);
    height: calc(100vh - 64px);
    max-height: none;
    padding: 0 0 18px;
    background: var(--palette-bg, var(--panel));
    border: 0;
    border-right: 1px solid var(--line);
    border-radius: 0;
    box-shadow: none;
  }
  #app.palette-collapsed.palette-open .palette-bar {
    margin: 0 0 12px;
    padding: 12px 14px 14px;
    background: linear-gradient(135deg, var(--topbar-0) 0%, var(--topbar-1) 55%, var(--topbar-2) 100%);
    border-bottom: 1px solid var(--topbar-border);
    box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.1);
    border-radius: 0;
  }
  #app.palette-collapsed.palette-open .palette-topbar {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    margin: 0 0 8px;
    gap: 10px;
  }
  #app.palette-collapsed.palette-open .palette-pin {
    display: inline-flex !important;
  }
  #app.palette-collapsed.palette-open .palette-bar h2,
  #app.palette-collapsed.palette-open .palette h2,
  #app.palette-collapsed.palette-open .palette-doc {
    display: flex !important;
  }
  #app.palette-collapsed.palette-open .palette-bar h2,
  #app.palette-collapsed.palette-open .palette h2 {
    display: block !important;
  }
  #app.palette-collapsed.palette-open .palette-list {
    display: grid !important;
    gap: 10px;
    padding: 0 14px;
    align-items: stretch;
  }
  #app.palette-collapsed.palette-open .palette-item {
    width: auto;
    min-width: 0;
    padding: 10px 12px 10px 10px;
    display: grid;
    grid-template-columns: 48px 1fr auto;
    gap: 0 12px;
    place-items: unset;
    align-items: start;
  }
  #app.palette-collapsed.palette-open .palette-item .ico-meta,
  #app.palette-collapsed.palette-open .palette-item .ico-code,
  #app.palette-collapsed.palette-open .palette-item .palette-accent {
    display: revert;
  }
  #app.palette-collapsed.palette-open .palette-item .ico-meta {
    display: grid;
    gap: 4px;
    min-width: 0;
  }
  #app.palette-collapsed.palette-open .palette-item .ico-code {
    display: inline-block;
  }
  #app.palette-collapsed.palette-open .palette-item .palette-accent {
    display: block;
  }
  #app.palette-collapsed.palette-open .palette-item .ico-wrap {
    width: 48px;
    height: 48px;
    border-radius: 14px;
  }
  #app.palette-collapsed.palette-open .palette-item .ico-img {
    width: 34px;
    height: 34px;
  }
}

@media (max-width: 640px) {
  html, body {
    height: 100%;
    height: 100dvh;
  }
  #app {
    height: 100%;
    height: 100dvh;
    grid-template-columns: 52px 1fr;
    grid-template-rows: 56px 1fr;
    padding-bottom: env(safe-area-inset-bottom, 0);
  }
  #app.palette-collapsed {
    grid-template-columns: 1fr;
    grid-template-rows: 56px 1fr;
  }

  .topbar {
    height: 56px;
    min-height: 56px;
    padding: 0 8px 0 6px;
    padding-left: max(6px, env(safe-area-inset-left, 0));
    padding-right: max(8px, env(safe-area-inset-right, 0));
  }
  .brand h1 { font-size: 1.05rem; }
  .brand-logo { width: 32px; height: 32px; border-radius: 10px; }
  .brand { gap: 8px; }
  .toolbar {
    padding: 2px;
    gap: 0;
    border-radius: 10px;
  }
  .topbar .icon-tool {
    padding: 6px;
    min-width: 30px;
    min-height: 30px;
    border-radius: 8px;
    justify-content: center;
  }
  .topbar .icon-tool svg {
    width: 14px;
    height: 14px;
  }
  .tool-sep { margin: 0 2px; height: 14px; }
  .top-actions { gap: 4px; }
  .user-chip {
    display: none;
  }
  /* Icon-only pill is ~square; keep ring centered inside overflow:hidden + radius clip. */
  .poll-meter {
    min-height: 30px;
    padding: 4px;
    line-height: 0;
  }
  .poll-meter .poll-ring {
    width: 20px;
    height: 20px;
  }
  .poll-meter .poll-ring svg {
    width: 20px;
    height: 20px;
  }

  .palette {
    width: 52px;
    min-width: 52px;
    max-width: 52px;
    padding: 6px 4px;
    gap: 4px;
  }
  #app.palette-collapsed .palette {
    top: calc(56px + 10px);
    width: auto;
    min-width: 0;
    max-width: none;
  }
  /* Overlay open: narrow icon-only strip (not 340px full cards) */
  #app.palette-collapsed.palette-open .palette {
    top: 56px;
    width: 68px;
    max-width: 68px;
    height: calc(100% - 56px);
    height: calc(100dvh - 56px);
  }
  #app.palette-collapsed.palette-open .palette-bar {
    margin: 0 0 6px;
    padding: 8px 4px 10px;
  }
  #app.palette-collapsed.palette-open .palette-topbar {
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 4px;
    margin: 0 0 4px;
  }
  #app.palette-collapsed.palette-open .palette-doc {
    display: none !important;
  }
  #app.palette-collapsed.palette-open .palette-bar h2,
  #app.palette-collapsed.palette-open .palette h2 {
    display: block !important;
    font-size: 0.58rem;
    letter-spacing: 0.01em;
    line-height: 1.15;
    text-align: center;
    margin: 0;
    padding: 0 2px;
  }
  #app.palette-collapsed.palette-open .palette-list {
    display: flex !important;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 0 6px;
  }
  #app.palette-collapsed.palette-open .palette-item {
    width: 48px;
    min-width: 48px;
    min-height: 48px;
    padding: 4px;
    display: grid;
    place-items: center;
    grid-template-columns: 1fr;
    gap: 0;
  }
  #app.palette-collapsed.palette-open .palette-item .ico-meta,
  #app.palette-collapsed.palette-open .palette-item .ico-code,
  #app.palette-collapsed.palette-open .palette-item .palette-accent {
    display: none !important;
  }
  #app.palette-collapsed.palette-open .palette-item .ico-wrap {
    width: 40px;
    height: 40px;
    border-radius: 12px;
    margin: 0;
  }
  #app.palette-collapsed.palette-open .palette-item .ico-img {
    width: 22px;
    height: 22px;
  }
  .palette-item {
    width: 42px;
    padding: 3px;
  }
  .palette-item .ico-wrap {
    width: 38px;
    height: 38px;
    border-radius: 11px;
  }
  .palette-item .ico-img { width: 20px; height: 20px; }

  .stage-dock-host {
    top: 8px;
    right: 8px;
  }
  .stage-dock {
    flex-direction: column;
    padding: 6px 5px;
    border-radius: 14px;
    gap: 4px;
  }
  .zoom-rail { display: none; }
  .dock-sep { width: 22px; height: 1px; margin: 2px 0; }
  .dock-btn {
    width: 40px;
    height: 40px;
    border-radius: 12px;
  }
  .dock-pct {
    min-width: 40px;
    min-height: 40px;
    display: grid;
    place-items: center;
    padding: 0 4px;
  }

  .stage-copy {
    bottom: max(12px, env(safe-area-inset-bottom, 0));
    left: 50%;
    font-size: 0.6rem;
    padding: 4px 10px;
  }

  .ctx-menu {
    max-width: min(280px, calc(100vw - 16px));
    max-height: min(70vh, 420px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .ctx-menu button {
    min-height: 44px;
    padding: 12px 14px;
    font-size: 0.9rem;
  }
  .ctx-submenu {
    position: static;
    display: none;
    box-shadow: none;
    border: 0;
    margin: 0 0 0 12px;
    padding: 0;
    min-width: 0;
  }
  .ctx-submenu-wrap.open > .ctx-submenu,
  .ctx-submenu-wrap:hover > .ctx-submenu {
    display: grid;
  }

  .file-menu {
    max-width: min(260px, calc(100vw - 16px));
    max-height: min(70vh, 420px);
    overflow-y: auto;
  }
  .file-submenu-wrap > .file-submenu {
    position: static;
    left: auto;
    right: auto;
    top: auto;
    margin: 2px 0 4px 10px;
    box-shadow: none;
    border: 0;
    padding: 0;
    display: none;
    background: transparent;
    min-width: 0;
  }
  .file-submenu-wrap.open > .file-submenu,
  .file-submenu-wrap:hover > .file-submenu {
    display: flex;
  }
  .file-menu button {
    min-height: 44px;
  }

  .modal {
    padding: 8px;
    padding-bottom: max(8px, env(safe-area-inset-bottom, 0));
    align-items: stretch;
  }
  .modal-card {
    width: 100%;
    max-height: min(94dvh, 94vh);
    border-radius: 16px;
  }
  .reports-card,
  .settings-card,
  .props-card,
  .ping-card,
  .scan-card,
  .scan-results-card {
    width: 100%;
    max-height: min(94dvh, 94vh);
  }
  #modalConfirm {
    align-items: center;
  }
  .confirm-card {
    width: min(420px, 100%);
    max-height: none;
    height: auto;
    align-self: center;
    grid-template-rows: auto auto auto;
  }
  .reports-card > header,
  .settings-card > header,
  .props-card > header,
  .ping-card > header,
  .scan-card > header,
  .confirm-card > header {
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 14px;
  }
  .reports-card > header h2,
  .settings-card > header h2,
  .props-card > header h2 {
    font-size: 1.05rem;
  }
  .report-header-actions,
  .props-header-actions,
  .settings-header-actions {
    flex-wrap: wrap;
    gap: 6px;
  }
  .report-body,
  .props-modal-body,
  .ping-modal-body,
  .scan-modal-body,
  .scan-ports-body {
    -webkit-overflow-scrolling: touch;
  }
  .prop-actions {
    flex-wrap: wrap;
    gap: 8px;
  }
  .prop-actions .btn {
    min-height: 44px;
    flex: 1 1 auto;
  }
  /* Keep scan modal CTAs content-sized; do not inherit flex:1 from .prop-actions .btn */
  .prop-actions.scan-modal-actions > .btn,
  #scanSubnetForm .scan-modal-actions > .btn,
  .scan-modal-actions > .btn {
    flex: 0 0 auto;
    width: auto;
    max-width: max-content;
    align-self: flex-end;
    justify-self: end;
  }

  .settings-grid { grid-template-columns: 1fr; }

  .toast {
    left: 12px;
    right: 12px;
    bottom: max(12px, env(safe-area-inset-bottom, 0));
    max-width: none;
  }

  #reportTable thead th,
  .report-body thead th {
    background: #e8edf4 !important;
    color: #4a5568;
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    z-index: 2;
    box-shadow: 0 1px 0 #d0d7e2;
  }
  #reportTable th.sortable:hover,
  #reportTable th.sortable:active {
    background: #dce3ee !important;
  }
  #reportTable th.sortable.sorted {
    background: #d5deec !important;
  }

  .device-hover-tip { display: none !important; }
}

@media (max-width: 640px) and (orientation: landscape) {
  #app {
    grid-template-columns: 48px 1fr;
    grid-template-rows: 48px 1fr;
  }
  .topbar { height: 48px; min-height: 48px; }
  .palette {
    width: 48px;
    min-width: 48px;
    max-width: 48px;
  }
  .stage-dock-host {
    top: 6px;
    right: 6px;
  }
  .stage-copy { display: none; }
}
