| 174 | |
| 175 | |
| 176 | def _html_styles() -> str: |
| 177 | return """<style> |
| 178 | * { box-sizing: border-box; margin: 0; padding: 0; } |
| 179 | body { background: #0f0f1a; color: #e0e0e0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; display: flex; height: 100vh; overflow: hidden; } |
| 180 | #graph { flex: 1; } |
| 181 | #sidebar { width: 280px; background: #1a1a2e; border-left: 1px solid #2a2a4e; display: flex; flex-direction: column; overflow: hidden; } |
| 182 | #search-wrap { padding: 12px; border-bottom: 1px solid #2a2a4e; } |
| 183 | #search { width: 100%; background: #0f0f1a; border: 1px solid #3a3a5e; color: #e0e0e0; padding: 7px 10px; border-radius: 6px; font-size: 13px; outline: none; } |
| 184 | #search:focus { border-color: #4E79A7; } |
| 185 | #search-results { max-height: 140px; overflow-y: auto; padding: 4px 12px; border-bottom: 1px solid #2a2a4e; display: none; } |
| 186 | .search-item { padding: 4px 6px; cursor: pointer; border-radius: 4px; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } |
| 187 | .search-item:hover { background: #2a2a4e; } |
| 188 | #info-panel { padding: 14px; border-bottom: 1px solid #2a2a4e; min-height: 140px; } |
| 189 | #info-panel h3 { font-size: 13px; color: #aaa; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.05em; } |
| 190 | #info-content { font-size: 13px; color: #ccc; line-height: 1.6; } |
| 191 | #info-content .field { margin-bottom: 5px; } |
| 192 | #info-content .field b { color: #e0e0e0; } |
| 193 | #info-content .empty { color: #555; font-style: italic; } |
| 194 | .neighbor-link { display: block; padding: 2px 6px; margin: 2px 0; border-radius: 3px; cursor: pointer; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; border-left: 3px solid #333; } |
| 195 | .neighbor-link:hover { background: #2a2a4e; } |
| 196 | #neighbors-list { max-height: 160px; overflow-y: auto; margin-top: 4px; } |
| 197 | #legend-wrap { flex: 1; overflow-y: auto; padding: 12px; } |
| 198 | #legend-wrap h3 { font-size: 13px; color: #aaa; margin-bottom: 10px; text-transform: uppercase; letter-spacing: 0.05em; } |
| 199 | .legend-item { display: flex; align-items: center; gap: 8px; padding: 4px 0; cursor: pointer; border-radius: 4px; font-size: 12px; } |
| 200 | .legend-item:hover { background: #2a2a4e; padding-left: 4px; } |
| 201 | .legend-item.dimmed { opacity: 0.35; } |
| 202 | .legend-dot { width: 12px; height: 12px; border-radius: 50%; flex-shrink: 0; } |
| 203 | .legend-label { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| 204 | .legend-count { color: #666; font-size: 11px; } |
| 205 | #stats { padding: 10px 14px; border-top: 1px solid #2a2a4e; font-size: 11px; color: #555; } |
| 206 | #legend-controls { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; padding: 4px 0; } |
| 207 | #legend-controls label { display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: 12px; color: #aaa; user-select: none; } |
| 208 | #legend-controls label:hover { color: #e0e0e0; } |
| 209 | .legend-cb, #select-all-cb { appearance: none; -webkit-appearance: none; width: 14px; height: 14px; border: 1.5px solid #3a3a5e; border-radius: 3px; background: #0f0f1a; cursor: pointer; position: relative; flex-shrink: 0; } |
| 210 | .legend-cb:checked, #select-all-cb:checked { background: #4E79A7; border-color: #4E79A7; } |
| 211 | .legend-cb:checked::after, #select-all-cb:checked::after { content: ''; position: absolute; left: 3.5px; top: 1px; width: 4px; height: 7px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); } |
| 212 | #select-all-cb:indeterminate { background: #4E79A7; border-color: #4E79A7; } |
| 213 | #select-all-cb:indeterminate::after { content: ''; position: absolute; left: 2px; top: 5px; width: 8px; height: 2px; background: #fff; border: none; transform: none; } |
| 214 | </style>""" |
| 215 | |
| 216 | |
| 217 | def _hyperedge_script(hyperedges_json: str) -> str: |