diff --git a/.playwright-mcp/console-2026-03-23T20-11-48-316Z.log b/.playwright-mcp/console-2026-03-23T20-11-48-316Z.log new file mode 100644 index 00000000..cde32898 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T20-11-48-316Z.log @@ -0,0 +1 @@ +[ 567ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/auth/me:0 diff --git a/.playwright-mcp/console-2026-03-23T20-11-59-703Z.log b/.playwright-mcp/console-2026-03-23T20-11-59-703Z.log new file mode 100644 index 00000000..504d5ee5 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T20-11-59-703Z.log @@ -0,0 +1,66 @@ +[ 156566ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 159562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 162561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 165562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 168561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 171561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 174562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 177561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 180561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 183561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 186561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 189561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 192561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 195561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 198562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 201561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 204561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 207561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 210561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 213562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 216562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 219561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 222561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 225562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 228561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 231562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 234562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 237562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 240390ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/dashboard/summary:0 +[ 240562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 243562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 246561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 249561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 252562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 255561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 258561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 261562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 264562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 267562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 270562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 273561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 276562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 279563ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 282561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 285562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 288562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 291562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 294562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 297561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 300562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 303561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 306562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 309561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 312562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 315561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 318561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 321561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 324561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 327561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 330562ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 333561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 336561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 339561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 342561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 345561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 348561ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 diff --git a/.playwright-mcp/console-2026-03-23T20-18-54-805Z.log b/.playwright-mcp/console-2026-03-23T20-18-54-805Z.log new file mode 100644 index 00000000..2ff3cdcb --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T20-18-54-805Z.log @@ -0,0 +1,2 @@ +[ 480462ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/dashboard/summary:0 +[ 1440463ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/dashboard/summary:0 diff --git a/.playwright-mcp/console-2026-03-23T20-52-21-821Z.log b/.playwright-mcp/console-2026-03-23T20-52-21-821Z.log new file mode 100644 index 00000000..276dbf03 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T20-52-21-821Z.log @@ -0,0 +1,14 @@ +[ 140214ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 143212ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 146211ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 149211ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/upgrade/status:0 +[ 360382ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/dashboard/summary:0 +[ 960378ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/dashboard/summary:0 +[ 1320377ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/dashboard/summary:0 +[ 1920379ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/dashboard/summary:0 +[ 2040375ms] [ERROR] Failed to load resource: net::ERR_CONNECTION_REFUSED @ http://localhost:3002/api/dashboard/summary:0 +[ 2280391ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/dashboard/summary:0 +[ 2400379ms] [ERROR] Failed to load resource: the server responded with a status of 500 (Internal Server Error) @ http://localhost:3002/api/dashboard/summary:0 +[ 3240382ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/dashboard/summary:0 +[ 4200393ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/dashboard/summary:0 +[ 5160392ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/dashboard/summary:0 diff --git a/.playwright-mcp/console-2026-03-23T22-33-26-262Z.log b/.playwright-mcp/console-2026-03-23T22-33-26-262Z.log new file mode 100644 index 00000000..5ab7af6d --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-33-26-262Z.log @@ -0,0 +1,2 @@ +[ 616ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:3002/favicon.ico:0 +[ 628ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/auth/me:0 diff --git a/.playwright-mcp/console-2026-03-23T22-48-25-770Z.log b/.playwright-mcp/console-2026-03-23T22-48-25-770Z.log new file mode 100644 index 00000000..62447069 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-48-25-770Z.log @@ -0,0 +1 @@ +[ 605ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/auth/me:0 diff --git a/.playwright-mcp/console-2026-03-23T22-50-36-491Z.log b/.playwright-mcp/console-2026-03-23T22-50-36-491Z.log new file mode 100644 index 00000000..f3de76f8 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-50-36-491Z.log @@ -0,0 +1 @@ +[ 1538ms] [ERROR] Failed to load resource: the server responded with a status of 400 (Bad Request) @ http://localhost:8091/auth/token/refresh:0 diff --git a/.playwright-mcp/console-2026-03-23T22-50-56-794Z.log b/.playwright-mcp/console-2026-03-23T22-50-56-794Z.log new file mode 100644 index 00000000..e5f60374 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-50-56-794Z.log @@ -0,0 +1 @@ +[ 32ms] [WARNING] Manifest: property 'start_url' ignored, should be same origin as document. @ data:application/json;base64,eyJuYW1lIjoiR2l0ZWE6IEdpdCB3aXRoIGEgY3VwIG9mIHRlYSIsInNob3J0X25hbWUiOiJHaXRlYTogR2l0IHdpdGggYSBjdXAgb2YgdGVhIiwic3RhcnRfdXJsIjoiaHR0cHM6Ly9naXQuY21saXRlLm9yZy8iLCJpY29ucyI6W3sic3JjIjoiaHR0cHM6Ly9naXQuY21saXRlLm9yZy9hc3NldHMvaW1nL2xvZ28ucG5nIiwidHlwZSI6ImltYWdlL3BuZyIsInNpemVzIjoiNTEyeDUxMiJ9LHsic3JjIjoiaHR0cHM6Ly9naXQuY21saXRlLm9yZy9hc3NldHMvaW1nL2xvZ28uc3ZnIiwidHlwZSI6ImltYWdlL3N2Zyt4bWwiLCJzaXplcyI6IjUxMng1MTIifV19:0 diff --git a/.playwright-mcp/console-2026-03-23T22-51-07-562Z.log b/.playwright-mcp/console-2026-03-23T22-51-07-562Z.log new file mode 100644 index 00000000..457e3b61 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-51-07-562Z.log @@ -0,0 +1 @@ +[ 871ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:5678/rest/login:0 diff --git a/.playwright-mcp/console-2026-03-23T22-51-37-826Z.log b/.playwright-mcp/console-2026-03-23T22-51-37-826Z.log new file mode 100644 index 00000000..76a1cf80 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-51-37-826Z.log @@ -0,0 +1 @@ +[ 343ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/favicon.ico:0 diff --git a/.playwright-mcp/console-2026-03-23T22-52-05-150Z.log b/.playwright-mcp/console-2026-03-23T22-52-05-150Z.log new file mode 100644 index 00000000..1a947742 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-52-05-150Z.log @@ -0,0 +1 @@ +[ 238ms] [WARNING] Simple Analytics: Set hostname on localhost:8090. See https://docs.simpleanalytics.com/overwrite-domain-name @ https://scripts.simpleanalyticscdn.com/latest.js:2 diff --git a/.playwright-mcp/console-2026-03-23T22-52-17-790Z.log b/.playwright-mcp/console-2026-03-23T22-52-17-790Z.log new file mode 100644 index 00000000..9f14e7ca --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-52-17-790Z.log @@ -0,0 +1,5 @@ +[ 967ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/node_modules/vsda/rust/web/vsda_bg.wasm:0 +[ 969ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/node_modules/vsda/rust/web/vsda.js:0 +[ 1271ms] [WARNING] The web worker extension host is started in a same-origin iframe! @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:4591 +[ 1304ms] [WARNING] An iframe which has both allow-scripts and allow-same-origin for its sandbox attribute can escape its sandboxing. @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html?&vscodeWebWorkerExtHostId=2ab26743-4428-4df3-944e-d603e9a82c44:0 +[ 2145ms] [WARNING] AI generated workspace trust dialog contents not available. @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:4552 diff --git a/.playwright-mcp/console-2026-03-23T22-52-56-849Z.log b/.playwright-mcp/console-2026-03-23T22-52-56-849Z.log new file mode 100644 index 00000000..cd68f88a --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-52-56-849Z.log @@ -0,0 +1,11 @@ +[ 5ms] [ERROR] %c ERR color: #f33 [lifecycle] Long running operations during shutdown are unsupported in the web (id: join.disconnectRemote) @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:37 +[ 6ms] [ERROR] %c ERR color: #f33 [lifecycle] Long running operations during shutdown are unsupported in the web (id: join.chatSessionStore) @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:37 +[ 7ms] [ERROR] %c ERR color: #f33 [lifecycle] Long running operations during shutdown are unsupported in the web (id: join.chatEditingSession) @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:37 +[ 27ms] [ERROR] %c ERR color: #f33 Error creating chat editing session content folder vscode-remote:/home/coder/.local/share/code-server/User/workspaceStorage/4a334e63/chatEditingSessions/266a91b3-2e96-499a-bfc1-6d451b72bd57/contents Canceled: Canceled + at Object.call (http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:612:1374) + at http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:613:2181 + at async vOt.W (http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:4587:115075) + at async vOt.createFolder (http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:4587:114875) + at async ice.storeState (http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:2978:15032) + at async Promise.all (index 0) @ http://localhost:8888/stable-13ca0e47310505f4ab1ac59e891e9a3c5e5eec04/static/out/vs/code/browser/workbench/workbench.js:37 +[ 137ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:8025/api/v2/jim:0 diff --git a/.playwright-mcp/console-2026-03-23T22-53-09-505Z.log b/.playwright-mcp/console-2026-03-23T22-53-09-505Z.log new file mode 100644 index 00000000..2b461da6 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-53-09-505Z.log @@ -0,0 +1 @@ +[ 1014ms] [WARNING] GPS permission denied — enable location access in your browser settings @ http://localhost:3002/src/components/canvass/GPSTracker.tsx:32 diff --git a/.playwright-mcp/console-2026-03-23T22-53-56-906Z.log b/.playwright-mcp/console-2026-03-23T22-53-56-906Z.log new file mode 100644 index 00000000..e32c9eb6 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T22-53-56-906Z.log @@ -0,0 +1,2 @@ +[ 600748ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/social/notifications/count:0 +[ 1560748ms] [ERROR] Failed to load resource: the server responded with a status of 401 (Unauthorized) @ http://localhost:3002/api/social/notifications/count:0 diff --git a/.playwright-mcp/console-2026-03-23T23-20-48-176Z.log b/.playwright-mcp/console-2026-03-23T23-20-48-176Z.log new file mode 100644 index 00000000..cb621a81 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T23-20-48-176Z.log @@ -0,0 +1,12 @@ +[ 127ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 127ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3242:41) + at async initSearch (http://localhost:4003/lander/:3307:9) @ http://localhost:4003/lander/:3254 +[ 626262ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 626262ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3212:41) + at async initSearch (http://localhost:4003/lander/:3277:9) @ http://localhost:4003/lander/:3224 +[ 628485ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 628485ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3212:41) + at async initSearch (http://localhost:4003/lander/:3277:9) @ http://localhost:4003/lander/:3224 diff --git a/.playwright-mcp/console-2026-03-23T23-31-23-226Z.log b/.playwright-mcp/console-2026-03-23T23-31-23-226Z.log new file mode 100644 index 00000000..29c5febe --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T23-31-23-226Z.log @@ -0,0 +1,60 @@ +[ 86ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 87ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3212:41) + at async initSearch (http://localhost:4003/lander/:3277:9) @ http://localhost:4003/lander/:3224 +[ 426459ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 426459ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3213:41) + at async initSearch (http://localhost:4003/lander/:3278:9) @ http://localhost:4003/lander/:3225 +[ 433706ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 433706ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3214:41) + at async initSearch (http://localhost:4003/lander/:3279:9) @ http://localhost:4003/lander/:3226 +[ 436108ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 436108ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3214:41) + at async initSearch (http://localhost:4003/lander/:3279:9) @ http://localhost:4003/lander/:3226 +[ 445396ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 445396ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3237:41) + at async initSearch (http://localhost:4003/lander/:3302:9) @ http://localhost:4003/lander/:3249 +[ 447757ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 447757ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3237:41) + at async initSearch (http://localhost:4003/lander/:3302:9) @ http://localhost:4003/lander/:3249 +[ 455113ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 455113ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3237:41) + at async initSearch (http://localhost:4003/lander/:3302:9) @ http://localhost:4003/lander/:3249 +[ 457733ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 457733ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3237:41) + at async initSearch (http://localhost:4003/lander/:3302:9) @ http://localhost:4003/lander/:3249 +[ 489124ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 489124ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3252:41) + at async initSearch (http://localhost:4003/lander/:3317:9) @ http://localhost:4003/lander/:3264 +[ 491509ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 491509ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3252:41) + at async initSearch (http://localhost:4003/lander/:3317:9) @ http://localhost:4003/lander/:3264 +[ 510185ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 510185ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3257:41) + at async initSearch (http://localhost:4003/lander/:3322:9) @ http://localhost:4003/lander/:3269 +[ 528536ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 528536ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3262:41) + at async initSearch (http://localhost:4003/lander/:3327:9) @ http://localhost:4003/lander/:3274 +[ 530976ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 530976ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3262:41) + at async initSearch (http://localhost:4003/lander/:3327:9) @ http://localhost:4003/lander/:3274 +[ 541596ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 541596ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3322:41) + at async initSearch (http://localhost:4003/lander/:3387:9) @ http://localhost:4003/lander/:3334 +[ 543950ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 543950ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3322:41) + at async initSearch (http://localhost:4003/lander/:3387:9) @ http://localhost:4003/lander/:3334 diff --git a/.playwright-mcp/console-2026-03-23T23-40-33-067Z.log b/.playwright-mcp/console-2026-03-23T23-40-33-067Z.log new file mode 100644 index 00000000..1b05b3b8 --- /dev/null +++ b/.playwright-mcp/console-2026-03-23T23-40-33-067Z.log @@ -0,0 +1,28 @@ +[ 96ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 97ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3322:41) + at async initSearch (http://localhost:4003/lander/:3387:9) @ http://localhost:4003/lander/:3334 +[ 320202ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 320202ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3335:41) + at async initSearch (http://localhost:4003/lander/:3400:9) @ http://localhost:4003/lander/:3347 +[ 329151ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 329151ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3337:41) + at async initSearch (http://localhost:4003/lander/:3402:9) @ http://localhost:4003/lander/:3349 +[ 331533ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 331533ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3337:41) + at async initSearch (http://localhost:4003/lander/:3402:9) @ http://localhost:4003/lander/:3349 +[ 628619ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 628619ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3337:41) + at async initSearch (http://localhost:4003/lander/:3402:9) @ http://localhost:4003/lander/:3349 +[ 631005ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 631005ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3337:41) + at async initSearch (http://localhost:4003/lander/:3402:9) @ http://localhost:4003/lander/:3349 +[ 633385ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:4003/lander/search/search_index.json:0 +[ 633385ms] [ERROR] Search init failed: Error: Failed to load search index + at MkDocsSearch.initialize (http://localhost:4003/lander/:3337:41) + at async initSearch (http://localhost:4003/lander/:3402:9) @ http://localhost:4003/lander/:3349 diff --git a/.playwright-mcp/page-2026-03-23T20-13-17-545Z.png b/.playwright-mcp/page-2026-03-23T20-13-17-545Z.png new file mode 100644 index 00000000..52136a66 Binary files /dev/null and b/.playwright-mcp/page-2026-03-23T20-13-17-545Z.png differ diff --git a/.playwright-mcp/page-2026-03-23T20-19-33-396Z.png b/.playwright-mcp/page-2026-03-23T20-19-33-396Z.png new file mode 100644 index 00000000..45aeaa58 Binary files /dev/null and b/.playwright-mcp/page-2026-03-23T20-19-33-396Z.png differ diff --git a/admin/src/pages/ListmonkPage.tsx b/admin/src/pages/ListmonkPage.tsx index bf96fd3c..3a4b219a 100644 --- a/admin/src/pages/ListmonkPage.tsx +++ b/admin/src/pages/ListmonkPage.tsx @@ -175,14 +175,20 @@ export default function ListmonkPage() { const { setPageHeader } = useOutletContext(); + const buildProxyAuthUrl = useCallback((token: string) => { + if (!config) return null; + const base = buildServiceUrl(config.listmonkSubdomain, config.domain, config.listmonkPort); + return `${base}/auth?token=${encodeURIComponent(token)}`; + }, [config]); + const loadIframe = useCallback(async () => { if (iframeInitialized.current && iframeSrc) return; setIframeLoading(true); setIframeError(null); try { const res = await api.get<{ port: number; token: string }>('/listmonk/proxy-url'); - const { port, token } = res.data; - const url = `//${window.location.hostname}:${port}/auth?token=${encodeURIComponent(token)}`; + const url = buildProxyAuthUrl(res.data.token); + if (!url) throw new Error('Config not loaded'); setIframeSrc(url); iframeInitialized.current = true; } catch { @@ -190,11 +196,17 @@ export default function ListmonkPage() { } finally { setIframeLoading(false); } - }, [iframeSrc]); + }, [iframeSrc, buildProxyAuthUrl]); - const listmonkAdminUrl = config - ? buildServiceUrl(config.listmonkSubdomain, config.domain, config.listmonkPort) - : null; + const handleOpenListmonk = useCallback(async () => { + try { + const res = await api.get<{ port: number; token: string }>('/listmonk/proxy-url'); + const url = buildProxyAuthUrl(res.data.token); + if (url) window.open(url, '_blank'); + } catch { + message.error('Failed to get Listmonk auth URL'); + } + }, [buildProxyAuthUrl]); useEffect(() => { setPageHeader({ title: 'Newsletter / Listmonk', fullBleed: activeTab === 'admin' }); @@ -234,12 +246,11 @@ export default function ListmonkPage() { > Test Connection - {listmonkAdminUrl && ( + {config && ( diff --git a/api/src/modules/services/services.routes.ts b/api/src/modules/services/services.routes.ts index e8eda816..f2bddad6 100644 --- a/api/src/modules/services/services.routes.ts +++ b/api/src/modules/services/services.routes.ts @@ -83,7 +83,7 @@ router.get( miniqrSubdomain: 'qr', excalidrawSubdomain: 'draw', // Listmonk (newsletter platform) - listmonkPort: 9001, + listmonkPort: env.LISTMONK_PROXY_PORT, listmonkSubdomain: 'listmonk', // Code Server (web IDE) codeServerPort: env.CODE_SERVER_PORT, diff --git a/mkdocs/.cache/plugin/social/assets/images/social/docs/upgrade-test-canary.png b/mkdocs/.cache/plugin/social/assets/images/social/docs/upgrade-test-canary.png new file mode 100644 index 00000000..31e2739e Binary files /dev/null and b/mkdocs/.cache/plugin/social/assets/images/social/docs/upgrade-test-canary.png differ diff --git a/mkdocs/.cache/plugin/social/assets/images/social/test-page.png b/mkdocs/.cache/plugin/social/assets/images/social/test-page.png index e337ba08..6a97489c 100644 Binary files a/mkdocs/.cache/plugin/social/assets/images/social/test-page.png and b/mkdocs/.cache/plugin/social/assets/images/social/test-page.png differ diff --git a/mkdocs/.cache/plugin/social/manifest.json b/mkdocs/.cache/plugin/social/manifest.json index b69e2aaa..bb836ceb 100644 --- a/mkdocs/.cache/plugin/social/manifest.json +++ b/mkdocs/.cache/plugin/social/manifest.json @@ -112,6 +112,7 @@ "assets/images/social/docs/phil.png": "ffe46a0052d8c23422f82d91e03a213118869539", "assets/images/social/docs/services/index.png": "9fcf00324266a9f7b58c7b277da2127e8882aa47", "assets/images/social/docs/troubleshooting/index.png": "b0ffadb8b01b261dfe7dea1b55fe02a3d639b7e7", + "assets/images/social/docs/upgrade-test-canary.png": "3d624f3412465c0f327ac1562675ae45dd30c3ce", "assets/images/social/docs/user-guide/campaigns.png": "298b1e317e065ba0459d4cd5779ce16a278b3c09", "assets/images/social/docs/user-guide/donations.png": "a907a64483b99ba1d1b3841a3b5928f1a77d73e4", "assets/images/social/docs/user-guide/events.png": "b4fed5fb2b288500035a68455b01994710c4aa98", @@ -149,7 +150,7 @@ "assets/images/social/services/postgresql.png": "831fb68dd3e01d9a017e59b100aaa8a455c8c112", "assets/images/social/services/static-server.png": "f36d527c80adba4bcb7778784683f429acb4ce74", "assets/images/social/test-2.png": "a6ae43d52d7c58fc106a562777e03b7da2263f83", - "assets/images/social/test-page.png": "af2c353ee377343678a58555726f6ad7d0624488", + "assets/images/social/test-page.png": "c9d5751a1f0a4c1341336bb7d00c9bc743d33ef4", "assets/images/social/test.png": "a6ae43d52d7c58fc106a562777e03b7da2263f83", "assets/images/social/testing.png": "f7aaf394b71cbe7084a6afa0e75a324ca59e23d8", "assets/images/social/v1/adv/ansible.png": "cb542ad9a3cc9a869258b3b1353966e1b9616a2b", diff --git a/mkdocs/docs/assets/images/screenshots/features/admin-cuts.png b/mkdocs/docs/assets/images/screenshots/features/admin-cuts.png new file mode 100644 index 00000000..2b74894f Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/admin-cuts.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/admin-dashboard.png b/mkdocs/docs/assets/images/screenshots/features/admin-dashboard.png new file mode 100644 index 00000000..6a95bec0 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/admin-dashboard.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/admin-listmonk.png b/mkdocs/docs/assets/images/screenshots/features/admin-listmonk.png new file mode 100644 index 00000000..32ba7211 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/admin-listmonk.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/admin-locations.png b/mkdocs/docs/assets/images/screenshots/features/admin-locations.png new file mode 100644 index 00000000..4018b0b1 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/admin-locations.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/admin-observability.png b/mkdocs/docs/assets/images/screenshots/features/admin-observability.png new file mode 100644 index 00000000..0b4c53a6 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/admin-observability.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/admin-settings.png b/mkdocs/docs/assets/images/screenshots/features/admin-settings.png new file mode 100644 index 00000000..a89cf579 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/admin-settings.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/admin-shifts.png b/mkdocs/docs/assets/images/screenshots/features/admin-shifts.png new file mode 100644 index 00000000..0f3efc1e Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/admin-shifts.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/admin-users.png b/mkdocs/docs/assets/images/screenshots/features/admin-users.png new file mode 100644 index 00000000..98f6ce32 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/admin-users.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/canvass-dashboard.png b/mkdocs/docs/assets/images/screenshots/features/canvass-dashboard.png new file mode 100644 index 00000000..977c4664 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/canvass-dashboard.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/code-server.png b/mkdocs/docs/assets/images/screenshots/features/code-server.png new file mode 100644 index 00000000..d4cbd531 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/code-server.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/data-quality.png b/mkdocs/docs/assets/images/screenshots/features/data-quality.png new file mode 100644 index 00000000..070db04e Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/data-quality.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/donation-pages.png b/mkdocs/docs/assets/images/screenshots/features/donation-pages.png new file mode 100644 index 00000000..e3f49cc9 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/donation-pages.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/email-queue.png b/mkdocs/docs/assets/images/screenshots/features/email-queue.png new file mode 100644 index 00000000..23134236 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/email-queue.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/email-templates.png b/mkdocs/docs/assets/images/screenshots/features/email-templates.png new file mode 100644 index 00000000..7aeac9ce Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/email-templates.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/excalidraw.png b/mkdocs/docs/assets/images/screenshots/features/excalidraw.png new file mode 100644 index 00000000..6f4ff8ba Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/excalidraw.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/gallery-ads.png b/mkdocs/docs/assets/images/screenshots/features/gallery-ads.png new file mode 100644 index 00000000..a15d1b91 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/gallery-ads.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/gitea.png b/mkdocs/docs/assets/images/screenshots/features/gitea.png new file mode 100644 index 00000000..1f9a8a57 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/gitea.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/influence-campaigns.png b/mkdocs/docs/assets/images/screenshots/features/influence-campaigns.png new file mode 100644 index 00000000..a83f3000 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/influence-campaigns.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/landing-pages.png b/mkdocs/docs/assets/images/screenshots/features/landing-pages.png new file mode 100644 index 00000000..50dda5c8 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/landing-pages.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/mailhog.png b/mkdocs/docs/assets/images/screenshots/features/mailhog.png new file mode 100644 index 00000000..daa3dd97 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/mailhog.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/map-settings.png b/mkdocs/docs/assets/images/screenshots/features/map-settings.png new file mode 100644 index 00000000..8f8d8c23 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/map-settings.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/media-analytics.png b/mkdocs/docs/assets/images/screenshots/features/media-analytics.png new file mode 100644 index 00000000..420e4519 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/media-analytics.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/media-library.png b/mkdocs/docs/assets/images/screenshots/features/media-library.png new file mode 100644 index 00000000..cbf1671b Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/media-library.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/miniqr.png b/mkdocs/docs/assets/images/screenshots/features/miniqr.png new file mode 100644 index 00000000..8de75a9e Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/miniqr.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/mkdocs.png b/mkdocs/docs/assets/images/screenshots/features/mkdocs.png new file mode 100644 index 00000000..9b559289 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/mkdocs.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/n8n.png b/mkdocs/docs/assets/images/screenshots/features/n8n.png new file mode 100644 index 00000000..490fcfcb Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/n8n.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/nocodb.png b/mkdocs/docs/assets/images/screenshots/features/nocodb.png new file mode 100644 index 00000000..1bd1d21e Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/nocodb.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/pangolin-tunnel.png b/mkdocs/docs/assets/images/screenshots/features/pangolin-tunnel.png new file mode 100644 index 00000000..0986ce1d Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/pangolin-tunnel.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/payments-dashboard.png b/mkdocs/docs/assets/images/screenshots/features/payments-dashboard.png new file mode 100644 index 00000000..38ad2747 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/payments-dashboard.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/products-shop.png b/mkdocs/docs/assets/images/screenshots/features/products-shop.png new file mode 100644 index 00000000..18db5cd5 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/products-shop.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-campaigns.png b/mkdocs/docs/assets/images/screenshots/features/public-campaigns.png new file mode 100644 index 00000000..8ab6b80c Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-campaigns.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-donations.png b/mkdocs/docs/assets/images/screenshots/features/public-donations.png new file mode 100644 index 00000000..39173428 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-donations.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-events.png b/mkdocs/docs/assets/images/screenshots/features/public-events.png new file mode 100644 index 00000000..01390e64 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-events.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-gallery.png b/mkdocs/docs/assets/images/screenshots/features/public-gallery.png new file mode 100644 index 00000000..ab54dc81 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-gallery.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-home.png b/mkdocs/docs/assets/images/screenshots/features/public-home.png new file mode 100644 index 00000000..e4fe9ed9 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-home.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-map.png b/mkdocs/docs/assets/images/screenshots/features/public-map.png new file mode 100644 index 00000000..3d0d94fd Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-map.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-pricing.png b/mkdocs/docs/assets/images/screenshots/features/public-pricing.png new file mode 100644 index 00000000..4c5be85a Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-pricing.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-shifts.png b/mkdocs/docs/assets/images/screenshots/features/public-shifts.png new file mode 100644 index 00000000..9c5f8aae Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-shifts.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-shop.png b/mkdocs/docs/assets/images/screenshots/features/public-shop.png new file mode 100644 index 00000000..05b5e524 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-shop.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/public-wall-of-fame.png b/mkdocs/docs/assets/images/screenshots/features/public-wall-of-fame.png new file mode 100644 index 00000000..30fbf7f6 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/public-wall-of-fame.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/sms-dashboard.png b/mkdocs/docs/assets/images/screenshots/features/sms-dashboard.png new file mode 100644 index 00000000..622a20ff Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/sms-dashboard.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/subscription-plans.png b/mkdocs/docs/assets/images/screenshots/features/subscription-plans.png new file mode 100644 index 00000000..461e79be Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/subscription-plans.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/volunteer-calendar.png b/mkdocs/docs/assets/images/screenshots/features/volunteer-calendar.png new file mode 100644 index 00000000..ac5af0f4 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/volunteer-calendar.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/volunteer-dashboard.png b/mkdocs/docs/assets/images/screenshots/features/volunteer-dashboard.png new file mode 100644 index 00000000..aef11869 Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/volunteer-dashboard.png differ diff --git a/mkdocs/docs/assets/images/screenshots/features/volunteer-friends.png b/mkdocs/docs/assets/images/screenshots/features/volunteer-friends.png new file mode 100644 index 00000000..86a61f8d Binary files /dev/null and b/mkdocs/docs/assets/images/screenshots/features/volunteer-friends.png differ diff --git a/mkdocs/docs/assets/repo-data/admin-changemaker.lite.json b/mkdocs/docs/assets/repo-data/admin-changemaker.lite.json index 29eb2c62..159085f7 100644 --- a/mkdocs/docs/assets/repo-data/admin-changemaker.lite.json +++ b/mkdocs/docs/assets/repo-data/admin-changemaker.lite.json @@ -2,15 +2,15 @@ "full_name": "admin/changemaker.lite", "name": "changemaker.lite", "description": "Changemaker-lite is the current active development branch of Changemaker, focused on streamlining core services. These improvements will be merged into the master branch once ready.", - "html_url": "https://gitea.bnkops.com/admin/changemaker.lite", + "html_url": "http://gitea.bnkops.com/admin/changemaker.lite", "language": "HTML", "stars_count": 0, "forks_count": 0, - "open_issues_count": 23, - "updated_at": "2026-03-10T18:27:08-06:00", + "open_issues_count": 0, + "updated_at": "2026-03-23T15:48:06-06:00", "created_at": "2025-05-28T14:54:59-06:00", "clone_url": "https://gitea.bnkops.com/admin/changemaker.lite.git", "ssh_url": "git@gitea.bnkops.com:admin/changemaker.lite.git", "default_branch": "main", - "last_build_update": "2026-03-10T18:27:08-06:00" + "last_build_update": "2026-03-23T15:48:06-06:00" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/anthropics-claude-code.json b/mkdocs/docs/assets/repo-data/anthropics-claude-code.json index 75ecaac2..86f4e3f6 100644 --- a/mkdocs/docs/assets/repo-data/anthropics-claude-code.json +++ b/mkdocs/docs/assets/repo-data/anthropics-claude-code.json @@ -4,13 +4,13 @@ "description": "Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.", "html_url": "https://github.com/anthropics/claude-code", "language": "Shell", - "stars_count": 77129, - "forks_count": 6266, - "open_issues_count": 6171, - "updated_at": "2026-03-12T17:36:34Z", + "stars_count": 81725, + "forks_count": 6816, + "open_issues_count": 7445, + "updated_at": "2026-03-23T23:45:06Z", "created_at": "2025-02-22T17:41:21Z", "clone_url": "https://github.com/anthropics/claude-code.git", "ssh_url": "git@github.com:anthropics/claude-code.git", "default_branch": "main", - "last_build_update": "2026-03-12T07:12:41Z" + "last_build_update": "2026-03-20T22:24:50Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/coder-code-server.json b/mkdocs/docs/assets/repo-data/coder-code-server.json index bd21bc53..192a8e2c 100644 --- a/mkdocs/docs/assets/repo-data/coder-code-server.json +++ b/mkdocs/docs/assets/repo-data/coder-code-server.json @@ -4,13 +4,13 @@ "description": "VS Code in the browser", "html_url": "https://github.com/coder/code-server", "language": "TypeScript", - "stars_count": 76609, - "forks_count": 6547, - "open_issues_count": 172, - "updated_at": "2026-03-12T17:13:08Z", + "stars_count": 76802, + "forks_count": 6567, + "open_issues_count": 167, + "updated_at": "2026-03-23T23:30:09Z", "created_at": "2019-02-27T16:50:41Z", "clone_url": "https://github.com/coder/code-server.git", "ssh_url": "git@github.com:coder/code-server.git", "default_branch": "main", - "last_build_update": "2026-03-11T22:19:15Z" + "last_build_update": "2026-03-23T18:50:37Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/gethomepage-homepage.json b/mkdocs/docs/assets/repo-data/gethomepage-homepage.json index 34bce9dd..46b3bc59 100644 --- a/mkdocs/docs/assets/repo-data/gethomepage-homepage.json +++ b/mkdocs/docs/assets/repo-data/gethomepage-homepage.json @@ -4,13 +4,13 @@ "description": "A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.", "html_url": "https://github.com/gethomepage/homepage", "language": "JavaScript", - "stars_count": 28865, - "forks_count": 1813, + "stars_count": 29108, + "forks_count": 1825, "open_issues_count": 1, - "updated_at": "2026-03-12T15:01:15Z", + "updated_at": "2026-03-23T22:44:02Z", "created_at": "2022-08-24T07:29:42Z", "clone_url": "https://github.com/gethomepage/homepage.git", "ssh_url": "git@github.com:gethomepage/homepage.git", "default_branch": "dev", - "last_build_update": "2026-03-12T12:22:19Z" + "last_build_update": "2026-03-23T12:27:34Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/go-gitea-gitea.json b/mkdocs/docs/assets/repo-data/go-gitea-gitea.json index ef4abfd2..2a2d1493 100644 --- a/mkdocs/docs/assets/repo-data/go-gitea-gitea.json +++ b/mkdocs/docs/assets/repo-data/go-gitea-gitea.json @@ -4,13 +4,13 @@ "description": "Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD", "html_url": "https://github.com/go-gitea/gitea", "language": "Go", - "stars_count": 54251, - "forks_count": 6466, - "open_issues_count": 2853, - "updated_at": "2026-03-12T17:33:45Z", + "stars_count": 54439, + "forks_count": 6485, + "open_issues_count": 2870, + "updated_at": "2026-03-23T23:19:17Z", "created_at": "2016-11-01T02:13:26Z", "clone_url": "https://github.com/go-gitea/gitea.git", "ssh_url": "git@github.com:go-gitea/gitea.git", "default_branch": "main", - "last_build_update": "2026-03-12T08:26:47Z" + "last_build_update": "2026-03-23T23:20:24Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/knadh-listmonk.json b/mkdocs/docs/assets/repo-data/knadh-listmonk.json index 015ff904..4381eade 100644 --- a/mkdocs/docs/assets/repo-data/knadh-listmonk.json +++ b/mkdocs/docs/assets/repo-data/knadh-listmonk.json @@ -4,13 +4,13 @@ "description": "High performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.", "html_url": "https://github.com/knadh/listmonk", "language": "Go", - "stars_count": 19256, - "forks_count": 1946, - "open_issues_count": 101, - "updated_at": "2026-03-12T16:54:34Z", + "stars_count": 19329, + "forks_count": 1958, + "open_issues_count": 105, + "updated_at": "2026-03-23T23:36:16Z", "created_at": "2019-06-26T05:08:39Z", "clone_url": "https://github.com/knadh/listmonk.git", "ssh_url": "git@github.com:knadh/listmonk.git", "default_branch": "master", - "last_build_update": "2026-03-12T16:54:26Z" + "last_build_update": "2026-03-23T11:44:19Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/lyqht-mini-qr.json b/mkdocs/docs/assets/repo-data/lyqht-mini-qr.json index d2f2f9a8..c67a8a41 100644 --- a/mkdocs/docs/assets/repo-data/lyqht-mini-qr.json +++ b/mkdocs/docs/assets/repo-data/lyqht-mini-qr.json @@ -4,13 +4,13 @@ "description": "Create & scan cute qr codes easily \ud83d\udc7e", "html_url": "https://github.com/lyqht/mini-qr", "language": "Vue", - "stars_count": 1905, - "forks_count": 241, - "open_issues_count": 19, - "updated_at": "2026-03-12T17:06:09Z", + "stars_count": 1928, + "forks_count": 243, + "open_issues_count": 20, + "updated_at": "2026-03-23T14:42:50Z", "created_at": "2023-04-21T14:20:14Z", "clone_url": "https://github.com/lyqht/mini-qr.git", "ssh_url": "git@github.com:lyqht/mini-qr.git", "default_branch": "main", - "last_build_update": "2026-03-11T14:53:40Z" + "last_build_update": "2026-03-13T12:48:04Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/n8n-io-n8n.json b/mkdocs/docs/assets/repo-data/n8n-io-n8n.json index b106ed6c..d57c7a2f 100644 --- a/mkdocs/docs/assets/repo-data/n8n-io-n8n.json +++ b/mkdocs/docs/assets/repo-data/n8n-io-n8n.json @@ -4,13 +4,13 @@ "description": "Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.", "html_url": "https://github.com/n8n-io/n8n", "language": "TypeScript", - "stars_count": 178836, - "forks_count": 55709, - "open_issues_count": 1414, - "updated_at": "2026-03-12T17:33:04Z", + "stars_count": 180706, + "forks_count": 56089, + "open_issues_count": 1433, + "updated_at": "2026-03-23T23:47:25Z", "created_at": "2019-06-22T09:24:21Z", "clone_url": "https://github.com/n8n-io/n8n.git", "ssh_url": "git@github.com:n8n-io/n8n.git", "default_branch": "master", - "last_build_update": "2026-03-12T16:48:37Z" + "last_build_update": "2026-03-23T22:55:38Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/nocodb-nocodb.json b/mkdocs/docs/assets/repo-data/nocodb-nocodb.json index efbfb022..9072cbd1 100644 --- a/mkdocs/docs/assets/repo-data/nocodb-nocodb.json +++ b/mkdocs/docs/assets/repo-data/nocodb-nocodb.json @@ -4,13 +4,13 @@ "description": "\ud83d\udd25 \ud83d\udd25 \ud83d\udd25 A Free & Self-hostable Airtable Alternative", "html_url": "https://github.com/nocodb/nocodb", "language": "TypeScript", - "stars_count": 62459, - "forks_count": 4662, - "open_issues_count": 636, - "updated_at": "2026-03-12T17:22:54Z", + "stars_count": 62544, + "forks_count": 4679, + "open_issues_count": 647, + "updated_at": "2026-03-23T22:41:15Z", "created_at": "2017-10-29T18:51:48Z", "clone_url": "https://github.com/nocodb/nocodb.git", "ssh_url": "git@github.com:nocodb/nocodb.git", "default_branch": "develop", - "last_build_update": "2026-03-12T15:47:46Z" + "last_build_update": "2026-03-23T19:39:55Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/ollama-ollama.json b/mkdocs/docs/assets/repo-data/ollama-ollama.json index beefcf5f..b042dc06 100644 --- a/mkdocs/docs/assets/repo-data/ollama-ollama.json +++ b/mkdocs/docs/assets/repo-data/ollama-ollama.json @@ -4,13 +4,13 @@ "description": "Get up and running with Kimi-K2.5, GLM-5, MiniMax, DeepSeek, gpt-oss, Qwen, Gemma and other models.", "html_url": "https://github.com/ollama/ollama", "language": "Go", - "stars_count": 164918, - "forks_count": 14922, - "open_issues_count": 2623, - "updated_at": "2026-03-12T17:11:02Z", + "stars_count": 165968, + "forks_count": 15121, + "open_issues_count": 2708, + "updated_at": "2026-03-23T23:47:27Z", "created_at": "2023-06-26T19:39:32Z", "clone_url": "https://github.com/ollama/ollama.git", "ssh_url": "git@github.com:ollama/ollama.git", "default_branch": "main", - "last_build_update": "2026-03-12T08:42:26Z" + "last_build_update": "2026-03-23T23:31:24Z" } \ No newline at end of file diff --git a/mkdocs/docs/assets/repo-data/squidfunk-mkdocs-material.json b/mkdocs/docs/assets/repo-data/squidfunk-mkdocs-material.json index bd11df2d..66f348b2 100644 --- a/mkdocs/docs/assets/repo-data/squidfunk-mkdocs-material.json +++ b/mkdocs/docs/assets/repo-data/squidfunk-mkdocs-material.json @@ -4,13 +4,13 @@ "description": "Documentation that simply works", "html_url": "https://github.com/squidfunk/mkdocs-material", "language": "Python", - "stars_count": 26261, - "forks_count": 4053, - "open_issues_count": 2, - "updated_at": "2026-03-12T17:20:59Z", + "stars_count": 26370, + "forks_count": 4058, + "open_issues_count": 1, + "updated_at": "2026-03-23T21:42:58Z", "created_at": "2016-01-28T22:09:23Z", "clone_url": "https://github.com/squidfunk/mkdocs-material.git", "ssh_url": "git@github.com:squidfunk/mkdocs-material.git", "default_branch": "master", - "last_build_update": "2026-03-10T15:42:14Z" + "last_build_update": "2026-03-22T15:57:47Z" } \ No newline at end of file diff --git a/mkdocs/docs/lander.md b/mkdocs/docs/lander.md new file mode 100644 index 00000000..2350380c --- /dev/null +++ b/mkdocs/docs/lander.md @@ -0,0 +1,7 @@ +--- +template: lander.html +hide: + - navigation + - toc +title: "lander" +--- diff --git a/mkdocs/docs/main.md b/mkdocs/docs/main.md new file mode 100644 index 00000000..d8ab1699 --- /dev/null +++ b/mkdocs/docs/main.md @@ -0,0 +1,7 @@ +--- +template: main.html +hide: + - navigation + - toc +title: "main" +--- diff --git a/mkdocs/docs/overrides/lander.html b/mkdocs/docs/overrides/lander.html index 37ace877..9fbda767 100644 --- a/mkdocs/docs/overrides/lander.html +++ b/mkdocs/docs/overrides/lander.html @@ -386,6 +386,29 @@ box-shadow: 0 4px 16px rgba(111, 66, 193, 0.4); } + .btn-demo { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.625rem 1.5rem; + background: transparent; + color: var(--primary-light); + font-weight: 600; + font-size: 0.9rem; + border-radius: 8px; + border: 1px solid var(--primary-light); + cursor: pointer; + transition: all var(--transition); + text-decoration: none; + } + + .btn-demo:hover { + background: rgba(139, 92, 246, 0.1); + color: var(--primary-light); + transform: translateY(-1px); + box-shadow: 0 4px 16px rgba(111, 66, 193, 0.2); + } + .btn-secondary { display: inline-flex; align-items: center; @@ -1167,6 +1190,141 @@ color: var(--text-muted); } + /* ============================================ + FEATURE NODE — HOVER SCREENSHOT PREVIEW + ============================================ */ + .feature-node[data-screenshot] { + cursor: pointer; + } + + .node-screenshot { + max-height: 0; + overflow: hidden; + margin: 0 -1.5rem; + border-radius: 0; + transition: max-height 0.35s cubic-bezier(0.4, 0, 0.2, 1), margin-top 0.35s ease, margin-bottom 0.35s ease; + margin-top: 0; + margin-bottom: 0; + } + + .feature-node:hover .node-screenshot { + max-height: 300px; + margin-top: 0.75rem; + margin-bottom: 0.5rem; + } + + .node-screenshot img { + width: 100%; + height: auto; + display: block; + border-top: 1px solid var(--border-color); + border-bottom: 1px solid var(--border-color); + } + + .node-screenshot-label { + padding: 0.3rem 1.5rem; + font-size: 0.7rem; + color: var(--text-muted); + display: flex; + align-items: center; + gap: 0.4rem; + background: rgba(0,0,0,0.15); + } + + [data-theme="light"] .node-screenshot-label { + background: rgba(0,0,0,0.04); + } + + .node-screenshot-label .screenshot-dot { + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--success); + flex-shrink: 0; + } + + /* On mobile, hide hover screenshots (touch doesn't hover well) */ + @media (max-width: 768px) { + .node-screenshot { + display: none; + } + } + + /* ============================================ + NARRATIVE BRIDGE SECTION + ============================================ */ + .narrative-bridge { + padding: 4rem 0 2rem; + background: transparent; + } + + .narrative-content { + max-width: 720px; + margin: 0 auto; + text-align: center; + background: rgba(30, 41, 59, 0.85); + border: 1px solid rgba(148, 163, 184, 0.1); + border-radius: var(--radius-lg); + padding: 3rem 2.5rem; + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + position: relative; + z-index: 2; + } + + [data-theme="light"] .narrative-content { + background: rgba(255, 255, 255, 0.88); + border-color: rgba(100, 116, 139, 0.15); + } + + .narrative-eyebrow { + font-size: 0.8rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--primary-light); + margin-bottom: 1rem; + } + + .narrative-content h2 { + font-size: clamp(1.5rem, 3vw, 2.25rem); + margin-bottom: 1.25rem; + line-height: 1.3; + } + + .narrative-body { + color: var(--text-secondary); + font-size: 1.1rem; + line-height: 1.7; + } + + /* In-feature narrative connectors */ + .branch-narrative { + max-width: 640px; + margin: 2rem auto 3rem; + text-align: center; + padding: 1.5rem 2rem; + background: rgba(30, 41, 59, 0.85); + border: 1px solid rgba(148, 163, 184, 0.1); + border-radius: var(--radius-lg); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + position: relative; + z-index: 2; + } + + [data-theme="light"] .branch-narrative { + background: rgba(255, 255, 255, 0.45); + border-color: rgba(100, 116, 139, 0.1); + } + + .branch-narrative p { + color: var(--text-secondary); + font-size: 1rem; + line-height: 1.7; + margin: 0; + } + /* ============================================ LIVE SITES ============================================ */ @@ -1915,6 +2073,7 @@ + Explore Demo Get Started + + + + + + + + + + + + + + + + + + + + + - + diff --git a/mkdocs/site/testing/index.html b/mkdocs/site/404/index.html similarity index 90% rename from mkdocs/site/testing/index.html rename to mkdocs/site/404/index.html index d68734fc..ef29bda1 100644 --- a/mkdocs/site/testing/index.html +++ b/mkdocs/site/404/index.html @@ -13,7 +13,7 @@ - + @@ -22,11 +22,11 @@ - + - testing - Changemaker Lite + Page Not Found - Changemaker Lite @@ -126,24 +126,24 @@ })(); - + - + - + - + - + - + @@ -163,7 +163,7 @@
- + Skip to content @@ -845,11 +845,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -940,7 +940,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1146,7 +1146,9 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { -
+ + + @@ -1466,7 +1470,7 @@ setTimeout(function() { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/advocacy/campaigns/index.html b/mkdocs/site/docs/admin/advocacy/campaigns/index.html index 8858cc4d..acef8c03 100644 --- a/mkdocs/site/docs/admin/advocacy/campaigns/index.html +++ b/mkdocs/site/docs/admin/advocacy/campaigns/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2784,6 +2792,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3032,9 +3042,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3043,7 +3085,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3149,6 +3191,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
+ +
@@ -3207,7 +3251,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/advocacy/email-queue/index.html b/mkdocs/site/docs/admin/advocacy/email-queue/index.html index 977c8a03..e7c4a5a2 100644 --- a/mkdocs/site/docs/admin/advocacy/email-queue/index.html +++ b/mkdocs/site/docs/admin/advocacy/email-queue/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2729,6 +2737,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2922,9 +2932,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2933,7 +2975,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2979,6 +3021,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3037,7 +3081,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/advocacy/index.html b/mkdocs/site/docs/admin/advocacy/index.html index 89924e38..fe7f7685 100644 --- a/mkdocs/site/docs/admin/advocacy/index.html +++ b/mkdocs/site/docs/admin/advocacy/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2656,6 +2664,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2838,9 +2848,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2849,7 +2884,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2888,6 +2923,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2946,7 +2983,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/advocacy/representatives/index.html b/mkdocs/site/docs/admin/advocacy/representatives/index.html index 1731ee65..9a5059fb 100644 --- a/mkdocs/site/docs/admin/advocacy/representatives/index.html +++ b/mkdocs/site/docs/admin/advocacy/representatives/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2729,6 +2737,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2922,9 +2932,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2933,7 +2968,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2978,6 +3013,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3036,7 +3073,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/advocacy/responses/index.html b/mkdocs/site/docs/admin/advocacy/responses/index.html index fd85d26b..b8cf3998 100644 --- a/mkdocs/site/docs/admin/advocacy/responses/index.html +++ b/mkdocs/site/docs/admin/advocacy/responses/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2729,6 +2737,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2922,9 +2932,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2933,7 +2975,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2979,6 +3021,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3037,7 +3081,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/broadcast/email-templates/index.html b/mkdocs/site/docs/admin/broadcast/email-templates/index.html index bd7699e4..1913eaff 100644 --- a/mkdocs/site/docs/admin/broadcast/email-templates/index.html +++ b/mkdocs/site/docs/admin/broadcast/email-templates/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1872,6 +1880,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2743,6 +2759,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2980,9 +2998,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2991,7 +3041,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3068,6 +3118,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3126,7 +3178,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/broadcast/index.html b/mkdocs/site/docs/admin/broadcast/index.html index ee51d47f..b2a84c0d 100644 --- a/mkdocs/site/docs/admin/broadcast/index.html +++ b/mkdocs/site/docs/admin/broadcast/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1755,6 +1763,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2626,6 +2642,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2808,9 +2826,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2819,7 +2862,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2857,6 +2900,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2915,7 +2960,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/broadcast/newsletter/index.html b/mkdocs/site/docs/admin/broadcast/newsletter/index.html index f862de3c..05135a78 100644 --- a/mkdocs/site/docs/admin/broadcast/newsletter/index.html +++ b/mkdocs/site/docs/admin/broadcast/newsletter/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1850,6 +1858,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2721,6 +2737,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2936,9 +2954,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2947,7 +2997,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3073,6 +3123,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3131,7 +3183,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/broadcast/sms/index.html b/mkdocs/site/docs/admin/broadcast/sms/index.html index b492b6d5..54a74886 100644 --- a/mkdocs/site/docs/admin/broadcast/sms/index.html +++ b/mkdocs/site/docs/admin/broadcast/sms/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1764,6 +1772,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1784,6 +1800,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -3115,6 +3139,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3724,9 +3750,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3735,7 +3793,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -4288,6 +4346,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -4346,7 +4406,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/dashboard/index.html b/mkdocs/site/docs/admin/dashboard/index.html index 0de67f6c..e3dc3903 100644 --- a/mkdocs/site/docs/admin/dashboard/index.html +++ b/mkdocs/site/docs/admin/dashboard/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1584,6 +1584,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2577,6 +2585,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2741,9 +2751,27 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2752,7 +2780,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2795,6 +2823,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2853,7 +2883,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/index.html b/mkdocs/site/docs/admin/index.html index 2f0a4169..78f8aa5f 100644 --- a/mkdocs/site/docs/admin/index.html +++ b/mkdocs/site/docs/admin/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2515,6 +2523,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2690,9 +2700,27 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2701,7 +2729,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2778,15 +2806,39 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { SUPER_ADMIN -Full platform access +Full platform access — implicitly bypasses all role checks INFLUENCE_ADMIN -Campaigns, responses, email queue +Campaigns, responses, representatives, email queue MAP_ADMIN -Locations, areas, shifts, canvassing +Locations, areas, shifts, canvassing, data quality + + +BROADCAST_ADMIN +Newsletter sync, email templates + + +CONTENT_ADMIN +Landing pages, homepage, navigation, documentation + + +MEDIA_ADMIN +Video library, analytics, gallery, moderation, ads + + +PAYMENTS_ADMIN +Products, donations, plans, Stripe configuration + + +EVENTS_ADMIN +Gancio event sync and calendar management + + +SOCIAL_ADMIN +Social connections, achievements, calendar layers USER @@ -2794,7 +2846,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { TEMP -Limited volunteer access (auto-created) +Limited volunteer access (auto-created on shift signup) @@ -2820,6 +2872,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2878,7 +2932,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/map/areas/index.html b/mkdocs/site/docs/admin/map/areas/index.html index 7d7c1df1..5b169f4e 100644 --- a/mkdocs/site/docs/admin/map/areas/index.html +++ b/mkdocs/site/docs/admin/map/areas/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2800,6 +2808,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3004,9 +3014,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3015,7 +3057,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3071,6 +3113,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3129,7 +3173,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/map/canvassing/index.html b/mkdocs/site/docs/admin/map/canvassing/index.html index 3e6b2a72..48641525 100644 --- a/mkdocs/site/docs/admin/map/canvassing/index.html +++ b/mkdocs/site/docs/admin/map/canvassing/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2811,6 +2819,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3026,9 +3036,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3037,7 +3079,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3099,6 +3141,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3157,7 +3201,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/map/data-quality/index.html b/mkdocs/site/docs/admin/map/data-quality/index.html index 4673d81d..7c784e86 100644 --- a/mkdocs/site/docs/admin/map/data-quality/index.html +++ b/mkdocs/site/docs/admin/map/data-quality/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2789,6 +2797,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2982,9 +2992,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2993,7 +3035,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3039,6 +3081,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3097,7 +3141,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/map/index.html b/mkdocs/site/docs/admin/map/index.html index 2fd47f5f..88288802 100644 --- a/mkdocs/site/docs/admin/map/index.html +++ b/mkdocs/site/docs/admin/map/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2716,6 +2724,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2898,9 +2908,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2909,7 +2944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2950,6 +2985,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3008,7 +3045,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/map/locations/index.html b/mkdocs/site/docs/admin/map/locations/index.html index 70b3f640..75b39347 100644 --- a/mkdocs/site/docs/admin/map/locations/index.html +++ b/mkdocs/site/docs/admin/map/locations/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2811,6 +2819,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3026,9 +3036,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3037,7 +3079,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3094,6 +3136,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3152,7 +3196,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/map/settings/index.html b/mkdocs/site/docs/admin/map/settings/index.html index 646252ee..f30921df 100644 --- a/mkdocs/site/docs/admin/map/settings/index.html +++ b/mkdocs/site/docs/admin/map/settings/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2789,6 +2797,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2982,9 +2992,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2993,7 +3035,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3037,6 +3079,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3095,7 +3139,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/map/shifts/index.html b/mkdocs/site/docs/admin/map/shifts/index.html index c9cc42c2..588396b2 100644 --- a/mkdocs/site/docs/admin/map/shifts/index.html +++ b/mkdocs/site/docs/admin/map/shifts/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2811,6 +2819,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3026,9 +3036,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3037,7 +3079,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3095,6 +3137,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3153,7 +3197,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/media/ads/index.html b/mkdocs/site/docs/admin/media/ads/index.html index 4854eb62..930ec0a4 100644 --- a/mkdocs/site/docs/admin/media/ads/index.html +++ b/mkdocs/site/docs/admin/media/ads/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2028,6 +2036,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2048,6 +2064,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2759,6 +2783,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2952,9 +2978,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2963,7 +3014,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3008,6 +3059,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3066,7 +3119,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/media/analytics/index.html b/mkdocs/site/docs/admin/media/analytics/index.html index beb00a09..c63fac10 100644 --- a/mkdocs/site/docs/admin/media/analytics/index.html +++ b/mkdocs/site/docs/admin/media/analytics/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2114,6 +2122,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2781,6 +2797,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2996,9 +3014,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3007,7 +3057,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3070,6 +3120,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3128,7 +3180,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/media/curated/index.html b/mkdocs/site/docs/admin/media/curated/index.html index 77561012..65d4f211 100644 --- a/mkdocs/site/docs/admin/media/curated/index.html +++ b/mkdocs/site/docs/admin/media/curated/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2103,6 +2111,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2770,6 +2786,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2974,9 +2992,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2985,7 +3035,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3039,6 +3089,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3097,7 +3149,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/media/index.html b/mkdocs/site/docs/admin/media/index.html index 96538fe2..89721d57 100644 --- a/mkdocs/site/docs/admin/media/index.html +++ b/mkdocs/site/docs/admin/media/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2019,6 +2027,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2686,6 +2702,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2868,9 +2886,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2879,7 +2922,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2919,6 +2962,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2977,7 +3022,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/media/library/index.html b/mkdocs/site/docs/admin/media/library/index.html index 4b8d4f8d..a8ddc27f 100644 --- a/mkdocs/site/docs/admin/media/library/index.html +++ b/mkdocs/site/docs/admin/media/library/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2125,6 +2133,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2792,6 +2808,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3018,9 +3036,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3029,7 +3079,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3093,6 +3143,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3151,7 +3203,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/media/moderation/index.html b/mkdocs/site/docs/admin/media/moderation/index.html index 1a5c7a1e..b9724aef 100644 --- a/mkdocs/site/docs/admin/media/moderation/index.html +++ b/mkdocs/site/docs/admin/media/moderation/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2114,6 +2122,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2781,6 +2797,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2996,9 +3014,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3007,7 +3057,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3090,6 +3140,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3148,7 +3200,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/payments/donations/index.html b/mkdocs/site/docs/admin/payments/donations/index.html index 36eaa64e..631d57e3 100644 --- a/mkdocs/site/docs/admin/payments/donations/index.html +++ b/mkdocs/site/docs/admin/payments/donations/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1919,6 +1927,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1965,6 +1981,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2004,6 +2028,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2024,6 +2056,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2109,6 +2149,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2139,6 +2187,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2740,6 +2796,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2944,9 +3002,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2955,7 +3038,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3011,6 +3094,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3069,7 +3154,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/payments/index.html b/mkdocs/site/docs/admin/payments/index.html index 659119e8..4c4b3775 100644 --- a/mkdocs/site/docs/admin/payments/index.html +++ b/mkdocs/site/docs/admin/payments/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1919,6 +1927,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1965,6 +1981,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1995,6 +2019,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2025,6 +2057,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2055,6 +2095,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2656,6 +2704,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2849,9 +2899,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2860,7 +2935,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2906,6 +2981,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2964,7 +3041,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/payments/plans/index.html b/mkdocs/site/docs/admin/payments/plans/index.html index 952f10dd..1fcf0891 100644 --- a/mkdocs/site/docs/admin/payments/plans/index.html +++ b/mkdocs/site/docs/admin/payments/plans/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1919,6 +1927,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1965,6 +1981,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1995,6 +2019,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2034,6 +2066,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2054,6 +2094,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2128,6 +2176,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2729,6 +2785,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2922,9 +2980,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2933,7 +3016,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2978,6 +3061,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3036,7 +3121,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/payments/products/index.html b/mkdocs/site/docs/admin/payments/products/index.html index c37ba6b2..182f6f48 100644 --- a/mkdocs/site/docs/admin/payments/products/index.html +++ b/mkdocs/site/docs/admin/payments/products/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1919,6 +1927,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1974,6 +1990,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1994,6 +2018,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2068,6 +2100,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2098,6 +2138,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2128,6 +2176,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2729,6 +2785,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2922,9 +2980,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2933,7 +3016,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2977,6 +3060,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3035,7 +3120,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/payments/settings/index.html b/mkdocs/site/docs/admin/payments/settings/index.html index 98bd7261..57219252 100644 --- a/mkdocs/site/docs/admin/payments/settings/index.html +++ b/mkdocs/site/docs/admin/payments/settings/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1919,6 +1927,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1965,6 +1981,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1995,6 +2019,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2025,6 +2057,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2064,6 +2104,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2084,6 +2132,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2740,6 +2796,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2944,9 +3002,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2955,7 +3045,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3006,6 +3096,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3064,7 +3156,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/people-access/index.html b/mkdocs/site/docs/admin/people-access/index.html index 380bd075..4261fa33 100644 --- a/mkdocs/site/docs/admin/people-access/index.html +++ b/mkdocs/site/docs/admin/people-access/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1531,6 +1531,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1551,6 +1559,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2765,6 +2781,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3117,9 +3135,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3128,7 +3171,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3310,6 +3353,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3368,7 +3413,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/services/crowdsec/index.html b/mkdocs/site/docs/admin/services/crowdsec/index.html index 72291ce2..dfbc47ac 100644 --- a/mkdocs/site/docs/admin/services/crowdsec/index.html +++ b/mkdocs/site/docs/admin/services/crowdsec/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2072,6 +2080,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2092,6 +2108,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2365,6 +2389,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2898,6 +2930,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3230,9 +3264,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3241,7 +3307,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3477,6 +3543,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3535,7 +3603,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/services/index.html b/mkdocs/site/docs/admin/services/index.html index f1bf7926..2c579674 100644 --- a/mkdocs/site/docs/admin/services/index.html +++ b/mkdocs/site/docs/admin/services/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2063,6 +2071,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2153,6 +2169,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2686,6 +2710,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2868,9 +2894,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2879,7 +2930,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2919,6 +2970,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2977,7 +3030,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/services/integrations/index.html b/mkdocs/site/docs/admin/services/integrations/index.html index 15c9c4d9..7ce62ead 100644 --- a/mkdocs/site/docs/admin/services/integrations/index.html +++ b/mkdocs/site/docs/admin/services/integrations/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2063,6 +2071,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2281,6 +2297,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2814,6 +2838,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3062,9 +3088,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3073,7 +3131,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3171,6 +3229,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3229,7 +3289,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/services/monitoring/index.html b/mkdocs/site/docs/admin/services/monitoring/index.html index 08eadfd3..5b79d4b9 100644 --- a/mkdocs/site/docs/admin/services/monitoring/index.html +++ b/mkdocs/site/docs/admin/services/monitoring/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2063,6 +2071,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2270,6 +2286,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2803,6 +2827,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3040,9 +3066,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3051,7 +3109,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3125,6 +3183,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3183,7 +3243,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/services/tunnel/index.html b/mkdocs/site/docs/admin/services/tunnel/index.html index 0d936ed1..0a61c37b 100644 --- a/mkdocs/site/docs/admin/services/tunnel/index.html +++ b/mkdocs/site/docs/admin/services/tunnel/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2169,6 +2177,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2259,6 +2275,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2792,6 +2816,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3018,9 +3044,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3029,7 +3087,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3098,6 +3156,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3156,7 +3216,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/services/user-provisioning/index.html b/mkdocs/site/docs/admin/services/user-provisioning/index.html index a2d66e6a..ee8eaa98 100644 --- a/mkdocs/site/docs/admin/services/user-provisioning/index.html +++ b/mkdocs/site/docs/admin/services/user-provisioning/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2063,6 +2071,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2162,6 +2178,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2182,6 +2206,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2781,6 +2813,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2996,9 +3030,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3007,7 +3066,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3088,6 +3147,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3146,7 +3207,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/settings/index.html b/mkdocs/site/docs/admin/settings/index.html index 63143604..f440029d 100644 --- a/mkdocs/site/docs/admin/settings/index.html +++ b/mkdocs/site/docs/admin/settings/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2649,6 +2657,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2885,9 +2895,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2896,7 +2931,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3079,6 +3114,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3137,7 +3174,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/web/documentation/index.html b/mkdocs/site/docs/admin/web/documentation/index.html index 24846e3d..c9cb8d63 100644 --- a/mkdocs/site/docs/admin/web/documentation/index.html +++ b/mkdocs/site/docs/admin/web/documentation/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2751,6 +2759,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2966,9 +2976,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2977,7 +3012,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3041,6 +3076,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3099,7 +3136,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/web/homepage/index.html b/mkdocs/site/docs/admin/web/homepage/index.html index cb31af7e..c0b0dc8f 100644 --- a/mkdocs/site/docs/admin/web/homepage/index.html +++ b/mkdocs/site/docs/admin/web/homepage/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2751,6 +2759,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2966,9 +2976,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2977,7 +3012,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3035,6 +3070,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3093,7 +3130,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/web/index.html b/mkdocs/site/docs/admin/web/index.html index 2cba550f..bd417768 100644 --- a/mkdocs/site/docs/admin/web/index.html +++ b/mkdocs/site/docs/admin/web/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2656,6 +2664,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2849,9 +2859,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2860,7 +2895,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2902,6 +2937,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2960,7 +2997,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/web/landing-pages/index.html b/mkdocs/site/docs/admin/web/landing-pages/index.html index 3a654b56..38f2c534 100644 --- a/mkdocs/site/docs/admin/web/landing-pages/index.html +++ b/mkdocs/site/docs/admin/web/landing-pages/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2740,6 +2748,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2944,9 +2954,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2955,7 +2997,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3005,6 +3047,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3063,7 +3107,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/admin/web/navigation/index.html b/mkdocs/site/docs/admin/web/navigation/index.html index f231265f..581e923a 100644 --- a/mkdocs/site/docs/admin/web/navigation/index.html +++ b/mkdocs/site/docs/admin/web/navigation/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1522,6 +1522,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2762,6 +2770,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2988,9 +2998,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2999,7 +3034,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3061,6 +3096,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3119,7 +3156,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/api/index.html b/mkdocs/site/docs/api/index.html index 880dca07..c19b468a 100644 --- a/mkdocs/site/docs/api/index.html +++ b/mkdocs/site/docs/api/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1952,6 +1952,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3102,9 +3104,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3113,7 +3140,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -6522,6 +6549,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -6580,7 +6609,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/architecture/index.html b/mkdocs/site/docs/architecture/index.html index b4f2bde8..bb007fd3 100644 --- a/mkdocs/site/docs/architecture/index.html +++ b/mkdocs/site/docs/architecture/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1952,6 +1952,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2025,10 +2027,10 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { @@ -2138,9 +2212,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2149,7 +2248,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2157,17 +2256,28 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

Architecture

-

Changemaker Lite uses a dual-API architecture with a shared PostgreSQL database.

-
-

Under Construction

-

Detailed architecture documentation is being written. Check back soon.

-
-

System Overview

-
Browser ──► Nginx (reverse proxy) ──┬──► Express API (port 4000) ──► PostgreSQL
-                                    ├──► Fastify Media API (port 4100) ──┘
-                                    ├──► React Admin GUI (port 3000)
-                                    └──► MkDocs / Other Services
-
+

Changemaker Lite uses a dual-API architecture with a shared PostgreSQL database, a React single-page application, and Nginx for subdomain routing across 30+ services.

+
+

System Diagram

+
graph LR
+    Browser["Browser"] --> Nginx["Nginx<br/>(reverse proxy)"]
+    Nginx --> Admin["React Admin GUI<br/>port 3000"]
+    Nginx --> API["Express API<br/>port 4000"]
+    Nginx --> MediaAPI["Fastify Media API<br/>port 4100"]
+    Nginx --> MkDocs["MkDocs<br/>port 4003/4004"]
+    Nginx --> Services["Other Services<br/>(Gitea, NocoDB, etc.)"]
+
+    API --> PostgreSQL[("PostgreSQL 16<br/>30+ tables")]
+    MediaAPI --> PostgreSQL
+    API --> Redis[("Redis<br/>cache + queues")]
+    API --> BullMQ["BullMQ<br/>(email, video jobs)"]
+    BullMQ --> Redis
+
+    subgraph Tunnel ["Public Access"]
+        Newt["Newt Client"] --> Pangolin["Pangolin Server"]
+    end
+    Newt --> Nginx
+

Key Components

@@ -2179,44 +2289,246 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - - - + + + - - - + + + - - - + + + - + - + - - - + + + - + - + + + + + + + + + + +
Main APIExpress.js + PrismaAuth, campaigns, map, shifts, pagesMain APIExpress.js + TypeScript + PrismaAuth, campaigns, map, shifts, pages, canvassing, email
Media APIFastify + PrismaVideo library, analytics, uploadsMedia APIFastify + TypeScript + PrismaVideo library, analytics, uploads, scheduling
Admin GUIReact + Ant DesignSingle-page admin applicationAdmin GUIReact 19 + Vite + Ant Design + ZustandAdmin dashboard, public pages, volunteer portal, media gallery
DatabaseDatabase PostgreSQL 16Shared by both APIs (30+ tables)Shared by both APIs (30+ models via Prisma)
CacheRedisRate limiting, job queues, geocodingCacheRedis 7Rate limiting, BullMQ job queues, geocoding cache
ProxyProxy NginxSubdomain routing, security headersSubdomain routing, security headers, WebSocket upgrade
TunnelPangolin + NewtExpose services without port forwarding
MonitoringPrometheus + Grafana + AlertmanagerMetrics collection, dashboards, alerting
-

Authentication Flow

+
+

Dual API Design

+

The platform runs two independent API servers sharing one PostgreSQL database:

+
+
+
+

The main API handles all core platform logic:

    -
  • JWT access tokens (15 min) + refresh tokens (7 days)
  • -
  • Refresh token rotation with atomic database transaction
  • -
  • Role-based access control (5 roles)
  • -
  • Rate limiting on auth endpoints (10/min per IP)
  • +
  • Authentication — JWT access/refresh tokens, RBAC middleware
  • +
  • Modules — Influence (campaigns, responses), Map (locations, cuts, shifts, canvassing), Pages, Email Templates, Settings, Users, Payments, Social, Calendar
  • +
  • Services — Email queue (BullMQ), geocoding queue, Listmonk sync, Pangolin client, user provisioning
  • +
  • ORM — Prisma with 30+ models and migration history
+
+
+

A separate server optimized for media handling:

+
    +
  • Video CRUD — Upload with FFprobe metadata extraction
  • +
  • Scheduled Publishing — BullMQ queue with timezone support
  • +
  • Analytics — View tracking, watch time, completion rates (GDPR-compliant)
  • +
  • Public Gallery — Playlists, reactions, comments, SSE chat
  • +
  • ORM — Prisma (migrated from Drizzle, Feb 2026)
  • +
+
+
+
+

Both servers connect to the same database and share the same Prisma schema. This separation allows the media API to handle large file uploads and streaming independently from the main API's request/response cycle.

+
+

Authentication Flow

+
sequenceDiagram
+    participant Client
+    participant API
+    participant DB
+    participant Redis
+
+    Client->>API: POST /api/auth/login {email, password}
+    API->>Redis: Check rate limit (10/min per IP)
+    Redis-->>API: OK
+    API->>DB: Verify bcrypt password
+    DB-->>API: User record
+    API->>DB: Create refresh token
+    API-->>Client: {accessToken (15min), refreshToken (7d)}
+
+    Note over Client: Authenticated requests
+    Client->>API: GET /api/campaigns<br/>Authorization: Bearer <accessToken>
+    API->>API: Verify JWT + check role (RBAC)
+    API-->>Client: 200 OK
+
+    Note over Client: Token expired
+    Client->>API: POST /api/auth/refresh {refreshToken}
+    API->>DB: Atomic rotation (delete old, create new)
+    API-->>Client: {new accessToken, new refreshToken}
+

Security Features

+ +
+

Request Lifecycle

+
graph TD
+    A["Incoming Request"] --> B["Nginx"]
+    B -->|"Host: api.domain"| C["Express API"]
+    B -->|"Host: media.domain"| D["Fastify Media API"]
+    B -->|"Host: app.domain"| E["React Admin GUI"]
+    C --> F["Rate Limiter (Redis)"]
+    F --> G["Auth Middleware (JWT)"]
+    G --> H["Role Check (RBAC)"]
+    H --> I["Validation (Zod)"]
+    I --> J["Route Handler"]
+    J --> K["Service Layer"]
+    K --> L["Prisma ORM"]
+    L --> M[("PostgreSQL")]
+    J --> N["Response + Metrics"]
+
+

Database Schema

+

The database contains 30+ Prisma models organized by module:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ModuleKey Models
AuthUser, RefreshToken
InfluenceCampaign, CampaignEmail, CampaignResponse, Representative, PostalCode
MapLocation, Address, Cut, Shift, ShiftSignup
CanvassCanvassSession, CanvassVisit, TrackingSession, TrackingPoint
PagesPage, PageBlock, EmailTemplate
MediaVideo, VideoReaction, VideoComment, VideoView, Playlist, PlaylistVideo
PaymentsStripeProduct, StripePrice, StripeDonationPage, StripeOrder
SocialFriendship, SocialNotification, CalendarLayer, CalendarItem
SMSSmsContactList, SmsCampaign, SmsMessage, SmsConversation
PeopleContact, ContactAddress, ContactEmail, ContactPhone, ContactConnection
SettingsSiteSettings, MapSettings
+
+

Docker Compose Architecture

+

Services are organized into categories with dependency management:

+
graph TD
+    subgraph Core ["Core (always started)"]
+        PG["PostgreSQL"] --> API["Express API"]
+        Redis --> API
+        PG --> Media["Fastify Media API"]
+        API --> Admin["React Admin"]
+        Admin --> Nginx
+        API --> Nginx
+        Media --> Nginx
+    end
+
+    subgraph Communication ["Communication (optional)"]
+        RC["Rocket.Chat"] --> MongoDB
+        Jitsi["Jitsi Meet (4 containers)"]
+        Gancio["Gancio Events"]
+    end
+
+    subgraph Monitoring ["Monitoring (profile)"]
+        Prometheus --> Grafana
+        Prometheus --> Alertmanager
+        cAdvisor --> Prometheus
+        NodeExporter --> Prometheus
+    end
+
+    subgraph Tunnel ["Tunnel"]
+        Newt --> Nginx
+    end
+

Docker healthchecks ensure proper startup order: PostgreSQL and Redis must be healthy before the API starts. The API runs migrations and seeding automatically via its entrypoint script.

+
+

Subdomain Routing

+

Nginx routes requests based on the Host header. All services run on the changemaker-lite Docker bridge network.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PatternTarget
app.DOMAINAdmin GUI (admin + public + volunteer + gallery)
api.DOMAINExpress API
media.DOMAINFastify Media API
DOMAIN (root)MkDocs static site
*.DOMAIN15+ additional service subdomains
+

See Services for the complete subdomain table.

@@ -2239,6 +2551,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2297,7 +2611,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/deployment/index.html b/mkdocs/site/docs/deployment/index.html index caabdeb6..ca53d446 100644 --- a/mkdocs/site/docs/deployment/index.html +++ b/mkdocs/site/docs/deployment/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1952,6 +1952,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2616,9 +2618,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2627,7 +2661,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3325,6 +3359,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3383,7 +3419,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/getting-started/control-panel/index.html b/mkdocs/site/docs/getting-started/control-panel/index.html index 5ca640b2..a065324c 100644 --- a/mkdocs/site/docs/getting-started/control-panel/index.html +++ b/mkdocs/site/docs/getting-started/control-panel/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1573,6 +1573,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1593,6 +1601,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2511,6 +2527,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2957,9 +2975,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2968,7 +3011,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3401,6 +3444,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3459,7 +3504,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/getting-started/environment-variables/index.html b/mkdocs/site/docs/getting-started/environment-variables/index.html index fae8fabb..c783074d 100644 --- a/mkdocs/site/docs/getting-started/environment-variables/index.html +++ b/mkdocs/site/docs/getting-started/environment-variables/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -2022,6 +2022,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2625,6 +2633,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -3185,9 +3195,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -3196,7 +3238,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -4847,6 +4889,8 @@ Then restart the API: docker compose restart api

+ + @@ -4905,7 +4949,7 @@ Then restart the API: docker compose restart api

+
+ + + + - + diff --git a/mkdocs/site/docs/getting-started/features/index.html b/mkdocs/site/docs/getting-started/features/index.html index 7b8d24bd..195628cc 100644 --- a/mkdocs/site/docs/getting-started/features/index.html +++ b/mkdocs/site/docs/getting-started/features/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1564,6 +1564,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2284,6 +2292,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2503,9 +2513,27 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2514,7 +2542,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2755,6 +2783,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2813,7 +2843,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/getting-started/first-steps/index.html b/mkdocs/site/docs/getting-started/first-steps/index.html index 8bd71efd..6ff947cc 100644 --- a/mkdocs/site/docs/getting-started/first-steps/index.html +++ b/mkdocs/site/docs/getting-started/first-steps/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1703,6 +1703,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2306,6 +2314,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2547,9 +2557,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2558,7 +2593,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2652,6 +2687,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2710,7 +2747,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
+ + + + - + diff --git a/mkdocs/site/docs/getting-started/index.html b/mkdocs/site/docs/getting-started/index.html index 68429401..b1b21ecb 100644 --- a/mkdocs/site/docs/getting-started/index.html +++ b/mkdocs/site/docs/getting-started/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1564,6 +1564,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2167,6 +2175,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2251,10 +2261,21 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
  • - + - Quick Start + Quick Install (Pre-built Images) + + + + +
  • + +
  • + + + + Quick Start (From Source) @@ -2375,9 +2396,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2386,7 +2432,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2404,14 +2450,20 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
  • At least 2 GB RAM and 10 GB disk space
  • A domain name (optional, but recommended for production)
  • -

    Quick Start

    -
    git clone https://gitea.bnkops.com/admin/changemaker.lite
    -cd changemaker.lite
    -git checkout v2
    +

    Quick Install (Pre-built Images)

    +

    The fastest way to deploy — no source code, no compilation:

    +
    curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/v2/scripts/install.sh | bash
     
    -
    bash config.sh
    +

    This downloads a lightweight release package (~2 MB), runs the configuration wizard, and pulls pre-built Docker images. First startup takes ~2 minutes. See Installation for details.

    +

    Quick Start (From Source)

    +

    For development or customization, clone the full repository:

    +
    git clone https://gitea.bnkops.com/admin/changemaker.lite
    +cd changemaker.lite
    +git checkout v2
     
    -
    docker compose up -d
    +
    bash config.sh
    +
    +
    docker compose up -d
     

    Open http://localhost:3000 and sign in with the admin email and password you configured. The API container automatically runs database migrations and seeding on first startup — no manual steps needed.

    @@ -2576,6 +2628,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
    + +
    @@ -2634,7 +2688,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/getting-started/installation/index.html b/mkdocs/site/docs/getting-started/installation/index.html index bc0f38e3..6747065e 100644 --- a/mkdocs/site/docs/getting-started/installation/index.html +++ b/mkdocs/site/docs/getting-started/installation/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1483,6 +1483,56 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
    + + +
  • + + + + Pre-built Image Installation + + + + + +
  • @@ -1891,6 +1941,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + +
  • @@ -2494,6 +2552,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2586,6 +2646,56 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + +
  • + + + + Pre-built Image Installation + + + + + +
  • @@ -2923,9 +3033,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2934,7 +3076,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2971,6 +3113,71 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

    If you used the wizard's generated password, change it immediately from the admin dashboard.


  • +

    Pre-built Image Installation

    +

    For production deployments, you can skip cloning the source repository entirely. Pre-built Docker images are pulled from the Gitea container registry.

    +

    One-Line Install

    +
    curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/v2/scripts/install.sh | bash
    +
    +

    This script:

    +
      +
    1. Checks prerequisites (Docker, Docker Compose, OpenSSL)
    2. +
    3. Downloads the latest release package from Gitea
    4. +
    5. Extracts to ~/changemaker.lite/
    6. +
    7. Launches the configuration wizard (config.sh)
    8. +
    +

    After the wizard completes, start everything with docker compose up -d.

    +

    Manual Download

    +

    If you prefer not to pipe to bash:

    +
    # Download latest release
    +curl -LO https://gitea.bnkops.com/admin/changemaker.lite/releases/latest/download/changemaker-lite-latest.tar.gz
    +tar xzf changemaker-lite-latest.tar.gz
    +cd changemaker-lite
    +bash config.sh
    +docker compose up -d
    +
    +

    What's Different from Source Install

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Source InstallPre-built Install
    Download size~200 MB (full repo)~2 MB (config + scripts)
    First startup10+ min (TypeScript compile + Docker build)~2 min (image pull only)
    RequiresGit, full repoDocker only
    Upgradesgit pull + rebuildDownload new release tarball
    DevelopmentEdit source, hot-reloadNot for development
    +
    +

    When to use which

    +

    Use pre-built install for production deployments and quick evaluation. +Use source install when you want to modify the platform code or contribute to development.

    +
    +

    Configuration Wizard (config.sh)

    The wizard performs 14 steps to produce a fully configured .env file and prepare the system for startup. Each step is interactive with sensible defaults.

    Step 1: Prerequisites Check

    @@ -3071,8 +3278,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { JWT & Encryption -3 -JWT_ACCESS_SECRET, JWT_REFRESH_SECRET, ENCRYPTION_KEY (64-char hex) +4 +JWT_ACCESS_SECRET, JWT_REFRESH_SECRET, JWT_INVITE_SECRET (each 64-char hex), ENCRYPTION_KEY (64-char hex, must differ from JWT secrets) Database @@ -3200,7 +3407,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

    Complete tunnel setup is done from the admin GUI at Settings > Tunnel after services are running.

    Step 9: CORS Origins

    Automatically calculates allowed origins from your domain:

    -
    http://app.DOMAIN,https://app.DOMAIN,http://DOMAIN,https://DOMAIN,http://localhost:3000,http://localhost,http://localhost:4003
    +
    http://app.DOMAIN,https://app.DOMAIN,http://DOMAIN,https://DOMAIN,http://localhost:3000,http://localhost,http://localhost:4003
     

    Step 10: Nginx Config Generation

    Renders all .conf.template files in nginx/conf.d/ by substituting ${DOMAIN} with your configured domain. This produces the nginx configuration files that handle subdomain routing.

    @@ -3315,19 +3522,20 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

    Manual Setup (Alternative)

    If you prefer to configure by hand instead of using the wizard:

    -
    cp .env.example .env
    +
    cp .env.example .env
     

    At minimum, set these required secrets:

    -
    # Generate cryptographic secrets
    -V2_POSTGRES_PASSWORD=$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | head -c 24)
    -REDIS_PASSWORD=$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | head -c 24)
    -JWT_ACCESS_SECRET=$(openssl rand -hex 32)
    -JWT_REFRESH_SECRET=$(openssl rand -hex 32)
    -ENCRYPTION_KEY=$(openssl rand -hex 32)
    +
    # Generate cryptographic secrets
    +V2_POSTGRES_PASSWORD=$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | head -c 24)
    +REDIS_PASSWORD=$(openssl rand -base64 48 | tr -dc 'a-zA-Z0-9' | head -c 24)
    +JWT_ACCESS_SECRET=$(openssl rand -hex 32)
    +JWT_REFRESH_SECRET=$(openssl rand -hex 32)
    +JWT_INVITE_SECRET=$(openssl rand -hex 32)
    +ENCRYPTION_KEY=$(openssl rand -hex 32)   # must differ from all JWT secrets
     

    Set your admin credentials (password must meet the 12+ char complexity requirement):

    -
    INITIAL_ADMIN_EMAIL=admin@yourdomain.org
    -INITIAL_ADMIN_PASSWORD=YourStrongPassword1
    +
    INITIAL_ADMIN_EMAIL=admin@yourdomain.org
    +INITIAL_ADMIN_PASSWORD=YourStrongPassword1
     

    Then configure optional sections:

      @@ -3340,7 +3548,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

      Full Stack Startup

      After configuration, start the entire platform:

      -
      docker compose up -d
      +
      docker compose up -d
       

      That's it. Docker handles the startup order automatically:

        @@ -3351,40 +3559,40 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
      1. Init containers (nocodb-init, listmonk-init, etc.) run once and exit

      Watch the startup progress:

      -
      docker compose logs -f api --tail 20
      +
      docker compose logs -f api --tail 20
       

      Once you see Starting server on port 4000, open http://localhost:3000 and log in.

      Include Monitoring

      The monitoring stack (Prometheus, Grafana, Alertmanager) uses a Docker Compose profile and isn't included by default:

      -
      docker compose --profile monitoring up -d
      +
      docker compose --profile monitoring up -d
       

      Start Only Core Services

      If you prefer a minimal startup (lower resource usage):

      -
      docker compose up -d v2-postgres redis api admin nginx
      +
      docker compose up -d v2-postgres redis api admin nginx
       

      Manual migrations

      The API container runs migrations and seeding automatically on startup via its entrypoint script. You only need to run them manually if you're developing locally without Docker:

      -
      cd api && npx prisma migrate deploy && npx prisma db seed
      +
      cd api && npx prisma migrate deploy && npx prisma db seed
       

      See Services Overview for the complete service catalog.


      Verifying Installation

      After starting services, verify everything is healthy:

      -
      # Check running containers
      -docker compose ps
      -
      -# API health check
      -curl -s http://localhost:4000/api/health | python3 -m json.tool
      -
      -# View API logs
      -docker compose logs api --tail 20
      -
      -# Check for containers in restart loops
      -docker compose ps | grep -i restarting
      +
      # Check running containers
      +docker compose ps
      +
      +# API health check
      +curl -s http://localhost:4000/api/health | python3 -m json.tool
      +
      +# View API logs
      +docker compose logs api --tail 20
      +
      +# Check for containers in restart loops
      +docker compose ps | grep -i restarting
       

      You should see the API return {"status":"ok"} and all started containers in a "running" state.


      @@ -3417,6 +3625,8 @@ locally without Docker:

      + +
      @@ -3475,7 +3685,7 @@ locally without Docker:

      +
      + + + + - + diff --git a/mkdocs/site/docs/getting-started/services/index.html b/mkdocs/site/docs/getting-started/services/index.html index 6a95fd23..7ed429b5 100644 --- a/mkdocs/site/docs/getting-started/services/index.html +++ b/mkdocs/site/docs/getting-started/services/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1786,6 +1786,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
      + + + + + + + + @@ -2389,6 +2397,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2713,9 +2723,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2724,7 +2766,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -3332,6 +3374,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
      + +
      @@ -3390,7 +3434,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
      + + + + - + diff --git a/mkdocs/site/docs/getting-started/upgrades/index.html b/mkdocs/site/docs/getting-started/upgrades/index.html index d85bbb3c..fa291a87 100644 --- a/mkdocs/site/docs/getting-started/upgrades/index.html +++ b/mkdocs/site/docs/getting-started/upgrades/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1709,6 +1709,45 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
    + + +
  • + + + + Registry Mode (Fast Upgrades) + + + + + +
  • @@ -1876,6 +1915,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + +
  • @@ -2479,6 +2526,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2677,6 +2726,45 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + +
  • + + + + Registry Mode (Fast Upgrades) + + + + + +
  • @@ -2893,9 +2981,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2904,7 +3017,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2963,6 +3076,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
  • Optionally configure:
    • Skip backup — skip the database backup phase (not recommended)
    • Pull images — also update third-party Docker images (PostgreSQL, Redis, etc.)
    • +
    • Use registry images — pull pre-built images from Gitea instead of compiling from source (faster — requires scripts/build-and-push.sh to have been run first)
    • Dry run — preview what would happen without making changes
  • @@ -3004,7 +3118,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { 4 50% Container Rebuild -Rebuilds api, admin, media-api; conditionally rebuilds nginx and code-server if their configs changed; optionally pulls third-party images +Rebuilds api, admin, media-api from source (default) or pulls pre-built images from the Gitea registry (--use-registry); conditionally rebuilds nginx and code-server if their configs changed; optionally pulls third-party images 5 @@ -3081,6 +3195,10 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { Also pull new third-party Docker images +--use-registry +Pull pre-built images from Gitea instead of compiling from source + + --dry-run Show what would happen without executing @@ -3112,14 +3230,52 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
    # Full upgrade including third-party image updates ./scripts/upgrade.sh --pull-services -# Rollback to the last pre-upgrade state -./scripts/upgrade.sh --rollback +# Upgrade using pre-built images from Gitea registry (faster, no TypeScript compile) +./scripts/upgrade.sh --use-registry --force --skip-backup + +# Rollback to the last pre-upgrade state +./scripts/upgrade.sh --rollback

    +

    Registry Mode (Fast Upgrades)

    +

    By default, the upgrade script compiles TypeScript from source (npm run build) and rebuilds Docker images on the deployment server. Registry mode skips this by pulling pre-built production images from the Gitea container registry — faster and requires no build tooling on the server.

    +

    How It Works

    +
      +
    1. Run scripts/build-and-push.sh on a machine with Docker (usually your dev machine) to build and push production images tagged with the current commit SHA
    2. +
    3. During the next upgrade, pass --use-registry (CLI) or enable the checkbox (GUI)
    4. +
    5. The upgrade script pulls gitea.bnkops.com/admin/changemaker-{service}:{sha} instead of rebuilding from source
    6. +
    7. If a registry image is unavailable (e.g., the SHA wasn't pushed), it automatically falls back to a source build
    8. +
    +

    Building and Pushing Images

    +
    # Build and push all core services (api, admin, media-api, nginx)
    +./scripts/build-and-push.sh
    +
    +# Skip code-server (9 GB — push only when Dockerfile changes)
    +./scripts/build-and-push.sh --services api,admin,media-api,nginx
    +
    +# Build only, no push (verify locally first)
    +./scripts/build-and-push.sh --no-push
    +
    +# Also mirror third-party images (postgres, redis, etc.) to Gitea
    +./scripts/mirror-images.sh
    +
    +
    +

    Registry prerequisites

    +
      +
    • Run docker login gitea.bnkops.com once per machine before pushing
    • +
    • Set GITEA_REGISTRY_USER and GITEA_REGISTRY_PASS in .env for the admin GUI's Registry status endpoint
    • +
    • gitea.bnkops.com must be reachable without proxies that limit upload size (Cloudflare free plan blocks blobs >100 MB)
    • +
    +
    +
    +

    Release installs upgrade automatically via registry

    +

    If you installed from a release tarball (not git clone), the upgrade script automatically uses registry mode. It downloads the latest release package from Gitea instead of running git pull. No additional configuration needed.

    +
    +

    Rollback

    Automatic Rollback

    If the upgrade fails at any phase, the script prints detailed rollback instructions including the pre-upgrade commit hash. Use the --rollback flag:

    -
    ./scripts/upgrade.sh --rollback
    +
    ./scripts/upgrade.sh --rollback
     

    This:

      @@ -3133,19 +3289,19 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

      --rollback restores the code to the pre-upgrade state but does not automatically restore the database. If database migrations were applied during the failed upgrade, you may need to manually restore from the backup archive.

    Manual Rollback

    -
    # 1. Restore code
    -cd /path/to/changemaker.lite
    -git checkout <pre-upgrade-commit-hash>
    -
    -# 2. Rebuild and restart
    -docker compose build api admin media-api
    -docker compose up -d
    -
    -# 3. Database restore (if needed — destructive!)
    -ls -lt backups/changemaker-v2-backup-*.tar.gz | head -5
    -tar xzf backups/<backup>.tar.gz -C /tmp
    -gunzip -c /tmp/<backup>/v2-postgres.sql.gz | \
    -  docker exec -i changemaker-v2-postgres psql -U changemaker -d changemaker_v2
    +
    # 1. Restore code
    +cd /path/to/changemaker.lite
    +git checkout <pre-upgrade-commit-hash>
    +
    +# 2. Rebuild and restart
    +docker compose build api admin media-api
    +docker compose up -d
    +
    +# 3. Database restore (if needed — destructive!)
    +ls -lt backups/changemaker-v2-backup-*.tar.gz | head -5
    +tar xzf backups/<backup>.tar.gz -C /tmp
    +gunzip -c /tmp/<backup>/v2-postgres.sql.gz | \
    +  docker exec -i changemaker-v2-postgres psql -U changemaker -d changemaker_v2
     

    New Environment Variables

    @@ -3155,15 +3311,15 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
  • Appends any missing variables with their default values
  • Warns you to review the new additions
  • -
    [WARN] New env vars added to .env (review defaults):
    -    NEW_FEATURE_FLAG
    -    NEW_API_KEY
    +
    [WARN] New env vars added to .env (review defaults):
    +    NEW_FEATURE_FLAG
    +    NEW_API_KEY
     

    Always review new variables after an upgrade — some may need manual configuration.


    Update Checker

    A separate lightweight script checks for available updates without performing any changes:

    -
    ./scripts/upgrade-check.sh
    +
    ./scripts/upgrade-check.sh
     

    This writes data/upgrade/status.json with:

      @@ -3178,39 +3334,39 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

      Stale Progress Indicator

      If the GUI shows an upgrade "in progress" but nothing is happening, the upgrade script may have crashed. The system automatically detects stale progress (no update for 10+ minutes) and treats it as not running.

      To manually clear:

      -
      rm -f data/upgrade/progress.json
      +
      rm -f data/upgrade/progress.json
       

      Merge Conflicts

      If git pull encounters merge conflicts in user-modifiable paths (docs, configs), the upgrade script auto-resolves by keeping your version. If conflicts occur in project-owned files (api/, admin/), the upgrade fails and asks you to resolve manually.

      Lock File

      The upgrade script uses .upgrade.lock to prevent concurrent upgrades. If a previous upgrade crashed without cleaning up:

      -
      # Verify no upgrade is actually running
      -ps aux | grep upgrade.sh
      -
      -# Remove stale lock
      -rm -f .upgrade.lock
      +
      # Verify no upgrade is actually running
      +ps aux | grep upgrade.sh
      +
      +# Remove stale lock
      +rm -f .upgrade.lock
       

      Health Check Failures

      If Phase 6 health checks fail, services may still be starting. Wait 1-2 minutes and check manually:

      -
      # API health
      -curl -s http://localhost:4000/api/health
      -
      -# Container status
      -docker compose ps
      -
      -# Recent logs
      -docker compose logs api --tail 50
      -docker compose logs admin --tail 50
      +
      # API health
      +curl -s http://localhost:4000/api/health
      +
      +# Container status
      +docker compose ps
      +
      +# Recent logs
      +docker compose logs api --tail 50
      +docker compose logs admin --tail 50
       

      Systemd Watcher Not Triggering

      -
      # Check watcher status
      -sudo systemctl status changemaker-upgrade.path
      -
      -# Check service logs
      -sudo journalctl -u changemaker-upgrade.service --tail 20
      -
      -# Re-enable if stopped
      -sudo systemctl enable --now changemaker-upgrade.path
      +
      # Check watcher status
      +sudo systemctl status changemaker-upgrade.path
      +
      +# Check service logs
      +sudo journalctl -u changemaker-upgrade.service --tail 20
      +
      +# Re-enable if stopped
      +sudo systemctl enable --now changemaker-upgrade.path
       
      @@ -3234,6 +3390,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
      + +
      @@ -3292,7 +3450,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
      + + + + - + diff --git a/mkdocs/site/docs/index.html b/mkdocs/site/docs/index.html index 851dc223..e392ef9e 100644 --- a/mkdocs/site/docs/index.html +++ b/mkdocs/site/docs/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1936,6 +1936,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2115,9 +2117,27 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2126,7 +2146,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2190,7 +2210,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

      Monitoring


      Prometheus metrics, Grafana dashboards, Alertmanager rules, and health checks.

      -

      Monitoring Coming soon

      +

      Monitoring

    @@ -2219,7 +2239,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

    Contributing


    Development setup, code style, git workflow, and pull request guidelines.

    -

    Contributing Coming soon

    +

    Contributing

    @@ -2306,6 +2326,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
    + +
    @@ -2364,7 +2386,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/phil/index.html b/mkdocs/site/docs/phil/index.html index 2241a281..4d5479a5 100644 --- a/mkdocs/site/docs/phil/index.html +++ b/mkdocs/site/docs/phil/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -2073,6 +2073,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2296,9 +2298,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2307,7 +2334,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2444,6 +2471,8 @@ Self-hosted doesn't have to mean self-excluding. Changemaker Lite is designed fo
    + +
    @@ -2502,7 +2531,7 @@ Self-hosted doesn't have to mean self-excluding. Changemaker Lite is designed fo +
    + + + + - + diff --git a/mkdocs/site/docs/services/index.html b/mkdocs/site/docs/services/index.html index 1cdf19fb..90ed70f1 100644 --- a/mkdocs/site/docs/services/index.html +++ b/mkdocs/site/docs/services/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1952,6 +1952,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2204,9 +2206,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2215,7 +2249,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2696,6 +2730,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
    + + @@ -2754,7 +2790,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/troubleshooting/index.html b/mkdocs/site/docs/troubleshooting/index.html index 32c93b9c..03ccb446 100644 --- a/mkdocs/site/docs/troubleshooting/index.html +++ b/mkdocs/site/docs/troubleshooting/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1952,6 +1952,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2039,7 +2041,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - Pangolin Tunnel 403/302 Errors + Pangolin Tunnel — 403/302 Errors @@ -2077,6 +2079,105 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + +
  • + + + + Containers in Restart Loops + + + + +
  • + +
  • + + + + Newt Tunnel Won't Connect + + + + +
  • + +
  • + + + + Migration Errors + + + + +
  • + +
  • + + + + Media API Upload Failures + + + + +
  • + +
  • + + + + Email Not Sending + + + + +
  • + +
  • + + + + Services Unreachable via Tunnel + + + + +
  • + +
  • + + + + Slow Map Performance + + + + +
  • + +
  • + + + + Docker Disk Space + + + + +
  • + +
  • + + + + Getting Help + + + +
  • @@ -2160,9 +2261,27 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2171,7 +2290,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2180,36 +2299,166 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {

    Troubleshooting

    Common issues and their solutions when running Changemaker Lite.

    -
    -

    Under Construction

    -

    This troubleshooting guide is being expanded. Check back soon for more solutions.

    -
    +

    CORS Errors in Production

    Symptom: Browser console shows CORS errors when accessing production domain.

    Fix: Add your production domain to CORS_ORIGINS in .env:

    CORS_ORIGINS=https://app.yourdomain.org,http://localhost:3000
     

    Then restart the API: docker compose restart api

    -

    Pangolin Tunnel 403/302 Errors

    -

    Symptom: All API endpoints return 302 redirects to Pangolin auth page.

    -

    Fix: In the Pangolin dashboard, set each resource to "Not Protected" (public access).

    +
    +

    Pangolin Tunnel — 403/302 Errors

    +

    Symptom: All API endpoints return 302 redirects to Pangolin auth page, or 403 Forbidden.

    +

    Fix: In the Pangolin dashboard, set each resource to Not Protected (public access). Critical resources to fix first:

    +
      +
    1. api.yourdomain.org — Main API
    2. +
    3. app.yourdomain.org — Admin GUI + public pages
    4. +
    5. media.yourdomain.org — Media API
    6. +
    +

    Verify:

    +
    # Should return JSON, NOT a 302 redirect
    +curl -I https://api.yourdomain.org/api/health
    +
    +

    Database Connection Failures

    +

    Symptom: API logs show database connection errors.

    +

    Checklist:

    1. Check PostgreSQL: docker compose ps v2-postgres
    2. -
    3. Verify DATABASE_URL in .env
    4. +
    5. Verify DATABASE_URL in .env matches container name and port
    6. View logs: docker compose logs v2-postgres --tail 50
    7. +
    8. Test connection: docker compose exec api npx prisma db execute --stdin <<< "SELECT 1"
    +

    Redis Connection Failures

    +

    Symptom: API logs show Redis connection errors, rate limiting doesn't work.

    +

    Checklist:

    1. Check Redis: docker compose ps redis-changemaker
    2. -
    3. Verify REDIS_PASSWORD and REDIS_URL format in .env
    4. +
    5. Verify REDIS_PASSWORD and REDIS_URL format (redis://:password@host:port)
    6. +
    7. View logs: docker compose logs redis-changemaker --tail 50
    8. Test: docker compose exec redis-changemaker redis-cli -a $REDIS_PASSWORD ping
    +

    API Not Starting

    +

    Symptom: API container keeps restarting or won't start.

    +

    Checklist:

    1. Check logs: docker compose logs api --tail 100
    2. -
    3. Verify all required env vars are set (see .env.example)
    4. -
    5. Run migrations: docker compose exec api npx prisma migrate deploy
    6. +
    7. Verify all required env vars are set (compare with .env.example)
    8. +
    9. Check database is ready: docker compose ps v2-postgres (should show "healthy")
    10. +
    11. Run migrations manually: docker compose exec api npx prisma migrate deploy
    12. +
    13. Check for port conflicts: ss -tlnp | grep 4000
    14. +
    +
    +

    Containers in Restart Loops

    +

    Symptom: docker compose ps shows containers with "restarting" status.

    +

    Diagnosis:

    +
    # Find restarting containers
    +docker compose ps | grep -i restarting
    +
    +# Check recent logs for the problem container
    +docker compose logs <service-name> --tail 50
    +
    +# Check container exit code
    +docker inspect <container-name> --format='{{.State.ExitCode}}'
    +
    +

    Common causes:

    +
      +
    • Missing environment variables (check .env)
    • +
    • Database not ready (healthcheck dependencies)
    • +
    • Port already in use by another process
    • +
    • Insufficient memory (check with free -h)
    • +
    +
    +

    Newt Tunnel Won't Connect

    +

    Checklist (in order):

    +
      +
    1. Credentials: Verify PANGOLIN_NEWT_ID and PANGOLIN_NEWT_SECRET in .env
    2. +
    3. Endpoint: Confirm PANGOLIN_ENDPOINT matches your Pangolin server URL
    4. +
    5. Logs: docker compose logs newt --tail 50
    6. +
    7. Nginx running: Newt depends on nginx — docker compose ps nginx
    8. +
    9. Network: Ensure outbound HTTPS is not blocked by your firewall
    10. +
    +
    +

    Migration Errors

    +

    Symptom: prisma migrate deploy fails.

    +

    Common fixes:

    +
    # Check migration status
    +docker compose exec api npx prisma migrate status
    +
    +# If migrations are out of sync, reset (DESTRUCTIVE — dev only)
    +docker compose exec api npx prisma migrate reset
    +
    +# If shadow database errors, create one
    +docker compose exec -T v2-postgres createdb -U changemaker prisma_shadow_diff
    +
    +
    +

    Never use prisma db push in production

    +

    Always use prisma migrate dev (development) or prisma migrate deploy (production) to keep migration history in sync.

    +
    +
    +

    Media API Upload Failures

    +

    Symptom: Video uploads fail with permission errors or 500 status.

    +

    Checklist:

    +
      +
    1. Verify inbox volume is writable: check media/local/inbox has :rw mount
    2. +
    3. Check disk space: df -h
    4. +
    5. Verify FFmpeg is installed in container: docker compose exec media-api ffprobe -version
    6. +
    7. Check upload size limit: default is 10 GB in Fastify multipart config
    8. +
    +
    +

    Email Not Sending

    +

    Symptom: Advocacy emails or notifications aren't delivered.

    +

    Checklist:

    +
      +
    1. Check EMAIL_TEST_MODE — if true, all emails go to MailHog (http://localhost:8025)
    2. +
    3. Verify SMTP credentials in .env (SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS)
    4. +
    5. Check BullMQ queue: visit Admin > Email Queue or check logs
    6. +
    7. Test SMTP from Settings: Admin > Settings > Email > Test Connection
    8. +
    +
    +

    Services Unreachable via Tunnel

    +

    Checklist:

    +
      +
    1. Verify nginx is running: docker compose ps nginx
    2. +
    3. Test locally first: curl http://localhost:4000/api/health
    4. +
    5. Check nginx logs: docker compose logs nginx --tail 50
    6. +
    7. Verify DNS: dig app.yourdomain.org should point to your Pangolin server
    8. +
    9. Check Pangolin resources are all set to "Not Protected"
    10. +
    +
    +

    Slow Map Performance

    +

    Symptom: Map page is slow or returns 500 errors with many locations.

    +

    Causes and fixes:

    +
      +
    • Too many locations loaded at once — the API limits by address count with debounced bounds queries
    • +
    • Missing indexes — verify database has the 5 performance indexes on Location/Address tables
    • +
    • Browser memory — marker clustering activates above zoom level 18; below that, addresses are grouped
    • +
    +
    +

    Docker Disk Space

    +

    Symptom: Builds fail, containers can't start, or images won't pull.

    +
    # Check disk usage
    +df -h
    +
    +# Clean unused Docker resources
    +docker system prune -f
    +
    +# Clean old images (keep only last 2 days)
    +docker image prune -a --filter "until=48h"
    +
    +# Check what's using space
    +docker system df
    +
    +
    +

    Getting Help

    +

    If your issue isn't listed here:

    +
      +
    1. Check the API logs: docker compose logs api --tail 200
    2. +
    3. Search the Gitea issues
    4. +
    5. Review the Deployment guide for production-specific issues
    6. +
    7. File a new issue with your logs and .env (redact passwords)
    @@ -2233,6 +2482,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2291,7 +2542,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/campaigns/index.html b/mkdocs/site/docs/user-guide/campaigns/index.html index 5fd24c6c..86ef886f 100644 --- a/mkdocs/site/docs/user-guide/campaigns/index.html +++ b/mkdocs/site/docs/user-guide/campaigns/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1811,6 +1811,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1841,6 +1849,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1871,6 +1887,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2292,6 +2316,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2489,9 +2515,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2500,7 +2558,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2555,6 +2613,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2613,7 +2673,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/donations/index.html b/mkdocs/site/docs/user-guide/donations/index.html index 0b17ba4b..acaa0d88 100644 --- a/mkdocs/site/docs/user-guide/donations/index.html +++ b/mkdocs/site/docs/user-guide/donations/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1716,6 +1716,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1755,6 +1763,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1775,6 +1791,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1860,6 +1884,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2281,6 +2313,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2467,9 +2501,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2478,7 +2537,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2533,6 +2592,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2591,7 +2652,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/events/index.html b/mkdocs/site/docs/user-guide/events/index.html index b1ec95f2..bf4fa2ac 100644 --- a/mkdocs/site/docs/user-guide/events/index.html +++ b/mkdocs/site/docs/user-guide/events/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1811,6 +1811,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1841,6 +1849,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1871,6 +1887,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2292,6 +2316,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2489,9 +2515,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2500,7 +2551,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2557,6 +2608,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2615,7 +2668,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/gallery/index.html b/mkdocs/site/docs/user-guide/gallery/index.html index 6b16c0e6..2eb97411 100644 --- a/mkdocs/site/docs/user-guide/gallery/index.html +++ b/mkdocs/site/docs/user-guide/gallery/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1811,6 +1811,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1841,6 +1849,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1871,6 +1887,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2292,6 +2316,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2489,9 +2515,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2500,7 +2558,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2559,6 +2617,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2617,7 +2677,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/index.html b/mkdocs/site/docs/user-guide/index.html index a4a8ddbe..9ce65a96 100644 --- a/mkdocs/site/docs/user-guide/index.html +++ b/mkdocs/site/docs/user-guide/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1716,6 +1716,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1746,6 +1754,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1776,6 +1792,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2197,6 +2221,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2361,9 +2387,27 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2372,7 +2416,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2449,6 +2493,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2507,7 +2553,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/map/index.html b/mkdocs/site/docs/user-guide/map/index.html index 3486fa38..d8359e4d 100644 --- a/mkdocs/site/docs/user-guide/map/index.html +++ b/mkdocs/site/docs/user-guide/map/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1789,6 +1789,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1819,6 +1827,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1849,6 +1865,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2270,6 +2294,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2445,9 +2471,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2456,7 +2507,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2500,6 +2551,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2558,7 +2611,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/profile/index.html b/mkdocs/site/docs/user-guide/profile/index.html index 14a7c2b6..461ba137 100644 --- a/mkdocs/site/docs/user-guide/profile/index.html +++ b/mkdocs/site/docs/user-guide/profile/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1716,6 +1716,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1746,6 +1754,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1785,6 +1801,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1805,6 +1829,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2303,6 +2335,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2511,9 +2545,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2522,7 +2581,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2586,6 +2645,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2644,7 +2705,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/shifts/index.html b/mkdocs/site/docs/user-guide/shifts/index.html index 7bb37b8a..c6066469 100644 --- a/mkdocs/site/docs/user-guide/shifts/index.html +++ b/mkdocs/site/docs/user-guide/shifts/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1811,6 +1811,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1841,6 +1849,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1871,6 +1887,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2292,6 +2316,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2489,9 +2515,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2500,7 +2551,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2563,6 +2614,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2621,7 +2674,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/user-guide/shop/index.html b/mkdocs/site/docs/user-guide/shop/index.html index c305c067..f06947f3 100644 --- a/mkdocs/site/docs/user-guide/shop/index.html +++ b/mkdocs/site/docs/user-guide/shop/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1725,6 +1725,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1745,6 +1753,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1830,6 +1846,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1860,6 +1884,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2281,6 +2313,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2467,9 +2501,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2478,7 +2537,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2531,6 +2590,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2589,7 +2650,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/volunteer/achievements/index.html b/mkdocs/site/docs/volunteer/achievements/index.html index 5058a87a..c142a3a2 100644 --- a/mkdocs/site/docs/volunteer/achievements/index.html +++ b/mkdocs/site/docs/volunteer/achievements/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1692,6 +1692,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1731,6 +1739,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1751,6 +1767,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2244,6 +2268,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2513,9 +2539,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2524,7 +2575,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2707,6 +2758,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2765,7 +2818,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/volunteer/canvassing/index.html b/mkdocs/site/docs/volunteer/canvassing/index.html index 1275f703..67cfc69a 100644 --- a/mkdocs/site/docs/volunteer/canvassing/index.html +++ b/mkdocs/site/docs/volunteer/canvassing/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1815,6 +1815,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1845,6 +1853,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2200,6 +2216,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2425,9 +2443,41 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2436,7 +2486,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2510,6 +2560,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2568,7 +2620,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/volunteer/index.html b/mkdocs/site/docs/volunteer/index.html index 7031e5ad..3599bdb2 100644 --- a/mkdocs/site/docs/volunteer/index.html +++ b/mkdocs/site/docs/volunteer/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1692,6 +1692,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1722,6 +1730,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2077,6 +2093,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2313,9 +2331,27 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2324,7 +2360,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2390,6 +2426,8 @@ A: Visit the public shifts page at /shifts.

    + + @@ -2448,7 +2486,7 @@ A: Visit the public shifts page at /shifts.

    +
    + + + + - + diff --git a/mkdocs/site/docs/volunteer/shifts/index.html b/mkdocs/site/docs/volunteer/shifts/index.html index c4122192..c708f94d 100644 --- a/mkdocs/site/docs/volunteer/shifts/index.html +++ b/mkdocs/site/docs/volunteer/shifts/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1776,6 +1776,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1806,6 +1814,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2161,6 +2177,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2347,9 +2365,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2358,7 +2401,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2411,6 +2454,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2469,7 +2514,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/docs/volunteer/social/index.html b/mkdocs/site/docs/volunteer/social/index.html index cef98bb2..a1e636e8 100644 --- a/mkdocs/site/docs/volunteer/social/index.html +++ b/mkdocs/site/docs/volunteer/social/index.html @@ -13,7 +13,7 @@ - + @@ -26,7 +26,7 @@ - + @@ -130,7 +130,7 @@ })(); - + @@ -139,15 +139,15 @@ - + - + - + @@ -849,11 +849,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -944,7 +944,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1701,6 +1701,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1721,6 +1729,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -1872,6 +1888,14 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + + + + + + + @@ -2227,6 +2251,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2479,9 +2505,34 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + - + @@ -2490,7 +2541,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -2600,6 +2651,8 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { + + @@ -2658,7 +2711,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { +
    + + + + - + diff --git a/mkdocs/site/hooks/__pycache__/env_config_hook.cpython-311.pyc b/mkdocs/site/hooks/__pycache__/env_config_hook.cpython-311.pyc index 13e9fdb5..0d11b807 100644 Binary files a/mkdocs/site/hooks/__pycache__/env_config_hook.cpython-311.pyc and b/mkdocs/site/hooks/__pycache__/env_config_hook.cpython-311.pyc differ diff --git a/mkdocs/site/hooks/__pycache__/repo_widget_hook.cpython-311.pyc b/mkdocs/site/hooks/__pycache__/repo_widget_hook.cpython-311.pyc index ccb14b94..9bf58cc1 100644 Binary files a/mkdocs/site/hooks/__pycache__/repo_widget_hook.cpython-311.pyc and b/mkdocs/site/hooks/__pycache__/repo_widget_hook.cpython-311.pyc differ diff --git a/mkdocs/site/hooks/__pycache__/wikilinks_hook.cpython-311.pyc b/mkdocs/site/hooks/__pycache__/wikilinks_hook.cpython-311.pyc index 98cf4825..3054014a 100644 Binary files a/mkdocs/site/hooks/__pycache__/wikilinks_hook.cpython-311.pyc and b/mkdocs/site/hooks/__pycache__/wikilinks_hook.cpython-311.pyc differ diff --git a/mkdocs/site/test/index.html b/mkdocs/site/includes/abbreviations/index.html similarity index 52% rename from mkdocs/site/test/index.html rename to mkdocs/site/includes/abbreviations/index.html index da48b6f5..7d91e953 100644 --- a/mkdocs/site/test/index.html +++ b/mkdocs/site/includes/abbreviations/index.html @@ -13,7 +13,7 @@ - + @@ -21,19 +21,19 @@ - - + + - Test - Changemaker Lite + Abbreviations - Changemaker Lite - + - + @@ -52,19 +52,19 @@ - + - + - + - + - + - + - + @@ -126,24 +126,24 @@ })(); - + - + - + - + - + - + @@ -162,11 +162,6 @@
    - - - Skip to content - -
    @@ -845,11 +840,11 @@ .cm-header-nav__hamburger { display: block; } .cm-header-nav__dropdown-menu { display: none !important; } } -/* Tell Material that sidebar sticky offset = tabs height (blue header scrolls away) */ +/* Sidebar sticky offset = 0 since blue header scrolls away */ :root { --md-header-height: 0px; } -/* Hidden Material header — 0 height but search children overflow visibly */ +/* Hidden Material header — keeps search anchored near tabs */ .md-header--cm-hidden { height: 0 !important; min-height: 0 !important; @@ -940,7 +935,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { height: 0 !important; overflow: hidden !important; } -/* Material tabs: sticky at top (blue header scrolls away, tabs persist) */ +/* Material tabs: sticky at viewport top when blue header scrolls away */ .md-tabs { position: sticky; top: 0; @@ -1077,7 +1072,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
  • - + @@ -1098,7 +1093,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
  • - + @@ -1122,7 +1117,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
  • - + @@ -1157,9 +1152,9 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
  • @@ -1387,7 +1382,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + @@ -1396,444 +1391,16 @@ body.cm-search-active .md-header--cm-hidden .md-search__output { - + -

    Test

    -

    Testing page.

    -

    test-page

    -

    TEst

    -

    test

    -

    test

    -
    Loading...
    +

    Abbreviations

    -
    -

    Choose Your Plan

    -

    Get access to exclusive content and features.

    - View Plans -
    - - -
    -
    🛒
    -
    DIGITAL
    -

    Test Product 1

    -

    A test product

    -

    $90.00

    -
    - - - - -

    - Secure payment via Stripe. Browse all products -

    -
    - -
    - - -
    -

    ❤️

    -

    Support Our Work

    -

    Every contribution makes a difference. Choose an amount below.

    - -
    - - - - - -
    - - - -
    - - -
    -

    ❤️

    -

    Support Our Work

    -

    Every contribution makes a difference. Choose an amount below.

    -
    - $10 - $25 - $50 - $100 -
    - Custom Amount -
    - -
    -

    🛒

    -

    Browse Our Products

    -

    Reports, toolkits, event tickets, and more.

    - Shop Now -
    - -
    -

    Choose Your Plan

    -

    Get access to exclusive content and features.

    - View Plans -
    - -
    -

    ❤️

    -

    Support Our Cause

    -

    Your contribution helps us create lasting change in our community.

    - Donate Now -
    - - - -

    Test

    -

    Testing page.

    -
    Loading...
    - - - -
    -
    🛒
    -
    DIGITAL
    -

    Test Product 1

    -

    A test product

    -

    $90.00

    -
    - - - - -

    - Secure payment via Stripe. Browse all products -

    -
    - -
    - - -
    -

    ❤️

    -

    Support Our Work

    -

    Every contribution makes a difference. Choose an amount below.

    - -
    - - - - - -
    - - - -
    - - -
    -

    ❤️

    -

    Support Our Work

    -

    Every contribution makes a difference. Choose an amount below.

    -
    - $10 - $25 - $50 - $100 -
    - Custom Amount -
    - -
    -

    🛒

    -

    Browse Our Products

    -

    Reports, toolkits, event tickets, and more.

    - Shop Now -
    - -
    -

    Choose Your Plan

    -

    Get access to exclusive content and features.

    - View Plans -
    - -
    -

    ❤️

    -

    Support Our Cause

    -

    Your contribution helps us create lasting change in our community.

    - Donate Now -
    - - @@ -1853,6 +1420,8 @@ Donate + + @@ -1873,7 +1442,7 @@ Donate +
    + + + + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/mkdocs/site/index.html b/mkdocs/site/index.html index 1bc013ee..4f77ba3c 100644 --- a/mkdocs/site/index.html +++ b/mkdocs/site/index.html @@ -386,6 +386,29 @@ box-shadow: 0 4px 16px rgba(111, 66, 193, 0.4); } + .btn-demo { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.625rem 1.5rem; + background: transparent; + color: var(--primary-light); + font-weight: 600; + font-size: 0.9rem; + border-radius: 8px; + border: 1px solid var(--primary-light); + cursor: pointer; + transition: all var(--transition); + text-decoration: none; + } + + .btn-demo:hover { + background: rgba(139, 92, 246, 0.1); + color: var(--primary-light); + transform: translateY(-1px); + box-shadow: 0 4px 16px rgba(111, 66, 193, 0.2); + } + .btn-secondary { display: inline-flex; align-items: center; @@ -1026,6 +1049,42 @@ margin-top: 0.25rem; } + /* Branch preview screenshot */ + .branch-preview { + margin-bottom: 2rem; + position: relative; + z-index: 2; + border-radius: var(--radius-lg); + overflow: hidden; + border: 1px solid var(--border-color); + box-shadow: var(--shadow-md); + background: var(--bg-card); + } + + .branch-preview img { + width: 100%; + height: auto; + display: block; + } + + .branch-preview-caption { + padding: 0.625rem 1.25rem; + font-size: 0.8rem; + color: var(--text-muted); + border-top: 1px solid var(--border-color); + display: flex; + align-items: center; + gap: 0.5rem; + } + + .branch-preview-caption .caption-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--success); + flex-shrink: 0; + } + /* Feature nodes grid */ .nodes-grid { display: grid; @@ -1131,6 +1190,141 @@ color: var(--text-muted); } + /* ============================================ + FEATURE NODE — HOVER SCREENSHOT PREVIEW + ============================================ */ + .feature-node[data-screenshot] { + cursor: pointer; + } + + .node-screenshot { + max-height: 0; + overflow: hidden; + margin: 0 -1.5rem; + border-radius: 0; + transition: max-height 0.35s cubic-bezier(0.4, 0, 0.2, 1), margin-top 0.35s ease, margin-bottom 0.35s ease; + margin-top: 0; + margin-bottom: 0; + } + + .feature-node:hover .node-screenshot { + max-height: 300px; + margin-top: 0.75rem; + margin-bottom: 0.5rem; + } + + .node-screenshot img { + width: 100%; + height: auto; + display: block; + border-top: 1px solid var(--border-color); + border-bottom: 1px solid var(--border-color); + } + + .node-screenshot-label { + padding: 0.3rem 1.5rem; + font-size: 0.7rem; + color: var(--text-muted); + display: flex; + align-items: center; + gap: 0.4rem; + background: rgba(0,0,0,0.15); + } + + [data-theme="light"] .node-screenshot-label { + background: rgba(0,0,0,0.04); + } + + .node-screenshot-label .screenshot-dot { + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--success); + flex-shrink: 0; + } + + /* On mobile, hide hover screenshots (touch doesn't hover well) */ + @media (max-width: 768px) { + .node-screenshot { + display: none; + } + } + + /* ============================================ + NARRATIVE BRIDGE SECTION + ============================================ */ + .narrative-bridge { + padding: 4rem 0 2rem; + background: transparent; + } + + .narrative-content { + max-width: 720px; + margin: 0 auto; + text-align: center; + background: rgba(30, 41, 59, 0.85); + border: 1px solid rgba(148, 163, 184, 0.1); + border-radius: var(--radius-lg); + padding: 3rem 2.5rem; + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + position: relative; + z-index: 2; + } + + [data-theme="light"] .narrative-content { + background: rgba(255, 255, 255, 0.88); + border-color: rgba(100, 116, 139, 0.15); + } + + .narrative-eyebrow { + font-size: 0.8rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--primary-light); + margin-bottom: 1rem; + } + + .narrative-content h2 { + font-size: clamp(1.5rem, 3vw, 2.25rem); + margin-bottom: 1.25rem; + line-height: 1.3; + } + + .narrative-body { + color: var(--text-secondary); + font-size: 1.1rem; + line-height: 1.7; + } + + /* In-feature narrative connectors */ + .branch-narrative { + max-width: 640px; + margin: 2rem auto 3rem; + text-align: center; + padding: 1.5rem 2rem; + background: rgba(30, 41, 59, 0.85); + border: 1px solid rgba(148, 163, 184, 0.1); + border-radius: var(--radius-lg); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + position: relative; + z-index: 2; + } + + [data-theme="light"] .branch-narrative { + background: rgba(255, 255, 255, 0.45); + border-color: rgba(100, 116, 139, 0.1); + } + + .branch-narrative p { + color: var(--text-secondary); + font-size: 1rem; + line-height: 1.7; + margin: 0; + } + /* ============================================ LIVE SITES ============================================ */ @@ -1831,15 +2025,15 @@ - + - + - + @@ -1892,6 +2086,7 @@ + Explore Demo Get Started + Explore Demo Get Started + + + + + + + + + + + + + + + + + + + + + - + diff --git a/mkdocs/site/overrides/lander.html b/mkdocs/site/overrides/lander.html index c7f0bef3..9fbda767 100644 --- a/mkdocs/site/overrides/lander.html +++ b/mkdocs/site/overrides/lander.html @@ -386,6 +386,29 @@ box-shadow: 0 4px 16px rgba(111, 66, 193, 0.4); } + .btn-demo { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.625rem 1.5rem; + background: transparent; + color: var(--primary-light); + font-weight: 600; + font-size: 0.9rem; + border-radius: 8px; + border: 1px solid var(--primary-light); + cursor: pointer; + transition: all var(--transition); + text-decoration: none; + } + + .btn-demo:hover { + background: rgba(139, 92, 246, 0.1); + color: var(--primary-light); + transform: translateY(-1px); + box-shadow: 0 4px 16px rgba(111, 66, 193, 0.2); + } + .btn-secondary { display: inline-flex; align-items: center; @@ -1026,6 +1049,42 @@ margin-top: 0.25rem; } + /* Branch preview screenshot */ + .branch-preview { + margin-bottom: 2rem; + position: relative; + z-index: 2; + border-radius: var(--radius-lg); + overflow: hidden; + border: 1px solid var(--border-color); + box-shadow: var(--shadow-md); + background: var(--bg-card); + } + + .branch-preview img { + width: 100%; + height: auto; + display: block; + } + + .branch-preview-caption { + padding: 0.625rem 1.25rem; + font-size: 0.8rem; + color: var(--text-muted); + border-top: 1px solid var(--border-color); + display: flex; + align-items: center; + gap: 0.5rem; + } + + .branch-preview-caption .caption-dot { + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--success); + flex-shrink: 0; + } + /* Feature nodes grid */ .nodes-grid { display: grid; @@ -1131,6 +1190,141 @@ color: var(--text-muted); } + /* ============================================ + FEATURE NODE — HOVER SCREENSHOT PREVIEW + ============================================ */ + .feature-node[data-screenshot] { + cursor: pointer; + } + + .node-screenshot { + max-height: 0; + overflow: hidden; + margin: 0 -1.5rem; + border-radius: 0; + transition: max-height 0.35s cubic-bezier(0.4, 0, 0.2, 1), margin-top 0.35s ease, margin-bottom 0.35s ease; + margin-top: 0; + margin-bottom: 0; + } + + .feature-node:hover .node-screenshot { + max-height: 300px; + margin-top: 0.75rem; + margin-bottom: 0.5rem; + } + + .node-screenshot img { + width: 100%; + height: auto; + display: block; + border-top: 1px solid var(--border-color); + border-bottom: 1px solid var(--border-color); + } + + .node-screenshot-label { + padding: 0.3rem 1.5rem; + font-size: 0.7rem; + color: var(--text-muted); + display: flex; + align-items: center; + gap: 0.4rem; + background: rgba(0,0,0,0.15); + } + + [data-theme="light"] .node-screenshot-label { + background: rgba(0,0,0,0.04); + } + + .node-screenshot-label .screenshot-dot { + width: 5px; + height: 5px; + border-radius: 50%; + background: var(--success); + flex-shrink: 0; + } + + /* On mobile, hide hover screenshots (touch doesn't hover well) */ + @media (max-width: 768px) { + .node-screenshot { + display: none; + } + } + + /* ============================================ + NARRATIVE BRIDGE SECTION + ============================================ */ + .narrative-bridge { + padding: 4rem 0 2rem; + background: transparent; + } + + .narrative-content { + max-width: 720px; + margin: 0 auto; + text-align: center; + background: rgba(30, 41, 59, 0.85); + border: 1px solid rgba(148, 163, 184, 0.1); + border-radius: var(--radius-lg); + padding: 3rem 2.5rem; + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + position: relative; + z-index: 2; + } + + [data-theme="light"] .narrative-content { + background: rgba(255, 255, 255, 0.88); + border-color: rgba(100, 116, 139, 0.15); + } + + .narrative-eyebrow { + font-size: 0.8rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--primary-light); + margin-bottom: 1rem; + } + + .narrative-content h2 { + font-size: clamp(1.5rem, 3vw, 2.25rem); + margin-bottom: 1.25rem; + line-height: 1.3; + } + + .narrative-body { + color: var(--text-secondary); + font-size: 1.1rem; + line-height: 1.7; + } + + /* In-feature narrative connectors */ + .branch-narrative { + max-width: 640px; + margin: 2rem auto 3rem; + text-align: center; + padding: 1.5rem 2rem; + background: rgba(30, 41, 59, 0.85); + border: 1px solid rgba(148, 163, 184, 0.1); + border-radius: var(--radius-lg); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + position: relative; + z-index: 2; + } + + [data-theme="light"] .branch-narrative { + background: rgba(255, 255, 255, 0.45); + border-color: rgba(100, 116, 139, 0.1); + } + + .branch-narrative p { + color: var(--text-secondary); + font-size: 1rem; + line-height: 1.7; + margin: 0; + } + /* ============================================ LIVE SITES ============================================ */ @@ -1879,6 +2073,7 @@ + Explore Demo Get Started + + + + + + + + + + + + + + + + + + + + + - + diff --git a/nginx/conf.d/services.conf.template b/nginx/conf.d/services.conf.template index 9e530917..f3821431 100644 --- a/nginx/conf.d/services.conf.template +++ b/nginx/conf.d/services.conf.template @@ -73,14 +73,14 @@ server { } } -# Listmonk +# Listmonk — via auth proxy, allows iframe embedding from admin server { listen 80; server_name listmonk.${DOMAIN}; - add_header X-Frame-Options "SAMEORIGIN" always; + add_header Content-Security-Policy "frame-ancestors 'self' app.${DOMAIN}" always; location / { - set $upstream_listmonk http://listmonk-app:9000; + set $upstream_listmonk http://changemaker-v2-api:9002; proxy_pass $upstream_listmonk; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;