Merge TOC into page content

This commit is contained in:
2026-08-23 13:38:45 +02:00
parent dddacf9262
commit a0b4f49915
6 changed files with 20 additions and 41 deletions
+1 -1
View File
@@ -48,7 +48,7 @@
</span>
</footer>
</div>
{{if not .EditMode}}<aside class="sidebar">{{block "sidebar" .}}{{end}}</aside>{{end}}
{{if not .EditMode}}{{block "aside" .}}{{end}}{{end}}
</div>
{{block "extras" .}}{{end}}
</body>
+2 -4
View File
@@ -1,8 +1,6 @@
// Full-viewport Overlay component (mobile). Distinct from the .modal dialog:
// this hosts a whole rail (the folder tree or the right-rail widgets/TOC) at
// full screen with its own scroll and a top-right close control. It reuses the
// low-level focus/Escape/bfcache patterns from modal.js rather than that
// component's panel chrome.
// this hosts a whole sidebar at full screen with its own scroll and a top-right close control.
// It reuses the low-level focus/Escape/bfcache patterns from modal.js rather than that component's panel chrome.
//
// openOverlay(node) MOVES `node` (an existing rail <aside>) into the overlay
// body and restores it to its original DOM position on close, so the rail keeps
+1 -1
View File
@@ -66,4 +66,4 @@
<script src="/_/page/sidebar-fab.js"></script>
{{end}}
{{define "sidebar"}}{{if .SidebarWidget}}{{.SidebarWidget}}{{end}}{{end}}
{{define "aside"}}{{if .SidebarWidget}}<aside class="sidebar">{{.SidebarWidget}}</aside>{{end}}{{end}}
-5
View File
@@ -1,8 +1,3 @@
// Mobile: the right-rail FAB is stacked ABOVE the tree FAB and opens the right
// rail (TOC + page widgets) in the full-viewport Overlay (overlay.js). It only
// appears when the rail actually has content — runs after toc.js has had a
// chance to populate the rail (script order in page/main.html), so an
// otherwise-empty rail shows no FAB. Hidden on desktop by .fab CSS.
document.addEventListener("DOMContentLoaded", function () {
var aside = document.querySelector("aside.sidebar");
if (!aside || !aside.children.length) return;
+2 -4
View File
@@ -6,7 +6,7 @@ document.addEventListener("DOMContentLoaded", function () {
if (headings.length < 2) return;
var nav = document.createElement("nav");
nav.className = "toc panel panel-sidebar";
nav.className = "toc panel";
var header = document.createElement("div");
header.className = "panel-header";
@@ -28,7 +28,5 @@ document.addEventListener("DOMContentLoaded", function () {
});
nav.appendChild(list);
// Stack the TOC on top of any server-rendered widget(s) already in the rail.
var rail = document.querySelector("aside.sidebar");
rail.insertBefore(nav, rail.firstChild);
content.insertBefore(nav, content.firstChild);
});
+14 -26
View File
@@ -597,12 +597,7 @@ button.fab { display: none; }
::-webkit-scrollbar-thumb { background: var(--primary); }
::-webkit-scrollbar-thumb:hover { background: var(--primary-hover); }
/* === Sidebar (right rail) ===
Full-height column in the app-shell that scrolls its own overflow (TOC on
top, page widget(s) below). Collapses out of the flex row when it has no
content so the center column widens. A dashed separator to main mirrors the
left tree rail; widgets within drop their panel outlines (see
.panel-sidebar). */
/* === Optional Sidebar (right side) === */
.sidebar {
width: 14rem;
flex-shrink: 0;
@@ -614,21 +609,23 @@ button.fab { display: none; }
border-left: var(--border-dashed);
}
aside.sidebar:empty { display: none; }
/* Density modifier for panels in the sidebar (smaller font, tighter padding).
Drops the .panel outline so the rail reads as a clean column separated from
main by the .sidebar dashed border, matching the left tree rail. Inside the
mobile Overlay the widgets render as plain full-width content. */
.panel-sidebar {
padding: var(--space-2) var(--space-3);
font-size: var(--font-sm);
border: none;
}
/* === Table of contents ===
Rendered as a .panel-sidebar block in the right rail (padding + font-size
come from that density class); toc.js always mounts it there, on both
desktop and inside the mobile Overlay. */
/* === Table of contents ===*/
.toc {
float: right;
width: 15rem;
max-width: 45%;
margin: 0 0 var(--space-3) var(--space-4);
padding: var(--space-2) var(--space-3);
font-size: var(--font-sm);
max-width: 60vh;
overflow-y: auto;
}
.toc ul { list-style: none; margin: 0; padding: 0; }
.toc li { margin: 0.15rem 0; }
.toc a {
@@ -889,10 +886,6 @@ aside.sidebar:empty { display: none; }
main { padding: var(--space-4) var(--space-3); }
.app-name {display: none;}
.editor-cm { min-height: 50vh; }
/* Editing on mobile is full-bleed: drop the main inset so the toolbar and
editor use the entire viewport width. */
body.edit-mode main { padding: 0; }
/* Fingers, not cursors: give every toolbar control a ~44px tap target. */
.editor-toolbar { gap: var(--space-2); padding: var(--space-2); }
.editor-toolbar .btn-tool {
display: inline-flex;
@@ -902,17 +895,10 @@ aside.sidebar:empty { display: none; }
min-height: 2rem;
padding: 0 var(--space-1);
}
/* Pin the toolbar above the on-screen keyboard rather than at the top, which
is out of thumb reach while typing. interactive-widget=resizes-content
(layout.html viewport) shrinks the viewport on keyboard open so bottom: 0
sits directly above it. cm-content reserves matching scroll space so the
last lines aren't hidden behind the bar. */
body.edit-mode .editor-toolbar {
position: fixed;
left: 0;
right: 0;
/* Reset the desktop sticky `top: 0`; with it, fixed + top + bottom would
stretch the bar to the full viewport height. */
top: auto;
bottom: 0;
z-index: 50;
@@ -923,6 +909,7 @@ aside.sidebar:empty { display: none; }
body.edit-mode .cm-content {
padding-bottom: calc(5rem + env(safe-area-inset-bottom));
}
body.edit-mode main { padding: 0; }
.modal-backdrop { padding: var(--space-2); align-items: flex-start; }
.modal { max-width: none; margin-top: var(--space-4); }
.modal .panel-header { cursor: default; }
@@ -938,4 +925,5 @@ aside.sidebar:empty { display: none; }
.list-item td.icon { grid-row: 1; grid-column: 1; }
.list-item td.name { grid-row: 1; grid-column: 2; }
.list-item td.meta { grid-row: 2; grid-column: 2; text-align: left; }
.toc {float: none; width: auto; max-width: none; margin: 0 0 var(--space-4);}
}