diff --git a/scripts/build-browser-extension.sh b/scripts/build-browser-extension.sh
index 0150883..ddd1ea0 100755
--- a/scripts/build-browser-extension.sh
+++ b/scripts/build-browser-extension.sh
@@ -5,4 +5,4 @@ version=$(node -p "require('./package.json').version")
 cd src
 mkdir -p ../dist
 rm -f "../dist/notion-enhancer-$version.zip"
-zip -r9 "../dist/notion-enhancer-$version.zip" . -x electron/\*
\ No newline at end of file
+zip -r9 "../dist/notion-enhancer-$version.zip" .
\ No newline at end of file
diff --git a/src/api/browser.js b/src/api/browser.js
index 99f3e80..1331c14 100644
--- a/src/api/browser.js
+++ b/src/api/browser.js
@@ -6,7 +6,9 @@
 
 "use strict";
 
-const platform = "browser",
+const platform = navigator.userAgent.includes("Firefox")
+    ? "firefox"
+    : "chromium",
   version = chrome.runtime.getManifest().version,
   enhancerUrl = (target) => chrome.runtime.getURL(target);
 
diff --git a/src/api/mods.js b/src/api/mods.js
index 6f383fb..5efa2cf 100644
--- a/src/api/mods.js
+++ b/src/api/mods.js
@@ -25,18 +25,17 @@ const _isManifestValid = (modManifest) => {
 };
 
 let _mods;
