{"body":"<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Walkable</title>\n    <style>\n:root {\n  --bg: #f5f2ec;\n  --nav-bg: #1f2a2e;\n  --nav-text: #f3efe8;\n  --accent: #e07a5f;\n  --muted: #a9a39b;\n  --shadow: 0 10px 30px rgba(0, 0, 0, 0.12);\n  --menu-shadow: 0 14px 40px rgba(0, 0, 0, 0.28);\n  --nav-height: 56px;\n  font-family: \"Avenir Next\", \"Avenir\", \"Futura\", \"Segoe UI\", sans-serif;\n}\n\n* {\n  box-sizing: border-box;\n}\n\nbody {\n  margin: 0;\n  background: var(--bg);\n  color: #1f2a2e;\n}\n\n.shell {\n  min-height: 100vh;\n  display: flex;\n  flex-direction: column;\n}\n\n/* ---- The frame ---- */\n\n.frame {\n  height: var(--nav-height);\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 0 12px 0 8px;\n  background: var(--nav-bg);\n  color: var(--nav-text);\n  box-shadow: var(--shadow);\n}\n\n.zone {\n  display: flex;\n  align-items: center;\n  min-width: 0;\n}\n\n.zone-left {\n  gap: 4px;\n  flex: 0 0 auto;\n}\n\n.zone-center {\n  flex: 1 1 auto;\n  min-width: 0;\n  justify-content: flex-start;\n}\n\n.zone-right {\n  flex: 0 0 auto;\n  justify-content: flex-end;\n}\n\n/* ---- Left: waffle + wordmark ---- */\n\n.waffle {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 36px;\n  height: 36px;\n  border-radius: 8px;\n  color: var(--nav-text);\n  text-decoration: none;\n  font-size: 1.2rem;\n  line-height: 1;\n}\n\n.waffle:hover {\n  background: rgba(255, 255, 255, 0.1);\n}\n\n.wordmark {\n  font-weight: 700;\n  letter-spacing: 0.08em;\n  text-transform: uppercase;\n  font-size: 0.82rem;\n  color: var(--nav-text);\n  text-decoration: none;\n  white-space: nowrap;\n}\n\n/* ---- Center: the location sentence ---- */\n\n.location {\n  display: inline-flex;\n  align-items: baseline;\n  gap: 8px;\n  min-width: 0;\n}\n\n.app-name {\n  font-size: 1.1rem;\n  font-weight: 600;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.from {\n  font-size: 0.85rem;\n  color: var(--muted);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  flex: 0 1 auto;\n}\n\n.from[hidden] {\n  display: none;\n}\n\n/* ---- Right: account chip + menu ---- */\n\n.account {\n  position: relative;\n}\n\n.account-chip {\n  display: inline-flex;\n  align-items: center;\n  gap: 8px;\n  background: transparent;\n  border: 1px solid transparent;\n  border-radius: 999px;\n  padding: 4px 10px 4px 4px;\n  color: var(--nav-text);\n  font: inherit;\n  font-size: 0.9rem;\n  cursor: pointer;\n  max-width: 220px;\n}\n\n.account-chip:hover,\n.account-chip[aria-expanded=\"true\"] {\n  background: rgba(255, 255, 255, 0.1);\n  border-color: rgba(255, 255, 255, 0.14);\n}\n\n.account-name {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.caret {\n  font-size: 0.7rem;\n  opacity: 0.7;\n}\n\n.avatar {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 28px;\n  height: 28px;\n  flex: 0 0 28px;\n  border-radius: 50%;\n  background: var(--accent);\n  color: #fff;\n  font-size: 0.85rem;\n  font-weight: 700;\n  text-transform: uppercase;\n  background-size: cover;\n  background-position: center;\n}\n\n.avatar.lg {\n  width: 40px;\n  height: 40px;\n  flex-basis: 40px;\n  font-size: 1.1rem;\n}\n\n/* ---- Account dropdown ---- */\n\n.account-menu {\n  position: absolute;\n  top: calc(100% + 8px);\n  right: 0;\n  min-width: 260px;\n  max-width: 320px;\n  background: #fff;\n  color: #1f2a2e;\n  border-radius: 12px;\n  box-shadow: var(--menu-shadow);\n  padding: 8px;\n  z-index: 50;\n}\n\n.account-menu[hidden] {\n  display: none;\n}\n\n.account-active {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 10px 10px 12px;\n}\n\n.account-active-text {\n  min-width: 0;\n}\n\n.account-active-name {\n  font-weight: 600;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.account-active-sub {\n  font-size: 0.8rem;\n  color: #6b6b6b;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.menu-sep {\n  height: 1px;\n  background: #ececec;\n  margin: 6px 4px;\n}\n\n.menu-label {\n  font-size: 0.7rem;\n  letter-spacing: 0.06em;\n  text-transform: uppercase;\n  color: #9a9a9a;\n  padding: 4px 12px;\n}\n\n.menu-item {\n  display: flex;\n  align-items: center;\n  gap: 10px;\n  width: 100%;\n  padding: 9px 12px;\n  border: none;\n  border-radius: 8px;\n  background: transparent;\n  color: inherit;\n  font: inherit;\n  font-size: 0.9rem;\n  text-align: left;\n  text-decoration: none;\n  cursor: pointer;\n}\n\n.menu-item:hover {\n  background: #f3f0ea;\n}\n\n.menu-item .avatar {\n  width: 26px;\n  height: 26px;\n  flex-basis: 26px;\n  font-size: 0.8rem;\n}\n\n.menu-item .menu-item-text {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.menu-item .menu-glyph {\n  display: inline-flex;\n  width: 26px;\n  justify-content: center;\n  opacity: 0.7;\n}\n\n.menu-item.danger {\n  color: #b3261e;\n}\n\n/* ---- Content ---- */\n\n.content {\n  flex: 1;\n  min-height: 0;\n}\n\n#app-frame {\n  width: 100%;\n  height: calc(100vh - var(--nav-height));\n  border: none;\n  display: block;\n  background: #fff;\n}\n\n/* ---- Mobile: stay a single row; shed the least-needed bits first ---- */\n\n@media (max-width: 600px) {\n  .wordmark {\n    display: none;\n  }\n  .account-name,\n  .caret {\n    display: none;\n  }\n  .account-chip {\n    padding: 4px;\n  }\n  .app-name {\n    font-size: 1rem;\n  }\n}\n\n</style></head>\n  <body>\n    <div class=\"shell\">\n      <header class=\"frame\">\n        <div class=\"zone zone-left\">\n          <a class=\"waffle\" id=\"waffle\" href=\"/\" title=\"Apps\" aria-label=\"Apps and home\">\n            <span aria-hidden=\"true\">⊞</span>\n          </a>\n          <a class=\"wordmark\" id=\"home-link\" href=\"/\">Walkable</a>\n        </div>\n\n        <div class=\"zone zone-center\">\n          <span class=\"location\">\n            <span class=\"app-name\" id=\"app-name\">App</span>\n            <span class=\"from\" id=\"from-owner\" hidden></span>\n          </span>\n        </div>\n\n        <div class=\"zone zone-right\">\n          <div class=\"account\" id=\"account\">\n            <button\n              class=\"account-chip\"\n              id=\"account-chip\"\n              aria-haspopup=\"menu\"\n              aria-expanded=\"false\"\n              aria-controls=\"account-menu\"\n            >\n              <span class=\"avatar\" id=\"account-avatar\" aria-hidden=\"true\">·</span>\n              <span class=\"account-name\" id=\"user-label\">Checking…</span>\n              <span class=\"caret\" aria-hidden=\"true\">▾</span>\n            </button>\n            <div class=\"account-menu\" id=\"account-menu\" role=\"menu\" hidden></div>\n          </div>\n        </div>\n      </header>\n\n      <main class=\"content\">\n        <iframe\n          id=\"app-frame\"\n          sandbox=\"allow-forms allow-scripts allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation\"\n          title=\"App\"\n        ></iframe>\n      </main>\n    </div>\n    <script type=\"module\" src=\"/apps/_shell-js?blob=true\"></script>\n  <script>\n(() => {\n  document.addEventListener(\"click\", (event) => {\n    if (!(event.target instanceof Element)) return;\n    const anchor = event.target.closest(\"a[href]\");\n    if (!(anchor instanceof HTMLAnchorElement)) return;\n    if (anchor.target && anchor.target !== \"_self\") return;\n    let url;\n    try {\n      url = new URL(anchor.href, window.location.href);\n    } catch {\n      return;\n    }\n    if (url.origin !== window.location.origin) return;\n    if (!url.pathname.startsWith(\"/apps/\")) return;\n    if (window.top && window.top !== window) {\n      event.preventDefault();\n      window.top.location.href = url.href;\n      return;\n    }\n    anchor.target = \"_top\";\n  }, true);\n})();\n</script>\n</body>\n</html>\n","html":"<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Walkable</title>\n    <style>\n:root {\n  --bg: #f5f2ec;\n  --nav-bg: #1f2a2e;\n  --nav-text: #f3efe8;\n  --accent: #e07a5f;\n  --muted: #a9a39b;\n  --shadow: 0 10px 30px rgba(0, 0, 0, 0.12);\n  --menu-shadow: 0 14px 40px rgba(0, 0, 0, 0.28);\n  --nav-height: 56px;\n  font-family: \"Avenir Next\", \"Avenir\", \"Futura\", \"Segoe UI\", sans-serif;\n}\n\n* {\n  box-sizing: border-box;\n}\n\nbody {\n  margin: 0;\n  background: var(--bg);\n  color: #1f2a2e;\n}\n\n.shell {\n  min-height: 100vh;\n  display: flex;\n  flex-direction: column;\n}\n\n/* ---- The frame ---- */\n\n.frame {\n  height: var(--nav-height);\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 0 12px 0 8px;\n  background: var(--nav-bg);\n  color: var(--nav-text);\n  box-shadow: var(--shadow);\n}\n\n.zone {\n  display: flex;\n  align-items: center;\n  min-width: 0;\n}\n\n.zone-left {\n  gap: 4px;\n  flex: 0 0 auto;\n}\n\n.zone-center {\n  flex: 1 1 auto;\n  min-width: 0;\n  justify-content: flex-start;\n}\n\n.zone-right {\n  flex: 0 0 auto;\n  justify-content: flex-end;\n}\n\n/* ---- Left: waffle + wordmark ---- */\n\n.waffle {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 36px;\n  height: 36px;\n  border-radius: 8px;\n  color: var(--nav-text);\n  text-decoration: none;\n  font-size: 1.2rem;\n  line-height: 1;\n}\n\n.waffle:hover {\n  background: rgba(255, 255, 255, 0.1);\n}\n\n.wordmark {\n  font-weight: 700;\n  letter-spacing: 0.08em;\n  text-transform: uppercase;\n  font-size: 0.82rem;\n  color: var(--nav-text);\n  text-decoration: none;\n  white-space: nowrap;\n}\n\n/* ---- Center: the location sentence ---- */\n\n.location {\n  display: inline-flex;\n  align-items: baseline;\n  gap: 8px;\n  min-width: 0;\n}\n\n.app-name {\n  font-size: 1.1rem;\n  font-weight: 600;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.from {\n  font-size: 0.85rem;\n  color: var(--muted);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  flex: 0 1 auto;\n}\n\n.from[hidden] {\n  display: none;\n}\n\n/* ---- Right: account chip + menu ---- */\n\n.account {\n  position: relative;\n}\n\n.account-chip {\n  display: inline-flex;\n  align-items: center;\n  gap: 8px;\n  background: transparent;\n  border: 1px solid transparent;\n  border-radius: 999px;\n  padding: 4px 10px 4px 4px;\n  color: var(--nav-text);\n  font: inherit;\n  font-size: 0.9rem;\n  cursor: pointer;\n  max-width: 220px;\n}\n\n.account-chip:hover,\n.account-chip[aria-expanded=\"true\"] {\n  background: rgba(255, 255, 255, 0.1);\n  border-color: rgba(255, 255, 255, 0.14);\n}\n\n.account-name {\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.caret {\n  font-size: 0.7rem;\n  opacity: 0.7;\n}\n\n.avatar {\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  width: 28px;\n  height: 28px;\n  flex: 0 0 28px;\n  border-radius: 50%;\n  background: var(--accent);\n  color: #fff;\n  font-size: 0.85rem;\n  font-weight: 700;\n  text-transform: uppercase;\n  background-size: cover;\n  background-position: center;\n}\n\n.avatar.lg {\n  width: 40px;\n  height: 40px;\n  flex-basis: 40px;\n  font-size: 1.1rem;\n}\n\n/* ---- Account dropdown ---- */\n\n.account-menu {\n  position: absolute;\n  top: calc(100% + 8px);\n  right: 0;\n  min-width: 260px;\n  max-width: 320px;\n  background: #fff;\n  color: #1f2a2e;\n  border-radius: 12px;\n  box-shadow: var(--menu-shadow);\n  padding: 8px;\n  z-index: 50;\n}\n\n.account-menu[hidden] {\n  display: none;\n}\n\n.account-active {\n  display: flex;\n  align-items: center;\n  gap: 12px;\n  padding: 10px 10px 12px;\n}\n\n.account-active-text {\n  min-width: 0;\n}\n\n.account-active-name {\n  font-weight: 600;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.account-active-sub {\n  font-size: 0.8rem;\n  color: #6b6b6b;\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n\n.menu-sep {\n  height: 1px;\n  background: #ececec;\n  margin: 6px 4px;\n}\n\n.menu-label {\n  font-size: 0.7rem;\n  letter-spacing: 0.06em;\n  text-transform: uppercase;\n  color: #9a9a9a;\n  padding: 4px 12px;\n}\n\n.menu-item {\n  display: flex;\n  align-items: center;\n  gap: 10px;\n  width: 100%;\n  padding: 9px 12px;\n  border: none;\n  border-radius: 8px;\n  background: transparent;\n  color: inherit;\n  font: inherit;\n  font-size: 0.9rem;\n  text-align: left;\n  text-decoration: none;\n  cursor: pointer;\n}\n\n.menu-item:hover {\n  background: #f3f0ea;\n}\n\n.menu-item .avatar {\n  width: 26px;\n  height: 26px;\n  flex-basis: 26px;\n  font-size: 0.8rem;\n}\n\n.menu-item .menu-item-text {\n  min-width: 0;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.menu-item .menu-glyph {\n  display: inline-flex;\n  width: 26px;\n  justify-content: center;\n  opacity: 0.7;\n}\n\n.menu-item.danger {\n  color: #b3261e;\n}\n\n/* ---- Content ---- */\n\n.content {\n  flex: 1;\n  min-height: 0;\n}\n\n#app-frame {\n  width: 100%;\n  height: calc(100vh - var(--nav-height));\n  border: none;\n  display: block;\n  background: #fff;\n}\n\n/* ---- Mobile: stay a single row; shed the least-needed bits first ---- */\n\n@media (max-width: 600px) {\n  .wordmark {\n    display: none;\n  }\n  .account-name,\n  .caret {\n    display: none;\n  }\n  .account-chip {\n    padding: 4px;\n  }\n  .app-name {\n    font-size: 1rem;\n  }\n}\n\n</style></head>\n  <body>\n    <div class=\"shell\">\n      <header class=\"frame\">\n        <div class=\"zone zone-left\">\n          <a class=\"waffle\" id=\"waffle\" href=\"/\" title=\"Apps\" aria-label=\"Apps and home\">\n            <span aria-hidden=\"true\">⊞</span>\n          </a>\n          <a class=\"wordmark\" id=\"home-link\" href=\"/\">Walkable</a>\n        </div>\n\n        <div class=\"zone zone-center\">\n          <span class=\"location\">\n            <span class=\"app-name\" id=\"app-name\">App</span>\n            <span class=\"from\" id=\"from-owner\" hidden></span>\n          </span>\n        </div>\n\n        <div class=\"zone zone-right\">\n          <div class=\"account\" id=\"account\">\n            <button\n              class=\"account-chip\"\n              id=\"account-chip\"\n              aria-haspopup=\"menu\"\n              aria-expanded=\"false\"\n              aria-controls=\"account-menu\"\n            >\n              <span class=\"avatar\" id=\"account-avatar\" aria-hidden=\"true\">·</span>\n              <span class=\"account-name\" id=\"user-label\">Checking…</span>\n              <span class=\"caret\" aria-hidden=\"true\">▾</span>\n            </button>\n            <div class=\"account-menu\" id=\"account-menu\" role=\"menu\" hidden></div>\n          </div>\n        </div>\n      </header>\n\n      <main class=\"content\">\n        <iframe\n          id=\"app-frame\"\n          sandbox=\"allow-forms allow-scripts allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation\"\n          title=\"App\"\n        ></iframe>\n      </main>\n    </div>\n    <script type=\"module\" src=\"/apps/_shell-js?blob=true\"></script>\n  <script>\n(() => {\n  document.addEventListener(\"click\", (event) => {\n    if (!(event.target instanceof Element)) return;\n    const anchor = event.target.closest(\"a[href]\");\n    if (!(anchor instanceof HTMLAnchorElement)) return;\n    if (anchor.target && anchor.target !== \"_self\") return;\n    let url;\n    try {\n      url = new URL(anchor.href, window.location.href);\n    } catch {\n      return;\n    }\n    if (url.origin !== window.location.origin) return;\n    if (!url.pathname.startsWith(\"/apps/\")) return;\n    if (window.top && window.top !== window) {\n      event.preventDefault();\n      window.top.location.href = url.href;\n      return;\n    }\n    anchor.target = \"_top\";\n  }, true);\n})();\n</script>\n</body>\n</html>\n"}