feat: miller column browser, offline cache, search, breadcrumbs

- Dynamic miller column sizing with flexbox layout
- Root column (160px), middle slices (48px), active column (flex)
- Auto-scroll browser to rightmost column on navigation
- Offline indicator UI and IndexedDB cache integration
- /api/documents endpoint for client-side document caching
- Breadcrumb navigation in document content area
- FTS5 search with SQLite virtual table
- Client-side Mermaid and KaTeX rendering via CDN
- Deep sample content (advanced-topics/raft-deep-dive)
- Border removal (only search button keeps radius)
- Full viewport layout with proper borders between sidebar/content
This commit is contained in:
2026-04-30 11:55:03 -04:00
parent e45eeeb600
commit 780ff3a02c
40 changed files with 2986 additions and 190 deletions

View File

@@ -46,6 +46,9 @@ func New(deps Dependencies) (http.Handler, error) {
"trimMd": func(path string) string {
return strings.TrimSuffix(path, ".md")
},
"sub": func(a, b int) int {
return a - b
},
}).ParseFS(assets, "templates/*.gohtml")
if err != nil {
return nil, err
@@ -83,6 +86,8 @@ func New(deps Dependencies) (http.Handler, error) {
router.Post("/api/admin/workspace/sync", server.handleAdminWorkspaceSync)
router.Get("/docs", server.handleDocsIndex)
router.Get("/docs/*", server.handleDocument)
router.Get("/api/documents", server.handleDocuments)
router.Get("/api/search", server.handleSearch)
router.Post("/api/uploads", server.handleUpload)
router.Get("/attachments/{hash}", server.handleAttachment)
router.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(mustSub("static"))))