diff --git a/zddc/internal/apps/embedded/archive.html b/zddc/internal/apps/embedded/archive.html
index 49ec16e..9cbae50 100644
--- a/zddc/internal/apps/embedded/archive.html
+++ b/zddc/internal/apps/embedded/archive.html
@@ -2131,7 +2131,7 @@ td[data-field="trackingNumber"] {
diff --git a/zddc/internal/apps/embedded/browse.html b/zddc/internal/apps/embedded/browse.html
index 578b97c..1083b02 100644
--- a/zddc/internal/apps/embedded/browse.html
+++ b/zddc/internal/apps/embedded/browse.html
@@ -896,7 +896,7 @@ body {
@@ -1000,6 +1000,10 @@ body {
- Click a folder
- Toggle expand/collapse on that folder.
+ - Double-click a folder
+ - Navigate into the folder — it becomes the new root of the
+ view. Server mode loads the folder's URL; local mode re-roots
+ onto that folder's handle.
- Shift-click a folder
- Recursive expand or collapse — applies to the whole subtree.
- Click a file
@@ -3601,6 +3605,54 @@ https://github.com/nodeca/pako/blob/main/LICENSE
// Browser handles target=_blank natively for middle
// click; don't preventDefault, just don't intercept.
});
+
+ // Double-click on a folder → "navigate into" it. Distinct
+ // from single-click (which expands inline) so users keep
+ // both UX models. Server mode jumps to the folder URL —
+ // zddc-server returns a fresh browse instance scoped to
+ // that directory. FS-API mode swaps state.rootHandle to
+ // the folder's handle and re-loads, so the user sees
+ // only that subtree at the root level.
+ //
+ // Files: dblclick is left alone — the single-click preview
+ // is already a "look at this file" action; a separate
+ // navigate-into doesn't apply.
+ // ZIPs: skipped too — they're inspected via inline
+ // expansion (JSZip), not navigated into.
+ tbody.addEventListener('dblclick', function (e) {
+ var row = e.target.closest('tr.tree-row');
+ if (!row) return;
+ if (row.dataset.isdir !== 'true') return;
+ var id = parseInt(row.dataset.id, 10);
+ var node = state.nodes.get(id);
+ if (!node) return;
+ e.preventDefault();
+ navigateIntoFolder(node);
+ });
+ }
+ }
+
+ async function navigateIntoFolder(node) {
+ if (state.source === 'server') {
+ var url = window.app.modules.tree.pathFor(node);
+ if (!url.endsWith('/')) url += '/';
+ window.location.assign(url);
+ return;
+ }
+ if (state.source === 'fs') {
+ if (!node.handle || node.handle.kind !== 'directory') return;
+ state.rootHandle = node.handle;
+ state.currentPath = node.handle.name + '/';
+ var raw;
+ try {
+ raw = await loader.fetchFsChildren(node.handle);
+ } catch (e) {
+ statusError('Failed to enter ' + node.name + ': ' + e.message);
+ return;
+ }
+ tree.setRoot(raw);
+ tree.render();
+ statusInfo('Entered ' + node.name);
}
}
diff --git a/zddc/internal/apps/embedded/classifier.html b/zddc/internal/apps/embedded/classifier.html
index d964913..f23282b 100644
--- a/zddc/internal/apps/embedded/classifier.html
+++ b/zddc/internal/apps/embedded/classifier.html
@@ -1394,7 +1394,7 @@ body.help-open .app-header {
diff --git a/zddc/internal/apps/embedded/index.html b/zddc/internal/apps/embedded/index.html
index cefd9da..3144dca 100644
--- a/zddc/internal/apps/embedded/index.html
+++ b/zddc/internal/apps/embedded/index.html
@@ -885,7 +885,7 @@ body {