diff --git a/ts/index.html b/ts/index.html
index 51bf104..bdbfa6e 100644
--- a/ts/index.html
+++ b/ts/index.html
@@ -6,632 +6,7 @@
MonoDisplay Editor
-
+
diff --git a/ts/style.css b/ts/style.css
new file mode 100644
index 0000000..65e6be8
--- /dev/null
+++ b/ts/style.css
@@ -0,0 +1,624 @@
+:root {
+ --bg: #111;
+ --bg-bar: #1a1a1a;
+ --bg-raised: #161616;
+ --bg-hover: #1b1b1b;
+ --bg-hover2: #222;
+ --bg-sunken: #141414;
+ --bg-accent: #141e14;
+ --bg-active: #182018;
+ --bg-deep: #0f0f0f;
+ --bg-input: #0a0a0a;
+ --bg-canvas: #000;
+ --bg-xhover: #1e1010;
+ --bg-overlay: rgba(0,0,0,.6);
+ --bd: #2a2a2a;
+ --bd-inner: #1e1e1e;
+ --bd-deep: #1c1c1c;
+ --bd-card: #222;
+ --bd-btn: #2d2d2d;
+ --bd-type: #252525;
+ --bd-active: #2b3d2b;
+ --bd-hover: #444;
+ --bd-strong: #333;
+ --tx: #ccc;
+ --tx-hover: #bbb;
+ --tx-sub: #888;
+ --tx-label: #777;
+ --tx-meta: #666;
+ --tx-dim: #555;
+ --tx-faint: #444;
+ --tx-ghost: #333;
+ --tx-file: #3a3a3a;
+ --tx-empty: #2e2e2e;
+ --ac: #33ff66;
+ --dirty: #886622
+}
+
+@media (prefers-color-scheme: light) {
+ :root:not([data-theme="dark"]) {
+ --bg: #f5f5f5;
+ --bg-bar: #e8e8e8;
+ --bg-raised: #efefef;
+ --bg-hover: #e5e5e5;
+ --bg-hover2: #e0e0e0;
+ --bg-sunken: #ebebeb;
+ --bg-accent: #e8f5e8;
+ --bg-active: #dff0df;
+ --bg-deep: #f0f0f0;
+ --bg-input: #fff;
+ --bg-canvas: #fff;
+ --bg-xhover: #ffe8e8;
+ --bg-overlay: rgba(0,0,0,.4);
+ --bd: #d0d0d0;
+ --bd-inner: #ddd;
+ --bd-deep: #e0e0e0;
+ --bd-card: #ddd;
+ --bd-btn: #ccc;
+ --bd-type: #d8d8d8;
+ --bd-active: #7dc87d;
+ --bd-hover: #bbb;
+ --bd-strong: #ccc;
+ --tx: #222;
+ --tx-hover: #333;
+ --tx-sub: #555;
+ --tx-label: #666;
+ --tx-meta: #777;
+ --tx-dim: #888;
+ --tx-faint: #999;
+ --tx-ghost: #aaa;
+ --tx-file: #aaa;
+ --tx-empty: #bbb;
+ --ac: #1a9940;
+ --dirty: #b37a00
+ }
+}
+
+[data-theme="light"] {
+ --bg: #f5f5f5;
+ --bg-bar: #e8e8e8;
+ --bg-raised: #efefef;
+ --bg-hover: #e5e5e5;
+ --bg-hover2: #e0e0e0;
+ --bg-sunken: #ebebeb;
+ --bg-accent: #e8f5e8;
+ --bg-active: #dff0df;
+ --bg-deep: #f0f0f0;
+ --bg-input: #fff;
+ --bg-canvas: #fff;
+ --bg-xhover: #ffe8e8;
+ --bg-overlay: rgba(0,0,0,.4);
+ --bd: #d0d0d0;
+ --bd-inner: #ddd;
+ --bd-deep: #e0e0e0;
+ --bd-card: #ddd;
+ --bd-btn: #ccc;
+ --bd-type: #d8d8d8;
+ --bd-active: #7dc87d;
+ --bd-hover: #bbb;
+ --bd-strong: #ccc;
+ --tx: #222;
+ --tx-hover: #333;
+ --tx-sub: #555;
+ --tx-label: #666;
+ --tx-meta: #777;
+ --tx-dim: #888;
+ --tx-faint: #999;
+ --tx-ghost: #aaa;
+ --tx-file: #aaa;
+ --tx-empty: #bbb;
+ --ac: #1a9940;
+ --dirty: #b37a00
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0
+}
+
+body {
+ background: var(--bg);
+ color: var(--tx);
+ font-family: monospace;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ font-size: 12px
+}
+
+#topbar {
+ height: 36px;
+ background: var(--bg-bar);
+ border-bottom: 1px solid var(--bd);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 0 12px;
+ flex-shrink: 0
+}
+
+#topbar .app-name {
+ color: var(--tx-dim);
+ font-size: 11px;
+ letter-spacing: .12em;
+ text-transform: uppercase;
+ margin-right: 4px
+}
+
+.tb-btn {
+ background: var(--bg-raised);
+ color: var(--tx-sub);
+ border: 1px solid var(--bd-btn);
+ border-radius: 3px;
+ padding: 3px 10px;
+ font-family: monospace;
+ font-size: 11px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ white-space: nowrap
+}
+
+.tb-btn:hover {
+ background: var(--bg-hover2);
+ color: var(--tx-hover);
+ border-color: var(--bd-hover)
+}
+
+.tb-btn svg {
+ width: 13px;
+ height: 13px;
+ stroke: currentColor;
+ fill: none;
+ stroke-width: 1.8;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ flex-shrink: 0
+}
+
+#file-input {
+ display: none
+}
+
+#filename {
+ color: var(--tx-file);
+ font-size: 11px;
+ margin-left: 2px;
+ max-width: 200px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap
+}
+
+.tb-sep {
+ width: 1px;
+ height: 18px;
+ background: var(--bd)
+}
+
+.dirty {
+ color: var(--dirty) !important
+}
+
+#main {
+ flex: 1;
+ display: flex;
+ min-height: 0
+}
+
+#left {
+ width: 48%;
+ border-right: 1px solid var(--bd-inner);
+ display: flex;
+ flex-direction: column;
+ padding: 14px;
+ gap: 10px;
+ overflow-y: auto;
+ flex-shrink: 0
+}
+
+#display-box {
+ width: 100%;
+ aspect-ratio: 2/1;
+ background: var(--bg-canvas);
+ border: 1px solid var(--bd);
+ border-radius: 3px;
+ overflow: hidden
+}
+
+#canvas_root {
+ width: 100%;
+ height: 100%;
+ display: block;
+ image-rendering: pixelated;
+ image-rendering: crisp-edges
+}
+
+.pv-label {
+ font-size: 10px;
+ color: var(--tx-ghost);
+ letter-spacing: .1em;
+ text-transform: uppercase
+}
+
+#demo-btns {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 5px;
+ margin-top: 6px
+}
+
+#sec-meta {
+ background: var(--bg-sunken);
+ border: 1px solid var(--bd-inner);
+ border-radius: 3px;
+ padding: 8px 10px;
+ display: flex;
+ flex-direction: column;
+ gap: 6px
+}
+
+.meta-row {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 11px
+}
+
+.meta-row label {
+ color: var(--tx-faint);
+ min-width: 90px
+}
+
+.meta-val {
+ color: var(--tx-meta)
+}
+
+.green {
+ color: var(--ac)
+}
+
+.flag-check {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+ font-size: 11px;
+ color: var(--tx-dim);
+ cursor: pointer
+}
+
+.flag-check input {
+ accent-color: var(--ac);
+ cursor: pointer
+}
+
+#right {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
+ overflow: hidden
+}
+
+#right-hdr {
+ height: 36px;
+ background: var(--bg-sunken);
+ border-bottom: 1px solid var(--bd-inner);
+ display: flex;
+ align-items: center;
+ padding: 0 10px;
+ gap: 6px;
+ flex-shrink: 0
+}
+
+#right-hdr .rh-title {
+ flex: 1;
+ color: var(--tx-faint);
+ font-size: 11px;
+ letter-spacing: .08em;
+ text-transform: uppercase
+}
+
+#sections-wrap {
+ flex: 1;
+ overflow-y: auto;
+ padding: 8px
+}
+
+.empty-state {
+ color: var(--tx-empty);
+ font-size: 11px;
+ padding: 28px 16px;
+ text-align: center;
+ line-height: 2
+}
+
+/* section card */
+.sec-card {
+ border: 1px solid var(--bd-card);
+ border-radius: 3px;
+ margin-bottom: 5px;
+ overflow: hidden
+}
+
+.sec-card.active {
+ border-color: var(--bd-active)
+}
+
+.sec-hdr {
+ display: flex;
+ align-items: center;
+ gap: 7px;
+ padding: 6px 8px;
+ cursor: pointer;
+ user-select: none;
+ background: var(--bg-raised);
+ position: relative
+}
+
+.sec-hdr:hover {
+ background: var(--bg-hover)
+}
+
+.sec-card.active .sec-hdr {
+ background: var(--bg-active)
+}
+
+.sec-arrow {
+ color: var(--tx-ghost);
+ font-size: 13px;
+ line-height: 1;
+ transition: transform .12s;
+ flex-shrink: 0
+}
+
+.sec-card.open .sec-arrow {
+ transform: rotate(90deg)
+}
+
+.sec-label {
+ flex: 1;
+ color: var(--tx-label);
+ font-size: 11px
+}
+
+.sec-badge {
+ font-size: 10px;
+ color: var(--ac);
+ border: 1px solid var(--bd-active);
+ background: var(--bg-accent);
+ border-radius: 2px;
+ padding: 1px 6px;
+ flex-shrink: 0
+}
+
+/* red × - section & element */
+.x-btn {
+ background: none;
+ border: none;
+ color: var(--bd);
+ cursor: pointer;
+ font-size: 15px;
+ line-height: 1;
+ padding: 2px 5px;
+ border-radius: 2px;
+ flex-shrink: 0;
+ transition: color .1s, background .1s
+}
+
+.x-btn:hover {
+ color: #ff4444;
+ background: var(--bg-xhover)
+}
+
+/* element */
+.el-list {
+ background: var(--bg-deep);
+ border-top: 1px solid var(--bd-deep);
+ padding: 6px
+}
+
+.el-item {
+ border: 1px solid var(--bd-inner);
+ border-radius: 3px;
+ background: var(--bg-sunken);
+ margin-bottom: 4px;
+ overflow: hidden
+}
+
+.el-item.active {
+ border-color: var(--ac)
+}
+
+.el-item-hdr {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 5px 8px;
+ cursor: pointer
+}
+
+.el-item-hdr:hover {
+ background: var(--bg-hover)
+}
+
+.el-type {
+ font-size: 10px;
+ color: var(--tx-meta);
+ border: 1px solid var(--bd-type);
+ border-radius: 2px;
+ padding: 1px 6px;
+ flex-shrink: 0
+}
+
+.el-item.active .el-type {
+ color: var(--ac);
+ border-color: var(--bd-active)
+}
+
+.el-name {
+ flex: 1;
+ color: var(--tx-dim);
+ font-size: 11px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ max-width: 120px
+}
+
+.el-fields {
+ padding: 6px 8px 8px;
+ border-top: 1px solid var(--bg-bar);
+ display: flex;
+ flex-direction: column;
+ gap: 5px
+}
+
+.fields-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 4px 10px
+}
+
+.field {
+ display: flex;
+ flex-direction: column;
+ gap: 2px
+}
+
+.field.full {
+ grid-column: 1/-1
+}
+
+.field>label {
+ font-size: 10px;
+ color: var(--tx-faint)
+}
+
+.field input[type=text],
+.field input[type=number],
+.field select,
+.field textarea {
+ background: var(--bg-input);
+ color: var(--tx-sub);
+ border: 1px solid var(--bd-card);
+ border-radius: 2px;
+ padding: 3px 6px;
+ font-family: monospace;
+ font-size: 11px;
+ width: 100%;
+ outline: none
+}
+
+.field input:focus,
+.field select:focus,
+.field textarea:focus {
+ border-color: var(--ac);
+ color: var(--tx)
+}
+
+.field textarea {
+ resize: vertical;
+ min-height: 44px;
+ line-height: 1.4
+}
+
+.field select option {
+ background: var(--bg-bar);
+ color: var(--tx-ghost)
+}
+
+.flags-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ padding: 2px 0
+}
+
+.add-el {
+ background: transparent;
+ color: var(--tx-ghost);
+ border: 1px dashed var(--bd-card);
+ border-radius: 3px;
+ padding: 5px 8px;
+ font-family: monospace;
+ font-size: 11px;
+ cursor: pointer;
+ width: 100%;
+ text-align: center;
+ margin-top: 2px
+}
+
+.add-el:hover {
+ color: var(--tx-sub);
+ border-color: var(--bd-hover)
+}
+
+/* confirm dialog */
+#confirm-overlay {
+ display: none;
+ position: fixed;
+ inset: 0;
+ background: var(--bg-overlay);
+ z-index: 100;
+ align-items: center;
+ justify-content: center
+}
+
+#confirm-overlay.show {
+ display: flex
+}
+
+#confirm-box {
+ background: var(--bg-bar);
+ border: 1px solid var(--bd-strong);
+ border-radius: 4px;
+ padding: 20px 24px;
+ max-width: 340px;
+ width: 90%;
+ display: flex;
+ flex-direction: column;
+ gap: 14px
+}
+
+#confirm-msg {
+ color: var(--tx-ghost);
+ font-size: 12px;
+ line-height: 1.6
+}
+
+#confirm-btns {
+ display: flex;
+ gap: 8px;
+ justify-content: flex-end
+}
+
+.cb {
+ background: var(--bg-raised);
+ color: var(--tx-sub);
+ border: 1px solid var(--bd-btn);
+ border-radius: 3px;
+ padding: 4px 14px;
+ font-family: monospace;
+ font-size: 11px;
+ cursor: pointer
+}
+
+.cb:hover {
+ background: var(--bg-hover2);
+ color: var(--tx-hover)
+}
+
+.cb.primary {
+ border-color: var(--bd-active);
+ color: var(--ac)
+}
+
+.cb.primary:hover {
+ background: var(--bg-active)
+}