-const getMods = async (category) => {
+const getMods = async (asyncFilter) => {
     const { readJson } = globalThis.__enhancerApi;
     // prettier-ignore
     _mods ??= (await Promise.all((await readJson("registry.json")).map(async (_src) => {
       const modManifest = { ...(await readJson(`${_src}/mod.json`)), _src };
       return _isManifestValid(modManifest) ? modManifest : undefined;
     }))).filter((mod) => mod);
-    return category
-      ? _mods.filter(({ _src }) => {
-          return _src === category || _src.startsWith(`${category}/`);
-        })
-      : _mods;
+    // prettier-ignore
+    return (await Promise.all(_mods.map(async (mod) => {
+      return !asyncFilter || (await asyncFilter(mod)) ? mod : undefined;
+    }))).filter((mod) => mod);
   },
   getProfile = async () => {
     const db = globalThis.__enhancerApi.initDatabase();
@@ -49,10 +48,10 @@ const isEnabled = async (id) => {
     const { version, initDatabase } = globalThis.__enhancerApi,
       mod = (await getMods()).find((mod) => mod.id === id);
     if (mod._src === "core") return true;
-    // prettier-ignore
     const agreedToTerms = await initDatabase().get("agreedToTerms"),
       enabledInProfile = await initDatabase([
-        await getProfile(), "enabledMods",
+        await getProfile(),
+        "enabledMods",
       ]).get(id);
     return agreedToTerms === version && enabledInProfile;
   },
@@ -63,10 +62,9 @@ const isEnabled = async (id) => {
   };
 
 const modDatabase = async (id) => {
-  // prettier-ignore
   const optionDefaults = (await getMods())
-    .find((mod) => mod.id === id)?.options
-    .map((opt) => [opt.key, opt.value ?? opt.values?.[0]])
+    .find((mod) => mod.id === id)
+    ?.options.map((opt) => [opt.key, opt.value ?? opt.values?.[0]])
     .filter(([, value]) => typeof value !== "undefined");
   return globalThis.__enhancerApi.initDatabase(
     [await getProfile(), id],
diff --git a/src/core/client.mjs b/src/core/client.mjs
index 9780a03..6ff0257 100644
--- a/src/core/client.mjs
+++ b/src/core/client.mjs
@@ -5,21 +5,20 @@
  */
 
 import { checkForUpdate } from "./update.mjs";
+import { sendTelemetryPing } from "./telemetry.mjs";
 import { Frame, Modal, Button } from "./components.mjs";
 
-// prettier-ignore
-const asyncFilter = async (arr, predicate) => Promise.all(arr.map(predicate))
-  .then((results) => arr.filter((_v, index) => results[index]));
-
 const doThemeOverride = async (db) => {
     const { getMods, isEnabled } = globalThis.__enhancerApi,
-      enabledFilter = (theme) => isEnabled(theme.id),
-      overrideThemes = await db.get("loadThemeOverrides"),
-      enabledThemes = await asyncFilter(await getMods("themes"), enabledFilter);
-    return (
-      overrideThemes === "Enabled" ||
-      (overrideThemes === "Auto" && enabledThemes.length)
-    );
+      loadThemeOverrides = await db.get("loadThemeOverrides");
+    if (loadThemeOverrides === "Enabled") return true;
+    if (loadThemeOverrides === "Disabled") return false;
+    // prettier-ignore
+    return (await getMods(async (mod) => {
+      // loadThemeOverrides === "Auto"
+      if (!mod._src.startsWith("themes/")) return false;
+      return await isEnabled(mod.id);
+    })).length;
   },
   overrideThemes = async (db) => {
     const { html, enhancerUrl } = globalThis.__enhancerApi;
@@ -39,86 +38,78 @@ const doThemeOverride = async (db) => {
   };
 
 const insertMenu = async (db) => {
-    const notionSidebar = `.notion-sidebar-container .notion-sidebar > :nth-child(3) > div > :nth-child(2)`,
-      { html, addKeyListener, addMutationListener } = globalThis.__enhancerApi,
-      { platform, enhancerUrl, onMessage } = globalThis.__enhancerApi,
-      menuButtonIconStyle = await db.get("menuButtonIconStyle"),
-      openMenuHotkey = await db.get("openMenuHotkey"),
-      renderPing = {
-        namespace: "notion-enhancer",
-        hotkey: openMenuHotkey,
-        icon: menuButtonIconStyle,
-      };
+  const notionSidebar = `.notion-sidebar-container .notion-sidebar > :nth-child(3) > div > :nth-child(2)`,
+    { html, addKeyListener, addMutationListener } = globalThis.__enhancerApi,
+    { platform, enhancerUrl, onMessage } = globalThis.__enhancerApi,
+    menuButtonIconStyle = await db.get("menuButtonIconStyle"),
+    openMenuHotkey = await db.get("openMenuHotkey"),
+    renderPing = {
+      namespace: "notion-enhancer",
+      hotkey: openMenuHotkey,
+      icon: menuButtonIconStyle,
+    };
 
-    let _contentWindow;
-    const sendThemePing = () => {
-        const darkMode = document.body.classList.contains("dark"),
-          notionTheme = darkMode ? "dark" : "light";
-        if (renderPing.theme === notionTheme) return;
-        renderPing.theme = notionTheme;
-        _contentWindow?.postMessage?.(renderPing, "*");
-      },
-      sendRenderPing = (contentWindow) => {
-        _contentWindow ??= contentWindow;
-        if (!$modal.hasAttribute("open")) return;
-        delete renderPing.theme;
-        _contentWindow?.focus?.();
-        sendThemePing();
-      };
+  let _contentWindow;
+  const sendThemePing = () => {
+      const darkMode = document.body.classList.contains("dark"),
+        notionTheme = darkMode ? "dark" : "light";
+      if (renderPing.theme === notionTheme) return;
+      renderPing.theme = notionTheme;
+      _contentWindow?.postMessage?.(renderPing, "*");
+    },
+    sendRenderPing = (contentWindow) => {
+      _contentWindow ??= contentWindow;
+      if (!$modal.hasAttribute("open")) return;
+      delete renderPing.theme;
+      _contentWindow?.focus?.();
+      sendThemePing();
+    };
 
-    const $modal = html`<${Modal} onopen=${sendRenderPing}>
-        <${Frame}
-          title="notion-enhancer menu"
-          src="${enhancerUrl("core/menu/index.html")}"
-          onload=${function () {
-            // pass notion-enhancer api to electron menu process
-            if (platform !== "browser") {
-              const apiKey = "__enhancerApi";
-              this.contentWindow[apiKey] = globalThis[apiKey];
-            }
-            sendRenderPing(this.contentWindow);
-          }}
-        />
-      <//>`,
-      $button = html`<${Button}
-        onclick=${$modal.open}
-        notifications=${(await checkForUpdate()) ? 1 : 0}
-        themeOverridesLoaded=${await doThemeOverride(db)}
-        icon="notion-enhancer${menuButtonIconStyle === "Monochrome"
-          ? "?mask"
-          : " text-[16px]"}"
-        >notion-enhancer
-      <//>`;
-    document.body.append($modal);
-    addMutationListener(notionSidebar, () => {
-      if (document.contains($button)) return;
-      document.querySelector(notionSidebar)?.append($button);
-    });
+  const $modal = html`<${Modal} onopen=${sendRenderPing}>
+      <${Frame}
+        title="notion-enhancer menu"
+        src="${enhancerUrl("core/menu/index.html")}"
+        onload=${function () {
+          // pass notion-enhancer api to electron menu process
+          if (["darwin", "win32", "linux"].includes(platform)) {
+            const apiKey = "__enhancerApi";
+            this.contentWindow[apiKey] = globalThis[apiKey];
+          }
+          sendRenderPing(this.contentWindow);
+        }}
+      />
+    <//>`,
+    $button = html`<${Button}
+      onclick=${$modal.open}
+      notifications=${(await checkForUpdate()) ? 1 : 0}
+      themeOverridesLoaded=${await doThemeOverride(db)}
+      icon="notion-enhancer${menuButtonIconStyle === "Monochrome"
+        ? "?mask"
+        : " text-[16px]"}"
+      >notion-enhancer
+    <//>`;
+  document.body.append($modal);
+  addMutationListener(notionSidebar, () => {
+    if (document.contains($button)) return;
     document.querySelector(notionSidebar)?.append($button);
-    addMutationListener("body", sendThemePing);
-    window.addEventListener("focus", sendRenderPing);
+  });
+  document.querySelector(notionSidebar)?.append($button);
+  addMutationListener("body", sendThemePing);
+  window.addEventListener("focus", sendRenderPing);
 
-    addKeyListener(openMenuHotkey, (event) => {
-      event.preventDefault();
-      $modal.open();
-    });
-    window.addEventListener("message", (event) => {
-      if (event.data?.namespace !== "notion-enhancer") return;
-      if (event.data?.action === "close-menu") $modal.close();
-      if (event.data?.action === "open-menu") $modal.open();
-    });
-    onMessage("notion-enhancer", (message) => {
-      if (message === "open-menu") $modal.open();
-    });
-  },
-  sendTelemetryPing = async () => {
-    const { version } = globalThis.__enhancerApi,
-      db = globalThis.__enhancerApi.initDatabase(),
-      agreedToTerms = await db.get("agreedToTerms"),
-      telemetryEnabled = await db.get("telemetryEnabled");
-    if (!telemetryEnabled || agreedToTerms !== version) return;
-    // telemetry
-  };
+  addKeyListener(openMenuHotkey, (event) => {
+    event.preventDefault();
+    $modal.open();
+  });
+  window.addEventListener("message", (event) => {
+    if (event.data?.namespace !== "notion-enhancer") return;
+    if (event.data?.action === "close-menu") $modal.close();
+    if (event.data?.action === "open-menu") $modal.open();
+  });
+  onMessage("notion-enhancer", (message) => {
+    if (message === "open-menu") $modal.open();
+  });
+};
 
 export default async (api, db) => {
   await Promise.all([
diff --git a/src/core/menu/islands/Onboarding.mjs b/src/core/menu/islands/Onboarding.mjs
index fdf2574..83cd105 100644
--- a/src/core/menu/islands/Onboarding.mjs
+++ b/src/core/menu/islands/Onboarding.mjs
@@ -23,16 +23,23 @@ function Onboarding() {
       >Continue
     <//>`,
     $agreeToTerms = html`<div class="mt-[32px]">
+      <${Heading} class="mb-[8px]">
+        Thanks for installing the notion-enhancer!
+      <//>
       <${Description}>
-        Thanks for installing the notion-enhancer! It's been absolutely
-        incredible to see how the notion-enhancer has grown from small
-        beginnings to something used today by over 11,000 people around the
-        world, now including you. Before you begin, please read the privacy
-        policy to learn how the notion-enhancer uses your data and the terms &
-        conditions to understand what the notion-enhancer does and does not
-        offer. Ticking the box below and pressing <mark>Continue</mark> will
-        unlock the notion-enhancer's full functionality, accessible through the
-        sidebar.
+        In order for the notion-enhancer to function, it may access, collect,
+        process and/or store data on your device (including workspace content,
+        device metadata, and notion-enhancer configuration) according to its
+        privacy policy. Unless otherwise stated for telemetry purposes, the
+        notion-enhancer will never transmit any of your data from your device.
+        Telemetry can be disabled at any time through the menu.
+        <br />
+        <br />
+        The notion-enhancer is free and open-source software distributed under
+        the <a href="${tsAndCs}#license">MIT License</a> without warranty of any
+        kind. In no event shall the authors be liable for any consequences of
+        the software's use. Before continuing, you must read and agree to the
+        notion-enhancer's privacy policy and terms & conditions.
       <//>
       <div class="flex items-center my-[14px] gap-[8px]">
         <${Checkbox}
@@ -77,7 +84,7 @@ function Onboarding() {
     </div>`,
     $featuredSponsors = html`
       <div class="mt-[32px]">
-        <${Heading} class="mt-[32px] mb-[8px]">Featured Sponsors<//>
+        <${Heading} class="mb-[8px]">Featured Sponsors<//>
         <${Description}>
           A few awesome companies out there have teamed up with me to provide
           you with the notion-enhancer, free forever. Check them out!
diff --git a/src/core/menu/islands/Sidebar.mjs b/src/core/menu/islands/Sidebar.mjs
index 06b2d77..e99b1fb 100644
--- a/src/core/menu/islands/Sidebar.mjs
+++ b/src/core/menu/islands/Sidebar.mjs
@@ -53,7 +53,7 @@ function Sidebar({ items, categories }) {
   const { html, version } = globalThis.__enhancerApi,
     { initDatabase, isEnabled } = globalThis.__enhancerApi,
     $agreeToUnlock = html`<span
-      class="pt-[2px] pb-[5px] px-[15px]
+      class="pt-[2px] pb-[5px] px-[15px] text-[12px]
       inline-block text-[color:var(--theme--fg-red)]"
       >To unlock the notion-enhancer's full functionality, agree to the privacy
       policy and terms & conditions on the welcome page.
diff --git a/src/core/menu/islands/Telemetry.mjs b/src/core/menu/islands/Telemetry.mjs
index fa01c1e..531b603 100644
--- a/src/core/menu/islands/Telemetry.mjs
+++ b/src/core/menu/islands/Telemetry.mjs
@@ -4,26 +4,14 @@
  * (https://notion-enhancer.github.io/) under the MIT license
  */
 
+import { collectTelemetryData } from "../../telemetry.mjs";
 import { useState, setState } from "../state.mjs";
 import { Option } from "./Options.mjs";
 
 const privacyPolicy = "https://notion-enhancer.github.io/about/privacy-policy/";
 function Telemetry() {
-  const { html, platform, version } = globalThis.__enhancerApi,
-    { getMods, isEnabled, initDatabase } = globalThis.__enhancerApi,
-    timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
-
-  const $enabledMods = html`<code></code>`;
-  useState(["rerender"], async () => {
-    let enabledMods = [];
-    for (const mod of await getMods()) {
-      if (mod._src === "core") continue;
-      if (await isEnabled(mod.id)) enabledMods.push(mod.id);
-    }
-    $enabledMods.innerText = JSON.stringify(enabledMods);
-  });
-
-  const _get = async () => {
+  const { html, initDatabase } = globalThis.__enhancerApi,
+    _get = async () => {
       // defaults to true, must be explicitly set to false to disable
       return initDatabase().get("telemetryEnabled") ?? true;
     },
@@ -32,6 +20,19 @@ function Telemetry() {
       setState({ rerender: true });
     };
 
+  const $ = {
+    platform: html`<code></code>`,
+    version: html`<code></code>`,
+    timezone: html`<code></code>`,
+    enabledMods: html`<code></code>`,
+  };
+  useState(["rerender"], async () => {
+    const telemetryData = await collectTelemetryData();
+    for (const key in telemetryData) {
+      $[key].innerText = JSON.stringify(telemetryData[key]);
+    }
+  });
+
   // todo: actually collect telemetry
   return html`<${Option}
     type="toggle"
@@ -39,11 +40,10 @@ function Telemetry() {
     description=${html`If telemetry is enabled, usage data will be collected
       once a week from your device in order to better understand how and where
       the notion-enhancer is used. This data is anonymous and includes only your
-      platform (<code>"${platform}"</code>), timezone
-      (<code>"${timezone}"</code>), notion-enhancer version
-      (<code>"${version}"</code>), and enabled mods (${$enabledMods}). You can
-      opt in or out of telemetry at any time. This setting syncs across
-      configuration profiles. For more information, read the notion-enhancer's
+      platform (${$.platform}), notion-enhancer version (${$.version}), timezone
+      (${$.timezone}), and enabled mods (${$.enabledMods}). You can opt in or
+      out of telemetry at any time. This setting syncs across configuration
+      profiles. For more information, read the notion-enhancer's
       <a href=${privacyPolicy} class="ml-[3px]">privacy policy</a>.`}
     ...${{ _get, _set }}
   />`;
diff --git a/src/core/telemetry.mjs b/src/core/telemetry.mjs
new file mode 100644
index 0000000..c743965
--- /dev/null
+++ b/src/core/telemetry.mjs
@@ -0,0 +1,27 @@
+/**
+ * notion-enhancer
+ * (c) 2023 dragonwocky <thedragonring.bod@gmail.com> (https://dragonwocky.me/)
+ * (https://notion-enhancer.github.io/) under the MIT license
+ */
+
+const collectTelemetryData = async () => {
+    const { platform, version } = globalThis.__enhancerApi,
+      { getMods, isEnabled } = globalThis.__enhancerApi,
+      timezone = Intl.DateTimeFormat().resolvedOptions().timeZone,
+      // prettier-ignore
+      enabledMods = (await getMods(async (mod) => {
+        if (mod._src === "core") return false;
+        return await isEnabled(mod.id);
+      })).map(mod => mod.id);
+    return { platform, version, timezone, enabledMods };
+  },
+  sendTelemetryPing = async () => {
+    const db = globalThis.__enhancerApi.initDatabase(),
+      agreedToTerms = await db.get("agreedToTerms"),
+      telemetryEnabled = await db.get("telemetryEnabled");
+    if (!telemetryEnabled || agreedToTerms !== version) return;
+    // telemetry
+    const telemetryData = await collectTelemetryData();
+  };
+
+export { collectTelemetryData, sendTelemetryPing };
diff --git a/src/core/update.mjs b/src/core/update.mjs
index 9293207..e8d7e84 100644
--- a/src/core/update.mjs
+++ b/src/core/update.mjs
@@ -8,8 +8,11 @@ let _release;
 const repo = "notion-enhancer/notion-enhancer",
   endpoint = `https://api.github.com/repos/${repo}/releases/latest`,
   getRelease = async () => {
-    const { readJson } = globalThis.__enhancerApi;
-    _release ??= (await readJson(endpoint))?.tag_name.replace(/^v/, "");
+    const { version, readJson } = globalThis.__enhancerApi;
+    try {
+      _release ??= (await readJson(endpoint))?.tag_name.replace(/^v/, "");
+    } catch {}
+    _release ??= version;
     return _release;
   };
 
diff --git a/src/init.js b/src/init.js
index ab659e0..71ac398 100644
--- a/src/init.js
+++ b/src/init.js
@@ -45,7 +45,10 @@ if (isElectron()) {
       }
     }
   };
-
+} else {
   // clientStyles
   // clientScripts
-} else import("./api/browser.js").then(() => import("./load.mjs"));
+  import(chrome.runtime.getURL("/api/browser.js")).then(() => {
+    import(chrome.runtime.getURL("/load.mjs"));
+  });
+}
diff --git a/src/load.mjs b/src/load.mjs
index 3a48c4f..303e979 100644
--- a/src/load.mjs
+++ b/src/load.mjs
@@ -9,21 +9,21 @@
 export default (async () => {
   // prettier-ignore
   const { enhancerUrl } = globalThis.__enhancerApi,
-    isMenu = location.href.startsWith(enhancerUrl("/core/menu/index.html")),
+    isMenu = location.href.startsWith(enhancerUrl("core/menu/index.html")),
     pageLoaded = /(^\/$)|((-|\/)[0-9a-f]{32}((\?.+)|$))/.test(location.pathname),
     signedIn = localStorage["LRU:KeyValueStore2:current-user-id"];
   if (!isMenu && (!signedIn || !pageLoaded)) return;
   if (!isMenu) console.log("notion-enhancer: loading...");
 
   await Promise.all([
-    import("./assets/icons.svg.js"),
-    import("./vendor/twind.min.js"),
-    import("./vendor/lucide.min.js"),
-    import("./vendor/htm.min.js"),
-    import("./api/events.js"),
-    import("./api/mods.js"),
+    import(enhancerUrl("assets/icons.svg.js")),
+    import(enhancerUrl("vendor/twind.min.js")),
+    import(enhancerUrl("vendor/lucide.min.js")),
+    import(enhancerUrl("vendor/htm.min.js")),
+    import(enhancerUrl("api/events.js")),
+    import(enhancerUrl("api/mods.js")),
   ]);
-  await import("./api/interface.js");
+  await import(enhancerUrl("api/interface.js"));
   const { getMods, isEnabled, modDatabase } = globalThis.__enhancerApi;
 
   for (const mod of await getMods()) {
diff --git a/src/manifest.json b/src/manifest.json
index ade0312..b6875ae 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -7,7 +7,6 @@
   "homepage_url": "https://notion-enhancer.github.io",
   "content_scripts": [{ "matches": ["*://*.notion.so/*"], "js": ["/init.js"] }],
   "background": { "service_worker": "/worker.js" },
-  "options_page": "/core/menu/index.html",
   "action": {},
   "icons": {
     "16": "/assets/colour-x16.png",