From 537de24364b4faa2d973f8919e724557bf0a226e Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 08:40:49 +0100 Subject: [PATCH 01/14] Match header with cyberduck.io. Add Cyberduck logo, top navigation and product bar linking to Cyberduck, Mountain Duck and CLI. Search and theme switch moved into the product bar. --- _static/css/documentation.css | 54 +++++++++++++++++++++++++- _static/js/header.js | 8 ++++ _templates/partials/site-head.html | 62 ++++++++++++++++++++++++++++++ conf.py | 4 ++ 4 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 _static/js/header.js create mode 100644 _templates/partials/site-head.html diff --git a/_static/css/documentation.css b/_static/css/documentation.css index a844d9bc..553e1f3c 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -43,4 +43,56 @@ html[data-accent-color='blue'] { .yue ul > li > p { margin: 0; -} \ No newline at end of file +} + +/* Cyberduck site header (see _templates/partials/site-head.html) */ +:root { + --sy-s-navbar-height: 0px; + --sy-s-offset-top: 0px; +} + +.cd-header { font-family: -apple-system, "Droid Sans", sans-serif; position: relative; z-index: 20; } +.cd-container { max-width: 1170px; margin: 0 auto; padding: 0 15px; } + +.cd-navbar { background: #eee; } +.cd-navbar-inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 16px; min-height: 90px; } +.cd-brand img { display: block; width: 64px; height: 64px; } + +.cd-nav { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 4px; margin-left: auto; } +.cd-nav > a:not(.cd-btn) { color: #999; font-size: 18px; padding: 10px 8px; text-decoration: none; } +.cd-nav > a:not(.cd-btn):hover { color: #333; } +.cd-tools { display: flex; align-items: center; gap: 8px; } + +.cd-btn { display: inline-block; padding: 6px 12px; font-size: 14px; line-height: 1.43; border: 1px solid transparent; border-radius: 4px; text-decoration: none; cursor: pointer; list-style: none; } +.cd-btn::-webkit-details-marker { display: none; } +.cd-btn-default { background: #fff; color: #333; border-color: #ccc; } +.cd-btn-default:hover { background: #e6e6e6; } +.cd-btn-primary { background: #5a5a5a; color: #fff; border-color: #4a4a4a; margin-left: 6px; } +.cd-btn-primary:hover { background: #444; color: #fff; } +.cd-btn-success { background: #5cb85c; color: #fff; border-color: #4cae4c; margin-left: 6px; } +.cd-btn-success:hover { background: #449d44; color: #fff; } +.cd-caret { display: inline-block; border-top: 4px solid; border-left: 4px solid transparent; border-right: 4px solid transparent; vertical-align: middle; margin-left: 2px; } + +.cd-dropdown { position: relative; margin-left: 6px; } +.cd-dropdown ul { position: absolute; top: 100%; left: 0; z-index: 1000; min-width: 200px; margin: 2px 0 0; padding: 5px 0; list-style: none; background: #fff; border: 1px solid #ccc; border-radius: 4px; box-shadow: 0 6px 12px rgba(0,0,0,.175); } +.cd-dropdown li a { display: block; padding: 3px 20px; color: #333; font-size: 14px; line-height: 1.43; white-space: nowrap; text-decoration: none; } +.cd-dropdown li a:hover { background: #f5f5f5; } +.cd-dropdown li.divider { height: 1px; margin: 9px 0; background: #e5e5e5; } + +.cd-products { background: #ffd54f; border-bottom: 2px solid #ccc; } +.cd-products .cd-container { padding-top: 10px; padding-bottom: 10px; } +.cd-products a { text-decoration: none; margin-right: 4px; } +.cd-label { display: inline-block; background: #777; color: #fff; font-size: 13.5px; font-weight: 700; line-height: 1; padding: .2em .6em .3em; border-radius: .25em; white-space: nowrap; } +.cd-label img { display: inline-block; height: 16px; width: auto; max-width: none; margin: 0 2px 0 0; vertical-align: text-bottom; } +.cd-products-inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; } +.cd-product-links { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; } +.cd-product-links a { margin-right: 0; } +.cd-products a:hover .cd-label { background: #5e5e5e; } + +html.dark .cd-navbar, html[data-color-mode="dark"] .cd-navbar { background: #2a2a2a; } + +/* Search and theme switch inside the yellow product bar */ +.cd-tools .searchbox { background: #fff; border: 1px solid #ccc; border-radius: 4px; padding: 0 8px; height: 30px; } +.cd-tools .searchbox input { color: #333; background: transparent; } +.cd-tools .searchbox input::placeholder { color: #777; } +.cd-tools .theme-switch { color: #333; } diff --git a/_static/js/header.js b/_static/js/header.js new file mode 100644 index 00000000..edc12bb8 --- /dev/null +++ b/_static/js/header.js @@ -0,0 +1,8 @@ +// The theme scrolls the active sidebar entry into view, which also scrolls the window +// past the (non-sticky) Cyberduck header. Keep the page at the top on load unless +// the URL targets an anchor. +window.addEventListener("load", function () { + if (!window.location.hash) { + window.scrollTo(0, 0); + } +}); diff --git a/_templates/partials/site-head.html b/_templates/partials/site-head.html new file mode 100644 index 00000000..8d817757 --- /dev/null +++ b/_templates/partials/site-head.html @@ -0,0 +1,62 @@ +{#- Cyberduck-style site header: logo, top navigation and product bar (matches https://cyberduck.io) -#} +
+ +
+
+ +
+ {%- include "components/searchbox.html" -%} + {%- include "components/theme-switch.html" -%} +
+
+
+
diff --git a/conf.py b/conf.py index 5d8e501b..5c33b8c9 100644 --- a/conf.py +++ b/conf.py @@ -82,6 +82,10 @@ 'css/documentation.css', ] +html_js_files = [ + 'js/header.js', +] + master_doc = 'index' myst_heading_anchors = 4 myst_enable_extensions = [ From ef28841a2ac777d9633a5dde843be1a9e6fd80d3 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 08:42:25 +0100 Subject: [PATCH 02/14] Match content width with cyberduck.io. --- _static/css/documentation.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_static/css/documentation.css b/_static/css/documentation.css index 553e1f3c..09277c9a 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -96,3 +96,6 @@ html.dark .cd-navbar, html[data-color-mode="dark"] .cd-navbar { background: #2a2 .cd-tools .searchbox input { color: #333; background: transparent; } .cd-tools .searchbox input::placeholder { color: #777; } .cd-tools .theme-switch { color: #333; } + +/* Match the content width of cyberduck.io (Bootstrap container) */ +.sy-container { max-width: 1170px; } From 0613ec49aad780e3e0836f1b22222f966a59dd5e Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 08:42:27 +0100 Subject: [PATCH 03/14] Use standard font weight for product links. --- _static/css/documentation.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_static/css/documentation.css b/_static/css/documentation.css index 09277c9a..2bac0bdf 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -82,7 +82,7 @@ html[data-accent-color='blue'] { .cd-products { background: #ffd54f; border-bottom: 2px solid #ccc; } .cd-products .cd-container { padding-top: 10px; padding-bottom: 10px; } .cd-products a { text-decoration: none; margin-right: 4px; } -.cd-label { display: inline-block; background: #777; color: #fff; font-size: 13.5px; font-weight: 700; line-height: 1; padding: .2em .6em .3em; border-radius: .25em; white-space: nowrap; } +.cd-label { display: inline-block; background: #777; color: #fff; font-size: 13.5px; font-weight: 400; line-height: 1; padding: .2em .6em .3em; border-radius: .25em; white-space: nowrap; } .cd-label img { display: inline-block; height: 16px; width: auto; max-width: none; margin: 0 2px 0 0; vertical-align: text-bottom; } .cd-products-inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; } .cd-product-links { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; } From 0e064e2b3060d92abddf2cc9f967cf448a3a852f Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 08:44:07 +0100 Subject: [PATCH 04/14] Show pointer cursor on theme switch. --- _static/css/documentation.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_static/css/documentation.css b/_static/css/documentation.css index 2bac0bdf..2a5f2e77 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -99,3 +99,5 @@ html.dark .cd-navbar, html[data-color-mode="dark"] .cd-navbar { background: #2a2 /* Match the content width of cyberduck.io (Bootstrap container) */ .sy-container { max-width: 1170px; } + +.cd-tools .theme-switch { cursor: pointer; } From 9320245d65ee79efe95b656481b558889b421192 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 08:46:13 +0100 Subject: [PATCH 05/14] Remove On this page sidebar. --- _static/css/documentation.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_static/css/documentation.css b/_static/css/documentation.css index 2a5f2e77..64a98646 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -101,3 +101,7 @@ html.dark .cd-navbar, html[data-color-mode="dark"] .cd-navbar { background: #2a2 .sy-container { max-width: 1170px; } .cd-tools .theme-switch { cursor: pointer; } + +/* Hide the "On this page" sidebar and its toggle in the breadcrumbs */ +.sy-rside, .rside-overlay, .sy-breadcrumbs button[aria-controls="rside"] { display: none !important; } +.sy-breadcrumbs button[aria-controls="rside"] { visibility: hidden; } From 1a65894094818cc521d58c17b757093bf644bf3c Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 08:49:16 +0100 Subject: [PATCH 06/14] Disable right sidebar and use full content width --- _static/css/documentation.css | 9 ++++++--- conf.py | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/_static/css/documentation.css b/_static/css/documentation.css index 64a98646..32828f97 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -102,6 +102,9 @@ html.dark .cd-navbar, html[data-color-mode="dark"] .cd-navbar { background: #2a2 .cd-tools .theme-switch { cursor: pointer; } -/* Hide the "On this page" sidebar and its toggle in the breadcrumbs */ -.sy-rside, .rside-overlay, .sy-breadcrumbs button[aria-controls="rside"] { display: none !important; } -.sy-breadcrumbs button[aria-controls="rside"] { visibility: hidden; } +/* The right sidebar is disabled in conf.py (html_sidebars); release its space and use the full content width */ +.sy-rside, .rside-overlay { display: none; } +.sy-main > div > div { max-width: none; } +@media (min-width: 768px) { + .sy-main { width: calc(100% - 18rem); max-width: none; } +} diff --git a/conf.py b/conf.py index 5c33b8c9..7731ccf0 100644 --- a/conf.py +++ b/conf.py @@ -70,6 +70,8 @@ "github_version": "main", "conf_py_path": "/" } +# Disable the right sidebar ("On this page") +html_sidebars = {"**": []} html_show_sourcelink = False html_show_sphinx = True From 6fdf64a3c6c3089f8d1df7c699699feb10642c38 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 08:51:07 +0100 Subject: [PATCH 07/14] Align content right edge with header --- _static/css/documentation.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_static/css/documentation.css b/_static/css/documentation.css index 32828f97..ce7d2cb8 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -104,7 +104,7 @@ html.dark .cd-navbar, html[data-color-mode="dark"] .cd-navbar { background: #2a2 /* The right sidebar is disabled in conf.py (html_sidebars); release its space and use the full content width */ .sy-rside, .rside-overlay { display: none; } -.sy-main > div > div { max-width: none; } +.sy-main > div > div { max-width: none; padding-right: 15px; } /* align with the header container padding */ @media (min-width: 768px) { .sy-main { width: calc(100% - 18rem); max-width: none; } } From 9d9f02a8cc0bb457b88fc41cebc944a2420c09cd Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 08:54:13 +0100 Subject: [PATCH 08/14] Add Documentation link to header --- _templates/partials/site-head.html | 1 + 1 file changed, 1 insertion(+) diff --git a/_templates/partials/site-head.html b/_templates/partials/site-head.html index 8d817757..2add0f6d 100644 --- a/_templates/partials/site-head.html +++ b/_templates/partials/site-head.html @@ -9,6 +9,7 @@ Changelog Cryptomator Help + Docs Connection Profiles Blog
From e5cec4ec5763b2c729089c95d8ae1a92a30289cc Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 09:01:50 +0100 Subject: [PATCH 09/14] Hide table of contents toggle in breadcrumbs --- _static/css/documentation.css | 3 +++ 1 file changed, 3 insertions(+) diff --git a/_static/css/documentation.css b/_static/css/documentation.css index ce7d2cb8..46cd26b0 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -108,3 +108,6 @@ html.dark .cd-navbar, html[data-color-mode="dark"] .cd-navbar { background: #2a2 @media (min-width: 768px) { .sy-main { width: calc(100% - 18rem); max-width: none; } } + +/* The right sidebar is disabled, so hide its toggle in the breadcrumbs */ +.sy-breadcrumbs button[aria-controls="rside"] { display: none; } From 7e4f4a7385b2360a55b010d1e080a0e30f1b60d2 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 11 Nov 2026 09:06:06 +0100 Subject: [PATCH 10/14] Add hamburger menu for header navigation on mobile --- _static/css/documentation.css | 19 +++++++++++++++++++ _static/js/header.js | 13 +++++++++++++ _templates/partials/site-head.html | 6 +++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/_static/css/documentation.css b/_static/css/documentation.css index 46cd26b0..c7cac7cf 100644 --- a/_static/css/documentation.css +++ b/_static/css/documentation.css @@ -111,3 +111,22 @@ html.dark .cd-navbar, html[data-color-mode="dark"] .cd-navbar { background: #2a2 /* The right sidebar is disabled, so hide its toggle in the breadcrumbs */ .sy-breadcrumbs button[aria-controls="rside"] { display: none; } + +/* Hamburger menu (collapses the header navigation below 768px, like cyberduck.io) */ +.cd-toggle { display: none; padding: 9px 10px; background: transparent; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; } +.cd-toggle .cd-bar { display: block; width: 22px; height: 2px; border-radius: 1px; background: #888; } +.cd-toggle .cd-bar + .cd-bar { margin-top: 4px; } +.cd-toggle:hover { background: rgba(128, 128, 128, .15); } +.cd-header .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } + +@media (max-width: 767px) { + .cd-navbar-inner { min-height: 0; padding-top: 12px; padding-bottom: 12px; } + .cd-toggle { display: block; } + .cd-nav { display: none; flex-direction: column; align-items: stretch; width: 100%; margin-left: 0; gap: 0; } + .cd-nav.cd-nav-open { display: flex; } + .cd-nav > a:not(.cd-btn) { padding: 10px 0; } + .cd-nav .cd-btn { margin: 6px 0 0; text-align: center; } + .cd-dropdown { margin: 6px 0 0; } + .cd-dropdown summary { text-align: left; } + .cd-dropdown ul { position: static; box-shadow: none; margin-top: 6px; } +} diff --git a/_static/js/header.js b/_static/js/header.js index edc12bb8..672526ff 100644 --- a/_static/js/header.js +++ b/_static/js/header.js @@ -6,3 +6,16 @@ window.addEventListener("load", function () { window.scrollTo(0, 0); } }); + +// Hamburger menu for the header navigation on small screens +document.addEventListener("DOMContentLoaded", function () { + var toggle = document.querySelector(".cd-toggle"); + var nav = document.getElementById("cd-nav"); + if (!toggle || !nav) { + return; + } + toggle.addEventListener("click", function () { + var open = nav.classList.toggle("cd-nav-open"); + toggle.setAttribute("aria-expanded", open ? "true" : "false"); + }); +}); diff --git a/_templates/partials/site-head.html b/_templates/partials/site-head.html index 2add0f6d..363899ff 100644 --- a/_templates/partials/site-head.html +++ b/_templates/partials/site-head.html @@ -5,7 +5,11 @@ Cyberduck -