diff --git a/ui/builder.html b/ui/builder.html index 3113413..6c0f9d5 100644 --- a/ui/builder.html +++ b/ui/builder.html @@ -13,7 +13,7 @@ --accent:#4f6ef7;--accent-bg:#eef0ff; --red:#ef4444;--red-bg:#fee2e2; --green:#16a34a;--green-bg:#dcfce7; - --r:8px;--sh:0 1px 3px rgba(0,0,0,.08),0 1px 2px rgba(0,0,0,.05); + --r:8px;--sh:0 1px 3px rgba(0,0,0,.08),0 1px 2px rgba(0,0,0,.04); --dk:#1e1e2e;--dk2:#181825;--dk3:#313244;--dk4:#45475a; --dt:#cdd6f4;--dt2:#bac2de;--dt3:#6c7086; } @@ -30,94 +30,94 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;backgrou /* ── 레이아웃 ─────────────────────────────── */ .app-body{display:flex;flex:1;overflow:hidden} .builder-panel{width:460px;min-width:340px;background:var(--surface);border-right:1px solid var(--border);display:flex;flex-direction:column;overflow:hidden} -.panel-label{padding:10px 16px 8px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);border-bottom:1px solid var(--border);flex-shrink:0;background:var(--surface-alt)} -.builder-scroll{flex:1;overflow-y:auto;padding:14px} +.panel-lbl{padding:10px 16px 8px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);border-bottom:1px solid var(--border);flex-shrink:0;background:var(--surface-alt)} +.builder-scroll{flex:1;overflow-y:auto;padding:12px} .builder-scroll::-webkit-scrollbar{width:5px} .builder-scroll::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px} -/* ── 문서 루트 노드 ───────────────────────── */ -.root-node{display:flex;align-items:center;gap:8px;background:var(--surface-alt);border:1.5px solid var(--border);border-radius:var(--r);padding:7px 11px;margin-bottom:12px;transition:border-color .15s} -.root-node:focus-within{border-color:var(--border-focus);background:var(--surface)} +/* ── 문서 루트 ────────────────────────────── */ +.root-row{display:flex;align-items:center;gap:8px;background:var(--surface-alt);border:1.5px solid var(--border);border-radius:var(--r);padding:7px 10px;margin-bottom:10px;transition:border-color .15s} +.root-row:focus-within{border-color:var(--border-focus);background:var(--surface)} .root-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);flex-shrink:0} -.root-title-inp{flex:1;border:none;outline:none;font-size:13px;font-weight:500;background:transparent} -.root-title-inp::placeholder{color:var(--muted);font-weight:400} +.root-title{flex:1;border:none;outline:none;font-size:13px;font-weight:500;background:transparent} +.root-title::placeholder{color:var(--muted);font-weight:400} -/* ── 구분자 입력 (공통) ───────────────────── */ -.node-mark-inp{width:36px;text-align:center;font-size:15px;border:1px solid var(--border);border-radius:5px;padding:2px 3px;background:var(--surface);flex-shrink:0;outline:none} -.node-mark-inp:focus{border-color:var(--border-focus)} +/* ── 공통 입력 ────────────────────────────── */ +.mark-inp{width:34px;text-align:center;font-size:15px;border:1px solid var(--border);border-radius:5px;padding:2px 2px;background:var(--surface);flex-shrink:0;outline:none} +.mark-inp:focus{border-color:var(--border-focus)} +input,textarea,button,select{font-family:inherit} -/* ── 버튼 ─────────────────────────────────── */ -.btn-add-sec{display:flex;align-items:center;justify-content:center;gap:7px;width:100%;padding:9px;background:var(--accent-bg);color:var(--accent);border:1.5px dashed var(--accent);border-radius:var(--r);cursor:pointer;font-size:12px;font-weight:600;margin-bottom:12px;transition:all .15s} -.btn-add-sec:hover{background:var(--accent);color:#fff;border-style:solid} +/* ── 버튼 공통 ────────────────────────────── */ .iBtn{width:22px;height:22px;display:flex;align-items:center;justify-content:center;border-radius:4px;border:none;cursor:pointer;font-size:12px;background:transparent;color:var(--muted);transition:all .1s;flex-shrink:0} .iBtn:hover{background:var(--red-bg);color:var(--red)} -.iBtn.up:hover,.iBtn.dn:hover{background:var(--accent-bg);color:var(--accent)} -.sBtn{font-size:11px;padding:3px 9px;border-radius:4px;border:1px solid;cursor:pointer;font-weight:600;transition:all .12s} -.sBtn.blue{background:var(--accent-bg);color:var(--accent);border-color:var(--accent)} -.sBtn.blue:hover{background:var(--accent);color:#fff} +.iBtn.mv:hover{background:var(--accent-bg);color:var(--accent)} +.iBtn.eye{font-size:13px} +.iBtn.eye.off{color:var(--border)} +.add-node-btn{display:flex;align-items:center;justify-content:center;gap:6px;width:100%;padding:8px;background:var(--accent-bg);color:var(--accent);border:1.5px dashed var(--accent);border-radius:var(--r);cursor:pointer;font-size:12px;font-weight:600;margin-bottom:10px;transition:all .15s} +.add-node-btn:hover{background:var(--accent);color:#fff;border-style:solid} -/* ── 섹션 카드 ────────────────────────────── */ -.sec-list{display:flex;flex-direction:column;gap:9px} -.sec-card{border:1.5px solid var(--border);border-radius:var(--r);background:var(--surface);box-shadow:var(--sh)} -.sec-head{display:flex;align-items:center;gap:6px;padding:7px 9px;background:var(--surface-alt);border-bottom:1px solid var(--border);border-radius:calc(var(--r) - 1.5px) calc(var(--r) - 1.5px) 0 0} -.sec-name-input{flex:1;border:none;outline:none;font-size:13px;font-weight:500;background:transparent;min-width:0} -.sec-name-input::placeholder{color:var(--muted);font-weight:400} -.sec-body{padding:8px 9px 9px;display:flex;flex-direction:column;gap:8px} +/* ── 노드 카드 ────────────────────────────── */ +.node-list{display:flex;flex-direction:column;gap:8px} +.node-card{border:1.5px solid var(--border);border-radius:var(--r);background:var(--surface);box-shadow:var(--sh)} +.node-card.nested{border-color:var(--accent);border-left-width:3px} +.node-head{display:flex;align-items:center;gap:5px;padding:6px 8px;background:var(--surface-alt);border-bottom:1px solid var(--border);border-radius:calc(var(--r) - 1.5px) calc(var(--r) - 1.5px) 0 0} +.node-head.is-hidden{border-bottom:none;border-radius:calc(var(--r) - 1.5px)} +.name-inp{flex:1;border:none;outline:none;font-size:13px;font-weight:500;background:transparent;min-width:0} +.name-inp::placeholder{color:var(--muted);font-weight:400} +.node-body{padding:8px;display:flex;flex-direction:column;gap:6px} -/* ── 노드 설정 패널 ───────────────────────── */ -.node-settings{} -.ns-toggle{display:flex;align-items:center;gap:5px;padding:5px 9px;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);cursor:pointer;background:var(--surface-alt);border:1px solid var(--border);border-radius:5px;transition:all .12s;user-select:none} -.ns-toggle:hover{color:var(--accent);border-color:var(--accent);background:var(--accent-bg)} -.ns-toggle.open{border-radius:5px 5px 0 0;border-bottom-color:transparent;color:var(--accent);background:var(--accent-bg);border-color:var(--accent)} -.ns-arrow{font-size:8px;transition:transform .15s} -.ns-dot{width:6px;height:6px;border-radius:50%;background:var(--accent);flex-shrink:0} -.ns-body{border:1px solid var(--accent);border-top:none;border-radius:0 0 5px 5px;background:var(--surface);padding:10px;display:flex;flex-direction:column;gap:10px} -.ns-section{} -.ns-section-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:6px;display:flex;align-items:center;justify-content:space-between} -.ns-deco-grid{display:grid;grid-template-columns:1fr 1fr;gap:5px} -.ns-field{display:flex;flex-direction:column;gap:2px} -.ns-field-lbl{font-size:10px;color:var(--muted)} -.ns-field-inp{font-size:12px;border:1px solid var(--border);border-radius:4px;padding:3px 6px;background:var(--surface-alt)} -.ns-field-inp:focus{outline:none;border-color:var(--border-focus);background:#fff} -.ns-attr-row{display:flex;gap:4px;margin-bottom:4px;align-items:center} -.ns-attr-key{width:90px;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:3px 6px;background:var(--surface-alt)} -.ns-attr-val{flex:1;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:3px 6px;background:var(--surface-alt)} -.ns-attr-key:focus,.ns-attr-val:focus{outline:none;border-color:var(--border-focus);background:#fff} -.ns-empty{font-size:11px;color:var(--muted);font-style:italic;padding:2px 0} -.ns-value-row{display:flex;gap:6px;align-items:center} -.ns-dtype{flex:0 0 auto;min-width:130px;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:3px 6px;background:var(--surface-alt)} -.ns-dtype:focus{outline:none;border-color:var(--border-focus)} -.ns-value-inp{flex:1;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:3px 6px;background:var(--surface-alt)} -.ns-value-inp:focus{outline:none;border-color:var(--border-focus);background:#fff} -.ns-add-btn{font-size:10px;padding:1px 7px} +/* ── 섹션 (값 / 노드설정) ──────────────────── */ +.body-sec{border:1px solid var(--border);border-radius:6px;overflow:hidden} +.body-sec-hdr{display:flex;align-items:center;gap:6px;padding:5px 8px;background:var(--surface-alt);border-bottom:1px solid var(--border)} +.body-sec-title{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);flex:1} +.add-sel{font-size:11px;padding:2px 6px;border:1px solid var(--border);border-radius:4px;background:var(--surface);color:var(--text);cursor:pointer;outline:none;max-width:140px} +.add-sel:focus{border-color:var(--border-focus)} +.all-set{font-size:10px;color:var(--muted);font-style:italic} +.empty-hint{font-size:11px;color:var(--muted);font-style:italic;padding:7px 8px} +.body-sec-body{padding:7px 8px;display:flex;flex-direction:column;gap:6px} -/* ── 이름 목록 그룹 ───────────────────────── */ -.grp{border:1px solid var(--border);border-radius:6px;padding:8px;margin-bottom:7px;background:var(--surface-alt)} -.grp:last-child{margin-bottom:0} -.grp-head{display:flex;align-items:center;gap:6px;margin-bottom:6px} -.grp-type-badge{font-size:10px;font-weight:700;color:var(--muted);background:var(--surface);border:1px solid var(--border);border-radius:4px;padding:1px 6px;text-transform:uppercase;letter-spacing:.04em} -.grp-cat-badge{font-size:11px;color:var(--accent);background:var(--accent-bg);border-radius:4px;padding:1px 7px;font-weight:600;white-space:nowrap;max-width:100px;overflow:hidden;text-overflow:ellipsis} -.grp-names{width:100%;min-height:44px;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:5px 7px;resize:vertical;font-family:inherit;background:var(--surface);line-height:1.55} -.grp-names:focus{outline:none;border-color:var(--border-focus)} -.grp-opts{display:flex;flex-direction:column;gap:5px;margin-top:6px;padding-top:6px;border-top:1px dashed var(--border)} -.opt-row{display:flex;align-items:center;gap:6px} -.opt-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);width:40px;flex-shrink:0} +/* ── 값 아이템 ────────────────────────────── */ +.val-item{border:1px solid var(--border);border-radius:5px;background:var(--surface-alt);overflow:hidden} +.val-item.val-node{border:none;background:transparent;padding:0} +.val-head{display:flex;align-items:center;gap:5px;padding:4px 6px;background:var(--surface);border-bottom:1px solid var(--border)} +.val-type-badge{font-size:10px;font-weight:700;color:var(--muted);background:var(--surface-alt);border:1px solid var(--border);border-radius:3px;padding:1px 5px;text-transform:uppercase;letter-spacing:.04em;flex-shrink:0} +.val-cat-inp{flex:1;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:2px 6px;background:var(--surface);outline:none;min-width:0} +.val-cat-inp:focus{border-color:var(--border-focus)} +.val-cat-inp::placeholder{color:var(--muted)} +.val-body{padding:6px} +.val-names{width:100%;min-height:42px;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:4px 6px;resize:vertical;background:var(--surface);line-height:1.55;outline:none} +.val-names:focus{border-color:var(--border-focus)} +.val-data-inp{width:100%;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:4px 6px;background:var(--surface);outline:none} +.val-data-inp:focus{border-color:var(--border-focus)} +.val-data-ta{width:100%;min-height:60px;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:4px 6px;resize:vertical;background:var(--surface);font-family:monospace;line-height:1.5;outline:none} +.val-data-ta:focus{border-color:var(--border-focus)} +.val-opts{display:flex;flex-direction:column;gap:4px;margin-top:5px;padding-top:5px;border-top:1px dashed var(--border)} +.opt-row{display:flex;align-items:center;gap:5px} +.opt-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);width:36px;flex-shrink:0} .sep-chips{display:flex;gap:3px;flex-wrap:wrap} -.sep-chip{font-size:11px;padding:2px 8px;border-radius:4px;border:1px solid var(--border);background:var(--surface);color:var(--muted);cursor:pointer;font-weight:500;transition:all .1s;white-space:nowrap} +.sep-chip{font-size:11px;padding:2px 6px;border-radius:4px;border:1px solid var(--border);background:var(--surface);color:var(--muted);cursor:pointer;font-weight:500;transition:all .1s;white-space:nowrap} .sep-chip:hover{border-color:var(--accent);color:var(--accent)} .sep-chip.on{background:var(--accent);color:#fff;border-color:var(--accent)} -.sep-custom{width:52px;font-size:11px;border:1px solid var(--border);border-radius:4px;padding:2px 5px;background:var(--surface);text-align:center} -.sep-custom:focus{outline:none;border-color:var(--border-focus)} -.npl-input{width:46px;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:2px 5px;text-align:center;background:var(--surface)} -.npl-input:focus{outline:none;border-color:var(--border-focus)} -.npl-input:disabled{background:var(--surface-alt);color:var(--muted)} +.sep-cust{width:48px;font-size:11px;border:1px solid var(--border);border-radius:4px;padding:2px 4px;background:var(--surface);text-align:center;outline:none} +.sep-cust:focus{border-color:var(--border-focus)} +.npl-inp{width:44px;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:2px 4px;text-align:center;background:var(--surface);outline:none} +.npl-inp:focus{border-color:var(--border-focus)} +.npl-inp:disabled{background:var(--surface-alt);color:var(--muted)} +.opt-hint{font-size:10px;color:var(--muted)} -/* ── 하위노드 영역 ────────────────────────── */ -.children-area{display:flex;flex-direction:column;gap:6px} -.children-lbl{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)} -.children-list{display:flex;flex-direction:column;gap:8px;padding-left:12px;border-left:2px solid var(--border)} -.btn-add-child{align-self:flex-start;display:flex;align-items:center;gap:5px;font-size:11px;padding:4px 10px;background:var(--green-bg);color:var(--green);border:1px dashed var(--green);border-radius:6px;cursor:pointer;font-weight:600;transition:all .15s} -.btn-add-child:hover{background:var(--green);color:#fff;border-style:solid} +/* ── 노드 설정 ────────────────────────────── */ +.setting-row{display:flex;align-items:center;gap:5px;padding:3px 0} +.setting-lbl{font-size:11px;color:var(--muted);width:54px;flex-shrink:0} +.setting-inp{flex:1;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:3px 6px;background:var(--surface-alt);outline:none} +.setting-inp:focus{border-color:var(--border-focus);background:#fff} +.attrs-hdr{display:flex;align-items:center;gap:5px;margin-bottom:4px} +.attrs-lbl{font-size:11px;color:var(--muted);flex:1} +.add-attr-btn{font-size:10px;padding:1px 7px;border-radius:4px;border:1px solid var(--accent);background:var(--accent-bg);color:var(--accent);cursor:pointer;font-weight:600} +.add-attr-btn:hover{background:var(--accent);color:#fff} +.attr-row{display:flex;align-items:center;gap:4px;margin-bottom:3px} +.attr-key{width:80px;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:2px 5px;background:var(--surface-alt);outline:none} +.attr-val{flex:1;font-size:12px;border:1px solid var(--border);border-radius:4px;padding:2px 5px;background:var(--surface-alt);outline:none} +.attr-key:focus,.attr-val:focus{border-color:var(--border-focus);background:#fff} /* ── 미리보기 패널 ────────────────────────── */ .preview-panel{flex:1;display:flex;flex-direction:column;overflow:hidden;background:var(--dk)} @@ -147,16 +147,15 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;backgrou .modal-field label{font-size:12px;color:var(--muted);width:80px;flex-shrink:0} .modal-field input{font-size:13px;border:1.5px solid var(--border);border-radius:6px;padding:4px 8px;flex:1;outline:none} .modal-field input:focus{border-color:var(--border-focus)} -.modal textarea{width:100%;height:180px;font-family:monospace;font-size:12px;border:1.5px solid var(--border);border-radius:6px;padding:9px;resize:vertical;line-height:1.6} -.modal textarea:focus{outline:none;border-color:var(--border-focus)} +.modal textarea{width:100%;height:175px;font-family:monospace;font-size:12px;border:1.5px solid var(--border);border-radius:6px;padding:9px;resize:vertical;line-height:1.6;outline:none} +.modal textarea:focus{border-color:var(--border-focus)} .modal-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:12px} .mBtn{font-size:13px;padding:7px 16px;border-radius:6px;border:1px solid;cursor:pointer;font-weight:600} .mBtn.ok{background:var(--accent);color:#fff;border-color:var(--accent)} .mBtn.ok:hover{background:#3a5ce0} .mBtn.cancel{background:var(--surface);color:var(--muted);border-color:var(--border)} .mBtn.cancel:hover{background:var(--surface-alt)} -.sep{height:1px;background:var(--border);margin:10px 0} -input,textarea,button,select{font-family:inherit} +.hsep{height:1px;background:var(--border);margin:10px 0}
@@ -164,30 +163,25 @@ input,textarea,button,select{font-family:inherit}