diff --git a/apps/widget-discord/src/App.tsx b/apps/widget-discord/src/App.tsx
index 55ee2258..ebd1cb1e 100644
--- a/apps/widget-discord/src/App.tsx
+++ b/apps/widget-discord/src/App.tsx
@@ -95,6 +95,18 @@ const LinkIcon = () => (
);
+// 2×2 grid of rounded squares — leads the OpenSpaceCard. Reads as
+// «space with channels inside»; consistent visual vocabulary with the
+// channels-tab workspace grid affordances on the host side.
+const SpaceGridIcon = () => (
+
+);
+
// Linkifier — same heuristic as TG widget.
const URL_RE = /https?:\/\/[^\s)]+/g;
@@ -388,6 +400,13 @@ const loadHCaptcha = (): Promise => {
`script[src^="https://js.hcaptcha.com/1/api.js"]`
) as HTMLScriptElement | null;
+ // `timeoutHandle` is read in the `settle` closure declared below
+ // BEFORE the assignment at the bottom of this function. ESLint's
+ // flow analysis can't see the deferred assignment through the
+ // closure and flags this as never-reassigned; in practice the value
+ // IS reassigned and using `const` here would break the hcaptcha
+ // script-load timeout path.
+ // eslint-disable-next-line prefer-const
let timeoutHandle: number | undefined;
let settled = false;
const settle = (action: () => void) => {
@@ -599,9 +618,7 @@ const CaptchaPanel = ({ state, t, onSolved, onCancel, onExpired }: CaptchaPanelP