:root {
  --bg: #f3f4f6; --panel: #ffffff; --panel-2: #f8fafc; --border: #e2e8f0; --text: #1f2937; --muted: #64748b;
  --accent: #2563eb; --accent-soft: #dbeafe; --hover: #eef2f7; --danger: #dc2626; --ok: #16a34a; --warn: #d97706;
  --grid-minor: #eef1f5; --grid-major: #dfe4ec; --page: #ffffff; --canvas-out: #e9ecf1;
  --wire: #334155; --wire-live: #dc2626; --wire-neutral: #2563eb; --wire-s: #ca8a04;
  --shadow: 0 8px 28px rgba(15, 23, 42, .16);
  --font: Pretendard, "Noto Sans KR", "Malgun Gothic", system-ui, sans-serif;
  color-scheme: light;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0f141b; --panel: #171d26; --panel-2: #1c2330; --border: #2b3442; --text: #e5e7eb; --muted: #94a3b8;
    --accent: #60a5fa; --accent-soft: #1e3a5f; --hover: #232c3a; --grid-minor: #1a2029; --grid-major: #222a36; --page: #11161d; --canvas-out: #0b0f14;
    --wire: #cbd5e1; --wire-live: #f87171; --wire-neutral: #60a5fa; --wire-s: #facc15; --shadow: 0 8px 28px rgba(0, 0, 0, .5); color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #0f141b; --panel: #171d26; --panel-2: #1c2330; --border: #2b3442; --text: #e5e7eb; --muted: #94a3b8;
  --accent: #60a5fa; --accent-soft: #1e3a5f; --hover: #232c3a; --grid-minor: #1a2029; --grid-major: #222a36; --page: #11161d; --canvas-out: #0b0f14;
  --wire: #cbd5e1; --wire-live: #f87171; --wire-neutral: #60a5fa; --wire-s: #facc15; --shadow: 0 8px 28px rgba(0, 0, 0, .5); color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; }
body { font: 13px/1.4 var(--font); color: var(--text); background: var(--bg); display: flex; flex-direction: column; user-select: none; -webkit-user-select: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
.spacer { flex: 1; }
.muted { color: var(--muted); }
.small { font-size: 11.5px; }
.pad { padding: 8px 10px; }
.link { border: 0; background: none; color: var(--accent); padding: 0 4px; }

/* ── 메뉴바 ── */
#menubar { height: 42px; display: flex; align-items: center; gap: 6px; padding: 0 10px; background: var(--panel); border-bottom: 1px solid var(--border); flex: none; }
.brand { display: flex; align-items: center; gap: 6px; font-weight: 700; font-size: 15px; margin-right: 6px; white-space: nowrap; }
.doc-name { border: 1px solid transparent; background: transparent; padding: 4px 6px; border-radius: 6px; width: 200px; font-weight: 600; }
.doc-name:hover { border-color: var(--border); }
.doc-name:focus { outline: none; border-color: var(--accent); background: var(--panel-2); }
#menus { display: flex; }
.menu-btn { border: 0; background: transparent; padding: 6px 10px; border-radius: 6px; }
.menu-btn:hover, .menu-btn.open { background: var(--hover); }
.save-state { color: var(--muted); font-size: 12px; margin-right: 6px; white-space: nowrap; }
.icon-btn { border: 0; background: transparent; width: 30px; height: 30px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; color: var(--text); flex: none; }
.icon-btn:hover { background: var(--hover); }
.menu-pop { position: fixed; z-index: 1000; min-width: 220px; background: var(--panel); border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow); padding: 5px; }
.menu-pop .mi { display: flex; align-items: center; gap: 10px; padding: 6px 10px; border-radius: 5px; white-space: nowrap; cursor: default; }
.menu-pop .mi:hover:not(.disabled) { background: var(--accent); color: #fff; }
.menu-pop .mi:hover:not(.disabled) .key { color: #e0e7ff; }
.menu-pop .mi.disabled { opacity: .4; }
.menu-pop .mi .lbl { flex: 1; }
.menu-pop .key { color: var(--muted); font-size: 11.5px; }
.menu-pop .sep { height: 1px; background: var(--border); margin: 4px 2px; }

/* ── 툴바 ── */
#toolbar { height: 40px; display: flex; align-items: center; gap: 3px; padding: 0 8px; background: var(--panel); border-bottom: 1px solid var(--border); flex: none; overflow-x: auto; scrollbar-width: none; }
#toolbar .sep { width: 1px; height: 22px; background: var(--border); margin: 0 5px; flex: none; }
.tb { border: 1px solid transparent; background: transparent; height: 28px; padding: 0 8px; border-radius: 6px; white-space: nowrap; display: inline-flex; align-items: center; gap: 4px; }
.tb:hover { background: var(--hover); }
.tb.active { background: var(--accent-soft); color: var(--accent); border-color: var(--accent); }
.tb:disabled { opacity: .35; cursor: default; }
.tb select { height: 22px; border: 1px solid var(--border); border-radius: 5px; background: var(--panel); }
.mode-switch, .layout-switch { display: inline-flex; border: 1px solid var(--border); border-radius: 7px; overflow: hidden; }
.mode-switch button, .layout-switch button { border: 0; background: var(--panel); height: 28px; padding: 0 12px; }
.mode-switch button.active { background: var(--accent); color: #fff; }
.mode-switch button[data-mode="run"].active { background: var(--ok); }
.layout-switch button.active { background: var(--accent-soft); color: var(--accent); }
.sim-status { font-variant-numeric: tabular-nums; color: var(--muted); white-space: nowrap; padding-right: 6px; }
.sim-status.fault { color: var(--danger); font-weight: 700; }

/* ── 본문 ── */
#main { flex: 1; display: flex; min-height: 0; overflow: hidden; position: relative; }
#sidebar { width: 236px; flex: none; overflow: hidden; background: var(--panel); border-right: 1px solid var(--border); display: flex; flex-direction: column; min-height: 0; }
#sidebar .search { padding: 8px; border-bottom: 1px solid var(--border); }
#sidebar .search input { width: 100%; height: 30px; border: 1px solid var(--border); border-radius: 6px; padding: 0 9px; background: var(--panel-2); }
#sidebar .search input:focus { outline: none; border-color: var(--accent); }
#palette { flex: 1; overflow-y: auto; overflow-x: hidden; scrollbar-gutter: stable; }
.lib-cat > summary { list-style: none; padding: 7px 12px; font-weight: 600; cursor: pointer; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 6px; background: var(--panel-2); }
.lib-cat > summary::-webkit-details-marker { display: none; }
.lib-cat > summary::before { content: '▸'; color: var(--muted); transition: transform .15s; }
.lib-cat[open] > summary::before { transform: rotate(90deg); }
.lib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(46px, 1fr)); gap: 3px; padding: 6px; border-bottom: 1px solid var(--border); }
.lib-item { aspect-ratio: 1; min-width: 0; overflow: hidden; border-radius: 6px; display: flex; flex-direction: column; align-items: center; justify-content: center; cursor: grab; border: 1px solid transparent; gap: 2px; padding: 2px; }
.lib-item:hover { background: var(--hover); border-color: var(--border); }
.lib-item.active { background: var(--accent-soft); border-color: var(--accent); }
.lib-item svg { width: 34px; height: 34px; overflow: visible; }
.lib-item .nm { font-size: 9.5px; color: var(--muted); text-align: center; line-height: 1.1; max-height: 22px; overflow: hidden; width: 100%; overflow-wrap: anywhere; word-break: keep-all; }
.sidebar-foot { border-top: 1px solid var(--border); padding: 8px; }
.link-btn { border: 0; background: transparent; color: var(--accent); padding: 4px; font-weight: 600; }
body.run #sidebar { opacity: .45; pointer-events: none; }

#canvasWrap { flex: 1; position: relative; overflow: hidden; background: var(--canvas-out); min-width: 120px; }
#canvas { width: 100%; height: 100%; display: block; cursor: default; touch-action: none; }
#canvas[data-tool="wire"] { cursor: crosshair; }
#canvas[data-tool="pan"], #canvas.panning { cursor: grab; }
#canvas[data-tool="place"] { cursor: copy; }
body.run #canvas { cursor: default; }
.page-bg { fill: var(--page); }
.grid-minor { stroke: var(--grid-minor); stroke-width: 1; }
.grid-major { stroke: var(--grid-major); stroke-width: 1; }
#canvas.grid-hidden #gridRect1 { display: none; }
#emptyHint { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; pointer-events: none; color: var(--muted); }
#emptyHint h2 { color: var(--text); margin: 0 0 8px; }
#emptyHint p { margin: 0 0 14px; line-height: 1.6; }
#emptyHint button { pointer-events: auto; }
#emptyHint[hidden] { display: none; }
#runBanner { position: absolute; top: 8px; left: 50%; transform: translateX(-50%); background: var(--ok); color: #fff; padding: 6px 12px; border-radius: 20px; font-weight: 600; box-shadow: var(--shadow); display: flex; gap: 10px; align-items: center; z-index: 5; }
#runBanner button { border: 0; background: #fff; color: var(--ok); border-radius: 12px; padding: 3px 10px; font-weight: 700; }
#runBanner[hidden] { display: none; }
button.primary { background: var(--accent); color: #fff; border: 0; border-radius: 6px; padding: 8px 14px; font-weight: 600; }
.btn { border: 1px solid var(--border); background: var(--panel-2); border-radius: 6px; padding: 5px 10px; }
.btn:hover { background: var(--hover); }
.btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
.btn.hold { user-select: none; }

#splitter { width: 6px; flex: none; cursor: col-resize; background: var(--border); }
#splitter:hover { background: var(--accent); }
#view3dWrap { width: 42%; flex: none; position: relative; min-width: 160px; background: #1e293b; border-left: 1px solid var(--border); }
#view3d { width: 100%; height: 100%; display: block; touch-action: none; }
#view3dBar { position: absolute; top: 6px; left: 6px; right: 6px; display: flex; gap: 4px; align-items: center; flex-wrap: wrap; pointer-events: none; }
#view3dBar > * { pointer-events: auto; }
#view3dBar button, #view3dBar label { border: 1px solid rgba(255,255,255,.2); background: rgba(15,23,42,.75); color: #e5e7eb; border-radius: 6px; padding: 3px 8px; font-size: 12px; display: inline-flex; align-items: center; gap: 4px; }
#view3dBar button:hover { background: rgba(37,99,235,.7); }
#view3dBar select, #kit3d { border: 1px solid rgba(255,255,255,.2); background: rgba(15,23,42,.75); color: #e5e7eb; border-radius: 6px; padding: 3px 6px; font-size: 12px; }
#view3dBar button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
#wireColors { display: inline-flex; gap: 3px; padding: 2px 4px; background: rgba(15,23,42,.75); border-radius: 6px; border: 1px solid rgba(255,255,255,.2); }
#wireColors .swatch { width: 16px; height: 16px; border-radius: 50%; border: 2px solid transparent; padding: 0; }
#wireColors .swatch.active { border-color: #fff; box-shadow: 0 0 0 1px #000; }
#view3dMsg { color: #fde68a; font-size: 12px; text-shadow: 0 1px 2px #000; padding: 2px 6px; }
#view3dTip { position: absolute; pointer-events: none; background: rgba(15,23,42,.85); color: #fff; padding: 3px 8px; border-radius: 5px; font-size: 12px; display: none; z-index: 3; white-space: nowrap; }
body[data-layout="2d"] #view3dWrap, body[data-layout="2d"] #splitter { display: none; }
body[data-layout="3d"] #canvasWrap, body[data-layout="3d"] #splitter { display: none; }
body[data-layout="3d"] #view3dWrap { flex: 1; width: auto; }

#props { width: 280px; flex: none; background: var(--panel); border-left: 1px solid var(--border); display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
.props-body { flex: 1; overflow-y: auto; padding: 10px 12px; }
.props-body h3 { margin: 0 0 2px; font-size: 14px; }
.field { display: flex; align-items: center; gap: 8px; margin: 7px 0; }
.field label { width: 96px; flex: none; color: var(--muted); font-size: 12px; }
.field input[type="text"], .field input[type="number"], .field select, .field textarea { flex: 1; min-width: 0; height: 28px; border: 1px solid var(--border); border-radius: 6px; padding: 0 8px; background: var(--panel-2); }
.field textarea { height: auto; padding: 6px 8px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--accent); }
.grp { margin: 14px 0 4px; font-weight: 600; font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; border-bottom: 1px solid var(--border); padding-bottom: 3px; }
.row { display: flex; gap: 6px; margin: 8px 0; flex-wrap: wrap; }
.state { display: flex; flex-direction: column; gap: 6px; margin: 6px 0; }
.state b.on { color: var(--ok); }
.help { padding-left: 18px; margin: 4px 0; color: var(--muted); }
.help li { margin: 4px 0; }
.tip { border-left: 3px solid var(--accent); padding-left: 8px; }
details.issues { border-top: 1px solid var(--border); max-height: 45%; display: flex; flex-direction: column; flex: none; }
details.issues[open] { min-height: 120px; }
details.issues > summary { list-style: none; padding: 8px 12px; font-weight: 600; cursor: pointer; background: var(--panel-2); display: flex; align-items: center; gap: 8px; }
details.issues > summary::-webkit-details-marker { display: none; }
.issue-list { overflow-y: auto; flex: 1; }
.badge { font-size: 11px; border-radius: 10px; padding: 1px 8px; font-weight: 600; }
.badge.err { background: #fee2e2; color: var(--danger); }
.badge.warn { background: #fef3c7; color: var(--warn); }
.badge.ok { display: none; }
.issue { display: flex; gap: 8px; padding: 6px 12px; border-bottom: 1px solid var(--border); cursor: pointer; font-size: 12px; line-height: 1.4; }
.issue:hover { background: var(--hover); }
.issue .ic { flex: none; width: 14px; font-weight: 700; }
.issue.error .ic { color: var(--danger); }
.issue.warn .ic { color: var(--warn); }
.issue.info .ic { color: var(--accent); }

#statusbar { height: 26px; display: flex; align-items: center; gap: 10px; padding: 0 10px; background: var(--panel); border-top: 1px solid var(--border); flex: none; font-size: 12px; color: var(--muted); }
#statusbar .icon-btn { width: 24px; height: 22px; }
.zoom-label { border: 0; background: none; color: var(--muted); min-width: 44px; }

/* ── SVG 회로 기호 ── */
#canvas .comp { cursor: grab; }
#canvas.dragging, #canvas.dragging .comp, #canvas.dragging .wire .hit { cursor: grabbing; }
body.run #canvas .comp { cursor: default; }
body.run #canvas .comp.operator, body.run #canvas .comp.role-protect, body.run #canvas .comp[data-id] .sym .body.on { cursor: pointer; }
.sym .hitbox { fill: transparent !important; stroke: none !important; pointer-events: all; }
.sym path, .sym circle, .sym rect, .sym polyline { stroke: var(--text); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.sym circle.dot { fill: var(--text); stroke: none; }
.sym .blade { stroke-width: 2; }
.sym .mark { stroke-width: 1.2; }
.sym .body { fill: var(--panel); }
.sym .coil { fill: var(--panel); }
.sym .coil.on { fill: #fde68a; stroke: #d97706; }
.sym .lamp { fill: color-mix(in srgb, var(--lc, #ef4444) 25%, var(--panel)); }
.sym .lamp.on { fill: var(--lc, #ef4444); filter: drop-shadow(0 0 6px var(--lc, #ef4444)); }
.sym .body.on { fill: #fde68a; stroke: #d97706; }
.sym text { fill: var(--text); stroke: none; font-family: var(--font); pointer-events: none; }
.sym .sym-text { font-size: 11px; font-weight: 700; }
.sym .tiny { font-size: 9.5px; }
.sym .tiny.trip { fill: var(--danger); font-weight: 700; }
.sym .free-text { font-size: 13px; }
.sym .bus-line { stroke: var(--text); stroke-width: 3; }
.comp[data-live="L"] .bus-line { stroke: var(--wire-live); }
.comp[data-live="N"] .bus-line { stroke: var(--wire-neutral); }
.comp[data-live="S"] .bus-line { stroke: var(--wire-s); }
.sym .bus-label { font-size: 12px; font-weight: 700; }
.bus-hit { stroke: transparent; stroke-width: 12; fill: none; cursor: move; }
.comp .label { font-size: 11px; fill: var(--muted); dominant-baseline: central; pointer-events: none; font-family: var(--font); }
.comp.selected .label { fill: var(--accent); }
.comp .port { fill: transparent; stroke: transparent; stroke-width: 1; cursor: crosshair; pointer-events: all; }
.comp:hover .port { fill: var(--accent); fill-opacity: .25; stroke: var(--accent); }
.comp .port:hover { fill-opacity: .85; stroke-width: 2; r: 8; }
.comp.selected .sym path, .comp.selected .sym circle:not(.lamp):not(.coil), .comp.selected .sym rect { stroke: var(--accent); }
.comp.selected .sym circle.dot { fill: var(--accent); }
.comp.closed .sym .blade { stroke: var(--ok); }
body.run .comp.powered .label { fill: var(--warn); font-weight: 700; }
.comp.issue-error .sym path, .comp.issue-error .sym circle, .comp.issue-error .sym rect { stroke: var(--danger); }
.comp.issue-warn .sym path, .comp.issue-warn .sym circle, .comp.issue-warn .sym rect { stroke: var(--warn); }
.port-hover { fill: var(--accent); fill-opacity: .35; stroke: var(--accent); stroke-width: 1.5; pointer-events: none; }
.junction { fill: var(--wire); }
.pneu-link { fill: none; stroke: #0ea5e9; stroke-width: 1.5; stroke-dasharray: 5 3; pointer-events: none; }
body.run .junction { fill: var(--text); }

.wire .hit { stroke: transparent; stroke-width: 12; fill: none; cursor: grab; }
.wire .line { stroke: var(--wire); stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; }
.wire.selected .line { stroke: var(--accent); stroke-width: 3; }
.wire.issue-error .line { stroke: var(--danger); stroke-width: 3; }
.wire.issue-warn .line { stroke: var(--warn); }
body.run .wire.live-L .line { stroke: var(--wire-live); }
body.run .wire.live-N .line { stroke: var(--wire-neutral); }
body.run .wire.live-S .line { stroke: var(--wire-s); }
body.run .wire.flow .line { stroke-dasharray: 6 5; animation: flow 0.6s linear infinite; stroke-width: 2.6; }
body.run .wire.fault .line { stroke: var(--danger); stroke-width: 4; animation: blink .4s steps(2) infinite; }
@keyframes flow { to { stroke-dashoffset: -11; } }
@keyframes blink { 50% { opacity: .3; } }
.draft { stroke: var(--accent); stroke-width: 2; stroke-dasharray: 5 4; fill: none; pointer-events: none; }
.band { fill: var(--accent); fill-opacity: .08; stroke: var(--accent); stroke-dasharray: 4 3; pointer-events: none; }
.issue-mark { fill: none; stroke-width: 2; pointer-events: none; }
.issue-mark.issue-error { stroke: var(--danger); }
.issue-mark.issue-warn { stroke: var(--warn); }
.flash { fill: var(--warn); fill-opacity: .12; stroke: var(--warn); stroke-width: 2; stroke-dasharray: 6 4; pointer-events: none; animation: blink .6s steps(2) 3; }

/* ── 모달 · 토스트 ── */
#modal { position: fixed; inset: 0; background: rgba(15, 23, 42, .45); z-index: 2000; display: flex; align-items: center; justify-content: center; }
#modal[hidden] { display: none; }
.dialog { background: var(--panel); border-radius: 10px; box-shadow: var(--shadow); min-width: 420px; max-width: min(760px, 92vw); max-height: 86vh; overflow: auto; padding: 18px 20px; }
.dialog h2 { margin: 0 0 12px; font-size: 17px; }
.dialog .ex { display: flex; gap: 12px; padding: 10px; border: 1px solid var(--border); border-radius: 8px; margin: 8px 0; cursor: pointer; align-items: center; }
.dialog .ex:hover { background: var(--hover); border-color: var(--accent); }
.dialog .ex b { display: block; margin-bottom: 2px; }
.dialog .ex p { margin: 0; color: var(--muted); font-size: 12px; }
.dialog .ex .no { width: 28px; height: 28px; border-radius: 50%; background: var(--accent-soft); color: var(--accent); display: flex; align-items: center; justify-content: center; font-weight: 700; flex: none; }
.dialog .actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.dialog table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.dialog td, .dialog th { border-bottom: 1px solid var(--border); padding: 5px 8px; text-align: left; vertical-align: top; }
.dialog kbd { background: var(--panel-2); border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; font-family: inherit; }
.dialog textarea { width: 100%; height: 200px; font-family: ui-monospace, Consolas, monospace; font-size: 12px; border: 1px solid var(--border); border-radius: 6px; padding: 8px; background: var(--panel-2); }
#toast { position: fixed; bottom: 40px; left: 50%; transform: translateX(-50%); z-index: 3000; display: flex; flex-direction: column; gap: 6px; align-items: center; pointer-events: none; }
#toast .t { background: #1e293b; color: #fff; padding: 8px 14px; border-radius: 8px; box-shadow: var(--shadow); font-size: 13px; animation: fadein .2s; max-width: 70vw; }
#toast .t.err { background: var(--danger); }
#toast .t.ok { background: var(--ok); }
@keyframes fadein { from { opacity: 0; transform: translateY(6px); } }

/* 임베드 */
body.embed #menubar { display: none; }
body.embed #sidebar { width: 200px; }
body.compact #props { display: none; }
body.compact #sidebar { display: none; }

@media (max-width: 900px) {
  #props { width: 230px; }
  #sidebar { width: 190px; }
}

/* 예제 탭 */
.ex-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 0 0 10px; }
.ex-tabs button { border: 1px solid var(--border); background: var(--panel-2); border-radius: 14px; padding: 4px 10px; font-size: 12px; }
.ex-tabs button.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.ex-list { max-height: 56vh; overflow-y: auto; }
.dialog.wide { min-width: 560px; max-width: min(900px, 94vw); }
