diff --git a/docs/index.html b/docs/index.html index b394796..73e9d47 100644 --- a/docs/index.html +++ b/docs/index.html @@ -323,6 +323,215 @@ body.dark-mode .hljs-meta { color: #82aaff !important; } + + /* ── Interactive Hex Viewer ─────────────────────────── */ + .hex-viewer { + display: flex; + gap: 0; + font-family: 'Menlo', 'Consolas', 'Courier New', monospace; + font-size: 13px; + line-height: 1.5; + min-height: 200px; + } + .hex-viewer-left { + flex: 1; + min-width: 0; + overflow-x: auto; + padding: 40px 12px 12px; + } + .hex-viewer-right { + width: 320px; + min-width: 260px; + border-left: 1px solid #ddd; + overflow-y: auto; + max-height: 600px; + padding: 40px 0 8px; + } + body.dark-mode .hex-viewer-right { + border-left-color: #444; + } + + /* Hex grid */ + .hex-header { + color: #888; + margin-bottom: 4px; + white-space: pre; + user-select: none; + } + .hex-row { + white-space: pre; + margin: 0; + padding: 0; + } + .hex-offset { + color: #888; + user-select: none; + } + .hex-byte { + display: inline-block; + width: 26px; + text-align: center; + cursor: pointer; + border-radius: 2px; + transition: outline 0.1s; + } + .hex-byte:hover { + outline: 2px solid #666; + outline-offset: -1px; + } + .hex-gap { + display: inline-block; + width: 8px; + } + .hex-ascii-sep { + display: inline-block; + width: 16px; + } + .hex-ascii { + display: inline-block; + width: 9px; + text-align: center; + cursor: pointer; + border-radius: 2px; + } + .hex-byte.highlight, .hex-ascii.highlight { + outline: 2px solid #1565c0 !important; + outline-offset: -1px; + } + body.dark-mode .hex-byte.highlight, body.dark-mode .hex-ascii.highlight { + outline-color: #64b5f6 !important; + } + + /* Layer colors */ + .hex-layer-frame { background: #bbdefb; color: #0d47a1; } + .hex-layer-appheader { background: #c8e6c9; color: #1b5e20; } + .hex-layer-record { background: #fff9c4; color: #f57f17; } + body.dark-mode .hex-layer-frame { background: #1a3a5c; color: #90caf9; } + body.dark-mode .hex-layer-appheader { background: #1b3d1f; color: #a5d6a7; } + body.dark-mode .hex-layer-record { background: #3e3510; color: #fff176; } + + /* Segment tooltip */ + .hex-tooltip { + position: fixed; + background: #333; + color: #fff; + padding: 6px 10px; + border-radius: 4px; + font-size: 12px; + pointer-events: none; + z-index: 1000; + max-width: 350px; + white-space: nowrap; + box-shadow: 0 2px 8px rgba(0,0,0,0.3); + display: none; + } + + /* Tree panel */ + .hex-tree-section { + padding: 0; + margin: 0; + } + .hex-tree-layer { + font-weight: bold; + font-size: 12px; + padding: 6px 12px 4px; + color: #555; + text-transform: uppercase; + letter-spacing: 0.5px; + user-select: none; + } + body.dark-mode .hex-tree-layer { + color: #aaa; + } + .hex-tree-group { + margin: 0; + padding: 0; + } + .hex-tree-group-header { + padding: 4px 12px; + cursor: pointer; + font-weight: 600; + font-size: 12px; + display: flex; + align-items: center; + gap: 6px; + user-select: none; + border-radius: 4px; + margin: 0 4px; + } + .hex-tree-group-header:hover { + background: #e3f2fd; + } + body.dark-mode .hex-tree-group-header:hover { + background: #1a3a5c; + } + .hex-tree-group-header .arrow { + display: inline-block; + transition: transform 0.15s; + font-size: 10px; + width: 12px; + } + .hex-tree-group-header.collapsed .arrow { + transform: rotate(-90deg); + } + .hex-tree-group-body { + padding: 0; + margin: 0; + } + .hex-tree-group-body.hidden { + display: none; + } + .hex-tree-item { + padding: 2px 12px 2px 30px; + cursor: pointer; + font-size: 12px; + border-radius: 4px; + margin: 0 4px; + display: flex; + justify-content: space-between; + gap: 8px; + } + .hex-tree-item:hover, + .hex-tree-item.active { + background: #e3f2fd; + } + body.dark-mode .hex-tree-item:hover, + body.dark-mode .hex-tree-item.active { + background: #1a3a5c; + } + .hex-tree-item .tree-kind { + color: #666; + flex-shrink: 0; + } + .hex-tree-item .tree-detail { + color: #333; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + body.dark-mode .hex-tree-item .tree-kind { + color: #aaa; + } + body.dark-mode .hex-tree-item .tree-detail { + color: #e0e0e0; + } + .hex-tree-item .tree-offset { + color: #999; + font-size: 11px; + flex-shrink: 0; + } + + @media (max-width: 800px) { + .hex-viewer { + flex-direction: column; + } + .hex-viewer-right { + width: 100%; + border-left: none; + border-top: 1px solid #ddd; + max-height: 400px; + } + } @@ -379,6 +588,7 @@

Online M-Bus Parser +