/* Workspace stickiness: the store selection rides the URL (?store=, the FR-003 seam), which a typed URL or new tab drops — so, like the theme, the last explicit selection is remembered (localStorage "cairn-store") and a bare visit redirects to it. Until the user picks a workspace, nothing is stored and bare URLs keep the launch store, byte-identical. A remembered key that no longer names a populated store (the workspace was deleted) is NOT redirected to — that would poison every future visit with the missing-DB page — it is forgotten and the launch store serves; the valid key set rides this tag's data-valid-stores attribute, server-rendered from the same enumerate_stores rows the selector lists. */ (function () { "use strict"; var STORAGE_KEY = "cairn-store"; var url = new URL(window.location.href); var selected = (url.searchParams.get("store") || "").trim(); try { if (selected) { window.localStorage.setItem(STORAGE_KEY, selected); } else { var remembered = window.localStorage.getItem(STORAGE_KEY); var valid = null; var validRaw = document.currentScript ? document.currentScript.getAttribute("data-valid-stores") : null; if (validRaw) { try { valid = JSON.parse(validRaw); } catch (err) { valid = null; /* unparsable set: redirect as before */ } } var known = valid === null || valid.indexOf(remembered) !== -1; if (remembered && known) { url.searchParams.set("store", remembered); window.location.replace( url.pathname + url.search + url.hash ); } else if (remembered) { window.localStorage.removeItem(STORAGE_KEY); } } } catch (err) { /* storage unavailable: the selection stays URL-only */ } })(); {%- set shell_ctx = shell if shell is defined else none %} {%- set nav_sections = (shell_ctx.nav.sections if shell_ctx else none) or [] %} {%- set selector = (shell_ctx.selector if shell_ctx else none) %} {%- set palette = (shell_ctx.palette if shell_ctx else none) %}
{#- The topbar label derives from the path segment ("/" -> Overview); views may override via the view_title block. -#}
{% block view_title %}{{ 'Overview' if path == '/' else (path.strip('/').split('/')[0] | capitalize) }}{% endblock %}
{#- Global workspace selector (FR-003 seam stays the URL param): switching rewrites ?store= on the current URL and reloads, so every tab shows the selected workspace. shell.js owns the change behavior; the options are server-rendered. -#} {% if selector %} {% endif %} {% if palette %} {% endif %}
{% include "_embed_banner.html" %} {% block content %}{% endblock %}
{% if palette %} {#- Command palette overlay: body-level so live-refresh region swaps (which replace only #refresh-region's children) never touch it. The seed JSON carries the view list (store-carrying hrefs, composed server-side from the same NAV_SECTIONS the sidebar renders) and the workspace options; symbols arrive live from /graph/suggest. -#} {% endif %} {% block scripts %}{% endblock %}