.line-samples-cumulative {
padding: 0 4px;
}
+
+ .bytecode-panel {
+ margin: 8px 10px 8px 160px;
+ }
}
.bytecode-toggle {
}
.bytecode-panel {
- margin-left: 90px;
- padding: 8px 15px;
- background: var(--bg-secondary);
- border-left: 3px solid var(--accent);
+ background: var(--bg-primary);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ box-shadow: var(--shadow-md);
font-family: var(--font-mono);
font-size: 12px;
- margin-bottom: 4px;
+ color: var(--text-primary);
+ line-height: 1.5;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ padding: 0;
+ margin: 8px 10px 8px 250px;
+ position: relative;
+ z-index: 1;
+ overflow-y: auto;
+ max-height: 500px;
+ flex: 1;
+ transition: padding 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.bytecode-panel.expanded {
+ padding: 14px;
+}
+
+.bytecode-wrapper {
+ position: relative;
+ display: flex;
+ overflow: visible;
+ max-height: 0;
+ opacity: 0;
+ transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease-in-out;
+}
+
+.bytecode-wrapper.expanded {
+ max-height: 600px;
+ opacity: 1;
+ transition: max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease-in-out;
+}
+
+/* Column backdrop matching table header columns (line/self/total) */
+.bytecode-columns {
+ display: none;
+ position: absolute;
+ left: 0;
+ overflow: hidden;
+ pointer-events: none;
+ z-index: 0;
+}
+
+.bytecode-wrapper.expanded .bytecode-columns {
+ display: flex;
+ top: 0;
+ bottom: 0;
+}
+
+.bytecode-panel::-webkit-scrollbar {
+ width: 8px;
+}
+
+.bytecode-panel::-webkit-scrollbar-track {
+ background: var(--bg-secondary);
+ border-radius: 4px;
+}
+
+.bytecode-panel::-webkit-scrollbar-thumb {
+ background: var(--border);
+ border-radius: 4px;
+}
+
+.bytecode-panel::-webkit-scrollbar-thumb:hover {
+ background: var(--text-muted);
}
/* Specialization summary bar */
const lineId = lineDiv.id;
const lineNum = lineId.replace('line-', '');
const panel = document.getElementById(`bytecode-${lineNum}`);
+ const wrapper = document.getElementById(`bytecode-wrapper-${lineNum}`);
- if (!panel) return;
+ if (!panel || !wrapper) return;
- const isExpanded = panel.style.display !== 'none';
+ const isExpanded = panel.classList.contains('expanded');
if (isExpanded) {
- panel.style.display = 'none';
+ panel.classList.remove('expanded');
+ wrapper.classList.remove('expanded');
button.classList.remove('expanded');
button.innerHTML = '▶'; // Right arrow
} else {
if (!panel.dataset.populated) {
populateBytecodePanel(panel, button);
}
- panel.style.display = 'block';
+ panel.classList.add('expanded');
+ wrapper.classList.add('expanded');
button.classList.add('expanded');
button.innerHTML = '▼'; // Down arrow
}
f'data-spec-pct="{spec_pct}" '
f'onclick="toggleBytecode(this)" title="Show bytecode">▶</button>'
)
- bytecode_panel_html = f' <div class="bytecode-panel" id="bytecode-{line_num}" style="display:none;"></div>\n'
+ # Wrapper contains columns + content panel
+ bytecode_panel_html = (
+ f' <div class="bytecode-wrapper" id="bytecode-wrapper-{line_num}">\n'
+ f' <div class="bytecode-columns">'
+ f'<div class="line-number"></div>'
+ f'<div class="line-samples-self"></div>'
+ f'<div class="line-samples-cumulative"></div>'
+ f'</div>\n'
+ f' <div class="bytecode-panel" id="bytecode-{line_num}"></div>\n'
+ f' </div>\n'
+ )
elif self.opcodes_enabled:
# Add invisible spacer to maintain consistent indentation when opcodes are enabled
bytecode_btn_html = '<div class="bytecode-spacer"></div>'