diff --git a/src/components.css b/src/components.css index 51d4b7be..5b3ca9c9 100644 --- a/src/components.css +++ b/src/components.css @@ -1,4 +1,4 @@ -/* --- Component structural styles --- */ +/* --- Component Structural Styles --- */ mc-world, mc-timeline, mc-camera, mc-frame { display: none; } @@ -8,15 +8,14 @@ mc-diorama { position: relative; width: 100%; height: 20em; + + & canvas { + display: block; + width: 100%; + height: 100%; + } } -mc-diorama canvas { - display: block; - width: 100%; - height: 100%; -} - -/* --- UI Controls styles --- */ .spacetime-overlay { position: absolute; top: 0; @@ -30,144 +29,146 @@ mc-diorama canvas { box-sizing: border-box; padding: 12px; z-index: 10; -} - -.reset-wrapper { - display: flex; - justify-content: flex-end; - width: 100%; -} - -.reset-btn { - pointer-events: auto; - padding: 6px 12px; - background: rgba(0, 0, 0, 0.6); - color: white; - border: 1px solid rgba(255, 255, 255, 0.3); - cursor: pointer; - display: none; font-family: sans-serif; - border-radius: 4px; - font-weight: bold; - backdrop-filter: blur(4px); -} -.reset-btn:hover { - background: rgba(0, 0, 0, 0.8); -} + & .btn { + background: rgba(255, 255, 255, 0.1); + border: 1px solid rgba(255, 255, 255, 0.2); + color: white; + padding: 4px 8px; + border-radius: 4px; + cursor: pointer; + text-align: center; + font-weight: bold; + font-family: inherit; + backdrop-filter: blur(4px); + transition: background 0.1s, border-color 0.1s; + pointer-events: auto; /* Always clickable when visible */ -.visualizer-ui { - pointer-events: none; /* Let clicks pass through the empty space by default */ - font-family: sans-serif; - background: transparent; - padding: 12px; - border-radius: 8px; - display: flex; - flex-direction: column; - gap: 12px; - color: white; - user-select: none; - border: 1px solid transparent; - transition: all 0.2s ease; -} + &:hover { + background: rgba(255, 255, 255, 0.2); + } + } -.spacetime-container:hover .visualizer-ui { - background: rgba(20, 20, 20, 0.85); - backdrop-filter: blur(4px); - border: 1px solid rgba(255, 255, 255, 0.1); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); - pointer-events: auto; /* Catch clicks on the panel background */ -} + & .reset-wrapper { + display: flex; + justify-content: flex-end; + width: 100%; -.scrubber-row { - display: flex; - gap: 12px; - align-items: center; -} + & .btn { + visibility: hidden; + } + } -.btn { - background: rgba(255, 255, 255, 0.1); - border: 1px solid rgba(255, 255, 255, 0.2); - color: white; - padding: 4px 8px; - border-radius: 4px; - cursor: pointer; - min-width: 4ch; - text-align: center; - font-weight: bold; - transition: background 0.1s; -} + /* Bottom: Timeline Panel Context */ -.btn:hover { - background: rgba(255, 255, 255, 0.2); -} + & .visualizer-ui { + pointer-events: none; + background: transparent; + padding: 12px; + border-radius: 8px; + display: flex; + flex-direction: column; + gap: 12px; + color: white; + user-select: none; + border: 1px solid transparent; + transition: all 0.2s ease; -.track-container { - flex-grow: 1; - height: 24px; - padding: 0 10px; - cursor: pointer; - display: flex; - align-items: center; -} + & .scrubber-row { + display: flex; + gap: 12px; + align-items: center; -.track-inner { - position: relative; - width: 100%; - height: 100%; - pointer-events: none; -} + & .btn { + min-width: 4ch; + } + } -.track-bg { - position: absolute; - left: -10px; - right: -10px; - top: 8px; - height: 8px; - background: rgba(255, 255, 255, 0.2); - border-radius: 4px; -} + & .track-container { + flex-grow: 1; + height: 24px; + padding: 0 10px; + cursor: pointer; + display: flex; + align-items: center; -.track-fill { - position: absolute; - left: -10px; - top: 8px; - height: 8px; - background: #f00; - width: 10px; - border-radius: 4px; -} + & .track-inner { + position: relative; + width: 100%; + height: 100%; + pointer-events: none; -.track-handle { - position: absolute; - width: 16px; - height: 16px; - background: #fff; - border-radius: 50%; - top: 12px; - transform: translate(-50%, -50%); - z-index: 3; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.5); -} + & .track-bg { + position: absolute; + left: -10px; + right: -10px; + top: 8px; + height: 8px; + background: rgba(255, 255, 255, 0.2); + border-radius: 4px; + } -.marker { - position: absolute; - top: 8px; - height: 8px; - transform: translateX(-50%); - pointer-events: none; - z-index: 1; -} + & .track-fill { + position: absolute; + left: -10px; + top: 8px; + height: 8px; + background: #f00; + width: 10px; + border-radius: 4px; + } -.marker-event { - width: 2px; - background: rgba(255, 255, 255, 0.5); -} + & .track-handle { + position: absolute; + width: 16px; + height: 16px; + background: #fff; + border-radius: 50%; + top: 12px; + transform: translate(-50%, -50%); + z-index: 3; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.5); + } -.marker-label { - width: 4px; - background: gold; - z-index: 2; + & .marker { + position: absolute; + top: 8px; + height: 8px; + transform: translateX(-50%); + pointer-events: none; + z-index: 1; + + &.marker-event { + width: 2px; + background: rgba(255, 255, 255, 0.5); + } + + &.marker-label { + width: 4px; + background: gold; + z-index: 2; + } + } + } + } + } + + /* Spatial Tool Hints */ + + & .spacetime-indicator { + position: absolute; + left: 33px; + top: 29px; + display: flex; + gap: 12px; + color: rgba(255, 255, 255, 0.4); + font-family: monospace; + font-size: 14px; + pointer-events: none; + opacity: 1; + transition: opacity 0.2s ease; + } } /* --- Hover Visibility Logic --- */ @@ -177,25 +178,21 @@ mc-diorama canvas { transition: opacity 0.2s ease; } -.spacetime-container:hover .spacetime-hover-reveal { - opacity: 1; - pointer-events: auto; -} +.spacetime-container:hover { + & .spacetime-hover-reveal { + opacity: 1; + pointer-events: auto; + } -.spacetime-indicator { - position: absolute; - right: 33px; - bottom: 29px; - display: flex; - gap: 12px; - color: rgba(255, 255, 255, 0.4); - font-family: monospace; - font-size: 14px; - pointer-events: none; - opacity: 1; - transition: opacity 0.2s ease; -} + & .spacetime-indicator { + opacity: 0; + } -.spacetime-container:hover .spacetime-indicator { - opacity: 0; + & .visualizer-ui { + background: rgba(20, 20, 20, 0.85); + backdrop-filter: blur(4px); + border: 1px solid rgba(255, 255, 255, 0.1); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); + pointer-events: auto; + } } \ No newline at end of file diff --git a/src/controller.js b/src/controller.js index 91e76ea1..1f759d9b 100644 --- a/src/controller.js +++ b/src/controller.js @@ -66,13 +66,13 @@ export class SpacetimeController { if (this.hasSpatial) { const topWrapper = document.createElement('div'); topWrapper.className = 'reset-wrapper'; - this.resetBtn = document.createElement('button'); - this.resetBtn.className = 'reset-btn'; + this.resetBtn = document.createElement('div'); + this.resetBtn.className = 'btn'; this.resetBtn.textContent = 'Reset View'; this.resetBtn.addEventListener('click', () => { this.diorama.loadState(); - this.resetBtn.style.display = 'none'; + this.resetBtn.style.visibility = 'hidden'; }); topWrapper.appendChild(this.resetBtn); @@ -181,7 +181,7 @@ export class SpacetimeController { const notifyCameraChange = () => { this.hasDragged = true; - if (this.resetBtn && this.diorama.checkpoint) this.resetBtn.style.display = 'block'; + if (this.resetBtn && this.diorama.checkpoint) this.resetBtn.style.visibility = 'visible'; this.diorama.requestRender(); };