diff --git a/ui/app.js b/ui/app.js
index c4fb694..932c60c 100644
--- a/ui/app.js
+++ b/ui/app.js
@@ -3116,6 +3116,35 @@ function closeModal() {
// ─── Event Bindings ────────────────────────────────────────
function bindEvents() {
+ // ─── FLOATING QUICK-SCROLL NAVIGATION PANEL ENGINE (#116) ───
+ const terminalBodyElement = document.getElementById('terminal-body');
+ const btnScrollTop = document.getElementById('scroll-to-top');
+ const btnScrollBottom = document.getElementById('scroll-to-bottom');
+ const scrollActionsContainer = document.getElementById('terminal-scroll-actions');
+ const cliCommandInput = document.getElementById('cli-input');
+
+ // 1. Math modifier scroll event triggers
+ if (btnScrollTop && terminalBodyElement) {
+ btnScrollTop.addEventListener('click', () => {
+ terminalBodyElement.scrollTo({ top: 0, behavior: 'smooth' });
+ });
+ }
+
+ if (btnScrollBottom && terminalBodyElement) {
+ btnScrollBottom.addEventListener('click', () => {
+ terminalBodyElement.scrollTo({ top: terminalBodyElement.scrollHeight, behavior: 'smooth' });
+ });
+ }
+
+ // 2. Clear typing space visibility management (translucent on focus)
+ if (cliCommandInput && scrollActionsContainer) {
+ cliCommandInput.addEventListener('focus', () => {
+ scrollActionsContainer.classList.add('input-focused');
+ });
+ cliCommandInput.addEventListener('blur', () => {
+ scrollActionsContainer.classList.remove('input-focused');
+ });
+ }
// Terminal Search
const cliSearchInput = document.getElementById('cli-search-input');
if (cliSearchInput) {
diff --git a/ui/index.html b/ui/index.html
index cb41145..0bde3dc 100644
--- a/ui/index.html
+++ b/ui/index.html
@@ -250,6 +250,19 @@
Scripts
$ Welcome to DevShell. Select a
script to run, or type a command below.
+
+
$
diff --git a/ui/style.css b/ui/style.css
index 79b4ee0..32878a9 100644
--- a/ui/style.css
+++ b/ui/style.css
@@ -2925,6 +2925,51 @@ body.debugger-open #app-main {
color: var(--text-secondary);
opacity: 0.8;
}
+/* ─── FLOATING QUICK-SCROLL NAVIGATION COMPONENT (#116) ─── */
+#terminal-body {
+ position: relative; /* Contextually anchors absolute layouts */
+}
+
+#terminal-scroll-actions {
+ position: absolute;
+ bottom: 16px;
+ right: 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ z-index: 10;
+ transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
+}
+
+/* Make controllers translucent when typing to preserve viewport visibility */
+#terminal-scroll-actions.input-focused {
+ opacity: 0.25;
+}
+
+#terminal-scroll-actions:hover {
+ opacity: 1.0 !important;
+}
+
+.btn-scroll-target {
+ background-color: var(--bg-secondary, #161b22);
+ border: 1px solid var(--border-color, #30363d);
+ color: var(--text-muted, #8b949e);
+ border-radius: 6px;
+ width: 28px;
+ height: 28px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+ transition: background-color 0.15s, color 0.15s, border-color 0.15s;
+}
+
+.btn-scroll-target:hover {
+ background-color: var(--border-color, #30363d);
+ color: var(--text-main, #c9d1d9);
+ border-color: var(--accent-blue, #58a6ff);
+}
/* ─── LIGHT THEME OVERRIDES ─── */
body.light-theme {
background-color: #f8f9fa !important;
@@ -2986,4 +3031,4 @@ body.light-theme #analysis-panel {
body.light-theme .analysis-empty h3 {
color: #212529 !important;
}
-/* ───────────────────────────── */
\ No newline at end of file
+/* ───────────────────────────── */