feat: sectioned toolbar + custom component editor

- Redesigned toolbar with I/O, Gates, and Components sections
- Component editor: sub-canvas mode to design reusable chips
  - Save/Cancel with main circuit state preservation
  - Components persist in localStorage
- Custom components render as purple chips with dynamic I/O ports
- Component evaluation simulates internal circuit as black box
- Toolbar height increased to 56px for section labels
- All height references updated consistently

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jose Luis
2026-03-20 02:54:04 +01:00
parent 3bff1fd4b4
commit 268013d053
8 changed files with 472 additions and 40 deletions

View File

@@ -41,7 +41,7 @@ body {
#toolbar {
position: fixed;
top: 0; left: 0; right: 0;
height: 48px;
height: 56px;
background: #12121a;
border-bottom: 1px solid #2a2a3a;
display: flex;
@@ -97,10 +97,60 @@ body {
.action-btn.sim-btn:hover { background: #ff44aa22; }
.action-btn.sim-btn.active { background: #ff44aa33; border-color: #ff66cc; color: #ff66cc; }
/* ==================== Toolbar Sections ==================== */
.toolbar-section {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1px;
height: 56px;
justify-content: flex-start;
}
.section-label {
font-size: 8px;
color: #666;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: 1px 6px;
height: 10px;
line-height: 10px;
}
.toolbar-section .gate-btn {
padding: 3px 8px;
font-size: 10px;
height: 20px;
display: flex;
align-items: center;
}
.toolbar-section #saved-components {
display: flex;
gap: 2px;
}
.toolbar-section .component-btn {
padding: 4px 8px;
font-size: 10px;
background: #1a1a2e;
border: 1px solid #2a2a3a;
border-radius: 4px;
color: #9900ff;
cursor: pointer;
transition: all 0.15s;
}
.toolbar-section .component-btn:hover {
border-color: #9900ff;
color: #cc66ff;
}
/* ==================== Canvas ==================== */
#canvas {
position: fixed;
top: 48px; left: 0; right: 0; bottom: 0;
top: 56px; left: 0; right: 0; bottom: 0;
cursor: default;
transition: left 0.2s ease;
}
@@ -273,14 +323,79 @@ body {
color: #00e599;
}
/* ==================== Component Editor Overlay ==================== */
#component-editor-overlay {
position: fixed;
top: 56px;
left: 0;
right: 0;
height: 44px;
background: #1a1a2e;
border-bottom: 2px solid #9900ff;
z-index: 105;
display: flex;
align-items: center;
padding: 0 12px;
gap: 12px;
}
#component-editor-bar {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
}
#component-editor-title {
color: #9900ff;
font-weight: 600;
font-size: 13px;
flex: 1;
}
#component-editor-save, #component-editor-cancel {
padding: 4px 12px;
border-radius: 4px;
border: none;
cursor: pointer;
font-size: 12px;
font-weight: 600;
transition: all 0.15s;
}
#component-editor-save {
background: #00e599;
color: #000;
}
#component-editor-save:hover {
background: #00ff99;
box-shadow: 0 0 10px #00e59944;
}
#component-editor-cancel {
background: transparent;
border: 1px solid #ff4444;
color: #ff4444;
}
#component-editor-cancel:hover {
background: #ff444422;
}
/* Shift canvas when editor is active */
#component-editor-overlay:not([style*="display: none"]) ~ #canvas {
top: calc(56px + 44px);
}
/* ==================== Puzzle Panels ==================== */
.puzzle-panel {
display: none;
position: fixed;
top: 48px;
top: 56px;
left: 0;
width: 340px;
height: calc(100vh - 48px);
height: calc(100vh - 56px);
background: #12121a;
border-right: 1px solid #2a2a3a;
z-index: 95;
@@ -293,7 +408,7 @@ body {
}
.puzzle-panel.puzzle-info {
top: 48px;
top: 56px;
width: 340px;
}