@the-portland-company/shell 0.76.18 → 0.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/app-chrome.cjs +3 -184
- package/dist/app-chrome.cjs.map +1 -1
- package/dist/app-chrome.d.cts +2 -2
- package/dist/app-chrome.d.ts +2 -2
- package/dist/app-chrome.js +4 -3
- package/dist/app-chrome.js.map +1 -1
- package/package.json +1 -1
package/dist/app-chrome.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/topbarIconSlot.ts","../src/lib/brandGlyphs.tsx","../src/lib/deprecation.ts","../src/native/orgFilter.ts","../src/active-org.ts","../src/nav-preference.ts","../src/speculation/emitRules.ts","../src/speculation/SpeculationRulesScript.tsx","../src/notifications/adapter.ts","../src/theme-preference.ts","../src/native/chromeActions.tsx","../src/native/standardNavIcons.ts","../src/native/standardNav.ts","../src/native/index.tsx","../src/lib/breadcrumbs.ts","../src/lib/identity.ts","../src/logout-signal.ts","../src/mode-preference.ts","../src/app-chrome/loading-screen.tsx","../src/lib/brandAssets.ts","../src/app-chrome/frame.tsx","../src/app-chrome/index.tsx"],"names":["useState","useEffect","FiBatteryCharging","FiBattery","FiZap","FiGrid","FiBell","FiAlertTriangle","FiAlertCircle","FiLifeBuoy","FiHelpCircle","FiMoon","FiSun","FiInfo","FiMail","FiMessageSquare","FiSettings","FiUser","useMemo","VALID","useSyncExternalStore","jsxs","jsx","createContext","useRef","useContext","Fragment","lowFuelHintVisible","useCallback","createPortal","LuHouse","LuUsers","LuMail","LuMessageSquare","LuLayoutDashboard","LuActivity","LuLifeBuoy","LuLayoutGrid","LuList","LuUpload","LuPencil","LuFileText","LuSend","LuClock","LuUser","LuChartColumn","LuBriefcase","LuSettings","LuCreditCard","LuDollarSign","LuShare2","LuPhone","LuMap","LuMapPin","LuTarget","LuFlag","LuUsersRound","LuMousePointerClick","LuClipboardList","LuCircleUser","LuCrosshair","LuLandmark","LuChartNoAxesColumn","LuDoorOpen","LuSignpost","clsx","trail","pathname","createDevNotesClient","DevNotesProvider","DevNotesTaskListModal","DevNotesOverlay","DevNotesMenu","LuNotebookPen","LuContactRound","LuMegaphone","LuFilePenLine"],"mappings":"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","file":"app-chrome.cjs","sourcesContent":["import { useEffect, useState } from 'react'\n\n/**\n * The six canonical top-bar action slots (Reference/Global-Rules v9 → top-bar\n * icons). Each slot's GLYPH is unique and comes from the Brand API\n * `topbarIcons.items.*` tokens, exposed as `--topbar-icon-<slot>` CSS vars\n * whose value is the brand-icon NAME. Every OTHER property — size, gap, color,\n * hover, selected — is universal across all six slots.\n */\nexport type TopBarIconSlot =\n | 'comms-fuel'\n | 'apps'\n | 'notifications'\n | 'alerts'\n | 'support'\n | 'dark-mode'\n\n/**\n * Reads the glyph NAME for a slot from its `--topbar-icon-<slot>` CSS var.\n *\n * Runs in an effect because the Brand stylesheet is appended to <head> at\n * runtime (Global Rules forbids baking it into the build), so the var is not\n * resolvable during SSR or the first synchronous render. The MutationObserver\n * re-reads once the stylesheet lands so the glyph upgrades from the caller's\n * fallback without a reload.\n *\n * Returns null when the slot has no Brand glyph — callers render their own\n * fallback icon in that case.\n */\nexport function useTopBarIconSlotGlyph(slot: TopBarIconSlot): string | null {\n const [name, setName] = useState<string | null>(null)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const read = () => {\n const raw = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(`--topbar-icon-${slot}`)\n .trim()\n // Brand may emit the name quoted (e.g. \"bell\"); strip the quotes.\n .replace(/^['\"]|['\"]$/g, '')\n setName(raw.length > 0 ? raw : null)\n }\n\n read()\n\n const observer = new MutationObserver(read)\n observer.observe(document.head, { childList: true, subtree: true })\n return () => observer.disconnect()\n }, [slot])\n\n return name\n}\n\n/** Path to a brand-icon SVG in the consuming app's public dir. */\nexport function brandIconSrc(name: string, basePath = '/brand/icons/') {\n return `${basePath}${name}.svg`\n}\n","import type { ComponentType } from 'react'\nimport {\n FiAlertCircle,\n FiBattery,\n FiBatteryCharging,\n FiAlertTriangle,\n FiBell,\n FiGrid,\n FiHelpCircle,\n FiInfo,\n FiLifeBuoy,\n FiMail,\n FiMessageSquare,\n FiMoon,\n FiSettings,\n FiSun,\n FiUser,\n FiZap,\n} from 'react-icons/fi'\n\nexport type GlyphComponent = ComponentType<{ size?: number | string; className?: string }>\n\n/**\n * Brand-glyph registry: maps the icon NAME the Brand API emits (e.g.\n * `--topbar-icon-comms-fuel: bolt`) to a component.\n *\n * These names are Feather/Lucide icon names, NOT asset filenames — there is no\n * `/brand/icons/<name>.svg` for them in any app, and treating them as URLs\n * renders a broken image. Resolving them against the icon library the shell\n * already depends on keeps every app consistent with zero vendored assets.\n *\n * Aliases are included where Brand and Feather disagree on a name (`bolt` vs\n * `zap`, `life-buoy` vs `life-ring`).\n */\nconst GLYPHS: Record<string, GlyphComponent> = {\n // Communications Fuel reads as a LEVEL, so its glyph is a battery. `bolt`/\n // `zap` stay mapped for older Brand values.\n 'battery-charging': FiBatteryCharging,\n battery: FiBattery,\n fuel: FiBatteryCharging,\n bolt: FiZap,\n zap: FiZap,\n grid: FiGrid,\n apps: FiGrid,\n bell: FiBell,\n notification: FiBell,\n 'alert-triangle': FiAlertTriangle,\n alert: FiAlertTriangle,\n 'alert-circle': FiAlertCircle,\n 'life-buoy': FiLifeBuoy,\n 'life-ring': FiLifeBuoy,\n support: FiLifeBuoy,\n 'help-circle': FiHelpCircle,\n moon: FiMoon,\n sun: FiSun,\n info: FiInfo,\n mail: FiMail,\n 'message-square': FiMessageSquare,\n settings: FiSettings,\n user: FiUser,\n}\n\n/**\n * Resolve a Brand glyph name to a component. Returns null for an unknown name\n * so the caller renders its own fallback — an unrecognized token must never\n * produce a broken or empty icon.\n */\nexport function resolveBrandGlyph(name: string | null | undefined): GlyphComponent | null {\n if (!name) return null\n return GLYPHS[name.trim().toLowerCase()] ?? null\n}\n\n/** Names the registry knows — exported for tests and tooling. */\nexport const KNOWN_BRAND_GLYPHS = Object.keys(GLYPHS)\n","// One-time console warnings for retired shell API, in development only.\n\nconst warned = new Set<string>()\n\nfunction isDev(): boolean {\n try {\n return typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n } catch {\n return false\n }\n}\n\n/** Warn once per `key` in dev; silent in production builds. */\nexport function warnDeprecated(key: string, message: string): void {\n if (!isDev() || warned.has(key)) return\n warned.add(key)\n console.warn(`[@the-portland-company/shell] ${message}`)\n}\n\n/** Test hook: forget which warnings have fired. */\nexport function resetDeprecationWarnings(): void {\n warned.clear()\n}\n","/**\n * Organization-list filtering for the sidebar org selector.\n *\n * Accounts that belong to many organizations (a consultant managing a dozen\n * committees) got a 288 px panel showing seven rows and a near-invisible macOS\n * scrollbar — measured 2026-09-04: \"I cannot select other organizations\".\n * The panel now grows with the viewport and, above this threshold, gains a\n * type-to-filter box so any org is one keystroke away.\n */\nexport const ORG_FILTER_THRESHOLD = 8\n\nexport type FilterableOrg = { id: string; name: string | null }\n\n/** Case- and accent-insensitive substring match on the org name (or id prefix). */\nexport function filterOrgs<T extends FilterableOrg>(orgs: readonly T[], query: string): T[] {\n const q = normalize(query)\n if (!q) return [...orgs]\n return orgs.filter((o) => normalize(o.name ?? '').includes(q) || o.id.toLowerCase().startsWith(q))\n}\n\nexport function shouldShowOrgFilter(count: number): boolean {\n return count > ORG_FILTER_THRESHOLD\n}\n\nfunction normalize(s: string): string {\n return s\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .trim()\n}\n","// Universal active-organization selection — the ONE cross-app contract.\n//\n// A user belongs to many orgs; ONE active-org choice must follow them across\n// every Politogy app + subdomain so all apps resolve the SAME org (and campaign\n// apps don't land on a rel-only org and lock themselves). Layers cooperate,\n// mirroring the theme-preference contract:\n// 1. URL `?org=<uuid>` — the authoritative per-request selector. The shared\n// chrome stamps it onto every route so it is bookmarkable + shareable, and\n// each app forwards it to the chrome API as `x-contacts-org`.\n// 2. `.politogyvrm.com` cookie `politogy_active_org` — cross-subdomain vehicle\n// (auth session cookies are host-only) that remembers the LAST USED org so\n// a bare URL in the next app opens on the same org.\n//\n// The stored/most-authoritative value is the FULL org UUID: contacts-api\n// (auth/vrmMembership.selectRequestedMembership) matches the selector by EXACT\n// id first, then falls back to a short suffix that can COLLIDE across a user's\n// orgs — so the full UUID is the only collision-free selector.\n//\n// Server-safe (no 'use client'): constants/resolve helpers are importable from\n// server layouts; the cookie read/write helpers no-op on the server.\n\nexport const ACTIVE_ORG_COOKIE = 'politogy_active_org'\nexport const ACTIVE_ORG_QUERY_PARAM = 'org'\n\n// Loose UUID shape check — we only ever store ids that came from the user's own\n// authoritative membership list, so this just rejects obvious garbage.\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nexport function isOrgId(v: unknown): v is string {\n return typeof v === 'string' && UUID_RE.test(v.trim())\n}\n\n/**\n * Read the shared active-org cookie (browser only; null on server or unset).\n * @deprecated v2 apps read the org from the token claims (`orgClaimsFromToken`).\n * The cookie stays written during rollout for apps not yet on the token path.\n */\nexport function readActiveOrgCookie(): string | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${ACTIVE_ORG_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isOrgId(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Write the cross-subdomain cookie with the SAME scoping rules as the theme\n// cookie: on a *.politogyvrm.com host scope to the parent domain so every app\n// subdomain reads it; on any other host (localhost, *.pages.dev preview) fall\n// back to a host-only cookie. 1-year, SameSite=Lax, Secure on https.\nexport function writeActiveOrgCookie(orgId: string): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n if (!isOrgId(orgId)) return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${ACTIVE_ORG_COOKIE}=${encodeURIComponent(\n orgId,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/**\n * Read the `?org=` selector from a URL search string (full UUID only). Accepts a\n * `location.search`-style string or a full URL.\n */\nexport function readActiveOrgFromUrl(search: string | null | undefined): string | null {\n if (!search) return null\n try {\n const qs = search.includes('?') ? search.slice(search.indexOf('?') + 1) : search\n const v = new URLSearchParams(qs).get(ACTIVE_ORG_QUERY_PARAM)\n return isOrgId(v) ? v : null\n } catch {\n return null\n }\n}\n\n/**\n * Resolve the active org with the cross-app precedence:\n * 1. `?org=<uuid>` in the current URL (explicit per-request selector)\n * 2. the `.politogyvrm.com` cookie (last used, cross-subdomain)\n * 3. null → let the app fall back to the chrome-API default (earliest-joined)\n * Pass `search` on the server (from the request URL); it defaults to\n * `window.location.search` in the browser.\n * @deprecated v2 apps use the token `org_id` claim plus `readOrgSelectorFromUrl`\n * as a per-tab override only.\n */\nexport function resolveActiveOrg(search?: string | null): string | null {\n const fromUrl = readActiveOrgFromUrl(\n search ?? (typeof window !== 'undefined' ? window.location.search : null),\n )\n if (fromUrl) return fromUrl\n return readActiveOrgCookie()\n}\n\n/** The canonical `?org=` query fragment for a full org id (no leading `?`/`&`). */\nexport function activeOrgParam(orgId: string | null | undefined): string {\n return isOrgId(orgId) ? `${ACTIVE_ORG_QUERY_PARAM}=${orgId}` : ''\n}\n\n/**\n * Return `url` with `?org=<uuid>` set/replaced. Used by the shared chrome to\n * stamp the active org onto every route so it is always present in the address\n * bar. Leaves the URL unchanged when `orgId` is not a valid id.\n */\nexport function withActiveOrgParam(url: string, orgId: string | null | undefined): string {\n if (!isOrgId(orgId)) return url\n try {\n // Support both absolute and relative URLs.\n const base = typeof window !== 'undefined' ? window.location.origin : 'https://politogyvrm.com'\n const u = new URL(url, base)\n u.searchParams.set(ACTIVE_ORG_QUERY_PARAM, orgId as string)\n // Preserve relative form when the input was relative.\n return /^https?:\\/\\//i.test(url) ? u.toString() : `${u.pathname}${u.search}${u.hash}`\n } catch {\n return url\n }\n}\n\n// ---------------------------------------------------------------------------\n// v2: auth-owned active org (Global-Rules v38 \"Auth / Active Organization\",\n// UI-Platform v46 \"URL state\"). The IdP owns the shared active org on the SSO\n// session; tokens carry `org_id` (full uuid) + `org_role`. The URL carries the\n// 7-char `org_id` tail as a PER-TAB override only: it never changes the shared\n// active org. Full uuids and the legacy 6-char tail are accepted during rollout.\n// ---------------------------------------------------------------------------\n\nexport const ORG_ID_QUERY_PARAM = 'org_id'\nexport const ORG_ID_TAIL_LENGTH = 7\nconst LEGACY_ORG_TAIL_LENGTH = 6\nconst TAIL_RE = /^[0-9a-f]{6,7}$/i\n\nconst AUTH_BASE_URL = 'https://auth.politogyvrm.com'\nconst AUTH_BASE_URL_STAGING = 'https://auth-staging.politogyvrm.com'\n\n/** The URL form of an org id: the last 7 chars of the uuid, lower case. */\nexport function orgIdTail(orgId: string | null | undefined): string | null {\n return isOrgId(orgId) ? (orgId as string).trim().toLowerCase().slice(-ORG_ID_TAIL_LENGTH) : null\n}\n\n/** A full uuid, the 7-char tail, or the legacy 6-char tail. */\nexport function isOrgSelector(v: unknown): v is string {\n return typeof v === 'string' && (UUID_RE.test(v.trim()) || TAIL_RE.test(v.trim()))\n}\n\n/**\n * Resolve a selector against the user's own org list: exact uuid first, then a\n * unique 7-char tail, then a unique 6-char tail. Ambiguous or no match → null\n * (the IdP selector rules, so the shell never picks an org the IdP would not).\n */\nexport function matchOrgSelector<T extends { id: string }>(\n selector: string | null | undefined,\n orgs: readonly T[],\n): T | null {\n if (!isOrgSelector(selector)) return null\n const sel = selector.trim().toLowerCase()\n if (UUID_RE.test(sel)) return orgs.find((o) => o.id.toLowerCase() === sel) ?? null\n if (sel.length !== ORG_ID_TAIL_LENGTH && sel.length !== LEGACY_ORG_TAIL_LENGTH) return null\n const hits = orgs.filter((o) => o.id.toLowerCase().endsWith(sel))\n return hits.length === 1 ? hits[0] : null\n}\n\n/**\n * Read the per-tab org override from a URL: `org_id` (spec), else the legacy\n * `org`. Returns the raw selector (uuid or tail), or null. Never a source for\n * the shared active org.\n */\nexport function readOrgSelectorFromUrl(search: string | null | undefined): string | null {\n if (!search) return null\n try {\n const qs = search.includes('?') ? search.slice(search.indexOf('?') + 1) : search\n const params = new URLSearchParams(qs)\n for (const key of [ORG_ID_QUERY_PARAM, ACTIVE_ORG_QUERY_PARAM]) {\n const v = params.get(key)\n if (isOrgSelector(v)) return v.trim().toLowerCase()\n }\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Return `url` with `org_id=<7-char tail>` set and any legacy `org=` removed.\n * Leaves the URL unchanged when `orgId` is not a full uuid.\n */\nexport function withOrgIdParam(url: string, orgId: string | null | undefined): string {\n const tail = orgIdTail(orgId)\n if (!tail) return url\n try {\n const base = typeof window !== 'undefined' ? window.location.origin : 'https://politogyvrm.com'\n const u = new URL(url, base)\n u.searchParams.delete(ACTIVE_ORG_QUERY_PARAM)\n u.searchParams.set(ORG_ID_QUERY_PARAM, tail)\n return /^https?:\\/\\//i.test(url) ? u.toString() : `${u.pathname}${u.search}${u.hash}`\n } catch {\n return url\n }\n}\n\nexport type OrgClaims = { orgId: string; orgRole: string | null }\n\n/** Pick `org_id` / `org_role` out of a token claim set. */\nexport function orgClaimsFrom(claims: unknown): OrgClaims | null {\n if (!claims || typeof claims !== 'object') return null\n const c = claims as { org_id?: unknown; org_role?: unknown }\n if (!isOrgId(c.org_id)) return null\n return {\n orgId: (c.org_id as string).trim().toLowerCase(),\n orgRole: typeof c.org_role === 'string' ? c.org_role : null,\n }\n}\n\n/**\n * Read `org_id` / `org_role` from a JWT payload WITHOUT verifying it. For\n * display and routing only: the app server verifies the token (JWKS) and every\n * authorization decision keys on the verified claim, never on this.\n */\nexport function orgClaimsFromToken(token: string | null | undefined): OrgClaims | null {\n if (typeof token !== 'string') return null\n const part = token.split('.')[1]\n if (!part) return null\n try {\n const b64 = part.replace(/-/g, '+').replace(/_/g, '/')\n const padded = b64 + '='.repeat((4 - (b64.length % 4)) % 4)\n const json =\n typeof atob === 'function'\n ? decodeURIComponent(\n Array.from(atob(padded), (ch) => '%' + ch.charCodeAt(0).toString(16).padStart(2, '0')).join(''),\n )\n : ''\n return orgClaimsFrom(JSON.parse(json))\n } catch {\n return null\n }\n}\n\n/** The IdP base for the current environment (staging host → staging IdP). */\nexport function authBaseUrl(): string {\n if (typeof window !== 'undefined' && window.location.hostname.toLowerCase().includes('staging')) {\n return AUTH_BASE_URL_STAGING\n }\n return AUTH_BASE_URL\n}\n\nexport class ActiveOrgSwitchError extends Error {\n constructor(\n readonly status: number,\n message: string,\n ) {\n super(message)\n this.name = 'ActiveOrgSwitchError'\n }\n}\n\n/**\n * Switch the SHARED active org on the IdP: `POST {auth}/api/active-org`. The\n * IdP checks membership against VRM Core and updates the SSO session; the\n * caller then re-exchanges (server) for tokens carrying the new `org_id`.\n * Also mirrors the legacy cookie so apps not yet on v2 follow the switch.\n * Throws `ActiveOrgSwitchError` (403 = not a member, 401 = no SSO session).\n */\nexport async function switchActiveOrg(\n orgId: string,\n opts: { authBaseUrl?: string; fetch?: typeof fetch } = {},\n): Promise<OrgClaims> {\n if (!isOrgId(orgId)) throw new ActiveOrgSwitchError(400, 'org_id must be a full uuid')\n const doFetch = opts.fetch ?? fetch\n const res = await doFetch(`${opts.authBaseUrl ?? authBaseUrl()}/api/active-org`, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ org_id: orgId }),\n })\n if (!res.ok) {\n let msg = `active-org switch failed (${res.status})`\n try {\n const body = (await res.json()) as { error?: string }\n if (body?.error) msg = body.error\n } catch {\n /* no body */\n }\n throw new ActiveOrgSwitchError(res.status, msg)\n }\n const claims = orgClaimsFrom(await res.json().catch(() => null))\n if (!claims) throw new ActiveOrgSwitchError(502, 'active-org switch returned no org_id')\n writeActiveOrgCookie(claims.orgId)\n return claims\n}\n\n/**\n * URL-sync rule for the address-bar org selector. Returns the new href, or\n * null when nothing should be written. A bare URL (no `org_id`, no legacy\n * `org`) stays bare: the shell must never inject `org_id` on its own, because\n * a self-injected selector then acts as a per-tab override and beats the token\n * org and the cross-app `politogy_active_org` trigger. Only a selector the user\n * brought (or a real switch put there) is canonicalized to the current org.\n */\nexport function syncOrgIdInUrl(href: string, orgId: string | null | undefined): string | null {\n const tail = orgIdTail(orgId)\n if (!tail) return null\n let u: URL\n try {\n u = new URL(href)\n } catch {\n return null\n }\n const hasLegacy = u.searchParams.has(ACTIVE_ORG_QUERY_PARAM)\n const current = u.searchParams.get(ORG_ID_QUERY_PARAM)\n if (!hasLegacy && current === null) return null\n if (!hasLegacy && current === tail) return null\n u.searchParams.delete(ACTIVE_ORG_QUERY_PARAM)\n u.searchParams.set(ORG_ID_QUERY_PARAM, tail)\n return u.toString()\n}\n","// Universal navigation-display preference — the same cross-app contract as the\n// theme (see ./theme-preference, which this deliberately mirrors).\n//\n// The user's choice of how navigation renders (Menu / Tabs / Both) follows the\n// authenticated user across every Politogy app + subdomain. Three layers:\n// 1. VRM Core `profiles.nav_display_preference` — source of truth, persisted\n// via the chrome API (`PATCH me/preferences { navDisplay }`) and read back\n// from `GET me` (`navDisplay`).\n// 2. `.politogyvrm.com` cookie `politogy_nav_display` — the cross-subdomain\n// vehicle (app session cookies are host-only, and so is localStorage).\n// 3. localStorage — same-app fast reads and cross-tab `storage` events.\n//\n// Before this existed the preference lived ONLY in localStorage under\n// `vrm.navDisplay`, which is per-ORIGIN: every app subdomain kept its own copy\n// and a freshly opened app booted the default, so the setting appeared not to\n// hold when moving between apps. The legacy key is still read as a fallback so\n// an existing local choice survives the upgrade.\n//\n// Server-safe (no 'use client'): layouts may import NAV_DISPLAY_PREPAINT_SCRIPT.\n\nexport type NavDisplayPreference = 'menu' | 'tabs' | 'both'\n\n// One key for BOTH the localStorage store and the cross-subdomain cookie, so a\n// choice in one app is the same key in the next.\nexport const NAV_DISPLAY_STORAGE_KEY = 'politogy_nav_display'\nexport const NAV_DISPLAY_COOKIE = 'politogy_nav_display'\n\n/** Pre-0.37 host-only key. Read for migration; never written. */\nexport const LEGACY_NAV_DISPLAY_KEY = 'vrm.navDisplay'\n\nexport const NAV_DISPLAY_DEFAULT: NavDisplayPreference = 'both'\n\nconst VALID: readonly NavDisplayPreference[] = ['menu', 'tabs', 'both']\n\nexport function isNavDisplayPreference(v: unknown): v is NavDisplayPreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readNavDisplayCookie(): NavDisplayPreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isNavDisplayPreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Same host-aware scoping as the theme cookie: parent domain on\n// *.politogyvrm.com so every app subdomain reads it, host-only elsewhere\n// (localhost, *.pages.dev preview) because browsers silently drop a mismatched\n// Domain attribute. 1-year, SameSite=Lax, Secure on https.\nexport function writeNavDisplayCookie(pref: NavDisplayPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/** Read the local store, falling back to the legacy host-only key. */\nexport function readNavDisplayLocal(): NavDisplayPreference | null {\n if (typeof localStorage === 'undefined') return null\n try {\n const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY)\n if (isNavDisplayPreference(current)) return current\n const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY)\n return isNavDisplayPreference(legacy) ? legacy : null\n } catch {\n return null\n }\n}\n\nexport function writeNavDisplayLocal(pref: NavDisplayPreference): void {\n if (typeof localStorage === 'undefined') return\n try {\n localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n\n/** Boot precedence: cookie → localStorage (incl. legacy) → default. */\nexport function resolveNavDisplay(): NavDisplayPreference {\n return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT\n}\n\n// Inline pre-paint script — optional, and the mirror of THEME_PREPAINT_SCRIPT.\n// Nav display has no paint-blocking visual (the frame is client-rendered), but\n// seeding localStorage from the cookie before hydration keeps the first render\n// on the synced value instead of the default. Self-contained and silent.\nexport const NAV_DISPLAY_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};\nvar VALID=[\"menu\",\"tabs\",\"both\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nif(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nif(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}\n}catch(e){}})();`\n\n// ---------------------------------------------------------------------------\n// Rail expand preference — Left-Navigation §11.6: below `md` the rail\n// collapses to the 64px icon rail; \"the user can also collapse and expand it;\n// the choice is remembered per user\". Same cookie + localStorage layers as the\n// nav-display preference above (no server column yet), so the choice follows\n// the user across every app subdomain and survives reloads. Only an explicit\n// Expand / Collapse writes it; a route change that closes the overlay does not.\n// ---------------------------------------------------------------------------\n\nexport type RailPreference = 'expanded' | 'collapsed'\n\nexport const RAIL_STORAGE_KEY = 'politogy_rail'\nexport const RAIL_COOKIE = 'politogy_rail'\nexport const RAIL_DEFAULT: RailPreference = 'collapsed'\n\nexport function isRailPreference(v: unknown): v is RailPreference {\n return v === 'expanded' || v === 'collapsed'\n}\n\nexport function readRailPreference(): RailPreference {\n if (typeof document !== 'undefined') {\n try {\n const m = document.cookie.match(new RegExp(`(?:^|;\\\\s*)${RAIL_COOKIE}=([^;]+)`))\n const v = m ? decodeURIComponent(m[1]) : null\n if (isRailPreference(v)) return v\n } catch {\n /* ignore */\n }\n }\n if (typeof localStorage !== 'undefined') {\n try {\n const v = localStorage.getItem(RAIL_STORAGE_KEY)\n if (isRailPreference(v)) return v\n } catch {\n /* ignore */\n }\n }\n return RAIL_DEFAULT\n}\n\nexport function writeRailPreference(pref: RailPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n try {\n document.cookie = `${RAIL_COOKIE}=${pref}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n } catch {\n /* ignore */\n }\n try {\n localStorage.setItem(RAIL_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n","import type { AppRegistryEntry } from '../types'\nimport type { NavItem } from '../native/index'\n\n/**\n * Build a Speculation Rules JSON payload that prerenders other apps in the\n * registry on moderate eagerness. Returns null when there are no eligible\n * other apps to prerender (e.g., this is the only app in the registry).\n *\n * @deprecated Legacy `AppRegistryEntry[]`-based registry is unused by any\n * current consumer. Cross-app sidebar nav now ships real `NavItem[]` trees\n * (`standardPolitogyNav`) — use `buildNavSpeculationRules` instead, which this\n * now delegates to.\n *\n * The host app is expected to render this as\n * `<script type=\"speculationrules\">{json}</script>` in <head> at runtime.\n */\nexport function buildSpeculationRules(\n currentApp: string,\n registry: AppRegistryEntry[],\n): string | null {\n const others = registry.filter(\n (entry) => entry.id !== currentApp && entry.visible !== false,\n )\n if (others.length === 0) return null\n const payload = {\n prerender: [\n {\n urls: others.map((entry) => entry.path),\n eagerness: 'moderate' as const,\n },\n ],\n }\n return JSON.stringify(payload)\n}\n\n/**\n * Labels the shell will never prerender or prefetch, even if a consumer's nav\n * tree somehow carries an `href` for them (sign-out is normally a footer\n * `onClick`, never a `NavItem.href` — this is a second guard, not the primary\n * one). Case-insensitive substring match against the row's label.\n */\nconst DESTRUCTIVE_LABEL_PATTERNS = ['sign out', 'signout', 'log out', 'logout', 'delete']\n\n/** URL substrings that mark a link as destructive/non-idempotent regardless of label. */\nconst DESTRUCTIVE_PATH_PATTERNS = ['/signout', '/sign-out', '/logout', '/log-out']\n\nfunction isDestructive(item: { label: string; href?: string }): boolean {\n const label = item.label.toLowerCase()\n if (DESTRUCTIVE_LABEL_PATTERNS.some((p) => label.includes(p))) return true\n const href = (item.href ?? '').toLowerCase()\n return DESTRUCTIVE_PATH_PATTERNS.some((p) => href.includes(p))\n}\n\n/**\n * Walk a `NavItem[]` tree (as produced by `standardPolitogyNav`) and collect\n * every absolute, cross-origin, non-destructive, GET-safe link — the\n * candidate set for prerender/prefetch. Sections and action rows (`onClick`,\n * no `href`) are skipped; children are walked too (sub-menu rows like\n * \"Command Center\" / \"New Poll\" are real cross-app destinations).\n */\nexport function collectSiblingAppUrls(items: NavItem[], currentOrigin: string): string[] {\n const urls = new Set<string>()\n const walk = (list: NavItem[]) => {\n for (const item of list) {\n if (item.kind === 'section') continue\n if (item.href && !isDestructive(item)) {\n try {\n const url = new URL(item.href, currentOrigin)\n if (url.origin !== currentOrigin && /^https?:$/.test(url.protocol)) {\n urls.add(url.href)\n }\n } catch {\n // Malformed href — skip rather than throw during nav render.\n }\n }\n if (item.children?.length) walk(item.children)\n }\n }\n walk(items)\n return Array.from(urls)\n}\n\nexport interface NavSpeculationRules {\n prerender: [{ source: 'list'; urls: string[]; eagerness: 'moderate' }]\n}\n\n/**\n * Build the Speculation Rules payload for a consumer's real sidebar nav tree:\n * every sibling `*.politogyvrm.com` app link, `eagerness: \"moderate\"` (the\n * browser's own heuristic — prerender starts on hover/pointerdown of a\n * matching `<a>`, not on page load). Sign-out and other destructive rows are\n * excluded by `collectSiblingAppUrls`. Returns `null` when there is nothing\n * to speculate on (e.g., an empty or single-app tree).\n *\n * Each target origin must opt in by sending\n * `Supports-Loading-Mode: credentialed-prerender` on its responses, per the\n * Speculation Rules cross-origin prerender contract — without it the browser\n * silently falls back to a normal navigation. (Other apps are adding this\n * header separately.)\n */\nexport function buildNavSpeculationRules(\n items: NavItem[],\n currentOrigin: string = typeof window !== 'undefined' ? window.location.origin : '',\n): NavSpeculationRules | null {\n const urls = collectSiblingAppUrls(items, currentOrigin)\n if (urls.length === 0) return null\n return {\n prerender: [{ source: 'list', urls, eagerness: 'moderate' }],\n }\n}\n","import { useEffect, useMemo } from 'react'\nimport type { NavItem } from '../native/index'\nimport { buildNavSpeculationRules, collectSiblingAppUrls } from './emitRules'\n\nconst SCRIPT_ID = 'politogy-speculation-rules'\nconst PREFETCH_ATTR = 'data-politogy-speculation-prefetch'\n\n/**\n * Renders the cross-app Speculation Rules `<script>` for the current\n * consumer's sidebar nav tree, and mounts in every `NavAppShell` — so it is\n * never an opt-in an app has to remember. Browsers that support Speculation\n * Rules prerender a sibling `*.politogyvrm.com` app the moment the user\n * hovers or pointers-down on its sidebar link (`eagerness: \"moderate\"`);\n * browsers that don't fall back, after the page goes idle, to plain\n * `<link rel=\"prefetch\">` tags for the same URLs, so the next click is still\n * warmed by a DNS/TLS/HTML fetch even without a prerendered document.\n *\n * Each sibling origin must send `Supports-Loading-Mode:\n * credentialed-prerender` on its responses for the prerender to actually\n * happen while the user is authenticated (cross-origin prerender is opt-in\n * on the destination). Without it, browsers degrade this to a normal\n * navigation — the hover/click still works, it's just not pre-warmed.\n *\n * Renders nothing visible; this is a side-effecting `<script>` injector.\n */\nexport function SpeculationRulesScript({ items }: { items: NavItem[] }) {\n const origin = typeof window !== 'undefined' ? window.location.origin : ''\n const rules = useMemo(() => buildNavSpeculationRules(items, origin), [items, origin])\n const json = rules ? JSON.stringify(rules) : null\n\n // Native Speculation Rules — covers the hover/pointerdown prerender case in\n // supporting browsers (Chromium). Declarative: no listeners needed, the\n // browser applies its own \"moderate\" heuristic to matching <a> elements.\n useEffect(() => {\n if (!json || typeof document === 'undefined') return\n let el = document.getElementById(SCRIPT_ID) as HTMLScriptElement | null\n if (!el) {\n el = document.createElement('script')\n el.id = SCRIPT_ID\n el.type = 'speculationrules'\n document.head.appendChild(el)\n }\n el.textContent = json\n return () => {\n // Leave the tag in place across route changes within the same app —\n // only strip it if this effect instance's app unmounts entirely with no\n // sibling to replace it.\n }\n }, [json])\n\n // Idle-prefetch fallback for browsers without Speculation Rules support\n // (or where the destination hasn't sent the opt-in header): warm the\n // connection/document via <link rel=\"prefetch\"> once the main thread is\n // idle, so it never competes with first-paint work.\n useEffect(() => {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const supportsSpecRules =\n typeof HTMLScriptElement !== 'undefined' &&\n typeof (HTMLScriptElement as unknown as { supports?: (t: string) => boolean }).supports ===\n 'function' &&\n (HTMLScriptElement as unknown as { supports: (t: string) => boolean }).supports(\n 'speculationrules',\n )\n if (supportsSpecRules) return\n const urls = collectSiblingAppUrls(items, origin)\n if (urls.length === 0) return\n\n const schedule: (cb: () => void) => void =\n typeof (window as unknown as { requestIdleCallback?: (cb: () => void) => void })\n .requestIdleCallback === 'function'\n ? (window as unknown as { requestIdleCallback: (cb: () => void) => void })\n .requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 2000)\n\n const added: HTMLLinkElement[] = []\n schedule(() => {\n for (const url of urls) {\n if (document.querySelector(`link[${PREFETCH_ATTR}][href=\"${url}\"]`)) continue\n const link = document.createElement('link')\n link.rel = 'prefetch'\n link.href = url\n link.setAttribute(PREFETCH_ATTR, '')\n document.head.appendChild(link)\n added.push(link)\n }\n })\n return () => {\n added.forEach((l) => l.remove())\n }\n }, [items, origin])\n\n return null\n}\n","// ---------------------------------------------------------------------------\n// NotificationsAdapter — the contract the shell's single Notifications bell is\n// fed by (Specs/System-Communications §6.3 and §12.2; UI-Platform → top bar).\n//\n// The bell never calls the Comms service directly. Reads and writes go through\n// the same-origin chrome API proxy with the viewer's session, so the Comms\n// `GET /v1/me/notifications` and `POST /v1/me/notifications/:id/{read,archive,\n// resolve}` routes (politogy-comms PR #14) are reached as `me/notifications…`\n// relative to the proxy base. The proxy's session cookie or bearer is what\n// Comms verifies (`getSubject`, OIDC `sub`); the shell never sends a token.\n//\n// Degradation contract: a missing session (401), an absent route (404), a\n// network failure or a malformed body all resolve to an EMPTY feed or `false`.\n// The bell then renders \"all caught up\" rather than an error state, and nothing\n// is thrown into the chrome.\n// ---------------------------------------------------------------------------\n\nimport type { NavChromeFetcher } from '../native/chromeActions'\n\nexport type CommsNotificationKind = 'notification' | 'alert'\n\n/** One row of the bell feed, as the shell reads it (camelCased). */\nexport type CommsNotification = {\n id: string\n kind: CommsNotificationKind\n title: string\n body: string\n icon: string | null\n link: string | null\n readAt: string | null\n orgId: string | null\n createdAt: string | null\n}\n\nexport type NotificationsFeed = {\n /** Alerts first, then notifications, newest first (Comms sorts them). */\n notifications: CommsNotification[]\n /** One badge number: unread notifications plus unresolved alerts (Spec §6.3). */\n badge: number\n}\n\nexport type NotificationsAdapter = {\n /** Read the signed-in viewer's feed, scoped to an org when one is active. */\n list(orgId: string | null): Promise<NotificationsFeed>\n /** Mark one row read. Resolves false on any failure, never throws. */\n markRead(id: string): Promise<boolean>\n /** Archive one row (hides it from the feed). Resolves false on failure. */\n archive(id: string): Promise<boolean>\n /** Resolve one alert. Comms rejects this for non-alert rows. */\n resolve(id: string): Promise<boolean>\n}\n\n/** The empty bell: what every degraded path renders. Always a fresh object. */\nexport function emptyNotificationsFeed(): NotificationsFeed {\n return { notifications: [], badge: 0 }\n}\n\nfunction asString(value: unknown): string | null {\n return typeof value === 'string' ? value : null\n}\n\n/**\n * Shape a raw Comms body into the feed. Tolerant on purpose: unknown keys are\n * ignored, rows without an id are dropped, and archived rows are never shown.\n */\nexport function normalizeNotificationsFeed(raw: unknown): NotificationsFeed {\n if (!raw || typeof raw !== 'object') return emptyNotificationsFeed()\n const body = raw as { notifications?: unknown; badge?: unknown }\n const rows = Array.isArray(body.notifications) ? body.notifications : []\n const notifications: CommsNotification[] = []\n for (const row of rows) {\n if (!row || typeof row !== 'object') continue\n const r = row as Record<string, unknown>\n const id = asString(r.id)\n if (!id || asString(r.archived_at)) continue\n notifications.push({\n id,\n kind: r.kind === 'alert' ? 'alert' : 'notification',\n title: asString(r.title) ?? '',\n body: asString(r.body) ?? '',\n icon: asString(r.icon),\n link: asString(r.link),\n readAt: asString(r.read_at),\n orgId: asString(r.org_id),\n createdAt: asString(r.created_at),\n })\n }\n const badge =\n typeof body.badge === 'number' && Number.isFinite(body.badge)\n ? Math.max(0, Math.floor(body.badge))\n : notifications.filter((n) => n.kind === 'alert' || n.readAt === null).length\n return { notifications, badge }\n}\n\n/**\n * Build the comms-backed adapter over the app's chrome fetcher. A null fetcher\n * (no chrome proxy wired) yields the empty bell with no network activity.\n */\nexport function createCommsNotificationsAdapter(\n fetchJson: NavChromeFetcher | null,\n): NotificationsAdapter {\n const act = async (id: string, action: 'read' | 'archive' | 'resolve'): Promise<boolean> => {\n if (!fetchJson || !id) return false\n try {\n await fetchJson(`me/notifications/${encodeURIComponent(id)}/${action}`, { method: 'POST' })\n return true\n } catch {\n return false\n }\n }\n return {\n async list(orgId) {\n if (!fetchJson) return emptyNotificationsFeed()\n try {\n const query = orgId ? `?org_id=${encodeURIComponent(orgId)}` : ''\n return normalizeNotificationsFeed(await fetchJson(`me/notifications${query}`))\n } catch {\n return emptyNotificationsFeed()\n }\n },\n markRead: (id) => act(id, 'read'),\n archive: (id) => act(id, 'archive'),\n resolve: (id) => act(id, 'resolve'),\n }\n}\n\n/**\n * Map a feed onto the panel's payload shape so the existing bell UI (alert\n * rows, read toggles, badge) renders adapter rows without a second renderer.\n */\nexport function notificationsFeedToPayload(\n feed: NotificationsFeed,\n orgId: string | null,\n): {\n organizationId: string\n alerts: { id: string; title: string; description: string; href: string | null; kind: string; read: boolean }[]\n replies: never[]\n badge: number\n} {\n return {\n organizationId: orgId ?? '',\n alerts: feed.notifications.map((n) => ({\n id: n.id,\n title: n.title,\n description: n.body,\n href: n.link,\n kind: n.kind,\n read: n.readAt !== null,\n })),\n replies: [],\n badge: feed.badge,\n }\n}\n","// Universal theme preference — the ONE cross-app contract.\n//\n// One theme choice (Light / Dark / System) follows the authenticated user\n// across every Politogy app + subdomain. Three layers cooperate:\n// 1. VRM Core `profiles.theme_preference` — source of truth, persisted via\n// the chrome API (`PATCH me/preferences { themePreference }`) and read\n// back from `GET me` (`themePreference`).\n// 2. `.politogyvrm.com` cookie `politogy_theme` — zero-flash pre-paint\n// vehicle that crosses subdomains (auth session cookies are host-only).\n// 3. localStorage `politogy_theme` — offline fallback store.\n//\n// Ported verbatim from contacts/apps/web/src/lib/theme.ts (the origin of the\n// contract) so every app runs the identical behavior from npm. This module is\n// server-safe (no 'use client'): layouts import THEME_PREPAINT_SCRIPT for the\n// pre-paint inline script. The client-side hook lives in ./native\n// (useThemePreference).\n\nexport type ThemePreference = 'light' | 'dark' | 'system'\n\n// Single converged key for BOTH the localStorage store and the\n// cross-subdomain cookie, so a choice in one app is the same key in the next.\nexport const THEME_STORAGE_KEY = 'politogy_theme'\nexport const THEME_COOKIE = 'politogy_theme'\n\n// A local choice that has NOT yet reached VRM Core `profiles.theme_preference`.\n//\n// Politogy ID (auth.politogyvrm.com) has no chrome-API session to PATCH, so a\n// theme picked on the login screen only ever lands in the cookie. Without this\n// marker the next app booted the stale profile value through the reconcile step\n// below and overwrote the user's fresh choice — the \"I set System and it keeps\n// going back to Light\" bug (HITL 2026-07-23). The flag rides the same\n// cross-subdomain cookie so the first app that CAN talk to the chrome API\n// pushes the choice up instead of pulling the stale one down.\nexport const THEME_PENDING_COOKIE = 'politogy_theme_pending'\n\nconst VALID: readonly ThemePreference[] = ['light', 'dark', 'system']\n\nexport function isThemePreference(v: unknown): v is ThemePreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readThemeCookie(): ThemePreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${THEME_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isThemePreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Set the cross-subdomain cookie. On a *.politogyvrm.com host we scope it to\n// the parent domain so every app subdomain reads it; on any other host\n// (localhost, *.pages.dev preview) we fall back to a host-only cookie so\n// local/preview theming still works without a mismatched Domain attribute\n// (which browsers silently drop). 1-year, SameSite=Lax, Secure on https.\nexport function writeThemeCookie(pref: ThemePreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const onParentDomain = /(^|\\.)politogyvrm\\.com$/i.test(host)\n const domainAttr = onParentDomain ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${THEME_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n// Write an arbitrary cross-subdomain cookie with the same scoping rules as the\n// theme cookie itself (parent domain on *.politogyvrm.com, host-only elsewhere).\nfunction writeSharedCookie(name: string, value: string, maxAgeSeconds: number): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${name}=${encodeURIComponent(\n value,\n )}; Path=/; Max-Age=${maxAgeSeconds}; SameSite=Lax${domainAttr}${secure}`\n}\n\n/**\n * Mark the current cookie value as a local choice that still has to reach the\n * user's profile. Call this from any surface that changes the theme WITHOUT a\n * chrome-API session (Politogy ID's login screen is the only one today).\n */\nexport function markThemeChoicePending(pref: ThemePreference): void {\n writeSharedCookie(THEME_PENDING_COOKIE, pref, 31536000)\n}\n\n/** The pending (not-yet-persisted) local choice, if any. */\nexport function readPendingThemeChoice(): ThemePreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${THEME_PENDING_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isThemePreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n/** Clear the pending marker once the choice has been written to the profile. */\nexport function clearPendingThemeChoice(): void {\n writeSharedCookie(THEME_PENDING_COOKIE, '', 0)\n}\n\n/** Resolve a preference to the concrete light/dark it renders as right now. */\nexport function resolveTheme(_pref: ThemePreference): 'light' | 'dark' {\n // Light only. Reference/UI-Platform retired Dark Mode (2026-09-21) and\n // Reference/Global-Rules forbids gating colour on prefers-color-scheme, so\n // every stored preference (including a legacy 'dark' or 'system') renders\n // light. The type keeps 'dark' so stored values still parse.\n return 'light'\n}\n\n/**\n * Read the stored preference the way the pre-paint script does — cookie →\n * localStorage → `'system'`. Kept in lockstep with THEME_PREPAINT_SCRIPT so a\n * runtime reader can never disagree with what was applied before paint.\n */\nexport function readStoredThemePreference(): ThemePreference {\n const cookie = readThemeCookie()\n if (cookie) return cookie\n try {\n const stored = window.localStorage.getItem(THEME_STORAGE_KEY)\n if (isThemePreference(stored)) return stored\n } catch {\n /* localStorage may be unavailable (private mode) */\n }\n return 'system'\n}\n\n/**\n * The concrete light/dark the document is rendering as right now.\n *\n * This is the value anything theme-derived must follow — notably Chakra's\n * `colorMode`. Chakra used to be pinned to light while this resolved to dark,\n * which rendered dark chrome tokens over light Chakra content (the \"dark\n * labels on a light page\" desync).\n */\nexport function readResolvedTheme(): 'light' | 'dark' {\n return resolveTheme(readStoredThemePreference())\n}\n\n/** Apply a preference to the document: toggles `.dark` + `data-theme` on\n * `<html>` (both selectors the chrome's dark token block matches) and sets\n * `color-scheme` so native controls follow. */\nexport function applyThemePreference(pref: ThemePreference): void {\n if (typeof document === 'undefined') return\n const resolved = resolveTheme(pref)\n const d = document.documentElement\n d.classList.toggle('dark', resolved === 'dark')\n try {\n d.setAttribute('data-theme', resolved)\n d.style.colorScheme = resolved\n } catch {\n /* non-fatal */\n }\n}\n\n// Inline pre-paint script — render it in <head> (or as the first child of\n// <body>) so the theme applies before first paint. Resolves the preference\n// from cookie → localStorage → OS, applies the `.dark` class + `color-scheme`,\n// and seeds localStorage from the cookie so the app hydrates to the synced\n// value (the cross-subdomain flash fix). Self-contained, dependency-free, and\n// wrapped so any failure is silent (never blocks paint).\nexport const THEME_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(THEME_STORAGE_KEY)};\nvar VALID=[\"light\",\"dark\",\"system\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${THEME_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nvar ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nvar pref=cookie||ls||\"system\";\nif(VALID.indexOf(pref)===-1)pref=\"system\";\nif(cookie&&cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}\nvar dark=false;\nvar d=document.documentElement;\nif(dark)d.classList.add(\"dark\");else d.classList.remove(\"dark\");\ntry{d.setAttribute(\"data-theme\",dark?\"dark\":\"light\");d.style.colorScheme=dark?\"dark\":\"light\";}catch(e){}\n}catch(e){}})();`\n","// ---------------------------------------------------------------------------\n// Native chrome actions — Tailwind-only top-bar widgets (Fuel, Notifications,\n// Support, Navigation-display) backed by the shared chrome API\n// (politogy-contacts-api on Railway). Zero Chakra, zero router, zero fetch\n// opinion: the consuming app injects ONE fetcher via <NavChromeProvider> —\n// typically a same-origin proxy route that attaches its own session's Bearer\n// token server-side — and every widget in every app runs this exact code.\n//\n// Data endpoints (paths are relative; the app's fetcher owns the base URL):\n// GET communications/fuel-status (header x-contacts-org: <core org id>)\n// GET notifications (header x-contacts-org: <core org id>)\n// GET orgs\n// POST support { message }\n//\n// Loading states follow Global-Rules \"Loading & Async States\": the chrome\n// (button, popover frame, labels) always renders; only the VALUE area shows a\n// skeleton shimmer — never a spinner, never a blank panel.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n type ComponentType,\n type ReactNode,\n} from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { useTopBarIconSlotGlyph, type TopBarIconSlot } from '../lib/topbarIconSlot'\nimport { resolveBrandGlyph } from '../lib/brandGlyphs'\nimport {\n createCommsNotificationsAdapter,\n emptyNotificationsFeed,\n notificationsFeedToPayload,\n type NotificationsAdapter,\n} from '../notifications/adapter'\nimport {\n applyThemePreference,\n isThemePreference,\n readThemeCookie,\n writeThemeCookie,\n readPendingThemeChoice,\n markThemeChoicePending,\n clearPendingThemeChoice,\n THEME_STORAGE_KEY,\n type ThemePreference as SharedThemePreference,\n} from '../theme-preference'\n\ntype NavIconLike = ComponentType<{ size?: number; className?: string }>\n\n// ---------------------------------------------------------------------------\n// Core-app deep links. The billing surface lives on the VRM-core app; we would\n// derive its origin from POLITOGY_APPS.vrm, but that registry lives in\n// ../app-chrome which imports THIS module — so pulling it in here would create\n// an import cycle. One local constant instead (kept in step with the registry's\n// `vrm` origin).\n// ---------------------------------------------------------------------------\n\nexport const CORE_APP_ORIGIN = 'https://app.politogyvrm.com'\n/** Text/Email fuel top-up page (SMS Signal + Email Broadcast). */\nexport const CORE_BILLING_PATH = '/organization-settings/subscription-billing/text-email'\nconst CORE_BILLING_URL = `${CORE_APP_ORIGIN}${CORE_BILLING_PATH}`\nconst QUARANTINED_CONTACTS_URL = `https://contacts.politogyvrm.com/duplicates`\n\n/** Specs origin — same env-aware-constant pattern as CORE_APP_ORIGIN. */\nexport const SPECS_ORIGIN = 'https://specs.politogyvrm.com'\n\n/**\n * Stamp the active org onto a cross-app link, the same `?org=<uuid>` selector\n * the nav tree and Mode pill use. A bare link into VRM core drops a multi-org\n * user into whatever org core defaults to, which is a different account than\n * the one whose fuel / quarantine counts they just clicked.\n */\nfunction withOrgParam(url: string, orgId: string | null | undefined): string {\n if (!orgId) return url\n return `${url}${url.includes('?') ? '&' : '?'}org=${orgId}`\n}\n\n/** Scope the quarantined-contacts view to one sender. */\nfunction withPhoneParam(url: string, phone: string | null | undefined): string {\n if (!phone) return url\n return `${url}${url.includes('?') ? '&' : '?'}phone=${encodeURIComponent(phone)}`\n}\n\n/**\n * Resolve an organization logo URL for rendering in ANY app.\n *\n * `organizations.logo_url` is authored by VRM core and stored as a ROOT-RELATIVE\n * core route — `/api/storage/public?bucket=organization-logos&path=<org>/logo.png`\n * (the signed-storage proxy). VRM core renders it correctly because that path\n * resolves against its own origin; every other app resolves it against its own\n * origin (forms.politogyvrm.com/api/storage/public), gets a 404, and shows a\n * broken image. The chrome API passes the stored value through verbatim, so the\n * resolution belongs here — one definition for every app, core included.\n *\n * Absolute URLs (http/https/data/blob) pass through untouched.\n */\nexport function resolveOrgLogoUrl(url: string | null | undefined): string | undefined {\n const raw = url?.trim()\n if (!raw) return undefined\n if (/^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(raw)) return raw\n return `${CORE_APP_ORIGIN}${raw.startsWith('/') ? '' : '/'}${raw}`\n}\n\n// ---------------------------------------------------------------------------\n// Shared 32×32 circular top-bar button chrome — the ONE definition of the\n// top-bar trigger (Global Rules: no slot hand-rolls its own trigger/badge).\n// NavTopBar's structured actionsList buttons use this same builder.\n// ---------------------------------------------------------------------------\n\n/**\n * Glyph size inside every top-bar icon button — Reference/UI-Platform v30:\n * \"34px buttons / 17px glyph / 6px gap\".\n */\nexport const TOPBAR_GLYPH_SIZE = 17\n\nexport function topBarIconButtonClass(tone: 'default' | 'warning' | 'danger' = 'default'): string {\n const toneClass =\n tone === 'danger' || tone === 'warning'\n ? 'text-[color:var(--chrome-danger)] hover:text-[color:var(--chrome-danger)]'\n : 'text-[color:var(--topbar-icon-color,var(--muted))] hover:text-[color:var(--topbar-icon-hover-color,var(--foreground))] hover:bg-[color:var(--topbar-icon-hover-bg,transparent)]'\n return [\n // `group/tbtip` powers the shared <TopBarTooltip> rendered inside the trigger.\n 'group/tbtip relative flex items-center justify-center rounded-[var(--topbar-icon-button-radius,5px)] border border-transparent transition',\n 'h-[var(--topbar-icon-button-size,34px)] w-[var(--topbar-icon-button-size,34px)]',\n toneClass,\n ].join(' ')\n}\n\n/** The shared count badge — one definition, used by every slot. */\n// ---------------------------------------------------------------------------\n// Top-bar panel registry.\n//\n// The top bar hosts two KINDS of surface: panels (opened deliberately by the\n// user from an icon) and transient nudges (the low-fuel hint, the new-reply\n// toast) that appear on their own. They are separate components under separate\n// triggers, so nothing stopped a nudge from covering an open panel — measured\n// in production: the reply toast over the notifications header, and the\n// low-fuel nudge over the same header from the fuel trigger two icons away.\n//\n// A module-scoped counter is enough: any nudge can ask \"is a panel open?\"\n// without the slots having to know about each other.\n// ---------------------------------------------------------------------------\nlet openPanelCount = 0\nconst panelListeners = new Set<() => void>()\nconst emitPanelChange = () => panelListeners.forEach((l) => l())\n\nfunction setPanelOpenGlobal(open: boolean) {\n openPanelCount = Math.max(0, openPanelCount + (open ? 1 : -1))\n emitPanelChange()\n}\n\n/** True while ANY top-bar panel is open. Nudges use it to stay out of the way. */\nexport function useAnyTopBarPanelOpen() {\n return useSyncExternalStore(\n (cb) => {\n panelListeners.add(cb)\n return () => panelListeners.delete(cb)\n },\n () => openPanelCount > 0,\n () => false,\n )\n}\n\nexport function TopBarCountBadge({ count }: { count: number }) {\n if (!(count > 0)) return null\n return (\n <span className=\"absolute -top-[5px] -right-[5px] flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--chrome-danger)] px-1 text-[10px] font-bold leading-4 text-[#FFFFFF]\">\n {count > 99 ? '99+' : count}\n </span>\n )\n}\n\n/**\n * The shared hover tooltip every top-bar control renders BELOW itself: an\n * up-pointing arrow at the icon, a bold title line and a muted description.\n * Pure CSS (group-hover) so it works on <a>, <button> and <summary> triggers.\n * The trigger must carry `group/tbtip relative` (topBarIconButtonClass does).\n */\nexport function TopBarTooltip({\n title,\n description,\n}: {\n title: string\n description?: ReactNode\n}) {\n // Styled ONLY on the Spec tooltip tokens (shellChrome.button.tooltipBg/Fg ->\n // --app-btn-tooltip-bg/-fg; Brand guideline \"Tooltips point at their\n // trigger\", UI-Platform \"Top-bar tooltips and panels - one shared\n // treatment\"). The literal fallbacks are the v150 token values for a page\n // that has not loaded the runtime token sheet yet. The arrow shares the\n // body's fill and border so the two read as one continuous shape, and the\n // tooltip opens on keyboard focus as well as hover (guideline: hover AND\n // focus); the description is the title color at reduced opacity so it\n // stays legible on whatever the token picks.\n return (\n <span\n role=\"tooltip\"\n className=\"pointer-events-none absolute left-1/2 top-full z-50 mt-2 hidden w-max max-w-56 -translate-x-1/2 flex-col rounded-lg border border-[color:var(--app-btn-tooltip-bg,#2F3136)] bg-[color:var(--app-btn-tooltip-bg,#2F3136)] px-3 py-2 text-left shadow-[var(--shadow-soft)] group-hover/tbtip:flex group-focus-visible/tbtip:flex\"\n >\n {/* Arrow pointing up at the icon - same fill and border as the body. */}\n <span\n aria-hidden\n className=\"absolute -top-[5px] left-1/2 h-2.5 w-2.5 -translate-x-1/2 rotate-45 border-l border-t border-[color:var(--app-btn-tooltip-bg,#2F3136)] bg-[color:var(--app-btn-tooltip-bg,#2F3136)]\"\n />\n <span className=\"text-xs font-semibold text-[color:var(--app-btn-tooltip-fg,#FFFFFF)]\">{title}</span>\n {description ? (\n <span className=\"mt-0.5 text-[11px] leading-snug text-[color:var(--app-btn-tooltip-fg,#FFFFFF)] opacity-75\">\n {description}\n </span>\n ) : null}\n </span>\n )\n}\n\n/**\n * The up-pointing arrow every top-bar panel renders, anchored under its\n * trigger icon (panels are right-aligned, so the arrow sits at the trigger's\n * center: 16px in from the panel's right edge). One definition — every menu\n * points at its own icon identically.\n */\nexport function TopBarPanelArrow() {\n return (\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]\"\n />\n )\n}\n\n/**\n * Wrapper for third-party top-bar widgets that ship their own launcher button\n * (e.g. DevNotes). Normalizes the trigger to the universal 32px circular slot\n * (chrome.css `.topbar-widget-slot`) and adds the standard tooltip.\n */\nexport function TopBarWidgetSlot({\n title,\n description,\n children,\n}: {\n title: string\n description?: string\n children: ReactNode\n}) {\n return (\n <span className=\"topbar-widget-slot group/tbtip relative inline-flex\">\n {children}\n <TopBarTooltip title={title} description={description} />\n </span>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Theme control — Light / System / Dark, rendered inside the account menu.\n// Controlled: the app owns persistence (profile + cross-subdomain cookie).\n// ---------------------------------------------------------------------------\n\nexport type ThemePreference = SharedThemePreference\n\nconst THEME_OPTIONS: { value: ThemePreference; label: string }[] = [\n { value: 'light', label: 'Light' },\n]\n\nexport function NavThemeControl({\n value,\n onChange,\n}: {\n value: ThemePreference\n onChange: (next: ThemePreference) => void\n}) {\n return (\n <div className=\"px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Appearance\n </p>\n <div\n role=\"radiogroup\"\n aria-label=\"Appearance\"\n className=\"flex overflow-hidden rounded-full border border-[color:var(--line)]\"\n >\n {THEME_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={value === opt.value}\n onClick={() => onChange(opt.value)}\n className={[\n 'flex-1 px-3 py-1.5 text-xs font-semibold transition',\n value === opt.value\n ? 'bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-[#FFFFFF]'\n : 'text-[color:var(--muted)] hover:bg-[color:var(--panel)] hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {opt.label}\n </button>\n ))}\n </div>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Chrome data context — the injected fetcher.\n// ---------------------------------------------------------------------------\n\nexport type NavChromeFetcher = (\n path: string,\n init?: { method?: string; headers?: Record<string, string>; body?: string },\n) => Promise<unknown>\n\n/** GET me — the authenticated user's chrome identity from the shared API.\n * userName prefers the VRM-core profile full name over token claims. */\nexport type ChromeMe = {\n user: string | null\n userName: string | null\n avatarUrl: string | null\n themePreference: string | null\n /** Universal navigation-display choice ('menu'|'tabs'|'both'); null when\n * unset or when the profile column is absent in this environment. */\n navDisplay: string | null\n /** The user's durable active-org preference (full org uuid); null when unset\n * or when the profile column is absent. Adopted only when the request\n * carries no `?org=`/cookie selector — URL → cookie → profile → default. */\n activeOrg?: string | null\n account?: string | null\n accountName?: string | null\n role?: string | null\n /** Contact reply-to, when the profile carries them (optional/tolerant). */\n email?: string | null\n phone?: string | null\n}\n\n/** In-flight-promise + short-TTL cache entry for one (endpoint, orgId) key. */\ntype ChromeFetchCacheEntry = { promise: Promise<unknown>; expiresAt: number }\n\n/** Default freshness window for de-duped chrome reads (orgs/me/notifications/\n * fuel-status). Short enough that a stale value never survives one nav, long\n * enough to collapse every hook mounted on the same page paint into one call. */\nconst CHROME_FETCH_CACHE_TTL_MS = 30_000\n\nfunction chromeCacheKey(path: string, orgId?: string | null): string {\n return orgId === undefined ? path : `${path}::${orgId ?? ''}`\n}\n\n/**\n * A shared read cache scoped to one `<NavChromeProvider>` (one fetcher, one\n * page boot). Every consumer of a given (path, orgId) pair within the TTL\n * window awaits the SAME promise instead of firing its own request — this is\n * what collapsed `/orgs` (2-4x), `/me` (2-3x) and `/notifications` (2-3x) per\n * page load, 1-3.5s each, down to one call apiece (nav-latency-report.md\n * Table 2). Keying by orgId means switching the active org is itself the\n * invalidation: the new org gets a fresh key, never the previous org's cached\n * value. A failed request is evicted immediately so the next consumer retries\n * rather than replaying the same rejection for the rest of the TTL.\n */\nfunction createChromeFetchCache(getFetchJson: () => NavChromeFetcher) {\n const cache = new Map<string, ChromeFetchCacheEntry>()\n\n function dedupedFetch(\n path: string,\n init: Parameters<NavChromeFetcher>[1] | undefined,\n opts: { orgId?: string | null; ttlMs?: number } = {},\n ): Promise<unknown> {\n const key = chromeCacheKey(path, opts.orgId)\n const now = Date.now()\n const hit = cache.get(key)\n if (hit && hit.expiresAt > now) return hit.promise\n // Return the fetcher's own promise (no extra `.catch` hop) so callers see\n // the same microtask depth as a direct fetchJson call; the boot screen's\n // first-tick dismissal (frameBootChrome.test) depends on that.\n const promise = getFetchJson()(path, init)\n promise.catch(() => cache.delete(key))\n cache.set(key, { promise, expiresAt: now + (opts.ttlMs ?? CHROME_FETCH_CACHE_TTL_MS) })\n return promise\n }\n\n /** Force the next read of `path` (any org) to skip the cache. Used after a\n * mutation that changes what an endpoint would return (e.g. marking chrome\n * notifications read server-side, if that ever moves off local storage). */\n function invalidate(path: string) {\n for (const key of cache.keys()) {\n if (key === path || key.startsWith(`${path}::`)) cache.delete(key)\n }\n }\n\n return { dedupedFetch, invalidate }\n}\n\ntype NavChromeContextValue = {\n fetchJson: NavChromeFetcher\n dedupedFetch: ReturnType<typeof createChromeFetchCache>['dedupedFetch']\n invalidateChromeCache: ReturnType<typeof createChromeFetchCache>['invalidate']\n me: ChromeMe | null\n meLoaded: boolean\n /** The bell's feed adapter; null = the legacy contacts-shaped feed. */\n notificationsAdapter: NotificationsAdapter | null\n}\n\nconst NavChromeContext = createContext<NavChromeContextValue | null>(null)\n\nexport function NavChromeProvider({\n fetchJson,\n notificationsAdapter,\n children,\n}: {\n fetchJson: NavChromeFetcher\n /**\n * Omitted: the bell reads the comms feed through the same proxy (default).\n * An app may inject its own adapter; `null` keeps the legacy feed.\n */\n notificationsAdapter?: NotificationsAdapter | null\n children: ReactNode\n}) {\n // The cache outlives re-renders but always calls the LATEST fetchJson (the\n // consuming app may pass a new function identity every render).\n const fetchJsonRef = useRef(fetchJson)\n fetchJsonRef.current = fetchJson\n const cacheRef = useRef<ReturnType<typeof createChromeFetchCache> | null>(null)\n if (!cacheRef.current) {\n cacheRef.current = createChromeFetchCache(() => fetchJsonRef.current)\n }\n const { dedupedFetch, invalidate: invalidateChromeCache } = cacheRef.current\n\n // One stable adapter per provider, built over the latest fetcher.\n const defaultAdapterRef = useRef<NotificationsAdapter | null>(null)\n if (!defaultAdapterRef.current) {\n defaultAdapterRef.current = createCommsNotificationsAdapter((path, init) =>\n fetchJsonRef.current(path, init),\n )\n }\n const adapter = notificationsAdapter === undefined ? defaultAdapterRef.current : notificationsAdapter\n\n // ONE `me` fetch per provider — identity (profile name/avatar) and the\n // theme reconciliation both hang off it.\n const [me, setMe] = useState<ChromeMe | null>(null)\n const [meLoaded, setMeLoaded] = useState(false)\n useEffect(() => {\n let cancelled = false\n dedupedFetch('me', undefined)\n .then((data) => {\n if (!cancelled) setMe(data as ChromeMe)\n })\n .catch(() => {\n /* degraded: session identity stands in */\n })\n .finally(() => {\n if (!cancelled) setMeLoaded(true)\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch])\n\n return (\n <NavChromeContext.Provider\n value={{ fetchJson, dedupedFetch, invalidateChromeCache, me, meLoaded, notificationsAdapter: adapter }}\n >\n {children}\n </NavChromeContext.Provider>\n )\n}\n\n/** The authenticated user's chrome identity (profile name / avatar / theme). */\nexport function useChromeMe(): { me: ChromeMe | null; loaded: boolean } {\n const ctx = useContext(NavChromeContext)\n return { me: ctx?.me ?? null, loaded: ctx?.meLoaded ?? false }\n}\n\n/** The provider's de-duped chrome read (null outside <NavChromeProvider>). */\nexport function useNavChromeDedupedFetch(): NavChromeContextValue['dedupedFetch'] | null {\n return useContext(NavChromeContext)?.dedupedFetch ?? null\n}\n\n/** The injected chrome fetcher (null outside <NavChromeProvider>). */\nexport function useNavChromeFetcher(): NavChromeFetcher | null {\n return useContext(NavChromeContext)?.fetchJson ?? null\n}\n\nfunction useNavChrome(component: string): NavChromeContextValue {\n const ctx = useContext(NavChromeContext)\n if (!ctx) {\n throw new Error(\n `${component} must be rendered inside <NavChromeProvider> (inject the chrome API fetcher there).`,\n )\n }\n return ctx\n}\n\n// ---------------------------------------------------------------------------\n// Data shapes (mirror of politogy-contacts-api responses).\n// ---------------------------------------------------------------------------\n\nexport type FuelChannelStatus = {\n remainingUnits: number\n rawBalanceUnits: number\n usedUnits: number\n lowFuel: boolean\n lowFuelThreshold: number\n}\n\nexport type CommunicationsFuelStatus = {\n organizationId: string\n signal: FuelChannelStatus\n broadcast: FuelChannelStatus\n combinedAvailableCredits: number\n}\n\nexport type ChromeNotificationAlert = {\n id: string\n title: string\n description: string\n href: string | null\n kind: string\n /** Server read state (adapter feeds only); the local watermark still applies. */\n read?: boolean\n}\n\nexport type ChromeNotificationReply = {\n id: string\n contactId: string | null\n name: string\n preview: string\n /** Optional deep-link to the conversation; the new-reply toast opens it. */\n href?: string\n /**\n * Optional arrival timestamp. Present, it lets the trigger badge count a\n * reply as \"unseen\" only when it is newer than the last time the panel was\n * opened; absent (older payloads), replies simply don't survive the first\n * open as unseen. Tolerated either way.\n */\n createdAt?: string\n}\n\n/** A running or finished contact import surfaced in the notifications panel. */\nexport type ChromeNotificationImport = {\n id: string\n label: string\n /** 0–100 progress, or null when indeterminate (no bar rendered). */\n percent: number | null\n status: 'active' | 'completed'\n href: string | null\n}\n\n/** A cluster of quarantined contacts sharing one phone number. */\nexport type ChromeNotificationQuarantine = {\n phone: string\n count: number\n /** Upstream may omit it; the row already renders conditionally on it. */\n latestAt: string | null\n}\n\nexport type ChromeNotificationsPayload = {\n organizationId: string\n alerts: ChromeNotificationAlert[]\n replies: ChromeNotificationReply[]\n /** Optional — running/finished imports (tolerant when absent). */\n imports?: ChromeNotificationImport[]\n /** Optional — clustered quarantined contacts (tolerant when absent). */\n quarantined?: ChromeNotificationQuarantine[]\n /** Optional — the server's one badge number (adapter feeds only). */\n badge?: number\n}\n\nexport type ChromeOrgSummary = {\n id: string\n name: string | null\n logoUrl: string | null\n brandColor: string | null\n role: string | null\n /** Un-mapped VRM-core membership role (e.g. \"super_admin\"). */\n rawRole?: string | null\n}\n\n/**\n * Fetch the signed-in user's VRM-core organizations through the injected\n * fetcher. Exposed as a hook so the org switcher in the sidebar and the\n * org-scoped widgets share one request.\n */\nexport function useChromeOrgs({ enabled = true }: { enabled?: boolean } = {}): {\n orgs: ChromeOrgSummary[] | null\n loading: boolean\n error: boolean\n} {\n const { dedupedFetch } = useNavChrome('useChromeOrgs')\n const [orgs, setOrgs] = useState<ChromeOrgSummary[] | null>(null)\n const [loading, setLoading] = useState(enabled)\n const [error, setError] = useState(false)\n\n useEffect(() => {\n // Disabled when the app already holds the org list from its token-backed\n // session (auth-owned active org): no per-request chrome `/api/orgs` call.\n if (!enabled) {\n setLoading(false)\n return\n }\n let cancelled = false\n setLoading(true)\n setError(false)\n dedupedFetch('orgs', undefined)\n .then((data) => {\n if (cancelled) return\n const list = (data as { orgs?: ChromeOrgSummary[] })?.orgs ?? []\n setOrgs(list)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch, enabled])\n\n return { orgs, loading, error }\n}\n\n// ---------------------------------------------------------------------------\n// Internal building blocks.\n// ---------------------------------------------------------------------------\n\n/** Value-area skeleton shimmer (chrome/labels stay static per Global Rules). */\nfunction ValueSkeleton({ className }: { className?: string }) {\n return (\n <span\n aria-hidden\n className={[\n 'inline-block animate-pulse rounded bg-[color:var(--panel-elevated)]',\n className ?? 'h-4 w-16',\n ].join(' ')}\n />\n )\n}\n\n/** Slot-driven glyph: Brand-token name when resolvable, fallback otherwise. */\nfunction SlotGlyph({\n slot,\n fallback: Fallback,\n size = TOPBAR_GLYPH_SIZE,\n}: {\n slot?: TopBarIconSlot\n fallback: NavIconLike\n size?: number\n}) {\n const glyphName = useTopBarIconSlotGlyph(slot ?? 'apps')\n const BrandGlyph = slot ? resolveBrandGlyph(glyphName) : null\n const Glyph = BrandGlyph ?? Fallback\n return <Glyph size={size} className=\"text-current\" />\n}\n\n/**\n * A top-bar popover: the shared circular trigger + a right-aligned panel.\n * Closes on outside click / Escape. Purely presentational.\n *\n * EXPORTED so an app with a richer panel than the stock actions can render it\n * inside the SHARED chrome — same 32px trigger, same tooltip, same badge, same\n * panel surface and arrow — instead of hand-rolling a trigger and drifting.\n * This is the enabling step for folding VRM's Fuel breakdown, import-progress,\n * alerts and reply-feed panels into the shared cluster one at a time, without\n * dropping capability (shell-nav-handoff §4; UI-Platform forbids migrating an\n * app to a rendering that loses an element it already ships).\n */\nexport function TopBarPopover({\n label,\n description,\n slot,\n fallbackIcon,\n badge,\n tone,\n onOpen,\n openToken,\n onOpenChange,\n hideTooltip = false,\n children,\n panelClassName,\n}: {\n label: string\n description?: string\n slot?: TopBarIconSlot\n fallbackIcon: NavIconLike\n badge?: number\n tone?: 'default' | 'warning' | 'danger'\n onOpen?: () => void\n /**\n * Imperative \"open\" signal: whenever this number CHANGES the panel opens\n * (and `onOpen` fires). Lets a sibling — e.g. the notifications toast — open\n * the panel without owning the popover's state. Undefined disables it.\n */\n openToken?: number\n /**\n * Notified on every open/close. A sibling surface anchored to the same\n * trigger (e.g. the notifications toast) must know when the panel is open so\n * the two never render on top of each other — Reference/UI-Platform gives\n * every top-bar panel ONE surface anchored to its trigger, so a second\n * surface at the same anchor always occludes it.\n */\n onOpenChange?: (open: boolean) => void\n /**\n * Hide the trigger's hover tooltip while a transient nudge (the new-reply\n * toast, the low-fuel hint) is up under the same trigger. Both are z-50 and\n * anchored to the trigger, so without this the nudge paints over the\n * tooltip (measured on a2p: the reply toast covered \"Alerts &\n * Notifications\"). Reference/UI-Platform: one surface per trigger.\n */\n hideTooltip?: boolean\n children: ReactNode\n panelClassName?: string\n}) {\n const [open, setOpen] = useState(false)\n const onOpenChangeRef = useRef(onOpenChange)\n onOpenChangeRef.current = onOpenChange\n useEffect(() => {\n onOpenChangeRef.current?.(open)\n if (!open) return\n setPanelOpenGlobal(true)\n return () => setPanelOpenGlobal(false)\n }, [open])\n const rootRef = useRef<HTMLDivElement | null>(null)\n const lastOpenTokenRef = useRef(openToken)\n\n // React to external open signals (skips the initial value on mount).\n useEffect(() => {\n if (openToken === undefined) return\n if (openToken === lastOpenTokenRef.current) return\n lastOpenTokenRef.current = openToken\n setOpen((v) => {\n if (!v) onOpen?.()\n return true\n })\n }, [openToken, onOpen])\n\n useEffect(() => {\n if (!open) return\n const onDocClick = (e: MouseEvent) => {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false)\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n return (\n <div ref={rootRef} className=\"relative\">\n <button\n type=\"button\"\n aria-label={label}\n aria-expanded={open}\n className={topBarIconButtonClass(tone)}\n onClick={() => {\n setOpen((v) => {\n const next = !v\n if (next) onOpen?.()\n return next\n })\n }}\n >\n <SlotGlyph slot={slot} fallback={fallbackIcon} />\n {typeof badge === 'number' ? <TopBarCountBadge count={badge} /> : null}\n {!open && !hideTooltip ? <TopBarTooltip title={label} description={description} /> : null}\n </button>\n {open ? (\n <div\n className={[\n 'absolute right-0 z-40 mt-2 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] shadow-[var(--shadow-soft)]',\n panelClassName ?? 'w-80',\n ].join(' ')}\n >\n <TopBarPanelArrow />\n <div className=\"overflow-hidden rounded-xl\">{children}</div>\n </div>\n ) : null}\n </div>\n )\n}\n\n// Inline fallback glyphs (Feather-style paths) so the package needs no icon dep.\nfunction BatteryGlyph({ size = TOPBAR_GLYPH_SIZE, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <rect x=\"1\" y=\"6\" width=\"18\" height=\"12\" rx=\"2\" ry=\"2\" />\n <line x1=\"23\" y1=\"10\" x2=\"23\" y2=\"14\" />\n <line x1=\"5\" y1=\"10\" x2=\"5\" y2=\"14\" />\n <line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"14\" />\n </svg>\n )\n}\n\nfunction BellGlyph({ size = TOPBAR_GLYPH_SIZE, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\" />\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\" />\n </svg>\n )\n}\n\nfunction BellOffGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\" />\n <path d=\"M18.63 13A17.9 17.9 0 0 1 18 8\" />\n <path d=\"M6.26 6.26A5.86 5.86 0 0 0 6 8c0 7-3 9-3 9h14\" />\n <path d=\"M18 8a6 6 0 0 0-9.33-5\" />\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" />\n </svg>\n )\n}\n\nfunction LifeBuoyGlyph({ size = TOPBAR_GLYPH_SIZE, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <line x1=\"4.93\" y1=\"4.93\" x2=\"9.17\" y2=\"9.17\" />\n <line x1=\"14.83\" y1=\"14.83\" x2=\"19.07\" y2=\"19.07\" />\n <line x1=\"14.83\" y1=\"9.17\" x2=\"19.07\" y2=\"4.93\" />\n <line x1=\"4.93\" y1=\"19.07\" x2=\"9.17\" y2=\"14.83\" />\n </svg>\n )\n}\n\nfunction LayoutGlyph({ size = TOPBAR_GLYPH_SIZE, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\" />\n <line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\" />\n </svg>\n )\n}\n\nfunction PlusGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n )\n}\n\nfunction XGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\nfunction CheckGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )\n}\n\n// ---------------------------------------------------------------------------\n// FuelAction — Communications Fuel balance (battery glyph + popover meters).\n// ---------------------------------------------------------------------------\n\nconst LOW_FUEL_HINT_DISMISSED_KEY = 'politogy_low_fuel_hint_dismissed'\n\nfunction FuelRow({\n label,\n channel,\n loading,\n addHref,\n addLabel,\n}: {\n label: string\n channel: FuelChannelStatus | null\n loading: boolean\n /** Billing deep-link for the small \"+\" top-up button (omit to hide it). */\n addHref?: string\n addLabel?: string\n}) {\n const remaining = channel?.remainingUnits ?? 0\n const total = channel ? Math.max(channel.rawBalanceUnits, channel.remainingUnits) : 0\n const ratio = total > 0 ? Math.min(100, Math.max(0, (remaining / total) * 100)) : 0\n const low = channel?.lowFuel ?? false\n\n return (\n <div className=\"w-full\">\n <div className=\"mb-1 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold text-[color:var(--foreground)]\">{label}</span>\n <div className=\"flex items-center gap-2\">\n {loading ? (\n <ValueSkeleton className=\"h-3.5 w-14\" />\n ) : (\n <span\n className={[\n 'text-xs font-semibold tabular-nums',\n low ? 'text-[color:var(--chrome-danger)]' : 'text-[color:var(--muted)]',\n ].join(' ')}\n >\n {remaining.toLocaleString()} left\n </span>\n )}\n {addHref ? (\n <a\n href={addHref}\n aria-label={addLabel}\n className=\"flex h-5 w-5 items-center justify-center rounded-full border border-[color:var(--line)] text-[color:var(--muted)] transition hover:border-[color:var(--foreground)] hover:text-[color:var(--foreground)]\"\n >\n <PlusGlyph />\n </a>\n ) : null}\n </div>\n </div>\n <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-[color:var(--panel)]\">\n {loading ? (\n <div className=\"h-full w-full animate-pulse bg-[color:var(--line)]\" />\n ) : (\n <div\n className={[\n 'h-full rounded-full transition-[width]',\n low ? 'bg-[color:var(--chrome-danger)]' : 'bg-[color:var(--color-ok,#00783B)]',\n ].join(' ')}\n style={{ width: `${ratio}%` }}\n />\n )}\n </div>\n </div>\n )\n}\n\n// Both the low-fuel nudge and the new-reply toast are wide (240-320px)\n// absolute bubbles anchored to adjacent top-bar icons (Fuel, then\n// Notifications). Anchored-right boxes expand LEFTWARD from their trigger,\n// so a wide toast under the (further-right) bell can reach back over the\n// (further-left) fuel icon's hint, same z-50 — whichever mounted later\n// painted on top and the fuel banner got cut off/hidden (reported on\n// contacts.politogyvrm.com, 2026-10-09). This tiny external store lets the\n// toast learn the hint's visibility without a shared provider, so it can\n// drop below it instead of overlapping: the banner always stacks above the\n// toast, never the other way round.\nlet lowFuelHintVisible = false\nconst lowFuelHintListeners = new Set<() => void>()\nfunction setLowFuelHintVisible(visible: boolean): void {\n if (lowFuelHintVisible === visible) return\n lowFuelHintVisible = visible\n lowFuelHintListeners.forEach((l) => l())\n}\nfunction subscribeLowFuelHintVisible(onChange: () => void): () => void {\n lowFuelHintListeners.add(onChange)\n return () => lowFuelHintListeners.delete(onChange)\n}\nfunction useLowFuelHintVisible(): boolean {\n // Server snapshot: the hint is client-only (sessionStorage), so SSR renders\n // without it. FuelAction reads this during the frame's server render.\n return useSyncExternalStore(\n subscribeLowFuelHintVisible,\n () => lowFuelHintVisible,\n () => false,\n )\n}\n// Height (card + arrow + gap) the toast must clear when the hint is also up.\nconst LOW_FUEL_HINT_CLEARANCE_PX = 96\n\n/**\n * The low-fuel nudge: a small bubble anchored below the fuel trigger (arrow up)\n * with a \"Buy More Fuel\" deep-link. Dismissible; the dismissal persists for the\n * session (sessionStorage) so it never re-appears until a fresh session — and\n * the flag clears once fuel is no longer low, so a later drain can nudge again.\n */\nfunction LowFuelHint({ lowFuel, orgId }: { lowFuel: boolean; orgId: string | null }) {\n const [dismissed, setDismissed] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false\n try {\n return window.sessionStorage.getItem(LOW_FUEL_HINT_DISMISSED_KEY) === '1'\n } catch {\n return false\n }\n })\n\n useEffect(() => {\n if (lowFuel) return\n try {\n window.sessionStorage.removeItem(LOW_FUEL_HINT_DISMISSED_KEY)\n } catch {\n /* unavailable */\n }\n }, [lowFuel])\n\n // Yield to any open panel: the nudge is wider than its own trigger and the\n // panels are right-aligned, so it lands on top of whichever one is open\n // (measured on contacts: it covered the notifications panel's header).\n const panelOpen = useAnyTopBarPanelOpen()\n const showing = lowFuel && !dismissed && !panelOpen\n\n // Published so the new-reply toast (anchored to the adjacent Notifications\n // icon) can drop below this banner instead of racing it for the same\n // on-screen space. Effect, not inline: setting external-store state during\n // render is not allowed.\n useEffect(() => {\n setLowFuelHintVisible(showing)\n return () => setLowFuelHintVisible(false)\n }, [showing])\n\n if (!showing) return null\n\n const dismiss = () => {\n try {\n window.sessionStorage.setItem(LOW_FUEL_HINT_DISMISSED_KEY, '1')\n } catch {\n /* unavailable */\n }\n setDismissed(true)\n }\n\n return (\n <div\n role=\"status\"\n // z-[60]: one tier above the new-reply toast (z-50) so this banner is\n // never the one that gets covered when both are up at once.\n className=\"absolute right-0 top-[calc(100%+10px)] z-[60] w-60 rounded-lg border border-[color:var(--chrome-danger)] bg-[color:var(--chrome-danger)] px-3 py-2 text-[#FFFFFF] shadow-[var(--shadow-soft)]\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Arrow pointing up at the fuel button (mirrors TopBarPanelArrow's offset). */}\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 bg-[color:var(--chrome-danger)]\"\n />\n <div className=\"flex items-start gap-2\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-semibold\">You’re low on fuel</p>\n <a\n href={withOrgParam(CORE_BILLING_URL, orgId)}\n className=\"mt-1 inline-block text-sm font-bold underline hover:opacity-90\"\n >\n Buy More Fuel\n </a>\n </div>\n <button\n type=\"button\"\n aria-label=\"Dismiss low fuel notice\"\n onClick={dismiss}\n className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[#FFFFFF]/90 transition hover:bg-[#FFFFFF]/20\"\n >\n <XGlyph />\n </button>\n </div>\n </div>\n )\n}\n\nexport function FuelAction({ orgId }: { orgId: string | null }) {\n const { dedupedFetch } = useNavChrome('FuelAction')\n const [fuel, setFuel] = useState<CommunicationsFuelStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n\n useEffect(() => {\n let cancelled = false\n // No org yet: wait for it. A header-less read is a second request for\n // the same widget once the org resolves (twice per page load).\n if (!orgId) {\n setLoading(false)\n return\n }\n setLoading(true)\n setError(false)\n setFuel(null)\n dedupedFetch(\n 'communications/fuel-status',\n { headers: orgId ? { 'x-contacts-org': orgId } : undefined },\n { orgId },\n )\n .then((data) => {\n if (cancelled) return\n setFuel((data as { fuel?: CommunicationsFuelStatus | null })?.fuel ?? null)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch, orgId])\n\n const low = !!fuel && (fuel.signal.lowFuel || fuel.broadcast.lowFuel)\n // The low-fuel hint sits under this trigger; the tooltip yields to it.\n const lowFuelHintUp = useLowFuelHintVisible()\n\n return (\n // The nudge anchors to the trigger, so it sits OUTSIDE the popover panel in\n // its own relative wrapper (same shape the VRM widget used).\n <div className=\"relative inline-flex\">\n <TopBarPopover\n label=\"Communications Fuel\"\n description=\"Remaining SMS and email sending balance for the active organization.\"\n slot=\"comms-fuel\"\n fallbackIcon={BatteryGlyph}\n tone={low ? 'warning' : 'default'}\n hideTooltip={lowFuelHintUp}\n >\n <div className=\"px-4 py-3\">\n <p className=\"mb-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Communications Fuel\n </p>\n {error || (!loading && !fuel) ? (\n <p className=\"text-sm text-[color:var(--muted)]\">\n Fuel balance is unavailable right now.\n </p>\n ) : (\n <div className=\"flex flex-col gap-3\">\n <FuelRow\n label=\"SMS Signal\"\n channel={fuel?.signal ?? null}\n loading={loading}\n addHref={withOrgParam(CORE_BILLING_URL, orgId)}\n addLabel=\"Add SMS Signal fuel\"\n />\n <FuelRow\n label=\"Email Broadcast\"\n channel={fuel?.broadcast ?? null}\n loading={loading}\n addHref={withOrgParam(CORE_BILLING_URL, orgId)}\n addLabel=\"Add Email Broadcast fuel\"\n />\n </div>\n )}\n </div>\n </TopBarPopover>\n <LowFuelHint lowFuel={low} orgId={orgId} />\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// NotificationsAction — bell + count badge + alerts/replies popover.\n// ---------------------------------------------------------------------------\n\n/** Per-org read/seen state, persisted client-side (localStorage). */\ntype NotifState = {\n readAlertIds: string[]\n lastSeenAt: string | null\n /** Reply ids already surfaced as a toast, so none re-toasts (capped ~50). */\n toastedReplyIds: string[]\n}\n\nfunction notifStateKey(orgId: string | null): string {\n return `politogy_chrome_notif_state:${orgId ?? 'none'}`\n}\n\nfunction readNotifState(orgId: string | null): NotifState {\n const empty: NotifState = { readAlertIds: [], lastSeenAt: null, toastedReplyIds: [] }\n if (typeof window === 'undefined') return empty\n try {\n const raw = window.localStorage.getItem(notifStateKey(orgId))\n if (!raw) return empty\n const parsed = JSON.parse(raw) as Partial<NotifState>\n return {\n readAlertIds: Array.isArray(parsed?.readAlertIds)\n ? parsed.readAlertIds.filter((id): id is string => typeof id === 'string')\n : [],\n lastSeenAt: typeof parsed?.lastSeenAt === 'string' ? parsed.lastSeenAt : null,\n toastedReplyIds: Array.isArray(parsed?.toastedReplyIds)\n ? parsed.toastedReplyIds.filter((id): id is string => typeof id === 'string')\n : [],\n }\n } catch {\n return empty\n }\n}\n\nfunction writeNotifState(orgId: string | null, state: NotifState): void {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(notifStateKey(orgId), JSON.stringify(state))\n } catch {\n /* unavailable */\n }\n}\n\n/**\n * Session-scoped mute for the rotating new-reply toasts. Session (not local)\n * storage on purpose: silencing is a \"not right now\" gesture, so a reload\n * restores the toasts rather than silently disabling them forever.\n */\nconst TOASTS_MUTED_KEY = 'politogy_chrome_toasts_muted'\n\nfunction readToastsMuted(): boolean {\n if (typeof window === 'undefined') return false\n try {\n return window.sessionStorage.getItem(TOASTS_MUTED_KEY) === '1'\n } catch {\n return false\n }\n}\n\nfunction writeToastsMuted(muted: boolean): void {\n if (typeof window === 'undefined') return\n try {\n if (muted) window.sessionStorage.setItem(TOASTS_MUTED_KEY, '1')\n else window.sessionStorage.removeItem(TOASTS_MUTED_KEY)\n } catch {\n /* unavailable */\n }\n}\n\n/** Format a raw phone into US (XXX) XXX-XXXX; leave anything else as-is. */\nfunction formatPhone(raw: string): string {\n const digits = raw.replace(/\\D/g, '')\n const ten = digits.length === 11 && digits.startsWith('1') ? digits.slice(1) : digits\n if (ten.length === 10) return `(${ten.slice(0, 3)}) ${ten.slice(3, 6)}-${ten.slice(6)}`\n return raw\n}\n\nfunction ImportRow({ imp }: { imp: ChromeNotificationImport }) {\n const pct = imp.percent == null ? null : Math.max(0, Math.min(100, imp.percent))\n return (\n <>\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate text-sm text-[color:var(--foreground)]\">{imp.label}</span>\n {pct != null ? (\n <span className=\"shrink-0 text-xs tabular-nums text-[color:var(--muted)]\">\n {Math.round(pct)}%\n </span>\n ) : null}\n </div>\n {pct != null ? (\n <div className=\"mt-1 h-1 w-full overflow-hidden rounded-full bg-[color:var(--panel)]\">\n <div\n className=\"h-full rounded-full bg-[color:var(--color-accent)] transition-[width]\"\n style={{ width: `${pct}%` }}\n />\n </div>\n ) : null}\n </>\n )\n}\n\n/**\n * Transient \"new reply\" toast anchored below the bell. Dark bubble with an\n * up-arrow, sender + preview; auto-fades after ~12s; clicking activates it.\n * Mirrors VRM's NewTextBellPopup. Purely presentational — the parent owns which\n * reply shows and what a click does.\n */\nfunction NewReplyToast({\n reply,\n onActivate,\n onClose,\n onSilence,\n ttlMs = 12000,\n}: {\n reply: ChromeNotificationReply\n onActivate: () => void\n onClose: () => void\n onSilence: () => void\n ttlMs?: number\n}) {\n const [visible, setVisible] = useState(false)\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n const lowFuelHintVisible = useLowFuelHintVisible()\n\n useEffect(() => {\n setVisible(true)\n const fadeAt = Math.max(0, ttlMs - 450)\n const t1 = window.setTimeout(() => setVisible(false), fadeAt)\n const t2 = window.setTimeout(() => onCloseRef.current(), ttlMs)\n return () => {\n window.clearTimeout(t1)\n window.clearTimeout(t2)\n }\n }, [ttlMs])\n\n const activate = () => {\n setVisible(false)\n onActivate()\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n aria-label=\"Open new reply\"\n onClick={activate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n activate()\n }\n }}\n // z-50, below the low-fuel banner's z-[60] — and when that banner is\n // up, pushed down past it so the two stack instead of overlapping\n // (see LOW_FUEL_HINT_CLEARANCE_PX; both bubbles are wide enough to\n // reach across the Fuel ↔ Notifications gap at these icon spacings).\n className=\"absolute right-[-6px] top-[calc(100%+12px)] z-50 min-w-[240px] max-w-[320px] cursor-pointer rounded-xl bg-[#161616] px-4 py-3 text-[#FFFFFF] shadow-[var(--shadow-soft)]\"\n style={{\n top: lowFuelHintVisible ? `calc(100% + 12px + ${LOW_FUEL_HINT_CLEARANCE_PX}px)` : undefined,\n opacity: visible ? 1 : 0,\n transform: visible ? 'translateY(0px)' : 'translateY(-4px)',\n transition: 'opacity 250ms ease, transform 250ms ease',\n }}\n >\n {/* Up-arrow pointing at the bell. */}\n <span\n aria-hidden\n className=\"absolute right-[18px] top-[-7px] h-0 w-0 border-x-[8px] border-x-transparent border-b-[8px] border-b-[#161616]\"\n />\n {/* Dismiss this ONE toast without navigating. The bubble itself is the\n activate target, so the close control has to stop propagation or\n \"get rid of it\" would mean \"open it\" (reported 2026-08-12). */}\n <button\n type=\"button\"\n aria-label=\"Dismiss notification\"\n onClick={(e) => {\n e.stopPropagation()\n setVisible(false)\n onClose()\n }}\n className=\"absolute right-2 top-2 flex h-5 w-5 items-center justify-center rounded-full text-[#FFFFFF] opacity-60 transition hover:bg-[#FFFFFF]/10 hover:opacity-100\"\n >\n <XGlyph size={12} />\n </button>\n <p className=\"truncate pr-6 text-sm font-semibold\">{reply.name}</p>\n <p className=\"mt-1 truncate text-xs opacity-85\">{reply.preview}</p>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setVisible(false)\n onSilence()\n }}\n className=\"mt-2 inline-flex items-center gap-1 text-[11px] font-semibold text-[#FFFFFF] opacity-60 transition hover:opacity-100\"\n >\n <BellOffGlyph size={12} />\n Silence notifications\n </button>\n </div>\n )\n}\n\nexport function NotificationsAction({ orgId }: { orgId: string | null }) {\n const { dedupedFetch, notificationsAdapter } = useNavChrome('NotificationsAction')\n const [payload, setPayload] = useState<ChromeNotificationsPayload | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n const [notif, setNotif] = useState<NotifState>(() => readNotifState(orgId))\n const [toastReply, setToastReply] = useState<ChromeNotificationReply | null>(null)\n const [toastsMuted, setToastsMuted] = useState<boolean>(() => readToastsMuted())\n const [openToken, setOpenToken] = useState(0)\n const [panelOpen, setPanelOpen] = useState(false)\n // Bumped after a server write (adapter path) to re-read the feed and badge.\n const [reloadToken, setReloadToken] = useState(0)\n // Also yield to a panel opened from a NEIGHBOURING trigger — the fuel panel\n // is right-aligned and wide enough to sit under the bell.\n const anyPanelOpen = useAnyTopBarPanelOpen()\n\n // Re-hydrate the read/seen watermark whenever the active org changes.\n useEffect(() => {\n setNotif(readNotifState(orgId))\n setToastReply(null)\n }, [orgId])\n\n useEffect(() => {\n let cancelled = false\n // No org yet: wait for it. A header-less read is a second request for\n // the same widget once the org resolves (twice per page load).\n if (!orgId) {\n setLoading(false)\n return\n }\n if (notificationsAdapter) {\n // Comms feed. Never rejects: a missing session or absent route is an\n // empty bell, not an error state.\n setError(false)\n notificationsAdapter\n .list(orgId)\n .then((feed) => {\n if (!cancelled) setPayload(notificationsFeedToPayload(feed, orgId) as ChromeNotificationsPayload)\n })\n .catch(() => {\n if (!cancelled) setPayload(notificationsFeedToPayload(emptyNotificationsFeed(), orgId) as ChromeNotificationsPayload)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }\n setLoading(true)\n setError(false)\n setPayload(null)\n dedupedFetch(\n 'notifications',\n { headers: orgId ? { 'x-contacts-org': orgId } : undefined },\n { orgId },\n )\n .then((data) => {\n if (!cancelled) setPayload(data as ChromeNotificationsPayload)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch, notificationsAdapter, orgId, reloadToken])\n\n // 10DLC registration alert: surfaced only in the notifications panel/badge\n // (unread state). No auto-redirect — see Decisions in PR for feat/spec-overlay.\n\n const markRead = useCallback(\n (id: string) => {\n // Adapter feeds persist read state on the server, then re-read the feed\n // so the row and the badge reflect it. A failed write is simply a no-op.\n if (notificationsAdapter) {\n void notificationsAdapter.markRead(id).then((ok) => {\n if (ok) setReloadToken((t) => t + 1)\n })\n }\n setNotif((prev) => {\n if (prev.readAlertIds.includes(id)) return prev\n const next = { ...prev, readAlertIds: [...prev.readAlertIds, id] }\n writeNotifState(orgId, next)\n return next\n })\n },\n [orgId, notificationsAdapter],\n )\n\n const markUnread = useCallback(\n (id: string) => {\n setNotif((prev) => {\n if (!prev.readAlertIds.includes(id)) return prev\n const next = { ...prev, readAlertIds: prev.readAlertIds.filter((x) => x !== id) }\n writeNotifState(orgId, next)\n return next\n })\n },\n [orgId],\n )\n\n // Opening the panel advances the \"last seen\" watermark (replies are seen).\n const onOpen = useCallback(() => {\n // The panel shows the reply the toast was previewing, so the toast has\n // nothing left to say — retire it rather than let it cover the panel.\n setToastReply(null)\n setNotif((prev) => {\n const next = { ...prev, lastSeenAt: new Date().toISOString() }\n writeNotifState(orgId, next)\n return next\n })\n }, [orgId])\n\n const alerts = payload?.alerts ?? []\n const replies = payload?.replies ?? []\n const imports = payload?.imports ?? []\n const quarantined = payload?.quarantined ?? []\n\n // New-reply toast: surface the newest reply that is (a) newer than the seen\n // watermark and (b) not already toasted this org. One at a time; the id is\n // recorded so a re-render / re-fetch never re-toasts it (capped at 50).\n useEffect(() => {\n // Silenced for this session — surface nothing new (the badge still counts).\n if (toastsMuted) return\n if (!payload || toastReply || panelOpen) return\n const candidate = replies\n .filter((r) => {\n if (!r.createdAt) return false\n if (notif.lastSeenAt && r.createdAt <= notif.lastSeenAt) return false\n return !notif.toastedReplyIds.includes(r.id)\n })\n .sort((a, b) => (a.createdAt! < b.createdAt! ? 1 : -1))[0]\n if (!candidate) return\n setToastReply(candidate)\n setNotif((prev) => {\n const next = {\n ...prev,\n toastedReplyIds: [candidate.id, ...prev.toastedReplyIds].slice(0, 50),\n }\n writeNotifState(orgId, next)\n return next\n })\n }, [\n payload,\n replies,\n toastReply,\n panelOpen,\n toastsMuted,\n notif.lastSeenAt,\n notif.toastedReplyIds,\n orgId,\n ])\n\n // Toast click: navigate to the reply's href when it carries one; otherwise\n // open the notifications panel (which also advances the seen watermark).\n const setMuted = useCallback((muted: boolean) => {\n writeToastsMuted(muted)\n setToastsMuted(muted)\n }, [])\n\n const onToastSilence = useCallback(() => {\n setMuted(true)\n setToastReply(null)\n }, [setMuted])\n\n const onToastActivate = useCallback(() => {\n const href = toastReply?.href\n setToastReply(null)\n if (href && typeof window !== 'undefined') {\n window.location.assign(href)\n return\n }\n setOpenToken((t) => t + 1)\n }, [toastReply])\n\n // Badge: UNREAD alerts + replies newer than the last-seen watermark. A reply\n // with no timestamp counts before the first open, then is treated as seen.\n const isAlertRead = (a: ChromeNotificationAlert) => a.read === true || notif.readAlertIds.includes(a.id)\n const unreadAlertCount = alerts.filter((a) => !isAlertRead(a)).length\n const unseenReplyCount = replies.filter((r) => {\n if (!notif.lastSeenAt) return true\n if (!r.createdAt) return false\n return r.createdAt > notif.lastSeenAt\n }).length\n // Adapter feeds carry the server's one badge number (unread notifications\n // plus unresolved alerts); the local count is the legacy contacts path only.\n const badgeCount =\n notificationsAdapter && payload?.badge !== undefined\n ? payload.badge\n : unreadAlertCount + unseenReplyCount\n\n const isEmpty =\n alerts.length === 0 && replies.length === 0 && imports.length === 0 && quarantined.length === 0\n\n // The toast yields to any open panel (this one or a neighbour's), and while\n // it is up the bell's hover tooltip yields to it - one surface per trigger.\n const toastVisible = toastReply !== null && !panelOpen && !anyPanelOpen\n\n return (\n // Relative wrapper so the new-reply toast anchors to the bell trigger,\n // outside the popover panel (same pattern as the fuel low-fuel nudge).\n <div className=\"relative inline-flex\">\n <TopBarPopover\n label=\"Alerts & Notifications\"\n description=\"System alerts and recent activity for the active organization.\"\n slot=\"notifications\"\n fallbackIcon={BellGlyph}\n badge={loading ? 0 : badgeCount}\n onOpen={onOpen}\n openToken={openToken}\n onOpenChange={setPanelOpen}\n hideTooltip={toastVisible}\n >\n <div className=\"px-4 py-3\">\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Notifications\n </p>\n {/* Only shown once silenced — the way back, in the same session. */}\n {toastsMuted ? (\n <button\n type=\"button\"\n onClick={() => setMuted(false)}\n className=\"text-[11px] font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n Unsilence\n </button>\n ) : null}\n </div>\n {loading ? (\n <div className=\"flex flex-col gap-2 py-1\">\n <ValueSkeleton className=\"h-4 w-full\" />\n <ValueSkeleton className=\"h-4 w-3/4\" />\n </div>\n ) : error ? (\n <p className=\"text-sm text-[color:var(--muted)]\">\n Notifications are unavailable right now.\n </p>\n ) : isEmpty ? (\n <p className=\"py-1 text-sm text-[color:var(--muted)]\">You’re all caught up.</p>\n ) : (\n <div className=\"flex max-h-80 flex-col gap-2 overflow-y-auto\">\n {/* Alerts (with per-item read toggle) + replies — unchanged order. */}\n {alerts.length > 0 || replies.length > 0 ? (\n <ul className=\"flex flex-col gap-1\">\n {alerts.map((a) => {\n const isRead = isAlertRead(a)\n return (\n <li key={a.id} className={isRead ? 'opacity-50' : undefined}>\n <div className=\"flex items-start gap-1 rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n <a\n href={a.href ?? '#'}\n onClick={() => markRead(a.id)}\n className=\"block min-w-0 flex-1\"\n >\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {a.title}\n </p>\n <p className=\"text-xs text-[color:var(--muted)]\">{a.description}</p>\n </a>\n <button\n type=\"button\"\n aria-label={isRead ? 'Mark as unread' : 'Mark as read'}\n onClick={() => (isRead && !notificationsAdapter ? markUnread(a.id) : markRead(a.id))}\n className=\"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)]\"\n >\n <CheckGlyph />\n </button>\n </div>\n </li>\n )\n })}\n {/* A reply row is a REAL link when it carries a deep-link, so\n the hover highlight leads somewhere: the conversation the\n reply arrived in (reported 2026-08-12). Rows without an\n href stay inert rather than pretending to be clickable. */}\n {replies.map((r) => {\n const body = (\n <>\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {r.name}\n </p>\n <p className=\"truncate text-xs text-[color:var(--muted)]\">{r.preview}</p>\n </>\n )\n return (\n <li key={r.id}>\n {r.href ? (\n <a\n href={r.href}\n aria-label={`Open the conversation with ${r.name}`}\n className=\"block rounded-lg px-2 py-2 transition hover:bg-[color:var(--panel)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-accent)]\"\n >\n {body}\n </a>\n ) : (\n <div className=\"rounded-lg px-2 py-2\">{body}</div>\n )}\n </li>\n )\n })}\n </ul>\n ) : null}\n\n {/* Imports — running/finished contact imports. */}\n {imports.length > 0 ? (\n <div>\n <p className=\"mb-1 px-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Imports\n </p>\n <ul className=\"flex flex-col gap-1\">\n {imports.map((imp) => (\n <li key={imp.id} className=\"rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n {imp.href ? (\n <a href={imp.href} className=\"block\">\n <ImportRow imp={imp} />\n </a>\n ) : (\n <ImportRow imp={imp} />\n )}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {/* Quarantined contact clusters. */}\n {quarantined.length > 0 ? (\n <div>\n <div className=\"mb-1 flex items-center justify-between px-2\">\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Quarantined Contacts\n </p>\n <a\n href={withOrgParam(QUARANTINED_CONTACTS_URL, orgId)}\n className=\"text-[11px] font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n View all\n </a>\n </div>\n <ul className=\"flex flex-col gap-1\">\n {/* Each row is a REAL link, not a div with a hover class. It\n used to carry a hover highlight on a non-interactive <li>,\n so the row advertised interactivity and then did nothing\n when clicked (reported 2026-08-03). An affordance has to\n lead somewhere: the row opens the quarantined-contacts\n view filtered to that number — the same destination as\n \"View all\", scoped. Being an <a> makes it keyboard\n focusable and Enter-activatable for free. */}\n {quarantined.map((q) => (\n <li key={q.phone}>\n <a\n href={withPhoneParam(withOrgParam(QUARANTINED_CONTACTS_URL, orgId), q.phone)}\n aria-label={`Review ${q.count} quarantined message${q.count === 1 ? '' : 's'} from ${formatPhone(q.phone)}`}\n className=\"block rounded-lg px-2 py-2 transition hover:bg-[color:var(--nav-row-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-accent)]\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {formatPhone(q.phone)}\n </span>\n {/* Same geometry as the shared TopBarCountBadge (16px\n circle, 10px/400, px-1); it sits in flow rather\n than absolutely on a 32px trigger, because this is\n a list row and not a top-bar icon. */}\n <span className=\"flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--panel)] px-1 text-[10px] font-normal leading-none tabular-nums text-[color:var(--muted)]\">\n {q.count > 99 ? '99+' : q.count}\n </span>\n </div>\n {q.latestAt ? (\n <p className=\"text-xs text-[color:var(--muted)]\">\n {new Date(q.latestAt).toLocaleString()}\n </p>\n ) : null}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n )}\n </div>\n </TopBarPopover>\n {/* Only ONE surface at this anchor at a time: the toast yields to the panel\n (both hang off the bell trigger, so rendering both means the toast sits\n on the panel's header — Reference/UI-Platform, one surface per trigger). */}\n {toastVisible && toastReply ? (\n <NewReplyToast\n reply={toastReply}\n onActivate={onToastActivate}\n onClose={() => setToastReply(null)}\n onSilence={onToastSilence}\n />\n ) : null}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SupportAction — life-buoy trigger + the shared support-request modal\n// (never a mailto:, never an app-local form — Reference/UI-Platform).\n// ---------------------------------------------------------------------------\n\n/**\n * Compose the delivered support message: the user's note, then a context block\n * carrying the page, URL and active org — plus a Reply-to line when the user\n * had to supply contact details the profile was missing. The upstream contract\n * stays `POST support { message }`; this just enriches the text (VRM parity).\n */\nfunction composeSupportMessage(input: {\n note: string\n pageTitle: string\n url: string\n orgName?: string | null\n replyEmail?: string\n replyPhone?: string\n}): string {\n const ctx = [`Page: ${input.pageTitle || 'Unknown'}`, `URL: ${input.url}`]\n if (input.orgName) ctx.push(`Org: ${input.orgName}`)\n const reply = [input.replyEmail?.trim(), input.replyPhone?.trim()].filter(Boolean).join(' / ')\n if (reply) ctx.push(`Reply-to: ${reply}`)\n return `${input.note.trim()}\\n\\n---\\n${ctx.join('\\n')}`\n}\n\nexport function SupportAction({\n orgId,\n orgs: knownOrgs,\n}: { orgId?: string | null; orgs?: { id: string; name: string | null }[] } = {}) {\n const { fetchJson } = useNavChrome('SupportAction')\n const { me, loaded } = useChromeMe()\n // A caller that already holds the org list skips the chrome `/api/orgs` call.\n const { orgs: fetchedOrgs } = useChromeOrgs({ enabled: !knownOrgs })\n const orgs = knownOrgs ?? fetchedOrgs\n const [open, setOpen] = useState(false)\n const [message, setMessage] = useState('')\n const [email, setEmail] = useState('')\n const [phone, setPhone] = useState('')\n const [showEmailError, setShowEmailError] = useState(false)\n const [state, setState] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle')\n\n // The profile knows email/phone unless the chrome `me` loaded without them —\n // then we collect the missing one(s) in the modal (email required, phone not).\n const meEmail = me?.email ?? null\n const mePhone = me?.phone ?? null\n const missingEmail = loaded && !meEmail\n const missingPhone = loaded && !mePhone\n\n const activeOrg =\n (orgId ? orgs?.find((o) => o.id === orgId) : null) ??\n (orgs && orgs.length === 1 ? orgs[0] : null)\n const orgName = activeOrg?.name ?? null\n\n const close = useCallback(() => {\n setOpen(false)\n setState('idle')\n setMessage('')\n setShowEmailError(false)\n }, [])\n\n // Seed the contact inputs from the profile whenever the modal opens.\n useEffect(() => {\n if (!open) return\n setEmail(meEmail ?? '')\n setPhone(mePhone ?? '')\n setShowEmailError(false)\n }, [open, meEmail, mePhone])\n\n useEffect(() => {\n if (!open) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close()\n }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [open, close])\n\n const submit = async () => {\n if (!message.trim() || state === 'sending') return\n\n const resolvedEmail = (missingEmail ? email : meEmail ?? '').trim()\n const resolvedPhone = (missingPhone ? phone : mePhone ?? '').trim()\n // Email is required when the profile didn't carry one.\n if (missingEmail && !resolvedEmail) {\n setShowEmailError(true)\n return\n }\n setShowEmailError(false)\n\n const collectedContact = missingEmail || missingPhone\n const fullMessage = composeSupportMessage({\n note: message,\n pageTitle: typeof document !== 'undefined' ? document.title : '',\n url: typeof window !== 'undefined' ? window.location.href : '',\n orgName,\n replyEmail: collectedContact ? resolvedEmail : undefined,\n replyPhone: collectedContact ? resolvedPhone : undefined,\n })\n\n setState('sending')\n try {\n await fetchJson('support', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: fullMessage }),\n })\n setState('sent')\n } catch {\n setState('error')\n }\n }\n\n return (\n <>\n <button\n type=\"button\"\n aria-label=\"Support\"\n className={topBarIconButtonClass()}\n onClick={() => setOpen(true)}\n >\n <SlotGlyph slot=\"support\" fallback={LifeBuoyGlyph} />\n <TopBarTooltip\n title=\"Support\"\n description=\"Send a support request to the Politogy team.\"\n />\n </button>\n {open && typeof document !== 'undefined'\n ? createPortal(\n <div\n // Portaled to <body>: the top bar's backdrop-blur creates a CSS\n // containing block, so a fixed-position descendant would center on\n // the HEADER (rendering off-screen) instead of the viewport.\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Support request\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) close()\n }}\n >\n <div className=\"w-full max-w-md rounded-2xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-6 shadow-[var(--shadow-soft)]\">\n <h2 className=\"text-lg font-bold tracking-[-0.01em] text-[color:var(--foreground)]\">\n Contact Support\n </h2>\n {state === 'sent' ? (\n <>\n <p className=\"mt-3 text-sm text-[color:var(--muted)]\">\n Your request was sent. The team will reply by email.\n </p>\n <div className=\"mt-5 flex justify-end\">\n <button\n type=\"button\"\n onClick={close}\n className=\"rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] px-4 py-2 text-sm font-semibold text-[#FFFFFF] hover:opacity-90\"\n >\n Done\n </button>\n </div>\n </>\n ) : (\n <>\n <p className=\"mt-1 text-sm text-[color:var(--muted)]\">\n Describe the problem or question. Your account details ride along\n automatically.\n </p>\n {missingEmail ? (\n <label className=\"mt-4 block\">\n <span className=\"mb-1 block text-xs font-semibold text-[color:var(--foreground)]\">\n Your email\n </span>\n <input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n {showEmailError ? (\n <span className=\"mt-1 block text-xs text-[color:var(--chrome-danger)]\">\n Enter an email so support can reply.\n </span>\n ) : null}\n </label>\n ) : null}\n {missingPhone ? (\n <label className=\"mt-3 block\">\n <span className=\"mb-1 block text-xs font-semibold text-[color:var(--foreground)]\">\n Your phone — optional\n </span>\n <input\n type=\"tel\"\n value={phone}\n onChange={(e) => setPhone(e.target.value)}\n placeholder=\"(503) 555-1212\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n </label>\n ) : null}\n <textarea\n value={message}\n onChange={(e) => setMessage(e.target.value)}\n rows={5}\n placeholder=\"How can we help?\"\n className=\"mt-4 w-full resize-y rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n {state === 'error' ? (\n <p className=\"mt-2 text-sm text-[color:var(--chrome-danger)]\">\n Sending failed — try again.\n </p>\n ) : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={close}\n className=\"rounded-full border border-[color:var(--line)] px-4 py-2 text-sm font-semibold text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={submit}\n disabled={!message.trim() || state === 'sending'}\n className=\"rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] px-4 py-2 text-sm font-semibold text-[#FFFFFF] transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {state === 'sending' ? 'Sending…' : 'Send request'}\n </button>\n </div>\n </>\n )}\n </div>\n </div>,\n document.body,\n )\n : null}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SpecOverlayAction — Spencer + Ben only. A top-bar \"Spec\" trigger showing\n// the current page's spec compliance / visual-regression status, from the\n// Specs app's overlay API. Renders NOTHING when the viewer isn't allowed —\n// no icon, no badge, no console noise — so this is invisible to every other\n// user. All calls are plain cross-origin fetches with same-site cookies\n// (credentials: 'include'); this does NOT go through the chrome proxy\n// fetchJson, which is same-origin only.\n// ---------------------------------------------------------------------------\n\ntype SpecOverlayAccess = { allowed: boolean; email?: string }\n\ntype SpecOverlayStatus =\n | {\n matched: true\n spec_slug: string\n spec_title: string\n target_id: string\n label: string\n viewport: string\n /** null when there is no finished compare run yet — never coerce to 0. */\n mismatch_pct: number | null\n finished_at: string | null\n passed: boolean | null\n spec_url: string\n compare_url: string\n overlay_url: string\n live_selector?: string | null\n capture_url?: string\n theme?: 'light' | 'dark' | null\n live_source?: 'worker' | 'viewer' | null\n live_size?: { width: number; height: number } | null\n design_size?: { width: number; height: number } | null\n /** Ready-to-paste repair prompt for an AI agent (latest run). */\n prompt?: string | null\n }\n | { matched: false; search_url: string }\n\nconst SPEC_OVERLAY_ACCESS_CACHE_KEY = 'politogy_spec_overlay_access'\n\nfunction readSpecOverlayAccessCache(): SpecOverlayAccess | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.sessionStorage.getItem(SPEC_OVERLAY_ACCESS_CACHE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (typeof parsed?.allowed === 'boolean') return parsed as SpecOverlayAccess\n } catch {\n /* ignore */\n }\n return null\n}\n\nfunction writeSpecOverlayAccessCache(access: SpecOverlayAccess): void {\n if (typeof window === 'undefined') return\n try {\n window.sessionStorage.setItem(SPEC_OVERLAY_ACCESS_CACHE_KEY, JSON.stringify(access))\n } catch {\n /* ignore */\n }\n}\n\n/**\n * Notifies subscribers whenever the URL changes via pushState, replaceState\n * or a back/forward navigation. Patches `history` exactly once per page\n * (module-level guard) no matter how many components subscribe.\n */\ntype LocationChangeListener = () => void\nconst locationChangeListeners = new Set<LocationChangeListener>()\nlet historyPatched = false\n\nfunction ensureHistoryPatched(): void {\n if (historyPatched || typeof window === 'undefined') return\n historyPatched = true\n const notify = () => locationChangeListeners.forEach((fn) => fn())\n const originalPushState = window.history.pushState.bind(window.history)\n const originalReplaceState = window.history.replaceState.bind(window.history)\n window.history.pushState = (...args: Parameters<History['pushState']>) => {\n originalPushState(...args)\n notify()\n }\n window.history.replaceState = (...args: Parameters<History['replaceState']>) => {\n originalReplaceState(...args)\n notify()\n }\n window.addEventListener('popstate', notify)\n}\n\nfunction useLocationHref(): string {\n const [href, setHref] = useState(() =>\n typeof window === 'undefined' ? '' : window.location.href,\n )\n useEffect(() => {\n ensureHistoryPatched()\n const onChange = () => setHref(window.location.href)\n locationChangeListeners.add(onChange)\n return () => {\n locationChangeListeners.delete(onChange)\n }\n }, [])\n return href\n}\n\nfunction specOverlayFetchJson(path: string): Promise<unknown> {\n // Bounded: this hits a cross-origin app (specs.politogyvrm.com) from every\n // page's top bar. An unbounded call here let a stuck access/status check\n // keep the page's network alive indefinitely — which blocks `networkidle`\n // and tripped visual-regression captures' own 45s navigation timeout on\n // the very pages this widget instruments (seen on a2p 2026-10-02).\n return fetch(`${SPECS_ORIGIN}${path}`, { credentials: 'include', signal: AbortSignal.timeout(10_000) }).then((res) => {\n if (!res.ok) throw new Error(`spec overlay ${path}: ${res.status}`)\n return res.json()\n })\n}\n\n/**\n * True when this page is being driven by an automated capture session\n * (Cloudflare Browser Rendering / CDP-controlled Chromium — the Specs\n * design-compare tool, among others) rather than a real Spencer/Ben\n * session. `navigator.webdriver` is the standard CDP automation flag.\n * SpecOverlayAction must never self-trigger a capture loop in this case:\n * doing so competed with the very capture session rendering the page for\n * network activity, keeping `networkidle` from ever being reached.\n */\nfunction isAutomatedCaptureSession(): boolean {\n return typeof navigator !== 'undefined' && navigator.webdriver === true\n}\n\nfunction currentChromeTheme(): 'light' | 'dark' {\n const root = document.documentElement\n if (root.classList.contains('dark') || root.getAttribute('data-theme') === 'dark') return 'dark'\n if (root.classList.contains('light') || root.getAttribute('data-theme') === 'light') return 'light'\n return 'light'\n}\n\n/** Marks the drawer portal so the page raster leaves it out. */\nconst SPEC_OVERLAY_ROOT_ATTR = 'data-spec-overlay-root'\n\n/**\n * The viewer's real view: rasterize THIS page in the browser (DOM → canvas,\n * no permission prompt) at viewport size, without the Spec drawer, and send it\n * to Specs as the LIVE side of a compare. Their org, data and theme are\n * exactly what is on screen, cropped to the content region. Nothing but the PNG\n * and page facts leaves the browser.\n */\nasync function captureMyView(\n status: Extract<SpecOverlayStatus, { matched: true }>,\n orgId: string | null | undefined,\n orgName: string | null | undefined,\n): Promise<void> {\n const { domToCanvas } = await import('modern-screenshot')\n const w = window.innerWidth\n const h = window.innerHeight\n const theme = currentChromeTheme()\n const bg = getComputedStyle(document.body).backgroundColor || (theme === 'dark' ? '#0b0b0c' : '#ffffff')\n const full = await domToCanvas(document.body, {\n width: w,\n height: h,\n scale: 1,\n backgroundColor: bg,\n // Cross-origin images that refuse CORS render blank instead of failing.\n fetch: { requestInit: { mode: 'cors', credentials: 'omit' }, placeholderImage: '' },\n // Drop the Spec drawer and everything fixed (sidebar, toasts, popovers):\n // the design is the page body only, so chrome would only add noise.\n filter: (node) =>\n !(node instanceof Element) ||\n (!node.hasAttribute(SPEC_OVERLAY_ROOT_ATTR) && getComputedStyle(node).position !== 'fixed'),\n style: { transform: `translate(${-window.scrollX}px, ${-window.scrollY}px)` },\n })\n\n // Score the content region only — the target's live_selector, else the\n // shell's content column (below the top bar and beta banner, right of the\n // sidebar) — so LIVE covers the same region as the design export.\n const el =\n (status.live_selector ? document.querySelector(status.live_selector) : null) ??\n document.querySelector('[data-shell-content]')\n let region = { x: 0, y: 0, width: w, height: h }\n if (el) {\n const r = el.getBoundingClientRect()\n const x = Math.max(0, Math.round(r.left))\n const y = Math.max(0, Math.round(r.top))\n region = { x, y, width: Math.min(w - x, Math.round(r.width)), height: Math.min(h - y, Math.round(r.height)) }\n }\n const out = document.createElement('canvas')\n out.width = region.width\n out.height = region.height\n const ctx = out.getContext('2d')\n if (!ctx) throw new Error('page raster failed')\n ctx.drawImage(full, region.x, region.y, region.width, region.height, 0, 0, region.width, region.height)\n const blob = await new Promise<Blob | null>((resolve) => out.toBlob(resolve, 'image/png'))\n if (!blob) throw new Error('page raster failed')\n const form = new FormData()\n form.append('image', blob, 'live.png')\n form.append(\n 'meta',\n JSON.stringify({ url: window.location.href, theme, org_id: orgId ?? null, org_name: orgName ?? null, crop: null }),\n )\n const res = await fetch(status.capture_url ?? `${SPECS_ORIGIN}/api/overlay/capture`, {\n method: 'POST',\n credentials: 'include',\n headers: { 'X-Spec-Capture': '1' },\n body: form,\n signal: AbortSignal.timeout(10_000),\n })\n if (!res.ok) throw new Error(`capture ${res.status}: ${(await res.text()).slice(0, 160)}`)\n}\n\n/** Spinner + LIVE/DIFF skeletons shown while the capture and compare run. */\nexport function SpecCaptureLoading() {\n return (\n <div data-spec-capture-loading=\"\" role=\"status\" aria-live=\"polite\" className=\"flex-1 overflow-hidden px-4 py-4\">\n <div className=\"mb-4 flex items-center gap-3 text-sm text-[color:var(--foreground)]\">\n <span\n aria-hidden=\"true\"\n className=\"inline-block h-5 w-5 animate-spin rounded-full border-2 border-[color:var(--line)] border-t-[color:var(--color-accent)] motion-reduce:animate-none\"\n />\n Capturing your view and comparing…\n </div>\n {['Live — your view', 'Diff'].map((label) => (\n <div key={label} className=\"mb-4\">\n <p className=\"mb-1 text-xs font-semibold uppercase tracking-wide text-[color:var(--muted)]\">{label}</p>\n <div aria-hidden=\"true\" className=\"h-40 w-full animate-pulse rounded border border-[color:var(--line)] bg-[color:var(--panel)] motion-reduce:animate-none\" />\n </div>\n ))}\n </div>\n )\n}\n\n/** Status URL for this page in the viewer's current theme. */\nfunction specOverlayStatusPath(): string {\n return `/api/overlay/status?url=${encodeURIComponent(window.location.href)}&theme=${currentChromeTheme()}`\n}\n\nexport function SpecOverlayAction({ orgId, orgName }: { orgId?: string | null; orgName?: string | null } = {}) {\n const [access, setAccess] = useState<SpecOverlayAccess | null>(() => readSpecOverlayAccessCache())\n const [status, setStatus] = useState<SpecOverlayStatus | null>(null)\n const [open, setOpen] = useState(false)\n const [capture, setCapture] = useState<{ state: 'idle' | 'busy' | 'error'; message?: string }>({ state: 'idle' })\n const [frameKey, setFrameKey] = useState(0)\n const [copied, setCopied] = useState<'idle' | 'copied' | 'failed'>('idle')\n const href = useLocationHref()\n const automated = isAutomatedCaptureSession()\n\n // Resolve access once per session (cached in sessionStorage).\n useEffect(() => {\n if (access || automated) return\n let cancelled = false\n specOverlayFetchJson('/api/overlay/access')\n .then((data) => {\n if (cancelled) return\n const next: SpecOverlayAccess =\n data && typeof (data as SpecOverlayAccess).allowed === 'boolean'\n ? (data as SpecOverlayAccess)\n : { allowed: false }\n setAccess(next)\n writeSpecOverlayAccessCache(next)\n })\n .catch(() => {\n if (cancelled) return\n const next: SpecOverlayAccess = { allowed: false }\n setAccess(next)\n writeSpecOverlayAccessCache(next)\n })\n return () => {\n cancelled = true\n }\n }, [access])\n\n // Fetch status for the current page, debounced 300ms, on every route\n // change and org change. Only once access is known to be allowed.\n useEffect(() => {\n if (automated || !access?.allowed || typeof window === 'undefined') return\n const timer = window.setTimeout(() => {\n specOverlayFetchJson(specOverlayStatusPath())\n .then((data) => setStatus(data as SpecOverlayStatus))\n .catch(() => setStatus(null))\n }, 300)\n return () => window.clearTimeout(timer)\n }, [access?.allowed, href, orgId])\n\n // Opening the drawer captures the viewer's real view automatically — no\n // click, no prompt. The raster runs while the drawer is open; the drawer is\n // filtered out of the frame. One capture per open.\n const captureRun = useRef(0)\n // Live-read access inside the retry loop below: access can be revoked\n // mid-poll (session expiry, org switch), and the loop must stop hitting\n // /api/overlay/status the moment that happens rather than riding out its\n // full 45 × 3s budget regardless.\n const accessRef = useRef(access)\n accessRef.current = access\n const runCapture = async (s: Extract<SpecOverlayStatus, { matched: true }>) => {\n const run = ++captureRun.current\n const before = s.live_source === 'viewer' ? s.finished_at : null\n setCapture({ state: 'busy' })\n try {\n // Let the drawer paint first so the page is idle while we raster.\n await new Promise((r) => setTimeout(r, 150))\n await captureMyView(s, orgId, orgName)\n for (let i = 0; i < 45; i++) {\n await new Promise((r) => setTimeout(r, 3000))\n if (run !== captureRun.current) return\n // Access lost mid-poll: stop, but never leave the spinner up forever.\n if (!accessRef.current?.allowed) {\n setCapture({ state: 'idle' })\n return\n }\n const next = (await specOverlayFetchJson(specOverlayStatusPath()).catch(() => null)) as SpecOverlayStatus | null\n if (next && next.matched && next.live_source === 'viewer' && next.finished_at !== before) {\n setStatus(next)\n setFrameKey((k) => k + 1)\n setCapture({ state: 'idle' })\n return\n }\n }\n setCapture({ state: 'error', message: 'Compare did not finish in 2 min.' })\n } catch (e) {\n if (run === captureRun.current) setCapture({ state: 'error', message: e instanceof Error ? e.message : String(e) })\n }\n }\n useEffect(() => {\n if (automated || !open || !status || !status.matched) return\n void runCapture(status)\n return () => {\n captureRun.current++\n }\n // Only re-run on open / page change, not on every status refresh.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, status && status.matched ? status.target_id : null])\n\n\n if (automated || !access?.allowed) return null\n\n const hasScore = status && status.matched && typeof status.mismatch_pct === 'number'\n const badgeLabel =\n hasScore ? `${Math.round((status as Extract<SpecOverlayStatus, { matched: true }>).mismatch_pct as number)}%` : status ? '—' : undefined\n const badgeTone: 'default' | 'warning' | 'danger' =\n hasScore ? (status && status.matched && status.passed ? 'default' : 'danger') : 'default'\n\n return (\n <>\n <button\n type=\"button\"\n aria-label=\"Spec\"\n aria-expanded={open}\n className={topBarIconButtonClass(badgeTone)}\n onClick={() => setOpen(true)}\n >\n <LayoutGlyph size={TOPBAR_GLYPH_SIZE} className=\"text-current\" />\n {badgeLabel ? (\n <span\n className={[\n 'absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-normal leading-none text-[#FFFFFF]',\n hasScore\n ? status && status.matched && status.passed\n ? 'bg-[color:var(--chrome-success,#2f855a)]'\n : 'bg-[color:var(--chrome-danger)]'\n : 'bg-[color:var(--muted)]',\n ].join(' ')}\n >\n {badgeLabel}\n </span>\n ) : null}\n {!open ? (\n <TopBarTooltip\n title=\"Spec\"\n description=\"Spec design + visual regression for this page.\"\n />\n ) : null}\n </button>\n {open && typeof document !== 'undefined'\n ? createPortal(\n <div\n className=\"fixed inset-0 z-50 flex justify-end bg-black/40\"\n {...{ [SPEC_OVERLAY_ROOT_ATTR]: '' }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Spec overlay\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) setOpen(false)\n }}\n onKeyDown={(e) => {\n if (e.key === 'Escape') setOpen(false)\n }}\n >\n <div className=\"flex h-full w-full max-w-[480px] flex-col border-l border-[color:var(--line)] bg-[color:var(--panel-elevated)] shadow-[var(--shadow-soft)]\">\n <div className=\"flex items-center justify-between gap-2 border-b border-[color:var(--line)] px-4 py-3\">\n <h2 className=\"truncate text-sm font-bold tracking-[-0.01em] text-[color:var(--foreground)]\">\n Spec{status && status.matched ? `: ${status.spec_title}` : ''}\n </h2>\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={() => setOpen(false)}\n className=\"rounded-full p-1 text-[color:var(--muted)] hover:bg-[color:var(--panel)] hover:text-[color:var(--foreground)]\"\n >\n <CloseGlyph size={16} />\n </button>\n </div>\n {status && status.matched ? (\n <>\n <div className=\"flex items-center gap-3 border-b border-[color:var(--line)] px-4 py-2 text-xs font-semibold\">\n <a\n href={status.spec_url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n Open spec ↗\n </a>\n <a\n href={status.compare_url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n Compare tab ↗\n </a>\n <button\n type=\"button\"\n disabled={capture.state === 'busy'}\n onClick={() => void runCapture(status)}\n className=\"ml-auto rounded-md border border-[color:var(--line)] px-2 py-1 text-[color:var(--foreground)] hover:bg-[color:var(--panel)] disabled:opacity-60\"\n title=\"Your view is captured when the drawer opens. Recapture after changing the page.\"\n >\n {capture.state === 'busy' ? 'Capturing…' : 'Recapture'}\n </button>\n <button\n type=\"button\"\n data-spec-copy-prompt=\"\"\n disabled={capture.state === 'busy' || !status.prompt}\n onClick={() => {\n const text = status.prompt\n if (!text) return\n // The prompt is already in hand, so the write stays inside the click gesture.\n navigator.clipboard\n .writeText(text)\n .then(() => setCopied('copied'))\n .catch(() => setCopied('failed'))\n .finally(() => window.setTimeout(() => setCopied('idle'), 2000))\n }}\n className=\"rounded-md border border-[color:var(--line)] px-2 py-1 text-[color:var(--foreground)] hover:bg-[color:var(--panel)] disabled:opacity-60\"\n title=\"Copy a repair prompt for an AI agent: spec, score, image links, top mismatched regions and instructions.\"\n >\n {copied === 'copied' ? 'Copied ✓' : copied === 'failed' ? 'Copy failed' : 'Copy prompt'}\n </button>\n </div>\n {status.live_size && status.design_size && capture.state !== 'busy' ? (\n <p\n data-spec-sizes=\"\"\n className={[\n 'border-b border-[color:var(--line)] px-4 py-1.5 text-xs',\n status.live_size.width === status.design_size.width &&\n status.live_size.height === status.design_size.height\n ? 'text-[color:var(--muted)]'\n : 'font-semibold text-[color:var(--chrome-danger)]',\n ].join(' ')}\n >\n Live {status.live_size.width}×{status.live_size.height} · Design {status.design_size.width}×\n {status.design_size.height}\n {status.live_size.width === status.design_size.width &&\n status.live_size.height === status.design_size.height\n ? ' · sizes match'\n : ' · SIZE MISMATCH'}\n </p>\n ) : null}\n {capture.state === 'error' ? (\n <p className=\"border-b border-[color:var(--line)] px-4 py-2 text-xs text-[color:var(--chrome-danger)]\">\n {capture.message}\n </p>\n ) : null}\n {capture.state === 'busy' ? (\n <SpecCaptureLoading />\n ) : (\n <iframe\n key={frameKey}\n src={status.overlay_url}\n title=\"Spec overlay\"\n className=\"h-full w-full flex-1 border-0\"\n />\n )}\n </>\n ) : status && !status.matched ? (\n <div className=\"p-4 text-sm text-[color:var(--muted)]\">\n <p>No compare target covers this page.</p>\n <a\n href={status.search_url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-2 inline-block font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n Search specs ↗\n </a>\n </div>\n ) : (\n <div className=\"p-4\">\n <ValueSkeleton className=\"h-4 w-full\" />\n </div>\n )}\n </div>\n </div>,\n document.body,\n )\n : null}\n </>\n )\n}\n\nfunction CloseGlyph({ size = 16, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\n// ---------------------------------------------------------------------------\n// NavDisplayAction — the Menu / Tabs / Both navigation-display switcher.\n// Controlled: the app owns persistence (localStorage/profile) and layout\n// consequences (sub-menu visibility, tab strip visibility).\n// ---------------------------------------------------------------------------\n\nexport type NavDisplayMode = 'menu' | 'tabs' | 'both'\n\nexport const NAV_DISPLAY_OPTIONS: { value: NavDisplayMode; label: string }[] = [\n { value: 'menu', label: 'Sub Menu' },\n { value: 'tabs', label: 'Tabs Only' },\n { value: 'both', label: 'Both' },\n]\n\nexport function NavDisplayAction({\n value,\n onChange,\n}: {\n value: NavDisplayMode\n onChange: (next: NavDisplayMode) => void\n}) {\n return (\n <TopBarPopover\n label=\"Navigation Display\"\n description=\"Show navigation as a sub-menu, tabs, or both.\"\n fallbackIcon={LayoutGlyph}\n panelClassName=\"w-44\"\n >\n <div className=\"py-1\" role=\"radiogroup\" aria-label=\"Navigation display\">\n {NAV_DISPLAY_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={value === opt.value}\n onClick={() => onChange(opt.value)}\n className={[\n 'flex w-full items-center justify-between px-4 py-2 text-left text-sm font-medium',\n value === opt.value\n ? 'text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n {opt.label}\n {value === opt.value ? <span aria-hidden>✓</span> : null}\n </button>\n ))}\n </div>\n </TopBarPopover>\n )\n}\n\n// ---------------------------------------------------------------------------\n// useThemePreference — the cross-app theme state machine (Task: theme derived\n// from the Auth system, live across tabs and apps).\n//\n// boot : cookie → localStorage → \"system\" (the pre-paint script already\n// painted this), then ONCE per session reconcile against the\n// profile value from `GET me` (authoritative) when a fetcher is\n// available.\n// change : apply + localStorage + cross-subdomain cookie + best-effort\n// `PATCH me/preferences { themePreference }`.\n// sync : same-app tabs via the `storage` event; other-app tabs re-read the\n// shared cookie on focus/visibility; `system` follows live OS\n// changes via matchMedia.\n// ---------------------------------------------------------------------------\n\nexport function useThemePreference(): {\n value: ThemePreference\n setValue: (next: ThemePreference) => void\n} {\n const ctx = useContext(NavChromeContext)\n const fetchJson = ctx?.fetchJson ?? null\n const [value, setValueState] = useState<ThemePreference>('system')\n const reconciled = useRef(false)\n\n // Boot: cookie → localStorage → system.\n useEffect(() => {\n const cookie = readThemeCookie()\n let ls: string | null = null\n try {\n ls = localStorage.getItem(THEME_STORAGE_KEY)\n } catch {\n /* unavailable */\n }\n const pref = cookie ?? (isThemePreference(ls) ? ls : null) ?? 'system'\n setValueState(pref)\n applyThemePreference(pref)\n }, [])\n\n // Once per session: converge on the profile's saved choice (authoritative),\n // reusing the provider's single `me` fetch.\n const meCtx = useContext(NavChromeContext)\n useEffect(() => {\n if (reconciled.current) return\n // A choice made where no chrome-API session exists (Politogy ID's login\n // screen) is still only in the cookie. Push it UP rather than pulling the\n // stale profile value DOWN — otherwise the user's fresh pick is silently\n // reverted on the next app they open (HITL 2026-07-23: \"I set System and it\n // keeps switching back to Light\").\n const pending = readPendingThemeChoice()\n if (pending) {\n // Only latch once the profile write has actually been attempted, so a\n // later `me` arrival still gets a chance to persist it.\n if (meCtx?.me) reconciled.current = true\n setValueState(pending)\n applyThemePreference(pending)\n writeThemeCookie(pending)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, pending)\n } catch {\n /* unavailable */\n }\n if (!meCtx?.me) return\n fetchJson?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ themePreference: pending }),\n })\n .then(() => clearPendingThemeChoice())\n .catch(() => {})\n return\n }\n const pref = meCtx?.me?.themePreference\n if (isThemePreference(pref)) {\n reconciled.current = true\n setValueState(pref)\n applyThemePreference(pref)\n writeThemeCookie(pref)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, pref)\n } catch {\n /* unavailable */\n }\n }\n }, [meCtx?.me])\n\n // Live sync: storage events (same-app tabs), focus/visibility cookie\n // re-reads (other-app tabs), and OS changes while on \"system\".\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === THEME_STORAGE_KEY && isThemePreference(e.newValue)) {\n setValueState(e.newValue)\n applyThemePreference(e.newValue)\n }\n }\n const onWake = () => {\n const cookie = readThemeCookie()\n if (cookie) {\n setValueState((prev) => {\n if (cookie !== prev) applyThemePreference(cookie)\n return cookie\n })\n }\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [])\n\n\n const setValue = useCallback(\n (next: ThemePreference) => {\n setValueState(next)\n applyThemePreference(next)\n writeThemeCookie(next)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, next)\n } catch {\n /* unavailable */\n }\n // Best-effort profile persistence — a theme toggle never errors. Until it\n // lands, the choice stays marked pending so the next app pushes it up\n // instead of reconciling the stale profile value back down.\n markThemeChoicePending(next)\n fetchJson?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ themePreference: next }),\n })\n .then(() => clearPendingThemeChoice())\n .catch(() => {})\n },\n [fetchJson],\n )\n\n return { value, setValue }\n}\n","import type { NavIcon } from './index'\nimport type { StandardNavIconKey } from './standardNav'\nimport {\n LuActivity,\n LuBriefcase,\n LuChartColumn,\n LuChartNoAxesColumn,\n LuCircleUser,\n LuClipboardList,\n LuClock,\n LuCreditCard,\n LuCrosshair,\n LuDollarSign,\n LuDoorOpen,\n LuFileText,\n LuFlag,\n LuHouse,\n LuLandmark,\n LuLayoutDashboard,\n LuLayoutGrid,\n LuLifeBuoy,\n LuList,\n LuMail,\n LuMap,\n LuMapPin,\n LuMessageSquare,\n LuMousePointerClick,\n LuPencil,\n LuPhone,\n LuSend,\n LuSettings,\n LuShare2,\n LuSignpost,\n LuTarget,\n LuUpload,\n LuUser,\n LuUsers,\n LuUsersRound,\n} from 'react-icons/lu'\n\n/**\n * The canonical icon map for standardPolitogyNav — ONE definition so every\n * app renders identical glyphs (including the Organization Settings branch:\n * briefcase / settings / creditCard / dollarSign / share).\n */\nexport const standardNavIcons: Record<StandardNavIconKey, NavIcon> = {\n home: LuHouse,\n users: LuUsers,\n mail: LuMail,\n messageSquare: LuMessageSquare,\n layout: LuLayoutDashboard,\n activity: LuActivity,\n lifeBuoy: LuLifeBuoy,\n grid: LuLayoutGrid,\n list: LuList,\n upload: LuUpload,\n edit: LuPencil,\n fileText: LuFileText,\n send: LuSend,\n clock: LuClock,\n user: LuUser,\n barChart: LuChartColumn,\n briefcase: LuBriefcase,\n settings: LuSettings,\n creditCard: LuCreditCard,\n dollarSign: LuDollarSign,\n share: LuShare2,\n // Campaign / Petition mode slots.\n phone: LuPhone,\n map: LuMap,\n mapPin: LuMapPin,\n target: LuTarget,\n flag: LuFlag,\n layoutDashboard: LuLayoutDashboard,\n usersRound: LuUsersRound,\n mousePointerClick: LuMousePointerClick,\n clipboardList: LuClipboardList,\n circleUser: LuCircleUser,\n crosshair: LuCrosshair,\n landmark: LuLandmark,\n chartNoAxes: LuChartNoAxesColumn,\n doorOpen: LuDoorOpen,\n signpost: LuSignpost,\n}\n","import { standardNavIcons } from './standardNavIcons'\nimport type { NavIcon, NavItem } from './index'\n\n// ---------------------------------------------------------------------------\n// standardPolitogyNav — the canonical Politogy VRM menu, per operating Mode.\n//\n// This is the single source of truth for the navigation every politogy app\n// renders. The RELATIONSHIP tree is extracted verbatim from VRM core's\n// relationship-mode sidebar (`getRelationshipLinkItems`); the CAMPAIGN and\n// PETITION trees mirror VRM core's mode-scoped menus. Apps consume the same\n// menu everywhere; an app that owns one of the items (e.g. the standalone\n// Contacts app) nests its own pages as that item's children while every other\n// entry links out to another *.politogyvrm.com app as an absolute URL —\n// full-page navigation with SSO shared across the domain.\n//\n// Which tree an app renders is NOT the user's live mode selection — it is the\n// app's own mode, mapped from the app registry (see `POLITOGY_APPS[app].mode`),\n// EXCEPT for a DUAL-MODE app (`POLITOGY_APPS[app].dual`, today: a2p — Specs/A2P:\n// \"the SMS/MMS delivery engine for Relationship Mode and Campaign Mode\"). A\n// dual app has no single fixed mode: its EFFECTIVE mode is resolved per-visit\n// by `resolveActiveMode` (mode-preference.ts) — `?mode=` query param on the\n// current URL → the `politogy_active_mode` cookie (written by every pinned app\n// and core whenever their own mode is known) → the app's own `dual.defaultMode`\n// — and THAT resolved value substitutes for `meta.mode` wherever this function\n// or the Mode pill would otherwise read it. A campaign-scoped, non-dual app\n// (phonebank / canvass / signs) always renders the Campaign tree; an unscoped\n// app (forms / surveys / polls / contacts) always renders Relationship, exactly\n// as before. Switching modes is a full-page navigation between mode homes (the\n// Mode pill's job), and each destination is itself pinned (or, for a2p,\n// resolved) — so the tree is deterministic from app identity + the mode\n// resolution above, never a value an app has to pass.\n// ---------------------------------------------------------------------------\n\n/**\n * Icon slots used by the standard menus. The shell stays icon-library-agnostic:\n * callers map each key to their own icon components (lucide, react-icons, …).\n * A missing key simply renders that row without an icon.\n */\nexport type StandardNavIconKey =\n | 'home'\n | 'users'\n | 'mail'\n | 'messageSquare'\n | 'layout'\n | 'activity'\n | 'lifeBuoy'\n | 'grid'\n | 'list'\n | 'upload'\n | 'edit'\n | 'fileText'\n | 'send'\n | 'clock'\n | 'user'\n | 'barChart'\n | 'briefcase'\n | 'settings'\n | 'creditCard'\n | 'dollarSign'\n | 'share'\n // Campaign / Petition mode slots.\n | 'phone'\n | 'map'\n | 'mapPin'\n | 'target'\n | 'flag'\n // Left-Navigation §9 Lucide slots.\n | 'layoutDashboard'\n | 'usersRound'\n | 'mousePointerClick'\n | 'clipboardList'\n | 'circleUser'\n | 'crosshair'\n | 'landmark'\n | 'chartNoAxes'\n | 'doorOpen'\n | 'signpost'\n\n/** The operating Mode whose nav tree to build. Defaults to `relationship`. */\nexport type StandardNavMode = 'relationship' | 'campaign' | 'petition'\n\n/**\n * Per-feature availability for the Campaign tree. Campaign Mode ships its apps\n * incrementally: a disabled feature is omitted from the nav entirely (rather\n * than rendered as a dead/disabled row), and its flag flips to `true` in a\n * later patch release as the app goes live. Dashboard and Voter Contact are\n * core-hosted and always present, so they carry no flag.\n */\nexport interface CampaignFeatureAvailability {\n a2p: boolean\n phonebank: boolean\n canvass: boolean\n signs: boolean\n tribes: boolean\n polling: boolean\n}\n\n/**\n * Launch state at this shell version: every Campaign feature is deployed and\n * live (a2p / phonebank / canvass / signs .politogyvrm.com all serve the app\n * behind SSO as of 2026-07-24), so no row is hidden. The flags remain so a\n * future feature can ship dark, and so a caller can hide one per-deployment.\n */\nexport const CAMPAIGN_FEATURE_AVAILABILITY: CampaignFeatureAvailability = {\n a2p: true,\n phonebank: true,\n canvass: true,\n signs: true,\n tribes: true,\n polling: true,\n}\n\n/** Absolute origins for the standalone Campaign / Petition apps. */\nconst A2P_ORIGIN = 'https://a2p.politogyvrm.com/'\nconst PHONEBANK_ORIGIN = 'https://phonebank.politogyvrm.com/'\nconst CANVASS_ORIGIN = 'https://canvass.politogyvrm.com/'\nconst SIGNS_ORIGIN = 'https://signs.politogyvrm.com/'\nconst POLLS_ORIGIN = 'https://polls.politogyvrm.com/'\n// app.politogyvrm.com (VRM core) is retired (Reference/UI-Platform →\n// \"Retirement of app.politogyvrm.com\", DECIDED 2026-10-07). These are its V2\n// replacements: Settings owns org settings/billing, Dashboard owns the\n// Relationship/Campaign dashboards and Battleground, auth owns the Politogy\n// ID account pages (my-profile, invite acceptance).\nconst SETTINGS_ORIGIN = 'https://settings.politogyvrm.com/'\nconst DASHBOARD_ORIGIN = 'https://dashboard.politogyvrm.com/'\nconst AUTH_ORIGIN = 'https://auth.politogyvrm.com/'\n// Tribes is a page inside the standalone Contacts app (Specs/Tribes: Tribes is\n// implemented as an extension of Contacts). Matches app-shell.tsx's `/tribes`.\nconst CONTACTS_TRIBES = 'https://contacts.politogyvrm.com/tribes'\n// Petition Mode is its own standalone app on its own subdomain (the petitions\n// repo deploys production to petition-mode.politogyvrm.com).\nconst PETITION_MODE_ORIGIN = 'https://petition-mode.politogyvrm.com/'\n\nexport interface StandardNavOptions {\n /**\n * @deprecated app.politogyvrm.com (VRM core) is retired (Reference/UI-Platform\n * → \"Retirement of app.politogyvrm.com\"). Every row this tree used to resolve\n * against VRM core now points at its V2 host directly, so this is unused.\n * Kept only so existing callers don't need to drop the field immediately.\n */\n coreBaseUrl?: string\n /** Icon component per slot; omitted slots render icon-less rows. */\n icons?: Partial<Record<StandardNavIconKey, NavIcon>>\n /**\n * App-local override for the \"Contacts\" item. `children` are used verbatim\n * (NOT absolutized) so the owning app nests its own routes; `href` (also\n * verbatim) feeds active-detection for the group header. When omitted, the\n * item carries VRM core's own contacts sub-pages as absolute links.\n * (Relationship tree only.)\n */\n contactsItem?: {\n href?: string\n children?: NavItem[]\n /**\n * Live contact count shown right-aligned on the Contacts row, already\n * formatted for display (\"31.9K\"). Only the owning app knows it.\n * (Specs/Contacts design: `Contacts · 31.9K`.)\n */\n count?: string | number | null\n }\n /**\n * Top-level rows to OMIT, by label (case-insensitive), e.g. `['Polls','CTAs']`.\n * The Specs/Contacts design rail lists Relationship → Collect → Account with\n * exactly Dashboard · Contacts · Email broadcast · SMS/MMS blast / Calls to\n * action · Forms · Surveys / My profile · Organization settings; apps that\n * still surface Polls / CTAs keep them by default. A section row with no\n * remaining items is dropped too.\n */\n hiddenItems?: string[]\n /**\n * App-local override for the Petition-mode \"Dashboard\" entry, same contract\n * as `contactsItem`: `href`/`children` used verbatim so the Petitions app\n * nests its own routes under the entry. (Petition tree only.)\n */\n petitionsItem?: { href?: string; children?: NavItem[] }\n /**\n * The trailing \"Support\" row. VRM core opens its SupportRequestModal here;\n * other apps supply their own handler (`onClick`) or a link (`href`).\n * Omitted or `false` → no Support row. Appended to every mode's tree.\n */\n supportItem?: { onClick?: () => void; href?: string } | false\n /**\n * Which mode's tree to build. Default `relationship`, whose output is\n * byte-for-byte what this function produced before modes existed.\n */\n mode?: StandardNavMode\n /**\n * Active organization id (full UUID). EVERY link in EVERY tree carries it as\n * `?org=<uuid>` — the same convention the Mode switcher and My Account menu\n * use — so the destination app opens on the same org instead of the user's\n * default one. Omit it only when the caller genuinely has no active org yet.\n */\n activeOrgId?: string | null\n /**\n * Per-feature Campaign availability overrides, merged over\n * `CAMPAIGN_FEATURE_AVAILABILITY`. Only meaningful for the Campaign tree.\n */\n campaignAvailability?: Partial<CampaignFeatureAvailability>\n}\n\n/**\n * Drop the top-level rows named in `hidden` (case-insensitive label match),\n * then any section row left with no rows beneath it.\n */\nfunction applyHiddenItems(items: NavItem[], hidden?: string[]): NavItem[] {\n if (!hidden || hidden.length === 0) return items\n const drop = new Set(hidden.map((h) => h.trim().toLowerCase()))\n const kept = items.filter((i) => i.kind === 'section' || !drop.has(i.label.toLowerCase()))\n return kept.filter((item, idx) => {\n if (item.kind !== 'section') return true\n const next = kept[idx + 1]\n return !!next && next.kind !== 'section'\n })\n}\n\n/**\n * One sub-item of a standalone app, as a path RELATIVE to that app's origin\n * (`''` is the app root). Resolved against the origin and given the active-org\n * query param, exactly like the parent row it hangs under.\n */\ntype CrossAppLeaf = { label: string; icon: StandardNavIconKey; path: string }\n\nconst CONTACTS_APP = 'https://contacts.politogyvrm.com'\n\nconst APP_CONTACTS_CHILDREN = [\n { label: 'Dashboard', icon: 'grid' as const, href: `${CONTACTS_APP}/` },\n { label: 'All Contacts', icon: 'list' as const, href: `${CONTACTS_APP}/contacts` },\n { label: 'Tribes', icon: 'users' as const, href: `${CONTACTS_APP}/tribes` },\n { label: 'Import', icon: 'upload' as const, href: `${CONTACTS_APP}/import` },\n { label: 'Fields', icon: 'layout' as const, href: `${CONTACTS_APP}/fields` },\n { label: 'Activity', icon: 'activity' as const, href: `${CONTACTS_APP}/activity` },\n { label: 'Duplicates', icon: 'fileText' as const, href: `${CONTACTS_APP}/duplicates` },\n]\n\n// Email Broadcast now points at the standalone Email Engine V2 app\n// (email.politogyvrm.com, Specs/Email-Engine six tabs + Deliverability). The\n// V1 surface inside VRM core stays reachable as the last child while both run\n// in parallel. Absolute hrefs so active-detection lights this group when the\n// user is inside the Email app (same pattern as Contacts / Forms / Surveys).\nconst EMAIL_APP = 'https://email.politogyvrm.com'\nconst APP_EMAIL_CHILDREN = [\n { label: 'Dashboard', icon: 'grid' as const, href: `${EMAIL_APP}/dashboard` },\n { label: 'Creative Canvas', icon: 'edit' as const, href: `${EMAIL_APP}/canvas` },\n { label: 'Sender Information', icon: 'mail' as const, href: `${EMAIL_APP}/sender` },\n { label: 'Recipients', icon: 'user' as const, href: `${EMAIL_APP}/recipients` },\n { label: 'Send & Automate', icon: 'send' as const, href: `${EMAIL_APP}/send` },\n { label: 'Statistics', icon: 'barChart' as const, href: `${EMAIL_APP}/statistics` },\n { label: 'Deliverability', icon: 'activity' as const, href: `${EMAIL_APP}/deliverability` },\n]\n// Organization Settings — promoted from the My Account menu into the left nav\n// (HITL directive 2026-07-23). Mirrors the main app's former page IA, now\n// served by the standalone Settings app (settings.politogyvrm.com, Specs/\n// Organization-Settings v12) rather than VRM core: /organization-settings/:tab,\n// with Subscription & Billing carrying its own third level\n// (/organization-settings/subscription-billing/:tab). This is the canonical\n// depth-3 example the nav renderers support.\ntype CoreBranch = CrossAppLeaf & { children?: CrossAppLeaf[] }\n\nconst ORG_SETTINGS_CHILDREN: CoreBranch[] = [\n { label: 'General', icon: 'settings', path: 'organization-settings' },\n {\n label: 'Subscription & Billing',\n icon: 'creditCard',\n path: 'organization-settings/subscription-billing',\n children: [\n { label: 'Current Plan', icon: 'fileText', path: 'organization-settings/subscription-billing/current-plan' },\n { label: 'SMS, MMS & Email Usage', icon: 'activity', path: 'organization-settings/subscription-billing/text-email' },\n { label: 'Wallet', icon: 'dollarSign', path: 'organization-settings/subscription-billing/wallet' },\n { label: '10DLC', icon: 'messageSquare', path: 'organization-settings/subscription-billing/10dlc' },\n { label: 'Billing History', icon: 'clock', path: 'organization-settings/subscription-billing/billing-history' },\n ],\n },\n { label: 'Email', icon: 'mail', path: 'organization-settings/email-settings' },\n { label: 'Users', icon: 'users', path: 'organization-settings/users' },\n { label: 'Shared Links', icon: 'share', path: 'organization-settings/shared-links' },\n]\n\n// The NEW standalone acquisition apps (forms./surveys./polls.politogyvrm.com)\n// replace the legacy in-core \"Forms & Surveys\" system (HITL directive\n// 2026-07-23; removal plan: politogy/docs/legacy-forms-removal-plan.md).\n// Absolute cross-app links — SSO carries the session.\nconst APP_FORMS_CHILDREN = [\n { label: 'Forms', icon: 'list' as const, href: 'https://forms.politogyvrm.com/?tab=forms' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://forms.politogyvrm.com/?tab=canvas' },\n { label: 'Submissions', icon: 'fileText' as const, href: 'https://forms.politogyvrm.com/?tab=submissions' },\n]\n// The Surveys sub-menu mirrors the app's tab strip: Surveys / Canvas / Results.\n// Canvas and Results are survey-scoped routes (/surveys/:id/canvas), so with no\n// survey selected the list page carries a ?view= param — distinct hrefs, so\n// active-detection singles out exactly one (identical hrefs were the earlier\n// all-active bug; query params ARE compared, hashes are not).\nconst APP_SURVEYS_CHILDREN = [\n { label: 'Surveys', icon: 'list' as const, href: 'https://surveys.politogyvrm.com/surveys' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://surveys.politogyvrm.com/surveys?view=canvas' },\n { label: 'Results', icon: 'barChart' as const, href: 'https://surveys.politogyvrm.com/surveys?view=results' },\n]\nconst APP_POLLS_CHILDREN = [\n { label: 'Command Center', icon: 'grid' as const, href: 'https://polls.politogyvrm.com/' },\n { label: 'New Poll', icon: 'edit' as const, href: 'https://polls.politogyvrm.com/polls/new' },\n]\n// Standalone CTAs app (ctas.politogyvrm.com, Specs/CTAs) — same pattern as\n// Forms/Surveys/Polls above. This is also now the target for the\n// \"Calls to action\" row in the Relationship tree (the legacy in-core feature\n// it used to render was retired with app.politogyvrm.com).\nconst APP_CTAS_CHILDREN = [\n { label: 'CTAs', icon: 'list' as const, href: 'https://ctas.politogyvrm.com/' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://ctas.politogyvrm.com/?tab=canvas' },\n]\n\n// ---------------------------------------------------------------------------\n// Campaign app sub-navigation.\n//\n// Reference/UI-Platform v13 (Left bar → Navigation): \"The canonical VRM nav\n// tree — PARENT GROUPS WITH SUB-ITEMS. The app's own pages nest under their\n// group.\" The Campaign tree shipped as eight flat rows with no `children`, so\n// the Navigation Display control's \"Both\" and \"Sub Menu\" modes had nothing to\n// expand in the left bar of a2p / phonebank / canvass / signs — the three modes\n// rendered an identical sidebar and the control looked broken.\n//\n// Each list below is the app's OWN section list, taken verbatim from that app's\n// in-app tab strip (its `components/Shell.tsx`), so the sidebar sub-menu and the\n// page tab strip name the same sections in the same order — the sidebar/tab\n// agreement Reference/UI-Platform exists to enforce.\n// ---------------------------------------------------------------------------\n\n/** a2p/components/Shell.tsx `TABS` — the six A2P tabs. */\nconst APP_A2P_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: 'dashboard' },\n { label: 'Compose', icon: 'edit', path: 'compose' },\n { label: 'Recipients', icon: 'user', path: 'recipients' },\n { label: 'Tech Check', icon: 'activity', path: 'tech-check' },\n { label: 'Status', icon: 'clock', path: 'status' },\n { label: 'Conversations', icon: 'messageSquare', path: 'conversations' },\n]\n\n/** phonebank/components/Shell.tsx `NAV` — the Manager console's sections. */\nconst APP_PHONEBANK_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '' },\n { label: 'Campaigns', icon: 'phone', path: 'campaigns' },\n { label: 'Inbound', icon: 'messageSquare', path: 'inbound' },\n { label: 'Reports', icon: 'barChart', path: 'reports' },\n]\n\n/** canvass/components/Shell.tsx `SECTIONS` — the manager console's sections. */\nconst APP_CANVASS_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '' },\n { label: 'Campaigns', icon: 'target', path: 'campaigns' },\n { label: 'Canvassers', icon: 'users', path: 'canvassers' },\n]\n\n/**\n * signs/components/Shell.tsx `SECTIONS`. Review Queue is Manager+ in the app's\n * tab strip; the shared tree carries no role input, so the row is listed for\n * everyone and the ROUTE enforces it — /review renders a \"available to Managers\n * and Admins\" notice and loads no queue data for a volunteer (signs\n * app/review/page.tsx). Listing it keeps sidebar and tab strip identical for the\n * managers who use it rather than re-opening per-app nav drift.\n */\nconst APP_SIGNS_CHILDREN: CrossAppLeaf[] = [\n { label: 'Map', icon: 'map', path: '' },\n { label: 'Placements', icon: 'list', path: 'placements' },\n { label: 'Review Queue', icon: 'fileText', path: 'review' },\n { label: 'Recovery', icon: 'flag', path: 'recovery' },\n { label: 'Reports', icon: 'barChart', path: 'reports' },\n]\n\n/**\n * Build the standard Politogy VRM menu for the given `mode` (default\n * `relationship`), in the exact order and wording the main app renders it. See\n * `StandardNavOptions` for the app-specific hooks (`contactsItem`,\n * `supportItem`) and the Campaign inputs (`activeOrgId`, `campaignAvailability`).\n */\nexport function standardPolitogyNav(opts: StandardNavOptions): NavItem[] {\n // Left-Navigation §8.1: every row is a Lucide icon + label. Callers may\n // override per slot; otherwise the shared Lucide map applies.\n const icon = (key: StandardNavIconKey): NavIcon | undefined => opts.icons?.[key] ?? standardNavIcons[key]\n\n // EVERY link this tree emits leaves the current app (core routes are\n // cross-app for a standalone app, and the app-owned rows are supplied by the\n // caller), so each one carries the active org as `?org=<full-uuid>` — the\n // full id is the only collision-free selector (contacts-api matches exact id\n // first, then a short suffix that can collide across a user's orgs). Without\n // it a multi-org user following a bare cross-app link lands in whatever org\n // the destination defaults to; the cookie is only the fallback for a bare\n // URL, the param is the explicit selector. Active-detection ignores `org`\n // (isNavItemActive's ACTIVE_IGNORED_PARAMS) so stamping it selects nothing\n // differently, and it keeps the org in the address bar for bookmarking.\n const orgParam = opts.activeOrgId ? `org=${opts.activeOrgId}` : ''\n const withOrg = (url: string): string =>\n orgParam ? `${url}${url.includes('?') ? '&' : '?'}${orgParam}` : url\n\n const leaves = (origin: string, children: CrossAppLeaf[]): NavItem[] =>\n appLeaves(origin, children)\n const branches = (origin: string, children: CoreBranch[]): NavItem[] => {\n const o = origin.replace(/\\/+$/, '')\n return children.map((c) => ({\n label: c.label,\n icon: icon(c.icon),\n href: withOrg(`${o}/${c.path}`),\n children: c.children ? leaves(origin, c.children) : undefined,\n }))\n }\n\n // Sub-items of a standalone app: `origin` + the app-relative path, carrying\n // the active org the way the parent row does. Trailing slash on the origin\n // is normalized so `''` yields the app root and `x` yields `/x`. An optional\n // `modeParam` (a DUAL app entered from a mode other than its own default,\n // e.g. the Relationship tree's a2p row) is stamped on every leaf too, so the\n // destination resolves the same mode the row that got you there was in.\n const appLeaves = (\n origin: string,\n children: CrossAppLeaf[],\n modeParam?: StandardNavMode,\n ): NavItem[] => {\n const base = origin.replace(/\\/+$/, '')\n return children.map((c) => {\n const url = c.path ? `${base}/${c.path}` : `${base}/`\n const withMode = modeParam ? `${url}${url.includes('?') ? '&' : '?'}mode=${modeParam}` : url\n return { label: c.label, icon: icon(c.icon), href: withOrg(withMode) }\n })\n }\n\n // Left-Navigation §9.4: ACCOUNT is the last section in every mode.\n const accountRows = (): NavItem[] => [\n { kind: 'section', label: 'Account' },\n // My Profile moved to the Politogy ID account app (auth.politogyvrm.com)\n // with the retirement of app.politogyvrm.com.\n { label: 'My profile', icon: icon('circleUser'), href: withOrg(`${AUTH_ORIGIN}my-profile`) },\n {\n label: 'Organization settings',\n icon: icon('settings'),\n // Organization settings moved to the standalone Settings app\n // (settings.politogyvrm.com, Specs/Organization-Settings v12).\n href: withOrg(`${SETTINGS_ORIGIN}organization-settings`),\n children: branches(SETTINGS_ORIGIN, ORG_SETTINGS_CHILDREN),\n },\n ]\n\n const buildRelationship = (): NavItem[] => {\n const contacts: NavItem = opts.contactsItem\n ? {\n label: 'Contacts',\n icon: icon('usersRound'),\n href: opts.contactsItem.href,\n children: opts.contactsItem.children,\n badge: opts.contactsItem.count ?? undefined,\n }\n : {\n label: 'Contacts',\n icon: icon('usersRound'),\n href: withOrg(`${CONTACTS_APP}/`),\n children: APP_CONTACTS_CHILDREN.map((c) => ({\n label: c.label,\n icon: icon(c.icon),\n href: withOrg(c.href),\n })),\n }\n\n // Specs/Contacts design rail (Reference/UI-Platform → Left bar: section\n // rows via `kind: 'section'`, sentence-case labels). Three groups:\n // RELATIONSHIP Dashboard · Contacts · Email broadcast · SMS/MMS blast\n // COLLECT Calls to action · Forms · Surveys (· Polls · CTAs)\n // ACCOUNT My profile · Organization settings\n return [\n { kind: 'section', label: 'Relationship' },\n // Dashboard moved to the standalone Dashboard app (dashboard.politogyvrm.com,\n // Specs/Relationship-Dashboard) with the retirement of app.politogyvrm.com.\n { label: 'Dashboard', icon: icon('layoutDashboard'), href: withOrg(DASHBOARD_ORIGIN) },\n contacts,\n {\n label: 'Email broadcast',\n icon: icon('mail'),\n href: withOrg(`${EMAIL_APP}/dashboard`),\n children: APP_EMAIL_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n // SMS/MMS Blast is the a2p app entered in RELATIONSHIP mode (a2p is\n // dual-mode; Specs/A2P). The `?mode=relationship` param pins the\n // destination's tree so the row that got you there is the row that\n // lights up on arrival.\n label: 'SMS/MMS blast',\n icon: icon('messageSquare'),\n href: withOrg(`${A2P_ORIGIN}?mode=relationship`),\n children: appLeaves(A2P_ORIGIN, APP_A2P_CHILDREN, 'relationship'),\n },\n { kind: 'section', label: 'Collect' },\n // Calls to action moved to the standalone CTAs app (ctas./runtime.\n // politogyvrm.com, Specs/CTAs) with the retirement of app.politogyvrm.com.\n {\n label: 'Calls to action',\n icon: icon('mousePointerClick'),\n href: withOrg('https://ctas.politogyvrm.com/'),\n children: APP_CTAS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Forms',\n icon: icon('fileText'),\n href: withOrg('https://forms.politogyvrm.com/'),\n children: APP_FORMS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Surveys',\n icon: icon('clipboardList'),\n href: withOrg('https://surveys.politogyvrm.com/surveys'),\n children: APP_SURVEYS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n // Polls (polls.politogyvrm.com) — kept in the default Collect section;\n // apps that want it hidden pass `hiddenItems: ['Polls']`. Regression:\n // dropped entirely in 03c4dc2 when app.politogyvrm.com retired; restored\n // here (this row is independent of the retired app).\n {\n label: 'Polls',\n icon: icon('chartNoAxes'),\n href: withOrg(POLLS_ORIGIN),\n children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n ...accountRows(),\n ]\n }\n\n // Campaign tree — Dashboard + the 7 Campaign Mode features. Dashboard and\n // Voter Contact are core-hosted (VRM core /campaign/*); the rest link out to\n // standalone apps and are gated by CAMPAIGN_FEATURE_AVAILABILITY.\n const buildCampaign = (): NavItem[] => {\n const avail: CampaignFeatureAvailability = {\n ...CAMPAIGN_FEATURE_AVAILABILITY,\n ...opts.campaignAvailability,\n }\n type Gated = NavItem & { flag?: keyof CampaignFeatureAvailability }\n const rows: Gated[] = [\n // Left-Navigation §9.2: Race data -> Research -> GOTV -> Account.\n // Battleground is the Campaign landing page; there is no Campaign\n // Dashboard row, and Voter Contact and Tribes have no row.\n { kind: 'section', label: 'Race data' },\n // Battleground moved to the Dashboard app (dashboard.politogyvrm.com)\n // until a dedicated Battleground host is decided (UI-Platform route table).\n { label: 'Battleground', icon: icon('crosshair'), href: withOrg(`${DASHBOARD_ORIGIN}battleground`) },\n // District data moved to the Dashboard app (dashboard.politogyvrm.com)\n // per Reference/UI-Platform v44.\n { label: 'District data', icon: icon('landmark'), href: withOrg(`${DASHBOARD_ORIGIN}districts`) },\n { kind: 'section', label: 'Research' },\n {\n label: 'Polling',\n icon: icon('chartNoAxes'),\n href: withOrg(POLLS_ORIGIN),\n children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n flag: 'polling',\n },\n { kind: 'section', label: 'GOTV' },\n {\n label: 'Field canvassing',\n icon: icon('doorOpen'),\n href: withOrg(CANVASS_ORIGIN),\n children: appLeaves(CANVASS_ORIGIN, APP_CANVASS_CHILDREN),\n flag: 'canvass',\n },\n {\n label: 'Phone banking',\n icon: icon('phone'),\n href: withOrg(PHONEBANK_ORIGIN),\n children: appLeaves(PHONEBANK_ORIGIN, APP_PHONEBANK_CHILDREN),\n flag: 'phonebank',\n },\n {\n label: 'A2P texting',\n icon: icon('messageSquare'),\n href: withOrg(A2P_ORIGIN),\n children: appLeaves(A2P_ORIGIN, APP_A2P_CHILDREN),\n flag: 'a2p',\n },\n {\n label: 'Sign mapping',\n icon: icon('signpost'),\n href: withOrg(SIGNS_ORIGIN),\n children: appLeaves(SIGNS_ORIGIN, APP_SIGNS_CHILDREN),\n flag: 'signs',\n },\n ...accountRows(),\n ]\n const kept = rows\n .filter((r) => !r.flag || avail[r.flag])\n .map(({ flag: _flag, ...item }) => item as NavItem)\n // Drop a section left with no rows under it (e.g. Research when polling is off).\n return kept.filter((item, idx) => {\n if (item.kind !== 'section') return true\n const next = kept[idx + 1]\n return !!next && next.kind !== 'section'\n })\n }\n\n // Petition tree — the Petition Mode home (its own standalone app). The\n // Petitions app nests its own routes via `petitionsItem` (the contactsItem\n // contract); everyone else gets the minimal cross-app link. Labeled\n // Dashboard so the shared breadcrumb trail anchors correctly.\n const buildPetition = (): NavItem[] => [\n opts.petitionsItem\n ? {\n label: 'Dashboard',\n icon: icon('home'),\n href: opts.petitionsItem.href ?? withOrg(PETITION_MODE_ORIGIN),\n children: opts.petitionsItem.children,\n }\n : { label: 'Dashboard', icon: icon('home'), href: withOrg(PETITION_MODE_ORIGIN) },\n ]\n\n const mode = opts.mode ?? 'relationship'\n const built =\n mode === 'campaign'\n ? buildCampaign()\n : mode === 'petition'\n ? buildPetition()\n : buildRelationship()\n const items = applyHiddenItems(built, opts.hiddenItems)\n\n if (opts.supportItem) {\n items.push({\n label: 'Support',\n icon: icon('lifeBuoy'),\n href: opts.supportItem.href,\n onClick: opts.supportItem.onClick,\n })\n }\n\n return items\n}\n","// ---------------------------------------------------------------------------\n// Framework-agnostic chrome (sidebar + top navbar) for @the-portland-company/shell.\n//\n// The other chrome in this package (ShellChrome, Sidebar, Header, …) is built\n// on Chakra UI v2 + react-router and targets Vite SPAs. That stack cannot be\n// imported into a Next.js / React 19 / Tailwind app. This \"native\" module is a\n// dependency-light alternative: pure React (no Chakra, no emotion, no\n// react-router, no icon library) whose styling is driven entirely by the CSS\n// design tokens shipped in `@the-portland-company/shell/chrome.css`.\n//\n// It is a FAITHFUL VISUAL TWIN of the Chakra chrome (Sidebar.tsx / Header.tsx /\n// OrgPill / ModePill / NavItem / UserMenu): same 240px sidebar, brand-logo\n// slot, \"ORGANIZATION\" org pill, mode pill, solid active nav rows, pipe-\n// separated footer links + commit string, and an avatar+name+email+chevron user\n// menu — so an app rendering this looks identical to the main VRM app.\n//\n// Every app concern (nav items, org, mode, user, links, icons, the routing\n// Link component, the theme toggle) is injected via props, so both the Contacts\n// app (Next.js) and the VRM app could consume the same components.\n// ---------------------------------------------------------------------------\n\nimport type { ComponentType, CSSProperties, KeyboardEvent as ReactKeyboardEvent, ReactNode } from 'react'\nimport { Fragment, createContext, useContext, useEffect, useMemo, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport { useTopBarIconSlotGlyph, type TopBarIconSlot } from '../lib/topbarIconSlot'\nimport { resolveBrandGlyph } from '../lib/brandGlyphs'\nimport { warnDeprecated } from '../lib/deprecation'\nimport { filterOrgs, shouldShowOrgFilter } from './orgFilter'\nimport { orgIdTail } from '../active-org'\nimport { readRailPreference, writeRailPreference } from '../nav-preference'\nimport { SpeculationRulesScript } from '../speculation/SpeculationRulesScript'\nimport {\n topBarIconButtonClass,\n TopBarTooltip,\n TopBarPanelArrow,\n NavThemeControl,\n resolveOrgLogoUrl,\n NAV_DISPLAY_OPTIONS,\n TOPBAR_GLYPH_SIZE,\n type ThemePreference,\n type NavDisplayMode,\n} from './chromeActions'\n\n// Data-backed top-bar widgets (Fuel, Notifications, Support, Nav-display) +\n// the injected-fetcher provider they hang off. One implementation for every app.\nexport {\n NavChromeProvider,\n CORE_APP_ORIGIN,\n CORE_BILLING_PATH,\n SPECS_ORIGIN,\n FuelAction,\n NotificationsAction,\n SupportAction,\n SpecOverlayAction,\n NavDisplayAction,\n NavThemeControl,\n TopBarCountBadge,\n TopBarPanelArrow,\n TopBarTooltip,\n TopBarWidgetSlot,\n TopBarPopover,\n topBarIconButtonClass,\n resolveOrgLogoUrl,\n useChromeMe,\n useChromeOrgs,\n useNavChromeFetcher,\n useNavChromeDedupedFetch,\n useThemePreference,\n} from './chromeActions'\nexport type {\n ChromeMe,\n NavChromeFetcher,\n NavDisplayMode,\n ThemePreference,\n ChromeOrgSummary,\n ChromeNotificationsPayload,\n ChromeNotificationAlert,\n ChromeNotificationReply,\n ChromeNotificationImport,\n ChromeNotificationQuarantine,\n CommunicationsFuelStatus,\n FuelChannelStatus,\n} from './chromeActions'\n\n// An icon is any component that accepts an optional size + className. This\n// matches both `lucide-react` and `react-icons` icon signatures, so consuming\n// apps pass their own icon set without this package depending on one.\nexport type NavIcon = ComponentType<{ size?: number; className?: string; strokeWidth?: number }>\n\nexport type NavItem = {\n /**\n * What this row IS. Defaults to `'link'` — every existing `NavItem[]` keeps\n * its exact type and rendering.\n *\n * `'section'` is a non-interactive heading that groups the rows beneath it:\n * uppercase, muted, letterspaced, not focusable, no hover. Only `label` is\n * read; `href`, `icon`, `onClick` and `children` are ignored.\n *\n * The legacy chrome supported this and 0.43 dropped it, so apps faked it by\n * passing `disabled` rows with no href — which looks approximately right and\n * is wrong where it counts: a disabled row announces as an unavailable\n * CONTROL to a screen reader, when it is not a control at all. A section is\n * its own kind of row (Reference/UI-Platform → Left bar).\n *\n * Deliberately a widened field rather than a discriminated union: a union\n * would make `item.href` a type error for every existing consumer that reads\n * it, turning an additive feature into a breaking change.\n */\n kind?: 'link' | 'section'\n /** Route to link to. Optional when `onClick` is supplied (renders a button). */\n href?: string\n label: string\n icon?: NavIcon\n /**\n * When supplied the row renders as a `<button>` (styled identically to the\n * link rows) instead of a routed link — used for actions like \"Support\".\n */\n onClick?: () => void\n /**\n * Disables the row: non-interactive and dimmed, with `disabledTitle` shown as\n * a hover tooltip explaining why. Mirrors `NavTab`'s existing contract so a\n * gated row looks the same whether it renders in the sidebar or a tab strip.\n * Without this, an app that gates a section (VRM dims Email / SMS until setup\n * is complete) had no way to express it and the row rendered fully clickable\n * (shell-nav-handoff §3).\n */\n disabled?: boolean\n /** Tooltip for a disabled row — say why, and how to resolve it. */\n disabledTitle?: string\n /**\n * Right-aligned count/annotation on the row — e.g. the live contact count\n * on \"Contacts\" (`31.9K`). Pre-formatted by the app; the shell only draws\n * it (Specs/Contacts design rail). Omitted/null draws nothing.\n */\n badge?: string | number | null\n /**\n * Nested sub-items. When present, the row becomes an expandable GROUP header.\n * Clicking it always toggles the children open/closed and rotates the\n * right-aligned chevron; if the item ALSO carries an `onClick`, that runs too,\n * so a parent can navigate to its section dashboard while expanding\n * (shell-nav-handoff §2). An `href` alone never navigates from a group header. The sidebar runs a single-open accordion (opening one group closes\n * the others) and auto-expands whichever group contains the active route —\n * mirroring the main VRM app's Chakra sidebar. Children render as smaller nav\n * rows on a lighter panel and support both `href` links and `onClick` actions.\n */\n children?: NavItem[]\n}\n\n// The routing primitive is injected so each app supplies its own (Next.js\n// `<Link>`, react-router `<Link>`, or a plain `<a>`). Defaults to an anchor.\nexport type NavLinkProps = {\n href: string\n className?: string\n 'aria-current'?: 'page' | undefined\n children: ReactNode\n // Optional passthrough attributes so the same injected link can back a\n // routed nav row OR a routed tab (which needs ARIA tab semantics + inline\n // token geometry). Next.js `<Link>`, react-router `<Link>` and a plain <a>\n // all accept these DOM props, and DefaultLink spreads them onto its anchor.\n role?: string\n 'aria-selected'?: boolean\n 'aria-label'?: string\n title?: string\n style?: CSSProperties\n}\nexport type NavLinkComponent = ComponentType<NavLinkProps>\n\n/**\n * URL-scheme allow-list for host-supplied hrefs. React does not neutralize\n * `javascript:`/`data:` schemes on anchor href, so any app-supplied nav/footer/\n * action href must be validated before it reaches the DOM. Permits absolute\n * http(s), mailto/tel, and in-app relative targets; everything else → '#'.\n */\nconst safeHref = (h?: string) =>\n h && /^(https?:|mailto:|tel:|\\/|#|\\.)/i.test(h.trim()) ? h : '#'\n\nconst DefaultLink: NavLinkComponent = ({ href, children, ...rest }) => (\n <a href={safeHref(href)} {...rest}>\n {children}\n </a>\n)\n\n/**\n * Default active-route test. Handles three href shapes so the CURRENT app's\n * item + sub-item select correctly in the cross-app menu (HITL 2026-07-23):\n * - relative path: exact for \"/\", prefix otherwise (legacy behavior);\n * - absolute URL: active only when its host matches window.location.host,\n * then compared by path (and query, when the href carries one — e.g.\n * forms' /?tab=canvas sub-items);\n * - query-only relative hrefs likewise compare location.search.\n *\n * The `org` param is EXCLUDED from the query comparison. Campaign / Petition\n * links carry `?org=<last6>` purely to hand the active organization to the\n * destination app (`standardPolitogyNav`'s `activeOrgId`); it scopes data, it\n * does not identify a page. Comparing it would deselect every campaign row the\n * moment an org is active, because the app's own URL bar carries no `org=`.\n */\nconst ACTIVE_IGNORED_PARAMS = new Set(['org'])\n\nexport function isNavItemActive(pathname: string, href: string): boolean {\n let targetPath = href\n let targetSearch = ''\n if (/^https?:\\/\\//i.test(href)) {\n if (typeof window === 'undefined') return false\n try {\n const u = new URL(href)\n if (u.host !== window.location.host) return false\n targetPath = u.pathname\n targetSearch = u.search\n } catch {\n return false\n }\n } else {\n const qi = href.indexOf('?')\n if (qi >= 0) {\n targetPath = href.slice(0, qi) || '/'\n targetSearch = href.slice(qi)\n }\n }\n // Every IDENTIFYING key=value in the target query must be present in the\n // location. Once the scoping params are dropped a link like\n // \"https://signs.politogyvrm.com/placements?org=abc123\" is a plain path href\n // again and falls through to the path rules below.\n const want = new URLSearchParams(targetSearch)\n for (const k of ACTIVE_IGNORED_PARAMS) want.delete(k)\n if (Array.from(want).length > 0) {\n if (typeof window === 'undefined') return false\n if (pathname !== targetPath) return false\n const have = new URLSearchParams(window.location.search)\n for (const [k, v] of want) if (have.get(k) !== v) return false\n return true\n }\n if (targetPath === '/') return pathname === '/'\n return pathname === targetPath || pathname.startsWith(`${targetPath}/`)\n}\n\n/**\n * Stable identity for an expandable nav group's accordion state. Prefers the\n * item's href; falls back to an index-scoped label so two groups can never\n * collide even when they share a label and have no href.\n */\nfunction groupKeyOf(item: NavItem, index: number): string {\n return item.href ?? `nav-group-${index}-${item.label}`\n}\n\n/** True when any of a group's children links to the active route. */\nfunction hasActiveChild(\n item: NavItem,\n pathname: string,\n activeFn: (pathname: string, href: string) => boolean,\n): boolean {\n return (item.children ?? []).some(\n (child) =>\n (child.href ? activeFn(pathname, child.href) : false) ||\n // Depth-3: a grandchild owning the route also opens the top group.\n (child.children ?? []).some((leaf) =>\n leaf.href ? activeFn(pathname, leaf.href) : false,\n ),\n )\n}\n\n/**\n * Color-coded tone classes for the sidebar environment chip, matching the main\n * VRM app: prod red, staging orange, local/dev green, unknown gray.\n */\nfunction firstLeafHref(item: NavItem): string | undefined {\n for (const c of item.children ?? []) {\n if (c.kind === 'section') continue\n if (c.href) return c.href\n const deep = firstLeafHref(c)\n if (deep) return deep\n }\n return undefined\n}\n\n/** A multi-mode app (VRM core) renders NavAppShell without a registry modeId;\n * its current mode label still decides the rail colour (Left-Navigation §5). */\nexport function modeIdFromLabel(label: string | undefined): string | undefined {\n const l = label?.trim().toLowerCase()\n return l ? l.replace(/\\s+mode$/, '') : undefined\n}\n\n/** \"Ben Edtl\" -> \"Ben E.\" (Left-Navigation §10). One word stays as is. */\nexport function shortUserName(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean)\n if (parts.length < 2) return parts[0] ?? ''\n return `${parts[0]} ${parts[parts.length - 1][0].toUpperCase()}.`\n}\n\n/** Short environment name for the rail's build line (\"prod\", \"staging\", \"local\"). */\nexport function shortEnvLabel(label: string): string {\n const l = label.trim().toLowerCase()\n if (l === 'production') return 'prod'\n if (l === 'development') return 'dev'\n return l\n}\n\nexport function envChipClasses(label: string): string {\n const l = label.toLowerCase()\n if (l === 'production' || l === 'prod')\n return 'bg-[#fee2e2] text-[#ef4444]'\n if (l === 'staging' || l === 'stage')\n return 'bg-[#ffedd5] text-[#f97316]'\n if (l === 'local' || l === 'development' || l === 'dev')\n return 'bg-[#dcfce7] text-[#22c55e]'\n return 'bg-[rgba(107,114,128,0.16)] text-[#6b7280]'\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavBrand = {\n /** Where the logo links to. Defaults to \"/\". */\n homeHref?: string\n /**\n * Brand logo image src. When supplied this renders as the wordmark logo\n * (matching the main app's BrandLogo), and `badgeLabel`/`title`/`subtitle`\n * are used only as the no-image fallback.\n */\n logoSrc?: string\n logoAlt?: string\n /**\n * The square mark shown at the top of the COLLAPSED rail (Left-Navigation\n * §11.6) — Brand `assets.logoSquare`, the all-white vrm tile. Falls back to\n * the badge when omitted.\n */\n logoSquareSrc?: string\n /**\n * The logo URLs are still resolving from the Brand token sheet. The rail\n * reserves the logo's box and draws nothing — never the badge fallback,\n * which would flash a stand-in on every load.\n */\n logoPending?: boolean\n /** Short label shown inside the brand badge fallback (e.g. \"P\"). */\n badgeLabel: string\n title: string\n subtitle?: string\n}\n\nexport type NavOrgOption = {\n id: string\n name: string | null\n logoUrl?: string | null\n /** The org's Brand Kit icon mark; falls back to `logoUrl`, then initials. */\n iconUrl?: string | null\n brandColor?: string | null\n role?: string | null\n}\n\nexport type NavOrg = {\n name: string | null\n /** Full org id. When present, a copy affordance is shown by the label. */\n id?: string | null\n /** Optional org logo for the pill badge; falls back to initials. */\n logoUrl?: string | null\n /**\n * The org's Brand Kit icon mark, shown on the collapsed rail (32px, on its\n * white tile). Falls back to `logoUrl` scaled to fit, then initials.\n */\n iconUrl?: string | null\n /** Solid pill background (the org's brand color). Defaults to the accent. */\n brandColor?: string | null\n /** Org's secondary Brand Kit color; the card's bottom-edge gradient runs\n * primary → secondary. Falls back to the Politogy gradient when unset. */\n brandColorSecondary?: string | null\n /**\n * Organization Settings §7.1–§7.2: when the org has no logo yet, an Account\n * Admin sees an \"Upload logo\" link in the band instead of the org name.\n */\n canUploadLogo?: boolean\n uploadLogoHref?: string\n onClick?: () => void\n /**\n * The user's organizations. When present (even one), the pill renders as a\n * dropdown SWITCHER (Reference/UI-Platform \"Organization selector\": never a\n * static label in a multi-org app); selecting one calls `onSwitch(id)`.\n */\n organizations?: NavOrgOption[]\n onSwitch?: (id: string) => void\n /**\n * The active org is still resolving from the chrome API. Renders a skeleton\n * pill instead of a name. Required because the app's own workspace label is\n * NOT the organization: showing it while the real org loads flashes a wrong\n * value (Global Rules — async values shimmer, they never render a stand-in).\n */\n loading?: boolean\n}\n\nexport type NavModeOption = {\n id: string\n label: string\n icon?: NavIcon\n /**\n * Left-Navigation §7: a mode the organization does not hold is always\n * shown (never hidden), dimmed, and not selectable. Defaults to true.\n */\n available?: boolean\n /** Tooltip for an unavailable mode, e.g. \"Campaign Mode isn't active for\n * this organization.\" Appended with \"See upgrade options\" for an Account\n * Admin on a paid account (never during a trial). */\n unavailableTooltip?: string\n}\n\nexport type NavMode = {\n label: string\n icon?: NavIcon\n /**\n * Entitled modes for the active organization. With more than one option the\n * pill renders as a SELECTOR (dropdown); with zero/one it stays the classic\n * disabled single-mode pill. Selecting calls onSelect(id).\n */\n options?: NavModeOption[]\n onSelect?: (id: string) => void\n}\n\nexport type NavFooterLink = { label: string; href: string; external?: boolean }\n\nexport type NavFooter = {\n /**\n * Build metadata (env chip / commit / version / date / author). OPTIONAL:\n * omit envLabel/version/commit to render a links-only footer — apps show\n * the meta block to Super Administrators only (Reference/UI-Platform).\n */\n envLabel?: string\n version?: string\n commit?: string\n links?: NavFooterLink[]\n /** ISO date (or any Date-parseable string) of the deployed commit. */\n commitDate?: string\n /** Full name of the commit author (only the first name is shown). */\n commitAuthor?: string\n /**\n * The signed-in user, drawn as a card (avatar · name · email · chevron)\n * ABOVE the links row. Reference/UI-Platform v30 → Left bar: \"The user —\n * avatar, name, email and the user menu — lives in the left bar footer.\"\n * Clicking it opens the account menu UPWARD. `NavAppShell` fills these from\n * `topBar.user` / `topBar.userMenu` / `topBar.onSignOut` automatically, so\n * standalone `NavSidebar` consumers pass them only when they want the card.\n */\n user?: NavUser | null\n userMenu?: NavUserMenu | null\n onSignOut?: () => void\n}\n\nexport type NavSidebarProps = {\n pathname: string\n brand: NavBrand\n nav: {\n groupLabel?: string\n items: NavItem[]\n isActive?: (pathname: string, href: string) => boolean\n /**\n * Render each top-level group's CHILDREN directly at the root of the rail\n * — no parent header row, no accordion. For an app whose whole tree nests\n * under one entry (Petitions), that parent row is pure anatomy: V1 never\n * had it, it duplicates the first child's route, and it costs a level of\n * indentation. Sections render as sections; rows render with the 'flat'\n * variant (top-level geometry, wash active treatment). Top-level items\n * WITHOUT children render unchanged, so a mixed tree degrades sanely.\n */\n flatten?: boolean\n }\n org?: NavOrg | null\n mode?: NavMode | null\n footer?: NavFooter | null\n linkComponent?: NavLinkComponent\n /**\n * Small-screen expand state (owned by `NavAppShell`). The rail is never\n * hidden (Left-Navigation §11.6): at `md` and up it is the full rail, below\n * `md` it collapses to the 64px icon rail. `open` expands the collapsed\n * rail to the full rail as a modal drawer with a backdrop, and `onClose`\n * wires the backdrop, the close button, and Escape. `md` and up ignores\n * both.\n */\n open?: boolean\n onClose?: () => void\n /**\n * Expands the collapsed (below `md`) rail. When set, the square logo tile at\n * the top of the collapsed rail becomes the \"Expand navigation\" control —\n * the Left-Navigation Design draws no other toggle and no top-bar hamburger.\n */\n onOpen?: () => void\n /**\n * Closes the expanded rail after a nav-link click without counting as the\n * user's Collapse choice. Defaults to `onClose`.\n */\n onNavigate?: () => void\n}\n\n// Default org-pill BADGE background — the chrome accent, matching the main\n// app's fallback (mode primary) when an org has no explicit brand color. In a\n// Mode with its own accent this follows the Mode. Only the circular badge takes\n// it; the pill body stays neutral (Reference/UI-Platform → Left bar).\n// White initials/avatar sit on this badge, so it must clear 4.5:1 under white\n// text, not just read as \"the accent\" — hence the safe alias, not the raw one.\nconst ORG_PILL_DEFAULT = 'var(--color-accent-bg-safe,var(--color-accent))'\n\n// Left-Navigation §11.6: below `md` the rail collapses to the 64px icon rail;\n// it is never hidden. The collapse is pure CSS (`max-md:` utilities), so there\n// is one DOM tree and no hydration flash. It applies only while the rail is\n// not expanded as the small-screen drawer, which is what this context carries\n// down to the rows.\nconst RailCollapsibleContext = createContext(false)\n\n/** Returns `cls` when the small-screen collapse applies to this rail, else ''. */\nfunction useRailCollapse(): (cls: string) => string {\n const collapsible = useContext(RailCollapsibleContext)\n return (cls) => (collapsible ? cls : '')\n}\n\n/**\n * The org pill's label: the org's name, or (when an org exists but has no\n * name yet) the same 7-char id tail the address bar uses, so the pill never\n * shows a name-shaped placeholder for a real org. \"No organizations\" is\n * reserved for when there is no org at all.\n */\nfunction orgPillLabel(org: NavOrg): string {\n if (org.name) return org.name\n if (org.id) return orgIdTail(org.id) ?? 'Organization'\n return 'No organizations'\n}\n\n/**\n * The organization on the collapsed rail: its Brand Kit icon mark, 32px, on a\n * white tile (Left-Navigation §11.6). Rendered inside the same switcher\n * trigger as the full card, so the switcher stays interactive when collapsed.\n */\nfunction OrgIconMark({ org, logoSrc }: { org: NavOrg; logoSrc?: string }) {\n const rc = useRailCollapse()\n const src = resolveOrgLogoUrl(org.iconUrl) ?? logoSrc\n return (\n <span\n aria-hidden\n data-rail-org-mark=\"\"\n className={`hidden h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-[5px] bg-[#FFFFFF] text-[11px] font-bold text-neutral-800 ${rc('max-md:flex')}`}\n >\n {src ? (\n <img src={src} alt=\"\" className=\"max-h-full max-w-full object-contain\" />\n ) : (\n (org.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n )\n}\n\nexport function NavSidebar({\n pathname,\n brand,\n nav,\n org,\n mode,\n footer,\n linkComponent,\n open,\n onClose,\n onOpen,\n onNavigate,\n}: NavSidebarProps) {\n const Link = linkComponent ?? DefaultLink\n // The small-screen collapse applies whenever the rail is not expanded as\n // the drawer (see RailCollapsibleContext).\n const collapsible = !open\n const rc = (cls: string) => (collapsible ? cls : '')\n // Focus management for the mobile drawer: on open, move focus to the close\n // button; on close, return it to whatever had focus before (the hamburger,\n // in practice). Escape closes while the drawer is open.\n const asideRef = useRef<HTMLElement>(null)\n const closeButtonRef = useRef<HTMLButtonElement>(null)\n const previouslyFocusedRef = useRef<HTMLElement | null>(null)\n useEffect(() => {\n if (open) {\n previouslyFocusedRef.current = document.activeElement as HTMLElement | null\n closeButtonRef.current?.focus()\n } else if (previouslyFocusedRef.current) {\n previouslyFocusedRef.current.focus()\n previouslyFocusedRef.current = null\n }\n }, [open])\n useEffect(() => {\n if (!open) return\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose?.()\n }\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n }, [open, onClose])\n // Focus trap: Tab/Shift+Tab must stay inside the drawer while it is open —\n // no `inert` attribute (React 18/19 compatibility), so this is a plain\n // keydown handler that wraps focus at the first/last focusable element.\n const trapTab = (e: ReactKeyboardEvent<HTMLElement>) => {\n if (!open || e.key !== 'Tab') return\n const root = asideRef.current\n if (!root) return\n const focusable = Array.from(\n root.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ).filter((el) => {\n if (el.hidden) return false\n const style = window.getComputedStyle(el)\n return style.display !== 'none' && style.visibility !== 'hidden'\n })\n if (focusable.length === 0) return\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault()\n last.focus()\n }\n } else if (document.activeElement === last) {\n e.preventDefault()\n first.focus()\n }\n }\n const activeFn = nav.isActive ?? isNavItemActive\n const ModeIcon = mode?.icon\n // Core stores logo_url as a core-relative storage route; resolve it against\n // the core origin so it loads in EVERY app, not just app.politogyvrm.com.\n const orgLogoSrc = resolveOrgLogoUrl(org?.logoUrl)\n // Left-Navigation §6: brand-color gradient strip along the logo band's\n // bottom edge; the Politogy gradient (blue → purple → red) until the org\n // sets its own Brand Kit colors.\n const orgGradient = org?.brandColor\n ? `linear-gradient(to right, ${org.brandColor}, ${org.brandColorSecondary || org.brandColor})`\n : 'linear-gradient(to right, #007BFF, #A54B7A, #E63946)'\n // Design rail: the org card border is the org's brand color at 42% alpha\n // (`rgba(74,192,231,.42)` in the Specs/Contacts design); hairline otherwise.\n const orgCardStyle = hexToRgba(org?.brandColor, 0.42)\n ? { borderColor: hexToRgba(org?.brandColor, 0.42) as string }\n : undefined\n\n // Single-open accordion for expandable nav groups, mirroring the main VRM\n // app's Chakra sidebar. `activeGroupKey` is the group (if any) that owns the\n // current route; deriving it as a primitive string keeps the auto-expand\n // effect from firing when `nav.items` is a fresh array reference each render\n // (which would otherwise clobber a manual toggle).\n const activeGroupKey = useMemo(() => {\n for (let i = 0; i < nav.items.length; i++) {\n const item = nav.items[i]\n if (item.children && item.children.length > 0 && hasActiveChild(item, pathname, activeFn)) {\n return groupKeyOf(item, i)\n }\n }\n return null\n }, [nav.items, pathname, activeFn])\n\n // Seed the open group from the active route on first paint (no expand flash),\n // then keep it synced as the route changes. Manual toggles between route\n // changes are preserved because the effect only reruns when the *derived*\n // active group actually changes.\n const [openGroup, setOpenGroup] = useState<string | null>(activeGroupKey)\n // Org selector type-to-filter (see ./orgFilter.ts). Reset whenever the popover closes.\n const [orgFilter, setOrgFilter] = useState('')\n useEffect(() => {\n setOpenGroup(activeGroupKey)\n }, [activeGroupKey])\n const toggleGroup = (key: string) =>\n setOpenGroup((prev) => (prev === key ? null : key))\n\n return (\n <RailCollapsibleContext.Provider value={collapsible}>\n {/* Backdrop — small-screen drawer only, dismisses on click. */}\n {open ? (\n <div\n aria-hidden\n className=\"fixed inset-0 z-40 bg-black/40 md:hidden\"\n onClick={onClose}\n />\n ) : null}\n <aside\n ref={asideRef}\n id=\"politogy-nav-drawer\"\n role={open ? 'dialog' : undefined}\n aria-modal={open ? 'true' : undefined}\n aria-label={open ? 'Navigation' : undefined}\n className={clsx(\n 'fixed inset-y-0 left-0 flex flex-col border-r border-[color:var(--sidebar-line,var(--line))] bg-[color:var(--sidebar-bg,var(--nav-surface))]',\n // Never hidden: the 64px icon rail below `md`, the full rail from\n // `md` up, and the full rail as a drawer when expanded below `md`.\n open\n ? 'z-50 w-[var(--sidebar-width,236px)]'\n : 'z-30 w-[var(--sidebar-collapsed-width,64px)] md:w-[var(--sidebar-width,236px)]',\n )}\n // Pin the rail's own font explicitly to the Brand token (Reference/UI-Platform\n // \"Typography\") rather than relying on inherited `body` styles. An app that\n // sets its own body font on a sub-view (e.g. Contacts) would otherwise leak\n // into the rail purely by inheritance — one shell definition, never app-derived.\n style={{ fontFamily: 'var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif)' }}\n onKeyDown={trapTab}\n onClick={(e) => {\n // Any nav-link click closes the drawer — including a click on the\n // CURRENT route's link, which would otherwise strand it open since\n // `pathname` never changes to trigger NavAppShell's close effect.\n if (open && (e.target as HTMLElement).closest('a[href]')) (onNavigate ?? onClose)?.()\n }}\n >\n {/* Close button — small-screen drawer only. */}\n {open ? (\n <button\n type=\"button\"\n ref={closeButtonRef}\n onClick={onClose}\n aria-label=\"Collapse navigation\"\n className=\"absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)] md:hidden\"\n >\n <CloseIcon />\n </button>\n ) : null}\n {/* Header — brand, org card, mode switcher (Specs/Contacts design\n rail: padding 16px 18px, 14px between blocks, hairline below). */}\n <div className={`flex flex-shrink-0 flex-col gap-[14px] border-b border-[color:var(--sidebar-line,var(--line))] px-[18px] py-4 ${rc('max-md:items-center max-md:px-[10px]')}`}>\n {/* Brand — the lockup directly on the rail, no plate; the square\n tile when collapsed. Badge only when no logo was supplied at all. */}\n {/* Below `md` the collapsed rail's logo tile is the expand control\n (Left-Navigation §11.6: the rail is never hidden; the user expands\n it from the rail itself). Hidden while expanded and from `md` up. */}\n {onOpen ? (\n <button\n type=\"button\"\n onClick={onOpen}\n aria-label=\"Expand navigation\"\n aria-expanded={open ?? false}\n data-rail-toggle=\"expand\"\n className={`hidden h-8 w-8 items-center justify-center rounded-lg ${rc('max-md:flex')}`}\n >\n {brand.logoSquareSrc ? (\n <img src={brand.logoSquareSrc} alt=\"\" draggable={false} className=\"h-8 w-8 object-contain\" />\n ) : brand.logoPending ? (\n <span aria-hidden className=\"block h-8 w-8\" />\n ) : (\n <span className=\"flex h-8 w-8 items-center justify-center rounded-xl bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-sm font-black text-[#FFFFFF]\">\n {brand.badgeLabel}\n </span>\n )}\n </button>\n ) : null}\n <Link\n href={brand.homeHref ?? '/'}\n aria-label={brand.logoAlt ?? brand.title}\n className={`flex items-center gap-2.5 ${rc('max-md:justify-center')} ${onOpen ? rc('max-md:hidden') : ''}`}\n >\n {brand.logoSquareSrc ? (\n <img\n src={brand.logoSquareSrc}\n alt=\"\"\n draggable={false}\n data-rail-logo=\"square\"\n className={`hidden h-8 w-8 object-contain ${rc('max-md:block')}`}\n />\n ) : brand.logoPending ? (\n <span aria-hidden className={`hidden h-8 w-8 ${rc('max-md:block')}`} />\n ) : null}\n {brand.logoSrc ? (\n <img\n src={brand.logoSrc}\n alt={brand.logoAlt ?? brand.title}\n draggable={false}\n data-rail-logo=\"horizontal\"\n className={`h-[var(--sidebar-brand-logo-height,24px)] w-auto object-contain ${rc('max-md:hidden')}`}\n />\n ) : brand.logoPending ? (\n <span\n aria-hidden\n className={`block h-[var(--sidebar-brand-logo-height,24px)] ${rc('max-md:hidden')}`}\n />\n ) : (\n <>\n <span\n className={`flex h-9 w-9 items-center justify-center rounded-xl bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-base font-black text-[#FFFFFF] shadow-sm ${brand.logoSquareSrc ? rc('max-md:hidden') : ''}`}\n >\n {brand.badgeLabel}\n </span>\n <span className={`flex flex-col leading-tight ${rc('max-md:hidden')}`}>\n <span className=\"text-base font-extrabold tracking-[-0.01em] text-[color:var(--color-accent-fg,var(--color-accent))]\">\n {brand.title}\n </span>\n {brand.subtitle ? (\n <span className=\"text-[11px] font-semibold uppercase tracking-[0.16em] text-[color:var(--muted)]\">\n {brand.subtitle}\n </span>\n ) : null}\n </span>\n </>\n )}\n </Link>\n\n {/* Organization switcher */}\n {org ? (\n <div className={rc('max-md:flex max-md:justify-center')}>\n <div className={`mb-[7px] mt-[7px] flex items-center justify-between ${rc('max-md:hidden')}`}>\n <p className={NAV_EYEBROW_CLASS}>\n Organization\n </p>\n </div>\n {org.loading ? (\n <div className={`flex w-full items-center gap-2.5 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 shadow-sm ${rc('max-md:w-auto max-md:border-0 max-md:bg-transparent max-md:p-0 max-md:shadow-none')}`}>\n <span\n aria-hidden\n className=\"h-7 w-7 shrink-0 animate-pulse rounded-full bg-[color:var(--panel)]\"\n />\n <span\n aria-hidden\n className={`h-4 flex-1 animate-pulse rounded bg-[color:var(--panel)] ${rc('max-md:hidden')}`}\n />\n <span className=\"sr-only\">Loading organization</span>\n </div>\n ) : org.organizations && org.organizations.length > 0 && org.onSwitch ? (\n <details data-nav-details className=\"group relative\">\n <summary\n style={orgCardStyle}\n title={org.name ?? undefined}\n className={`flex w-full cursor-pointer list-none flex-col overflow-hidden rounded-[5px] border border-[color:var(--sidebar-card-border,var(--sidebar-line,var(--line)))] bg-[color:var(--sidebar-card-bg,var(--panel-elevated))] text-left text-[color:var(--sidebar-text,var(--foreground))] transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))] [&::-webkit-details-marker]:hidden ${rc('max-md:w-auto max-md:items-center max-md:overflow-visible max-md:border-0 max-md:bg-transparent')}`}\n >\n <OrgIconMark org={org} logoSrc={orgLogoSrc} />\n {/* Logo band: white, org's Primary Brand Kit logo ≤70px, never\n cropped/stretched/recolored; \"Upload logo\" for an Admin\n with no logo yet; otherwise the org's display name. */}\n <span className={`relative flex h-[var(--sidebar-org-band-height,70px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc('max-md:hidden')}`}>\n {orgLogoSrc ? (\n <img src={orgLogoSrc} alt=\"\" className=\"max-h-full max-w-[132px] object-contain\" />\n ) : org.canUploadLogo ? (\n <a\n href={org.uploadLogoHref ?? '#'}\n onClick={(e) => e.stopPropagation()}\n className=\"text-xs font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] underline\"\n >\n Upload logo\n </a>\n ) : (\n <span className=\"truncate text-sm font-semibold text-neutral-800\">\n {org.name ?? 'Organization'}\n </span>\n )}\n <span aria-hidden className=\"absolute inset-x-0 bottom-0 h-[3px]\" style={{ backgroundImage: orgGradient }} />\n </span>\n <span className={`flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-[10px] ${rc('max-md:hidden')}`}>\n <span className=\"flex min-w-0 flex-col\">\n <span\n title={org.name ?? undefined}\n className=\"truncate text-[12px] font-semibold leading-[1.2]\"\n >\n {orgPillLabel(org)}\n </span>\n {org.id && !org.loading ? <OrgIdCopyButton id={org.id} /> : null}\n </span>\n <ChevronDown size={14} />\n </span>\n </summary>\n <div className={`absolute left-0 right-0 z-40 mt-1 max-h-[min(60vh,520px)] overflow-y-auto rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)] ${rc('max-md:right-auto max-md:w-[236px]')}`}>\n {shouldShowOrgFilter(org.organizations.length) ? (\n <div className=\"sticky top-0 z-10 bg-[color:var(--panel-elevated)] px-2 pb-1 pt-1\">\n <input\n type=\"search\"\n value={orgFilter}\n onChange={(e) => setOrgFilter(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n setOrgFilter('')\n e.currentTarget.closest('details')?.removeAttribute('open')\n }\n }}\n placeholder={`Filter ${org.organizations.length} organizations`}\n aria-label=\"Filter organizations\"\n autoComplete=\"off\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-1.5 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n </div>\n ) : null}\n {filterOrgs(org.organizations, orgFilter).length === 0 ? (\n <p className=\"px-3 py-2 text-sm text-[color:var(--muted)]\">No organization matches “{orgFilter}”.</p>\n ) : null}\n {filterOrgs(org.organizations, orgFilter).map((o) => {\n const selected = o.id === org.id\n return (\n <button\n key={o.id}\n type=\"button\"\n onClick={(e) => {\n // Close the <details> popover, then switch.\n e.currentTarget.closest('details')?.removeAttribute('open')\n setOrgFilter('')\n if (!selected) org.onSwitch?.(o.id)\n }}\n aria-current={selected ? 'true' : undefined}\n className={[\n 'flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm',\n selected\n ? 'font-semibold text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n <span\n style={{ backgroundColor: o.brandColor || ORG_PILL_DEFAULT }}\n className=\"flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[10px] font-bold text-[#FFFFFF]\"\n >\n {resolveOrgLogoUrl(o.logoUrl) ? (\n <img\n src={resolveOrgLogoUrl(o.logoUrl)}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n (o.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n <span title={o.name ?? o.id} className=\"truncate\">\n {o.name ?? o.id.slice(0, 8)}\n </span>\n </button>\n )\n })}\n </div>\n </details>\n ) : (\n <button\n type=\"button\"\n onClick={org.onClick}\n style={orgCardStyle}\n title={org.name ?? undefined}\n className={`flex w-full flex-col overflow-hidden rounded-[5px] border border-[color:var(--sidebar-card-border,var(--sidebar-line,var(--line)))] bg-[color:var(--sidebar-card-bg,var(--panel-elevated))] text-left text-[color:var(--sidebar-text,var(--foreground))] transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))] ${rc('max-md:w-auto max-md:items-center max-md:overflow-visible max-md:border-0 max-md:bg-transparent')}`}\n >\n <OrgIconMark org={org} logoSrc={orgLogoSrc} />\n <span className={`relative flex h-[var(--sidebar-org-band-height,70px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc('max-md:hidden')}`}>\n {orgLogoSrc ? (\n <img src={orgLogoSrc} alt=\"\" className=\"max-h-full max-w-[132px] object-contain\" />\n ) : org.canUploadLogo ? (\n <a\n href={org.uploadLogoHref ?? '#'}\n onClick={(e) => e.stopPropagation()}\n className=\"text-xs font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] underline\"\n >\n Upload logo\n </a>\n ) : (\n <span className=\"truncate text-sm font-semibold text-neutral-800\">\n {org.name ?? 'Organization'}\n </span>\n )}\n <span aria-hidden className=\"absolute inset-x-0 bottom-0 h-[3px]\" style={{ backgroundImage: orgGradient }} />\n </span>\n <span className={`flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-[10px] ${rc('max-md:hidden')}`}>\n <span className=\"flex min-w-0 flex-col\">\n <span\n title={org.name ?? undefined}\n className=\"truncate text-[12px] font-semibold leading-[1.2]\"\n >\n {orgPillLabel(org)}\n </span>\n {org.id && !org.loading ? <OrgIdCopyButton id={org.id} /> : null}\n </span>\n <ChevronDown size={14} />\n </span>\n </button>\n )}\n </div>\n ) : null}\n\n {/* Mode selector — Reference/UI-Platform: \"A row of three icon buttons\n — Relationship · Campaign · Petition — under the org card, never a\n dropdown, with the current mode's name beneath.\" Identical in every\n app, mode-scoped apps included: the app's own mode is selected and\n the other available modes navigate to that mode's landing page. */}\n {mode ? (\n <div className={rc('max-md:w-full')}>\n <div\n role=\"radiogroup\"\n aria-label=\"Mode\"\n className={`flex w-full items-center gap-1 rounded-lg border border-[color:var(--border-inverse,var(--sidebar-line,var(--line)))] bg-[color:var(--mode-track-bg,var(--panel-elevated))] p-[3px] ${rc('max-md:flex-col max-md:items-stretch')}`}\n >\n {(mode.options && mode.options.length > 0 ? mode.options : [{ id: mode.label, label: mode.label, icon: ModeIcon }]).map(\n (opt) => {\n const selected = opt.label === mode.label\n const OptIcon = opt.icon\n const available = opt.available ?? true\n const title = !available\n ? opt.unavailableTooltip ?? `${opt.label} isn't active for this organization.`\n : opt.label\n return (\n <button\n key={opt.id}\n type=\"button\"\n role=\"radio\"\n title={title}\n aria-label={title}\n aria-checked={selected}\n aria-current={selected ? 'true' : undefined}\n onClick={() => {\n if (available && !selected) mode.onSelect?.(opt.id)\n }}\n disabled={!available}\n className={[\n `flex flex-none items-center justify-center rounded-[5px] px-[9px] py-[6px] transition ${rc('max-md:flex-1')}`,\n !available\n ? 'cursor-not-allowed text-[color:var(--sidebar-text-muted,var(--muted))] opacity-35'\n : selected\n ? 'bg-[color:var(--sidebar-mode-selected-bg,var(--mode-accent,var(--color-accent)))] text-[color:var(--mode-on-accent,var(--color-accent-bg-safe,white))]'\n : 'text-[color:var(--sidebar-text-muted,var(--muted))] hover:bg-[#FFFFFF]/5 hover:text-[color:var(--sidebar-text,var(--foreground))]',\n ].join(' ')}\n >\n {OptIcon ? <OptIcon size={15} className=\"shrink-0\" /> : null}\n </button>\n )\n },\n )}\n </div>\n {/* Sentence-case caption, left-aligned under the switcher\n (\"Relationship mode\") — Specs/Contacts design rail. */}\n <p className={`mt-1.5 text-left text-[11px] leading-[1.2] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] ${rc('max-md:hidden')}`}>\n {modeCaption(mode.label)}\n </p>\n </div>\n ) : null}\n </div>\n\n {/* Scroll region: nav only — the header above stays put. */}\n <div className=\"flex flex-1 flex-col overflow-y-auto px-[10px] py-3\">\n {/* Nav list */}\n <nav className=\"flex flex-col gap-0.5\">\n {nav.groupLabel ? (\n <p className={`${NAV_EYEBROW_CLASS} px-2 pb-1.5 pt-1 ${rc('max-md:hidden')}`}>\n {nav.groupLabel}\n </p>\n ) : null}\n {nav.items.map((item, idx) => {\n // Section heading: groups the rows beneath it. Non-interactive and\n // not focusable, so it is skipped by tab order and never reads as a\n // dead control. Top margin except on the first row, so the groups\n // separate without a stray gap at the top of the rail.\n if (item.kind === 'section') {\n return (\n <NavSectionRow\n key={`section-${idx}-${item.label}`}\n label={item.label}\n first={idx === 0}\n />\n )\n }\n // Flattened tree: the group's children ARE the rail. See nav.flatten.\n if (nav.flatten && item.children && item.children.length > 0) {\n return item.children.map((child, i) => {\n if (child.kind === 'section') {\n return (\n <NavSectionRow\n key={`flat-section-${idx}-${i}-${child.label}`}\n label={child.label}\n first={idx === 0 && i === 0}\n />\n )\n }\n return (\n <NavRow\n key={child.href ?? `flat-${idx}-${i}-${child.label}`}\n item={child}\n active={child.href ? activeFn(pathname, child.href) : false}\n Link={Link}\n variant=\"flat\"\n />\n )\n })\n }\n // Left-Navigation §8.2: the bar is flat — no sub-menus, no\n // accordions, no chevrons. A row with children renders as one row\n // linking to its own page (or its first child's) and is active\n // whenever any page beneath it is (§11.3, by route prefix). The\n // children stay in the tree for breadcrumbs and in-page tabs.\n if (item.children && item.children.length > 0) {\n const selfActive = item.href ? activeFn(pathname, item.href) : false\n const parentActive = selfActive || hasActiveChild(item, pathname, activeFn)\n return (\n <NavRow\n key={item.href ?? groupKeyOf(item, idx)}\n item={{ ...item, href: item.href ?? firstLeafHref(item), children: undefined }}\n active={parentActive}\n Link={Link}\n />\n )\n }\n const active = item.href ? activeFn(pathname, item.href) : false\n return (\n <NavRow\n key={item.href ?? `nav-${idx}-${item.label}`}\n item={item}\n active={active}\n Link={Link}\n />\n )\n })}\n </nav>\n </div>\n\n {/* Footer — user card (account menu opens upward), then the links row,\n then the build meta (non-production only). Specs/Contacts design rail. */}\n {footer ? (\n <div className={`relative flex-shrink-0 border-t border-[color:var(--sidebar-line,var(--line))] px-[14px] py-3 ${rc('max-md:px-[10px]')}`}>\n {footer.user ? (\n <NavSidebarUserCard\n user={footer.user}\n userMenu={footer.userMenu ?? undefined}\n onSignOut={footer.onSignOut}\n />\n ) : null}\n {footer.links && footer.links.length > 0 ? (\n <div className={`flex flex-wrap items-center justify-center gap-[6px] text-[11px] leading-[1.2] ${footer.user ? 'mt-3' : ''} ${rc('max-md:hidden')}`}>\n {footer.links.map((l, i) => (\n <Fragment key={l.label}>\n {i > 0 ? <span aria-hidden className=\"text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))]\">·</span> : null}\n <a\n href={safeHref(l.href)}\n className=\"text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] hover:text-[color:var(--sidebar-text,var(--foreground))] hover:underline\"\n >\n {l.label}\n </a>\n </Fragment>\n ))}\n </div>\n ) : null}\n {footer.envLabel || footer.commit || footer.version ? (\n <div\n data-shell-meta\n className={`mt-1.5 flex flex-col items-center gap-0.5 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] text-[color:var(--sidebar-meta-text,rgba(255,255,255,0.72))] ${rc('max-md:hidden')}`}\n >\n {/* Row 1: env | commit | version — Specs/Left-Navigation §9:\n plain mono text, centered, no leading or trailing pipes. */}\n <div className=\"flex items-center gap-1.5\">\n {[\n footer.envLabel ? shortEnvLabel(footer.envLabel) : null,\n footer.commit ? footer.commit.slice(-4) : null,\n footer.version ? `v${footer.version.replace(/^v/, '')}` : null,\n ]\n .filter((v): v is string => Boolean(v))\n .map((v, i) => (\n <Fragment key={i}>\n {i > 0 ? <span>|</span> : null}\n <span>{v}</span>\n </Fragment>\n ))}\n </div>\n {/* Row 2: date | author (only when supplied) */}\n {footer.commitDate || footer.commitAuthor ? (\n <div className=\"flex items-center gap-1.5\">\n {footer.commitDate ? (\n <span>\n {new Date(footer.commitDate).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n })}\n </span>\n ) : null}\n {footer.commitDate && footer.commitAuthor ? (\n <span>|</span>\n ) : null}\n {footer.commitAuthor ? (\n <span>{footer.commitAuthor.split(/\\s+/)[0]}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </aside>\n </RailCollapsibleContext.Provider>\n )\n}\n\n// Inline hamburger / close glyphs for the mobile nav drawer — no icon\n// dependency, same idiom as every other inline SVG in this file.\nfunction HamburgerIcon() {\n return (\n <svg\n width={24}\n height={24}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n </svg>\n )\n}\n\n/** 14px book-open glyph for the \"Build notes\" quiet button (design). */\nfunction BookOpenIcon() {\n return (\n <svg\n width={14}\n height={14}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"shrink-0\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 7v14\" />\n <path d=\"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z\" />\n </svg>\n )\n}\n\nfunction SearchIcon({ className }: { className?: string } = {}) {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n )\n}\n\nfunction CloseIcon() {\n return (\n <svg\n width={20}\n height={20}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\n// Inline chevron-down (mirrors lucide `ChevronDown`) — no icon dependency.\n// Callers may override `className` to add a rotation (used by expandable groups).\nfunction ChevronDown({ className, size = 16 }: { className?: string; size?: number } = {}) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className ?? 'shrink-0 opacity-80'}\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n )\n}\n\n// A single sidebar nav row. Renders as a routed <Link> (href) or a <button>\n// (onClick), styled identically. Inactive rows animate a left→right gradient\n// sweep on hover (matching the main app); active rows keep the solid accent.\n//\n// `variant=\"sub\"` renders the smaller child rows inside an expanded group: a\n// tighter row whose ACTIVE state is a lighter elevated surface with accent\n// text (not a solid fill — that stays reserved for top-level/parent rows,\n// exactly as the main VRM app's Chakra sidebar treats active sub-items).\n//\n// The gradient was hardcoded to the race-red 400/500 stops; it now reads the\n// token so a Mode with its own accent sweeps in its own colour. chrome.css\n// defaults it to those same two stops, so nothing moves for anyone else.\nconst NAV_HOVER_GRADIENT = 'var(--nav-hover-gradient)'\n\n// A non-interactive section heading. Groups the rows beneath it; not a control,\n// so it is not focusable and carries no hover, no aria-disabled and no role.\n//\n// Rendered at BOTH levels: an app whose routes are nested under a standard nav\n// entry (Petitions nests its whole tree under the Petition Mode row) needs its\n// sections inside the expanded group, not only at the top level.\n//\n// `first` suppresses the leading margin so a rail that opens with a section\n// does not start with a gap.\n// Rail typography/geometry — Specs/Contacts design rail (Reference/UI-Platform\n// v30 → Left bar). Every token has an inline fallback so an app that is not\n// mode-scoped (white rail) keeps a sane rendering.\nconst NAV_EYEBROW_CLASS =\n 'text-[11px] font-bold uppercase leading-[1.2] tracking-[0.09em] text-[color:var(--sidebar-eyebrow,var(--sidebar-text-muted,var(--muted)))]'\nconst NAV_TOP_ICON_SIZE = 17\nconst NAV_TOP_ROW_CLASS = (active: boolean) =>\n `gap-[11px] px-[10px] py-[9px] text-[13px] leading-none ${active ? 'font-semibold' : 'font-normal'}`\nconst NAV_TOP_ACTIVE_CLASS =\n 'bg-[color:var(--sidebar-active-bg,var(--color-accent-bg-safe,var(--color-accent)))] text-[color:var(--sidebar-active-text,white)]'\nconst NAV_TOP_INACTIVE_CLASS =\n 'text-[color:var(--sidebar-row-text,var(--sidebar-text,var(--muted)))] hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel-elevated))] hover:text-[color:var(--sidebar-text,var(--foreground))]'\n\n/** \"Relationship Mode\" → \"Relationship mode\" (design caption is sentence case). */\nfunction modeCaption(label: string): string {\n return label.replace(/\\s+Mode$/i, ' mode')\n}\n\n/** 2px inset rail on the active row, in the Mode accent (design: inset 2px 0 0 0). */\nfunction NavActiveRail() {\n // `--mode-accent` is only set by a declared Mode chrome group; the inline\n // `transparent` fallback is what every other app gets — present but\n // invisible, and absolutely positioned so it moves nothing.\n return (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 w-[2px]\"\n style={{ background: 'var(--mode-accent, transparent)' }}\n />\n )\n}\n\n/** Right-aligned mono count on a nav row (`Contacts · 31.9K`). */\nfunction NavRowBadge({ value }: { value?: string | number | null }) {\n const rc = useRailCollapse()\n if (value === undefined || value === null || value === '') return null\n return (\n <span className={`ml-auto shrink-0 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] font-semibold leading-none text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] ${rc('max-md:hidden')}`}>\n {value}\n </span>\n )\n}\n\nfunction NavSectionRow({\n label,\n first,\n variant = 'top',\n}: {\n label: string\n first: boolean\n variant?: 'top' | 'sub'\n}) {\n const rc = useRailCollapse()\n // Collapsed rail: the eyebrow becomes a 1px divider (Left-Navigation §11.6).\n // The divider is its OWN decorative element (aria-hidden) now, not the\n // heading's text painted transparent over it — a live capture on Forms at\n // 375px (light theme) measured that transparent heading text as a real\n // rgba(0,0,0,0)-on-rgb(63,64,68) 1.00:1 contrast failure (\"Collect\"/\n // \"Account\"), because a contrast scan sees the painted (if invisible)\n // glyphs, not the 1px overflow-hidden box clipping them. Moving the label\n // itself to `sr-only` (truly off-screen, same treatment the first section\n // already used) removes it from the visual contrast surface entirely while\n // it stays in the DOM as a heading for screen readers, same as before.\n const labelCollapsed = variant === 'sub' ? '' : rc('max-md:sr-only')\n return (\n <>\n {variant !== 'sub' && !first ? (\n <div\n aria-hidden\n className={rc('max-md:mx-2 max-md:my-2 max-md:h-px max-md:bg-[color:var(--sidebar-line,var(--line))]')}\n />\n ) : null}\n <p\n className={[\n NAV_EYEBROW_CLASS,\n variant === 'sub' ? 'px-3 pb-0.5' : 'px-2 pb-1.5 pt-1',\n first ? '' : variant === 'sub' ? 'mt-3' : 'mt-[14px]',\n labelCollapsed,\n ].join(' ')}\n >\n {label}\n </p>\n </>\n )\n}\n\nfunction NavRow({\n item,\n active,\n Link,\n variant = 'top',\n}: {\n item: NavItem\n active: boolean\n Link: NavLinkComponent\n variant?: 'top' | 'sub' | 'flat'\n}) {\n const rc = useRailCollapse()\n const Icon = item.icon\n const isSub = variant === 'sub'\n // 'flat' rows keep top-level geometry but take the wash active treatment —\n // tinted surface + accent text — the way V1's full-height rail rows did,\n // rather than the solid fill reserved for parent rows.\n const washActive = variant !== 'top'\n // The active sub-row surface follows the Mode when one is declared.\n //\n // The fallback is INLINE, and has to be. `--mode-accent-surface` is only ever\n // set inside `[data-politogy-mode]`, so an app that is not mode-scoped never\n // has it — and a bare `var(--x)` with no fallback is invalid at\n // computed-value time, which would drop `background-color` all the way to\n // `transparent` and silently delete the active highlight for Contacts, Forms,\n // Surveys and Polls. Nor can the fallback be hoisted into a `:root`\n // declaration: `.dark` is a separate top-level selector here, so a `:root`\n // alias would freeze the LIGHT `--panel-elevated` and inherit it into dark.\n // Resolving at the point of use is the only placement that is correct in both\n // themes, scoped and unscoped.\n const activeClasses = washActive\n ? 'bg-[color:var(--mode-accent-surface,var(--panel-elevated))] text-[color:var(--color-accent-fg,var(--color-accent))] shadow-sm'\n : NAV_TOP_ACTIVE_CLASS\n const wrapperClasses = [\n 'group relative block overflow-hidden transition',\n isSub ? 'rounded-md' : 'rounded-[5px]',\n active ? activeClasses : isSub ? 'text-[color:var(--sidebar-text,var(--muted))] hover:text-[#FFFFFF]' : NAV_TOP_INACTIVE_CLASS,\n ].join(' ')\n\n const rowPadding = isSub ? 'gap-3 px-3 py-1.5 text-[13px] font-semibold' : NAV_TOP_ROW_CLASS(active)\n const iconSize = isSub ? 16 : NAV_TOP_ICON_SIZE\n // Glyphs inherit the row's text color in every variant.\n const iconClass = 'text-current'\n\n const inner = (\n <>\n {!active ? (\n // Sub rows keep the left→right gradient sweep; top-level rows take a\n // flat wash on hover (design rail: rgba(255,255,255,.05)).\n isSub ? (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 w-0 transition-[width] duration-300 group-hover:w-full\"\n style={{ background: NAV_HOVER_GRADIENT }}\n />\n ) : null\n ) : (\n <NavActiveRail />\n )}\n <span className={`relative z-10 flex items-center ${rowPadding} ${rc('max-md:justify-center max-md:px-0')}`}>\n {Icon ? (\n <Icon size={iconSize} className={`shrink-0 ${iconClass}`} />\n ) : (\n // A row with no glyph still needs something on the icon rail.\n <span aria-hidden className={`hidden text-[11px] font-semibold uppercase ${rc('max-md:inline')}`}>\n {item.label.slice(0, 2)}\n </span>\n )}\n <span className={`min-w-0 flex-1 truncate ${rc('max-md:hidden')}`}>{item.label}</span>\n <NavRowBadge value={item.badge} />\n </span>\n </>\n )\n\n // A gated row renders as a non-interactive span: dimmed, not focusable, and\n // carrying its reason as a tooltip. Same treatment a disabled NavTab gets, so\n // gating reads identically in the sidebar and in a tab strip.\n if (item.disabled) {\n return (\n <span\n aria-disabled=\"true\"\n title={item.disabledTitle ?? item.label}\n className={`${wrapperClasses} cursor-not-allowed opacity-50`}\n >\n {inner}\n </span>\n )\n }\n\n if (item.onClick && !item.href) {\n return (\n <button\n type=\"button\"\n onClick={item.onClick}\n title={item.label}\n className={`w-full text-left ${wrapperClasses}`}\n >\n {inner}\n </button>\n )\n }\n\n return (\n <Link\n href={item.href ?? '#'}\n aria-current={active ? 'page' : undefined}\n // The tooltip names the row; on the collapsed rail it is also the\n // row's accessible name, since the label is not displayed.\n title={item.label}\n className={wrapperClasses}\n >\n {inner}\n </Link>\n )\n}\n\n// An expandable nav GROUP: a toggle header + a collapsible list of child rows.\n// Faithful twin of the main VRM app's Chakra accordion (Sidebar.tsx /\n// NavItem.tsx):\n// - Clicking the header toggles the children — it never navigates, even when\n// the group carries an `href`.\n// - A right-aligned chevron rotates 180° when open.\n// - The header goes solid accent (white text) when the group owns the active\n// route (its own href OR any child), matching top-level active rows; when\n// merely open it lifts onto the `--panel` surface; otherwise it's a muted row\n// with the same left→right gradient hover sweep as every other nav row.\n// - Children sit on the lighter `--panel` surface, indented and rounded, each\n// rendered through the SAME injected LinkComponent (or as a button for\n// `onClick` children) via <NavRow variant=\"sub\" />.\nfunction NavGroup({\n item,\n active,\n open,\n onToggle,\n pathname,\n activeFn,\n Link,\n}: {\n item: NavItem\n active: boolean\n open: boolean\n onToggle: () => void\n pathname: string\n activeFn: (pathname: string, href: string) => boolean\n Link: NavLinkComponent\n}) {\n const rc = useRailCollapse()\n const Icon = item.icon\n const headerClasses = [\n 'group relative block w-full overflow-hidden text-left transition',\n open ? 'rounded-t-[5px]' : 'rounded-[5px]',\n active\n ? NAV_TOP_ACTIVE_CLASS\n : open\n ? 'bg-[color:var(--sidebar-row-hover-bg,var(--panel))] text-[color:var(--sidebar-text,var(--foreground))]'\n : NAV_TOP_INACTIVE_CLASS,\n ].join(' ')\n\n return (\n <div>\n <button\n type=\"button\"\n // A group header ALWAYS toggles. When the item also carries its own\n // onClick, that runs too — so a parent can navigate to its section\n // dashboard (e.g. Email Broadcast → /relationship/email/dashboard) and\n // expand in one click. Existing apps pass no parent onClick, so their\n // behavior is unchanged (shell-nav-handoff §2).\n onClick={() => {\n onToggle()\n item.onClick?.()\n }}\n aria-expanded={open}\n title={item.label}\n className={headerClasses}\n >\n {active ? <NavActiveRail /> : null}\n <span className={`relative z-10 flex items-center ${NAV_TOP_ROW_CLASS(active)} ${rc('max-md:justify-center max-md:px-0')}`}>\n {Icon ? (\n <Icon size={NAV_TOP_ICON_SIZE} className=\"shrink-0 text-current\" />\n ) : null}\n <span className={`min-w-0 flex-1 truncate ${rc('max-md:hidden')}`}>{item.label}</span>\n <NavRowBadge value={item.badge} />\n <ChevronDown\n className={[\n 'shrink-0 opacity-80 transition-transform duration-200',\n open ? 'rotate-180' : '',\n rc('max-md:hidden'),\n ].join(' ')}\n />\n </span>\n </button>\n\n {open ? (\n <div className={`overflow-hidden rounded-b-md bg-[color:var(--nav-submenu-bg)] p-1 ${rc('max-md:hidden')}`}>\n <div className=\"flex flex-col gap-0.5\">\n {item.children!.map((child, i) => {\n if (child.kind === 'section') {\n return (\n <NavSectionRow\n key={`sub-section-${i}-${child.label}`}\n label={child.label}\n first={i === 0}\n variant=\"sub\"\n />\n )\n }\n const childActive = child.href ? activeFn(pathname, child.href) : false\n // Depth-3: a child that carries its own children renders as a\n // NESTED collapsible sub-group (e.g. Organization Settings →\n // Subscription & Billing → Wallet). Deeper levels are not\n // rendered — three is the platform maximum.\n if (child.children && child.children.length > 0) {\n return (\n <NavSubGroup\n key={child.href ?? `subgrp-${i}-${child.label}`}\n item={child}\n pathname={pathname}\n activeFn={activeFn}\n Link={Link}\n />\n )\n }\n return (\n <NavRow\n key={child.href ?? `sub-${i}-${child.label}`}\n item={child}\n active={childActive}\n Link={Link}\n variant=\"sub\"\n />\n )\n })}\n </div>\n </div>\n ) : null}\n </div>\n )\n}\n\n// A second-level group INSIDE an expanded group — the depth-3 renderer\n// (Reference/UI-Platform: sub-sub items). Auto-expands when it owns the active\n// route; otherwise toggles locally. Grandchildren render as further-indented\n// sub rows on the same panel surface.\nfunction NavSubGroup({\n item,\n pathname,\n activeFn,\n Link,\n}: {\n item: NavItem\n pathname: string\n activeFn: (pathname: string, href: string) => boolean\n Link: NavLinkComponent\n}) {\n const ownsActive =\n (item.href ? activeFn(pathname, item.href) : false) ||\n (item.children ?? []).some((c) => (c.href ? activeFn(pathname, c.href) : false))\n const [open, setOpen] = useState(ownsActive)\n useEffect(() => {\n if (ownsActive) setOpen(true)\n }, [ownsActive])\n const Icon = item.icon\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n aria-expanded={open}\n className={[\n 'flex w-full items-center gap-2.5 rounded px-3 py-1.5 text-left text-[13px] font-medium transition',\n ownsActive\n ? 'text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'text-[color:var(--sidebar-text,var(--muted))] hover:bg-[color:var(--nav-row-hover)] hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {Icon ? <Icon size={15} className=\"shrink-0 text-current\" /> : null}\n <span className=\"flex-1\">{item.label}</span>\n <ChevronDown\n className={[\n 'shrink-0 opacity-70 transition-transform duration-200',\n open ? 'rotate-180' : '',\n ].join(' ')}\n />\n </button>\n {open ? (\n <div className=\"ml-4 flex flex-col gap-0.5 border-l border-[color:var(--line)] pl-2\">\n {item.children!.map((leaf, i) => (\n <NavRow\n key={leaf.href ?? `subsub-${i}-${leaf.label}`}\n item={leaf}\n active={leaf.href ? activeFn(pathname, leaf.href) : false}\n Link={Link}\n variant=\"sub\"\n />\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\n// Right-aligned copy affordance for the org id, shown beside the \"Organization\"\n// label. Copies the full id and briefly swaps its text to \"Copied\".\nfunction OrgIdCopyButton({ id }: { id: string }) {\n const [copied, setCopied] = useState(false)\n return (\n <button\n type=\"button\"\n onClick={() => {\n try {\n void navigator.clipboard?.writeText(id)\n } catch {\n /* clipboard unavailable — ignore */\n }\n setCopied(true)\n setTimeout(() => setCopied(false), 1500)\n }}\n title=\"Copy organization id\"\n className=\"-ml-1 rounded px-1 text-left font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))]\"\n >\n {copied ? 'Copied' : `…${id.slice(-8)}`}\n </button>\n )\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavUser = {\n name: string | null\n email?: string | null\n /** Profile PHOTO url — highest-precedence avatar source. */\n avatarUrl?: string | null\n /** Memoji url — used when no photo is set; falls back to initials. */\n memojiUrl?: string | null\n tier?: string | null\n role?: string | null\n}\n\nexport type NavTopBarAction = {\n key: string\n /**\n * Canonical top-bar slot. When set, the glyph is sourced by NAME from the\n * Brand API via `--topbar-icon-<slot>`; `icon` becomes the fallback used\n * until the runtime Brand stylesheet lands (or when the token is unset).\n */\n slot?: TopBarIconSlot\n icon: NavIcon\n label: string\n onClick?: () => void\n href?: string\n badge?: number | null\n tone?: 'default' | 'warning' | 'danger'\n /** Tooltip body shown under the icon (label is the tooltip title). */\n description?: string\n}\n\nexport type NavLinkedAccount = {\n id: string\n name: string | null\n email?: string | null\n avatarUrl?: string | null\n active?: boolean\n}\n\nexport type NavRoleBadge = {\n role: string\n orgName?: string | null\n}\n\n/**\n * The My Account menu (avatar dropdown) — mirrors the main VRM app's user\n * menu: My Profile / Organization Settings links, a ROLES & ORGANIZATIONS\n * section, an ACCOUNTS switcher, an optional theme control, then Sign out.\n * Every section renders only when its data is supplied.\n */\nexport type NavUserMenu = {\n myProfileHref?: string\n organizationSettingsHref?: string\n roles?: NavRoleBadge[]\n accounts?: NavLinkedAccount[]\n onSwitchAccount?: (id: string) => void\n onRemoveAccount?: (id: string) => void\n addAccountHref?: string\n onAddAccount?: () => void\n /**\n * Navigation display (Sub Menu / Tabs Only / Both) — lives in the account\n * menu since 0.68.0; the top-bar `NavDisplayAction` popover is retired from\n * the standard cluster (design: 4 icon buttons + Help).\n */\n navDisplay?: {\n value: NavDisplayMode\n onChange: (next: NavDisplayMode) => void\n }\n /** Theme preference segmented control (Light / System / Dark). */\n theme?: {\n value: ThemePreference\n onChange: (next: ThemePreference) => void\n }\n}\n\nexport type NavBreadcrumb = {\n label: string\n href?: string\n}\n\nexport type NavTopBarProps = {\n /**\n * Chrome-owned page title line (`<h1>` above main). Omit when the page body\n * owns its own title (registry `pageTitle: false`, e.g. Contacts).\n */\n title?: string\n subtitle?: string\n /**\n * Breadcrumb trail rendered UNDER the page title (Reference/UI-Platform:\n * every page and sub-page/tab shows its location). Last crumb = current\n * location (non-link); earlier crumbs may carry hrefs.\n */\n breadcrumbs?: NavBreadcrumb[]\n user?: NavUser | null\n userMenu?: NavUserMenu\n onSignOut?: () => void\n /**\n * Structured icon-button action cluster (32×32 circular buttons with optional\n * count badges), rendered before the `actions` slot. Matches the main app's\n * topbar action icons.\n */\n actionsList?: NavTopBarAction[]\n /** App-specific action cluster rendered left of the theme toggle. */\n actions?: ReactNode\n /** Theme toggle slot (injected so this package needs no theme dependency). */\n themeToggle?: ReactNode\n /**\n * Mobile drawer trigger (owned by `NavAppShell`). Supplying it renders a\n * hamburger button, hidden at `lg` and up, as the first thing in the header\n * — below `lg` the sidebar is otherwise unreachable. Omit to render no\n * hamburger at all (e.g. `NavTopBar` used standalone).\n */\n onOpenNav?: () => void\n /** Whether the drawer `onOpenNav` opens is currently open (drives `aria-expanded`). */\n navOpen?: boolean\n /**\n * Universal search — Reference/UI-Platform \"Top bar → required elements\":\n * the search field, 320px wide, at the left end of the bar; nothing else\n * sits on the left. Omit `onChange`/`onSubmit` for a decorative field (an\n * app that has not wired search yet still gets the correct chrome).\n */\n search?: {\n placeholder?: string\n value?: string\n onChange?: (value: string) => void\n onSubmit?: (value: string) => void\n }\n /**\n * Build notes — a quiet text button that starts the right-hand group\n * (Reference/UI-Platform \"Top bar → required elements\").\n */\n /**\n * Where the My Account trigger lives. `'topbar'` (default for a standalone\n * `NavTopBar`) keeps the avatar + name + chevron at the right end of the bar;\n * `'sidebar'` / `'none'` hide it here — `NavAppShell` passes `'sidebar'` and\n * draws the user card in the left-bar footer instead (UI-Platform v30:\n * \"There is no My Account badge in the top bar\").\n */\n accountMenu?: 'topbar' | 'sidebar' | 'none'\n buildNotes?: {\n label?: string\n onOpen?: () => void\n }\n}\n\nexport function NavTopBar({\n title,\n subtitle,\n breadcrumbs,\n user,\n userMenu,\n onSignOut,\n actionsList,\n actions,\n themeToggle,\n onOpenNav,\n navOpen,\n search,\n buildNotes,\n accountMenu = 'topbar',\n}: NavTopBarProps) {\n // Real name = anything that isn't empty and isn't an email address. The\n // trigger shows \"First L.\" — never the email on both lines.\n const rawName = user?.name?.trim() || ''\n const hasRealName = rawName.length > 0 && !rawName.includes('@')\n const displayName = hasRealName ? formatFirstLast(rawName) : (user?.email ?? 'Signed in')\n const initials = (hasRealName ? rawName : (user?.email ?? 'P')).slice(0, 2).toUpperCase()\n const secondary = hasRealName\n ? user?.email || [user?.tier, user?.role].filter(Boolean).join(' · ') || 'member'\n : [user?.tier, user?.role].filter(Boolean).join(' · ') || 'member'\n // `title` / `subtitle` / `breadcrumbs` are no longer rendered here —\n // Reference/UI-Platform \"Page header\" moved the title into the main body\n // (22px below this bar) and retired the breadcrumb trail entirely. They\n // stay accepted on the prop type so apps mid-migration do not break the\n // build; the chrome just stops drawing them.\n void title\n void subtitle\n void breadcrumbs\n return (\n <div className=\"sticky top-0 z-20\">\n <header className=\"flex min-w-0 h-[var(--topbar-height,60px)] items-center justify-between gap-[8px] md:gap-[14px] border-b border-[color:var(--line)] bg-[color:var(--panel)] px-[var(--topbar-padding-x,20px)]\">\n {onOpenNav ? (\n <button\n type=\"button\"\n onClick={onOpenNav}\n aria-label=\"Open menu\"\n aria-expanded={navOpen ?? false}\n aria-controls=\"politogy-nav-drawer\"\n className={`${topBarIconButtonClass('default')} mr-1 shrink-0 md:hidden`}\n >\n <HamburgerIcon />\n </button>\n ) : null}\n\n {/* Universal search — the only thing on the left end of the bar. 320px\n (Reference/UI-Platform); below md it shrinks so the bar never pushes\n the page wider than a 390px phone. */}\n <label className=\"relative flex h-9 w-[320px] min-w-0 max-w-full shrink items-center md:shrink-0\">\n <SearchIcon className=\"pointer-events-none absolute left-[10px] h-[15px] w-[15px] text-[color:var(--muted)]\" />\n <input\n type=\"search\"\n placeholder={search?.placeholder ?? 'Search'}\n value={search?.value}\n onChange={search?.onChange ? (e) => search.onChange?.(e.target.value) : undefined}\n onKeyDown={\n search?.onSubmit\n ? (e) => {\n if (e.key === 'Enter') search.onSubmit?.((e.target as HTMLInputElement).value)\n }\n : undefined\n }\n readOnly={!search?.onChange}\n className=\"h-full w-full rounded-[5px] border border-[color:var(--line)] bg-[color:var(--surface-sunken,var(--panel-elevated))] pl-[33px] pr-10 text-[13px] text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n <kbd\n aria-hidden\n className=\"pointer-events-none absolute right-[10px] hidden md:block rounded-[3px] border border-[color:var(--line)] px-[5px] py-px font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--muted)]\"\n >\n /\n </kbd>\n </label>\n\n <div className=\"relative ml-auto flex shrink-0 items-center gap-[var(--topbar-icon-gap,8px)]\">\n {/* Reference/UI-Platform \"Top bar — required elements\" (2026-10-03):\n there is no Build notes control. Rendered only if an app opts in. */}\n {buildNotes ? (\n <button\n type=\"button\"\n onClick={buildNotes?.onOpen}\n className=\"inline-flex h-8 shrink-0 items-center gap-1.5 rounded-[5px] px-3 text-xs font-semibold text-[color:var(--muted)] transition hover:bg-[color:var(--surface-sunken,var(--panel-elevated))] hover:text-[color:var(--foreground)]\"\n >\n <BookOpenIcon />\n {buildNotes?.label ?? 'Build notes'}\n </button>\n ) : null}\n {actionsList && actionsList.length > 0\n ? actionsList.map((action) => (\n <NavTopBarActionButton key={action.key} action={action} />\n ))\n : null}\n {actions}\n {themeToggle}\n\n {/* My Account menu — avatar + name/email + chevron trigger, with the\n full account dropdown (profile/org links, roles, account switcher,\n appearance, sign out). Native <details> popover. Hidden when the\n shell draws the user card in the left-bar footer instead. */}\n {accountMenu === 'topbar' ? (\n <details data-nav-details className=\"group/acct relative\">\n <summary className=\"group/tbtip relative flex cursor-pointer list-none items-center gap-2.5 rounded-full py-1 pl-1 pr-2 transition hover:bg-[color:var(--panel-elevated)] [&::-webkit-details-marker]:hidden\">\n {/* Same circle size as every top-bar icon button (one shared var).\n Avatar precedence: photo → memoji → initials. */}\n <span className=\"flex h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)] items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-xs font-bold text-[#FFFFFF]\">\n {user?.avatarUrl || user?.memojiUrl ? (\n <img\n src={(user.avatarUrl || user.memojiUrl) as string}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n initials\n )}\n </span>\n <span className=\"hidden flex-col leading-tight md:flex\">\n <span className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {displayName}\n </span>\n <span className=\"text-xs text-[color:var(--muted)]\">{secondary}</span>\n </span>\n <ChevronDown />\n <span className=\"group-open/acct:hidden\">\n <TopBarTooltip\n title=\"My Account\"\n description={\n <>\n {hasRealName ? rawName : user?.email ?? 'Signed in'}\n {user?.email ? (\n <>\n <br />\n {user.email}\n </>\n ) : null}\n <br />\n Profile, organizations, appearance and sign out.\n </>\n }\n />\n </span>\n </summary>\n {/*\n The menu grows with the user's data — roles, linked accounts, the\n theme control — and on a short viewport (or a user in many orgs) it\n ran past the bottom of the screen with no way to scroll, putting\n Sign out permanently out of reach. Cap the panel at the viewport,\n scroll the SECTIONS, and keep Sign out outside that scroll area so\n it is always on screen no matter how long the list gets.\n */}\n <NavAccountMenuPanel userMenu={userMenu} onSignOut={onSignOut} placement=\"below\" />\n </details>\n ) : null}\n {accountMenu === 'topbar' && !hasRealName && user ? (\n <NamePromptBubble profileHref={userMenu?.myProfileHref} />\n ) : null}\n </div>\n </header>\n {/* Brand gradient rule — Reference/UI-Platform \"Top bar → required\n elements\": \"A 3px strip of the brand gradient (blue → red) runs\n directly beneath it.\" Chrome-owned token, never the party-identity\n race-red. */}\n <div\n aria-hidden\n className=\"h-[3px] w-full shrink-0\"\n style={{\n background:\n 'var(--chrome-gradient, linear-gradient(to right, #007BFF, #A54B7A, #E63946))',\n }}\n />\n </div>\n )\n}\n\n/**\n * The account menu body — profile/org links, roles, account switcher,\n * appearance, navigation display, sign out. One definition drawn from two\n * triggers: the top-bar avatar (`placement=\"below\"`, legacy) and the left-bar\n * footer user card (`placement=\"above\"`, Reference/UI-Platform v30).\n */\nfunction NavAccountMenuPanel({\n userMenu,\n onSignOut,\n placement,\n}: {\n userMenu?: NavUserMenu\n onSignOut?: () => void\n placement: 'below' | 'above'\n}) {\n const rc = useRailCollapse()\n const wrapper =\n placement === 'above'\n ? rc('max-md:right-auto max-md:w-64') + ' absolute bottom-full left-0 right-0 z-40 mb-2 flex max-h-[calc(100vh-5rem)] flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 text-[color:var(--foreground)] shadow-[var(--shadow-soft)]'\n : 'absolute right-0 z-30 mt-2 flex max-h-[calc(100vh-5rem)] w-72 flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]'\n return (\n <div className={wrapper}>\n {placement === 'below' ? <TopBarPanelArrow /> : null}\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n {userMenu?.myProfileHref ? (\n <a\n href={safeHref(userMenu.myProfileHref)}\n className=\"flex w-full items-center gap-2.5 px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n <ProfileIcon />\n My Profile\n </a>\n ) : null}\n {userMenu?.organizationSettingsHref ? (\n <a\n href={safeHref(userMenu.organizationSettingsHref)}\n className=\"flex w-full items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n <BriefcaseIcon />\n Organization Settings\n </a>\n ) : null}\n\n {userMenu?.roles && userMenu.roles.length > 0 ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Roles & Organizations\n </p>\n <ul className=\"flex flex-col gap-1.5\">\n {userMenu.roles.map((r, i) => (\n <li key={`${r.role}-${i}`} className=\"flex flex-wrap items-center gap-1.5 text-sm\">\n <span className=\"rounded-md bg-[color:var(--panel)] px-2 py-0.5 text-xs font-bold uppercase tracking-wide text-[color:var(--foreground)]\">\n {r.role}\n </span>\n {r.orgName ? (\n <span className=\"text-[color:var(--muted)]\">in {r.orgName}</span>\n ) : null}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {userMenu?.accounts && userMenu.accounts.length > 0 ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Accounts\n </p>\n <ul className=\"flex flex-col gap-1\">\n {userMenu.accounts.map((a) => (\n <li key={a.id} className=\"flex items-center gap-2.5\">\n <button\n type=\"button\"\n onClick={() => {\n if (!a.active) userMenu.onSwitchAccount?.(a.id)\n }}\n className=\"flex min-w-0 flex-1 items-center gap-2.5 rounded-lg px-1 py-1 text-left hover:bg-[color:var(--panel)]\"\n >\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-[11px] font-bold text-[#FFFFFF]\">\n {a.avatarUrl ? (\n <img src={a.avatarUrl} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n (a.name ?? a.email ?? '?').slice(0, 2).toUpperCase()\n )}\n </span>\n <span className=\"flex min-w-0 flex-col leading-tight\">\n <span\n className={[\n 'truncate text-sm font-semibold',\n a.active\n ? 'text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {a.name ?? a.email ?? a.id.slice(0, 8)}\n </span>\n <span className=\"truncate text-xs text-[color:var(--muted)]\">\n {a.active ? 'Active' : a.email ?? ''}\n </span>\n </span>\n </button>\n {!a.active && userMenu.onRemoveAccount ? (\n <button\n type=\"button\"\n aria-label={`Remove ${a.name ?? a.email ?? 'account'}`}\n onClick={() => userMenu.onRemoveAccount?.(a.id)}\n className=\"shrink-0 rounded p-1 text-[color:var(--color-accent-fg,var(--color-accent))] hover:bg-[color:var(--panel)]\"\n >\n <TrashIcon />\n </button>\n ) : null}\n </li>\n ))}\n </ul>\n {userMenu.addAccountHref || userMenu.onAddAccount ? (\n userMenu.addAccountHref ? (\n <a\n href={safeHref(userMenu.addAccountHref)}\n className=\"mt-1.5 flex items-center gap-2.5 rounded-lg px-1 py-1.5 text-sm font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:bg-[color:var(--panel)]\"\n >\n <AddUserIcon />\n Add Account\n </a>\n ) : (\n <button\n type=\"button\"\n onClick={userMenu.onAddAccount}\n className=\"mt-1.5 flex w-full items-center gap-2.5 rounded-lg px-1 py-1.5 text-left text-sm font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:bg-[color:var(--panel)]\"\n >\n <AddUserIcon />\n Add Account\n </button>\n )\n ) : null}\n </div>\n ) : null}\n\n {userMenu?.theme ? (\n <div className=\"border-t border-[color:var(--line)]\">\n <NavThemeControl\n value={userMenu.theme.value}\n onChange={userMenu.theme.onChange}\n />\n </div>\n ) : null}\n {userMenu?.navDisplay ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Navigation display\n </p>\n <div role=\"radiogroup\" aria-label=\"Navigation display\" className=\"flex flex-col gap-0.5\">\n {NAV_DISPLAY_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={userMenu.navDisplay?.value === opt.value}\n onClick={() => userMenu.navDisplay?.onChange(opt.value)}\n className={[\n 'flex w-full items-center justify-between rounded-md px-2 py-1.5 text-left text-sm font-medium',\n userMenu.navDisplay?.value === opt.value\n ? 'text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n {opt.label}\n {userMenu.navDisplay?.value === opt.value ? <span aria-hidden>✓</span> : null}\n </button>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n\n {onSignOut ? (\n <button\n type=\"button\"\n onClick={onSignOut}\n className=\"flex w-full shrink-0 items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)] hover:text-[color:var(--color-accent-fg,var(--color-accent))]\"\n >\n <SignOutIcon />\n Sign out\n </button>\n ) : null}\n </div>\n )\n}\n\n/**\n * Left-bar footer user card: 28px avatar · name · email · chevron-up. Opens\n * the account menu upward (Specs/Contacts design rail; UI-Platform v30 →\n * \"The user … lives in the left bar footer\").\n */\nfunction NavSidebarUserCard({\n user,\n userMenu,\n onSignOut,\n}: {\n user: NavUser\n userMenu?: NavUserMenu\n onSignOut?: () => void\n}) {\n const rawName = user.name?.trim() || ''\n const hasRealName = rawName.length > 0 && !rawName.includes('@')\n // Left-Navigation §10: \"First L.\" — first name plus last initial.\n const displayName = hasRealName ? shortUserName(rawName) : (user.email ?? 'Signed in')\n const initials = hasRealName\n ? rawName.split(/\\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join('').toUpperCase()\n : (user.email ?? 'P').slice(0, 2).toUpperCase()\n const secondary = hasRealName\n ? user.email || [user.tier, user.role].filter(Boolean).join(' · ') || 'member'\n : [user.tier, user.role].filter(Boolean).join(' · ') || 'member'\n const rc = useRailCollapse()\n return (\n <details data-nav-details className=\"group/acct relative\">\n <summary\n aria-label=\"My Account\"\n className={`flex w-full cursor-pointer list-none items-center gap-[9px] rounded-[5px] px-1 py-1 text-left transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel-elevated))] [&::-webkit-details-marker]:hidden ${rc('max-md:justify-center max-md:px-0')}`}\n >\n <span className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--sidebar-avatar-bg,var(--color-accent-bg-safe,var(--color-accent)))] text-[11px] font-bold text-[#FFFFFF]\">\n {user.avatarUrl || user.memojiUrl ? (\n <img src={(user.avatarUrl || user.memojiUrl) as string} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n initials\n )}\n </span>\n <span className={`flex min-w-0 flex-1 flex-col ${rc('max-md:hidden')}`}>\n <span className=\"truncate text-[12px] font-semibold leading-[1.2] text-[color:var(--sidebar-text,var(--foreground))]\">\n {displayName}\n </span>\n <span className=\"truncate text-[11px] leading-[1.3] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))]\">\n {secondary}\n </span>\n </span>\n <ChevronDown size={14} className={`shrink-0 rotate-180 text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] transition group-open/acct:rotate-0 ${rc('max-md:hidden')}`} />\n </summary>\n <NavAccountMenuPanel userMenu={userMenu} onSignOut={onSignOut} placement=\"above\" />\n {!hasRealName ? <NamePromptBubble profileHref={userMenu?.myProfileHref} placement=\"above\" /> : null}\n </details>\n )\n}\n\n/** `#RRGGBB` (+ optional alpha) → `rgba(r,g,b,a)`; undefined for anything else. */\nfunction hexToRgba(hex: string | null | undefined, alpha: number): string | undefined {\n if (!hex) return undefined\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim())\n if (!m) return undefined\n const n = parseInt(m[1], 16)\n return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${alpha})`\n}\n\n/**\n * Floating, per-session-dismissable bubble under the account trigger that\n * prompts a user with no display name to set their first + last name. The\n * arrow points up at the avatar; dismissal is remembered in sessionStorage\n * until they actually set a name.\n */\nfunction NamePromptBubble({ profileHref, placement = 'below' }: { profileHref?: string; placement?: 'below' | 'above' }) {\n const KEY = 'politogy_name_prompt_dismissed'\n const [dismissed, setDismissed] = useState(true)\n useEffect(() => {\n try {\n setDismissed(sessionStorage.getItem(KEY) === '1')\n } catch {\n setDismissed(false)\n }\n }, [])\n if (dismissed) return null\n return (\n <div\n className={\n placement === 'above'\n ? 'absolute bottom-full left-0 z-30 mb-2 w-64 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-3 text-left shadow-[var(--shadow-soft)]'\n : 'absolute right-4 top-full z-30 mt-2 w-64 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-3 shadow-[var(--shadow-soft)]'\n }\n >\n <span\n aria-hidden\n className={\n placement === 'above'\n ? 'absolute -bottom-[5px] left-[14px] h-2.5 w-2.5 rotate-45 border-b border-r border-[color:var(--line)] bg-[color:var(--panel-elevated)]'\n : 'absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]'\n }\n />\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n Add your name\n </p>\n <p className=\"mt-0.5 text-xs leading-snug text-[color:var(--muted)]\">\n Set your first and last name so teammates see you — not your email.\n </p>\n <div className=\"mt-2 flex items-center gap-2\">\n {profileHref ? (\n <a\n href={safeHref(profileHref)}\n className=\"rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] px-3 py-1 text-xs font-semibold text-[#FFFFFF] hover:opacity-90\"\n >\n Set name\n </a>\n ) : null}\n <button\n type=\"button\"\n onClick={() => {\n setDismissed(true)\n try {\n sessionStorage.setItem(KEY, '1')\n } catch {\n /* session-only dismiss */\n }\n }}\n className=\"rounded-full border border-[color:var(--line)] px-3 py-1 text-xs font-semibold text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n Dismiss\n </button>\n </div>\n </div>\n )\n}\n\n/** \"Spencer Hill\" → \"Spencer H.\" — first name + last initial. */\nfunction formatFirstLast(name: string): string {\n const parts = name.split(/\\s+/).filter(Boolean)\n if (parts.length === 1) return parts[0]\n return `${parts[0]} ${parts[parts.length - 1][0].toUpperCase()}.`\n}\n\nfunction ProfileIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n </svg>\n )\n}\n\nfunction BriefcaseIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <rect x=\"2\" y=\"7\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\" />\n <path d=\"M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\" />\n </svg>\n )\n}\n\nfunction TrashIcon() {\n return (\n <svg width={14} height={14} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n )\n}\n\nfunction AddUserIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\" />\n <circle cx=\"8.5\" cy=\"7\" r=\"4\" />\n <line x1=\"20\" y1=\"8\" x2=\"20\" y2=\"14\" />\n <line x1=\"23\" y1=\"11\" x2=\"17\" y2=\"11\" />\n </svg>\n )\n}\n\n// Inline log-out glyph (mirrors lucide `LogOut`) to avoid an icon dependency.\nfunction SignOutIcon() {\n return (\n <svg\n width={15}\n height={15}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" x2=\"9\" y1=\"12\" y2=\"12\" />\n </svg>\n )\n}\n\n// A single 32×32 circular icon button for the top bar's structured action list.\n// Renders an <a> when `href` is present (external links open in a new tab),\n// otherwise a <button>. Shows a red count badge when `badge > 0`.\nfunction NavTopBarActionButton({ action }: { action: NavTopBarAction }) {\n const Icon = action.icon\n // Universal treatment (Global Rules v9): size, color and hover are a single\n // shared value across every top-bar slot — only the glyph varies per slot.\n // Tone is a semantic state, not a bespoke per-slot style. The class comes\n // from the ONE shared builder in chromeActions so the data-backed widgets\n // and this structured list can never drift apart.\n const className = topBarIconButtonClass(action.tone ?? 'default')\n\n // Per-slot glyph from Brand; `icon` is the fallback until the token resolves.\n // Brand emits Feather/Lucide glyph NAMES, not asset paths.\n const glyphName = useTopBarIconSlotGlyph(action.slot ?? 'apps')\n const BrandGlyph = action.slot ? resolveBrandGlyph(glyphName) : null\n const Glyph = BrandGlyph ?? Icon\n\n const content = (\n <>\n <Glyph size={TOPBAR_GLYPH_SIZE} className=\"text-current\" />\n {typeof action.badge === 'number' && action.badge > 0 ? (\n <span className=\"absolute -top-[5px] -right-[5px] flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--chrome-danger,var(--color-accent))] px-1 text-[10px] font-bold leading-4 text-[#FFFFFF]\">\n {action.badge}\n </span>\n ) : null}\n <TopBarTooltip title={action.label} description={action.description} />\n </>\n )\n\n const isExternal = action.href ? /^https?:\\/\\//.test(action.href) : false\n\n if (action.href) {\n return (\n <a\n href={safeHref(action.href)}\n aria-label={action.label}\n className={className}\n {...(isExternal ? { target: '_blank', rel: 'noreferrer' } : {})}\n >\n {content}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n onClick={action.onClick}\n aria-label={action.label}\n className={className}\n >\n {content}\n </button>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Page tab strip — THE canonical page tab strip (shell 0.69.0).\n//\n// Brand guideline \"Tabs are an underlined strip\" (components-tabs-geometry):\n// a row of text tabs, each with an optional mono count pill, above a 1px G3\n// rule, with no folder or card chrome. Tabs are 13px semibold with 12px\n// vertical padding (12px / 8px when small). The selected tab is Graphite with\n// a 2px underline in the MODE COLOR (`modes.<mode>.primary`), read as\n// `--mode-accent` — never `modes.<mode>.accent`, which is white and only for\n// highlights on the dark rail. Unselected tabs are G4 and turn Graphite on\n// hover.\n//\n// It sits in the page body, below the page header, aligned to the content\n// gutter (Brand guideline \"UX Navigation\"). Apps render it inside the frame's\n// `children`; they never hand-roll or restyle a tab strip.\n//\n// Why this one and not the main entry's `HeaderTabBar` (now @deprecated): it\n// has no Chakra or react-router dependency, so every app can import it\n// whatever its framework; it renders `href` tabs through the app's own link\n// primitive, so sub-views are URL-addressable; and it already carries the\n// tablist / tab / disabled semantics. `HeaderTabBar` is icon-only by\n// construction (its label is only a tooltip) and state-only (no links).\n//\n// Colors come from the Brand `--tab-*` / `--color-*` vars emitted by\n// `/api/tokens?format=css`, with literal fallbacks so the strip still renders\n// before the runtime token sheet loads.\n// ---------------------------------------------------------------------------\n\nexport type NavTab = {\n /** Stable identity (used as the React key). */\n key: string\n /** The tab's visible text. */\n label: string\n /**\n * A Lucide icon rendered 6px left of the label (Reference/UI-Platform →\n * Tabs, decided 2026-10-06: \"Icon + label. Each tab is a Lucide icon.\"),\n * 15px / 1.75 stroke (13px on a small strip), following the label's\n * selected / unselected / hover color via `currentColor`. Icon-ONLY tabs\n * (no label) are retired — this always pairs with `label`.\n */\n icon?: NavIcon\n /** Optional count, drawn as a mono pill after the label. */\n count?: string | number | null\n /** Route to link to (rendered through `linkComponent`). */\n href?: string\n /** Click handler — rendered as a `<button>` when there's no `href`. */\n onSelect?: () => void\n /** Whether this tab is the active one (drives the mode-color underline). */\n selected?: boolean\n /**\n * Non-interactive, dimmed tab (e.g. Surveys' Canvas/Results before a survey\n * is chosen). Renders a non-navigating span; `disabledTitle` is the tooltip\n * explaining why.\n */\n disabled?: boolean\n disabledTitle?: string\n}\n\nexport type NavTabStripProps = {\n tabs: NavTab[]\n /** Accessible name for the tablist. */\n 'aria-label'?: string\n /** Routing primitive for `href` tabs (Next `<Link>`, etc). Defaults to <a>. */\n linkComponent?: NavLinkComponent\n /** `'sm'`: 12px text with 8px vertical padding. Default `'md'` (13px / 12px). */\n size?: 'md' | 'sm'\n /** Extra classes on the tablist container. */\n className?: string\n /**\n * Optional tab panel rendered directly below the strip, on the page\n * surface with no card chrome. Omit to render only the strip and compose\n * the page body yourself.\n */\n children?: ReactNode\n}\n\n/** The mode color on light surfaces (Reference/UI-Platform → Per-mode branding). */\nconst TAB_UNDERLINE_COLOR = 'var(--mode-accent, var(--color-accent))'\n\nfunction NavTabButton({\n tab,\n Link,\n size,\n}: {\n tab: NavTab\n Link: NavLinkComponent\n size: 'md' | 'sm'\n}) {\n const { label, icon: Icon, count, href, onSelect, selected, disabled, disabledTitle } = tab\n\n // The 2px underline sits on the strip's 1px rule (`-mb-px`), so the selected\n // tab's underline replaces the rule beneath it rather than stacking on it.\n // Color/border/text-align are set inline, not via arbitrary-bracket Tailwind\n // classes (`text-[color:var(...)]`) — a style-diff against design (Specs,\n // 2026-10-09, phonebank-dashboard-desktop) found a live color/border/align\n // mismatch, and a consuming app's Tailwind content scan not catching a\n // bracketed `var()`-with-fallback utility is a known failure mode for this\n // pattern (see UI-Platform `@source` contract). Inline styles can't be\n // dropped by a content scanner.\n const base = '-mb-px inline-flex shrink-0 items-center gap-2 font-semibold leading-none transition-colors'\n const sizeClass = size === 'sm' ? 'py-2 text-[12px]' : 'py-3 text-[13px]'\n const stateClass = disabled ? 'cursor-not-allowed opacity-50' : 'hover:text-[color:var(--tab-hover-color,#2F3136)]'\n const className = `${base} ${sizeClass} ${stateClass}`\n // Unselected/disabled tab text used --color-g4 (#929599), the Brand\n // content-neutral gray — correct for body copy but only 2.58-2.76:1 against\n // the tab strip's light surfaces, failing WCAG AA (4.5:1 minimum, axe scan\n // 2026-10-09, 26 violations). --tab-text-muted is a dedicated nav-tab token\n // (not a --color-g4 edit, which stays as-is for the rest of the Brand ramp)\n // defaulting to --muted (#5C6B80), already measured at 5.42:1 on the light\n // rail and ~4.8:1+ on the tab-row surfaces — same muted blue-gray family,\n // just dark enough to clear AA.\n const color = disabled\n ? 'var(--tab-text-muted,#5C6B80)'\n : selected\n ? 'var(--tab-selected-color,#2F3136)'\n : 'var(--tab-text-muted,#5C6B80)'\n // Design has NO border on an unselected tab (border-width/style 0/none),\n // not a 2px transparent one — a transparent-color border still reports a\n // non-zero width/solid style to a computed-style diff (Specs style_diff,\n // 2026-10-09, email-builder-desktop). Only the selected tab gets the 2px\n // underline.\n const style: CSSProperties =\n selected && !disabled\n ? {\n textAlign: 'center',\n borderBottomWidth: 2,\n borderBottomStyle: 'solid',\n borderBottomColor: TAB_UNDERLINE_COLOR,\n color,\n }\n : {\n textAlign: 'center',\n borderBottomWidth: 0,\n borderBottomStyle: 'none',\n borderBottomColor: 'transparent',\n color,\n }\n\n const iconSize = size === 'sm' ? 13 : 15\n const content = (\n <>\n {Icon ? (\n <Icon size={iconSize} className=\"shrink-0 text-current\" strokeWidth={1.75} />\n ) : null}\n <span>{label}</span>\n {count !== undefined && count !== null && count !== '' ? (\n <span className=\"rounded-full bg-[color:var(--color-g2,#ECEEEF)] px-1.5 py-0.5 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] font-semibold leading-none\">\n {count}\n </span>\n ) : null}\n </>\n )\n\n // Disabled: non-navigating span, still exposed as a tab for AT.\n if (disabled) {\n return (\n <span\n role=\"tab\"\n aria-selected={false}\n aria-disabled=\"true\"\n aria-label={label}\n title={disabledTitle}\n className={className}\n style={style}\n >\n {content}\n </span>\n )\n }\n\n if (href) {\n return (\n <Link\n href={href}\n role=\"tab\"\n aria-selected={selected ? true : false}\n aria-label={label}\n className={className}\n style={style}\n >\n {content}\n </Link>\n )\n }\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected ? true : false}\n aria-label={label}\n onClick={onSelect}\n className={className}\n style={style}\n >\n {content}\n </button>\n )\n}\n\n/**\n * The canonical page tab strip: underlined text tabs on a 1px rule. Render it\n * in the page body below the page header; pass the app's `Link` as\n * `linkComponent` for `href` tabs.\n */\nexport function NavTabStrip({\n tabs,\n 'aria-label': ariaLabel,\n linkComponent,\n size = 'md',\n className,\n children,\n}: NavTabStripProps) {\n const Link = linkComponent ?? DefaultLink\n return (\n <>\n <div\n role=\"tablist\"\n aria-label={ariaLabel}\n className={[\n // 26px, not 24px: a style_diff against design (email-builder-desktop,\n // 2026-10-09) measured the rendered row gap 4px short of spec (48 vs\n // 52) at the 24px default.\n 'flex items-end gap-[var(--tab-gap,26px)] border-b border-[color:var(--tab-border-color,#D7DADF)]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {tabs.map((tab) => (\n <NavTabButton key={tab.key} tab={tab} Link={Link} size={size} />\n ))}\n </div>\n {children !== undefined ? <div className=\"pt-5\">{children}</div> : null}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Beta banner — a full-width amber NOTICE strip rendered directly below the top\n// bar (a semantic notice, not a chrome surface, so it keeps its amber hue in\n// both themes via the --beta-banner-* tokens in chrome.css). One line, centered,\n// with a bold + underlined link to the Beta Terms & Conditions.\n// ---------------------------------------------------------------------------\n\nconst BETA_BANNER_DEFAULTS = {\n text: 'Our product is in Beta. Thank you for participating in the Pilot Program. ',\n linkLabel: 'You can click here to see the Terms & Conditions for Beta users.',\n href: 'https://app.politogyvrm.com/beta-terms-and-conditions',\n} as const\n\n/**\n * sessionStorage key holding the Beta-banner dismissal. sessionStorage — not\n * localStorage — so the dismissal lasts only for the browser session; and it is\n * additionally cleared on sign-out (see `clearBetaBannerDismissal`, called from\n * the chrome frame) so a fresh LOGIN always re-shows the notice.\n */\nexport const BETA_BANNER_DISMISS_KEY = 'politogy_beta_banner_dismissed'\n\n/**\n * Re-arm the Beta banner. The chrome frame calls this on sign-out so the notice\n * reappears at the next login rather than staying hidden across the boundary\n * (sessionStorage survives an in-tab logout→login round trip on its own).\n */\nexport function clearBetaBannerDismissal(): void {\n if (typeof window === 'undefined') return\n try {\n window.sessionStorage.removeItem(BETA_BANNER_DISMISS_KEY)\n } catch {\n /* storage unavailable (private mode / disabled) — nothing to clear */\n }\n}\n\nexport type NavBetaBannerProps = {\n /** Leading sentence(s) before the link. Defaults to the standard Beta copy. */\n text?: string\n /** Bold + underlined link label. Defaults to the standard Terms copy. */\n linkLabel?: string\n /** Terms & Conditions URL (opens in a new tab). Defaults to the app T&C page. */\n href?: string\n /**\n * Show a dismiss (×) button that hides the banner for the rest of the browser\n * session. Cleared on sign-out, so it returns at the next login. Default true.\n */\n dismissible?: boolean\n}\n\nexport function NavBetaBanner({ text, linkLabel, href, dismissible = true }: NavBetaBannerProps) {\n const body = text ?? BETA_BANNER_DEFAULTS.text\n const label = linkLabel ?? BETA_BANNER_DEFAULTS.linkLabel\n const target = href ?? BETA_BANNER_DEFAULTS.href\n\n // Start visible on both server and first client render (sessionStorage is not\n // readable during SSR), then hide in an effect if this session already\n // dismissed it — this keeps hydration markup identical and avoids a mismatch.\n const [dismissed, setDismissed] = useState(false)\n useEffect(() => {\n if (!dismissible) return\n try {\n if (window.sessionStorage.getItem(BETA_BANNER_DISMISS_KEY) === '1') setDismissed(true)\n } catch {\n /* storage unavailable — leave the banner visible */\n }\n }, [dismissible])\n\n if (dismissible && dismissed) return null\n\n const onDismiss = () => {\n setDismissed(true)\n try {\n window.sessionStorage.setItem(BETA_BANNER_DISMISS_KEY, '1')\n } catch {\n /* storage unavailable — banner still hides for this render */\n }\n }\n\n return (\n <div\n role=\"note\"\n className=\"relative w-full px-10 py-2 text-center text-sm\"\n style={{\n // Amber warning fill, matching the \"10DLC Registration Required\" notice\n // (HITL 2026-07-29). This used to fall through to `--color-accent`, the\n // brand RED, so a participation notice read as an error. The\n // --beta-banner-* tokens carry the amber defaults (chrome.css) and a\n // Brand edit still wins over them.\n background: 'var(--beta-banner-bg, #FEEBC8)',\n color: 'var(--beta-banner-text, #1A202C)',\n }}\n >\n <span>{body}</span>\n <a\n href={safeHref(target)}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-bold underline\"\n style={{ color: 'var(--beta-banner-text, #1A202C)' }}\n >\n {label}\n </a>\n {dismissible ? (\n <button\n type=\"button\"\n onClick={onDismiss}\n aria-label=\"Dismiss this notice\"\n title=\"Dismiss\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex h-6 w-6 items-center justify-center rounded text-base leading-none opacity-70 hover:opacity-100\"\n style={{ color: 'var(--beta-banner-text, #1A202C)' }}\n >\n ×\n </button>\n ) : null}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavAppShellProps = {\n sidebar: NavSidebarProps\n topBar: NavTopBarProps\n /**\n * When supplied, a full-width Beta notice strip renders directly below the top\n * bar. Presence of the prop enables it; all fields fall back to the standard\n * Beta copy + Terms & Conditions link.\n */\n betaBanner?: NavBetaBannerProps\n /**\n * @deprecated The frame's content area is one fluid `<main>` (Brand\n * guideline \"Content width is fluid\"): the 24px gutter (16px below `md`),\n * no max-width and no centered container. Apps never emit their own page\n * container, so there is nothing left to choose here.\n *\n * `'bare'` is still honored — it renders `children` with no `<main>` and no\n * gutter — only so VRM core, which renders `NavAppShell` directly around\n * pages that still carry their own `PageContainer`, does not get a nested\n * `<main>` before it migrates. It warns in development and will be removed.\n * `'padded'` is now the same as omitting the prop.\n */\n contentWrapper?: 'padded' | 'bare'\n /**\n * The operating Mode this frame is scoped to, stamped on the root as\n * `data-politogy-mode` so the Brand API's per-Mode chrome tokens can target\n * it (Reference/UI-Platform → \"Per-mode branding — one accent per Mode\").\n *\n * This is app IDENTITY, not app configuration: `PolitogyAppFrame` passes it\n * from the `POLITOGY_APPS` registry, never from a prop an app supplies, so an\n * app still cannot choose its own chrome colour.\n *\n * Omitted (or a Mode that declares no chrome group in the Brand API) => every\n * accent falls back to the global one, exactly as before 0.47.\n */\n modeId?: string\n /**\n * Where the user card / account menu renders. `'sidebar'` (default since\n * 0.68.0) draws it in the left-bar footer and hides the top-bar trigger\n * (Reference/UI-Platform v30); `'topbar'` restores the 0.67 top-right badge.\n */\n accountMenuPlacement?: 'sidebar' | 'topbar'\n children: ReactNode\n}\n\n/**\n * Full chrome: branded left sidebar + sticky top navbar + scrollable content\n * region. Presentational only — wrap it in app-level auth/gating as needed.\n */\n/**\n * Closes any open chrome <details data-nav-details> (org switcher, mode\n * selector, My Account) when the pointer lands outside it or Escape is\n * pressed — dropdowns must deselect on outside click (HITL 2026-07-23).\n */\nfunction useCloseNavDetailsOnOutsideClick() {\n useEffect(() => {\n const close = (target: Node | null) => {\n document.querySelectorAll('details[data-nav-details][open]').forEach((d) => {\n if (!target || !d.contains(target)) d.removeAttribute('open')\n })\n }\n const onPointerDown = (e: MouseEvent) => close(e.target as Node)\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close(null)\n }\n document.addEventListener('mousedown', onPointerDown)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onPointerDown)\n document.removeEventListener('keydown', onKey)\n }\n }, [])\n}\n\nexport function NavAppShell({\n sidebar,\n topBar,\n betaBanner,\n contentWrapper = 'padded',\n accountMenuPlacement = 'sidebar',\n modeId,\n children,\n}: NavAppShellProps) {\n useCloseNavDetailsOnOutsideClick()\n if (contentWrapper === 'bare') {\n warnDeprecated(\n 'contentWrapper',\n \"`contentWrapper: 'bare'` is deprecated: the frame's <main> is fluid and apps must not emit their own page container. Remove the app's PageContainer and drop the prop.\",\n )\n }\n // Below `md` the rail is the 64px icon rail (see NavSidebar). The shell owns\n // the expanded-drawer state so the hamburger (NavTopBar) and the drawer\n // (NavSidebar) can stay presentational.\n const [navOpen, setNavOpen] = useState(false)\n const expandRail = () => {\n writeRailPreference('expanded')\n setNavOpen(true)\n }\n const collapseRail = () => {\n writeRailPreference('collapsed')\n setNavOpen(false)\n }\n // Route navigation closes the drawer — a stale open drawer over a new page\n // reads as broken, not as \"still browsing\".\n useEffect(() => {\n setNavOpen(false)\n }, [sidebar.pathname])\n // Left-Navigation §11.6: the expand choice is remembered per user. Read it\n // back after mount (no hydration mismatch); it only applies below `md`,\n // where the rail is collapsed. Explicit Expand / Collapse writes it.\n useEffect(() => {\n if (readRailPreference() !== 'expanded') return\n const narrow =\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia('(max-width: 767.98px)').matches\n : false\n if (narrow) setNavOpen(true)\n }, [])\n // The page behind a mobile drawer must not scroll while it's open.\n useEffect(() => {\n if (!navOpen) return\n const previous = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n return () => {\n document.body.style.overflow = previous\n }\n }, [navOpen])\n // The user card lives in the left-bar footer (UI-Platform v30). Lift the\n // top bar's user / menu / sign-out into the sidebar footer unless the app\n // already supplied them there or opted back into the top-bar badge.\n const sidebarFooter: NavFooter | null | undefined =\n accountMenuPlacement === 'sidebar' && topBar.user\n ? {\n ...(sidebar.footer ?? {}),\n user: sidebar.footer?.user ?? topBar.user,\n userMenu: sidebar.footer?.userMenu ?? topBar.userMenu,\n onSignOut: sidebar.footer?.onSignOut ?? topBar.onSignOut,\n }\n : sidebar.footer\n return (\n <div\n data-politogy-mode={modeId ?? modeIdFromLabel(sidebar.mode?.label)}\n className=\"min-h-screen bg-[color:var(--background)] text-[color:var(--foreground)]\"\n >\n {/* Cross-app sidebar nav speculation: every consumer rendering\n NavAppShell gets this for free (no per-app opt-in) — see\n src/speculation/SpeculationRulesScript.tsx. */}\n <SpeculationRulesScript items={sidebar.nav.items} />\n <NavSidebar\n {...sidebar}\n footer={sidebarFooter}\n open={navOpen}\n onClose={collapseRail}\n onOpen={expandRail}\n onNavigate={() => setNavOpen(false)}\n />\n {/* The rail is never hidden, so content is always offset by it: 64px\n below `md`, the full rail from `md` up. */}\n <div className=\"pl-[var(--sidebar-collapsed-width,64px)] md:pl-[var(--sidebar-width,236px)]\">\n <NavTopBar\n {...topBar}\n accountMenu={topBar.accountMenu ?? (accountMenuPlacement === 'sidebar' ? 'sidebar' : 'topbar')}\n />\n {betaBanner ? <NavBetaBanner {...betaBanner} /> : null}\n {/* Reference/UI-Platform \"Page header\": the title lives in the page\n body now, 22px below the top bar, not in the bar itself and never\n as a breadcrumb trail. Rendered here — above both wrapper modes —\n so a 'bare' app (which owns its own content furniture) still gets\n the required chrome-owned title line. */}\n {topBar.title ? (\n <h1 className=\"px-4 pt-7 text-xl font-semibold text-[color:var(--foreground)] md:px-6\">\n {topBar.title}\n </h1>\n ) : null}\n {contentWrapper === 'bare' ? (\n <div data-shell-content=\"\" className={topBar.title ? 'mt-[22px]' : undefined}>\n {children}\n </div>\n ) : (\n // Brand guidelines \"Content width is fluid\" + \"Content body\n // padding\": `<main>` fills the space beside the rail with ONE\n // gutter — 24px, or 16px below `md`, horizontally and vertically —\n // and has no max-width and no centered container. Form and settings\n // pages constrain themselves with <FormColumn> (960px, left-aligned).\n // The shell owns the page background and the gutter; an app's own\n // cards are its own furniture and stay app-owned.\n <main\n data-shell-content=\"\"\n className={`min-h-[calc(100vh-63px)] bg-[color:var(--chrome-page-bg,#F4F5F7)] px-4 pb-4 md:px-6 md:pb-6 ${topBar.title ? 'pt-[22px]' : 'pt-4 md:pt-6'}`}\n >\n {children}\n </main>\n )}\n </div>\n </div>\n )\n}\n\n// The one constrained layout inside the fluid <main>: a 960px left-aligned\n// column for form and settings pages. Re-exported here (as well as from the\n// main entry) so an app needs no Chakra / react-router peer to use it.\nexport { default as FormColumn } from '../components/FormColumn'\n\n// Canonical Politogy VRM menu — the standard nav structure every politogy app\n// renders, per operating Mode, with hooks for the app-owned \"Contacts\" item and\n// Support handler, plus the Campaign feature-availability config.\nexport {\n standardPolitogyNav,\n CAMPAIGN_FEATURE_AVAILABILITY,\n type StandardNavIconKey,\n type StandardNavOptions,\n type StandardNavMode,\n type CampaignFeatureAvailability,\n} from './standardNav'\n","// Breadcrumb derivation — pure, dependency-free logic (no React, no DevNotes),\n// so it is importable from a server module and testable in isolation.\n//\n// The standard is Dashboard > Sub > Item (HITL 2026-07-23), derived from the\n// same nav tree the sidebar renders. Apps previously hand-built their own\n// trails and disagreed: forms rendered \"Forms > Dashboard\" while polls rendered\n// a lone \"Polls\" crumb under a \"Polls\" title (\"Polls / Polls\").\n\nimport type { NavBreadcrumb, NavItem } from '../native/index'\n\nexport function deriveBreadcrumbs(\n items: NavItem[],\n pathname: string,\n opts?: { search?: string; origin?: string },\n): NavBreadcrumb[] {\n const search = opts?.search ?? (typeof window !== 'undefined' ? window.location.search : '')\n const origin = opts?.origin ?? (typeof window !== 'undefined' ? window.location.origin : '')\n\n // Same-origin comparison: cross-app hrefs are absolute, local ones relative.\n const matches = (href?: string): boolean => {\n if (!href) return false\n let path = href\n let query = ''\n if (/^https?:\\/\\//i.test(href)) {\n try {\n const u = new URL(href)\n if (origin && u.origin !== origin) return false\n path = u.pathname\n query = u.search\n } catch {\n return false\n }\n } else {\n const qi = href.indexOf('?')\n if (qi >= 0) {\n path = href.slice(0, qi) || '/'\n query = href.slice(qi)\n }\n }\n if (path !== pathname) return false\n if (!query) return true\n const want = new URLSearchParams(query)\n const have = new URLSearchParams(search)\n for (const [k, v] of want) if (have.get(k) !== v) return false\n return true\n }\n\n // Depth-first walk for the deepest item owning the current route.\n const walk = (nodes: NavItem[], trail: NavItem[]): NavItem[] | null => {\n for (const node of nodes) {\n const here = [...trail, node]\n if (node.children?.length) {\n const deeper = walk(node.children, here)\n if (deeper) return deeper\n }\n if (matches(node.href)) return here\n }\n return null\n }\n\n const trail = walk(items, [])\n // Always anchored at Dashboard; the last crumb is the current location and\n // carries no href (the shell marks it aria-current=\"page\").\n const dashboard = items.find((i) => i.label === 'Dashboard')\n const crumbs: NavBreadcrumb[] = [{ label: 'Dashboard', href: dashboard?.href }]\n if (!trail) return crumbs\n for (const node of trail) {\n if (node.label === 'Dashboard') continue\n crumbs.push({ label: node.label, href: node.href })\n }\n const last = crumbs[crumbs.length - 1]\n if (last) delete (last as { href?: string }).href\n return crumbs\n}\n","// Identity resolution — pure logic, shared by the chrome hook.\n//\n// The chrome API (VRM-core profile) is the AUTHORITY for a user's display name;\n// what an app knows from its own session token is a pre-hydration fallback. An\n// email is never a name: forms passed `user.name ?? user.email`, so a user with\n// no name set had their email rendered as their name in the top bar and the\n// shell's \"add your name\" affordance never fired (HITL 2026-07-23).\n\nexport type ResolvedIdentity = {\n userName: string | null\n email: string | null\n avatarUrl: string | null\n loaded: boolean\n}\n\n/** True when a \"name\" is really just an email address. */\nexport function looksLikeEmail(value: string | null | undefined): boolean {\n return typeof value === 'string' && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value.trim())\n}\n\nexport function resolveIdentity(input: {\n apiName?: string | null\n fallbackName?: string | null\n email?: string | null\n avatarUrl?: string | null\n loaded?: boolean\n}): ResolvedIdentity {\n const apiName = looksLikeEmail(input.apiName) ? null : input.apiName ?? null\n const fallbackName = looksLikeEmail(input.fallbackName) ? null : input.fallbackName ?? null\n return {\n userName: apiName ?? fallbackName,\n email: input.email ?? null,\n avatarUrl: input.avatarUrl ?? null,\n loaded: input.loaded ?? false,\n }\n}\n","// Universal sign-out propagation — the ONE cross-app logout contract.\n//\n// Every Politogy app holds its OWN host-only session cookie with a long sliding\n// window, so signing out of one app used to leave every other open tab — and\n// every other subdomain — signed in until its cookie happened to expire. A user\n// who signs out in Contacts and switches to the Forms tab they already had open\n// is still fully authenticated there. That is the bug this module closes.\n//\n// The vehicle mirrors the active-org contract: a `.politogyvrm.com` cookie that\n// every subdomain can read. It carries a single monotonic value — the epoch\n// milliseconds at which the user signed out.\n//\n// politogy_logout_at = <epoch ms of the most recent sign-out>\n//\n// Two layers cooperate, and BOTH are required:\n//\n// 1. SERVER (authoritative). Each app's middleware compares this cookie\n// against the session's `auth_time`. A session minted BEFORE the last\n// sign-out is dead, whatever its own expiry says — so a reload, a\n// bookmark, or a restored tab can never resurrect it. See\n// `isSessionRevoked`.\n//\n// 2. CLIENT (immediacy). Open tabs are not making requests, so the server\n// layer alone only takes effect on their next navigation. `watchLogout`\n// notices the cookie change within ~1s and navigates the tab out.\n//\n// The cookie is deliberately NOT HttpOnly: it holds no secret — just a\n// timestamp — and every tab on every subdomain must be able to read it from\n// JavaScript. It grants nothing; it only ever revokes.\n//\n// Server-safe (no 'use client'): the constants and `isSessionRevoked` are\n// importable from middleware and server components; the browser helpers no-op\n// on the server.\n\nexport const LOGOUT_COOKIE = 'politogy_logout_at'\n\n/** Same-origin instant channel; cross-subdomain falls back to the cookie poll. */\nconst LOGOUT_CHANNEL = 'politogy-logout'\n\n/** How often a tab re-reads the cookie. Cheap: a string compare, no I/O. */\nconst POLL_MS = 1000\n\nfunction parseTimestamp(value: string | null | undefined): number | null {\n if (!value) return null\n const n = Number(value)\n return Number.isFinite(n) && n > 0 ? n : null\n}\n\n/**\n * Server-side authority. Given the logout-cookie value and the moment this\n * session was authenticated, is the session revoked?\n *\n * `authTime` is the OIDC `auth_time` (seconds) or an equivalent millisecond\n * timestamp captured when the session was minted. Sessions with no recorded\n * auth time are treated as revoked whenever a logout is on record: we cannot\n * prove they postdate it, and failing closed is the only safe direction for a\n * sign-out.\n */\nexport function isSessionRevoked(\n logoutCookieValue: string | null | undefined,\n authTime: number | null | undefined,\n): boolean {\n const loggedOutAt = parseTimestamp(logoutCookieValue)\n if (loggedOutAt === null) return false\n if (authTime == null || !Number.isFinite(authTime) || authTime <= 0) return true\n // Accept either seconds (OIDC auth_time) or milliseconds.\n const authMs = authTime < 1e12 ? authTime * 1000 : authTime\n return authMs < loggedOutAt\n}\n\n/** Read the shared logout timestamp (browser only; null on server or unset). */\nexport function readLogoutCookie(): number | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(new RegExp(`(?:^|;\\\\s*)${LOGOUT_COOKIE}=([^;]+)`))\n return parseTimestamp(m ? decodeURIComponent(m[1]) : null)\n } catch {\n return null\n }\n}\n\n/**\n * Record a sign-out for every tab on every Politogy subdomain. Call this\n * BEFORE navigating to the app's sign-out route, so tabs that are already open\n * see it immediately rather than after the round trip.\n *\n * Scoping mirrors the active-org and theme cookies: parent-domain on\n * *.politogyvrm.com so all app subdomains read it, host-only anywhere else\n * (localhost, *.pages.dev previews).\n */\nexport function broadcastLogout(at: number = Date.now()): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n // 30 days: comfortably longer than the longest app session window, so a tab\n // resumed from sleep still sees the revocation. Shorter than that and a stale\n // session could outlive the signal that killed it.\n document.cookie = `${LOGOUT_COOKIE}=${at}; Path=/; Max-Age=2592000; SameSite=Lax${domainAttr}${secure}`\n try {\n new BroadcastChannel(LOGOUT_CHANNEL).postMessage(at)\n } catch {\n // No BroadcastChannel (older Safari) — the cookie poll covers it.\n }\n}\n\n/**\n * Clear the signal. Call after a successful LOGIN: the new session postdates\n * the old sign-out, and leaving the cookie behind would make every future\n * `isSessionRevoked` check depend on clock skew between the two.\n */\nexport function clearLogoutSignal(): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n document.cookie = `${LOGOUT_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax${domainAttr}`\n}\n\nexport type WatchLogoutOptions = {\n /**\n * Sessions minted at or before this moment are revoked by a sign-out. Pass\n * the session's auth time; when omitted, ANY logout signal observed after the\n * watcher starts fires the callback (correct for an already-open tab, which\n * by definition authenticated earlier).\n */\n authTime?: number | null\n /** Poll interval override, for tests. */\n intervalMs?: number\n}\n\n/**\n * Watch for a sign-out that happened in ANY other tab or window, on this or any\n * sibling Politogy subdomain, and invoke `onLogout` once.\n *\n * Returns an unsubscribe function.\n *\n * Three signals, cheapest first:\n * - BroadcastChannel — instant, same-origin only.\n * - visibility/focus/pageshow — the moment a backgrounded tab is looked at.\n * - a ~1s cookie poll — the cross-subdomain path, and the backstop for a\n * visible tab the user is staring at but not interacting with.\n */\nexport function watchLogout(\n onLogout: () => void,\n options: WatchLogoutOptions = {},\n): () => void {\n if (typeof document === 'undefined' || typeof window === 'undefined') {\n return () => {}\n }\n\n const { authTime = null, intervalMs = POLL_MS } = options\n // Anything already on record when this tab started is not news: the server\n // layer decides whether THIS session is revoked, and it has already let the\n // page render. Only a signal newer than our baseline means \"someone just\n // signed out\".\n const baseline = readLogoutCookie() ?? 0\n let done = false\n\n const fire = (at: number) => {\n if (done) return\n if (at <= baseline) return\n if (authTime != null && !isSessionRevoked(String(at), authTime)) return\n done = true\n cleanup()\n onLogout()\n }\n\n const check = () => {\n const at = readLogoutCookie()\n if (at !== null) fire(at)\n }\n\n let channel: BroadcastChannel | null = null\n try {\n channel = new BroadcastChannel(LOGOUT_CHANNEL)\n channel.onmessage = (event) => {\n const at = typeof event.data === 'number' ? event.data : readLogoutCookie()\n if (at !== null) fire(at)\n }\n } catch {\n channel = null\n }\n\n const timer = window.setInterval(check, intervalMs)\n window.addEventListener('visibilitychange', check)\n window.addEventListener('focus', check)\n window.addEventListener('pageshow', check)\n\n function cleanup() {\n window.clearInterval(timer)\n window.removeEventListener('visibilitychange', check)\n window.removeEventListener('focus', check)\n window.removeEventListener('pageshow', check)\n try {\n channel?.close()\n } catch {\n /* already closed */\n }\n }\n\n return cleanup\n}\n","// Active-mode continuity — the cross-app \"which mode am I in\" contract.\n//\n// A DUAL-MODE app (today: a2p, Specs/A2P — \"the SMS/MMS delivery engine for\n// Relationship Mode and Campaign Mode\") has no single registry `mode`: its\n// nav tree and Mode pill must follow the user's LAST-SELECTED mode instead of\n// a fixed value. The resolution order, cheapest/most-explicit first:\n// 1. `?mode=` query param on the current URL (an explicit cross-app link,\n// e.g. the Relationship tree's SMS/MMS Blast row linking into a2p).\n// 2. `politogy_active_mode` cookie — the same cross-subdomain pattern as\n// `politogy_theme` / `politogy_active_org` (see theme-preference.ts):\n// `.politogyvrm.com` on a *.politogyvrm.com host, host-only elsewhere.\n// 3. The dual app's own configured default mode.\n//\n// Every PINNED app (one with a fixed `meta.mode`, e.g. petitions/email) and\n// core (`vrm`, whose mode switches client-side) write this cookie whenever\n// their resolved mode is known/changes, so arriving at a dual app later\n// resolves to whatever mode the user was last actually in.\n\nimport type { StandardNavMode } from './native/standardNav'\n\nexport const ACTIVE_MODE_COOKIE = 'politogy_active_mode'\n\nconst VALID_MODES: readonly StandardNavMode[] = ['relationship', 'campaign', 'petition']\n\nexport function isStandardNavMode(v: unknown): v is StandardNavMode {\n return typeof v === 'string' && (VALID_MODES as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readActiveModeCookie(): StandardNavMode | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${ACTIVE_MODE_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isStandardNavMode(v) ? v : null\n } catch {\n return null\n }\n}\n\n/**\n * Write the cross-subdomain cookie with the same scoping rules as the theme\n * cookie (parent domain on *.politogyvrm.com, host-only elsewhere). 1-year,\n * SameSite=Lax, Secure on https. No-op on the server.\n */\nexport function writeActiveModeCookie(mode: StandardNavMode): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${ACTIVE_MODE_COOKIE}=${encodeURIComponent(\n mode,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/** Read `?mode=` from a query string (`search`, with or without a leading `?`). */\nfunction modeFromSearch(search: string | undefined): string | null {\n if (!search) return null\n try {\n const params = new URLSearchParams(search.startsWith('?') ? search.slice(1) : search)\n return params.get('mode')\n } catch {\n return null\n }\n}\n\n/**\n * Resolve a dual-mode app's effective mode: `?mode=` query param (must be one\n * of `modes`) → `politogy_active_mode` cookie (must be one of `modes`) →\n * `defaultMode`. Client-side only; on the server (or when nothing resolves)\n * this simply falls through to `defaultMode`.\n */\nexport function resolveActiveMode({\n search,\n modes,\n defaultMode,\n}: {\n search?: string\n modes: readonly StandardNavMode[]\n defaultMode: StandardNavMode\n}): StandardNavMode {\n const fromQuery = modeFromSearch(search)\n if (fromQuery && isStandardNavMode(fromQuery) && modes.includes(fromQuery)) {\n return fromQuery\n }\n const fromCookie = readActiveModeCookie()\n if (fromCookie && modes.includes(fromCookie)) {\n return fromCookie\n }\n return defaultMode\n}\n","// ---------------------------------------------------------------------------\n// LoadingScreen — the platform's boot handshake (Specs/Loading-Screen).\n//\n// Mounted once by PolitogyAppFrame (see frame.tsx), never hand-rolled per app\n// (Global-Rules \"Boot Screen Exception\": one screen, one owner). It renders on\n// the four triggers that replace the account context wholesale — cold start,\n// hard reload, organization switch, mode switch — and never for an in-page\n// fetch or plain navigation, which stay on scoped skeletons.\n//\n// Progress is a REPORT, not an animation (spec §4): determinate, monotonic,\n// weighted across boot stages. An app that has real pipeline signals passes\n// `bootProgress`; an app that does not (V1: every consumer but core's own\n// pipeline work is still to come) gets a synthetic two-stage report driven by\n// the same chrome-state signal FrameBody already computes (org list resolved),\n// so the screen still tells the truth — it just has fewer stages to report —\n// and no consumer app can regress to a spinner or a hand-rolled splash.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\n\n/** One stage in the boot pipeline (spec §7). */\nexport type BootStageId =\n | 's0_session'\n | 's1_org'\n | 's2_uvp_connect'\n | 's3_district'\n | 's4_universe'\n | 's5_layers'\n | 's6_verified'\n | 's7_tribes'\n | 's8_intelligence'\n | 's9_shell'\n\nexport type BootPhase = 'booting' | 'slow' | 'error' | 'done'\n\n/**\n * The boot pipeline weight table (spec §7). Stages run in catalog order;\n * weights sum to 100 for a full cold boot. \"Waits on\" documents the real\n * signal a caller must have before it may claim the stage is progressing or\n * complete — the status line may not claim a stage the client isn't actually\n * waiting on.\n */\nexport const BOOT_STAGE_TABLE: readonly {\n id: BootStageId\n weight: number\n critical: boolean\n waitsOn: string\n}[] = [\n { id: 's0_session', weight: 5, critical: true, waitsOn: 'Politogy ID session resolution' },\n { id: 's1_org', weight: 10, critical: true, waitsOn: 'Chrome API /api/chrome/me + orgs' },\n { id: 's2_uvp_connect', weight: 10, critical: true, waitsOn: 'UVP data layer connection' },\n { id: 's3_district', weight: 5, critical: true, waitsOn: 'uvp_geo_entitlements / uvp_boundaries scope' },\n { id: 's4_universe', weight: 25, critical: true, waitsOn: 'UVP universe load + total count' },\n { id: 's5_layers', weight: 15, critical: false, waitsOn: 'UVP enrichment layer joins' },\n { id: 's6_verified', weight: 10, critical: false, waitsOn: 'VRM Verified tier computation' },\n { id: 's7_tribes', weight: 10, critical: false, waitsOn: 'Tribes member_count + Hot Tribes warm-up' },\n { id: 's8_intelligence', weight: 5, critical: false, waitsOn: 'Mode intelligence signals (Polling/Relationship/Petition)' },\n { id: 's9_shell', weight: 5, critical: true, waitsOn: 'Shell paint-ready handoff' },\n]\n\nconst BOOT_STAGE_ORDER: readonly BootStageId[] = BOOT_STAGE_TABLE.map((s) => s.id)\nconst BOOT_STAGE_WEIGHTS: Record<BootStageId, number> = Object.fromEntries(\n BOOT_STAGE_TABLE.map((s) => [s.id, s.weight]),\n) as Record<BootStageId, number>\n\n/**\n * Weighted, monotonic, redistributing progress (spec §4.1 principles 3 & 5).\n * `completedStageIds` are fully done (their full weight counts); `skippedStageIds`\n * don't apply to this account/mode and have their weight redistributed\n * proportionally across the stages that DO apply; `currentStageId` is in\n * flight and contributes `currentStageProgress` (0–1) of its own weight.\n * Pure function — no fake motion, no timers.\n */\nexport function computeWeightedPct(args: {\n completedStageIds: readonly BootStageId[]\n skippedStageIds?: readonly BootStageId[]\n currentStageId?: BootStageId\n currentStageProgress?: number\n}): number {\n const skipped = new Set(args.skippedStageIds ?? [])\n const applicable = BOOT_STAGE_ORDER.filter((id) => !skipped.has(id))\n const applicableWeightTotal = applicable.reduce((sum, id) => sum + BOOT_STAGE_WEIGHTS[id], 0)\n if (applicableWeightTotal <= 0) return 100\n // Redistribute each skipped stage's weight proportionally across the\n // remaining applicable stages so the bar still ends at 100.\n const redistributionFactor = 100 / applicableWeightTotal\n\n const completed = new Set(args.completedStageIds)\n let pct = 0\n for (const id of applicable) {\n const effectiveWeight = BOOT_STAGE_WEIGHTS[id] * redistributionFactor\n if (completed.has(id)) {\n pct += effectiveWeight\n } else if (id === args.currentStageId) {\n const progress = Math.min(1, Math.max(0, args.currentStageProgress ?? 0))\n pct += effectiveWeight * progress\n }\n }\n return Math.min(100, pct)\n}\n\n/**\n * The progress-reporting contract (spec §14, Shell package integration\n * point). An app with a real pipeline drives this; the shape is intentionally\n * small so a future per-app pipeline can report into it without a shell\n * release.\n */\nexport type BootProgress = {\n stageId: BootStageId\n /**\n * 0–100, real, monotonic. Callers that already know the weighted value\n * (e.g. by calling `computeWeightedPct` themselves) pass it directly here;\n * callers that only know stage completion/skip state may omit `pct` and\n * pass `completedStageIds`/`skippedStageIds`/`currentStageProgress`\n * instead, and the screen computes the weighted value itself.\n */\n pct?: number\n /** Stages fully completed so far this boot (spec §7 weight table). */\n completedStageIds?: readonly BootStageId[]\n /** Stages that don't apply to this account/mode; their weight redistributes\n * proportionally across the remaining stages (spec §4.1 principle 5). */\n skippedStageIds?: readonly BootStageId[]\n /** 0–1 sub-stage progress within `stageId`, for stages that stream a real\n * counter (S4 universe records, S7 Tribes warmed) (spec §4.1 principle 4). */\n currentStageProgress?: number\n /** The account's own status line for this stage (spec §8; tokens already\n * filled, fallback already applied by the caller). */\n label: string\n phase: BootPhase\n /** Critical-stage failure: Retry / Sign out (spec §9.1). */\n onRetry?: () => void\n onSignOut?: () => void\n /** Footer (spec §6, §14 `version.ts` + deploy environment). */\n version?: string\n region?: string\n}\n\n/** Default synthetic pipeline used when no app supplies `bootProgress` yet.\n * UNCHANGED from the shipped V1 behavior — do not alter without a spec\n * amendment; consumers that haven't wired the real pipeline must keep seeing\n * exactly this. */\nconst SYNTHETIC_STAGES: readonly { pct: number; label: string }[] = [\n { pct: 20, label: 'Connecting to your organization…' },\n { pct: 100, label: 'Ready.' },\n]\n\n/** Spec §11: announcements throttled to one per 1.5s so a fast boot doesn't\n * read five lines at once; \"Ready.\" is always announced regardless. */\nconst ANNOUNCE_THROTTLE_MS = 1500\n/** Spec §4.1 principle 7: minimum dwell time per status line. */\nconst MIN_DWELL_MS = 450\n/** Spec §10: exit transition timings. */\nconst FILL_EASE_MS = 380\nconst HOLD_MS = 240\nconst FADE_MS = 300\n\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false)\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)')\n setReduced(mq.matches)\n const onChange = () => setReduced(mq.matches)\n mq.addEventListener('change', onChange)\n return () => mq.removeEventListener('change', onChange)\n }, [])\n return reduced\n}\n\n/**\n * Announces `label` on an `aria-live=\"polite\"` cadence: never more than once\n * per ANNOUNCE_THROTTLE_MS, except the terminal \"Ready.\" line, which always\n * gets announced (spec §11).\n */\nfunction useThrottledAnnouncement(label: string, isFinal: boolean): string {\n const [announced, setAnnounced] = useState(label)\n const lastAtRef = useRef(0)\n useEffect(() => {\n const now = Date.now()\n if (isFinal || now - lastAtRef.current >= ANNOUNCE_THROTTLE_MS) {\n lastAtRef.current = now\n setAnnounced(label)\n return\n }\n const wait = ANNOUNCE_THROTTLE_MS - (now - lastAtRef.current)\n const t = setTimeout(() => {\n lastAtRef.current = Date.now()\n setAnnounced(label)\n }, wait)\n return () => clearTimeout(t)\n }, [label, isFinal])\n return announced\n}\n\n/**\n * Enforces the minimum-dwell floor on the DISPLAYED label only — the bar\n * itself is never delayed (spec §4.1 \"the copy is throttled; the bar is not\").\n */\nfunction useDwelledLabel(label: string): string {\n const [displayed, setDisplayed] = useState(label)\n const shownAtRef = useRef(0)\n const pendingRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n useEffect(() => {\n if (label === displayed) return\n const elapsed = Date.now() - shownAtRef.current\n if (pendingRef.current) clearTimeout(pendingRef.current)\n if (elapsed >= MIN_DWELL_MS) {\n shownAtRef.current = Date.now()\n setDisplayed(label)\n } else {\n pendingRef.current = setTimeout(() => {\n shownAtRef.current = Date.now()\n setDisplayed(label)\n }, MIN_DWELL_MS - elapsed)\n }\n return () => {\n if (pendingRef.current) clearTimeout(pendingRef.current)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [label])\n return displayed\n}\n\nexport type LoadingScreenProps = {\n /** Real pipeline progress, when the host app has one wired. */\n bootProgress?: BootProgress\n /**\n * Fallback completion signal used when `bootProgress` is absent: the\n * screen dismisses once this flips true. Callers pass the same \"org list\n * resolved\" signal FrameBody already computes, so a consumer that never\n * wires the full contract still gets a truthful (if coarse) boot report\n * instead of a spinner.\n */\n syntheticReady?: boolean\n /** True while the screen should be mounted at all (trigger gate lives in\n * frame.tsx; this component only renders its own exit transition). */\n visible: boolean\n /** Called after the fade-out completes and the DOM node should unmount. */\n onExitComplete: () => void\n}\n\nexport function LoadingScreen({\n bootProgress,\n syntheticReady,\n visible,\n onExitComplete,\n}: LoadingScreenProps) {\n const reducedMotion = usePrefersReducedMotion()\n\n const synthetic = useMemo(() => {\n const stage = syntheticReady ? SYNTHETIC_STAGES[1] : SYNTHETIC_STAGES[0]\n return {\n pct: stage.pct,\n label: stage.label,\n phase: (syntheticReady ? 'done' : 'booting') as BootPhase,\n }\n }, [syntheticReady])\n\n const weightedPct = useMemo(() => {\n if (!bootProgress) return undefined\n if (typeof bootProgress.pct === 'number') return bootProgress.pct\n if (!bootProgress.completedStageIds && !bootProgress.skippedStageIds) return undefined\n return computeWeightedPct({\n completedStageIds: bootProgress.completedStageIds ?? [],\n skippedStageIds: bootProgress.skippedStageIds,\n currentStageId: bootProgress.stageId,\n currentStageProgress: bootProgress.currentStageProgress,\n })\n }, [\n bootProgress,\n bootProgress?.pct,\n bootProgress?.completedStageIds,\n bootProgress?.skippedStageIds,\n bootProgress?.stageId,\n bootProgress?.currentStageProgress,\n ])\n\n const pct = weightedPct ?? synthetic.pct\n const rawLabel = bootProgress?.label ?? synthetic.label\n const phase = bootProgress?.phase ?? synthetic.phase\n const isFinal = phase === 'done' && pct >= 100\n\n // Monotonic clamp: a re-render can never show a lower value than the last\n // one painted, even if a caller's own state briefly regresses.\n const highWaterRef = useRef(0)\n const clampedPct = Math.max(pct, highWaterRef.current)\n useEffect(() => {\n highWaterRef.current = clampedPct\n }, [clampedPct])\n\n const displayedLabel = useDwelledLabel(rawLabel)\n const announced = useThrottledAnnouncement(displayedLabel, isFinal)\n\n // Exit transition: hold at 100 for HOLD_MS, then fade, then unmount.\n const [fading, setFading] = useState(false)\n useEffect(() => {\n if (!isFinal) return\n const holdMs = reducedMotion ? 0 : HOLD_MS\n const fadeMs = reducedMotion ? 0 : FADE_MS\n const holdTimer = setTimeout(() => {\n setFading(true)\n const fadeTimer = setTimeout(onExitComplete, fadeMs)\n return () => clearTimeout(fadeTimer)\n }, holdMs)\n return () => clearTimeout(holdTimer)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isFinal, reducedMotion])\n\n if (!visible) return null\n\n const isError = phase === 'error'\n\n return (\n <div\n data-testid=\"politogy-loading-screen\"\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 2147483000,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '2rem',\n background: 'var(--color-ink-900, #0a0a0c)',\n color: '#fff',\n opacity: fading ? 0 : 1,\n transition: reducedMotion ? undefined : `opacity ${FADE_MS}ms ease-out`,\n }}\n >\n {/*\n Inline lockup, not an <img>: the screen mounts in every consumer app and\n none of them serves a shared asset at a fixed path, so an asset URL\n rendered as a broken image (the alt text) on every boot. Inline markup\n needs no network and cannot 404.\n */}\n <div\n aria-label=\"Politogy\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.6rem',\n fontFamily: \"var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 34,\n height: 26,\n borderRadius: 6,\n background: '#fff',\n color: 'var(--color-ink-900, #0a0a0c)',\n fontSize: '0.8125rem',\n fontWeight: 800,\n letterSpacing: '-0.02em',\n }}\n >\n vrm\n </span>\n <span style={{ fontSize: '1.375rem', fontWeight: 700, letterSpacing: '-0.02em' }}>Politogy</span>\n </div>\n <div style={{ width: 320, maxWidth: '80vw' }}>\n <div\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={Math.round(clampedPct)}\n aria-label=\"Loading your workspace\"\n style={{\n height: 3,\n width: '100%',\n borderRadius: 2,\n background: 'rgba(255,255,255,0.12)',\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n height: '100%',\n width: `${clampedPct}%`,\n background:\n 'linear-gradient(90deg, var(--color-race-blue, #1d4ed8), var(--color-race-red, #dc2626))',\n transition: reducedMotion ? undefined : `width ${FILL_EASE_MS}ms ease-out`,\n }}\n />\n </div>\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={{\n marginTop: '0.75rem',\n fontFamily: 'var(--font-mono, ui-monospace, monospace)',\n fontSize: '0.8125rem',\n color: isError ? 'var(--color-race-red, #dc2626)' : 'rgba(255,255,255,0.72)',\n textAlign: 'center',\n }}\n >\n {announced}\n </div>\n {isError && (bootProgress?.onRetry || bootProgress?.onSignOut) && (\n <div\n style={{\n marginTop: '1.25rem',\n display: 'flex',\n flexDirection: 'column',\n gap: '0.75rem',\n alignItems: 'center',\n }}\n >\n {bootProgress?.onRetry && (\n <button\n type=\"button\"\n onClick={bootProgress.onRetry}\n style={{\n height: 40,\n padding: '0 1.25rem',\n borderRadius: 'var(--radius-md, 8px)',\n border: 'none',\n background: 'var(--color-race-red, #dc2626)',\n color: '#fff',\n fontFamily: \"var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)\",\n fontSize: '0.875rem',\n fontWeight: 600,\n cursor: 'pointer',\n }}\n >\n Retry\n </button>\n )}\n {bootProgress?.onSignOut && (\n <button\n type=\"button\"\n onClick={bootProgress.onSignOut}\n style={{\n height: 'auto',\n padding: 0,\n border: 'none',\n background: 'transparent',\n // 0.38 alpha was 3.51:1 on the ink-900 loading background —\n // below WCAG 2.2 AA 4.5:1. 0.72 clears it.\n color: 'rgba(255,255,255,0.72)',\n fontFamily: \"var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)\",\n fontSize: '12.5px',\n textDecoration: 'underline',\n cursor: 'pointer',\n }}\n >\n Sign out\n </button>\n )}\n </div>\n )}\n </div>\n <div\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '0 32px 30px',\n fontFamily: \"var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)\",\n fontSize: '12.5px',\n // 0.38 alpha was 3.51:1 on the ink-900 loading background — below\n // WCAG 2.2 AA 4.5:1. 0.72 clears it.\n color: 'rgba(255,255,255,0.72)',\n }}\n >\n <span>Politogy VRM. Built for the long game.</span>\n <span style={{ fontFamily: 'var(--font-mono, ui-monospace, monospace)', letterSpacing: '0.04em' }}>\n {(bootProgress?.version ?? 'v—') + ' · ' + (bootProgress?.region ?? '—')}\n </span>\n </div>\n </div>\n )\n}\n","// Brand assets — logo URLs read at RUNTIME from the Brand token sheet.\n//\n// Brand guideline \"Logo standard: use the uploaded Brand assets as-is\": apps\n// (and the shell) never bundle their own copy of a logo; they read the URLs\n// from the Brand `assets` group. `/api/tokens?format=css` emits each set asset\n// as `--asset-<kebab>: url(\"…\")` on `:root`, and every app already loads that\n// sheet at runtime (see ../runtime-tokens.ts), so the rail logo is resolved\n// from the same live sheet as every other chrome value — a Brand upload swaps\n// the logo in every app without a deploy, and there is nothing to fall back to\n// that could drift.\n\n'use client'\n\nimport { useEffect, useState } from 'react'\n\n/** Brand `assets` keys the chrome renders, by their `--asset-<kebab>` name. */\nexport type BrandAssetKind = 'logo-horizontal' | 'logo-square'\n\n/** `url(\"https://…\")` / `url(https://…)` → the bare https URL, else null. */\nexport function parseCssUrl(value: string | null | undefined): string | null {\n if (!value) return null\n const m = /^url\\(\\s*(['\"]?)(.*?)\\1\\s*\\)$/i.exec(value.trim())\n const url = m?.[2]?.trim()\n return url && /^https:\\/\\//i.test(url) ? url : null\n}\n\n/** One Brand asset URL from the live token sheet, or null while it is unset. */\nexport function readBrandAsset(kind: BrandAssetKind): string | null {\n if (typeof document === 'undefined') return null\n try {\n return parseCssUrl(\n window.getComputedStyle(document.documentElement).getPropertyValue(`--asset-${kind}`),\n )\n } catch {\n return null\n }\n}\n\nexport type BrandAssets = {\n /** `assets.logoHorizontal` — the all-white lockup at the top of the rail. */\n logoHorizontal: string | null\n /** `assets.logoSquare` — the all-white vrm tile on the collapsed rail. */\n logoSquare: string | null\n}\n\nconst EMPTY: BrandAssets = { logoHorizontal: null, logoSquare: null }\n\n// The token sheet is a <link> the app appends at startup, so it may still be\n// in flight on first paint. Re-read when it loads, and a few times after, to\n// cover a link that is inserted after this effect ran.\nconst RETRY_MS = [0, 250, 1000, 3000]\n\n/**\n * The Brand logo URLs, resolved after mount (null on the server and until the\n * runtime token sheet has loaded). Callers reserve the logo's box and draw\n * nothing while a value is null — never a stand-in image.\n */\nexport function useBrandAssets(): BrandAssets {\n const [assets, setAssets] = useState<BrandAssets>(EMPTY)\n useEffect(() => {\n let done = false\n const read = () => {\n if (done) return\n const next = {\n logoHorizontal: readBrandAsset('logo-horizontal'),\n logoSquare: readBrandAsset('logo-square'),\n }\n setAssets((prev) =>\n prev.logoHorizontal === next.logoHorizontal && prev.logoSquare === next.logoSquare\n ? prev\n : next,\n )\n }\n const links = Array.from(\n document.querySelectorAll<HTMLLinkElement>('link[rel=\"stylesheet\"][href*=\"api/tokens\"]'),\n )\n links.forEach((l) => l.addEventListener('load', read))\n const timers = RETRY_MS.map((ms) => window.setTimeout(read, ms))\n read()\n return () => {\n done = true\n links.forEach((l) => l.removeEventListener('load', read))\n timers.forEach((t) => window.clearTimeout(t))\n }\n }, [])\n return assets\n}\n","// ---------------------------------------------------------------------------\n// PolitogyAppFrame — ONE component that renders the entire app frame.\n//\n// Why this exists (HITL directive 2026-07-23): shipping the same npm package at\n// the same version is necessary but NOT sufficient. The package exposed\n// PRIMITIVES (NavAppShell + a dozen hooks) and every app hand-assembled them in\n// its own ~150-line Shell.tsx. Identical inputs were never guaranteed, so the\n// outputs diverged — measured on production: forms rendered its user's EMAIL as\n// their name, polls' breadcrumb read \"Polls / Polls\", forms and surveys pinned\n// the mode pill to a hardcoded \"relationship\", and each app declared its own\n// chrome CSS variables (surveys' accent was #C8102E where everyone else was\n// #E63946).\n//\n// The fix is to stop exporting assembly as an app responsibility. An app now\n// renders:\n//\n// <PolitogyAppFrame app=\"forms\" pathname={pathname} linkComponent={Link}\n// session={{ userId, email, role, accountName, accountId }}\n// onSignOut={signOut}>\n// {children}\n// </PolitogyAppFrame>\n//\n// and passes NOTHING about the chrome: no nav, no breadcrumbs, no title, no\n// mode, no user menu, no footer, no theme. Those are derived here, identically,\n// for every app. Anything an app cannot pass is something it cannot drift on.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\n\nimport { broadcastLogout, watchLogout } from '../logout-signal'\nimport { resolveActiveMode, writeActiveModeCookie } from '../mode-preference'\nimport { clearBetaBannerDismissal, isNavItemActive } from '../native/index'\nimport { LoadingScreen, type BootProgress } from './loading-screen'\nimport {\n NavAppShell,\n standardPolitogyNav,\n type NavLinkComponent,\n} from '../native/index'\nimport {\n ChromeTopBarActions,\n PolitogyAppChrome,\n standardNavIcons,\n useChromeFooter,\n useChromeIdentity,\n useChromeMode,\n useChromeState,\n useChromeUserMenu,\n type ChromeDevNotesConfig,\n type ControlledOrgState,\n type TokenOrgState,\n} from './index'\nimport type {\n NavBreadcrumb,\n NavChromeFetcher,\n NavItem,\n NavMode,\n NavUserMenu,\n} from '../native/index'\nimport type { StandardNavMode } from '../native/standardNav'\nimport { deriveBreadcrumbs } from '../lib/breadcrumbs'\nimport { useBrandAssets } from '../lib/brandAssets'\nimport { warnDeprecated } from '../lib/deprecation'\n\n/**\n * The core app — the one that OWNS the canonical nav tree and routes in-app.\n * `PolitogyFrameData.core` is honored for this key and no other.\n */\nconst CORE_APP: PolitogyAppKey = 'vrm'\n\n/**\n * Template A convention: every feature app exposes GET /auth/signout, which\n * clears its session cookie and 302s to the IdP's end_session endpoint. Apps\n * that route sign-out elsewhere (core: /api/auth/logout) pass `signOutUrl`.\n */\nconst DEFAULT_SIGN_OUT_URL = '/auth/signout'\n\n/** Every app that renders the shared chrome. Keyed by its subdomain. */\nexport type PolitogyAppKey =\n | 'vrm'\n | 'contacts'\n | 'forms'\n | 'surveys'\n | 'polls'\n | 'petitions'\n // V2 apps that replace retired app.politogyvrm.com pages (Reference/\n // UI-Platform v42 \"Retirement of app.politogyvrm.com\").\n | 'dashboard'\n | 'settings'\n // Relationship Mode standalone apps.\n | 'email'\n // Campaign Mode standalone apps.\n | 'a2p'\n | 'phonebank'\n | 'canvass'\n | 'signs'\n // Relationship Mode CTAs (Specs/CTAs) — the new standalone acquisition app,\n // same \"forms./surveys./polls.\" pattern (unscoped, own subdomain).\n | 'ctas'\n\n/**\n * The operating Mode an app is scoped to, if any. It drives two things,\n * BOTH derived here from app identity so no app passes chrome config:\n * 1. the standardPolitogyNav tree the sidebar renders, and\n * 2. the static Mode pill the app shows (a campaign app shows a Campaign\n * pill, never Relationship).\n * An UNSCOPED app (no `mode`) keeps its prior behavior exactly: the\n * Relationship tree + an entitlement-driven Mode pill.\n */\nexport type PolitogyAppMode = StandardNavMode\n\n/**\n * A frame input a feature app is allowed to supply, because the answer is a\n * fact only the app has — not a styling choice.\n *\n * The grant list is the COMPLETE set of exceptions to \"an app never passes\n * chrome configuration\", and it lives here, in the shell, in one greppable\n * table. That is what keeps the no-drift guarantee: an app cannot grant itself,\n * so widening the surface takes a shell release and a review by whoever owns\n * the shell.\n *\n * Never add a grant for a visual input. `breadcrumbs` qualifies because only\n * the app knows which record a deep link points at. \"Petitions wants a wider\n * box\" would not qualify — that is a look, and looks come from tokens.\n *\n * RETIRED (0.69.0): the `contentWrapper` grant. The frame's `<main>` is fluid\n * and apps never emit their own page container (Brand guideline \"Content\n * width is fluid\"; Reference/UI-Platform → PolitogyAppFrame), so no app may be\n * granted one. Do not re-add it.\n */\nexport type PolitogyFrameGrant = 'breadcrumbs' | 'title'\n\n/**\n * The per-app registry — the ONLY place app identity lives. A new app adds a\n * row here and inherits every chrome behavior; it never re-derives one.\n */\nexport const POLITOGY_APPS: Record<\n PolitogyAppKey,\n {\n title: string\n origin: string\n storagePrefix: string\n mode?: PolitogyAppMode\n /**\n * DUAL-MODE apps (today: a2p — Specs/A2P: \"the SMS/MMS delivery engine\n * for Relationship Mode and Campaign Mode\") have no single fixed mode.\n * `mode` above stays the fallback/default identity for any code that\n * still reads `meta.mode` directly; FrameBody instead resolves the\n * EFFECTIVE mode via `resolveActiveMode` (?mode= query → the\n * `politogy_active_mode` cookie → `defaultMode`) and uses that for the\n * nav tree, the Mode pill, and the brand lockup.\n */\n dual?: { modes: readonly StandardNavMode[]; defaultMode: StandardNavMode }\n /** See PolitogyFrameGrant. Omitted => the app may pass no frame input. */\n grants?: readonly PolitogyFrameGrant[]\n /**\n * 'flat': the app's whole tree nests under one standard entry, and the rail\n * renders that entry's CHILDREN at the root — no parent header row, no\n * accordion (see NavSidebar nav.flatten). V1's petition rail was flat;\n * the parent row duplicated its first child's route.\n */\n navShape?: 'flat'\n /**\n * false: this app does not render the Beta banner strip. A registry\n * declaration, not an app prop, for the same reason as grants — whether a\n * product shows the platform's Beta notice is a platform decision.\n */\n beta?: boolean\n /**\n * false: the chrome does NOT draw its own page-title line (the 56px\n * `<h1>` above `main`); the app's page body owns its title. Specs/Contacts\n * design: the page opens on its own \"RELATIONSHIP MODE\" eyebrow + H1, so\n * a chrome-owned \"Contacts\" line above it was a second heading not in the\n * design. Registry-level (platform decision), like `beta`.\n */\n pageTitle?: false\n }\n> = {\n vrm: { title: 'Politogy VRM', origin: 'https://app.politogyvrm.com', storagePrefix: 'vrm' },\n contacts: {\n title: 'Contacts',\n origin: 'https://contacts.politogyvrm.com',\n storagePrefix: 'contacts',\n pageTitle: false,\n },\n // 'title' for forms/surveys/polls/ctas for the same reason as petitions\n // below: their pages have real names (\"Volunteer Signup\", \"Q3 Satisfaction\"),\n // where the registry can only say the app's own name. Without the grant the\n // page header falls back to the static registry title forever, so the\n // designed \"<mode> mode\" eyebrow + H2 + subtitle block never gets the real\n // per-page title an app passes it (UI-Platform → Page header).\n forms: { title: 'Forms', origin: 'https://forms.politogyvrm.com', storagePrefix: 'forms', grants: ['title'] },\n surveys: { title: 'Surveys', origin: 'https://surveys.politogyvrm.com', storagePrefix: 'surveys', grants: ['title'] },\n // Specs/Left-Navigation §9.2: Polling is a Campaign row (Research).\n polls: { title: 'Polls', origin: 'https://polls.politogyvrm.com', storagePrefix: 'polls', mode: 'campaign', grants: ['title'] },\n ctas: { title: 'CTAs', origin: 'https://ctas.politogyvrm.com', storagePrefix: 'ctas', grants: ['title'] },\n // V2 apps that replace retired app.politogyvrm.com pages (Reference/\n // UI-Platform v42 \"Retirement of app.politogyvrm.com\"). Dashboard hosts the\n // Relationship Dashboard + Campaign Battleground/District data/Campaigns\n // (Specs/Relationship-Dashboard); Settings hosts org settings & billing\n // (Specs/Organization-Settings).\n dashboard: { title: 'Dashboard', origin: 'https://dashboard.politogyvrm.com', storagePrefix: 'dashboard' },\n settings: { title: 'Settings', origin: 'https://settings.politogyvrm.com', storagePrefix: 'settings' },\n petitions: {\n title: 'Petitions',\n origin: 'https://petition-mode.politogyvrm.com',\n storagePrefix: 'petitions',\n mode: 'petition',\n // Its adjudication case is addressed per sheet and per line — a trail\n // derived from the nav tree reads \"Dashboard › Adjudication\" on every one\n // of those URLs and cannot name the record you are actually on. 'title'\n // for the same reason: its pages have real names (\"Batches\"), where the\n // registry can only say \"Petitions\".\n grants: ['breadcrumbs', 'title'],\n navShape: 'flat',\n beta: false,\n },\n // Relationship Mode Email Engine (Specs/Email-Engine) — the V2 standalone\n // app, running in parallel to VRM core's V1 Email Broadcast.\n email: { title: 'Email', origin: 'https://email.politogyvrm.com', storagePrefix: 'email', mode: 'relationship', grants: ['title'] },\n // Campaign Mode apps — each scoped to Campaign, so they render the Campaign\n // tree and a static Campaign pill. Not yet deployed; hidden from the Campaign\n // nav by CAMPAIGN_FEATURE_AVAILABILITY until their launch flips the flag.\n // Dual-mode: a2p is the SMS/MMS delivery engine for BOTH Relationship Mode\n // and Campaign Mode (Specs/A2P). `mode: 'campaign'` stays the fallback for\n // anything reading `meta.mode` directly; the effective mode a user sees is\n // resolved per-visit (see `dual`, resolveActiveMode).\n a2p: {\n title: 'A2P Messaging',\n origin: 'https://a2p.politogyvrm.com',\n storagePrefix: 'a2p',\n mode: 'campaign',\n dual: { modes: ['relationship', 'campaign'], defaultMode: 'campaign' },\n grants: ['title'],\n },\n phonebank: { title: 'Phone Banking', origin: 'https://phonebank.politogyvrm.com', storagePrefix: 'phonebank', mode: 'campaign', grants: ['title'] },\n canvass: { title: 'Field Canvassing', origin: 'https://canvass.politogyvrm.com', storagePrefix: 'canvass', mode: 'campaign', grants: ['title'] },\n signs: { title: 'Sign Mapping', origin: 'https://signs.politogyvrm.com', storagePrefix: 'signs', mode: 'campaign', grants: ['title'] },\n}\n\nexport type PolitogyAppSession = {\n /** Stable IdP subject (`sub`). */\n userId: string\n email: string | null\n /** The app's own role string — feeds DevNotes admin gating. */\n role: string\n /** The app's own workspace label, used only until core orgs resolve. */\n accountName: string\n accountId: string\n /**\n * Pre-hydration display name ONLY. The chrome API is the authority; an email\n * passed here is discarded rather than rendered as a name.\n */\n userName?: string | null\n}\n\n/**\n * Optional DATA plumbing for apps whose session/auth differs — never styling.\n *\n * Everything here is about WHERE data comes from (which fetcher, which org\n * state, which routes an app owns), not what the chrome looks like. Adding a\n * visual option to this type would re-open the drift this component exists to\n * close.\n */\n/** Per-app universal-search placeholder (design copy); \"Search\" elsewhere. */\nconst DEFAULT_SEARCH_PLACEHOLDER: Partial<Record<PolitogyAppKey, string>> = {\n contacts: 'Search contacts, segments, forms',\n}\n\nexport type PolitogyFrameData = {\n /** Chrome-API fetcher override for apps that authenticate client-side. */\n fetchJson?: NavChromeFetcher\n /** DevNotes wiring override for those same direct-auth apps. */\n devNotes?: ChromeDevNotesConfig\n /** Controlled org state for apps that own active-org + switching. */\n org?: ControlledOrgState\n /** Auth-owned active org from verified token claims (v2). Wins over `org`. */\n tokenOrg?: TokenOrgState\n /**\n * App-owned children for a standard nav entry this app owns (Contacts).\n * `count` is the live contact total, pre-formatted (\"31.9K\"), drawn\n * right-aligned on the Contacts row (Specs/Contacts design rail).\n */\n contactsItem?: { href?: string; children?: NavItem[]; count?: string | number | null }\n /**\n * Top-level standard-nav rows to omit, by label (e.g. `['Polls', 'CTAs']`).\n * The Specs/Contacts design rail shows exactly Dashboard · Contacts · Email\n * broadcast · SMS/MMS blast / Calls to action · Forms · Surveys / My profile\n * · Organization settings. Default: nothing hidden.\n */\n hiddenNavItems?: string[]\n /**\n * Universal-search placeholder. Defaults per app (Contacts: \"Search\n * contacts, segments, forms\"), else \"Search\".\n */\n searchPlaceholder?: string\n /**\n * true: render the rail as flat rows — every standard entry's `children`\n * are stripped before the sidebar draws, so no row carries an accordion\n * chevron (Specs/Contacts design rail: nine plain rows). Routing data is\n * untouched: active-row matching still uses the unstripped tree, exactly\n * as the 'tabs only' preference does. Default: children kept.\n */\n flatNav?: boolean\n /** Petitions app: nest its own routes under the Petition-mode entry. */\n petitionsItem?: { href?: string; children?: NavItem[] }\n /** Avatar fallback when the profile has no uploaded photo (memoji, default). */\n fallbackAvatarUrl?: string | null\n /**\n * Frame inputs this app has been GRANTED in the registry.\n *\n * Each field is honored only when the app's `POLITOGY_APPS` row lists it in\n * `grants`; an undeclared field is dropped before it reaches the chrome, so\n * passing one has no effect rather than a silent effect. Nothing here is\n * styling — see PolitogyFrameGrant for what qualifies.\n *\n * This is deliberately NOT a widening of the `app === CORE_APP` gate below.\n * That gate makes core's props inert for every other app; this makes a named\n * input live for a named app, listed in one place the shell owns.\n */\n frame?: PolitogyGrantedFrame\n /**\n * CORE-ONLY frame inputs. **Honored only when `app` is the core app (`vrm`)\n * — silently ignored for every other app**, which is what keeps the\n * no-drift guarantee intact: a feature app cannot re-specify a chrome\n * element even by passing this, so the props are inert for it.\n *\n * Core is genuinely different, and pretending otherwise would have meant\n * REMOVING shipped behavior from app.politogyvrm.com to satisfy packaging —\n * which Reference/UI-Platform forbids (\"migration may not drop a shipped\n * element … extend the shell first, then migrate\"). Specifically, core:\n * - owns the canonical nav tree AND decorates it with live entitlement\n * state a static tree cannot express (10DLC gating, contact/group\n * counts, org-lock),\n * - routes in-app (react-router), so its rows must be app-relative paths,\n * not the absolute cross-app URLs `standardPolitogyNav` emits,\n * - publishes per-page title/breadcrumbs from 66 page components,\n * - switches Mode client-side rather than by full-page navigation,\n * - owns real linked-account switching (with its own modals).\n *\n * Everything here is still DATA or app-owned STATE. There is no styling\n * input, no ordering input, and no way to change the top-bar action cluster\n * — those stay identical for every app, core included.\n */\n core?: PolitogyCoreFrame\n}\n\n/** See `PolitogyFrameData.frame` — honored per the app's registry `grants`. */\nexport type PolitogyGrantedFrame = {\n /**\n * @deprecated RETIRED in 0.69.0 and ignored: no app holds a `contentWrapper`\n * grant any more. The frame's `<main>` is fluid; remove the app's own page\n * container (`PageContainer`) and stop passing this. Still typed so an app\n * that passes it keeps compiling until it is cleaned up.\n */\n contentWrapper?: 'padded' | 'bare'\n /**\n * The trail for pages whose location is finer-grained than their nav row —\n * a specific record, not a section. For an app granted 'breadcrumbs' the\n * published trail REPLACES the derived one entirely: a page that publishes\n * none shows none, exactly as core's pages do. (Falling back to the derived\n * trail put \"Dashboard › Batches\" under the title of every list page — a\n * parent nobody chose, on apps whose pages already say where they are.)\n */\n breadcrumbs?: NavBreadcrumb[]\n /** The page's own name for the top bar (\"Batches\"), not the app's. */\n title?: string\n}\n\n/** See `PolitogyFrameData.core` — core app (`vrm`) only. */\nexport type PolitogyCoreFrame = {\n /** The canonical nav tree, decorated with core's live entitlement state. */\n nav?: NavItem[]\n /** Per-page identity published by core's own pages. */\n page?: { title?: string; breadcrumbs?: NavBreadcrumb[]; actions?: ReactNode }\n /** Client-side Mode switching (core navigates in-app, not cross-origin). */\n mode?: NavMode\n /** Real linked-account switching + core's theme persistence. */\n userMenu?: NavUserMenu\n /**\n * @deprecated Ignored since 0.69.0. The rail logo is the all-white lockup\n * from Brand `assets.logoHorizontal`, read at runtime, in every Mode —\n * never a mode-specific or bundled wordmark (Left-Navigation §5).\n */\n brandLogoSrc?: string\n /**\n * @deprecated Core still wraps its pages in `PageContainer`, which emits its\n * own `<main>`, so `'bare'` is honored for core until those pages are\n * migrated to the frame's fluid `<main>`. Not available to any other app.\n */\n contentWrapper?: 'padded' | 'bare'\n}\n\nexport type PolitogyBuildMeta = {\n envLabel?: string\n version?: string\n commit?: string\n commitDate?: string\n commitAuthor?: string\n}\n\nexport function PolitogyAppFrame({\n app,\n pathname,\n search,\n linkComponent,\n session,\n onSignOut,\n signOutUrl = DEFAULT_SIGN_OUT_URL,\n buildMeta,\n data,\n bootProgress,\n appReady,\n children,\n}: {\n app: PolitogyAppKey\n /** Current path from the app's router (Next: usePathname()). */\n pathname: string\n /** Current query string, when the app routes by query (forms' ?tab=). */\n search?: string\n /** The app's routing primitive (Next: <Link>). */\n linkComponent: NavLinkComponent\n session: PolitogyAppSession\n onSignOut: () => void\n /**\n * The app's sign-out ROUTE — a GET endpoint that clears the session cookie\n * and redirects to RP-initiated logout at the IdP. Defaults to the Template A\n * convention; core overrides it. This, not `onSignOut`, is what actually\n * signs the user out (see handleSignOut).\n */\n signOutUrl?: string\n buildMeta?: PolitogyBuildMeta\n /** Optional DATA plumbing (never styling) — see PolitogyFrameData. */\n data?: PolitogyFrameData\n /**\n * Real boot-pipeline progress (Specs/Loading-Screen §14 contract). Absent\n * for apps that have not wired their own pipeline yet — the frame then\n * reports a truthful but coarse two-stage boot instead of a spinner.\n */\n bootProgress?: BootProgress\n /**\n * Explicit \"the host app is ready to be shown\" signal. When omitted (every\n * app today), the Loading Screen dismisses itself once the chrome's own\n * org/nav state resolves, so none of the 14 consumer apps has to opt in to\n * keep working.\n */\n appReady?: boolean\n children: ReactNode\n}) {\n const meta = POLITOGY_APPS[app]\n return (\n <PolitogyAppChrome\n storagePrefix={meta.storagePrefix}\n fetchJson={data?.fetchJson}\n devNotes={data?.devNotes}\n org={data?.org}\n tokenOrg={data?.tokenOrg}\n identity={{\n userId: session.userId,\n userName: session.userName ?? null,\n email: session.email,\n role: session.role,\n }}\n >\n <FrameBody\n app={app}\n pathname={pathname}\n search={search}\n linkComponent={linkComponent}\n session={session}\n onSignOut={onSignOut}\n signOutUrl={signOutUrl}\n buildMeta={buildMeta}\n data={data}\n bootProgress={bootProgress}\n appReady={appReady}\n >\n {children}\n </FrameBody>\n </PolitogyAppChrome>\n )\n}\n\nfunction FrameBody({\n app,\n pathname,\n search,\n linkComponent,\n session,\n onSignOut,\n signOutUrl,\n buildMeta,\n data,\n bootProgress,\n appReady,\n children,\n}: {\n app: PolitogyAppKey\n pathname: string\n search?: string\n linkComponent: NavLinkComponent\n session: PolitogyAppSession\n onSignOut: () => void\n signOutUrl: string\n buildMeta?: PolitogyBuildMeta\n data?: PolitogyFrameData\n bootProgress?: BootProgress\n appReady?: boolean\n children: ReactNode\n}) {\n const meta = POLITOGY_APPS[app]\n const chrome = useChromeState()\n // Left-Navigation §5: the rail logo is Brand `assets.logoHorizontal` (and\n // `assets.logoSquare` on the collapsed rail), read at runtime from the Brand\n // token sheet — the same white lockup in every Mode and every app, never a\n // bundled or mode-specific copy.\n const brandAssets = useBrandAssets()\n if (data?.frame?.contentWrapper !== undefined) {\n warnDeprecated(\n 'frame.contentWrapper',\n \"`data.frame.contentWrapper` is retired and ignored: the frame's <main> is fluid. Remove the app's own page container and drop the prop.\",\n )\n }\n if (data?.core?.brandLogoSrc !== undefined) {\n warnDeprecated(\n 'core.brandLogoSrc',\n '`data.core.brandLogoSrc` is ignored: the rail logo is read at runtime from Brand `assets.logoHorizontal`.',\n )\n }\n\n // Loading Screen trigger gate (Specs/Loading-Screen §5, Global-Rules \"Boot\n // Screen Exception\"): shown on mount (cold start / hard reload both remount\n // this component fresh) and re-shown on organization switch or mode switch —\n // the two events that replace the account context after mount. A plain\n // route change never touches these refs, so it never re-arms the screen.\n const bootAppMode = meta.mode\n const bootOrgId = chrome?.orgId ?? null\n const [bootVisible, setBootVisible] = useState(true)\n // Remounts LoadingScreen on every new trigger so its internal monotonic\n // high-water mark and exit-transition state start clean for the new boot.\n const [bootGeneration, setBootGeneration] = useState(0)\n const seenOrgRef = useRef(bootOrgId)\n const seenModeRef = useRef(bootAppMode)\n useEffect(() => {\n if (seenOrgRef.current !== null && seenOrgRef.current !== bootOrgId) {\n setBootVisible(true)\n setBootGeneration((g) => g + 1)\n }\n seenOrgRef.current = bootOrgId\n }, [bootOrgId])\n useEffect(() => {\n if (seenModeRef.current !== undefined && seenModeRef.current !== bootAppMode) {\n setBootVisible(true)\n setBootGeneration((g) => g + 1)\n }\n seenModeRef.current = bootAppMode\n }, [bootAppMode])\n // Default dismiss signal when the app has not wired a real pipeline: the\n // chrome's own org list has resolved, i.e. the same state FrameBody already\n // needed to render the sidebar/org switcher truthfully. `chrome` is null\n // for an app rendered without a chrome/org provider at all (no org state to\n // wait on), which must count as resolved — otherwise the screen never\n // dismisses and blocks the app forever.\n const chromeResolved = chrome == null || !chrome.orgsLoading\n\n // Sign-out is a PLATFORM event, not an app event. Each app holds its own\n // host-only session cookie with a long sliding window, so without this a user\n // who signed out in one tab stayed fully signed in in every other open tab\n // and on every other subdomain. Announce the sign-out to all of them, then\n // run the app's own sign-out.\n //\n // Every app reaches sign-out through this frame, so wiring it here covers the\n // whole estate without an app having to opt in — the same guarantee the rest\n // of the chrome relies on.\n const signOutRef = useRef(onSignOut)\n signOutRef.current = onSignOut\n // This tab started the sign-out, so its own watcher must not also fire and\n // run the app's sign-out a second time concurrently.\n const signingOutRef = useRef(false)\n\n const handleSignOut = useCallback(() => {\n signingOutRef.current = true\n // Re-arm the Beta banner so it reappears at the next login rather than\n // staying hidden across an in-tab logout→login (sessionStorage survives it).\n clearBetaBannerDismissal()\n broadcastLogout()\n // Navigate to the app's sign-out ROUTE. Apps also pass an onSignOut\n // handler, but it cannot be relied on: they wire it as\n // `onSignOut={() => { void signOutAction(); }}`, and a server action\n // invoked outside a transition can never have its redirect() applied by\n // the client. Measured against production 2026-07-25: clicking Sign out\n // left the user signed in, and an app they had never opened authenticated\n // with no credentials — the IdP session was still alive because the\n // browser never reached its end-session endpoint.\n //\n // A plain navigation to a GET route cannot fail that way: the route drops\n // the session cookie and 302s to RP-initiated logout at the IdP.\n signOutRef.current()\n window.location.assign(signOutUrl)\n }, [signOutUrl])\n\n useEffect(\n () =>\n // A tab that learns of a sign-out elsewhere ends its own session for\n // real, by navigating to the same sign-out route.\n //\n // Measured against production before this landed: calling the app's\n // handler did nothing at all. Apps wire it as\n // `onSignOut={() => { void signOutAction(); }}` — a server action invoked\n // outside a transition, so the `redirect()` inside it can never be\n // applied by the client and the tab just sits there. Building cross-tab\n // logout on that path made the whole feature a no-op.\n //\n // A hard navigation cannot fail that way, and it hands the decision to\n // the authority rather than guessing: the app's middleware sees a session\n // whose auth_time predates `politogy_logout_at`, treats it as revoked,\n // and redirects to Politogy ID. Server-side truth decides; the client\n // only forces the request. No re-broadcast — the signal that woke us is\n // already on record for every tab.\n watchLogout(() => {\n if (signingOutRef.current) return\n clearBetaBannerDismissal()\n window.location.assign(signOutUrl)\n }),\n [signOutUrl],\n )\n // Core-only inputs are read through this ONE gate. For every other app it is\n // undefined no matter what the app passed, so the \"an app cannot re-specify a\n // chrome element\" guarantee holds by construction, not by convention.\n const core = app === CORE_APP ? data?.core : undefined\n\n // Registry-granted inputs run through the SAME shape of gate, one field at a\n // time: the registry decides, the app only supplies. An app that passes\n // `frame.breadcrumbs` without the grant gets `undefined` here, so the failure\n // mode is \"no effect\", never \"an app quietly re-specified the chrome\".\n const grants = meta.grants\n const granted = <K extends keyof PolitogyGrantedFrame>(\n key: K & PolitogyFrameGrant,\n ): PolitogyGrantedFrame[K] | undefined =>\n grants?.includes(key) ? data?.frame?.[key] : undefined\n\n // Identity: chrome API wins, app claims are a fallback, an email is never a\n // name (that is what forms was rendering in the top right).\n const identity = useChromeIdentity({ userName: session.userName, email: session.email })\n const derivedUserMenu = useChromeUserMenu({\n userId: session.userId,\n userName: identity.userName,\n email: identity.email,\n })\n const userMenu = core?.userMenu ?? derivedUserMenu\n const footer = useChromeFooter(buildMeta ?? {})\n // A mode-scoped app (Campaign apps, Petitions) pins its pill to its own mode;\n // an unscoped app stays entitlement + user-selection driven. Either way no\n // app passes a mode — it is read from the registry (app identity).\n //\n // A DUAL-MODE app (a2p — Specs/A2P) has no single fixed mode: its EFFECTIVE\n // mode is resolved per-visit, ?mode= query → politogy_active_mode cookie →\n // the app's own default, and that resolved value stands in for `meta.mode`\n // everywhere below (nav tree, Mode pill, brand lockup). Every other app is\n // unaffected — `appMode` is exactly `meta.mode`, as before.\n const resolvedDualMode = meta.dual\n ? resolveActiveMode({\n search: search ?? (typeof window !== 'undefined' ? window.location.search : undefined),\n modes: meta.dual.modes,\n defaultMode: meta.dual.defaultMode,\n })\n : undefined\n const appMode = resolvedDualMode ?? meta.mode\n const derivedMode = useChromeMode(appMode ? { pinnedModeId: appMode } : undefined)\n // Core switches Mode client-side; every other app jumps to the mode's home.\n const mode = core?.mode ?? derivedMode\n\n // PINNED apps (a fixed `meta.mode`, no `dual`) write their own mode to the\n // shared cookie whenever it is known, so a dual app visited next (a2p)\n // resolves to it instead of its own default — that is what makes \"SMS/MMS\n // Blast\" clicked from Relationship Mode land on the Relationship tree in\n // a2p even without a `?mode=` link.\n //\n // Core (`vrm`) has no `meta.mode` — it switches mode client-side via\n // in-app routing, not the registry — so its live mode is read from its own\n // route namespace (`/relationship/...` vs `/campaign/...`, the same split\n // `standardPolitogyNav`'s trees use) rather than `core?.mode` (a `NavMode`\n // describing the PILL's label/options, not which mode is currently active).\n // Re-runs on every pathname change, so switching mode in-app (a route\n // change, not a remount) still updates the cookie.\n const coreLiveMode: StandardNavMode | undefined =\n app === CORE_APP\n ? pathname.startsWith('/campaign')\n ? 'campaign'\n : pathname.startsWith('/relationship')\n ? 'relationship'\n : undefined\n : undefined\n const cookieMode = coreLiveMode ?? (meta.dual ? undefined : meta.mode)\n useEffect(() => {\n if (cookieMode) writeActiveModeCookie(cookieMode)\n }, [cookieMode])\n\n const coreOrgs = chrome?.orgs ?? []\n const activeCoreOrg = coreOrgs.find((o) => o.id === chrome?.orgId) ?? null\n const navDisplay = chrome?.navDisplay ?? 'both'\n\n // The nav tree follows the app's OWN mode (registry), not the live pill\n // selection — so it is deterministic from app identity. Unscoped apps render\n // Relationship exactly as before. Cross-app links in the Campaign/Petition\n // trees carry the active org the way the switcher/account menu do.\n const navMode: StandardNavMode = appMode ?? 'relationship'\n const activeOrgId = chrome?.orgId ?? null\n const derivedNavItems = useMemo(\n () =>\n standardPolitogyNav({\n coreBaseUrl: POLITOGY_APPS.vrm.origin,\n icons: standardNavIcons,\n // An app that OWNS a standard nav entry (Contacts) nests its own routes\n // under it. This is routing data, not chrome configuration.\n contactsItem: data?.contactsItem,\n petitionsItem: data?.petitionsItem,\n hiddenItems: data?.hiddenNavItems,\n mode: navMode,\n activeOrgId,\n }),\n [data?.contactsItem, data?.petitionsItem, data?.hiddenNavItems, navMode, activeOrgId],\n )\n // Core supplies the canonical tree already decorated with its live gating\n // state (and with app-relative hrefs so its router handles them in-app).\n const navItems = core?.nav ?? derivedNavItems\n\n // Left-Navigation §11.3: a row is active when the current route belongs to\n // its feature, by route prefix, never by exact URL — so a parent whose\n // OWN route is \"/\" still lights up on every child route it owns. The\n // 'tabs' display strips `children` before handing rows to the sidebar\n // (below), which would otherwise leave `isNavItemActive` with nothing to\n // prefix-match against and no row active on a child page (DevNotes\n // ebb036a1: Contacts' rail row went dark on /tribes, /import, /fields…).\n // Built from the UNSTRIPPED tree so the parent's activeness still reflects\n // routes its children (and grandchildren) own, independent of stripping.\n const navIsActive = useMemo(() => {\n const childHrefs = new Map<string, string[]>()\n for (const item of navItems) {\n if (!item.href || !item.children?.length) continue\n const hrefs: string[] = []\n for (const child of item.children) {\n if (child.href) hrefs.push(child.href)\n for (const leaf of child.children ?? []) {\n if (leaf.href) hrefs.push(leaf.href)\n }\n }\n childHrefs.set(item.href, hrefs)\n }\n return (pathname: string, href: string) =>\n isNavItemActive(pathname, href) ||\n (childHrefs.get(href) ?? []).some((h) => isNavItemActive(pathname, h))\n }, [navItems])\n\n // Dashboard › Sub › Item, derived from the same tree the sidebar renders.\n // Core publishes its trail from the page itself, because a core page's\n // location is finer-grained than its nav row (e.g. a contact detail view).\n const derivedBreadcrumbs = useMemo(\n () => deriveBreadcrumbs(navItems, pathname, { search, origin: meta.origin }),\n [navItems, pathname, search, meta.origin],\n )\n // An app granted 'breadcrumbs' behaves like core: the page's published\n // trail IS the trail, and a page that publishes nothing shows nothing.\n // (First cut fell back to the derived trail, which put \"Dashboard › Batches\"\n // under every list-page title — a parent nobody chose.) Ungranted apps keep\n // the derived trail exactly as before.\n const breadcrumbs = core\n ? core.page?.breadcrumbs\n : grants?.includes('breadcrumbs')\n ? granted('breadcrumbs')\n : derivedBreadcrumbs\n\n return (\n <>\n <LoadingScreen\n key={bootGeneration}\n visible={bootVisible}\n bootProgress={bootProgress}\n syntheticReady={appReady ?? chromeResolved}\n onExitComplete={() => setBootVisible(false)}\n />\n <NavAppShell\n sidebar={{\n pathname,\n brand: {\n logoSrc: brandAssets.logoHorizontal ?? undefined,\n logoSquareSrc: brandAssets.logoSquare ?? undefined,\n // Reserve the logo's box while the token sheet loads; never draw a\n // stand-in.\n logoPending: true,\n logoAlt: 'Politogy',\n badgeLabel: 'P',\n title: 'Politogy',\n },\n nav: {\n // A flat rail's sub-menu IS the nav, so the 'tabs only' preference\n // (which strips children) would leave one childless parent row —\n // flat apps ignore the stripping.\n items:\n (navDisplay === 'tabs' || data?.flatNav === true) && meta.navShape !== 'flat'\n ? navItems.map(({ children: _sub, ...item }) => item)\n : navItems,\n isActive: navIsActive,\n flatten: meta.navShape === 'flat',\n },\n // The app's own workspace is NOT the organization — it is a per-app\n // bootstrap account with a different id in every app. Showing it while\n // the chrome API resolves flashed the wrong org on every load (\"not\n // connected to the account\"). Shimmer while in flight; only fall back\n // to the app label once the chrome lookup has actually failed.\n org: activeCoreOrg\n ? {\n name: activeCoreOrg.name,\n id: activeCoreOrg.id,\n logoUrl: activeCoreOrg.logoUrl,\n brandColor: activeCoreOrg.brandColor,\n organizations: coreOrgs,\n onSwitch: chrome?.setOrgId,\n }\n : chrome?.orgsLoading\n ? { name: null, id: null, loading: true }\n : { name: session.accountName, id: session.accountId },\n mode,\n footer,\n linkComponent,\n }}\n // Reference/UI-Platform: the Beta banner is opt-in — it shows only\n // when the app's own POLITOGY_APPS registry entry sets `beta: true`,\n // not by default minus an opt-out.\n betaBanner={meta.beta === true ? {} : undefined}\n // Mode identity, straight from the registry — this is what lets the Brand\n // API's per-Mode chrome tokens target this frame. Not app-supplied: an app\n // still cannot pick its own accent, it inherits its Mode's.\n modeId={appMode}\n // Fluid <main> for every app. Core alone may still opt out while its\n // pages carry their own PageContainer (see PolitogyCoreFrame).\n contentWrapper={core?.contentWrapper}\n topBar={{\n // Core's pages publish their own identity; every other app is one\n // product surface and takes its registry title.\n // TITLEBAR (Design is truth): the chrome no longer draws a page-title\n // <h1> strip above the page for feature apps. Specs/Design shows the\n // page opening on its own eyebrow + H2 (app content), so only core's\n // own page title is passed. The 'title' grant is retained but inert.\n title: core?.page?.title,\n breadcrumbs,\n user: {\n name: identity.userName,\n email: identity.email,\n // The chrome API's avatar wins; the app may supply a fallback chain\n // (e.g. a stored memoji) for users with no uploaded photo.\n avatarUrl: identity.avatarUrl ?? data?.fallbackAvatarUrl ?? null,\n role: session.role,\n },\n userMenu,\n onSignOut: handleSignOut,\n // Reference/UI-Platform \"Top bar — required elements\": Universal\n // search is the only thing on the left end of the bar. No app wires\n // search yet, so this stays decorative (`NavTopBarProps.search` — \"an\n // app that has not wired search yet still gets the correct chrome\").\n search: { placeholder: data?.searchPlaceholder ?? DEFAULT_SEARCH_PLACEHOLDER[app] ?? 'Search' },\n // No Build notes control (Reference/UI-Platform, decided 2026-10-03).\n // The action cluster is IDENTICAL everywhere — core included. Page\n // actions sit BEFORE it, never inside it, so the Alerts bell keeps its\n // required position: farthest right, immediately before My Account.\n actions: (\n <>\n {core?.page?.actions}\n <ChromeTopBarActions />\n </>\n ),\n }}\n >\n {children}\n </NavAppShell>\n </>\n )\n}\n","// ---------------------------------------------------------------------------\n// App chrome wiring — the ONE shared implementation of the per-app glue that\n// previously lived as a copied ChromeWidgets.tsx in every Next.js feature app\n// (forms / surveys / polls / contacts). Copies drifted (org dropdown, badges);\n// this module makes that class of drift impossible: apps configure, never\n// re-implement (Reference/UI-Platform: consume via npm, never vendored).\n//\n// Provides:\n// <PolitogyAppChrome> — NavChromeProvider (same-origin proxy fetcher) +\n// chrome state (active core org, nav display) +\n// DevNotes provider, in one wrapper.\n// <ChromeTopBarActions> — the canonical top-bar cluster, in canonical order\n// (Fuel · Nav display · DevNotes · Support · Alerts\n// LAST, immediately left of My Account).\n// useChromeState / useChromeUserMenu / useIsSuperAdmin / useChromeFooter.\n//\n// The app still owns: its session (the /api/chrome proxy), page frames, build\n// metadata (env/commit/version), tab strips, and its own icons.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport type { NotificationsAdapter } from '../notifications/adapter'\nimport {\n NavChromeProvider,\n FuelAction,\n NotificationsAction,\n SupportAction,\n SpecOverlayAction,\n NavDisplayAction,\n TopBarWidgetSlot,\n useChromeOrgs,\n useThemePreference,\n type NavChromeFetcher,\n type NavDisplayMode,\n type NavOrgOption,\n type NavUserMenu,\n type NavFooter,\n type NavFooterLink,\n} from '../native/index'\nimport {\n DevNotesProvider,\n DevNotesMenu,\n DevNotesOverlay,\n DevNotesTaskListModal,\n createDevNotesClient,\n type DevNotesConfig,\n} from '@the-portland-company/devnotes'\nimport {\n LuActivity,\n LuChartColumn,\n LuBriefcase,\n LuClock,\n LuCreditCard,\n LuDollarSign,\n LuPencil,\n LuFileText,\n LuFlag,\n LuLayoutGrid,\n LuHouse,\n LuLayoutDashboard,\n LuLifeBuoy,\n LuList,\n LuMail,\n LuMap,\n LuMapPin,\n LuMessageSquare,\n LuPhone,\n LuSend,\n LuSettings,\n LuShare2,\n LuTarget,\n LuUpload,\n LuUser,\n LuUsers,\n LuContactRound,\n LuUsersRound,\n LuMousePointerClick,\n LuClipboardList,\n LuCircleUser,\n LuCrosshair,\n LuLandmark,\n LuChartNoAxesColumn,\n LuDoorOpen,\n LuSignpost,\n LuMegaphone,\n LuFilePenLine,\n LuNotebookPen,\n} from 'react-icons/lu'\nimport { useChromeMe, useNavChromeDedupedFetch, useNavChromeFetcher } from '../native/index'\nimport {\n ACTIVE_ORG_QUERY_PARAM,\n ORG_ID_QUERY_PARAM,\n isOrgId,\n matchOrgSelector,\n orgIdTail,\n readActiveOrgCookie,\n readOrgSelectorFromUrl,\n resolveActiveOrg,\n switchActiveOrg,\n writeActiveOrgCookie,\n syncOrgIdInUrl,\n} from '../active-org'\nimport {\n NAV_DISPLAY_DEFAULT,\n NAV_DISPLAY_STORAGE_KEY,\n isNavDisplayPreference,\n readNavDisplayCookie,\n resolveNavDisplay,\n writeNavDisplayCookie,\n writeNavDisplayLocal,\n} from '../nav-preference'\nimport type { StandardNavIconKey } from '../native/standardNav'\nimport type { NavBreadcrumb, NavIcon, NavItem, NavMode } from '../native/index'\n\nexport { standardNavIcons } from '../native/standardNavIcons'\nimport { standardNavIcons } from '../native/standardNavIcons'\n\nconst ORG_STORAGE_KEY = 'vrm.activeOrg'\n// The user's mode choice, shared by every app on the origin's localStorage.\nconst MODE_STORAGE_KEY = 'vrm.activeMode'\nconst CORE_BASE_URL = 'https://app.politogyvrm.com'\nconst CORE_BASE_URL_STAGING = 'https://staging-app.politogyvrm.com'\n\n/**\n * VRM-core base for the CURRENT environment, resolved at call time from the\n * host. A staging app (e.g. `surveys-staging.politogyvrm.com`,\n * `staging-app.politogyvrm.com`) targets the staging core, so cross-app links\n * into core — My Profile, Organization Settings, Add Account, the mode\n * dashboards — stay in staging instead of bouncing the user to production.\n * Everything else (prod hosts, localhost, previews) keeps the production core.\n *\n * Runtime, not build-time: the shell is one shared bundle consumed by every\n * app, so the environment can only be known from the host it runs on.\n */\nfunction getCoreBaseUrl(): string {\n if (typeof window !== 'undefined') {\n if (window.location.hostname.toLowerCase().includes('staging')) {\n return CORE_BASE_URL_STAGING\n }\n }\n return CORE_BASE_URL\n}\n\nexport type ChromeIdentity = {\n userId: string\n userName: string | null\n email: string | null\n /** The APP's own role string (any casing) — feeds DevNotes admin gating. */\n role: string\n}\n\ntype ChromeState = {\n orgId: string | null\n setOrgId: (id: string) => void\n orgs: (NavOrgOption & { rawRole?: string | null })[]\n /**\n * The org list is still in flight. Consumers must render a skeleton rather\n * than fall back to the app's own workspace label, which is a DIFFERENT\n * account and flashes as the wrong organization.\n */\n orgsLoading: boolean\n navDisplay: NavDisplayMode\n setNavDisplay: (m: NavDisplayMode) => void\n}\n\nconst ChromeStateContext = createContext<ChromeState | null>(null)\n\nexport function useChromeState(): ChromeState | null {\n return useContext(ChromeStateContext)\n}\n\nexport type ControlledOrgState = {\n orgId: string | null\n onSwitch: (id: string) => void\n /** Override the org list (e.g. the app's own session-scoped list). */\n orgs?: (NavOrgOption & { rawRole?: string | null })[]\n /**\n * Applied for EXTERNAL org changes (another tab/app switched the shared\n * cookie, or the profile preference was adopted at boot). Unlike `onSwitch`\n * (a user gesture), this fires on tab focus — wire it WITHOUT navigation\n * side effects (e.g. vrm/core's switch without the dashboard redirect).\n * Falls back to `onSwitch` when absent.\n */\n onExternalSwitch?: (id: string) => void\n}\n\n/**\n * Auth-owned active org (Global-Rules v38, UI-Platform v46). The app server\n * passes the VERIFIED token claims; the shell never resolves the org itself.\n */\nexport type TokenOrgState = {\n /** `org_id` claim from the app's verified token (full uuid). */\n orgId: string | null\n /** `org_role` claim (raw VRM Core role). */\n orgRole?: string | null\n /**\n * The switcher list from the app server (names for the pill). When given,\n * the chrome `/api/orgs` call is skipped. When absent it is the fallback.\n */\n orgs?: (NavOrgOption & { rawRole?: string | null })[]\n /**\n * Server action that re-exchanges for tokens on `orgId`. Called after the\n * IdP accepted the switch (shared) or for a per-tab override (`perTab`).\n */\n onReexchange: (orgId: string, opts: { perTab: boolean }) => void | Promise<void>\n /** IdP base override (default: auth / auth-staging by host). */\n authBaseUrl?: string\n /** Called when the IdP refuses a switch (403 not a member, 401 no session). */\n onSwitchError?: (err: unknown) => void\n}\n\nfunction TokenChromeStateProvider({\n tokenOrg,\n children,\n}: {\n tokenOrg: TokenOrgState\n children: ReactNode\n}) {\n const { orgs: fetchedOrgs, loading: orgsFetching, error: orgsError } = useChromeOrgs({\n enabled: !tokenOrg.orgs,\n })\n const [navDisplay, setNavDisplayState] = useState<NavDisplayMode>(NAV_DISPLAY_DEFAULT)\n const [pendingOrg, setPendingOrg] = useState<string | null>(null)\n const tokenOrgRef = useRef(tokenOrg)\n tokenOrgRef.current = tokenOrg\n\n useEffect(() => {\n setNavDisplayState(resolveNavDisplay())\n }, [])\n\n const orgs = useMemo(\n () =>\n tokenOrg.orgs ??\n (fetchedOrgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n [tokenOrg.orgs, fetchedOrgs],\n )\n\n // Per-tab override: `?org_id=` (or legacy `?org=`) in THIS tab's URL. It\n // scopes this tab only and never changes the shared active org. A selector\n // that is not one of the user's orgs is ignored.\n //\n // `urlSelector` used to be read once at mount (`useState(() => ...)`),\n // which froze whatever org was in the URL at that moment. A later shared\n // switch (setOrgId) rewrites the URL to the new org but never told this\n // state about it, so the stale selector kept winning at line ~264 forever\n // — repro: switch A -> B, reload (urlSelector now \"B\"), switch B -> A: the\n // pill stayed on B because overrideOrg was still matching the frozen \"B\"\n // from mount. Re-read on every URL change (a switch calls\n // history.replaceState, which doesn't fire `popstate`, so setOrgId clears\n // this directly on success below instead of relying on the listener for\n // that case) and on back/forward navigation.\n const [urlSelector, setUrlSelector] = useState<string | null>(() =>\n typeof window === 'undefined' ? null : readOrgSelectorFromUrl(window.location.search),\n )\n useEffect(() => {\n if (typeof window === 'undefined') return\n const onLocationChange = () => setUrlSelector(readOrgSelectorFromUrl(window.location.search))\n window.addEventListener('popstate', onLocationChange)\n return () => window.removeEventListener('popstate', onLocationChange)\n }, [])\n const overrideOrg = useMemo(\n () => (urlSelector ? matchOrgSelector(urlSelector, orgs)?.id ?? null : null),\n [urlSelector, orgs],\n )\n const orgId = pendingOrg ?? (tokenOrg.orgId && overrideOrg ? overrideOrg : tokenOrg.orgId)\n\n // A per-tab override that differs from the token org: ask the app server for\n // a tab-scoped token once (the IdP shared active org stays as it is).\n const reexchangedFor = useRef<string | null>(null)\n useEffect(() => {\n if (!overrideOrg || !tokenOrg.orgId || overrideOrg === tokenOrg.orgId) return\n if (reexchangedFor.current === overrideOrg) return\n reexchangedFor.current = overrideOrg\n void Promise.resolve(tokenOrgRef.current.onReexchange(overrideOrg, { perTab: true })).catch(\n () => {},\n )\n }, [overrideOrg, tokenOrg.orgId])\n\n // Clear the optimistic value once the app's new token carries it.\n useEffect(() => {\n if (pendingOrg && tokenOrg.orgId === pendingOrg) setPendingOrg(null)\n }, [pendingOrg, tokenOrg.orgId])\n\n const setOrgId = useCallback((id: string) => {\n const current = tokenOrgRef.current\n if (!isOrgId(id) || id === (current.orgId ?? null)) return\n setPendingOrg(id)\n void (async () => {\n try {\n const claims = await switchActiveOrg(id, { authBaseUrl: current.authBaseUrl })\n // The switch is shared: drop this tab's URL override so it follows.\n // Clear it here directly (not only via the popstate listener above)\n // because the URL rewrite below is a `history.replaceState`, which\n // never fires `popstate` — so this is the only place in the\n // shared-switch path that would otherwise see the stale selector.\n setUrlSelector(null)\n try {\n const url = new URL(window.location.href)\n url.searchParams.delete(ACTIVE_ORG_QUERY_PARAM)\n url.searchParams.set(ORG_ID_QUERY_PARAM, orgIdTail(claims.orgId) as string)\n window.history.replaceState(window.history.state, '', url.toString())\n } catch {\n /* SSR / no window */\n }\n await tokenOrgRef.current.onReexchange(claims.orgId, { perTab: false })\n } catch (err) {\n setPendingOrg(null)\n tokenOrgRef.current.onSwitchError?.(err)\n }\n })()\n }, [])\n\n const setNavDisplay = useCallback((m: NavDisplayMode) => {\n setNavDisplayState(m)\n writeNavDisplayLocal(m)\n writeNavDisplayCookie(m)\n }, [])\n\n // Address bar carries the 7-char `org_id` (UI-Platform \"URL state\") ONLY\n // when the user brought a selector or a real switch put one there; a bare\n // load stays bare (see syncOrgIdInUrl). A legacy `?org=<uuid>` is rewritten\n // with a replace, never a navigation.\n useEffect(() => {\n try {\n const next = syncOrgIdInUrl(window.location.href, orgId)\n if (next) window.history.replaceState(window.history.state, '', next)\n } catch {\n /* SSR / no window */\n }\n }, [orgId])\n\n // Legacy cookie mirror for apps not yet on v2 — the SHARED org only, never a\n // per-tab override.\n useEffect(() => {\n if (isOrgId(tokenOrg.orgId) && !pendingOrg) writeActiveOrgCookie(tokenOrg.orgId as string)\n }, [tokenOrg.orgId, pendingOrg])\n\n // Follow a SHARED switch made in another app/tab (Forge 773bf0eb). Unlike\n // the legacy `ChromeStateProvider`, this provider never re-read the mirror\n // cookie on wake, so an already-open tab kept its own stale `tokenOrg.orgId`\n // until the next full reload — reload-driven routes work because they\n // re-fetch `scope.account` from the server, bypassing this cookie entirely.\n // Re-exchange shared (never perTab) whenever the cookie disagrees with the\n // token on wake; the dedup/membership judgment is the IdP's own job inside\n // `onReexchange`, not this listener's.\n useEffect(() => {\n const onWake = () => {\n const cookieOrg = readActiveOrgCookie()\n const current = tokenOrgRef.current\n if (!isOrgId(cookieOrg) || cookieOrg === (current.orgId ?? null)) return\n if (pendingOrg === cookieOrg) return\n void Promise.resolve(current.onReexchange(cookieOrg as string, { perTab: false })).catch(\n () => {},\n )\n }\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [pendingOrg])\n\n const value = useMemo<ChromeState>(\n () => ({\n orgId,\n setOrgId,\n orgs,\n orgsLoading: !tokenOrg.orgs && orgsFetching && !orgsError && !fetchedOrgs,\n navDisplay,\n setNavDisplay,\n }),\n [orgId, setOrgId, orgs, tokenOrg.orgs, orgsFetching, orgsError, fetchedOrgs, navDisplay, setNavDisplay],\n )\n\n return <ChromeStateContext.Provider value={value}>{children}</ChromeStateContext.Provider>\n}\n\nfunction ChromeStateProvider({\n controlledOrg,\n children,\n}: {\n controlledOrg?: ControlledOrgState\n children: ReactNode\n}) {\n const { orgs, loading: orgsFetching, error: orgsError } = useChromeOrgs()\n const chromeMe = useChromeMe()\n const chromeFetch = useNavChromeFetcher()\n const [orgId, setOrgIdState] = useState<string | null>(null)\n const [navDisplay, setNavDisplayState] = useState<NavDisplayMode>(NAV_DISPLAY_DEFAULT)\n const navReconciled = useRef(false)\n const orgReconciled = useRef(false)\n // Whether boot found an explicit selector (URL `?org=` or the shared cookie).\n // The mirror effect writes the cookie right after first resolve, so a later\n // `resolveActiveOrg()` read is a false positive — this ref is the only\n // reliable \"was there a pre-existing selector?\" signal for the profile tier.\n const hadBootSelector = useRef(false)\n\n // Boot: restore persisted choices. The cross-app active org (URL `?org=` or\n // the `.politogyvrm.com` cookie) wins over host-only localStorage so every\n // app + subdomain resolves the SAME org instead of each defaulting to its own\n // earliest-joined org. Nav display follows the same cross-subdomain contract\n // as theme (cookie → localStorage → default) — it used to be localStorage\n // only, which is per-origin, so it reset on every app the user opened.\n useEffect(() => {\n try {\n const selector = resolveActiveOrg()\n if (selector) hadBootSelector.current = true\n const storedOrg = selector ?? localStorage.getItem(ORG_STORAGE_KEY)\n if (storedOrg) setOrgIdState(storedOrg)\n } catch {\n /* storage unavailable */\n }\n setNavDisplayState(resolveNavDisplay())\n }, [])\n\n // Once per session: converge on the profile's saved choice (authoritative),\n // reusing the provider's single `me` fetch — the theme reconcile pattern.\n useEffect(() => {\n if (navReconciled.current || !chromeMe.me) return\n const pref = chromeMe.me.navDisplay\n if (!isNavDisplayPreference(pref)) return\n navReconciled.current = true\n setNavDisplayState(pref)\n writeNavDisplayCookie(pref)\n writeNavDisplayLocal(pref)\n }, [chromeMe])\n\n // Live sync: `storage` events for same-app tabs, cookie re-reads on\n // focus/visibility for tabs on OTHER app subdomains.\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === NAV_DISPLAY_STORAGE_KEY && isNavDisplayPreference(e.newValue)) {\n setNavDisplayState(e.newValue)\n }\n }\n const onWake = () => {\n const cookie = readNavDisplayCookie()\n if (cookie) setNavDisplayState(cookie)\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [])\n\n // Once orgs resolve: validate the stored org, default to the first.\n useEffect(() => {\n if (!orgs || orgs.length === 0) return\n setOrgIdState((prev) => (prev && orgs.some((o) => o.id === prev) ? prev : orgs[0].id))\n }, [orgs])\n\n // Refs for the live-sync wake handler: registered once (theme/nav precedent)\n // but acting on CURRENT state, so listeners never re-subscribe per render.\n const activeOrgRef = useRef<string | null>(null)\n const memberOrgsRef = useRef<{ id: string }[]>([])\n const controlledOrgRef = useRef<ControlledOrgState | undefined>(controlledOrg)\n controlledOrgRef.current = controlledOrg\n\n // Apply an EXTERNAL org change (another tab/app, or the adopted profile\n // preference). Membership-guarded and change-guarded; silent fall-through\n // otherwise — a non-member cookie value is normal, not an error.\n const applyExternalOrg = useCallback((next: string | null) => {\n if (!isOrgId(next)) return\n const members = memberOrgsRef.current\n if (members.length === 0) return\n if (!members.some((o) => o.id === next)) return\n if (next === activeOrgRef.current) return\n const controlled = controlledOrgRef.current\n if (controlled) (controlled.onExternalSwitch ?? controlled.onSwitch)(next as string)\n else setOrgIdState(next as string)\n }, [])\n\n // Live org sync: `storage` events for same-origin tabs, cookie re-reads on\n // focus/visibility for tabs on OTHER app subdomains — the same two channels\n // theme and nav display use. A user switching orgs in one app re-scopes\n // every other open tab the moment it regains focus.\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === ORG_STORAGE_KEY) applyExternalOrg(e.newValue)\n }\n const onWake = () => {\n applyExternalOrg(readActiveOrgCookie())\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [applyExternalOrg])\n\n // Once per session: adopt the profile's saved org (me.activeOrg) — but ONLY\n // when this load carried no explicit selector. Precedence is URL → cookie →\n // profile → default; theme's unconditional adopt is wrong for org because an\n // explicit per-request selector must always win.\n //\n // Membership is judged against the FETCHED chrome-API org list, not the\n // controlled app's list: controlled apps seed a provisional single-org list\n // (their session default) before their real fetch settles, and judging the\n // preference against that dropped it every time (verified live 2026-08-07).\n useEffect(() => {\n if (orgReconciled.current || !chromeMe.me) return\n if (hadBootSelector.current) {\n orgReconciled.current = true\n return\n }\n const pref = (chromeMe.me as { activeOrg?: string | null }).activeOrg\n if (!isOrgId(pref)) {\n orgReconciled.current = true\n return\n }\n // Wait until the chrome-API org fetch settles (success or error) — do NOT\n // latch while it is in flight, or the preference is silently dropped.\n if (!orgs && !orgsError) return\n orgReconciled.current = true\n const members = [...(orgs ?? []), ...(controlledOrg?.orgs ?? [])]\n if (!members.some((o) => o.id === pref)) return\n const controlled = controlledOrgRef.current\n if (controlled) (controlled.onExternalSwitch ?? controlled.onSwitch)(pref as string)\n else setOrgIdState(pref as string)\n }, [chromeMe.me, orgs, orgsError, controlledOrg])\n\n const setOrgId = useCallback((id: string) => {\n setOrgIdState(id)\n try {\n localStorage.setItem(ORG_STORAGE_KEY, id)\n } catch {\n /* best effort */\n }\n // Remember the choice cross-subdomain so the next app opens on the same org.\n writeActiveOrgCookie(id)\n }, [])\n\n const setNavDisplay = useCallback(\n (m: NavDisplayMode) => {\n setNavDisplayState(m)\n writeNavDisplayLocal(m)\n // Cross-subdomain, so the next app opens on the same choice.\n writeNavDisplayCookie(m)\n // Best-effort durable persistence on the user's profile — a nav toggle\n // never errors, and the cookie already carries the choice meanwhile.\n chromeFetch?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ navDisplay: m }),\n })?.catch(() => {})\n },\n [chromeFetch],\n )\n\n const value = useMemo<ChromeState>(() => {\n // CONTROLLED mode (Contacts): the APP owns the active org + switching —\n // its switch does a full session re-scope. The shared widgets read the\n // app's state so there is exactly one org truth (unification directive).\n if (controlledOrg) {\n return {\n orgId: controlledOrg.orgId,\n setOrgId: controlledOrg.onSwitch,\n orgs:\n controlledOrg.orgs ??\n (orgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n orgsLoading: false,\n navDisplay,\n setNavDisplay,\n }\n }\n return {\n orgId,\n setOrgId,\n orgs: (orgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n // Loading until the fetch settles. On error we stop loading so the frame\n // falls back to the app label rather than shimmering forever.\n orgsLoading: orgsFetching && !orgsError && !orgs,\n navDisplay,\n setNavDisplay,\n }\n }, [controlledOrg, orgId, setOrgId, orgs, orgsFetching, orgsError, navDisplay, setNavDisplay])\n\n // Keep the shared cookie + address-bar `?org=` in sync with the ACTIVE org —\n // whichever path owns it, controlled (Contacts) or uncontrolled (feature\n // apps) — so every app + tab resolves the same org and every URL is\n // bookmarkable/shareable with its org context. Idempotent; no-op on server.\n const activeOrgId = value.orgId\n activeOrgRef.current = activeOrgId\n memberOrgsRef.current = value.orgs\n const lastPatchedOrg = useRef<string | null>(null)\n useEffect(() => {\n if (!isOrgId(activeOrgId)) return\n writeActiveOrgCookie(activeOrgId as string)\n try {\n // Same-origin storage channel for OTHER tabs of this app (the cookie\n // write emits no event) — mirrors the choice whichever branch owns it.\n localStorage.setItem(ORG_STORAGE_KEY, activeOrgId as string)\n } catch {\n /* best effort */\n }\n try {\n const url = new URL(window.location.href)\n if (url.searchParams.get(ACTIVE_ORG_QUERY_PARAM) !== activeOrgId) {\n url.searchParams.set(ACTIVE_ORG_QUERY_PARAM, activeOrgId as string)\n window.history.replaceState(window.history.state, '', url.toString())\n }\n } catch {\n /* SSR / no window */\n }\n // Durable profile write (the theme/nav pattern): one call site covers both\n // the controlled and uncontrolled branches. Best-effort, deduped against\n // the profile's known value and our own last write; a fresh browser with\n // no cookie then boots on this org via the profile tier.\n //\n // GATED on the reconcile having resolved: before that, activeOrgId is the\n // app's boot DEFAULT, and patching it overwrote the user's stored\n // preference with the default on every fresh session (verified live\n // 2026-08-07 — the preference lasted exactly one login).\n const known = (chromeMe.me as { activeOrg?: string | null } | null)?.activeOrg ?? null\n if (\n orgReconciled.current &&\n chromeMe.me &&\n activeOrgId !== known &&\n activeOrgId !== lastPatchedOrg.current\n ) {\n lastPatchedOrg.current = activeOrgId as string\n chromeFetch?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ activeOrg: activeOrgId }),\n })?.catch(() => {})\n }\n }, [activeOrgId, chromeMe.me, chromeFetch])\n\n return <ChromeStateContext.Provider value={value}>{children}</ChromeStateContext.Provider>\n}\n\nexport type ChromeDevNotesConfig = {\n /** Override the DevNotes API base (default: `${proxyBasePath}/devnotes`). */\n basePath?: string\n /** Client-side token supplier (default: empty — same-origin proxy injects). */\n getAuthToken?: () => Promise<string> | string\n /** Custom fetch (e.g. credentials:'include' against a cross-origin API). */\n fetch?: typeof globalThis.fetch\n /**\n * The app already mounts its own `<DevNotesProvider>` ABOVE this chrome, so\n * the chrome must not mount a second one (VRM core, whose provider carries\n * capabilities the generic client has no equivalent for — user stories, its\n * own role gating). The working SURFACE still comes from here, so the\n * launcher, the overlay and the task modal behave identically everywhere;\n * only the data adapter is the app's.\n */\n providedByApp?: boolean\n}\n\nfunction AppDevNotes({\n storagePrefix,\n proxyBasePath,\n devNotes,\n identity,\n children,\n}: {\n storagePrefix: string\n proxyBasePath: string\n devNotes?: ChromeDevNotesConfig\n identity: ChromeIdentity\n children: ReactNode\n}) {\n const adapter = useMemo(\n () =>\n createDevNotesClient({\n basePath: devNotes?.basePath ?? `${proxyBasePath}/devnotes`,\n // Default: the same-origin proxy attaches the session's Bearer.\n getAuthToken: devNotes?.getAuthToken ?? (async () => ''),\n ...(devNotes?.fetch ? { fetch: devNotes.fetch } : {}),\n }),\n [proxyBasePath, devNotes?.basePath, devNotes?.getAuthToken, devNotes?.fetch],\n )\n\n const user = useMemo(\n () => ({\n id: identity.userId,\n email: identity.email ?? '',\n fullName: identity.userName ?? undefined,\n }),\n [identity.userId, identity.email, identity.userName],\n )\n\n const config = useMemo<DevNotesConfig>(\n () => ({\n storagePrefix,\n role: identity.role.toLowerCase() === 'admin' ? 'admin' : 'reporter',\n disableAi: true,\n getPagePath: () => window.location.pathname,\n }),\n [storagePrefix, identity.role],\n )\n\n // `<DevNotesProvider>` hydrates tasks/task-types/task-lists/collaborators/\n // app-link/capabilities unconditionally on mount — 5-6 requests, one 6.8s\n // cold, even when the panel is never opened (nav-latency-report.md Table 2).\n // Gate those specific adapter methods behind the panel's FIRST open; the\n // launcher button (`ChromeDevNotesMenu` below) still renders and responds\n // instantly, it just flips `activate()` on pointerdown before its own click\n // handler runs. `fetchUnreadCounts` (the launcher badge count) is exempt\n // from the open-gate — it still needs a number before the user opens\n // anything — but its first call is pushed off the boot path onto\n // requestIdleCallback so it never competes with first paint.\n const activatedRef = useRef(false)\n const activationWaitersRef = useRef<Array<() => void>>([])\n const activate = useCallback(() => {\n if (activatedRef.current) return\n activatedRef.current = true\n const waiters = activationWaitersRef.current\n activationWaitersRef.current = []\n waiters.forEach((resolve) => resolve())\n }, [])\n const waitForActivation = useCallback((): Promise<void> => {\n if (activatedRef.current) return Promise.resolve()\n return new Promise((resolve) => {\n activationWaitersRef.current.push(resolve)\n })\n }, [])\n\n const lazyAdapter = useMemo<typeof adapter>(() => {\n const GATED_METHODS = [\n 'fetchTasks',\n 'fetchTaskTypes',\n 'fetchTaskLists',\n 'fetchCollaborators',\n 'fetchCapabilities',\n 'getAppLinkStatus',\n 'fetchBugReports',\n 'fetchBugReportTypes',\n ] as const\n const wrapped: Record<string, unknown> = { ...adapter }\n for (const method of GATED_METHODS) {\n const original = (adapter[method] as (...args: unknown[]) => Promise<unknown>).bind(adapter)\n wrapped[method] = (...args: unknown[]) => waitForActivation().then(() => original(...args))\n }\n let idleScheduled = false\n const originalUnreadCounts = adapter.fetchUnreadCounts.bind(adapter)\n wrapped.fetchUnreadCounts = () => {\n if (idleScheduled || typeof window === 'undefined') return originalUnreadCounts()\n idleScheduled = true\n return new Promise((resolve, reject) => {\n const run = () => originalUnreadCounts().then(resolve, reject)\n const ric = (window as { requestIdleCallback?: (cb: () => void) => number })\n .requestIdleCallback\n if (ric) ric(run)\n else setTimeout(run, 0)\n })\n }\n return wrapped as unknown as typeof adapter\n }, [adapter, waitForActivation])\n\n // The app brought its own provider — mount only the surface, so a second\n // DevNotesProvider never shadows the app's adapter. (The app's own adapter\n // is out of this chrome's control, so the open-gate above does not apply.)\n if (devNotes?.providedByApp) return <DevNotesSurface activate={activate}>{children}</DevNotesSurface>\n\n return (\n <DevNotesProvider adapter={lazyAdapter} user={user} config={config}>\n <DevNotesSurface activate={activate}>{children}</DevNotesSurface>\n </DevNotesProvider>\n )\n}\n\n// \"View All Tasks\" is triggered from the menu in the top bar but the modal has\n// to render at the chrome ROOT, or it would be trapped inside the top bar's\n// stacking/blur context. The menu publishes the request through this context.\nconst DevNotesTasksContext = createContext<{\n ready: boolean\n openTasks: () => void\n activate: () => void\n}>({\n ready: false,\n openTasks: () => {},\n activate: () => {},\n})\n\n/**\n * The DevNotes working surface, mounted once at the chrome root.\n *\n * `<DevNotesMenu>` only TOGGLES creation mode — `<DevNotesOverlay>` is what\n * renders the click-to-place capture layer, the report dots and the report\n * form. The shell shipped the provider and the menu but never the overlay, so\n * on every app that used this chrome (forms / surveys / polls) \"Create Task\"\n * closed the menu and did nothing at all: the mode flipped on with nothing\n * listening (HITL bug report 2026-07-23). Contacts didn't hit it only because\n * it still had its own hand-rolled surface.\n */\nfunction DevNotesSurface({\n activate,\n children,\n}: {\n /** Flips the DevNotes data adapter open for the first time (no-op after). */\n activate: () => void\n children: ReactNode\n}) {\n const [tasksOpen, setTasksOpen] = useState(false)\n const openTasks = useCallback(() => {\n activate()\n setTasksOpen(true)\n }, [activate])\n const tasksCtx = useMemo(() => ({ ready: true, openTasks, activate }), [openTasks, activate])\n\n return (\n <DevNotesTasksContext.Provider value={tasksCtx}>\n {children}\n {/* Mounted only while open: the modal loads data on mount regardless of\n its `open` prop, so keeping it unmounted avoids fetching every user's\n tasks before they ask for them. */}\n {tasksOpen ? <DevNotesTaskListModal open onClose={() => setTasksOpen(false)} /> : null}\n <DevNotesOverlay />\n </DevNotesTasksContext.Provider>\n )\n}\n\n/**\n * The app-chrome root. Wrap the authenticated frame once:\n *\n * <PolitogyAppChrome storagePrefix=\"forms\" identity={{userId, userName, email, role}}>\n * <ShellFrame …/>\n * </PolitogyAppChrome>\n */\nexport function PolitogyAppChrome({\n storagePrefix,\n proxyBasePath = '/api/chrome',\n fetchJson: fetchJsonOverride,\n notificationsAdapter,\n devNotes,\n org,\n tokenOrg,\n identity,\n children,\n}: {\n storagePrefix: string\n proxyBasePath?: string\n /**\n * Override the same-origin proxy fetcher for apps that talk to the chrome\n * API directly with their own auth (Contacts sends a client-side Bearer).\n * Paths stay relative ('orgs', 'me', …) — the override owns base + auth.\n */\n fetchJson?: NavChromeFetcher\n /**\n * The bell's feed adapter. Omitted: the comms feed over the same proxy.\n * `null`: the legacy contacts-shaped feed. See NotificationsAdapter.\n */\n notificationsAdapter?: NotificationsAdapter | null\n /** DevNotes wiring override for direct-auth apps (Contacts). */\n devNotes?: ChromeDevNotesConfig\n /** Controlled org state — the app owns active-org + switching (Contacts). */\n org?: ControlledOrgState\n /** Auth-owned active org from verified token claims (v2). Wins over `org`. */\n tokenOrg?: TokenOrgState\n identity: ChromeIdentity\n children: ReactNode\n}) {\n const proxyFetchJson = useMemo<NavChromeFetcher>(\n () =>\n async (path, init) => {\n const res = await fetch(`${proxyBasePath}/${path}`, {\n method: init?.method ?? 'GET',\n headers: init?.headers,\n body: init?.body,\n })\n if (!res.ok) throw new Error(`chrome ${path}: ${res.status}`)\n if (res.status === 204) return null\n const text = await res.text()\n return text ? JSON.parse(text) : null\n },\n [proxyBasePath],\n )\n const fetchJson = fetchJsonOverride ?? proxyFetchJson\n const devNotesTree = (\n <AppDevNotes\n storagePrefix={storagePrefix}\n proxyBasePath={proxyBasePath}\n devNotes={devNotes}\n identity={identity}\n >\n {children}\n </AppDevNotes>\n )\n\n return (\n <NavChromeProvider fetchJson={fetchJson} notificationsAdapter={notificationsAdapter}>\n {tokenOrg ? (\n <TokenChromeStateProvider tokenOrg={tokenOrg}>{devNotesTree}</TokenChromeStateProvider>\n ) : (\n <ChromeStateProvider controlledOrg={org}>{devNotesTree}</ChromeStateProvider>\n )}\n </NavChromeProvider>\n )\n}\n\n/** The standard top-bar action cluster — Reference/UI-Platform v30 \"Top bar\":\n * Search | Dev notes | Credits | Notifications | Help (farthest right). The\n * Navigation Display switcher moved into the account menu (0.68.0); the Spec\n * overlay slot still renders between Credits and Notifications when the\n * signed-in user is allowed it (it draws nothing otherwise). */\nexport function ChromeTopBarActions() {\n const state = useChromeState()\n if (!state) return null\n // Org-scoped widgets read only once the org list settled: before that the\n // boot org (stored/URL) can still be replaced, and each change was a second\n // fuel-status / notifications request on the same page load.\n const settledOrgId = state.orgsLoading ? null : state.orgId\n return (\n <>\n <TopBarWidgetSlot\n title=\"DevNotes\"\n description=\"Capture bugs and notes, filed straight to Forge.\"\n >\n <ChromeDevNotesMenu />\n </TopBarWidgetSlot>\n <FuelAction orgId={settledOrgId} />\n <SpecOverlayAction orgId={state.orgId} orgName={state.orgs.find((o) => o.id === state.orgId)?.name ?? null} />\n <NotificationsAction orgId={settledOrgId} />\n <SupportAction orgId={state.orgId} orgs={state.orgs.length ? state.orgs : undefined} />\n </>\n )\n}\n\n/**\n * The DevNotes launcher. Renders nothing until the surface above is mounted, so\n * it never touches DevNotes context before the provider exists, and forwards\n * \"View All Tasks\" to the root-level modal.\n */\nfunction ChromeDevNotesMenu() {\n const { ready, openTasks, activate } = useContext(DevNotesTasksContext)\n if (!ready) return null\n // `onPointerDownCapture` fires before DevNotesMenu's own click handler, so\n // the adapter is already unblocked by the time the menu's first \"Create\n // Task\" click reaches it. `display: contents` keeps the wrapper out of\n // layout entirely — the launcher renders exactly as before.\n return (\n <span style={{ display: 'contents' }} onPointerDownCapture={activate} onFocusCapture={activate} onKeyDownCapture={activate}>\n <DevNotesMenu position=\"top-right\" icon={LuNotebookPen} onViewTasks={openTasks} />\n </span>\n )\n}\n\n/** True when any core-org membership carries a super-admin tier. */\nexport function useIsSuperAdmin(): boolean {\n const state = useChromeState()\n return (state?.orgs ?? []).some((o) => /super/i.test(o.rawRole ?? ''))\n}\n\nconst FOOTER_LINKS: NavFooterLink[] = [\n { label: 'Privacy', href: `${CORE_BASE_URL}/privacy-policy`, external: true },\n { label: 'Terms', href: `${CORE_BASE_URL}/terms-and-conditions`, external: true },\n {\n label: 'Subscriptions',\n href: 'https://politogyvrm.com/subscription-cancellation-policy',\n external: true,\n },\n]\n\n/**\n * Sidebar footer: legal links AND build metadata (env / commit / version /\n * date / author) for every user. Reference/UI-Platform \"Left bar — required\n * elements\" lists Meta unconditionally — it carries no Super Administrator\n * gate. Gating it here (pre-2026-09-30) silently dropped the whole Meta row\n * for every non-admin viewer, which is exactly the \"Left Nav not adhering to\n * UI/UX rules\" violation DevNotes 83a4713 filed against Contacts. Pass the\n * app's build-time metadata in; it now always reaches the rail.\n */\nexport function useChromeFooter(meta: {\n envLabel?: string\n version?: string\n commit?: string\n commitDate?: string\n commitAuthor?: string\n}): NavFooter {\n return useMemo<NavFooter>(\n () => ({ links: FOOTER_LINKS, ...meta }),\n [meta.envLabel, meta.version, meta.commit, meta.commitDate, meta.commitAuthor],\n )\n}\n\n// ---------------------------------------------------------------------------\n// Identity — resolved by the PACKAGE, from the chrome API.\n//\n// Apps used to pass a display name straight from their own session claims, and\n// forms passed `user.name ?? user.email` — so a user with no name set had their\n// EMAIL rendered as their name, and the chrome API's real profile name could\n// never win (HITL 2026-07-23). The chrome API is the authority; what the app\n// passes is a pre-hydration fallback only, and an email is never a name.\n// ---------------------------------------------------------------------------\n\nexport function useChromeIdentity(fallback?: {\n userName?: string | null\n email?: string | null\n}): ResolvedIdentity {\n const { me, loaded } = useChromeMe()\n return resolveIdentity({\n apiName: me?.userName,\n fallbackName: fallback?.userName,\n email: fallback?.email,\n avatarUrl: me?.avatarUrl,\n loaded,\n })\n}\n\n// Breadcrumbs live in ../lib/breadcrumbs (pure, dependency-free) and are\n// re-exported here so apps keep a single import surface.\nexport { deriveBreadcrumbs } from '../lib/breadcrumbs'\nexport { looksLikeEmail, resolveIdentity, type ResolvedIdentity } from '../lib/identity'\nimport { resolveIdentity, type ResolvedIdentity } from '../lib/identity'\n\n// ---------------------------------------------------------------------------\n// Breadcrumbs — derived by the PACKAGE from the nav tree + the current path.\n//\n// Every app hand-built its own trail, so they disagreed: forms rendered\n// \"Forms › Dashboard\" while polls rendered \"Polls\" under a \"Polls\" title\n// (\"Polls / Polls\"). The standard is Dashboard › Sub › Item (HITL 2026-07-23),\n// derived from the same nav tree the sidebar renders, so no app can drift.\n// ---------------------------------------------------------------------------\n\n/**\n * The My Account menu config — profile/org links into VRM core, real roles\n * from the user's core organizations, the signed-in account, and the shared\n * Light/System/Dark theme control (auth-derived, cross-app).\n */\nexport function useChromeUserMenu({\n userId,\n userName,\n email,\n}: {\n userId: string\n userName: string | null\n email: string | null\n}): NavUserMenu {\n const state = useChromeState()\n const theme = useThemePreference()\n const activeOrg = state?.orgs.find((o) => o.id === state.orgId) ?? null\n const orgSuffix = activeOrg ? `?org=${activeOrg.id}` : ''\n // Environment-aware: on a staging app these must point at the staging core,\n // not production (HITL: editing Profile from a staging app redirected to prod).\n const coreBase = getCoreBaseUrl()\n return {\n // My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).\n myProfileHref: `${coreBase}/my-profile`,\n organizationSettingsHref: `${coreBase}/organization-settings${orgSuffix}`,\n roles: (state?.orgs ?? [])\n .filter((o) => o.rawRole || o.role)\n .map((o) => ({ role: (o.rawRole ?? o.role) as string, orgName: o.name })),\n accounts: [{ id: userId, name: userName, email, avatarUrl: null, active: true }],\n addAccountHref: `${coreBase}/my-profile#accounts`,\n theme: { value: theme.value, onChange: theme.setValue },\n navDisplay: state ? { value: state.navDisplay, onChange: state.setNavDisplay } : undefined,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Mode selector — entitlement-driven (HITL 2026-07-23: an org with multiple\n// active modes selects them from the left nav). Entitlements come from the\n// chrome API: GET me with the active org header → modes booleans\n// {relationship, campaign, petition, polling}. Selecting a mode navigates to\n// that mode's VRM-core dashboard carrying the active org.\n// ---------------------------------------------------------------------------\n\nconst MODE_DEFS: {\n id: string\n label: string\n icon: NavIcon\n /** Absolute destination, or a VRM-core path prefixed with CORE_BASE_URL. */\n href: string\n orgQuery: boolean\n}[] = [\n {\n id: 'relationship',\n label: 'Relationship Mode',\n icon: LuContactRound,\n href: `${CORE_BASE_URL}/relationship/dashboard`,\n orgQuery: true,\n },\n {\n id: 'campaign',\n label: 'Campaign Mode',\n icon: LuMegaphone,\n href: `${CORE_BASE_URL}/campaign/dashboard`,\n orgQuery: true,\n },\n {\n // Petition Mode lives in its own standalone app on its own subdomain — the\n // petitions repo deploys production to petition-mode.politogyvrm.com.\n id: 'petition',\n label: 'Petition Mode',\n icon: LuFilePenLine,\n href: 'https://petition-mode.politogyvrm.com/',\n orgQuery: true,\n },\n]\n\ntype ModeId = 'relationship' | 'campaign' | 'petition'\n\ntype UseChromeModeArg =\n | ModeId\n | {\n /** Pre-entitlement fallback for first paint (default 'relationship'). */\n fallbackModeId?: ModeId\n /**\n * Registry-pinned mode for a MODE-SCOPED app (e.g. the Campaign apps\n * a2p / phonebank / canvass / signs, from `POLITOGY_APPS[app].mode`). The\n * pill DISPLAYS this mode regardless of the cross-app selection, so a\n * campaign app never shows a Relationship pill. The switcher still appears\n * when the active org is entitled to more than one mode, so the user can\n * jump out to another mode's home.\n */\n pinnedModeId?: ModeId\n }\n\n/**\n * The active mode pill / selector.\n *\n * For an UNSCOPED app the current mode is the USER'S OWN SELECTION (persisted\n * cross-app in localStorage under `vrm.activeMode`), narrowed to what the active\n * org is entitled to — never a literal an app hardcodes. Apps used to call\n * `useChromeMode('relationship')`, which pinned the pill to Relationship even\n * for an org entitled to Campaign or Petition (HITL 2026-07-23); the string\n * argument now only supplies the pre-entitlement fallback for first paint.\n *\n * A MODE-SCOPED app passes `{ pinnedModeId }` so its pill displays that mode\n * (its own mode from the app registry) rather than the cross-app selection —\n * while a multi-mode org still gets the switcher to leave.\n */\nexport function useChromeMode(arg: UseChromeModeArg = {}): NavMode {\n const { fallbackModeId = 'relationship', pinnedModeId } =\n typeof arg === 'string' ? { fallbackModeId: arg, pinnedModeId: undefined } : arg\n const ctx = useContext(ChromeStateContext)\n const dedupedFetch = useNavChromeDedupedFetch()\n const { me, loaded: meLoaded } = useChromeMe()\n const orgId = ctx?.orgId ?? null\n const [entitled, setEntitled] = useState<Record<string, boolean> | null>(null)\n const [selectedModeId, setSelectedModeId] = useState<string | null>(null)\n\n // Restore the user's last mode choice (shared key across every app).\n useEffect(() => {\n try {\n const stored = localStorage.getItem(MODE_STORAGE_KEY)\n if (stored && MODE_DEFS.some((m) => m.id === stored)) setSelectedModeId(stored)\n } catch {\n /* storage unavailable */\n }\n }, [])\n\n useEffect(() => {\n // Wait for the boot `me` so the reuse check below can decide.\n if (!dedupedFetch || !orgId || !meLoaded) return\n // The provider's boot `me` already carries `modes` for its resolved org:\n // reuse it instead of a second `me` call when that org is the active one.\n const bootMe = me as { account?: string | null; modes?: Record<string, boolean> | null } | null\n if (bootMe && bootMe.account === orgId && bootMe.modes !== undefined) {\n setEntitled(bootMe.modes ?? null)\n return\n }\n let cancelled = false\n dedupedFetch('me', { headers: { 'x-contacts-org': orgId } }, { orgId })\n .then((data) => {\n if (cancelled) return\n const modes = (data as { modes?: Record<string, boolean> | null })?.modes ?? null\n setEntitled(modes)\n })\n .catch(() => {\n /* entitlements unavailable — single-mode pill stands */\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch, me, meLoaded, orgId])\n\n const options = MODE_DEFS.filter((m) => entitled?.[m.id])\n // Resolution order: a registry pin (mode-scoped app) wins outright → then the\n // user's selection (if the org is still entitled to it) → the first entitled\n // mode → the app's fallback. Entitlements are async, so before they land the\n // pin/fallback holds the pill's shape (no layout shift).\n const pinned = pinnedModeId ? MODE_DEFS.find((m) => m.id === pinnedModeId) ?? null : null\n const selected = selectedModeId\n ? options.find((m) => m.id === selectedModeId) ?? null\n : null\n const current =\n pinned ??\n selected ??\n options[0] ??\n MODE_DEFS.find((m) => m.id === fallbackModeId) ??\n MODE_DEFS[0]\n const suffix = orgId ? `?org=${orgId}` : ''\n\n return {\n label: current.label,\n icon: current.icon,\n // Left-Navigation §7 / Reference/UI-Platform: always the row of three icon\n // buttons. A mode the organization does not hold is shown dimmed and not\n // selectable, never hidden. Before entitlements land only the current mode\n // reads as available (no layout shift, nothing clickable it shouldn't be).\n options: MODE_DEFS.map((o) => ({\n id: o.id,\n label: o.label,\n icon: o.icon,\n available: entitled ? Boolean(entitled[o.id]) || o.id === current.id : o.id === current.id,\n })),\n onSelect:\n options.length > 0\n ? (id: string) => {\n const def = MODE_DEFS.find((m) => m.id === id)\n if (!def || !entitled?.[def.id]) return\n // Remember the choice BEFORE navigating so the destination app —\n // and every app after it — opens in the mode the user picked.\n setSelectedModeId(id)\n try {\n localStorage.setItem(MODE_STORAGE_KEY, id)\n } catch {\n /* storage unavailable */\n }\n // Env-aware: the two VRM-core dashboards are baked with the prod\n // base at module load; on a staging app rewrite it to the staging\n // core so a mode switch stays in staging (petition mode is a fully\n // absolute URL and is left untouched by the replace).\n const href = def.href.replace(CORE_BASE_URL, getCoreBaseUrl())\n const sep = href.includes('?') ? '&' : '?'\n window.location.assign(\n def.orgQuery && suffix ? `${href}${sep}${suffix.slice(1)}` : href,\n )\n }\n : undefined,\n }\n}\n\n// The one-component app frame (see ./frame.tsx). Re-exported here so apps have\n// a single import surface: `@the-portland-company/shell/app-chrome`.\nexport {\n PolitogyAppFrame,\n POLITOGY_APPS,\n type PolitogyAppKey,\n type PolitogyAppMode,\n type PolitogyAppSession,\n type PolitogyBuildMeta,\n type PolitogyFrameData,\n type PolitogyFrameGrant,\n type PolitogyGrantedFrame,\n} from './frame'\n\n// The boot-screen surface (Specs/Loading-Screen), mounted by PolitogyAppFrame.\n// Re-exported so an app with a real pipeline can type its `bootProgress` prop.\nexport { LoadingScreen, type BootProgress, type BootStageId, type BootPhase } from './loading-screen'\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/topbarIconSlot.ts","../src/lib/brandGlyphs.tsx","../src/lib/deprecation.ts","../src/native/orgFilter.ts","../src/active-org.ts","../src/nav-preference.ts","../src/speculation/emitRules.ts","../src/speculation/SpeculationRulesScript.tsx","../src/notifications/adapter.ts","../src/native/chromeActions.tsx","../src/native/standardNavIcons.ts","../src/native/standardNav.ts","../src/native/index.tsx","../src/lib/breadcrumbs.ts","../src/lib/identity.ts","../src/logout-signal.ts","../src/mode-preference.ts","../src/app-chrome/loading-screen.tsx","../src/lib/brandAssets.ts","../src/app-chrome/frame.tsx","../src/app-chrome/index.tsx"],"names":["useState","useEffect","FiBatteryCharging","FiBattery","FiZap","FiGrid","FiBell","FiAlertTriangle","FiAlertCircle","FiLifeBuoy","FiHelpCircle","FiMoon","FiSun","FiInfo","FiMail","FiMessageSquare","FiSettings","FiUser","useMemo","useSyncExternalStore","jsxs","jsx","createContext","useRef","useContext","Fragment","lowFuelHintVisible","useCallback","createPortal","LuHouse","LuUsers","LuMail","LuMessageSquare","LuLayoutDashboard","LuActivity","LuLifeBuoy","LuLayoutGrid","LuList","LuUpload","LuPencil","LuFileText","LuSend","LuClock","LuUser","LuChartColumn","LuBriefcase","LuSettings","LuCreditCard","LuDollarSign","LuShare2","LuPhone","LuMap","LuMapPin","LuTarget","LuFlag","LuUsersRound","LuMousePointerClick","LuClipboardList","LuCircleUser","LuCrosshair","LuLandmark","LuChartNoAxesColumn","LuDoorOpen","LuSignpost","clsx","trail","pathname","createDevNotesClient","DevNotesProvider","DevNotesTaskListModal","DevNotesOverlay","DevNotesMenu","LuNotebookPen","LuContactRound","LuMegaphone","LuFilePenLine"],"mappings":"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","file":"app-chrome.cjs","sourcesContent":["import { useEffect, useState } from 'react'\n\n/**\n * The six canonical top-bar action slots (Reference/Global-Rules v9 → top-bar\n * icons). Each slot's GLYPH is unique and comes from the Brand API\n * `topbarIcons.items.*` tokens, exposed as `--topbar-icon-<slot>` CSS vars\n * whose value is the brand-icon NAME. Every OTHER property — size, gap, color,\n * hover, selected — is universal across all six slots.\n */\nexport type TopBarIconSlot =\n | 'comms-fuel'\n | 'apps'\n | 'notifications'\n | 'alerts'\n | 'support'\n | 'dark-mode'\n\n/**\n * Reads the glyph NAME for a slot from its `--topbar-icon-<slot>` CSS var.\n *\n * Runs in an effect because the Brand stylesheet is appended to <head> at\n * runtime (Global Rules forbids baking it into the build), so the var is not\n * resolvable during SSR or the first synchronous render. The MutationObserver\n * re-reads once the stylesheet lands so the glyph upgrades from the caller's\n * fallback without a reload.\n *\n * Returns null when the slot has no Brand glyph — callers render their own\n * fallback icon in that case.\n */\nexport function useTopBarIconSlotGlyph(slot: TopBarIconSlot): string | null {\n const [name, setName] = useState<string | null>(null)\n\n useEffect(() => {\n if (typeof window === 'undefined') return\n\n const read = () => {\n const raw = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(`--topbar-icon-${slot}`)\n .trim()\n // Brand may emit the name quoted (e.g. \"bell\"); strip the quotes.\n .replace(/^['\"]|['\"]$/g, '')\n setName(raw.length > 0 ? raw : null)\n }\n\n read()\n\n const observer = new MutationObserver(read)\n observer.observe(document.head, { childList: true, subtree: true })\n return () => observer.disconnect()\n }, [slot])\n\n return name\n}\n\n/** Path to a brand-icon SVG in the consuming app's public dir. */\nexport function brandIconSrc(name: string, basePath = '/brand/icons/') {\n return `${basePath}${name}.svg`\n}\n","import type { ComponentType } from 'react'\nimport {\n FiAlertCircle,\n FiBattery,\n FiBatteryCharging,\n FiAlertTriangle,\n FiBell,\n FiGrid,\n FiHelpCircle,\n FiInfo,\n FiLifeBuoy,\n FiMail,\n FiMessageSquare,\n FiMoon,\n FiSettings,\n FiSun,\n FiUser,\n FiZap,\n} from 'react-icons/fi'\n\nexport type GlyphComponent = ComponentType<{ size?: number | string; className?: string }>\n\n/**\n * Brand-glyph registry: maps the icon NAME the Brand API emits (e.g.\n * `--topbar-icon-comms-fuel: bolt`) to a component.\n *\n * These names are Feather/Lucide icon names, NOT asset filenames — there is no\n * `/brand/icons/<name>.svg` for them in any app, and treating them as URLs\n * renders a broken image. Resolving them against the icon library the shell\n * already depends on keeps every app consistent with zero vendored assets.\n *\n * Aliases are included where Brand and Feather disagree on a name (`bolt` vs\n * `zap`, `life-buoy` vs `life-ring`).\n */\nconst GLYPHS: Record<string, GlyphComponent> = {\n // Communications Fuel reads as a LEVEL, so its glyph is a battery. `bolt`/\n // `zap` stay mapped for older Brand values.\n 'battery-charging': FiBatteryCharging,\n battery: FiBattery,\n fuel: FiBatteryCharging,\n bolt: FiZap,\n zap: FiZap,\n grid: FiGrid,\n apps: FiGrid,\n bell: FiBell,\n notification: FiBell,\n 'alert-triangle': FiAlertTriangle,\n alert: FiAlertTriangle,\n 'alert-circle': FiAlertCircle,\n 'life-buoy': FiLifeBuoy,\n 'life-ring': FiLifeBuoy,\n support: FiLifeBuoy,\n 'help-circle': FiHelpCircle,\n moon: FiMoon,\n sun: FiSun,\n info: FiInfo,\n mail: FiMail,\n 'message-square': FiMessageSquare,\n settings: FiSettings,\n user: FiUser,\n}\n\n/**\n * Resolve a Brand glyph name to a component. Returns null for an unknown name\n * so the caller renders its own fallback — an unrecognized token must never\n * produce a broken or empty icon.\n */\nexport function resolveBrandGlyph(name: string | null | undefined): GlyphComponent | null {\n if (!name) return null\n return GLYPHS[name.trim().toLowerCase()] ?? null\n}\n\n/** Names the registry knows — exported for tests and tooling. */\nexport const KNOWN_BRAND_GLYPHS = Object.keys(GLYPHS)\n","// One-time console warnings for retired shell API, in development only.\n\nconst warned = new Set<string>()\n\nfunction isDev(): boolean {\n try {\n return typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n } catch {\n return false\n }\n}\n\n/** Warn once per `key` in dev; silent in production builds. */\nexport function warnDeprecated(key: string, message: string): void {\n if (!isDev() || warned.has(key)) return\n warned.add(key)\n console.warn(`[@the-portland-company/shell] ${message}`)\n}\n\n/** Test hook: forget which warnings have fired. */\nexport function resetDeprecationWarnings(): void {\n warned.clear()\n}\n","/**\n * Organization-list filtering for the sidebar org selector.\n *\n * Accounts that belong to many organizations (a consultant managing a dozen\n * committees) got a 288 px panel showing seven rows and a near-invisible macOS\n * scrollbar — measured 2026-09-04: \"I cannot select other organizations\".\n * The panel now grows with the viewport and, above this threshold, gains a\n * type-to-filter box so any org is one keystroke away.\n */\nexport const ORG_FILTER_THRESHOLD = 8\n\nexport type FilterableOrg = { id: string; name: string | null }\n\n/** Case- and accent-insensitive substring match on the org name (or id prefix). */\nexport function filterOrgs<T extends FilterableOrg>(orgs: readonly T[], query: string): T[] {\n const q = normalize(query)\n if (!q) return [...orgs]\n return orgs.filter((o) => normalize(o.name ?? '').includes(q) || o.id.toLowerCase().startsWith(q))\n}\n\nexport function shouldShowOrgFilter(count: number): boolean {\n return count > ORG_FILTER_THRESHOLD\n}\n\nfunction normalize(s: string): string {\n return s\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .trim()\n}\n","// Universal active-organization selection — the ONE cross-app contract.\n//\n// A user belongs to many orgs; ONE active-org choice must follow them across\n// every Politogy app + subdomain so all apps resolve the SAME org (and campaign\n// apps don't land on a rel-only org and lock themselves). Layers cooperate,\n// mirroring the theme-preference contract:\n// 1. URL `?org=<uuid>` — the authoritative per-request selector. The shared\n// chrome stamps it onto every route so it is bookmarkable + shareable, and\n// each app forwards it to the chrome API as `x-contacts-org`.\n// 2. `.politogyvrm.com` cookie `politogy_active_org` — cross-subdomain vehicle\n// (auth session cookies are host-only) that remembers the LAST USED org so\n// a bare URL in the next app opens on the same org.\n//\n// The stored/most-authoritative value is the FULL org UUID: contacts-api\n// (auth/vrmMembership.selectRequestedMembership) matches the selector by EXACT\n// id first, then falls back to a short suffix that can COLLIDE across a user's\n// orgs — so the full UUID is the only collision-free selector.\n//\n// Server-safe (no 'use client'): constants/resolve helpers are importable from\n// server layouts; the cookie read/write helpers no-op on the server.\n\nexport const ACTIVE_ORG_COOKIE = 'politogy_active_org'\nexport const ACTIVE_ORG_QUERY_PARAM = 'org'\n\n// Loose UUID shape check — we only ever store ids that came from the user's own\n// authoritative membership list, so this just rejects obvious garbage.\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nexport function isOrgId(v: unknown): v is string {\n return typeof v === 'string' && UUID_RE.test(v.trim())\n}\n\n/**\n * Read the shared active-org cookie (browser only; null on server or unset).\n * @deprecated v2 apps read the org from the token claims (`orgClaimsFromToken`).\n * The cookie stays written during rollout for apps not yet on the token path.\n */\nexport function readActiveOrgCookie(): string | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${ACTIVE_ORG_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isOrgId(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Write the cross-subdomain cookie with the SAME scoping rules as the theme\n// cookie: on a *.politogyvrm.com host scope to the parent domain so every app\n// subdomain reads it; on any other host (localhost, *.pages.dev preview) fall\n// back to a host-only cookie. 1-year, SameSite=Lax, Secure on https.\nexport function writeActiveOrgCookie(orgId: string): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n if (!isOrgId(orgId)) return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${ACTIVE_ORG_COOKIE}=${encodeURIComponent(\n orgId,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/**\n * Read the `?org=` selector from a URL search string (full UUID only). Accepts a\n * `location.search`-style string or a full URL.\n */\nexport function readActiveOrgFromUrl(search: string | null | undefined): string | null {\n if (!search) return null\n try {\n const qs = search.includes('?') ? search.slice(search.indexOf('?') + 1) : search\n const v = new URLSearchParams(qs).get(ACTIVE_ORG_QUERY_PARAM)\n return isOrgId(v) ? v : null\n } catch {\n return null\n }\n}\n\n/**\n * Resolve the active org with the cross-app precedence:\n * 1. `?org=<uuid>` in the current URL (explicit per-request selector)\n * 2. the `.politogyvrm.com` cookie (last used, cross-subdomain)\n * 3. null → let the app fall back to the chrome-API default (earliest-joined)\n * Pass `search` on the server (from the request URL); it defaults to\n * `window.location.search` in the browser.\n * @deprecated v2 apps use the token `org_id` claim plus `readOrgSelectorFromUrl`\n * as a per-tab override only.\n */\nexport function resolveActiveOrg(search?: string | null): string | null {\n const fromUrl = readActiveOrgFromUrl(\n search ?? (typeof window !== 'undefined' ? window.location.search : null),\n )\n if (fromUrl) return fromUrl\n return readActiveOrgCookie()\n}\n\n/** The canonical `?org=` query fragment for a full org id (no leading `?`/`&`). */\nexport function activeOrgParam(orgId: string | null | undefined): string {\n return isOrgId(orgId) ? `${ACTIVE_ORG_QUERY_PARAM}=${orgId}` : ''\n}\n\n/**\n * Return `url` with `?org=<uuid>` set/replaced. Used by the shared chrome to\n * stamp the active org onto every route so it is always present in the address\n * bar. Leaves the URL unchanged when `orgId` is not a valid id.\n */\nexport function withActiveOrgParam(url: string, orgId: string | null | undefined): string {\n if (!isOrgId(orgId)) return url\n try {\n // Support both absolute and relative URLs.\n const base = typeof window !== 'undefined' ? window.location.origin : 'https://politogyvrm.com'\n const u = new URL(url, base)\n u.searchParams.set(ACTIVE_ORG_QUERY_PARAM, orgId as string)\n // Preserve relative form when the input was relative.\n return /^https?:\\/\\//i.test(url) ? u.toString() : `${u.pathname}${u.search}${u.hash}`\n } catch {\n return url\n }\n}\n\n// ---------------------------------------------------------------------------\n// v2: auth-owned active org (Global-Rules v38 \"Auth / Active Organization\",\n// UI-Platform v46 \"URL state\"). The IdP owns the shared active org on the SSO\n// session; tokens carry `org_id` (full uuid) + `org_role`. The URL carries the\n// 7-char `org_id` tail as a PER-TAB override only: it never changes the shared\n// active org. Full uuids and the legacy 6-char tail are accepted during rollout.\n// ---------------------------------------------------------------------------\n\nexport const ORG_ID_QUERY_PARAM = 'org_id'\nexport const ORG_ID_TAIL_LENGTH = 7\nconst LEGACY_ORG_TAIL_LENGTH = 6\nconst TAIL_RE = /^[0-9a-f]{6,7}$/i\n\nconst AUTH_BASE_URL = 'https://auth.politogyvrm.com'\nconst AUTH_BASE_URL_STAGING = 'https://auth-staging.politogyvrm.com'\n\n/** The URL form of an org id: the last 7 chars of the uuid, lower case. */\nexport function orgIdTail(orgId: string | null | undefined): string | null {\n return isOrgId(orgId) ? (orgId as string).trim().toLowerCase().slice(-ORG_ID_TAIL_LENGTH) : null\n}\n\n/** A full uuid, the 7-char tail, or the legacy 6-char tail. */\nexport function isOrgSelector(v: unknown): v is string {\n return typeof v === 'string' && (UUID_RE.test(v.trim()) || TAIL_RE.test(v.trim()))\n}\n\n/**\n * Resolve a selector against the user's own org list: exact uuid first, then a\n * unique 7-char tail, then a unique 6-char tail. Ambiguous or no match → null\n * (the IdP selector rules, so the shell never picks an org the IdP would not).\n */\nexport function matchOrgSelector<T extends { id: string }>(\n selector: string | null | undefined,\n orgs: readonly T[],\n): T | null {\n if (!isOrgSelector(selector)) return null\n const sel = selector.trim().toLowerCase()\n if (UUID_RE.test(sel)) return orgs.find((o) => o.id.toLowerCase() === sel) ?? null\n if (sel.length !== ORG_ID_TAIL_LENGTH && sel.length !== LEGACY_ORG_TAIL_LENGTH) return null\n const hits = orgs.filter((o) => o.id.toLowerCase().endsWith(sel))\n return hits.length === 1 ? hits[0] : null\n}\n\n/**\n * Read the per-tab org override from a URL: `org_id` (spec), else the legacy\n * `org`. Returns the raw selector (uuid or tail), or null. Never a source for\n * the shared active org.\n */\nexport function readOrgSelectorFromUrl(search: string | null | undefined): string | null {\n if (!search) return null\n try {\n const qs = search.includes('?') ? search.slice(search.indexOf('?') + 1) : search\n const params = new URLSearchParams(qs)\n for (const key of [ORG_ID_QUERY_PARAM, ACTIVE_ORG_QUERY_PARAM]) {\n const v = params.get(key)\n if (isOrgSelector(v)) return v.trim().toLowerCase()\n }\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Return `url` with `org_id=<7-char tail>` set and any legacy `org=` removed.\n * Leaves the URL unchanged when `orgId` is not a full uuid.\n */\nexport function withOrgIdParam(url: string, orgId: string | null | undefined): string {\n const tail = orgIdTail(orgId)\n if (!tail) return url\n try {\n const base = typeof window !== 'undefined' ? window.location.origin : 'https://politogyvrm.com'\n const u = new URL(url, base)\n u.searchParams.delete(ACTIVE_ORG_QUERY_PARAM)\n u.searchParams.set(ORG_ID_QUERY_PARAM, tail)\n return /^https?:\\/\\//i.test(url) ? u.toString() : `${u.pathname}${u.search}${u.hash}`\n } catch {\n return url\n }\n}\n\nexport type OrgClaims = { orgId: string; orgRole: string | null }\n\n/** Pick `org_id` / `org_role` out of a token claim set. */\nexport function orgClaimsFrom(claims: unknown): OrgClaims | null {\n if (!claims || typeof claims !== 'object') return null\n const c = claims as { org_id?: unknown; org_role?: unknown }\n if (!isOrgId(c.org_id)) return null\n return {\n orgId: (c.org_id as string).trim().toLowerCase(),\n orgRole: typeof c.org_role === 'string' ? c.org_role : null,\n }\n}\n\n/**\n * Read `org_id` / `org_role` from a JWT payload WITHOUT verifying it. For\n * display and routing only: the app server verifies the token (JWKS) and every\n * authorization decision keys on the verified claim, never on this.\n */\nexport function orgClaimsFromToken(token: string | null | undefined): OrgClaims | null {\n if (typeof token !== 'string') return null\n const part = token.split('.')[1]\n if (!part) return null\n try {\n const b64 = part.replace(/-/g, '+').replace(/_/g, '/')\n const padded = b64 + '='.repeat((4 - (b64.length % 4)) % 4)\n const json =\n typeof atob === 'function'\n ? decodeURIComponent(\n Array.from(atob(padded), (ch) => '%' + ch.charCodeAt(0).toString(16).padStart(2, '0')).join(''),\n )\n : ''\n return orgClaimsFrom(JSON.parse(json))\n } catch {\n return null\n }\n}\n\n/** The IdP base for the current environment (staging host → staging IdP). */\nexport function authBaseUrl(): string {\n if (typeof window !== 'undefined' && window.location.hostname.toLowerCase().includes('staging')) {\n return AUTH_BASE_URL_STAGING\n }\n return AUTH_BASE_URL\n}\n\nexport class ActiveOrgSwitchError extends Error {\n constructor(\n readonly status: number,\n message: string,\n ) {\n super(message)\n this.name = 'ActiveOrgSwitchError'\n }\n}\n\n/**\n * Switch the SHARED active org on the IdP: `POST {auth}/api/active-org`. The\n * IdP checks membership against VRM Core and updates the SSO session; the\n * caller then re-exchanges (server) for tokens carrying the new `org_id`.\n * Also mirrors the legacy cookie so apps not yet on v2 follow the switch.\n * Throws `ActiveOrgSwitchError` (403 = not a member, 401 = no SSO session).\n */\nexport async function switchActiveOrg(\n orgId: string,\n opts: { authBaseUrl?: string; fetch?: typeof fetch } = {},\n): Promise<OrgClaims> {\n if (!isOrgId(orgId)) throw new ActiveOrgSwitchError(400, 'org_id must be a full uuid')\n const doFetch = opts.fetch ?? fetch\n const res = await doFetch(`${opts.authBaseUrl ?? authBaseUrl()}/api/active-org`, {\n method: 'POST',\n credentials: 'include',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ org_id: orgId }),\n })\n if (!res.ok) {\n let msg = `active-org switch failed (${res.status})`\n try {\n const body = (await res.json()) as { error?: string }\n if (body?.error) msg = body.error\n } catch {\n /* no body */\n }\n throw new ActiveOrgSwitchError(res.status, msg)\n }\n const claims = orgClaimsFrom(await res.json().catch(() => null))\n if (!claims) throw new ActiveOrgSwitchError(502, 'active-org switch returned no org_id')\n writeActiveOrgCookie(claims.orgId)\n return claims\n}\n\n/**\n * URL-sync rule for the address-bar org selector. Returns the new href, or\n * null when nothing should be written. A bare URL (no `org_id`, no legacy\n * `org`) stays bare: the shell must never inject `org_id` on its own, because\n * a self-injected selector then acts as a per-tab override and beats the token\n * org and the cross-app `politogy_active_org` trigger. Only a selector the user\n * brought (or a real switch put there) is canonicalized to the current org.\n */\nexport function syncOrgIdInUrl(href: string, orgId: string | null | undefined): string | null {\n const tail = orgIdTail(orgId)\n if (!tail) return null\n let u: URL\n try {\n u = new URL(href)\n } catch {\n return null\n }\n const hasLegacy = u.searchParams.has(ACTIVE_ORG_QUERY_PARAM)\n const current = u.searchParams.get(ORG_ID_QUERY_PARAM)\n if (!hasLegacy && current === null) return null\n if (!hasLegacy && current === tail) return null\n u.searchParams.delete(ACTIVE_ORG_QUERY_PARAM)\n u.searchParams.set(ORG_ID_QUERY_PARAM, tail)\n return u.toString()\n}\n","// Universal navigation-display preference — the same cross-app contract as the\n// theme (see ./theme-preference, which this deliberately mirrors).\n//\n// The user's choice of how navigation renders (Menu / Tabs / Both) follows the\n// authenticated user across every Politogy app + subdomain. Three layers:\n// 1. VRM Core `profiles.nav_display_preference` — source of truth, persisted\n// via the chrome API (`PATCH me/preferences { navDisplay }`) and read back\n// from `GET me` (`navDisplay`).\n// 2. `.politogyvrm.com` cookie `politogy_nav_display` — the cross-subdomain\n// vehicle (app session cookies are host-only, and so is localStorage).\n// 3. localStorage — same-app fast reads and cross-tab `storage` events.\n//\n// Before this existed the preference lived ONLY in localStorage under\n// `vrm.navDisplay`, which is per-ORIGIN: every app subdomain kept its own copy\n// and a freshly opened app booted the default, so the setting appeared not to\n// hold when moving between apps. The legacy key is still read as a fallback so\n// an existing local choice survives the upgrade.\n//\n// Server-safe (no 'use client'): layouts may import NAV_DISPLAY_PREPAINT_SCRIPT.\n\nexport type NavDisplayPreference = 'menu' | 'tabs' | 'both'\n\n// One key for BOTH the localStorage store and the cross-subdomain cookie, so a\n// choice in one app is the same key in the next.\nexport const NAV_DISPLAY_STORAGE_KEY = 'politogy_nav_display'\nexport const NAV_DISPLAY_COOKIE = 'politogy_nav_display'\n\n/** Pre-0.37 host-only key. Read for migration; never written. */\nexport const LEGACY_NAV_DISPLAY_KEY = 'vrm.navDisplay'\n\nexport const NAV_DISPLAY_DEFAULT: NavDisplayPreference = 'both'\n\nconst VALID: readonly NavDisplayPreference[] = ['menu', 'tabs', 'both']\n\nexport function isNavDisplayPreference(v: unknown): v is NavDisplayPreference {\n return typeof v === 'string' && (VALID as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readNavDisplayCookie(): NavDisplayPreference | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isNavDisplayPreference(v) ? v : null\n } catch {\n return null\n }\n}\n\n// Same host-aware scoping as the theme cookie: parent domain on\n// *.politogyvrm.com so every app subdomain reads it, host-only elsewhere\n// (localhost, *.pages.dev preview) because browsers silently drop a mismatched\n// Domain attribute. 1-year, SameSite=Lax, Secure on https.\nexport function writeNavDisplayCookie(pref: NavDisplayPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${NAV_DISPLAY_COOKIE}=${encodeURIComponent(\n pref,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/** Read the local store, falling back to the legacy host-only key. */\nexport function readNavDisplayLocal(): NavDisplayPreference | null {\n if (typeof localStorage === 'undefined') return null\n try {\n const current = localStorage.getItem(NAV_DISPLAY_STORAGE_KEY)\n if (isNavDisplayPreference(current)) return current\n const legacy = localStorage.getItem(LEGACY_NAV_DISPLAY_KEY)\n return isNavDisplayPreference(legacy) ? legacy : null\n } catch {\n return null\n }\n}\n\nexport function writeNavDisplayLocal(pref: NavDisplayPreference): void {\n if (typeof localStorage === 'undefined') return\n try {\n localStorage.setItem(NAV_DISPLAY_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n\n/** Boot precedence: cookie → localStorage (incl. legacy) → default. */\nexport function resolveNavDisplay(): NavDisplayPreference {\n return readNavDisplayCookie() ?? readNavDisplayLocal() ?? NAV_DISPLAY_DEFAULT\n}\n\n// Inline pre-paint script — optional, and the mirror of THEME_PREPAINT_SCRIPT.\n// Nav display has no paint-blocking visual (the frame is client-rendered), but\n// seeding localStorage from the cookie before hydration keeps the first render\n// on the synced value instead of the default. Self-contained and silent.\nexport const NAV_DISPLAY_PREPAINT_SCRIPT = `(function(){try{\nvar KEY=${JSON.stringify(NAV_DISPLAY_STORAGE_KEY)};\nvar VALID=[\"menu\",\"tabs\",\"both\"];\nfunction fromCookie(){try{var m=document.cookie.match(/(?:^|;\\\\s*)${NAV_DISPLAY_COOKIE}=([^;]+)/);return m?decodeURIComponent(m[1]):null;}catch(e){return null;}}\nvar cookie=fromCookie();\nif(cookie&&VALID.indexOf(cookie)!==-1){var ls=null;try{ls=localStorage.getItem(KEY);}catch(e){}\nif(cookie!==ls){try{localStorage.setItem(KEY,cookie);}catch(e){}}}\n}catch(e){}})();`\n\n// ---------------------------------------------------------------------------\n// Rail expand preference — Left-Navigation §11.6: below `md` the rail\n// collapses to the 64px icon rail; \"the user can also collapse and expand it;\n// the choice is remembered per user\". Same cookie + localStorage layers as the\n// nav-display preference above (no server column yet), so the choice follows\n// the user across every app subdomain and survives reloads. Only an explicit\n// Expand / Collapse writes it; a route change that closes the overlay does not.\n// ---------------------------------------------------------------------------\n\nexport type RailPreference = 'expanded' | 'collapsed'\n\nexport const RAIL_STORAGE_KEY = 'politogy_rail'\nexport const RAIL_COOKIE = 'politogy_rail'\nexport const RAIL_DEFAULT: RailPreference = 'collapsed'\n\nexport function isRailPreference(v: unknown): v is RailPreference {\n return v === 'expanded' || v === 'collapsed'\n}\n\nexport function readRailPreference(): RailPreference {\n if (typeof document !== 'undefined') {\n try {\n const m = document.cookie.match(new RegExp(`(?:^|;\\\\s*)${RAIL_COOKIE}=([^;]+)`))\n const v = m ? decodeURIComponent(m[1]) : null\n if (isRailPreference(v)) return v\n } catch {\n /* ignore */\n }\n }\n if (typeof localStorage !== 'undefined') {\n try {\n const v = localStorage.getItem(RAIL_STORAGE_KEY)\n if (isRailPreference(v)) return v\n } catch {\n /* ignore */\n }\n }\n return RAIL_DEFAULT\n}\n\nexport function writeRailPreference(pref: RailPreference): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n try {\n document.cookie = `${RAIL_COOKIE}=${pref}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n } catch {\n /* ignore */\n }\n try {\n localStorage.setItem(RAIL_STORAGE_KEY, pref)\n } catch {\n /* storage unavailable */\n }\n}\n","import type { AppRegistryEntry } from '../types'\nimport type { NavItem } from '../native/index'\n\n/**\n * Build a Speculation Rules JSON payload that prerenders other apps in the\n * registry on moderate eagerness. Returns null when there are no eligible\n * other apps to prerender (e.g., this is the only app in the registry).\n *\n * @deprecated Legacy `AppRegistryEntry[]`-based registry is unused by any\n * current consumer. Cross-app sidebar nav now ships real `NavItem[]` trees\n * (`standardPolitogyNav`) — use `buildNavSpeculationRules` instead, which this\n * now delegates to.\n *\n * The host app is expected to render this as\n * `<script type=\"speculationrules\">{json}</script>` in <head> at runtime.\n */\nexport function buildSpeculationRules(\n currentApp: string,\n registry: AppRegistryEntry[],\n): string | null {\n const others = registry.filter(\n (entry) => entry.id !== currentApp && entry.visible !== false,\n )\n if (others.length === 0) return null\n const payload = {\n prerender: [\n {\n urls: others.map((entry) => entry.path),\n eagerness: 'moderate' as const,\n },\n ],\n }\n return JSON.stringify(payload)\n}\n\n/**\n * Labels the shell will never prerender or prefetch, even if a consumer's nav\n * tree somehow carries an `href` for them (sign-out is normally a footer\n * `onClick`, never a `NavItem.href` — this is a second guard, not the primary\n * one). Case-insensitive substring match against the row's label.\n */\nconst DESTRUCTIVE_LABEL_PATTERNS = ['sign out', 'signout', 'log out', 'logout', 'delete']\n\n/** URL substrings that mark a link as destructive/non-idempotent regardless of label. */\nconst DESTRUCTIVE_PATH_PATTERNS = ['/signout', '/sign-out', '/logout', '/log-out']\n\nfunction isDestructive(item: { label: string; href?: string }): boolean {\n const label = item.label.toLowerCase()\n if (DESTRUCTIVE_LABEL_PATTERNS.some((p) => label.includes(p))) return true\n const href = (item.href ?? '').toLowerCase()\n return DESTRUCTIVE_PATH_PATTERNS.some((p) => href.includes(p))\n}\n\n/**\n * Walk a `NavItem[]` tree (as produced by `standardPolitogyNav`) and collect\n * every absolute, cross-origin, non-destructive, GET-safe link — the\n * candidate set for prerender/prefetch. Sections and action rows (`onClick`,\n * no `href`) are skipped; children are walked too (sub-menu rows like\n * \"Command Center\" / \"New Poll\" are real cross-app destinations).\n */\nexport function collectSiblingAppUrls(items: NavItem[], currentOrigin: string): string[] {\n const urls = new Set<string>()\n const walk = (list: NavItem[]) => {\n for (const item of list) {\n if (item.kind === 'section') continue\n if (item.href && !isDestructive(item)) {\n try {\n const url = new URL(item.href, currentOrigin)\n if (url.origin !== currentOrigin && /^https?:$/.test(url.protocol)) {\n urls.add(url.href)\n }\n } catch {\n // Malformed href — skip rather than throw during nav render.\n }\n }\n if (item.children?.length) walk(item.children)\n }\n }\n walk(items)\n return Array.from(urls)\n}\n\nexport interface NavSpeculationRules {\n prerender: [{ source: 'list'; urls: string[]; eagerness: 'moderate' }]\n}\n\n/**\n * Build the Speculation Rules payload for a consumer's real sidebar nav tree:\n * every sibling `*.politogyvrm.com` app link, `eagerness: \"moderate\"` (the\n * browser's own heuristic — prerender starts on hover/pointerdown of a\n * matching `<a>`, not on page load). Sign-out and other destructive rows are\n * excluded by `collectSiblingAppUrls`. Returns `null` when there is nothing\n * to speculate on (e.g., an empty or single-app tree).\n *\n * Each target origin must opt in by sending\n * `Supports-Loading-Mode: credentialed-prerender` on its responses, per the\n * Speculation Rules cross-origin prerender contract — without it the browser\n * silently falls back to a normal navigation. (Other apps are adding this\n * header separately.)\n */\nexport function buildNavSpeculationRules(\n items: NavItem[],\n currentOrigin: string = typeof window !== 'undefined' ? window.location.origin : '',\n): NavSpeculationRules | null {\n const urls = collectSiblingAppUrls(items, currentOrigin)\n if (urls.length === 0) return null\n return {\n prerender: [{ source: 'list', urls, eagerness: 'moderate' }],\n }\n}\n","import { useEffect, useMemo } from 'react'\nimport type { NavItem } from '../native/index'\nimport { buildNavSpeculationRules, collectSiblingAppUrls } from './emitRules'\n\nconst SCRIPT_ID = 'politogy-speculation-rules'\nconst PREFETCH_ATTR = 'data-politogy-speculation-prefetch'\n\n/**\n * Renders the cross-app Speculation Rules `<script>` for the current\n * consumer's sidebar nav tree, and mounts in every `NavAppShell` — so it is\n * never an opt-in an app has to remember. Browsers that support Speculation\n * Rules prerender a sibling `*.politogyvrm.com` app the moment the user\n * hovers or pointers-down on its sidebar link (`eagerness: \"moderate\"`);\n * browsers that don't fall back, after the page goes idle, to plain\n * `<link rel=\"prefetch\">` tags for the same URLs, so the next click is still\n * warmed by a DNS/TLS/HTML fetch even without a prerendered document.\n *\n * Each sibling origin must send `Supports-Loading-Mode:\n * credentialed-prerender` on its responses for the prerender to actually\n * happen while the user is authenticated (cross-origin prerender is opt-in\n * on the destination). Without it, browsers degrade this to a normal\n * navigation — the hover/click still works, it's just not pre-warmed.\n *\n * Renders nothing visible; this is a side-effecting `<script>` injector.\n */\nexport function SpeculationRulesScript({ items }: { items: NavItem[] }) {\n const origin = typeof window !== 'undefined' ? window.location.origin : ''\n const rules = useMemo(() => buildNavSpeculationRules(items, origin), [items, origin])\n const json = rules ? JSON.stringify(rules) : null\n\n // Native Speculation Rules — covers the hover/pointerdown prerender case in\n // supporting browsers (Chromium). Declarative: no listeners needed, the\n // browser applies its own \"moderate\" heuristic to matching <a> elements.\n useEffect(() => {\n if (!json || typeof document === 'undefined') return\n let el = document.getElementById(SCRIPT_ID) as HTMLScriptElement | null\n if (!el) {\n el = document.createElement('script')\n el.id = SCRIPT_ID\n el.type = 'speculationrules'\n document.head.appendChild(el)\n }\n el.textContent = json\n return () => {\n // Leave the tag in place across route changes within the same app —\n // only strip it if this effect instance's app unmounts entirely with no\n // sibling to replace it.\n }\n }, [json])\n\n // Idle-prefetch fallback for browsers without Speculation Rules support\n // (or where the destination hasn't sent the opt-in header): warm the\n // connection/document via <link rel=\"prefetch\"> once the main thread is\n // idle, so it never competes with first-paint work.\n useEffect(() => {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const supportsSpecRules =\n typeof HTMLScriptElement !== 'undefined' &&\n typeof (HTMLScriptElement as unknown as { supports?: (t: string) => boolean }).supports ===\n 'function' &&\n (HTMLScriptElement as unknown as { supports: (t: string) => boolean }).supports(\n 'speculationrules',\n )\n if (supportsSpecRules) return\n const urls = collectSiblingAppUrls(items, origin)\n if (urls.length === 0) return\n\n const schedule: (cb: () => void) => void =\n typeof (window as unknown as { requestIdleCallback?: (cb: () => void) => void })\n .requestIdleCallback === 'function'\n ? (window as unknown as { requestIdleCallback: (cb: () => void) => void })\n .requestIdleCallback\n : (cb: () => void) => setTimeout(cb, 2000)\n\n const added: HTMLLinkElement[] = []\n schedule(() => {\n for (const url of urls) {\n if (document.querySelector(`link[${PREFETCH_ATTR}][href=\"${url}\"]`)) continue\n const link = document.createElement('link')\n link.rel = 'prefetch'\n link.href = url\n link.setAttribute(PREFETCH_ATTR, '')\n document.head.appendChild(link)\n added.push(link)\n }\n })\n return () => {\n added.forEach((l) => l.remove())\n }\n }, [items, origin])\n\n return null\n}\n","// ---------------------------------------------------------------------------\n// NotificationsAdapter — the contract the shell's single Notifications bell is\n// fed by (Specs/System-Communications §6.3 and §12.2; UI-Platform → top bar).\n//\n// The bell never calls the Comms service directly. Reads and writes go through\n// the same-origin chrome API proxy with the viewer's session, so the Comms\n// `GET /v1/me/notifications` and `POST /v1/me/notifications/:id/{read,archive,\n// resolve}` routes (politogy-comms PR #14) are reached as `me/notifications…`\n// relative to the proxy base. The proxy's session cookie or bearer is what\n// Comms verifies (`getSubject`, OIDC `sub`); the shell never sends a token.\n//\n// Degradation contract: a missing session (401), an absent route (404), a\n// network failure or a malformed body all resolve to an EMPTY feed or `false`.\n// The bell then renders \"all caught up\" rather than an error state, and nothing\n// is thrown into the chrome.\n// ---------------------------------------------------------------------------\n\nimport type { NavChromeFetcher } from '../native/chromeActions'\n\nexport type CommsNotificationKind = 'notification' | 'alert'\n\n/** One row of the bell feed, as the shell reads it (camelCased). */\nexport type CommsNotification = {\n id: string\n kind: CommsNotificationKind\n title: string\n body: string\n icon: string | null\n link: string | null\n readAt: string | null\n orgId: string | null\n createdAt: string | null\n}\n\nexport type NotificationsFeed = {\n /** Alerts first, then notifications, newest first (Comms sorts them). */\n notifications: CommsNotification[]\n /** One badge number: unread notifications plus unresolved alerts (Spec §6.3). */\n badge: number\n}\n\nexport type NotificationsAdapter = {\n /** Read the signed-in viewer's feed, scoped to an org when one is active. */\n list(orgId: string | null): Promise<NotificationsFeed>\n /** Mark one row read. Resolves false on any failure, never throws. */\n markRead(id: string): Promise<boolean>\n /** Archive one row (hides it from the feed). Resolves false on failure. */\n archive(id: string): Promise<boolean>\n /** Resolve one alert. Comms rejects this for non-alert rows. */\n resolve(id: string): Promise<boolean>\n}\n\n/** The empty bell: what every degraded path renders. Always a fresh object. */\nexport function emptyNotificationsFeed(): NotificationsFeed {\n return { notifications: [], badge: 0 }\n}\n\nfunction asString(value: unknown): string | null {\n return typeof value === 'string' ? value : null\n}\n\n/**\n * Shape a raw Comms body into the feed. Tolerant on purpose: unknown keys are\n * ignored, rows without an id are dropped, and archived rows are never shown.\n */\nexport function normalizeNotificationsFeed(raw: unknown): NotificationsFeed {\n if (!raw || typeof raw !== 'object') return emptyNotificationsFeed()\n const body = raw as { notifications?: unknown; badge?: unknown }\n const rows = Array.isArray(body.notifications) ? body.notifications : []\n const notifications: CommsNotification[] = []\n for (const row of rows) {\n if (!row || typeof row !== 'object') continue\n const r = row as Record<string, unknown>\n const id = asString(r.id)\n if (!id || asString(r.archived_at)) continue\n notifications.push({\n id,\n kind: r.kind === 'alert' ? 'alert' : 'notification',\n title: asString(r.title) ?? '',\n body: asString(r.body) ?? '',\n icon: asString(r.icon),\n link: asString(r.link),\n readAt: asString(r.read_at),\n orgId: asString(r.org_id),\n createdAt: asString(r.created_at),\n })\n }\n const badge =\n typeof body.badge === 'number' && Number.isFinite(body.badge)\n ? Math.max(0, Math.floor(body.badge))\n : notifications.filter((n) => n.kind === 'alert' || n.readAt === null).length\n return { notifications, badge }\n}\n\n/**\n * Build the comms-backed adapter over the app's chrome fetcher. A null fetcher\n * (no chrome proxy wired) yields the empty bell with no network activity.\n */\nexport function createCommsNotificationsAdapter(\n fetchJson: NavChromeFetcher | null,\n): NotificationsAdapter {\n const act = async (id: string, action: 'read' | 'archive' | 'resolve'): Promise<boolean> => {\n if (!fetchJson || !id) return false\n try {\n await fetchJson(`me/notifications/${encodeURIComponent(id)}/${action}`, { method: 'POST' })\n return true\n } catch {\n return false\n }\n }\n return {\n async list(orgId) {\n if (!fetchJson) return emptyNotificationsFeed()\n try {\n const query = orgId ? `?org_id=${encodeURIComponent(orgId)}` : ''\n return normalizeNotificationsFeed(await fetchJson(`me/notifications${query}`))\n } catch {\n return emptyNotificationsFeed()\n }\n },\n markRead: (id) => act(id, 'read'),\n archive: (id) => act(id, 'archive'),\n resolve: (id) => act(id, 'resolve'),\n }\n}\n\n/**\n * Map a feed onto the panel's payload shape so the existing bell UI (alert\n * rows, read toggles, badge) renders adapter rows without a second renderer.\n */\nexport function notificationsFeedToPayload(\n feed: NotificationsFeed,\n orgId: string | null,\n): {\n organizationId: string\n alerts: { id: string; title: string; description: string; href: string | null; kind: string; read: boolean }[]\n replies: never[]\n badge: number\n} {\n return {\n organizationId: orgId ?? '',\n alerts: feed.notifications.map((n) => ({\n id: n.id,\n title: n.title,\n description: n.body,\n href: n.link,\n kind: n.kind,\n read: n.readAt !== null,\n })),\n replies: [],\n badge: feed.badge,\n }\n}\n","// ---------------------------------------------------------------------------\n// Native chrome actions — Tailwind-only top-bar widgets (Fuel, Notifications,\n// Support, Navigation-display) backed by the shared chrome API\n// (politogy-contacts-api on Railway). Zero Chakra, zero router, zero fetch\n// opinion: the consuming app injects ONE fetcher via <NavChromeProvider> —\n// typically a same-origin proxy route that attaches its own session's Bearer\n// token server-side — and every widget in every app runs this exact code.\n//\n// Data endpoints (paths are relative; the app's fetcher owns the base URL):\n// GET communications/fuel-status (header x-contacts-org: <core org id>)\n// GET notifications (header x-contacts-org: <core org id>)\n// GET orgs\n// POST support { message }\n//\n// Loading states follow Global-Rules \"Loading & Async States\": the chrome\n// (button, popover frame, labels) always renders; only the VALUE area shows a\n// skeleton shimmer — never a spinner, never a blank panel.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n useSyncExternalStore,\n type ComponentType,\n type ReactNode,\n} from 'react'\nimport { createPortal } from 'react-dom'\n\nimport { useTopBarIconSlotGlyph, type TopBarIconSlot } from '../lib/topbarIconSlot'\nimport { resolveBrandGlyph } from '../lib/brandGlyphs'\nimport {\n createCommsNotificationsAdapter,\n emptyNotificationsFeed,\n notificationsFeedToPayload,\n type NotificationsAdapter,\n} from '../notifications/adapter'\nimport {\n applyThemePreference,\n isThemePreference,\n readThemeCookie,\n writeThemeCookie,\n readPendingThemeChoice,\n markThemeChoicePending,\n clearPendingThemeChoice,\n THEME_STORAGE_KEY,\n type ThemePreference as SharedThemePreference,\n} from '../theme-preference'\n\ntype NavIconLike = ComponentType<{ size?: number; className?: string }>\n\n// ---------------------------------------------------------------------------\n// Core-app deep links. The billing surface lives on the VRM-core app; we would\n// derive its origin from POLITOGY_APPS.vrm, but that registry lives in\n// ../app-chrome which imports THIS module — so pulling it in here would create\n// an import cycle. One local constant instead (kept in step with the registry's\n// `vrm` origin).\n// ---------------------------------------------------------------------------\n\nexport const CORE_APP_ORIGIN = 'https://app.politogyvrm.com'\n/** Text/Email fuel top-up page (SMS Signal + Email Broadcast). */\nexport const CORE_BILLING_PATH = '/organization-settings/subscription-billing/text-email'\nconst CORE_BILLING_URL = `${CORE_APP_ORIGIN}${CORE_BILLING_PATH}`\nconst QUARANTINED_CONTACTS_URL = `https://contacts.politogyvrm.com/duplicates`\n\n/** Specs origin — same env-aware-constant pattern as CORE_APP_ORIGIN. */\nexport const SPECS_ORIGIN = 'https://specs.politogyvrm.com'\n\n/**\n * Stamp the active org onto a cross-app link, the same `?org=<uuid>` selector\n * the nav tree and Mode pill use. A bare link into VRM core drops a multi-org\n * user into whatever org core defaults to, which is a different account than\n * the one whose fuel / quarantine counts they just clicked.\n */\nfunction withOrgParam(url: string, orgId: string | null | undefined): string {\n if (!orgId) return url\n return `${url}${url.includes('?') ? '&' : '?'}org=${orgId}`\n}\n\n/** Scope the quarantined-contacts view to one sender. */\nfunction withPhoneParam(url: string, phone: string | null | undefined): string {\n if (!phone) return url\n return `${url}${url.includes('?') ? '&' : '?'}phone=${encodeURIComponent(phone)}`\n}\n\n/**\n * Resolve an organization logo URL for rendering in ANY app.\n *\n * `organizations.logo_url` is authored by VRM core and stored as a ROOT-RELATIVE\n * core route — `/api/storage/public?bucket=organization-logos&path=<org>/logo.png`\n * (the signed-storage proxy). VRM core renders it correctly because that path\n * resolves against its own origin; every other app resolves it against its own\n * origin (forms.politogyvrm.com/api/storage/public), gets a 404, and shows a\n * broken image. The chrome API passes the stored value through verbatim, so the\n * resolution belongs here — one definition for every app, core included.\n *\n * Absolute URLs (http/https/data/blob) pass through untouched.\n */\nexport function resolveOrgLogoUrl(url: string | null | undefined): string | undefined {\n const raw = url?.trim()\n if (!raw) return undefined\n if (/^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i.test(raw)) return raw\n return `${CORE_APP_ORIGIN}${raw.startsWith('/') ? '' : '/'}${raw}`\n}\n\n// ---------------------------------------------------------------------------\n// Shared 32×32 circular top-bar button chrome — the ONE definition of the\n// top-bar trigger (Global Rules: no slot hand-rolls its own trigger/badge).\n// NavTopBar's structured actionsList buttons use this same builder.\n// ---------------------------------------------------------------------------\n\n/**\n * Glyph size inside every top-bar icon button — Reference/UI-Platform v30:\n * \"34px buttons / 17px glyph / 6px gap\".\n */\nexport const TOPBAR_GLYPH_SIZE = 17\n\nexport function topBarIconButtonClass(tone: 'default' | 'warning' | 'danger' = 'default'): string {\n const toneClass =\n tone === 'danger' || tone === 'warning'\n ? 'text-[color:var(--chrome-danger)] hover:text-[color:var(--chrome-danger)]'\n : 'text-[color:var(--topbar-icon-color,var(--muted))] hover:text-[color:var(--topbar-icon-hover-color,var(--foreground))] hover:bg-[color:var(--topbar-icon-hover-bg,transparent)]'\n return [\n // `group/tbtip` powers the shared <TopBarTooltip> rendered inside the trigger.\n 'group/tbtip relative flex items-center justify-center rounded-[var(--topbar-icon-button-radius,5px)] border border-transparent transition',\n 'h-[var(--topbar-icon-button-size,34px)] w-[var(--topbar-icon-button-size,34px)]',\n toneClass,\n ].join(' ')\n}\n\n/** The shared count badge — one definition, used by every slot. */\n// ---------------------------------------------------------------------------\n// Top-bar panel registry.\n//\n// The top bar hosts two KINDS of surface: panels (opened deliberately by the\n// user from an icon) and transient nudges (the low-fuel hint, the new-reply\n// toast) that appear on their own. They are separate components under separate\n// triggers, so nothing stopped a nudge from covering an open panel — measured\n// in production: the reply toast over the notifications header, and the\n// low-fuel nudge over the same header from the fuel trigger two icons away.\n//\n// A module-scoped counter is enough: any nudge can ask \"is a panel open?\"\n// without the slots having to know about each other.\n// ---------------------------------------------------------------------------\nlet openPanelCount = 0\nconst panelListeners = new Set<() => void>()\nconst emitPanelChange = () => panelListeners.forEach((l) => l())\n\nfunction setPanelOpenGlobal(open: boolean) {\n openPanelCount = Math.max(0, openPanelCount + (open ? 1 : -1))\n emitPanelChange()\n}\n\n/** True while ANY top-bar panel is open. Nudges use it to stay out of the way. */\nexport function useAnyTopBarPanelOpen() {\n return useSyncExternalStore(\n (cb) => {\n panelListeners.add(cb)\n return () => panelListeners.delete(cb)\n },\n () => openPanelCount > 0,\n () => false,\n )\n}\n\nexport function TopBarCountBadge({ count }: { count: number }) {\n if (!(count > 0)) return null\n return (\n <span className=\"absolute -top-[5px] -right-[5px] flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--chrome-danger)] px-1 text-[10px] font-bold leading-4 text-[#FFFFFF]\">\n {count > 99 ? '99+' : count}\n </span>\n )\n}\n\n/**\n * The shared hover tooltip every top-bar control renders BELOW itself: an\n * up-pointing arrow at the icon, a bold title line and a muted description.\n * Pure CSS (group-hover) so it works on <a>, <button> and <summary> triggers.\n * The trigger must carry `group/tbtip relative` (topBarIconButtonClass does).\n */\nexport function TopBarTooltip({\n title,\n description,\n}: {\n title: string\n description?: ReactNode\n}) {\n // Styled ONLY on the Spec tooltip tokens (shellChrome.button.tooltipBg/Fg ->\n // --app-btn-tooltip-bg/-fg; Brand guideline \"Tooltips point at their\n // trigger\", UI-Platform \"Top-bar tooltips and panels - one shared\n // treatment\"). The literal fallbacks are the v150 token values for a page\n // that has not loaded the runtime token sheet yet. The arrow shares the\n // body's fill and border so the two read as one continuous shape, and the\n // tooltip opens on keyboard focus as well as hover (guideline: hover AND\n // focus); the description is the title color at reduced opacity so it\n // stays legible on whatever the token picks.\n return (\n <span\n role=\"tooltip\"\n className=\"pointer-events-none absolute left-1/2 top-full z-50 mt-2 hidden w-max max-w-56 -translate-x-1/2 flex-col rounded-lg border border-[color:var(--app-btn-tooltip-bg,#2F3136)] bg-[color:var(--app-btn-tooltip-bg,#2F3136)] px-3 py-2 text-left shadow-[var(--shadow-soft)] group-hover/tbtip:flex group-focus-visible/tbtip:flex\"\n >\n {/* Arrow pointing up at the icon - same fill and border as the body. */}\n <span\n aria-hidden\n className=\"absolute -top-[5px] left-1/2 h-2.5 w-2.5 -translate-x-1/2 rotate-45 border-l border-t border-[color:var(--app-btn-tooltip-bg,#2F3136)] bg-[color:var(--app-btn-tooltip-bg,#2F3136)]\"\n />\n <span className=\"text-xs font-semibold text-[color:var(--app-btn-tooltip-fg,#FFFFFF)]\">{title}</span>\n {description ? (\n <span className=\"mt-0.5 text-[11px] leading-snug text-[color:var(--app-btn-tooltip-fg,#FFFFFF)] opacity-75\">\n {description}\n </span>\n ) : null}\n </span>\n )\n}\n\n/**\n * The up-pointing arrow every top-bar panel renders, anchored under its\n * trigger icon (panels are right-aligned, so the arrow sits at the trigger's\n * center: 16px in from the panel's right edge). One definition — every menu\n * points at its own icon identically.\n */\nexport function TopBarPanelArrow() {\n return (\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]\"\n />\n )\n}\n\n/**\n * Wrapper for third-party top-bar widgets that ship their own launcher button\n * (e.g. DevNotes). Normalizes the trigger to the universal 32px circular slot\n * (chrome.css `.topbar-widget-slot`) and adds the standard tooltip.\n */\nexport function TopBarWidgetSlot({\n title,\n description,\n children,\n}: {\n title: string\n description?: string\n children: ReactNode\n}) {\n return (\n <span className=\"topbar-widget-slot group/tbtip relative inline-flex\">\n {children}\n <TopBarTooltip title={title} description={description} />\n </span>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Theme control — Light / System / Dark, rendered inside the account menu.\n// Controlled: the app owns persistence (profile + cross-subdomain cookie).\n// ---------------------------------------------------------------------------\n\nexport type ThemePreference = SharedThemePreference\n\nconst THEME_OPTIONS: { value: ThemePreference; label: string }[] = [\n { value: 'light', label: 'Light' },\n]\n\nexport function NavThemeControl({\n value,\n onChange,\n}: {\n value: ThemePreference\n onChange: (next: ThemePreference) => void\n}) {\n return (\n <div className=\"px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Appearance\n </p>\n <div\n role=\"radiogroup\"\n aria-label=\"Appearance\"\n className=\"flex overflow-hidden rounded-full border border-[color:var(--line)]\"\n >\n {THEME_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={value === opt.value}\n onClick={() => onChange(opt.value)}\n className={[\n 'flex-1 px-3 py-1.5 text-xs font-semibold transition',\n value === opt.value\n ? 'bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-[#FFFFFF]'\n : 'text-[color:var(--muted)] hover:bg-[color:var(--panel)] hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {opt.label}\n </button>\n ))}\n </div>\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Chrome data context — the injected fetcher.\n// ---------------------------------------------------------------------------\n\nexport type NavChromeFetcher = (\n path: string,\n init?: { method?: string; headers?: Record<string, string>; body?: string },\n) => Promise<unknown>\n\n/** GET me — the authenticated user's chrome identity from the shared API.\n * userName prefers the VRM-core profile full name over token claims. */\nexport type ChromeMe = {\n user: string | null\n userName: string | null\n avatarUrl: string | null\n themePreference: string | null\n /** Universal navigation-display choice ('menu'|'tabs'|'both'); null when\n * unset or when the profile column is absent in this environment. */\n navDisplay: string | null\n /** The user's durable active-org preference (full org uuid); null when unset\n * or when the profile column is absent. Adopted only when the request\n * carries no `?org=`/cookie selector — URL → cookie → profile → default. */\n activeOrg?: string | null\n account?: string | null\n accountName?: string | null\n role?: string | null\n /** Contact reply-to, when the profile carries them (optional/tolerant). */\n email?: string | null\n phone?: string | null\n}\n\n/** In-flight-promise + short-TTL cache entry for one (endpoint, orgId) key. */\ntype ChromeFetchCacheEntry = { promise: Promise<unknown>; expiresAt: number }\n\n/** Default freshness window for de-duped chrome reads (orgs/me/notifications/\n * fuel-status). Short enough that a stale value never survives one nav, long\n * enough to collapse every hook mounted on the same page paint into one call. */\nconst CHROME_FETCH_CACHE_TTL_MS = 30_000\n\nfunction chromeCacheKey(path: string, orgId?: string | null): string {\n return orgId === undefined ? path : `${path}::${orgId ?? ''}`\n}\n\n/**\n * A shared read cache scoped to one `<NavChromeProvider>` (one fetcher, one\n * page boot). Every consumer of a given (path, orgId) pair within the TTL\n * window awaits the SAME promise instead of firing its own request — this is\n * what collapsed `/orgs` (2-4x), `/me` (2-3x) and `/notifications` (2-3x) per\n * page load, 1-3.5s each, down to one call apiece (nav-latency-report.md\n * Table 2). Keying by orgId means switching the active org is itself the\n * invalidation: the new org gets a fresh key, never the previous org's cached\n * value. A failed request is evicted immediately so the next consumer retries\n * rather than replaying the same rejection for the rest of the TTL.\n */\nfunction createChromeFetchCache(getFetchJson: () => NavChromeFetcher) {\n const cache = new Map<string, ChromeFetchCacheEntry>()\n\n function dedupedFetch(\n path: string,\n init: Parameters<NavChromeFetcher>[1] | undefined,\n opts: { orgId?: string | null; ttlMs?: number } = {},\n ): Promise<unknown> {\n const key = chromeCacheKey(path, opts.orgId)\n const now = Date.now()\n const hit = cache.get(key)\n if (hit && hit.expiresAt > now) return hit.promise\n // Return the fetcher's own promise (no extra `.catch` hop) so callers see\n // the same microtask depth as a direct fetchJson call; the boot screen's\n // first-tick dismissal (frameBootChrome.test) depends on that.\n const promise = getFetchJson()(path, init)\n promise.catch(() => cache.delete(key))\n cache.set(key, { promise, expiresAt: now + (opts.ttlMs ?? CHROME_FETCH_CACHE_TTL_MS) })\n return promise\n }\n\n /** Force the next read of `path` (any org) to skip the cache. Used after a\n * mutation that changes what an endpoint would return (e.g. marking chrome\n * notifications read server-side, if that ever moves off local storage). */\n function invalidate(path: string) {\n for (const key of cache.keys()) {\n if (key === path || key.startsWith(`${path}::`)) cache.delete(key)\n }\n }\n\n return { dedupedFetch, invalidate }\n}\n\ntype NavChromeContextValue = {\n fetchJson: NavChromeFetcher\n dedupedFetch: ReturnType<typeof createChromeFetchCache>['dedupedFetch']\n invalidateChromeCache: ReturnType<typeof createChromeFetchCache>['invalidate']\n me: ChromeMe | null\n meLoaded: boolean\n /** The bell's feed adapter; null = the legacy contacts-shaped feed. */\n notificationsAdapter: NotificationsAdapter | null\n}\n\nconst NavChromeContext = createContext<NavChromeContextValue | null>(null)\n\nexport function NavChromeProvider({\n fetchJson,\n notificationsAdapter,\n children,\n}: {\n fetchJson: NavChromeFetcher\n /**\n * Omitted: the bell reads the comms feed through the same proxy (default).\n * An app may inject its own adapter; `null` keeps the legacy feed.\n */\n notificationsAdapter?: NotificationsAdapter | null\n children: ReactNode\n}) {\n // The cache outlives re-renders but always calls the LATEST fetchJson (the\n // consuming app may pass a new function identity every render).\n const fetchJsonRef = useRef(fetchJson)\n fetchJsonRef.current = fetchJson\n const cacheRef = useRef<ReturnType<typeof createChromeFetchCache> | null>(null)\n if (!cacheRef.current) {\n cacheRef.current = createChromeFetchCache(() => fetchJsonRef.current)\n }\n const { dedupedFetch, invalidate: invalidateChromeCache } = cacheRef.current\n\n // One stable adapter per provider, built over the latest fetcher.\n const defaultAdapterRef = useRef<NotificationsAdapter | null>(null)\n if (!defaultAdapterRef.current) {\n defaultAdapterRef.current = createCommsNotificationsAdapter((path, init) =>\n fetchJsonRef.current(path, init),\n )\n }\n const adapter = notificationsAdapter === undefined ? defaultAdapterRef.current : notificationsAdapter\n\n // ONE `me` fetch per provider — identity (profile name/avatar) and the\n // theme reconciliation both hang off it.\n const [me, setMe] = useState<ChromeMe | null>(null)\n const [meLoaded, setMeLoaded] = useState(false)\n useEffect(() => {\n let cancelled = false\n dedupedFetch('me', undefined)\n .then((data) => {\n if (!cancelled) setMe(data as ChromeMe)\n })\n .catch(() => {\n /* degraded: session identity stands in */\n })\n .finally(() => {\n if (!cancelled) setMeLoaded(true)\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch])\n\n return (\n <NavChromeContext.Provider\n value={{ fetchJson, dedupedFetch, invalidateChromeCache, me, meLoaded, notificationsAdapter: adapter }}\n >\n {children}\n </NavChromeContext.Provider>\n )\n}\n\n/** The authenticated user's chrome identity (profile name / avatar / theme). */\nexport function useChromeMe(): { me: ChromeMe | null; loaded: boolean } {\n const ctx = useContext(NavChromeContext)\n return { me: ctx?.me ?? null, loaded: ctx?.meLoaded ?? false }\n}\n\n/** The provider's de-duped chrome read (null outside <NavChromeProvider>). */\nexport function useNavChromeDedupedFetch(): NavChromeContextValue['dedupedFetch'] | null {\n return useContext(NavChromeContext)?.dedupedFetch ?? null\n}\n\n/** The injected chrome fetcher (null outside <NavChromeProvider>). */\nexport function useNavChromeFetcher(): NavChromeFetcher | null {\n return useContext(NavChromeContext)?.fetchJson ?? null\n}\n\nfunction useNavChrome(component: string): NavChromeContextValue {\n const ctx = useContext(NavChromeContext)\n if (!ctx) {\n throw new Error(\n `${component} must be rendered inside <NavChromeProvider> (inject the chrome API fetcher there).`,\n )\n }\n return ctx\n}\n\n// ---------------------------------------------------------------------------\n// Data shapes (mirror of politogy-contacts-api responses).\n// ---------------------------------------------------------------------------\n\nexport type FuelChannelStatus = {\n remainingUnits: number\n rawBalanceUnits: number\n usedUnits: number\n lowFuel: boolean\n lowFuelThreshold: number\n}\n\nexport type CommunicationsFuelStatus = {\n organizationId: string\n signal: FuelChannelStatus\n broadcast: FuelChannelStatus\n combinedAvailableCredits: number\n}\n\nexport type ChromeNotificationAlert = {\n id: string\n title: string\n description: string\n href: string | null\n kind: string\n /** Server read state (adapter feeds only); the local watermark still applies. */\n read?: boolean\n}\n\nexport type ChromeNotificationReply = {\n id: string\n contactId: string | null\n name: string\n preview: string\n /** Optional deep-link to the conversation; the new-reply toast opens it. */\n href?: string\n /**\n * Optional arrival timestamp. Present, it lets the trigger badge count a\n * reply as \"unseen\" only when it is newer than the last time the panel was\n * opened; absent (older payloads), replies simply don't survive the first\n * open as unseen. Tolerated either way.\n */\n createdAt?: string\n}\n\n/** A running or finished contact import surfaced in the notifications panel. */\nexport type ChromeNotificationImport = {\n id: string\n label: string\n /** 0–100 progress, or null when indeterminate (no bar rendered). */\n percent: number | null\n status: 'active' | 'completed'\n href: string | null\n}\n\n/** A cluster of quarantined contacts sharing one phone number. */\nexport type ChromeNotificationQuarantine = {\n phone: string\n count: number\n /** Upstream may omit it; the row already renders conditionally on it. */\n latestAt: string | null\n}\n\nexport type ChromeNotificationsPayload = {\n organizationId: string\n alerts: ChromeNotificationAlert[]\n replies: ChromeNotificationReply[]\n /** Optional — running/finished imports (tolerant when absent). */\n imports?: ChromeNotificationImport[]\n /** Optional — clustered quarantined contacts (tolerant when absent). */\n quarantined?: ChromeNotificationQuarantine[]\n /** Optional — the server's one badge number (adapter feeds only). */\n badge?: number\n}\n\nexport type ChromeOrgSummary = {\n id: string\n name: string | null\n logoUrl: string | null\n brandColor: string | null\n role: string | null\n /** Un-mapped VRM-core membership role (e.g. \"super_admin\"). */\n rawRole?: string | null\n}\n\n/**\n * Fetch the signed-in user's VRM-core organizations through the injected\n * fetcher. Exposed as a hook so the org switcher in the sidebar and the\n * org-scoped widgets share one request.\n */\nexport function useChromeOrgs({ enabled = true }: { enabled?: boolean } = {}): {\n orgs: ChromeOrgSummary[] | null\n loading: boolean\n error: boolean\n} {\n const { dedupedFetch } = useNavChrome('useChromeOrgs')\n const [orgs, setOrgs] = useState<ChromeOrgSummary[] | null>(null)\n const [loading, setLoading] = useState(enabled)\n const [error, setError] = useState(false)\n\n useEffect(() => {\n // Disabled when the app already holds the org list from its token-backed\n // session (auth-owned active org): no per-request chrome `/api/orgs` call.\n if (!enabled) {\n setLoading(false)\n return\n }\n let cancelled = false\n setLoading(true)\n setError(false)\n dedupedFetch('orgs', undefined)\n .then((data) => {\n if (cancelled) return\n const list = (data as { orgs?: ChromeOrgSummary[] })?.orgs ?? []\n setOrgs(list)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch, enabled])\n\n return { orgs, loading, error }\n}\n\n// ---------------------------------------------------------------------------\n// Internal building blocks.\n// ---------------------------------------------------------------------------\n\n/** Value-area skeleton shimmer (chrome/labels stay static per Global Rules). */\nfunction ValueSkeleton({ className }: { className?: string }) {\n return (\n <span\n aria-hidden\n className={[\n 'inline-block animate-pulse rounded bg-[color:var(--panel-elevated)]',\n className ?? 'h-4 w-16',\n ].join(' ')}\n />\n )\n}\n\n/** Slot-driven glyph: Brand-token name when resolvable, fallback otherwise. */\nfunction SlotGlyph({\n slot,\n fallback: Fallback,\n size = TOPBAR_GLYPH_SIZE,\n}: {\n slot?: TopBarIconSlot\n fallback: NavIconLike\n size?: number\n}) {\n const glyphName = useTopBarIconSlotGlyph(slot ?? 'apps')\n const BrandGlyph = slot ? resolveBrandGlyph(glyphName) : null\n const Glyph = BrandGlyph ?? Fallback\n return <Glyph size={size} className=\"text-current\" />\n}\n\n/**\n * A top-bar popover: the shared circular trigger + a right-aligned panel.\n * Closes on outside click / Escape. Purely presentational.\n *\n * EXPORTED so an app with a richer panel than the stock actions can render it\n * inside the SHARED chrome — same 32px trigger, same tooltip, same badge, same\n * panel surface and arrow — instead of hand-rolling a trigger and drifting.\n * This is the enabling step for folding VRM's Fuel breakdown, import-progress,\n * alerts and reply-feed panels into the shared cluster one at a time, without\n * dropping capability (shell-nav-handoff §4; UI-Platform forbids migrating an\n * app to a rendering that loses an element it already ships).\n */\nexport function TopBarPopover({\n label,\n description,\n slot,\n fallbackIcon,\n badge,\n tone,\n onOpen,\n openToken,\n onOpenChange,\n hideTooltip = false,\n children,\n panelClassName,\n}: {\n label: string\n description?: string\n slot?: TopBarIconSlot\n fallbackIcon: NavIconLike\n badge?: number\n tone?: 'default' | 'warning' | 'danger'\n onOpen?: () => void\n /**\n * Imperative \"open\" signal: whenever this number CHANGES the panel opens\n * (and `onOpen` fires). Lets a sibling — e.g. the notifications toast — open\n * the panel without owning the popover's state. Undefined disables it.\n */\n openToken?: number\n /**\n * Notified on every open/close. A sibling surface anchored to the same\n * trigger (e.g. the notifications toast) must know when the panel is open so\n * the two never render on top of each other — Reference/UI-Platform gives\n * every top-bar panel ONE surface anchored to its trigger, so a second\n * surface at the same anchor always occludes it.\n */\n onOpenChange?: (open: boolean) => void\n /**\n * Hide the trigger's hover tooltip while a transient nudge (the new-reply\n * toast, the low-fuel hint) is up under the same trigger. Both are z-50 and\n * anchored to the trigger, so without this the nudge paints over the\n * tooltip (measured on a2p: the reply toast covered \"Alerts &\n * Notifications\"). Reference/UI-Platform: one surface per trigger.\n */\n hideTooltip?: boolean\n children: ReactNode\n panelClassName?: string\n}) {\n const [open, setOpen] = useState(false)\n const onOpenChangeRef = useRef(onOpenChange)\n onOpenChangeRef.current = onOpenChange\n useEffect(() => {\n onOpenChangeRef.current?.(open)\n if (!open) return\n setPanelOpenGlobal(true)\n return () => setPanelOpenGlobal(false)\n }, [open])\n const rootRef = useRef<HTMLDivElement | null>(null)\n const lastOpenTokenRef = useRef(openToken)\n\n // React to external open signals (skips the initial value on mount).\n useEffect(() => {\n if (openToken === undefined) return\n if (openToken === lastOpenTokenRef.current) return\n lastOpenTokenRef.current = openToken\n setOpen((v) => {\n if (!v) onOpen?.()\n return true\n })\n }, [openToken, onOpen])\n\n useEffect(() => {\n if (!open) return\n const onDocClick = (e: MouseEvent) => {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false)\n }\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') setOpen(false)\n }\n document.addEventListener('mousedown', onDocClick)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onDocClick)\n document.removeEventListener('keydown', onKey)\n }\n }, [open])\n\n return (\n <div ref={rootRef} className=\"relative\">\n <button\n type=\"button\"\n aria-label={label}\n aria-expanded={open}\n className={topBarIconButtonClass(tone)}\n onClick={() => {\n setOpen((v) => {\n const next = !v\n if (next) onOpen?.()\n return next\n })\n }}\n >\n <SlotGlyph slot={slot} fallback={fallbackIcon} />\n {typeof badge === 'number' ? <TopBarCountBadge count={badge} /> : null}\n {!open && !hideTooltip ? <TopBarTooltip title={label} description={description} /> : null}\n </button>\n {open ? (\n <div\n className={[\n 'absolute right-0 z-40 mt-2 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] shadow-[var(--shadow-soft)]',\n panelClassName ?? 'w-80',\n ].join(' ')}\n >\n <TopBarPanelArrow />\n <div className=\"overflow-hidden rounded-xl\">{children}</div>\n </div>\n ) : null}\n </div>\n )\n}\n\n// Inline fallback glyphs (Feather-style paths) so the package needs no icon dep.\nfunction BatteryGlyph({ size = TOPBAR_GLYPH_SIZE, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <rect x=\"1\" y=\"6\" width=\"18\" height=\"12\" rx=\"2\" ry=\"2\" />\n <line x1=\"23\" y1=\"10\" x2=\"23\" y2=\"14\" />\n <line x1=\"5\" y1=\"10\" x2=\"5\" y2=\"14\" />\n <line x1=\"9\" y1=\"10\" x2=\"9\" y2=\"14\" />\n </svg>\n )\n}\n\nfunction BellGlyph({ size = TOPBAR_GLYPH_SIZE, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\" />\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\" />\n </svg>\n )\n}\n\nfunction BellOffGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <path d=\"M13.73 21a2 2 0 0 1-3.46 0\" />\n <path d=\"M18.63 13A17.9 17.9 0 0 1 18 8\" />\n <path d=\"M6.26 6.26A5.86 5.86 0 0 0 6 8c0 7-3 9-3 9h14\" />\n <path d=\"M18 8a6 6 0 0 0-9.33-5\" />\n <line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\" />\n </svg>\n )\n}\n\nfunction LifeBuoyGlyph({ size = TOPBAR_GLYPH_SIZE, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <line x1=\"4.93\" y1=\"4.93\" x2=\"9.17\" y2=\"9.17\" />\n <line x1=\"14.83\" y1=\"14.83\" x2=\"19.07\" y2=\"19.07\" />\n <line x1=\"14.83\" y1=\"9.17\" x2=\"19.07\" y2=\"4.93\" />\n <line x1=\"4.93\" y1=\"19.07\" x2=\"9.17\" y2=\"14.83\" />\n </svg>\n )\n}\n\nfunction LayoutGlyph({ size = TOPBAR_GLYPH_SIZE, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\" />\n <line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\" />\n <line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\" />\n </svg>\n )\n}\n\nfunction PlusGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n )\n}\n\nfunction XGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\nfunction CheckGlyph({ size = 14, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n )\n}\n\n// ---------------------------------------------------------------------------\n// FuelAction — Communications Fuel balance (battery glyph + popover meters).\n// ---------------------------------------------------------------------------\n\nconst LOW_FUEL_HINT_DISMISSED_KEY = 'politogy_low_fuel_hint_dismissed'\n\nfunction FuelRow({\n label,\n channel,\n loading,\n addHref,\n addLabel,\n}: {\n label: string\n channel: FuelChannelStatus | null\n loading: boolean\n /** Billing deep-link for the small \"+\" top-up button (omit to hide it). */\n addHref?: string\n addLabel?: string\n}) {\n const remaining = channel?.remainingUnits ?? 0\n const total = channel ? Math.max(channel.rawBalanceUnits, channel.remainingUnits) : 0\n const ratio = total > 0 ? Math.min(100, Math.max(0, (remaining / total) * 100)) : 0\n const low = channel?.lowFuel ?? false\n\n return (\n <div className=\"w-full\">\n <div className=\"mb-1 flex items-center justify-between gap-2\">\n <span className=\"text-xs font-semibold text-[color:var(--foreground)]\">{label}</span>\n <div className=\"flex items-center gap-2\">\n {loading ? (\n <ValueSkeleton className=\"h-3.5 w-14\" />\n ) : (\n <span\n className={[\n 'text-xs font-semibold tabular-nums',\n low ? 'text-[color:var(--chrome-danger)]' : 'text-[color:var(--muted)]',\n ].join(' ')}\n >\n {remaining.toLocaleString()} left\n </span>\n )}\n {addHref ? (\n <a\n href={addHref}\n aria-label={addLabel}\n className=\"flex h-5 w-5 items-center justify-center rounded-full border border-[color:var(--line)] text-[color:var(--muted)] transition hover:border-[color:var(--foreground)] hover:text-[color:var(--foreground)]\"\n >\n <PlusGlyph />\n </a>\n ) : null}\n </div>\n </div>\n <div className=\"h-1.5 w-full overflow-hidden rounded-full bg-[color:var(--panel)]\">\n {loading ? (\n <div className=\"h-full w-full animate-pulse bg-[color:var(--line)]\" />\n ) : (\n <div\n className={[\n 'h-full rounded-full transition-[width]',\n low ? 'bg-[color:var(--chrome-danger)]' : 'bg-[color:var(--color-ok,#00783B)]',\n ].join(' ')}\n style={{ width: `${ratio}%` }}\n />\n )}\n </div>\n </div>\n )\n}\n\n// Both the low-fuel nudge and the new-reply toast are wide (240-320px)\n// absolute bubbles anchored to adjacent top-bar icons (Fuel, then\n// Notifications). Anchored-right boxes expand LEFTWARD from their trigger,\n// so a wide toast under the (further-right) bell can reach back over the\n// (further-left) fuel icon's hint, same z-50 — whichever mounted later\n// painted on top and the fuel banner got cut off/hidden (reported on\n// contacts.politogyvrm.com, 2026-10-09). This tiny external store lets the\n// toast learn the hint's visibility without a shared provider, so it can\n// drop below it instead of overlapping: the banner always stacks above the\n// toast, never the other way round.\nlet lowFuelHintVisible = false\nconst lowFuelHintListeners = new Set<() => void>()\nfunction setLowFuelHintVisible(visible: boolean): void {\n if (lowFuelHintVisible === visible) return\n lowFuelHintVisible = visible\n lowFuelHintListeners.forEach((l) => l())\n}\nfunction subscribeLowFuelHintVisible(onChange: () => void): () => void {\n lowFuelHintListeners.add(onChange)\n return () => lowFuelHintListeners.delete(onChange)\n}\nfunction useLowFuelHintVisible(): boolean {\n // Server snapshot: the hint is client-only (sessionStorage), so SSR renders\n // without it. FuelAction reads this during the frame's server render.\n return useSyncExternalStore(\n subscribeLowFuelHintVisible,\n () => lowFuelHintVisible,\n () => false,\n )\n}\n// Height (card + arrow + gap) the toast must clear when the hint is also up.\nconst LOW_FUEL_HINT_CLEARANCE_PX = 96\n\n/**\n * The low-fuel nudge: a small bubble anchored below the fuel trigger (arrow up)\n * with a \"Buy More Fuel\" deep-link. Dismissible; the dismissal persists for the\n * session (sessionStorage) so it never re-appears until a fresh session — and\n * the flag clears once fuel is no longer low, so a later drain can nudge again.\n */\nfunction LowFuelHint({ lowFuel, orgId }: { lowFuel: boolean; orgId: string | null }) {\n const [dismissed, setDismissed] = useState<boolean>(() => {\n if (typeof window === 'undefined') return false\n try {\n return window.sessionStorage.getItem(LOW_FUEL_HINT_DISMISSED_KEY) === '1'\n } catch {\n return false\n }\n })\n\n useEffect(() => {\n if (lowFuel) return\n try {\n window.sessionStorage.removeItem(LOW_FUEL_HINT_DISMISSED_KEY)\n } catch {\n /* unavailable */\n }\n }, [lowFuel])\n\n // Yield to any open panel: the nudge is wider than its own trigger and the\n // panels are right-aligned, so it lands on top of whichever one is open\n // (measured on contacts: it covered the notifications panel's header).\n const panelOpen = useAnyTopBarPanelOpen()\n const showing = lowFuel && !dismissed && !panelOpen\n\n // Published so the new-reply toast (anchored to the adjacent Notifications\n // icon) can drop below this banner instead of racing it for the same\n // on-screen space. Effect, not inline: setting external-store state during\n // render is not allowed.\n useEffect(() => {\n setLowFuelHintVisible(showing)\n return () => setLowFuelHintVisible(false)\n }, [showing])\n\n if (!showing) return null\n\n const dismiss = () => {\n try {\n window.sessionStorage.setItem(LOW_FUEL_HINT_DISMISSED_KEY, '1')\n } catch {\n /* unavailable */\n }\n setDismissed(true)\n }\n\n return (\n <div\n role=\"status\"\n // z-[60]: one tier above the new-reply toast (z-50) so this banner is\n // never the one that gets covered when both are up at once.\n className=\"absolute right-0 top-[calc(100%+10px)] z-[60] w-60 rounded-lg border border-[color:var(--chrome-danger)] bg-[color:var(--chrome-danger)] px-3 py-2 text-[#FFFFFF] shadow-[var(--shadow-soft)]\"\n onClick={(e) => e.stopPropagation()}\n >\n {/* Arrow pointing up at the fuel button (mirrors TopBarPanelArrow's offset). */}\n <span\n aria-hidden\n className=\"absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 bg-[color:var(--chrome-danger)]\"\n />\n <div className=\"flex items-start gap-2\">\n <div className=\"flex-1\">\n <p className=\"text-sm font-semibold\">You’re low on fuel</p>\n <a\n href={withOrgParam(CORE_BILLING_URL, orgId)}\n className=\"mt-1 inline-block text-sm font-bold underline hover:opacity-90\"\n >\n Buy More Fuel\n </a>\n </div>\n <button\n type=\"button\"\n aria-label=\"Dismiss low fuel notice\"\n onClick={dismiss}\n className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[#FFFFFF]/90 transition hover:bg-[#FFFFFF]/20\"\n >\n <XGlyph />\n </button>\n </div>\n </div>\n )\n}\n\nexport function FuelAction({ orgId }: { orgId: string | null }) {\n const { dedupedFetch } = useNavChrome('FuelAction')\n const [fuel, setFuel] = useState<CommunicationsFuelStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n\n useEffect(() => {\n let cancelled = false\n // No org yet: wait for it. A header-less read is a second request for\n // the same widget once the org resolves (twice per page load).\n if (!orgId) {\n setLoading(false)\n return\n }\n setLoading(true)\n setError(false)\n setFuel(null)\n dedupedFetch(\n 'communications/fuel-status',\n { headers: orgId ? { 'x-contacts-org': orgId } : undefined },\n { orgId },\n )\n .then((data) => {\n if (cancelled) return\n setFuel((data as { fuel?: CommunicationsFuelStatus | null })?.fuel ?? null)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch, orgId])\n\n const low = !!fuel && (fuel.signal.lowFuel || fuel.broadcast.lowFuel)\n // The low-fuel hint sits under this trigger; the tooltip yields to it.\n const lowFuelHintUp = useLowFuelHintVisible()\n\n return (\n // The nudge anchors to the trigger, so it sits OUTSIDE the popover panel in\n // its own relative wrapper (same shape the VRM widget used).\n <div className=\"relative inline-flex\">\n <TopBarPopover\n label=\"Communications Fuel\"\n description=\"Remaining SMS and email sending balance for the active organization.\"\n slot=\"comms-fuel\"\n fallbackIcon={BatteryGlyph}\n tone={low ? 'warning' : 'default'}\n hideTooltip={lowFuelHintUp}\n >\n <div className=\"px-4 py-3\">\n <p className=\"mb-3 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Communications Fuel\n </p>\n {error || (!loading && !fuel) ? (\n <p className=\"text-sm text-[color:var(--muted)]\">\n Fuel balance is unavailable right now.\n </p>\n ) : (\n <div className=\"flex flex-col gap-3\">\n <FuelRow\n label=\"SMS Signal\"\n channel={fuel?.signal ?? null}\n loading={loading}\n addHref={withOrgParam(CORE_BILLING_URL, orgId)}\n addLabel=\"Add SMS Signal fuel\"\n />\n <FuelRow\n label=\"Email Broadcast\"\n channel={fuel?.broadcast ?? null}\n loading={loading}\n addHref={withOrgParam(CORE_BILLING_URL, orgId)}\n addLabel=\"Add Email Broadcast fuel\"\n />\n </div>\n )}\n </div>\n </TopBarPopover>\n <LowFuelHint lowFuel={low} orgId={orgId} />\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// NotificationsAction — bell + count badge + alerts/replies popover.\n// ---------------------------------------------------------------------------\n\n/** Per-org read/seen state, persisted client-side (localStorage). */\ntype NotifState = {\n readAlertIds: string[]\n lastSeenAt: string | null\n /** Reply ids already surfaced as a toast, so none re-toasts (capped ~50). */\n toastedReplyIds: string[]\n}\n\nfunction notifStateKey(orgId: string | null): string {\n return `politogy_chrome_notif_state:${orgId ?? 'none'}`\n}\n\nfunction readNotifState(orgId: string | null): NotifState {\n const empty: NotifState = { readAlertIds: [], lastSeenAt: null, toastedReplyIds: [] }\n if (typeof window === 'undefined') return empty\n try {\n const raw = window.localStorage.getItem(notifStateKey(orgId))\n if (!raw) return empty\n const parsed = JSON.parse(raw) as Partial<NotifState>\n return {\n readAlertIds: Array.isArray(parsed?.readAlertIds)\n ? parsed.readAlertIds.filter((id): id is string => typeof id === 'string')\n : [],\n lastSeenAt: typeof parsed?.lastSeenAt === 'string' ? parsed.lastSeenAt : null,\n toastedReplyIds: Array.isArray(parsed?.toastedReplyIds)\n ? parsed.toastedReplyIds.filter((id): id is string => typeof id === 'string')\n : [],\n }\n } catch {\n return empty\n }\n}\n\nfunction writeNotifState(orgId: string | null, state: NotifState): void {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(notifStateKey(orgId), JSON.stringify(state))\n } catch {\n /* unavailable */\n }\n}\n\n/**\n * Session-scoped mute for the rotating new-reply toasts. Session (not local)\n * storage on purpose: silencing is a \"not right now\" gesture, so a reload\n * restores the toasts rather than silently disabling them forever.\n */\nconst TOASTS_MUTED_KEY = 'politogy_chrome_toasts_muted'\n\nfunction readToastsMuted(): boolean {\n if (typeof window === 'undefined') return false\n try {\n return window.sessionStorage.getItem(TOASTS_MUTED_KEY) === '1'\n } catch {\n return false\n }\n}\n\nfunction writeToastsMuted(muted: boolean): void {\n if (typeof window === 'undefined') return\n try {\n if (muted) window.sessionStorage.setItem(TOASTS_MUTED_KEY, '1')\n else window.sessionStorage.removeItem(TOASTS_MUTED_KEY)\n } catch {\n /* unavailable */\n }\n}\n\n/** Format a raw phone into US (XXX) XXX-XXXX; leave anything else as-is. */\nfunction formatPhone(raw: string): string {\n const digits = raw.replace(/\\D/g, '')\n const ten = digits.length === 11 && digits.startsWith('1') ? digits.slice(1) : digits\n if (ten.length === 10) return `(${ten.slice(0, 3)}) ${ten.slice(3, 6)}-${ten.slice(6)}`\n return raw\n}\n\nfunction ImportRow({ imp }: { imp: ChromeNotificationImport }) {\n const pct = imp.percent == null ? null : Math.max(0, Math.min(100, imp.percent))\n return (\n <>\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"truncate text-sm text-[color:var(--foreground)]\">{imp.label}</span>\n {pct != null ? (\n <span className=\"shrink-0 text-xs tabular-nums text-[color:var(--muted)]\">\n {Math.round(pct)}%\n </span>\n ) : null}\n </div>\n {pct != null ? (\n <div className=\"mt-1 h-1 w-full overflow-hidden rounded-full bg-[color:var(--panel)]\">\n <div\n className=\"h-full rounded-full bg-[color:var(--color-accent)] transition-[width]\"\n style={{ width: `${pct}%` }}\n />\n </div>\n ) : null}\n </>\n )\n}\n\n/**\n * Transient \"new reply\" toast anchored below the bell. Dark bubble with an\n * up-arrow, sender + preview; auto-fades after ~12s; clicking activates it.\n * Mirrors VRM's NewTextBellPopup. Purely presentational — the parent owns which\n * reply shows and what a click does.\n */\nfunction NewReplyToast({\n reply,\n onActivate,\n onClose,\n onSilence,\n ttlMs = 12000,\n}: {\n reply: ChromeNotificationReply\n onActivate: () => void\n onClose: () => void\n onSilence: () => void\n ttlMs?: number\n}) {\n const [visible, setVisible] = useState(false)\n const onCloseRef = useRef(onClose)\n onCloseRef.current = onClose\n const lowFuelHintVisible = useLowFuelHintVisible()\n\n useEffect(() => {\n setVisible(true)\n const fadeAt = Math.max(0, ttlMs - 450)\n const t1 = window.setTimeout(() => setVisible(false), fadeAt)\n const t2 = window.setTimeout(() => onCloseRef.current(), ttlMs)\n return () => {\n window.clearTimeout(t1)\n window.clearTimeout(t2)\n }\n }, [ttlMs])\n\n const activate = () => {\n setVisible(false)\n onActivate()\n }\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n aria-label=\"Open new reply\"\n onClick={activate}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n activate()\n }\n }}\n // z-50, below the low-fuel banner's z-[60] — and when that banner is\n // up, pushed down past it so the two stack instead of overlapping\n // (see LOW_FUEL_HINT_CLEARANCE_PX; both bubbles are wide enough to\n // reach across the Fuel ↔ Notifications gap at these icon spacings).\n className=\"absolute right-[-6px] top-[calc(100%+12px)] z-50 min-w-[240px] max-w-[320px] cursor-pointer rounded-xl bg-[#161616] px-4 py-3 text-[#FFFFFF] shadow-[var(--shadow-soft)]\"\n style={{\n top: lowFuelHintVisible ? `calc(100% + 12px + ${LOW_FUEL_HINT_CLEARANCE_PX}px)` : undefined,\n opacity: visible ? 1 : 0,\n transform: visible ? 'translateY(0px)' : 'translateY(-4px)',\n transition: 'opacity 250ms ease, transform 250ms ease',\n }}\n >\n {/* Up-arrow pointing at the bell. */}\n <span\n aria-hidden\n className=\"absolute right-[18px] top-[-7px] h-0 w-0 border-x-[8px] border-x-transparent border-b-[8px] border-b-[#161616]\"\n />\n {/* Dismiss this ONE toast without navigating. The bubble itself is the\n activate target, so the close control has to stop propagation or\n \"get rid of it\" would mean \"open it\" (reported 2026-08-12). */}\n <button\n type=\"button\"\n aria-label=\"Dismiss notification\"\n onClick={(e) => {\n e.stopPropagation()\n setVisible(false)\n onClose()\n }}\n className=\"absolute right-2 top-2 flex h-5 w-5 items-center justify-center rounded-full text-[#FFFFFF] opacity-60 transition hover:bg-[#FFFFFF]/10 hover:opacity-100\"\n >\n <XGlyph size={12} />\n </button>\n <p className=\"truncate pr-6 text-sm font-semibold\">{reply.name}</p>\n <p className=\"mt-1 truncate text-xs opacity-85\">{reply.preview}</p>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setVisible(false)\n onSilence()\n }}\n className=\"mt-2 inline-flex items-center gap-1 text-[11px] font-semibold text-[#FFFFFF] opacity-60 transition hover:opacity-100\"\n >\n <BellOffGlyph size={12} />\n Silence notifications\n </button>\n </div>\n )\n}\n\nexport function NotificationsAction({ orgId }: { orgId: string | null }) {\n const { dedupedFetch, notificationsAdapter } = useNavChrome('NotificationsAction')\n const [payload, setPayload] = useState<ChromeNotificationsPayload | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState(false)\n const [notif, setNotif] = useState<NotifState>(() => readNotifState(orgId))\n const [toastReply, setToastReply] = useState<ChromeNotificationReply | null>(null)\n const [toastsMuted, setToastsMuted] = useState<boolean>(() => readToastsMuted())\n const [openToken, setOpenToken] = useState(0)\n const [panelOpen, setPanelOpen] = useState(false)\n // Bumped after a server write (adapter path) to re-read the feed and badge.\n const [reloadToken, setReloadToken] = useState(0)\n // Also yield to a panel opened from a NEIGHBOURING trigger — the fuel panel\n // is right-aligned and wide enough to sit under the bell.\n const anyPanelOpen = useAnyTopBarPanelOpen()\n\n // Re-hydrate the read/seen watermark whenever the active org changes.\n useEffect(() => {\n setNotif(readNotifState(orgId))\n setToastReply(null)\n }, [orgId])\n\n useEffect(() => {\n let cancelled = false\n // No org yet: wait for it. A header-less read is a second request for\n // the same widget once the org resolves (twice per page load).\n if (!orgId) {\n setLoading(false)\n return\n }\n if (notificationsAdapter) {\n // Comms feed. Never rejects: a missing session or absent route is an\n // empty bell, not an error state.\n setError(false)\n notificationsAdapter\n .list(orgId)\n .then((feed) => {\n if (!cancelled) setPayload(notificationsFeedToPayload(feed, orgId) as ChromeNotificationsPayload)\n })\n .catch(() => {\n if (!cancelled) setPayload(notificationsFeedToPayload(emptyNotificationsFeed(), orgId) as ChromeNotificationsPayload)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }\n setLoading(true)\n setError(false)\n setPayload(null)\n dedupedFetch(\n 'notifications',\n { headers: orgId ? { 'x-contacts-org': orgId } : undefined },\n { orgId },\n )\n .then((data) => {\n if (!cancelled) setPayload(data as ChromeNotificationsPayload)\n })\n .catch(() => {\n if (!cancelled) setError(true)\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch, notificationsAdapter, orgId, reloadToken])\n\n // 10DLC registration alert: surfaced only in the notifications panel/badge\n // (unread state). No auto-redirect — see Decisions in PR for feat/spec-overlay.\n\n const markRead = useCallback(\n (id: string) => {\n // Adapter feeds persist read state on the server, then re-read the feed\n // so the row and the badge reflect it. A failed write is simply a no-op.\n if (notificationsAdapter) {\n void notificationsAdapter.markRead(id).then((ok) => {\n if (ok) setReloadToken((t) => t + 1)\n })\n }\n setNotif((prev) => {\n if (prev.readAlertIds.includes(id)) return prev\n const next = { ...prev, readAlertIds: [...prev.readAlertIds, id] }\n writeNotifState(orgId, next)\n return next\n })\n },\n [orgId, notificationsAdapter],\n )\n\n const markUnread = useCallback(\n (id: string) => {\n setNotif((prev) => {\n if (!prev.readAlertIds.includes(id)) return prev\n const next = { ...prev, readAlertIds: prev.readAlertIds.filter((x) => x !== id) }\n writeNotifState(orgId, next)\n return next\n })\n },\n [orgId],\n )\n\n // Opening the panel advances the \"last seen\" watermark (replies are seen).\n const onOpen = useCallback(() => {\n // The panel shows the reply the toast was previewing, so the toast has\n // nothing left to say — retire it rather than let it cover the panel.\n setToastReply(null)\n setNotif((prev) => {\n const next = { ...prev, lastSeenAt: new Date().toISOString() }\n writeNotifState(orgId, next)\n return next\n })\n }, [orgId])\n\n const alerts = payload?.alerts ?? []\n const replies = payload?.replies ?? []\n const imports = payload?.imports ?? []\n const quarantined = payload?.quarantined ?? []\n\n // New-reply toast: surface the newest reply that is (a) newer than the seen\n // watermark and (b) not already toasted this org. One at a time; the id is\n // recorded so a re-render / re-fetch never re-toasts it (capped at 50).\n useEffect(() => {\n // Silenced for this session — surface nothing new (the badge still counts).\n if (toastsMuted) return\n if (!payload || toastReply || panelOpen) return\n const candidate = replies\n .filter((r) => {\n if (!r.createdAt) return false\n if (notif.lastSeenAt && r.createdAt <= notif.lastSeenAt) return false\n return !notif.toastedReplyIds.includes(r.id)\n })\n .sort((a, b) => (a.createdAt! < b.createdAt! ? 1 : -1))[0]\n if (!candidate) return\n setToastReply(candidate)\n setNotif((prev) => {\n const next = {\n ...prev,\n toastedReplyIds: [candidate.id, ...prev.toastedReplyIds].slice(0, 50),\n }\n writeNotifState(orgId, next)\n return next\n })\n }, [\n payload,\n replies,\n toastReply,\n panelOpen,\n toastsMuted,\n notif.lastSeenAt,\n notif.toastedReplyIds,\n orgId,\n ])\n\n // Toast click: navigate to the reply's href when it carries one; otherwise\n // open the notifications panel (which also advances the seen watermark).\n const setMuted = useCallback((muted: boolean) => {\n writeToastsMuted(muted)\n setToastsMuted(muted)\n }, [])\n\n const onToastSilence = useCallback(() => {\n setMuted(true)\n setToastReply(null)\n }, [setMuted])\n\n const onToastActivate = useCallback(() => {\n const href = toastReply?.href\n setToastReply(null)\n if (href && typeof window !== 'undefined') {\n window.location.assign(href)\n return\n }\n setOpenToken((t) => t + 1)\n }, [toastReply])\n\n // Badge: UNREAD alerts + replies newer than the last-seen watermark. A reply\n // with no timestamp counts before the first open, then is treated as seen.\n const isAlertRead = (a: ChromeNotificationAlert) => a.read === true || notif.readAlertIds.includes(a.id)\n const unreadAlertCount = alerts.filter((a) => !isAlertRead(a)).length\n const unseenReplyCount = replies.filter((r) => {\n if (!notif.lastSeenAt) return true\n if (!r.createdAt) return false\n return r.createdAt > notif.lastSeenAt\n }).length\n // Adapter feeds carry the server's one badge number (unread notifications\n // plus unresolved alerts); the local count is the legacy contacts path only.\n const badgeCount =\n notificationsAdapter && payload?.badge !== undefined\n ? payload.badge\n : unreadAlertCount + unseenReplyCount\n\n const isEmpty =\n alerts.length === 0 && replies.length === 0 && imports.length === 0 && quarantined.length === 0\n\n // The toast yields to any open panel (this one or a neighbour's), and while\n // it is up the bell's hover tooltip yields to it - one surface per trigger.\n const toastVisible = toastReply !== null && !panelOpen && !anyPanelOpen\n\n return (\n // Relative wrapper so the new-reply toast anchors to the bell trigger,\n // outside the popover panel (same pattern as the fuel low-fuel nudge).\n <div className=\"relative inline-flex\">\n <TopBarPopover\n label=\"Alerts & Notifications\"\n description=\"System alerts and recent activity for the active organization.\"\n slot=\"notifications\"\n fallbackIcon={BellGlyph}\n badge={loading ? 0 : badgeCount}\n onOpen={onOpen}\n openToken={openToken}\n onOpenChange={setPanelOpen}\n hideTooltip={toastVisible}\n >\n <div className=\"px-4 py-3\">\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Notifications\n </p>\n {/* Only shown once silenced — the way back, in the same session. */}\n {toastsMuted ? (\n <button\n type=\"button\"\n onClick={() => setMuted(false)}\n className=\"text-[11px] font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n Unsilence\n </button>\n ) : null}\n </div>\n {loading ? (\n <div className=\"flex flex-col gap-2 py-1\">\n <ValueSkeleton className=\"h-4 w-full\" />\n <ValueSkeleton className=\"h-4 w-3/4\" />\n </div>\n ) : error ? (\n <p className=\"text-sm text-[color:var(--muted)]\">\n Notifications are unavailable right now.\n </p>\n ) : isEmpty ? (\n <p className=\"py-1 text-sm text-[color:var(--muted)]\">You’re all caught up.</p>\n ) : (\n <div className=\"flex max-h-80 flex-col gap-2 overflow-y-auto\">\n {/* Alerts (with per-item read toggle) + replies — unchanged order. */}\n {alerts.length > 0 || replies.length > 0 ? (\n <ul className=\"flex flex-col gap-1\">\n {alerts.map((a) => {\n const isRead = isAlertRead(a)\n return (\n <li key={a.id} className={isRead ? 'opacity-50' : undefined}>\n <div className=\"flex items-start gap-1 rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n <a\n href={a.href ?? '#'}\n onClick={() => markRead(a.id)}\n className=\"block min-w-0 flex-1\"\n >\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {a.title}\n </p>\n <p className=\"text-xs text-[color:var(--muted)]\">{a.description}</p>\n </a>\n <button\n type=\"button\"\n aria-label={isRead ? 'Mark as unread' : 'Mark as read'}\n onClick={() => (isRead && !notificationsAdapter ? markUnread(a.id) : markRead(a.id))}\n className=\"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)]\"\n >\n <CheckGlyph />\n </button>\n </div>\n </li>\n )\n })}\n {/* A reply row is a REAL link when it carries a deep-link, so\n the hover highlight leads somewhere: the conversation the\n reply arrived in (reported 2026-08-12). Rows without an\n href stay inert rather than pretending to be clickable. */}\n {replies.map((r) => {\n const body = (\n <>\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {r.name}\n </p>\n <p className=\"truncate text-xs text-[color:var(--muted)]\">{r.preview}</p>\n </>\n )\n return (\n <li key={r.id}>\n {r.href ? (\n <a\n href={r.href}\n aria-label={`Open the conversation with ${r.name}`}\n className=\"block rounded-lg px-2 py-2 transition hover:bg-[color:var(--panel)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-accent)]\"\n >\n {body}\n </a>\n ) : (\n <div className=\"rounded-lg px-2 py-2\">{body}</div>\n )}\n </li>\n )\n })}\n </ul>\n ) : null}\n\n {/* Imports — running/finished contact imports. */}\n {imports.length > 0 ? (\n <div>\n <p className=\"mb-1 px-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Imports\n </p>\n <ul className=\"flex flex-col gap-1\">\n {imports.map((imp) => (\n <li key={imp.id} className=\"rounded-lg px-2 py-2 hover:bg-[color:var(--panel)]\">\n {imp.href ? (\n <a href={imp.href} className=\"block\">\n <ImportRow imp={imp} />\n </a>\n ) : (\n <ImportRow imp={imp} />\n )}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {/* Quarantined contact clusters. */}\n {quarantined.length > 0 ? (\n <div>\n <div className=\"mb-1 flex items-center justify-between px-2\">\n <p className=\"text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Quarantined Contacts\n </p>\n <a\n href={withOrgParam(QUARANTINED_CONTACTS_URL, orgId)}\n className=\"text-[11px] font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n View all\n </a>\n </div>\n <ul className=\"flex flex-col gap-1\">\n {/* Each row is a REAL link, not a div with a hover class. It\n used to carry a hover highlight on a non-interactive <li>,\n so the row advertised interactivity and then did nothing\n when clicked (reported 2026-08-03). An affordance has to\n lead somewhere: the row opens the quarantined-contacts\n view filtered to that number — the same destination as\n \"View all\", scoped. Being an <a> makes it keyboard\n focusable and Enter-activatable for free. */}\n {quarantined.map((q) => (\n <li key={q.phone}>\n <a\n href={withPhoneParam(withOrgParam(QUARANTINED_CONTACTS_URL, orgId), q.phone)}\n aria-label={`Review ${q.count} quarantined message${q.count === 1 ? '' : 's'} from ${formatPhone(q.phone)}`}\n className=\"block rounded-lg px-2 py-2 transition hover:bg-[color:var(--nav-row-hover)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--color-accent)]\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {formatPhone(q.phone)}\n </span>\n {/* Same geometry as the shared TopBarCountBadge (16px\n circle, 10px/400, px-1); it sits in flow rather\n than absolutely on a 32px trigger, because this is\n a list row and not a top-bar icon. */}\n <span className=\"flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--panel)] px-1 text-[10px] font-normal leading-none tabular-nums text-[color:var(--muted)]\">\n {q.count > 99 ? '99+' : q.count}\n </span>\n </div>\n {q.latestAt ? (\n <p className=\"text-xs text-[color:var(--muted)]\">\n {new Date(q.latestAt).toLocaleString()}\n </p>\n ) : null}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n </div>\n )}\n </div>\n </TopBarPopover>\n {/* Only ONE surface at this anchor at a time: the toast yields to the panel\n (both hang off the bell trigger, so rendering both means the toast sits\n on the panel's header — Reference/UI-Platform, one surface per trigger). */}\n {toastVisible && toastReply ? (\n <NewReplyToast\n reply={toastReply}\n onActivate={onToastActivate}\n onClose={() => setToastReply(null)}\n onSilence={onToastSilence}\n />\n ) : null}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SupportAction — life-buoy trigger + the shared support-request modal\n// (never a mailto:, never an app-local form — Reference/UI-Platform).\n// ---------------------------------------------------------------------------\n\n/**\n * Compose the delivered support message: the user's note, then a context block\n * carrying the page, URL and active org — plus a Reply-to line when the user\n * had to supply contact details the profile was missing. The upstream contract\n * stays `POST support { message }`; this just enriches the text (VRM parity).\n */\nfunction composeSupportMessage(input: {\n note: string\n pageTitle: string\n url: string\n orgName?: string | null\n replyEmail?: string\n replyPhone?: string\n}): string {\n const ctx = [`Page: ${input.pageTitle || 'Unknown'}`, `URL: ${input.url}`]\n if (input.orgName) ctx.push(`Org: ${input.orgName}`)\n const reply = [input.replyEmail?.trim(), input.replyPhone?.trim()].filter(Boolean).join(' / ')\n if (reply) ctx.push(`Reply-to: ${reply}`)\n return `${input.note.trim()}\\n\\n---\\n${ctx.join('\\n')}`\n}\n\nexport function SupportAction({\n orgId,\n orgs: knownOrgs,\n}: { orgId?: string | null; orgs?: { id: string; name: string | null }[] } = {}) {\n const { fetchJson } = useNavChrome('SupportAction')\n const { me, loaded } = useChromeMe()\n // A caller that already holds the org list skips the chrome `/api/orgs` call.\n const { orgs: fetchedOrgs } = useChromeOrgs({ enabled: !knownOrgs })\n const orgs = knownOrgs ?? fetchedOrgs\n const [open, setOpen] = useState(false)\n const [message, setMessage] = useState('')\n const [email, setEmail] = useState('')\n const [phone, setPhone] = useState('')\n const [showEmailError, setShowEmailError] = useState(false)\n const [state, setState] = useState<'idle' | 'sending' | 'sent' | 'error'>('idle')\n\n // The profile knows email/phone unless the chrome `me` loaded without them —\n // then we collect the missing one(s) in the modal (email required, phone not).\n const meEmail = me?.email ?? null\n const mePhone = me?.phone ?? null\n const missingEmail = loaded && !meEmail\n const missingPhone = loaded && !mePhone\n\n const activeOrg =\n (orgId ? orgs?.find((o) => o.id === orgId) : null) ??\n (orgs && orgs.length === 1 ? orgs[0] : null)\n const orgName = activeOrg?.name ?? null\n\n const close = useCallback(() => {\n setOpen(false)\n setState('idle')\n setMessage('')\n setShowEmailError(false)\n }, [])\n\n // Seed the contact inputs from the profile whenever the modal opens.\n useEffect(() => {\n if (!open) return\n setEmail(meEmail ?? '')\n setPhone(mePhone ?? '')\n setShowEmailError(false)\n }, [open, meEmail, mePhone])\n\n useEffect(() => {\n if (!open) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close()\n }\n document.addEventListener('keydown', onKey)\n return () => document.removeEventListener('keydown', onKey)\n }, [open, close])\n\n const submit = async () => {\n if (!message.trim() || state === 'sending') return\n\n const resolvedEmail = (missingEmail ? email : meEmail ?? '').trim()\n const resolvedPhone = (missingPhone ? phone : mePhone ?? '').trim()\n // Email is required when the profile didn't carry one.\n if (missingEmail && !resolvedEmail) {\n setShowEmailError(true)\n return\n }\n setShowEmailError(false)\n\n const collectedContact = missingEmail || missingPhone\n const fullMessage = composeSupportMessage({\n note: message,\n pageTitle: typeof document !== 'undefined' ? document.title : '',\n url: typeof window !== 'undefined' ? window.location.href : '',\n orgName,\n replyEmail: collectedContact ? resolvedEmail : undefined,\n replyPhone: collectedContact ? resolvedPhone : undefined,\n })\n\n setState('sending')\n try {\n await fetchJson('support', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ message: fullMessage }),\n })\n setState('sent')\n } catch {\n setState('error')\n }\n }\n\n return (\n <>\n <button\n type=\"button\"\n aria-label=\"Support\"\n className={topBarIconButtonClass()}\n onClick={() => setOpen(true)}\n >\n <SlotGlyph slot=\"support\" fallback={LifeBuoyGlyph} />\n <TopBarTooltip\n title=\"Support\"\n description=\"Send a support request to the Politogy team.\"\n />\n </button>\n {open && typeof document !== 'undefined'\n ? createPortal(\n <div\n // Portaled to <body>: the top bar's backdrop-blur creates a CSS\n // containing block, so a fixed-position descendant would center on\n // the HEADER (rendering off-screen) instead of the viewport.\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Support request\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) close()\n }}\n >\n <div className=\"w-full max-w-md rounded-2xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-6 shadow-[var(--shadow-soft)]\">\n <h2 className=\"text-lg font-bold tracking-[-0.01em] text-[color:var(--foreground)]\">\n Contact Support\n </h2>\n {state === 'sent' ? (\n <>\n <p className=\"mt-3 text-sm text-[color:var(--muted)]\">\n Your request was sent. The team will reply by email.\n </p>\n <div className=\"mt-5 flex justify-end\">\n <button\n type=\"button\"\n onClick={close}\n className=\"rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] px-4 py-2 text-sm font-semibold text-[#FFFFFF] hover:opacity-90\"\n >\n Done\n </button>\n </div>\n </>\n ) : (\n <>\n <p className=\"mt-1 text-sm text-[color:var(--muted)]\">\n Describe the problem or question. Your account details ride along\n automatically.\n </p>\n {missingEmail ? (\n <label className=\"mt-4 block\">\n <span className=\"mb-1 block text-xs font-semibold text-[color:var(--foreground)]\">\n Your email\n </span>\n <input\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n {showEmailError ? (\n <span className=\"mt-1 block text-xs text-[color:var(--chrome-danger)]\">\n Enter an email so support can reply.\n </span>\n ) : null}\n </label>\n ) : null}\n {missingPhone ? (\n <label className=\"mt-3 block\">\n <span className=\"mb-1 block text-xs font-semibold text-[color:var(--foreground)]\">\n Your phone — optional\n </span>\n <input\n type=\"tel\"\n value={phone}\n onChange={(e) => setPhone(e.target.value)}\n placeholder=\"(503) 555-1212\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n </label>\n ) : null}\n <textarea\n value={message}\n onChange={(e) => setMessage(e.target.value)}\n rows={5}\n placeholder=\"How can we help?\"\n className=\"mt-4 w-full resize-y rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-2 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n {state === 'error' ? (\n <p className=\"mt-2 text-sm text-[color:var(--chrome-danger)]\">\n Sending failed — try again.\n </p>\n ) : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n onClick={close}\n className=\"rounded-full border border-[color:var(--line)] px-4 py-2 text-sm font-semibold text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={submit}\n disabled={!message.trim() || state === 'sending'}\n className=\"rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] px-4 py-2 text-sm font-semibold text-[#FFFFFF] transition hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {state === 'sending' ? 'Sending…' : 'Send request'}\n </button>\n </div>\n </>\n )}\n </div>\n </div>,\n document.body,\n )\n : null}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// SpecOverlayAction — Spencer + Ben only. A top-bar \"Spec\" trigger showing\n// the current page's spec compliance / visual-regression status, from the\n// Specs app's overlay API. Renders NOTHING when the viewer isn't allowed —\n// no icon, no badge, no console noise — so this is invisible to every other\n// user. All calls are plain cross-origin fetches with same-site cookies\n// (credentials: 'include'); this does NOT go through the chrome proxy\n// fetchJson, which is same-origin only.\n// ---------------------------------------------------------------------------\n\ntype SpecOverlayAccess = { allowed: boolean; email?: string }\n\ntype SpecOverlayStatus =\n | {\n matched: true\n spec_slug: string\n spec_title: string\n target_id: string\n label: string\n viewport: string\n /** null when there is no finished compare run yet — never coerce to 0. */\n mismatch_pct: number | null\n finished_at: string | null\n passed: boolean | null\n spec_url: string\n compare_url: string\n overlay_url: string\n live_selector?: string | null\n capture_url?: string\n theme?: 'light' | 'dark' | null\n live_source?: 'worker' | 'viewer' | null\n live_size?: { width: number; height: number } | null\n design_size?: { width: number; height: number } | null\n /** Ready-to-paste repair prompt for an AI agent (latest run). */\n prompt?: string | null\n }\n | { matched: false; search_url: string }\n\nconst SPEC_OVERLAY_ACCESS_CACHE_KEY = 'politogy_spec_overlay_access'\n\nfunction readSpecOverlayAccessCache(): SpecOverlayAccess | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.sessionStorage.getItem(SPEC_OVERLAY_ACCESS_CACHE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (typeof parsed?.allowed === 'boolean') return parsed as SpecOverlayAccess\n } catch {\n /* ignore */\n }\n return null\n}\n\nfunction writeSpecOverlayAccessCache(access: SpecOverlayAccess): void {\n if (typeof window === 'undefined') return\n try {\n window.sessionStorage.setItem(SPEC_OVERLAY_ACCESS_CACHE_KEY, JSON.stringify(access))\n } catch {\n /* ignore */\n }\n}\n\n/**\n * Notifies subscribers whenever the URL changes via pushState, replaceState\n * or a back/forward navigation. Patches `history` exactly once per page\n * (module-level guard) no matter how many components subscribe.\n */\ntype LocationChangeListener = () => void\nconst locationChangeListeners = new Set<LocationChangeListener>()\nlet historyPatched = false\n\nfunction ensureHistoryPatched(): void {\n if (historyPatched || typeof window === 'undefined') return\n historyPatched = true\n const notify = () => locationChangeListeners.forEach((fn) => fn())\n const originalPushState = window.history.pushState.bind(window.history)\n const originalReplaceState = window.history.replaceState.bind(window.history)\n window.history.pushState = (...args: Parameters<History['pushState']>) => {\n originalPushState(...args)\n notify()\n }\n window.history.replaceState = (...args: Parameters<History['replaceState']>) => {\n originalReplaceState(...args)\n notify()\n }\n window.addEventListener('popstate', notify)\n}\n\nfunction useLocationHref(): string {\n const [href, setHref] = useState(() =>\n typeof window === 'undefined' ? '' : window.location.href,\n )\n useEffect(() => {\n ensureHistoryPatched()\n const onChange = () => setHref(window.location.href)\n locationChangeListeners.add(onChange)\n return () => {\n locationChangeListeners.delete(onChange)\n }\n }, [])\n return href\n}\n\nfunction specOverlayFetchJson(path: string): Promise<unknown> {\n // Bounded: this hits a cross-origin app (specs.politogyvrm.com) from every\n // page's top bar. An unbounded call here let a stuck access/status check\n // keep the page's network alive indefinitely — which blocks `networkidle`\n // and tripped visual-regression captures' own 45s navigation timeout on\n // the very pages this widget instruments (seen on a2p 2026-10-02).\n return fetch(`${SPECS_ORIGIN}${path}`, { credentials: 'include', signal: AbortSignal.timeout(10_000) }).then((res) => {\n if (!res.ok) throw new Error(`spec overlay ${path}: ${res.status}`)\n return res.json()\n })\n}\n\n/**\n * True when this page is being driven by an automated capture session\n * (Cloudflare Browser Rendering / CDP-controlled Chromium — the Specs\n * design-compare tool, among others) rather than a real Spencer/Ben\n * session. `navigator.webdriver` is the standard CDP automation flag.\n * SpecOverlayAction must never self-trigger a capture loop in this case:\n * doing so competed with the very capture session rendering the page for\n * network activity, keeping `networkidle` from ever being reached.\n */\nfunction isAutomatedCaptureSession(): boolean {\n return typeof navigator !== 'undefined' && navigator.webdriver === true\n}\n\nfunction currentChromeTheme(): 'light' | 'dark' {\n const root = document.documentElement\n if (root.classList.contains('dark') || root.getAttribute('data-theme') === 'dark') return 'dark'\n if (root.classList.contains('light') || root.getAttribute('data-theme') === 'light') return 'light'\n return 'light'\n}\n\n/** Marks the drawer portal so the page raster leaves it out. */\nconst SPEC_OVERLAY_ROOT_ATTR = 'data-spec-overlay-root'\n\n/**\n * The viewer's real view: rasterize THIS page in the browser (DOM → canvas,\n * no permission prompt) at viewport size, without the Spec drawer, and send it\n * to Specs as the LIVE side of a compare. Their org, data and theme are\n * exactly what is on screen, cropped to the content region. Nothing but the PNG\n * and page facts leaves the browser.\n */\nasync function captureMyView(\n status: Extract<SpecOverlayStatus, { matched: true }>,\n orgId: string | null | undefined,\n orgName: string | null | undefined,\n): Promise<void> {\n const { domToCanvas } = await import('modern-screenshot')\n const w = window.innerWidth\n const h = window.innerHeight\n const theme = currentChromeTheme()\n const bg = getComputedStyle(document.body).backgroundColor || (theme === 'dark' ? '#0b0b0c' : '#ffffff')\n const full = await domToCanvas(document.body, {\n width: w,\n height: h,\n scale: 1,\n backgroundColor: bg,\n // Cross-origin images that refuse CORS render blank instead of failing.\n fetch: { requestInit: { mode: 'cors', credentials: 'omit' }, placeholderImage: '' },\n // Drop the Spec drawer and everything fixed (sidebar, toasts, popovers):\n // the design is the page body only, so chrome would only add noise.\n filter: (node) =>\n !(node instanceof Element) ||\n (!node.hasAttribute(SPEC_OVERLAY_ROOT_ATTR) && getComputedStyle(node).position !== 'fixed'),\n style: { transform: `translate(${-window.scrollX}px, ${-window.scrollY}px)` },\n })\n\n // Score the content region only — the target's live_selector, else the\n // shell's content column (below the top bar and beta banner, right of the\n // sidebar) — so LIVE covers the same region as the design export.\n const el =\n (status.live_selector ? document.querySelector(status.live_selector) : null) ??\n document.querySelector('[data-shell-content]')\n let region = { x: 0, y: 0, width: w, height: h }\n if (el) {\n const r = el.getBoundingClientRect()\n const x = Math.max(0, Math.round(r.left))\n const y = Math.max(0, Math.round(r.top))\n region = { x, y, width: Math.min(w - x, Math.round(r.width)), height: Math.min(h - y, Math.round(r.height)) }\n }\n const out = document.createElement('canvas')\n out.width = region.width\n out.height = region.height\n const ctx = out.getContext('2d')\n if (!ctx) throw new Error('page raster failed')\n ctx.drawImage(full, region.x, region.y, region.width, region.height, 0, 0, region.width, region.height)\n const blob = await new Promise<Blob | null>((resolve) => out.toBlob(resolve, 'image/png'))\n if (!blob) throw new Error('page raster failed')\n const form = new FormData()\n form.append('image', blob, 'live.png')\n form.append(\n 'meta',\n JSON.stringify({ url: window.location.href, theme, org_id: orgId ?? null, org_name: orgName ?? null, crop: null }),\n )\n const res = await fetch(status.capture_url ?? `${SPECS_ORIGIN}/api/overlay/capture`, {\n method: 'POST',\n credentials: 'include',\n headers: { 'X-Spec-Capture': '1' },\n body: form,\n signal: AbortSignal.timeout(10_000),\n })\n if (!res.ok) throw new Error(`capture ${res.status}: ${(await res.text()).slice(0, 160)}`)\n}\n\n/** Spinner + LIVE/DIFF skeletons shown while the capture and compare run. */\nexport function SpecCaptureLoading() {\n return (\n <div data-spec-capture-loading=\"\" role=\"status\" aria-live=\"polite\" className=\"flex-1 overflow-hidden px-4 py-4\">\n <div className=\"mb-4 flex items-center gap-3 text-sm text-[color:var(--foreground)]\">\n <span\n aria-hidden=\"true\"\n className=\"inline-block h-5 w-5 animate-spin rounded-full border-2 border-[color:var(--line)] border-t-[color:var(--color-accent)] motion-reduce:animate-none\"\n />\n Capturing your view and comparing…\n </div>\n {['Live — your view', 'Diff'].map((label) => (\n <div key={label} className=\"mb-4\">\n <p className=\"mb-1 text-xs font-semibold uppercase tracking-wide text-[color:var(--muted)]\">{label}</p>\n <div aria-hidden=\"true\" className=\"h-40 w-full animate-pulse rounded border border-[color:var(--line)] bg-[color:var(--panel)] motion-reduce:animate-none\" />\n </div>\n ))}\n </div>\n )\n}\n\n/** Status URL for this page in the viewer's current theme. */\nfunction specOverlayStatusPath(): string {\n return `/api/overlay/status?url=${encodeURIComponent(window.location.href)}&theme=${currentChromeTheme()}`\n}\n\nexport function SpecOverlayAction({ orgId, orgName }: { orgId?: string | null; orgName?: string | null } = {}) {\n const [access, setAccess] = useState<SpecOverlayAccess | null>(() => readSpecOverlayAccessCache())\n const [status, setStatus] = useState<SpecOverlayStatus | null>(null)\n const [open, setOpen] = useState(false)\n const [capture, setCapture] = useState<{ state: 'idle' | 'busy' | 'error'; message?: string }>({ state: 'idle' })\n const [frameKey, setFrameKey] = useState(0)\n const [copied, setCopied] = useState<'idle' | 'copied' | 'failed'>('idle')\n const href = useLocationHref()\n const automated = isAutomatedCaptureSession()\n\n // Resolve access once per session (cached in sessionStorage).\n useEffect(() => {\n if (access || automated) return\n let cancelled = false\n specOverlayFetchJson('/api/overlay/access')\n .then((data) => {\n if (cancelled) return\n const next: SpecOverlayAccess =\n data && typeof (data as SpecOverlayAccess).allowed === 'boolean'\n ? (data as SpecOverlayAccess)\n : { allowed: false }\n setAccess(next)\n writeSpecOverlayAccessCache(next)\n })\n .catch(() => {\n if (cancelled) return\n const next: SpecOverlayAccess = { allowed: false }\n setAccess(next)\n writeSpecOverlayAccessCache(next)\n })\n return () => {\n cancelled = true\n }\n }, [access])\n\n // Fetch status for the current page, debounced 300ms, on every route\n // change and org change. Only once access is known to be allowed.\n useEffect(() => {\n if (automated || !access?.allowed || typeof window === 'undefined') return\n const timer = window.setTimeout(() => {\n specOverlayFetchJson(specOverlayStatusPath())\n .then((data) => setStatus(data as SpecOverlayStatus))\n .catch(() => setStatus(null))\n }, 300)\n return () => window.clearTimeout(timer)\n }, [access?.allowed, href, orgId])\n\n // Opening the drawer captures the viewer's real view automatically — no\n // click, no prompt. The raster runs while the drawer is open; the drawer is\n // filtered out of the frame. One capture per open.\n const captureRun = useRef(0)\n // Live-read access inside the retry loop below: access can be revoked\n // mid-poll (session expiry, org switch), and the loop must stop hitting\n // /api/overlay/status the moment that happens rather than riding out its\n // full 45 × 3s budget regardless.\n const accessRef = useRef(access)\n accessRef.current = access\n const runCapture = async (s: Extract<SpecOverlayStatus, { matched: true }>) => {\n const run = ++captureRun.current\n const before = s.live_source === 'viewer' ? s.finished_at : null\n setCapture({ state: 'busy' })\n try {\n // Let the drawer paint first so the page is idle while we raster.\n await new Promise((r) => setTimeout(r, 150))\n await captureMyView(s, orgId, orgName)\n for (let i = 0; i < 45; i++) {\n await new Promise((r) => setTimeout(r, 3000))\n if (run !== captureRun.current) return\n // Access lost mid-poll: stop, but never leave the spinner up forever.\n if (!accessRef.current?.allowed) {\n setCapture({ state: 'idle' })\n return\n }\n const next = (await specOverlayFetchJson(specOverlayStatusPath()).catch(() => null)) as SpecOverlayStatus | null\n if (next && next.matched && next.live_source === 'viewer' && next.finished_at !== before) {\n setStatus(next)\n setFrameKey((k) => k + 1)\n setCapture({ state: 'idle' })\n return\n }\n }\n setCapture({ state: 'error', message: 'Compare did not finish in 2 min.' })\n } catch (e) {\n if (run === captureRun.current) setCapture({ state: 'error', message: e instanceof Error ? e.message : String(e) })\n }\n }\n useEffect(() => {\n if (automated || !open || !status || !status.matched) return\n void runCapture(status)\n return () => {\n captureRun.current++\n }\n // Only re-run on open / page change, not on every status refresh.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, status && status.matched ? status.target_id : null])\n\n\n if (automated || !access?.allowed) return null\n\n const hasScore = status && status.matched && typeof status.mismatch_pct === 'number'\n const badgeLabel =\n hasScore ? `${Math.round((status as Extract<SpecOverlayStatus, { matched: true }>).mismatch_pct as number)}%` : status ? '—' : undefined\n const badgeTone: 'default' | 'warning' | 'danger' =\n hasScore ? (status && status.matched && status.passed ? 'default' : 'danger') : 'default'\n\n return (\n <>\n <button\n type=\"button\"\n aria-label=\"Spec\"\n aria-expanded={open}\n className={topBarIconButtonClass(badgeTone)}\n onClick={() => setOpen(true)}\n >\n <LayoutGlyph size={TOPBAR_GLYPH_SIZE} className=\"text-current\" />\n {badgeLabel ? (\n <span\n className={[\n 'absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-normal leading-none text-[#FFFFFF]',\n hasScore\n ? status && status.matched && status.passed\n ? 'bg-[color:var(--chrome-success,#2f855a)]'\n : 'bg-[color:var(--chrome-danger)]'\n : 'bg-[color:var(--muted)]',\n ].join(' ')}\n >\n {badgeLabel}\n </span>\n ) : null}\n {!open ? (\n <TopBarTooltip\n title=\"Spec\"\n description=\"Spec design + visual regression for this page.\"\n />\n ) : null}\n </button>\n {open && typeof document !== 'undefined'\n ? createPortal(\n <div\n className=\"fixed inset-0 z-50 flex justify-end bg-black/40\"\n {...{ [SPEC_OVERLAY_ROOT_ATTR]: '' }}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Spec overlay\"\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) setOpen(false)\n }}\n onKeyDown={(e) => {\n if (e.key === 'Escape') setOpen(false)\n }}\n >\n <div className=\"flex h-full w-full max-w-[480px] flex-col border-l border-[color:var(--line)] bg-[color:var(--panel-elevated)] shadow-[var(--shadow-soft)]\">\n <div className=\"flex items-center justify-between gap-2 border-b border-[color:var(--line)] px-4 py-3\">\n <h2 className=\"truncate text-sm font-bold tracking-[-0.01em] text-[color:var(--foreground)]\">\n Spec{status && status.matched ? `: ${status.spec_title}` : ''}\n </h2>\n <button\n type=\"button\"\n aria-label=\"Close\"\n onClick={() => setOpen(false)}\n className=\"rounded-full p-1 text-[color:var(--muted)] hover:bg-[color:var(--panel)] hover:text-[color:var(--foreground)]\"\n >\n <CloseGlyph size={16} />\n </button>\n </div>\n {status && status.matched ? (\n <>\n <div className=\"flex items-center gap-3 border-b border-[color:var(--line)] px-4 py-2 text-xs font-semibold\">\n <a\n href={status.spec_url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n Open spec ↗\n </a>\n <a\n href={status.compare_url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n Compare tab ↗\n </a>\n <button\n type=\"button\"\n disabled={capture.state === 'busy'}\n onClick={() => void runCapture(status)}\n className=\"ml-auto rounded-md border border-[color:var(--line)] px-2 py-1 text-[color:var(--foreground)] hover:bg-[color:var(--panel)] disabled:opacity-60\"\n title=\"Your view is captured when the drawer opens. Recapture after changing the page.\"\n >\n {capture.state === 'busy' ? 'Capturing…' : 'Recapture'}\n </button>\n <button\n type=\"button\"\n data-spec-copy-prompt=\"\"\n disabled={capture.state === 'busy' || !status.prompt}\n onClick={() => {\n const text = status.prompt\n if (!text) return\n // The prompt is already in hand, so the write stays inside the click gesture.\n navigator.clipboard\n .writeText(text)\n .then(() => setCopied('copied'))\n .catch(() => setCopied('failed'))\n .finally(() => window.setTimeout(() => setCopied('idle'), 2000))\n }}\n className=\"rounded-md border border-[color:var(--line)] px-2 py-1 text-[color:var(--foreground)] hover:bg-[color:var(--panel)] disabled:opacity-60\"\n title=\"Copy a repair prompt for an AI agent: spec, score, image links, top mismatched regions and instructions.\"\n >\n {copied === 'copied' ? 'Copied ✓' : copied === 'failed' ? 'Copy failed' : 'Copy prompt'}\n </button>\n </div>\n {status.live_size && status.design_size && capture.state !== 'busy' ? (\n <p\n data-spec-sizes=\"\"\n className={[\n 'border-b border-[color:var(--line)] px-4 py-1.5 text-xs',\n status.live_size.width === status.design_size.width &&\n status.live_size.height === status.design_size.height\n ? 'text-[color:var(--muted)]'\n : 'font-semibold text-[color:var(--chrome-danger)]',\n ].join(' ')}\n >\n Live {status.live_size.width}×{status.live_size.height} · Design {status.design_size.width}×\n {status.design_size.height}\n {status.live_size.width === status.design_size.width &&\n status.live_size.height === status.design_size.height\n ? ' · sizes match'\n : ' · SIZE MISMATCH'}\n </p>\n ) : null}\n {capture.state === 'error' ? (\n <p className=\"border-b border-[color:var(--line)] px-4 py-2 text-xs text-[color:var(--chrome-danger)]\">\n {capture.message}\n </p>\n ) : null}\n {capture.state === 'busy' ? (\n <SpecCaptureLoading />\n ) : (\n <iframe\n key={frameKey}\n src={status.overlay_url}\n title=\"Spec overlay\"\n className=\"h-full w-full flex-1 border-0\"\n />\n )}\n </>\n ) : status && !status.matched ? (\n <div className=\"p-4 text-sm text-[color:var(--muted)]\">\n <p>No compare target covers this page.</p>\n <a\n href={status.search_url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"mt-2 inline-block font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:underline\"\n >\n Search specs ↗\n </a>\n </div>\n ) : (\n <div className=\"p-4\">\n <ValueSkeleton className=\"h-4 w-full\" />\n </div>\n )}\n </div>\n </div>,\n document.body,\n )\n : null}\n </>\n )\n}\n\nfunction CloseGlyph({ size = 16, className }: { size?: number; className?: string }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" className={className} aria-hidden>\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\n// ---------------------------------------------------------------------------\n// NavDisplayAction — the Menu / Tabs / Both navigation-display switcher.\n// Controlled: the app owns persistence (localStorage/profile) and layout\n// consequences (sub-menu visibility, tab strip visibility).\n// ---------------------------------------------------------------------------\n\nexport type NavDisplayMode = 'menu' | 'tabs' | 'both'\n\nexport const NAV_DISPLAY_OPTIONS: { value: NavDisplayMode; label: string }[] = [\n { value: 'menu', label: 'Sub Menu' },\n { value: 'tabs', label: 'Tabs Only' },\n { value: 'both', label: 'Both' },\n]\n\nexport function NavDisplayAction({\n value,\n onChange,\n}: {\n value: NavDisplayMode\n onChange: (next: NavDisplayMode) => void\n}) {\n return (\n <TopBarPopover\n label=\"Navigation Display\"\n description=\"Show navigation as a sub-menu, tabs, or both.\"\n fallbackIcon={LayoutGlyph}\n panelClassName=\"w-44\"\n >\n <div className=\"py-1\" role=\"radiogroup\" aria-label=\"Navigation display\">\n {NAV_DISPLAY_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={value === opt.value}\n onClick={() => onChange(opt.value)}\n className={[\n 'flex w-full items-center justify-between px-4 py-2 text-left text-sm font-medium',\n value === opt.value\n ? 'text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n {opt.label}\n {value === opt.value ? <span aria-hidden>✓</span> : null}\n </button>\n ))}\n </div>\n </TopBarPopover>\n )\n}\n\n// ---------------------------------------------------------------------------\n// useThemePreference — the cross-app theme state machine (Task: theme derived\n// from the Auth system, live across tabs and apps).\n//\n// boot : cookie → localStorage → \"system\" (the pre-paint script already\n// painted this), then ONCE per session reconcile against the\n// profile value from `GET me` (authoritative) when a fetcher is\n// available.\n// change : apply + localStorage + cross-subdomain cookie + best-effort\n// `PATCH me/preferences { themePreference }`.\n// sync : same-app tabs via the `storage` event; other-app tabs re-read the\n// shared cookie on focus/visibility; `system` follows live OS\n// changes via matchMedia.\n// ---------------------------------------------------------------------------\n\nexport function useThemePreference(): {\n value: ThemePreference\n setValue: (next: ThemePreference) => void\n} {\n const ctx = useContext(NavChromeContext)\n const fetchJson = ctx?.fetchJson ?? null\n const [value, setValueState] = useState<ThemePreference>('system')\n const reconciled = useRef(false)\n\n // Boot: cookie → localStorage → system.\n useEffect(() => {\n const cookie = readThemeCookie()\n let ls: string | null = null\n try {\n ls = localStorage.getItem(THEME_STORAGE_KEY)\n } catch {\n /* unavailable */\n }\n const pref = cookie ?? (isThemePreference(ls) ? ls : null) ?? 'system'\n setValueState(pref)\n applyThemePreference(pref)\n }, [])\n\n // Once per session: converge on the profile's saved choice (authoritative),\n // reusing the provider's single `me` fetch.\n const meCtx = useContext(NavChromeContext)\n useEffect(() => {\n if (reconciled.current) return\n // A choice made where no chrome-API session exists (Politogy ID's login\n // screen) is still only in the cookie. Push it UP rather than pulling the\n // stale profile value DOWN — otherwise the user's fresh pick is silently\n // reverted on the next app they open (HITL 2026-07-23: \"I set System and it\n // keeps switching back to Light\").\n const pending = readPendingThemeChoice()\n if (pending) {\n // Only latch once the profile write has actually been attempted, so a\n // later `me` arrival still gets a chance to persist it.\n if (meCtx?.me) reconciled.current = true\n setValueState(pending)\n applyThemePreference(pending)\n writeThemeCookie(pending)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, pending)\n } catch {\n /* unavailable */\n }\n if (!meCtx?.me) return\n fetchJson?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ themePreference: pending }),\n })\n .then(() => clearPendingThemeChoice())\n .catch(() => {})\n return\n }\n const pref = meCtx?.me?.themePreference\n if (isThemePreference(pref)) {\n reconciled.current = true\n setValueState(pref)\n applyThemePreference(pref)\n writeThemeCookie(pref)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, pref)\n } catch {\n /* unavailable */\n }\n }\n }, [meCtx?.me])\n\n // Live sync: storage events (same-app tabs), focus/visibility cookie\n // re-reads (other-app tabs), and OS changes while on \"system\".\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === THEME_STORAGE_KEY && isThemePreference(e.newValue)) {\n setValueState(e.newValue)\n applyThemePreference(e.newValue)\n }\n }\n const onWake = () => {\n const cookie = readThemeCookie()\n if (cookie) {\n setValueState((prev) => {\n if (cookie !== prev) applyThemePreference(cookie)\n return cookie\n })\n }\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [])\n\n\n const setValue = useCallback(\n (next: ThemePreference) => {\n setValueState(next)\n applyThemePreference(next)\n writeThemeCookie(next)\n try {\n localStorage.setItem(THEME_STORAGE_KEY, next)\n } catch {\n /* unavailable */\n }\n // Best-effort profile persistence — a theme toggle never errors. Until it\n // lands, the choice stays marked pending so the next app pushes it up\n // instead of reconciling the stale profile value back down.\n markThemeChoicePending(next)\n fetchJson?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ themePreference: next }),\n })\n .then(() => clearPendingThemeChoice())\n .catch(() => {})\n },\n [fetchJson],\n )\n\n return { value, setValue }\n}\n","import type { NavIcon } from './index'\nimport type { StandardNavIconKey } from './standardNav'\nimport {\n LuActivity,\n LuBriefcase,\n LuChartColumn,\n LuChartNoAxesColumn,\n LuCircleUser,\n LuClipboardList,\n LuClock,\n LuCreditCard,\n LuCrosshair,\n LuDollarSign,\n LuDoorOpen,\n LuFileText,\n LuFlag,\n LuHouse,\n LuLandmark,\n LuLayoutDashboard,\n LuLayoutGrid,\n LuLifeBuoy,\n LuList,\n LuMail,\n LuMap,\n LuMapPin,\n LuMessageSquare,\n LuMousePointerClick,\n LuPencil,\n LuPhone,\n LuSend,\n LuSettings,\n LuShare2,\n LuSignpost,\n LuTarget,\n LuUpload,\n LuUser,\n LuUsers,\n LuUsersRound,\n} from 'react-icons/lu'\n\n/**\n * The canonical icon map for standardPolitogyNav — ONE definition so every\n * app renders identical glyphs (including the Organization Settings branch:\n * briefcase / settings / creditCard / dollarSign / share).\n */\nexport const standardNavIcons: Record<StandardNavIconKey, NavIcon> = {\n home: LuHouse,\n users: LuUsers,\n mail: LuMail,\n messageSquare: LuMessageSquare,\n layout: LuLayoutDashboard,\n activity: LuActivity,\n lifeBuoy: LuLifeBuoy,\n grid: LuLayoutGrid,\n list: LuList,\n upload: LuUpload,\n edit: LuPencil,\n fileText: LuFileText,\n send: LuSend,\n clock: LuClock,\n user: LuUser,\n barChart: LuChartColumn,\n briefcase: LuBriefcase,\n settings: LuSettings,\n creditCard: LuCreditCard,\n dollarSign: LuDollarSign,\n share: LuShare2,\n // Campaign / Petition mode slots.\n phone: LuPhone,\n map: LuMap,\n mapPin: LuMapPin,\n target: LuTarget,\n flag: LuFlag,\n layoutDashboard: LuLayoutDashboard,\n usersRound: LuUsersRound,\n mousePointerClick: LuMousePointerClick,\n clipboardList: LuClipboardList,\n circleUser: LuCircleUser,\n crosshair: LuCrosshair,\n landmark: LuLandmark,\n chartNoAxes: LuChartNoAxesColumn,\n doorOpen: LuDoorOpen,\n signpost: LuSignpost,\n}\n","import { standardNavIcons } from './standardNavIcons'\nimport type { NavIcon, NavItem } from './index'\n\n// ---------------------------------------------------------------------------\n// standardPolitogyNav — the canonical Politogy VRM menu, per operating Mode.\n//\n// This is the single source of truth for the navigation every politogy app\n// renders. The RELATIONSHIP tree is extracted verbatim from VRM core's\n// relationship-mode sidebar (`getRelationshipLinkItems`); the CAMPAIGN and\n// PETITION trees mirror VRM core's mode-scoped menus. Apps consume the same\n// menu everywhere; an app that owns one of the items (e.g. the standalone\n// Contacts app) nests its own pages as that item's children while every other\n// entry links out to another *.politogyvrm.com app as an absolute URL —\n// full-page navigation with SSO shared across the domain.\n//\n// Which tree an app renders is NOT the user's live mode selection — it is the\n// app's own mode, mapped from the app registry (see `POLITOGY_APPS[app].mode`),\n// EXCEPT for a DUAL-MODE app (`POLITOGY_APPS[app].dual`, today: a2p — Specs/A2P:\n// \"the SMS/MMS delivery engine for Relationship Mode and Campaign Mode\"). A\n// dual app has no single fixed mode: its EFFECTIVE mode is resolved per-visit\n// by `resolveActiveMode` (mode-preference.ts) — `?mode=` query param on the\n// current URL → the `politogy_active_mode` cookie (written by every pinned app\n// and core whenever their own mode is known) → the app's own `dual.defaultMode`\n// — and THAT resolved value substitutes for `meta.mode` wherever this function\n// or the Mode pill would otherwise read it. A campaign-scoped, non-dual app\n// (phonebank / canvass / signs) always renders the Campaign tree; an unscoped\n// app (forms / surveys / polls / contacts) always renders Relationship, exactly\n// as before. Switching modes is a full-page navigation between mode homes (the\n// Mode pill's job), and each destination is itself pinned (or, for a2p,\n// resolved) — so the tree is deterministic from app identity + the mode\n// resolution above, never a value an app has to pass.\n// ---------------------------------------------------------------------------\n\n/**\n * Icon slots used by the standard menus. The shell stays icon-library-agnostic:\n * callers map each key to their own icon components (lucide, react-icons, …).\n * A missing key simply renders that row without an icon.\n */\nexport type StandardNavIconKey =\n | 'home'\n | 'users'\n | 'mail'\n | 'messageSquare'\n | 'layout'\n | 'activity'\n | 'lifeBuoy'\n | 'grid'\n | 'list'\n | 'upload'\n | 'edit'\n | 'fileText'\n | 'send'\n | 'clock'\n | 'user'\n | 'barChart'\n | 'briefcase'\n | 'settings'\n | 'creditCard'\n | 'dollarSign'\n | 'share'\n // Campaign / Petition mode slots.\n | 'phone'\n | 'map'\n | 'mapPin'\n | 'target'\n | 'flag'\n // Left-Navigation §9 Lucide slots.\n | 'layoutDashboard'\n | 'usersRound'\n | 'mousePointerClick'\n | 'clipboardList'\n | 'circleUser'\n | 'crosshair'\n | 'landmark'\n | 'chartNoAxes'\n | 'doorOpen'\n | 'signpost'\n\n/** The operating Mode whose nav tree to build. Defaults to `relationship`. */\nexport type StandardNavMode = 'relationship' | 'campaign' | 'petition'\n\n/**\n * Per-feature availability for the Campaign tree. Campaign Mode ships its apps\n * incrementally: a disabled feature is omitted from the nav entirely (rather\n * than rendered as a dead/disabled row), and its flag flips to `true` in a\n * later patch release as the app goes live. Dashboard and Voter Contact are\n * core-hosted and always present, so they carry no flag.\n */\nexport interface CampaignFeatureAvailability {\n a2p: boolean\n phonebank: boolean\n canvass: boolean\n signs: boolean\n tribes: boolean\n polling: boolean\n}\n\n/**\n * Launch state at this shell version: every Campaign feature is deployed and\n * live (a2p / phonebank / canvass / signs .politogyvrm.com all serve the app\n * behind SSO as of 2026-07-24), so no row is hidden. The flags remain so a\n * future feature can ship dark, and so a caller can hide one per-deployment.\n */\nexport const CAMPAIGN_FEATURE_AVAILABILITY: CampaignFeatureAvailability = {\n a2p: true,\n phonebank: true,\n canvass: true,\n signs: true,\n tribes: true,\n polling: true,\n}\n\n/** Absolute origins for the standalone Campaign / Petition apps. */\nconst A2P_ORIGIN = 'https://a2p.politogyvrm.com/'\nconst PHONEBANK_ORIGIN = 'https://phonebank.politogyvrm.com/'\nconst CANVASS_ORIGIN = 'https://canvass.politogyvrm.com/'\nconst SIGNS_ORIGIN = 'https://signs.politogyvrm.com/'\nconst POLLS_ORIGIN = 'https://polls.politogyvrm.com/'\n// app.politogyvrm.com (VRM core) is retired (Reference/UI-Platform →\n// \"Retirement of app.politogyvrm.com\", DECIDED 2026-10-07). These are its V2\n// replacements: Settings owns org settings/billing, Dashboard owns the\n// Relationship/Campaign dashboards and Battleground, auth owns the Politogy\n// ID account pages (my-profile, invite acceptance).\nconst SETTINGS_ORIGIN = 'https://settings.politogyvrm.com/'\nconst DASHBOARD_ORIGIN = 'https://dashboard.politogyvrm.com/'\nconst AUTH_ORIGIN = 'https://auth.politogyvrm.com/'\n// Tribes is a page inside the standalone Contacts app (Specs/Tribes: Tribes is\n// implemented as an extension of Contacts). Matches app-shell.tsx's `/tribes`.\nconst CONTACTS_TRIBES = 'https://contacts.politogyvrm.com/tribes'\n// Petition Mode is its own standalone app on its own subdomain (the petitions\n// repo deploys production to petition-mode.politogyvrm.com).\nconst PETITION_MODE_ORIGIN = 'https://petition-mode.politogyvrm.com/'\n\nexport interface StandardNavOptions {\n /**\n * @deprecated app.politogyvrm.com (VRM core) is retired (Reference/UI-Platform\n * → \"Retirement of app.politogyvrm.com\"). Every row this tree used to resolve\n * against VRM core now points at its V2 host directly, so this is unused.\n * Kept only so existing callers don't need to drop the field immediately.\n */\n coreBaseUrl?: string\n /** Icon component per slot; omitted slots render icon-less rows. */\n icons?: Partial<Record<StandardNavIconKey, NavIcon>>\n /**\n * App-local override for the \"Contacts\" item. `children` are used verbatim\n * (NOT absolutized) so the owning app nests its own routes; `href` (also\n * verbatim) feeds active-detection for the group header. When omitted, the\n * item carries VRM core's own contacts sub-pages as absolute links.\n * (Relationship tree only.)\n */\n contactsItem?: {\n href?: string\n children?: NavItem[]\n /**\n * Live contact count shown right-aligned on the Contacts row, already\n * formatted for display (\"31.9K\"). Only the owning app knows it.\n * (Specs/Contacts design: `Contacts · 31.9K`.)\n */\n count?: string | number | null\n }\n /**\n * Top-level rows to OMIT, by label (case-insensitive), e.g. `['Polls','CTAs']`.\n * The Specs/Contacts design rail lists Relationship → Collect → Account with\n * exactly Dashboard · Contacts · Email broadcast · SMS/MMS blast / Calls to\n * action · Forms · Surveys / My profile · Organization settings; apps that\n * still surface Polls / CTAs keep them by default. A section row with no\n * remaining items is dropped too.\n */\n hiddenItems?: string[]\n /**\n * App-local override for the Petition-mode \"Dashboard\" entry, same contract\n * as `contactsItem`: `href`/`children` used verbatim so the Petitions app\n * nests its own routes under the entry. (Petition tree only.)\n */\n petitionsItem?: { href?: string; children?: NavItem[] }\n /**\n * The trailing \"Support\" row. VRM core opens its SupportRequestModal here;\n * other apps supply their own handler (`onClick`) or a link (`href`).\n * Omitted or `false` → no Support row. Appended to every mode's tree.\n */\n supportItem?: { onClick?: () => void; href?: string } | false\n /**\n * Which mode's tree to build. Default `relationship`, whose output is\n * byte-for-byte what this function produced before modes existed.\n */\n mode?: StandardNavMode\n /**\n * Active organization id (full UUID). EVERY link in EVERY tree carries it as\n * `?org=<uuid>` — the same convention the Mode switcher and My Account menu\n * use — so the destination app opens on the same org instead of the user's\n * default one. Omit it only when the caller genuinely has no active org yet.\n */\n activeOrgId?: string | null\n /**\n * Per-feature Campaign availability overrides, merged over\n * `CAMPAIGN_FEATURE_AVAILABILITY`. Only meaningful for the Campaign tree.\n */\n campaignAvailability?: Partial<CampaignFeatureAvailability>\n}\n\n/**\n * Drop the top-level rows named in `hidden` (case-insensitive label match),\n * then any section row left with no rows beneath it.\n */\nfunction applyHiddenItems(items: NavItem[], hidden?: string[]): NavItem[] {\n if (!hidden || hidden.length === 0) return items\n const drop = new Set(hidden.map((h) => h.trim().toLowerCase()))\n const kept = items.filter((i) => i.kind === 'section' || !drop.has(i.label.toLowerCase()))\n return kept.filter((item, idx) => {\n if (item.kind !== 'section') return true\n const next = kept[idx + 1]\n return !!next && next.kind !== 'section'\n })\n}\n\n/**\n * One sub-item of a standalone app, as a path RELATIVE to that app's origin\n * (`''` is the app root). Resolved against the origin and given the active-org\n * query param, exactly like the parent row it hangs under.\n */\ntype CrossAppLeaf = { label: string; icon: StandardNavIconKey; path: string }\n\nconst CONTACTS_APP = 'https://contacts.politogyvrm.com'\n\nconst APP_CONTACTS_CHILDREN = [\n { label: 'Dashboard', icon: 'grid' as const, href: `${CONTACTS_APP}/` },\n { label: 'All Contacts', icon: 'list' as const, href: `${CONTACTS_APP}/contacts` },\n { label: 'Tribes', icon: 'users' as const, href: `${CONTACTS_APP}/tribes` },\n { label: 'Import', icon: 'upload' as const, href: `${CONTACTS_APP}/import` },\n { label: 'Fields', icon: 'layout' as const, href: `${CONTACTS_APP}/fields` },\n { label: 'Activity', icon: 'activity' as const, href: `${CONTACTS_APP}/activity` },\n { label: 'Duplicates', icon: 'fileText' as const, href: `${CONTACTS_APP}/duplicates` },\n]\n\n// Email Broadcast now points at the standalone Email Engine V2 app\n// (email.politogyvrm.com, Specs/Email-Engine six tabs + Deliverability). The\n// V1 surface inside VRM core stays reachable as the last child while both run\n// in parallel. Absolute hrefs so active-detection lights this group when the\n// user is inside the Email app (same pattern as Contacts / Forms / Surveys).\nconst EMAIL_APP = 'https://email.politogyvrm.com'\nconst APP_EMAIL_CHILDREN = [\n { label: 'Dashboard', icon: 'grid' as const, href: `${EMAIL_APP}/dashboard` },\n { label: 'Creative Canvas', icon: 'edit' as const, href: `${EMAIL_APP}/canvas` },\n { label: 'Sender Information', icon: 'mail' as const, href: `${EMAIL_APP}/sender` },\n { label: 'Recipients', icon: 'user' as const, href: `${EMAIL_APP}/recipients` },\n { label: 'Send & Automate', icon: 'send' as const, href: `${EMAIL_APP}/send` },\n { label: 'Statistics', icon: 'barChart' as const, href: `${EMAIL_APP}/statistics` },\n { label: 'Deliverability', icon: 'activity' as const, href: `${EMAIL_APP}/deliverability` },\n]\n// Organization Settings — promoted from the My Account menu into the left nav\n// (HITL directive 2026-07-23). Mirrors the main app's former page IA, now\n// served by the standalone Settings app (settings.politogyvrm.com, Specs/\n// Organization-Settings v12) rather than VRM core: /organization-settings/:tab,\n// with Subscription & Billing carrying its own third level\n// (/organization-settings/subscription-billing/:tab). This is the canonical\n// depth-3 example the nav renderers support.\ntype CoreBranch = CrossAppLeaf & { children?: CrossAppLeaf[] }\n\nconst ORG_SETTINGS_CHILDREN: CoreBranch[] = [\n { label: 'General', icon: 'settings', path: 'organization-settings' },\n {\n label: 'Subscription & Billing',\n icon: 'creditCard',\n path: 'organization-settings/subscription-billing',\n children: [\n { label: 'Current Plan', icon: 'fileText', path: 'organization-settings/subscription-billing/current-plan' },\n { label: 'SMS, MMS & Email Usage', icon: 'activity', path: 'organization-settings/subscription-billing/text-email' },\n { label: 'Wallet', icon: 'dollarSign', path: 'organization-settings/subscription-billing/wallet' },\n { label: '10DLC', icon: 'messageSquare', path: 'organization-settings/subscription-billing/10dlc' },\n { label: 'Billing History', icon: 'clock', path: 'organization-settings/subscription-billing/billing-history' },\n ],\n },\n { label: 'Email', icon: 'mail', path: 'organization-settings/email-settings' },\n { label: 'Users', icon: 'users', path: 'organization-settings/users' },\n { label: 'Shared Links', icon: 'share', path: 'organization-settings/shared-links' },\n]\n\n// The NEW standalone acquisition apps (forms./surveys./polls.politogyvrm.com)\n// replace the legacy in-core \"Forms & Surveys\" system (HITL directive\n// 2026-07-23; removal plan: politogy/docs/legacy-forms-removal-plan.md).\n// Absolute cross-app links — SSO carries the session.\nconst APP_FORMS_CHILDREN = [\n { label: 'Forms', icon: 'list' as const, href: 'https://forms.politogyvrm.com/?tab=forms' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://forms.politogyvrm.com/?tab=canvas' },\n { label: 'Submissions', icon: 'fileText' as const, href: 'https://forms.politogyvrm.com/?tab=submissions' },\n]\n// The Surveys sub-menu mirrors the app's tab strip: Surveys / Canvas / Results.\n// Canvas and Results are survey-scoped routes (/surveys/:id/canvas), so with no\n// survey selected the list page carries a ?view= param — distinct hrefs, so\n// active-detection singles out exactly one (identical hrefs were the earlier\n// all-active bug; query params ARE compared, hashes are not).\nconst APP_SURVEYS_CHILDREN = [\n { label: 'Surveys', icon: 'list' as const, href: 'https://surveys.politogyvrm.com/surveys' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://surveys.politogyvrm.com/surveys?view=canvas' },\n { label: 'Results', icon: 'barChart' as const, href: 'https://surveys.politogyvrm.com/surveys?view=results' },\n]\nconst APP_POLLS_CHILDREN = [\n { label: 'Command Center', icon: 'grid' as const, href: 'https://polls.politogyvrm.com/' },\n { label: 'New Poll', icon: 'edit' as const, href: 'https://polls.politogyvrm.com/polls/new' },\n]\n// Standalone CTAs app (ctas.politogyvrm.com, Specs/CTAs) — same pattern as\n// Forms/Surveys/Polls above. This is also now the target for the\n// \"Calls to action\" row in the Relationship tree (the legacy in-core feature\n// it used to render was retired with app.politogyvrm.com).\nconst APP_CTAS_CHILDREN = [\n { label: 'CTAs', icon: 'list' as const, href: 'https://ctas.politogyvrm.com/' },\n { label: 'Canvas', icon: 'edit' as const, href: 'https://ctas.politogyvrm.com/?tab=canvas' },\n]\n\n// ---------------------------------------------------------------------------\n// Campaign app sub-navigation.\n//\n// Reference/UI-Platform v13 (Left bar → Navigation): \"The canonical VRM nav\n// tree — PARENT GROUPS WITH SUB-ITEMS. The app's own pages nest under their\n// group.\" The Campaign tree shipped as eight flat rows with no `children`, so\n// the Navigation Display control's \"Both\" and \"Sub Menu\" modes had nothing to\n// expand in the left bar of a2p / phonebank / canvass / signs — the three modes\n// rendered an identical sidebar and the control looked broken.\n//\n// Each list below is the app's OWN section list, taken verbatim from that app's\n// in-app tab strip (its `components/Shell.tsx`), so the sidebar sub-menu and the\n// page tab strip name the same sections in the same order — the sidebar/tab\n// agreement Reference/UI-Platform exists to enforce.\n// ---------------------------------------------------------------------------\n\n/** a2p/components/Shell.tsx `TABS` — the six A2P tabs. */\nconst APP_A2P_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: 'dashboard' },\n { label: 'Compose', icon: 'edit', path: 'compose' },\n { label: 'Recipients', icon: 'user', path: 'recipients' },\n { label: 'Tech Check', icon: 'activity', path: 'tech-check' },\n { label: 'Status', icon: 'clock', path: 'status' },\n { label: 'Conversations', icon: 'messageSquare', path: 'conversations' },\n]\n\n/** phonebank/components/Shell.tsx `NAV` — the Manager console's sections. */\nconst APP_PHONEBANK_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '' },\n { label: 'Campaigns', icon: 'phone', path: 'campaigns' },\n { label: 'Inbound', icon: 'messageSquare', path: 'inbound' },\n { label: 'Reports', icon: 'barChart', path: 'reports' },\n]\n\n/** canvass/components/Shell.tsx `SECTIONS` — the manager console's sections. */\nconst APP_CANVASS_CHILDREN: CrossAppLeaf[] = [\n { label: 'Dashboard', icon: 'grid', path: '' },\n { label: 'Campaigns', icon: 'target', path: 'campaigns' },\n { label: 'Canvassers', icon: 'users', path: 'canvassers' },\n]\n\n/**\n * signs/components/Shell.tsx `SECTIONS`. Review Queue is Manager+ in the app's\n * tab strip; the shared tree carries no role input, so the row is listed for\n * everyone and the ROUTE enforces it — /review renders a \"available to Managers\n * and Admins\" notice and loads no queue data for a volunteer (signs\n * app/review/page.tsx). Listing it keeps sidebar and tab strip identical for the\n * managers who use it rather than re-opening per-app nav drift.\n */\nconst APP_SIGNS_CHILDREN: CrossAppLeaf[] = [\n { label: 'Map', icon: 'map', path: '' },\n { label: 'Placements', icon: 'list', path: 'placements' },\n { label: 'Review Queue', icon: 'fileText', path: 'review' },\n { label: 'Recovery', icon: 'flag', path: 'recovery' },\n { label: 'Reports', icon: 'barChart', path: 'reports' },\n]\n\n/**\n * Build the standard Politogy VRM menu for the given `mode` (default\n * `relationship`), in the exact order and wording the main app renders it. See\n * `StandardNavOptions` for the app-specific hooks (`contactsItem`,\n * `supportItem`) and the Campaign inputs (`activeOrgId`, `campaignAvailability`).\n */\nexport function standardPolitogyNav(opts: StandardNavOptions): NavItem[] {\n // Left-Navigation §8.1: every row is a Lucide icon + label. Callers may\n // override per slot; otherwise the shared Lucide map applies.\n const icon = (key: StandardNavIconKey): NavIcon | undefined => opts.icons?.[key] ?? standardNavIcons[key]\n\n // EVERY link this tree emits leaves the current app (core routes are\n // cross-app for a standalone app, and the app-owned rows are supplied by the\n // caller), so each one carries the active org as `?org=<full-uuid>` — the\n // full id is the only collision-free selector (contacts-api matches exact id\n // first, then a short suffix that can collide across a user's orgs). Without\n // it a multi-org user following a bare cross-app link lands in whatever org\n // the destination defaults to; the cookie is only the fallback for a bare\n // URL, the param is the explicit selector. Active-detection ignores `org`\n // (isNavItemActive's ACTIVE_IGNORED_PARAMS) so stamping it selects nothing\n // differently, and it keeps the org in the address bar for bookmarking.\n const orgParam = opts.activeOrgId ? `org=${opts.activeOrgId}` : ''\n const withOrg = (url: string): string =>\n orgParam ? `${url}${url.includes('?') ? '&' : '?'}${orgParam}` : url\n\n const leaves = (origin: string, children: CrossAppLeaf[]): NavItem[] =>\n appLeaves(origin, children)\n const branches = (origin: string, children: CoreBranch[]): NavItem[] => {\n const o = origin.replace(/\\/+$/, '')\n return children.map((c) => ({\n label: c.label,\n icon: icon(c.icon),\n href: withOrg(`${o}/${c.path}`),\n children: c.children ? leaves(origin, c.children) : undefined,\n }))\n }\n\n // Sub-items of a standalone app: `origin` + the app-relative path, carrying\n // the active org the way the parent row does. Trailing slash on the origin\n // is normalized so `''` yields the app root and `x` yields `/x`. An optional\n // `modeParam` (a DUAL app entered from a mode other than its own default,\n // e.g. the Relationship tree's a2p row) is stamped on every leaf too, so the\n // destination resolves the same mode the row that got you there was in.\n const appLeaves = (\n origin: string,\n children: CrossAppLeaf[],\n modeParam?: StandardNavMode,\n ): NavItem[] => {\n const base = origin.replace(/\\/+$/, '')\n return children.map((c) => {\n const url = c.path ? `${base}/${c.path}` : `${base}/`\n const withMode = modeParam ? `${url}${url.includes('?') ? '&' : '?'}mode=${modeParam}` : url\n return { label: c.label, icon: icon(c.icon), href: withOrg(withMode) }\n })\n }\n\n // Left-Navigation §9.4: ACCOUNT is the last section in every mode.\n const accountRows = (): NavItem[] => [\n { kind: 'section', label: 'Account' },\n // My Profile moved to the Politogy ID account app (auth.politogyvrm.com)\n // with the retirement of app.politogyvrm.com.\n { label: 'My profile', icon: icon('circleUser'), href: withOrg(`${AUTH_ORIGIN}my-profile`) },\n {\n label: 'Organization settings',\n icon: icon('settings'),\n // Organization settings moved to the standalone Settings app\n // (settings.politogyvrm.com, Specs/Organization-Settings v12).\n href: withOrg(`${SETTINGS_ORIGIN}organization-settings`),\n children: branches(SETTINGS_ORIGIN, ORG_SETTINGS_CHILDREN),\n },\n ]\n\n const buildRelationship = (): NavItem[] => {\n const contacts: NavItem = opts.contactsItem\n ? {\n label: 'Contacts',\n icon: icon('usersRound'),\n href: opts.contactsItem.href,\n children: opts.contactsItem.children,\n badge: opts.contactsItem.count ?? undefined,\n }\n : {\n label: 'Contacts',\n icon: icon('usersRound'),\n href: withOrg(`${CONTACTS_APP}/`),\n children: APP_CONTACTS_CHILDREN.map((c) => ({\n label: c.label,\n icon: icon(c.icon),\n href: withOrg(c.href),\n })),\n }\n\n // Specs/Contacts design rail (Reference/UI-Platform → Left bar: section\n // rows via `kind: 'section'`, sentence-case labels). Three groups:\n // RELATIONSHIP Dashboard · Contacts · Email broadcast · SMS/MMS blast\n // COLLECT Calls to action · Forms · Surveys (· Polls · CTAs)\n // ACCOUNT My profile · Organization settings\n return [\n { kind: 'section', label: 'Relationship' },\n // Dashboard moved to the standalone Dashboard app (dashboard.politogyvrm.com,\n // Specs/Relationship-Dashboard) with the retirement of app.politogyvrm.com.\n { label: 'Dashboard', icon: icon('layoutDashboard'), href: withOrg(DASHBOARD_ORIGIN) },\n contacts,\n {\n label: 'Email broadcast',\n icon: icon('mail'),\n href: withOrg(`${EMAIL_APP}/dashboard`),\n children: APP_EMAIL_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n // SMS/MMS Blast is the a2p app entered in RELATIONSHIP mode (a2p is\n // dual-mode; Specs/A2P). The `?mode=relationship` param pins the\n // destination's tree so the row that got you there is the row that\n // lights up on arrival.\n label: 'SMS/MMS blast',\n icon: icon('messageSquare'),\n href: withOrg(`${A2P_ORIGIN}?mode=relationship`),\n children: appLeaves(A2P_ORIGIN, APP_A2P_CHILDREN, 'relationship'),\n },\n { kind: 'section', label: 'Collect' },\n // Calls to action moved to the standalone CTAs app (ctas./runtime.\n // politogyvrm.com, Specs/CTAs) with the retirement of app.politogyvrm.com.\n {\n label: 'Calls to action',\n icon: icon('mousePointerClick'),\n href: withOrg('https://ctas.politogyvrm.com/'),\n children: APP_CTAS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Forms',\n icon: icon('fileText'),\n href: withOrg('https://forms.politogyvrm.com/'),\n children: APP_FORMS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n {\n label: 'Surveys',\n icon: icon('clipboardList'),\n href: withOrg('https://surveys.politogyvrm.com/surveys'),\n children: APP_SURVEYS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n // Polls (polls.politogyvrm.com) — kept in the default Collect section;\n // apps that want it hidden pass `hiddenItems: ['Polls']`. Regression:\n // dropped entirely in 03c4dc2 when app.politogyvrm.com retired; restored\n // here (this row is independent of the retired app).\n {\n label: 'Polls',\n icon: icon('chartNoAxes'),\n href: withOrg(POLLS_ORIGIN),\n children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n },\n ...accountRows(),\n ]\n }\n\n // Campaign tree — Dashboard + the 7 Campaign Mode features. Dashboard and\n // Voter Contact are core-hosted (VRM core /campaign/*); the rest link out to\n // standalone apps and are gated by CAMPAIGN_FEATURE_AVAILABILITY.\n const buildCampaign = (): NavItem[] => {\n const avail: CampaignFeatureAvailability = {\n ...CAMPAIGN_FEATURE_AVAILABILITY,\n ...opts.campaignAvailability,\n }\n type Gated = NavItem & { flag?: keyof CampaignFeatureAvailability }\n const rows: Gated[] = [\n // Left-Navigation §9.2: Race data -> Research -> GOTV -> Account.\n // Battleground is the Campaign landing page; there is no Campaign\n // Dashboard row, and Voter Contact and Tribes have no row.\n { kind: 'section', label: 'Race data' },\n // Battleground moved to the Dashboard app (dashboard.politogyvrm.com)\n // until a dedicated Battleground host is decided (UI-Platform route table).\n { label: 'Battleground', icon: icon('crosshair'), href: withOrg(`${DASHBOARD_ORIGIN}battleground`) },\n // District data moved to the Dashboard app (dashboard.politogyvrm.com)\n // per Reference/UI-Platform v44.\n { label: 'District data', icon: icon('landmark'), href: withOrg(`${DASHBOARD_ORIGIN}districts`) },\n { kind: 'section', label: 'Research' },\n {\n label: 'Polling',\n icon: icon('chartNoAxes'),\n href: withOrg(POLLS_ORIGIN),\n children: APP_POLLS_CHILDREN.map((c) => ({ label: c.label, icon: icon(c.icon), href: withOrg(c.href) })),\n flag: 'polling',\n },\n { kind: 'section', label: 'GOTV' },\n {\n label: 'Field canvassing',\n icon: icon('doorOpen'),\n href: withOrg(CANVASS_ORIGIN),\n children: appLeaves(CANVASS_ORIGIN, APP_CANVASS_CHILDREN),\n flag: 'canvass',\n },\n {\n label: 'Phone banking',\n icon: icon('phone'),\n href: withOrg(PHONEBANK_ORIGIN),\n children: appLeaves(PHONEBANK_ORIGIN, APP_PHONEBANK_CHILDREN),\n flag: 'phonebank',\n },\n {\n label: 'A2P texting',\n icon: icon('messageSquare'),\n href: withOrg(A2P_ORIGIN),\n children: appLeaves(A2P_ORIGIN, APP_A2P_CHILDREN),\n flag: 'a2p',\n },\n {\n label: 'Sign mapping',\n icon: icon('signpost'),\n href: withOrg(SIGNS_ORIGIN),\n children: appLeaves(SIGNS_ORIGIN, APP_SIGNS_CHILDREN),\n flag: 'signs',\n },\n ...accountRows(),\n ]\n const kept = rows\n .filter((r) => !r.flag || avail[r.flag])\n .map(({ flag: _flag, ...item }) => item as NavItem)\n // Drop a section left with no rows under it (e.g. Research when polling is off).\n return kept.filter((item, idx) => {\n if (item.kind !== 'section') return true\n const next = kept[idx + 1]\n return !!next && next.kind !== 'section'\n })\n }\n\n // Petition tree — the Petition Mode home (its own standalone app). The\n // Petitions app nests its own routes via `petitionsItem` (the contactsItem\n // contract); everyone else gets the minimal cross-app link. Labeled\n // Dashboard so the shared breadcrumb trail anchors correctly.\n const buildPetition = (): NavItem[] => [\n opts.petitionsItem\n ? {\n label: 'Dashboard',\n icon: icon('home'),\n href: opts.petitionsItem.href ?? withOrg(PETITION_MODE_ORIGIN),\n children: opts.petitionsItem.children,\n }\n : { label: 'Dashboard', icon: icon('home'), href: withOrg(PETITION_MODE_ORIGIN) },\n ]\n\n const mode = opts.mode ?? 'relationship'\n const built =\n mode === 'campaign'\n ? buildCampaign()\n : mode === 'petition'\n ? buildPetition()\n : buildRelationship()\n const items = applyHiddenItems(built, opts.hiddenItems)\n\n if (opts.supportItem) {\n items.push({\n label: 'Support',\n icon: icon('lifeBuoy'),\n href: opts.supportItem.href,\n onClick: opts.supportItem.onClick,\n })\n }\n\n return items\n}\n","// ---------------------------------------------------------------------------\n// Framework-agnostic chrome (sidebar + top navbar) for @the-portland-company/shell.\n//\n// The other chrome in this package (ShellChrome, Sidebar, Header, …) is built\n// on Chakra UI v2 + react-router and targets Vite SPAs. That stack cannot be\n// imported into a Next.js / React 19 / Tailwind app. This \"native\" module is a\n// dependency-light alternative: pure React (no Chakra, no emotion, no\n// react-router, no icon library) whose styling is driven entirely by the CSS\n// design tokens shipped in `@the-portland-company/shell/chrome.css`.\n//\n// It is a FAITHFUL VISUAL TWIN of the Chakra chrome (Sidebar.tsx / Header.tsx /\n// OrgPill / ModePill / NavItem / UserMenu): same 240px sidebar, brand-logo\n// slot, \"ORGANIZATION\" org pill, mode pill, solid active nav rows, pipe-\n// separated footer links + commit string, and an avatar+name+email+chevron user\n// menu — so an app rendering this looks identical to the main VRM app.\n//\n// Every app concern (nav items, org, mode, user, links, icons, the routing\n// Link component, the theme toggle) is injected via props, so both the Contacts\n// app (Next.js) and the VRM app could consume the same components.\n// ---------------------------------------------------------------------------\n\nimport type { ComponentType, CSSProperties, KeyboardEvent as ReactKeyboardEvent, ReactNode } from 'react'\nimport { Fragment, createContext, useContext, useEffect, useMemo, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport { useTopBarIconSlotGlyph, type TopBarIconSlot } from '../lib/topbarIconSlot'\nimport { resolveBrandGlyph } from '../lib/brandGlyphs'\nimport { warnDeprecated } from '../lib/deprecation'\nimport { filterOrgs, shouldShowOrgFilter } from './orgFilter'\nimport { orgIdTail } from '../active-org'\nimport { readRailPreference, writeRailPreference } from '../nav-preference'\nimport { SpeculationRulesScript } from '../speculation/SpeculationRulesScript'\nimport {\n topBarIconButtonClass,\n TopBarTooltip,\n TopBarPanelArrow,\n NavThemeControl,\n resolveOrgLogoUrl,\n NAV_DISPLAY_OPTIONS,\n TOPBAR_GLYPH_SIZE,\n type ThemePreference,\n type NavDisplayMode,\n} from './chromeActions'\n\n// Data-backed top-bar widgets (Fuel, Notifications, Support, Nav-display) +\n// the injected-fetcher provider they hang off. One implementation for every app.\nexport {\n NavChromeProvider,\n CORE_APP_ORIGIN,\n CORE_BILLING_PATH,\n SPECS_ORIGIN,\n FuelAction,\n NotificationsAction,\n SupportAction,\n SpecOverlayAction,\n NavDisplayAction,\n NavThemeControl,\n TopBarCountBadge,\n TopBarPanelArrow,\n TopBarTooltip,\n TopBarWidgetSlot,\n TopBarPopover,\n topBarIconButtonClass,\n resolveOrgLogoUrl,\n useChromeMe,\n useChromeOrgs,\n useNavChromeFetcher,\n useNavChromeDedupedFetch,\n useThemePreference,\n} from './chromeActions'\nexport type {\n ChromeMe,\n NavChromeFetcher,\n NavDisplayMode,\n ThemePreference,\n ChromeOrgSummary,\n ChromeNotificationsPayload,\n ChromeNotificationAlert,\n ChromeNotificationReply,\n ChromeNotificationImport,\n ChromeNotificationQuarantine,\n CommunicationsFuelStatus,\n FuelChannelStatus,\n} from './chromeActions'\n\n// An icon is any component that accepts an optional size + className. This\n// matches both `lucide-react` and `react-icons` icon signatures, so consuming\n// apps pass their own icon set without this package depending on one.\nexport type NavIcon = ComponentType<{ size?: number; className?: string; strokeWidth?: number }>\n\nexport type NavItem = {\n /**\n * What this row IS. Defaults to `'link'` — every existing `NavItem[]` keeps\n * its exact type and rendering.\n *\n * `'section'` is a non-interactive heading that groups the rows beneath it:\n * uppercase, muted, letterspaced, not focusable, no hover. Only `label` is\n * read; `href`, `icon`, `onClick` and `children` are ignored.\n *\n * The legacy chrome supported this and 0.43 dropped it, so apps faked it by\n * passing `disabled` rows with no href — which looks approximately right and\n * is wrong where it counts: a disabled row announces as an unavailable\n * CONTROL to a screen reader, when it is not a control at all. A section is\n * its own kind of row (Reference/UI-Platform → Left bar).\n *\n * Deliberately a widened field rather than a discriminated union: a union\n * would make `item.href` a type error for every existing consumer that reads\n * it, turning an additive feature into a breaking change.\n */\n kind?: 'link' | 'section'\n /** Route to link to. Optional when `onClick` is supplied (renders a button). */\n href?: string\n label: string\n icon?: NavIcon\n /**\n * When supplied the row renders as a `<button>` (styled identically to the\n * link rows) instead of a routed link — used for actions like \"Support\".\n */\n onClick?: () => void\n /**\n * Disables the row: non-interactive and dimmed, with `disabledTitle` shown as\n * a hover tooltip explaining why. Mirrors `NavTab`'s existing contract so a\n * gated row looks the same whether it renders in the sidebar or a tab strip.\n * Without this, an app that gates a section (VRM dims Email / SMS until setup\n * is complete) had no way to express it and the row rendered fully clickable\n * (shell-nav-handoff §3).\n */\n disabled?: boolean\n /** Tooltip for a disabled row — say why, and how to resolve it. */\n disabledTitle?: string\n /**\n * Right-aligned count/annotation on the row — e.g. the live contact count\n * on \"Contacts\" (`31.9K`). Pre-formatted by the app; the shell only draws\n * it (Specs/Contacts design rail). Omitted/null draws nothing.\n */\n badge?: string | number | null\n /**\n * Nested sub-items. When present, the row becomes an expandable GROUP header.\n * Clicking it always toggles the children open/closed and rotates the\n * right-aligned chevron; if the item ALSO carries an `onClick`, that runs too,\n * so a parent can navigate to its section dashboard while expanding\n * (shell-nav-handoff §2). An `href` alone never navigates from a group header. The sidebar runs a single-open accordion (opening one group closes\n * the others) and auto-expands whichever group contains the active route —\n * mirroring the main VRM app's Chakra sidebar. Children render as smaller nav\n * rows on a lighter panel and support both `href` links and `onClick` actions.\n */\n children?: NavItem[]\n}\n\n// The routing primitive is injected so each app supplies its own (Next.js\n// `<Link>`, react-router `<Link>`, or a plain `<a>`). Defaults to an anchor.\nexport type NavLinkProps = {\n href: string\n className?: string\n 'aria-current'?: 'page' | undefined\n children: ReactNode\n // Optional passthrough attributes so the same injected link can back a\n // routed nav row OR a routed tab (which needs ARIA tab semantics + inline\n // token geometry). Next.js `<Link>`, react-router `<Link>` and a plain <a>\n // all accept these DOM props, and DefaultLink spreads them onto its anchor.\n role?: string\n 'aria-selected'?: boolean\n 'aria-label'?: string\n title?: string\n style?: CSSProperties\n}\nexport type NavLinkComponent = ComponentType<NavLinkProps>\n\n/**\n * URL-scheme allow-list for host-supplied hrefs. React does not neutralize\n * `javascript:`/`data:` schemes on anchor href, so any app-supplied nav/footer/\n * action href must be validated before it reaches the DOM. Permits absolute\n * http(s), mailto/tel, and in-app relative targets; everything else → '#'.\n */\nconst safeHref = (h?: string) =>\n h && /^(https?:|mailto:|tel:|\\/|#|\\.)/i.test(h.trim()) ? h : '#'\n\nconst DefaultLink: NavLinkComponent = ({ href, children, ...rest }) => (\n <a href={safeHref(href)} {...rest}>\n {children}\n </a>\n)\n\n/**\n * Default active-route test. Handles three href shapes so the CURRENT app's\n * item + sub-item select correctly in the cross-app menu (HITL 2026-07-23):\n * - relative path: exact for \"/\", prefix otherwise (legacy behavior);\n * - absolute URL: active only when its host matches window.location.host,\n * then compared by path (and query, when the href carries one — e.g.\n * forms' /?tab=canvas sub-items);\n * - query-only relative hrefs likewise compare location.search.\n *\n * The `org` param is EXCLUDED from the query comparison. Campaign / Petition\n * links carry `?org=<last6>` purely to hand the active organization to the\n * destination app (`standardPolitogyNav`'s `activeOrgId`); it scopes data, it\n * does not identify a page. Comparing it would deselect every campaign row the\n * moment an org is active, because the app's own URL bar carries no `org=`.\n */\nconst ACTIVE_IGNORED_PARAMS = new Set(['org'])\n\nexport function isNavItemActive(pathname: string, href: string): boolean {\n let targetPath = href\n let targetSearch = ''\n if (/^https?:\\/\\//i.test(href)) {\n if (typeof window === 'undefined') return false\n try {\n const u = new URL(href)\n if (u.host !== window.location.host) return false\n targetPath = u.pathname\n targetSearch = u.search\n } catch {\n return false\n }\n } else {\n const qi = href.indexOf('?')\n if (qi >= 0) {\n targetPath = href.slice(0, qi) || '/'\n targetSearch = href.slice(qi)\n }\n }\n // Every IDENTIFYING key=value in the target query must be present in the\n // location. Once the scoping params are dropped a link like\n // \"https://signs.politogyvrm.com/placements?org=abc123\" is a plain path href\n // again and falls through to the path rules below.\n const want = new URLSearchParams(targetSearch)\n for (const k of ACTIVE_IGNORED_PARAMS) want.delete(k)\n if (Array.from(want).length > 0) {\n if (typeof window === 'undefined') return false\n if (pathname !== targetPath) return false\n const have = new URLSearchParams(window.location.search)\n for (const [k, v] of want) if (have.get(k) !== v) return false\n return true\n }\n if (targetPath === '/') return pathname === '/'\n return pathname === targetPath || pathname.startsWith(`${targetPath}/`)\n}\n\n/**\n * Stable identity for an expandable nav group's accordion state. Prefers the\n * item's href; falls back to an index-scoped label so two groups can never\n * collide even when they share a label and have no href.\n */\nfunction groupKeyOf(item: NavItem, index: number): string {\n return item.href ?? `nav-group-${index}-${item.label}`\n}\n\n/** True when any of a group's children links to the active route. */\nfunction hasActiveChild(\n item: NavItem,\n pathname: string,\n activeFn: (pathname: string, href: string) => boolean,\n): boolean {\n return (item.children ?? []).some(\n (child) =>\n (child.href ? activeFn(pathname, child.href) : false) ||\n // Depth-3: a grandchild owning the route also opens the top group.\n (child.children ?? []).some((leaf) =>\n leaf.href ? activeFn(pathname, leaf.href) : false,\n ),\n )\n}\n\n/**\n * Color-coded tone classes for the sidebar environment chip, matching the main\n * VRM app: prod red, staging orange, local/dev green, unknown gray.\n */\nfunction firstLeafHref(item: NavItem): string | undefined {\n for (const c of item.children ?? []) {\n if (c.kind === 'section') continue\n if (c.href) return c.href\n const deep = firstLeafHref(c)\n if (deep) return deep\n }\n return undefined\n}\n\n/** A multi-mode app (VRM core) renders NavAppShell without a registry modeId;\n * its current mode label still decides the rail colour (Left-Navigation §5). */\nexport function modeIdFromLabel(label: string | undefined): string | undefined {\n const l = label?.trim().toLowerCase()\n return l ? l.replace(/\\s+mode$/, '') : undefined\n}\n\n/** \"Ben Edtl\" -> \"Ben E.\" (Left-Navigation §10). One word stays as is. */\nexport function shortUserName(name: string): string {\n const parts = name.trim().split(/\\s+/).filter(Boolean)\n if (parts.length < 2) return parts[0] ?? ''\n return `${parts[0]} ${parts[parts.length - 1][0].toUpperCase()}.`\n}\n\n/** Short environment name for the rail's build line (\"prod\", \"staging\", \"local\"). */\nexport function shortEnvLabel(label: string): string {\n const l = label.trim().toLowerCase()\n if (l === 'production') return 'prod'\n if (l === 'development') return 'dev'\n return l\n}\n\nexport function envChipClasses(label: string): string {\n const l = label.toLowerCase()\n if (l === 'production' || l === 'prod')\n return 'bg-[#fee2e2] text-[#ef4444]'\n if (l === 'staging' || l === 'stage')\n return 'bg-[#ffedd5] text-[#f97316]'\n if (l === 'local' || l === 'development' || l === 'dev')\n return 'bg-[#dcfce7] text-[#22c55e]'\n return 'bg-[rgba(107,114,128,0.16)] text-[#6b7280]'\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavBrand = {\n /** Where the logo links to. Defaults to \"/\". */\n homeHref?: string\n /**\n * Brand logo image src. When supplied this renders as the wordmark logo\n * (matching the main app's BrandLogo), and `badgeLabel`/`title`/`subtitle`\n * are used only as the no-image fallback.\n */\n logoSrc?: string\n logoAlt?: string\n /**\n * The square mark shown at the top of the COLLAPSED rail (Left-Navigation\n * §11.6) — Brand `assets.logoSquare`, the all-white vrm tile. Falls back to\n * the badge when omitted.\n */\n logoSquareSrc?: string\n /**\n * The logo URLs are still resolving from the Brand token sheet. The rail\n * reserves the logo's box and draws nothing — never the badge fallback,\n * which would flash a stand-in on every load.\n */\n logoPending?: boolean\n /** Short label shown inside the brand badge fallback (e.g. \"P\"). */\n badgeLabel: string\n title: string\n subtitle?: string\n}\n\nexport type NavOrgOption = {\n id: string\n name: string | null\n logoUrl?: string | null\n /** The org's Brand Kit icon mark; falls back to `logoUrl`, then initials. */\n iconUrl?: string | null\n brandColor?: string | null\n role?: string | null\n}\n\nexport type NavOrg = {\n name: string | null\n /** Full org id. When present, a copy affordance is shown by the label. */\n id?: string | null\n /** Optional org logo for the pill badge; falls back to initials. */\n logoUrl?: string | null\n /**\n * The org's Brand Kit icon mark, shown on the collapsed rail (32px, on its\n * white tile). Falls back to `logoUrl` scaled to fit, then initials.\n */\n iconUrl?: string | null\n /** Solid pill background (the org's brand color). Defaults to the accent. */\n brandColor?: string | null\n /** Org's secondary Brand Kit color; the card's bottom-edge gradient runs\n * primary → secondary. Falls back to the Politogy gradient when unset. */\n brandColorSecondary?: string | null\n /**\n * Organization Settings §7.1–§7.2: when the org has no logo yet, an Account\n * Admin sees an \"Upload logo\" link in the band instead of the org name.\n */\n canUploadLogo?: boolean\n uploadLogoHref?: string\n onClick?: () => void\n /**\n * The user's organizations. When present (even one), the pill renders as a\n * dropdown SWITCHER (Reference/UI-Platform \"Organization selector\": never a\n * static label in a multi-org app); selecting one calls `onSwitch(id)`.\n */\n organizations?: NavOrgOption[]\n onSwitch?: (id: string) => void\n /**\n * The active org is still resolving from the chrome API. Renders a skeleton\n * pill instead of a name. Required because the app's own workspace label is\n * NOT the organization: showing it while the real org loads flashes a wrong\n * value (Global Rules — async values shimmer, they never render a stand-in).\n */\n loading?: boolean\n}\n\nexport type NavModeOption = {\n id: string\n label: string\n icon?: NavIcon\n /**\n * Left-Navigation §7: a mode the organization does not hold is always\n * shown (never hidden), dimmed, and not selectable. Defaults to true.\n */\n available?: boolean\n /** Tooltip for an unavailable mode, e.g. \"Campaign Mode isn't active for\n * this organization.\" Appended with \"See upgrade options\" for an Account\n * Admin on a paid account (never during a trial). */\n unavailableTooltip?: string\n}\n\nexport type NavMode = {\n label: string\n icon?: NavIcon\n /**\n * Entitled modes for the active organization. With more than one option the\n * pill renders as a SELECTOR (dropdown); with zero/one it stays the classic\n * disabled single-mode pill. Selecting calls onSelect(id).\n */\n options?: NavModeOption[]\n onSelect?: (id: string) => void\n}\n\nexport type NavFooterLink = { label: string; href: string; external?: boolean }\n\nexport type NavFooter = {\n /**\n * Build metadata (env chip / commit / version / date / author). OPTIONAL:\n * omit envLabel/version/commit to render a links-only footer — apps show\n * the meta block to Super Administrators only (Reference/UI-Platform).\n */\n envLabel?: string\n version?: string\n commit?: string\n links?: NavFooterLink[]\n /** ISO date (or any Date-parseable string) of the deployed commit. */\n commitDate?: string\n /** Full name of the commit author (only the first name is shown). */\n commitAuthor?: string\n /**\n * The signed-in user, drawn as a card (avatar · name · email · chevron)\n * ABOVE the links row. Reference/UI-Platform v30 → Left bar: \"The user —\n * avatar, name, email and the user menu — lives in the left bar footer.\"\n * Clicking it opens the account menu UPWARD. `NavAppShell` fills these from\n * `topBar.user` / `topBar.userMenu` / `topBar.onSignOut` automatically, so\n * standalone `NavSidebar` consumers pass them only when they want the card.\n */\n user?: NavUser | null\n userMenu?: NavUserMenu | null\n onSignOut?: () => void\n}\n\nexport type NavSidebarProps = {\n pathname: string\n brand: NavBrand\n nav: {\n groupLabel?: string\n items: NavItem[]\n isActive?: (pathname: string, href: string) => boolean\n /**\n * Render each top-level group's CHILDREN directly at the root of the rail\n * — no parent header row, no accordion. For an app whose whole tree nests\n * under one entry (Petitions), that parent row is pure anatomy: V1 never\n * had it, it duplicates the first child's route, and it costs a level of\n * indentation. Sections render as sections; rows render with the 'flat'\n * variant (top-level geometry, wash active treatment). Top-level items\n * WITHOUT children render unchanged, so a mixed tree degrades sanely.\n */\n flatten?: boolean\n }\n org?: NavOrg | null\n mode?: NavMode | null\n footer?: NavFooter | null\n linkComponent?: NavLinkComponent\n /**\n * Small-screen expand state (owned by `NavAppShell`). The rail is never\n * hidden (Left-Navigation §11.6): at `md` and up it is the full rail, below\n * `md` it collapses to the 64px icon rail. `open` expands the collapsed\n * rail to the full rail as a modal drawer with a backdrop, and `onClose`\n * wires the backdrop, the close button, and Escape. `md` and up ignores\n * both.\n */\n open?: boolean\n onClose?: () => void\n /**\n * Expands the collapsed (below `md`) rail. When set, the square logo tile at\n * the top of the collapsed rail becomes the \"Expand navigation\" control —\n * the Left-Navigation Design draws no other toggle and no top-bar hamburger.\n */\n onOpen?: () => void\n /**\n * Closes the expanded rail after a nav-link click without counting as the\n * user's Collapse choice. Defaults to `onClose`.\n */\n onNavigate?: () => void\n}\n\n// Default org-pill BADGE background — the chrome accent, matching the main\n// app's fallback (mode primary) when an org has no explicit brand color. In a\n// Mode with its own accent this follows the Mode. Only the circular badge takes\n// it; the pill body stays neutral (Reference/UI-Platform → Left bar).\n// White initials/avatar sit on this badge, so it must clear 4.5:1 under white\n// text, not just read as \"the accent\" — hence the safe alias, not the raw one.\nconst ORG_PILL_DEFAULT = 'var(--color-accent-bg-safe,var(--color-accent))'\n\n// Left-Navigation §11.6: below `md` the rail collapses to the 64px icon rail;\n// it is never hidden. The collapse is pure CSS (`max-md:` utilities), so there\n// is one DOM tree and no hydration flash. It applies only while the rail is\n// not expanded as the small-screen drawer, which is what this context carries\n// down to the rows.\nconst RailCollapsibleContext = createContext(false)\n\n/** Returns `cls` when the small-screen collapse applies to this rail, else ''. */\nfunction useRailCollapse(): (cls: string) => string {\n const collapsible = useContext(RailCollapsibleContext)\n return (cls) => (collapsible ? cls : '')\n}\n\n/**\n * The org pill's label: the org's name, or (when an org exists but has no\n * name yet) the same 7-char id tail the address bar uses, so the pill never\n * shows a name-shaped placeholder for a real org. \"No organizations\" is\n * reserved for when there is no org at all.\n */\nfunction orgPillLabel(org: NavOrg): string {\n if (org.name) return org.name\n if (org.id) return orgIdTail(org.id) ?? 'Organization'\n return 'No organizations'\n}\n\n/**\n * The organization on the collapsed rail: its Brand Kit icon mark, 32px, on a\n * white tile (Left-Navigation §11.6). Rendered inside the same switcher\n * trigger as the full card, so the switcher stays interactive when collapsed.\n */\nfunction OrgIconMark({ org, logoSrc }: { org: NavOrg; logoSrc?: string }) {\n const rc = useRailCollapse()\n const src = resolveOrgLogoUrl(org.iconUrl) ?? logoSrc\n return (\n <span\n aria-hidden\n data-rail-org-mark=\"\"\n className={`hidden h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-[5px] bg-[#FFFFFF] text-[11px] font-bold text-neutral-800 ${rc('max-md:flex')}`}\n >\n {src ? (\n <img src={src} alt=\"\" className=\"max-h-full max-w-full object-contain\" />\n ) : (\n (org.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n )\n}\n\nexport function NavSidebar({\n pathname,\n brand,\n nav,\n org,\n mode,\n footer,\n linkComponent,\n open,\n onClose,\n onOpen,\n onNavigate,\n}: NavSidebarProps) {\n const Link = linkComponent ?? DefaultLink\n // The small-screen collapse applies whenever the rail is not expanded as\n // the drawer (see RailCollapsibleContext).\n const collapsible = !open\n const rc = (cls: string) => (collapsible ? cls : '')\n // Focus management for the mobile drawer: on open, move focus to the close\n // button; on close, return it to whatever had focus before (the hamburger,\n // in practice). Escape closes while the drawer is open.\n const asideRef = useRef<HTMLElement>(null)\n const closeButtonRef = useRef<HTMLButtonElement>(null)\n const previouslyFocusedRef = useRef<HTMLElement | null>(null)\n useEffect(() => {\n if (open) {\n previouslyFocusedRef.current = document.activeElement as HTMLElement | null\n closeButtonRef.current?.focus()\n } else if (previouslyFocusedRef.current) {\n previouslyFocusedRef.current.focus()\n previouslyFocusedRef.current = null\n }\n }, [open])\n useEffect(() => {\n if (!open) return\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose?.()\n }\n document.addEventListener('keydown', onKeyDown)\n return () => document.removeEventListener('keydown', onKeyDown)\n }, [open, onClose])\n // Focus trap: Tab/Shift+Tab must stay inside the drawer while it is open —\n // no `inert` attribute (React 18/19 compatibility), so this is a plain\n // keydown handler that wraps focus at the first/last focusable element.\n const trapTab = (e: ReactKeyboardEvent<HTMLElement>) => {\n if (!open || e.key !== 'Tab') return\n const root = asideRef.current\n if (!root) return\n const focusable = Array.from(\n root.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ).filter((el) => {\n if (el.hidden) return false\n const style = window.getComputedStyle(el)\n return style.display !== 'none' && style.visibility !== 'hidden'\n })\n if (focusable.length === 0) return\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n if (e.shiftKey) {\n if (document.activeElement === first) {\n e.preventDefault()\n last.focus()\n }\n } else if (document.activeElement === last) {\n e.preventDefault()\n first.focus()\n }\n }\n const activeFn = nav.isActive ?? isNavItemActive\n const ModeIcon = mode?.icon\n // Core stores logo_url as a core-relative storage route; resolve it against\n // the core origin so it loads in EVERY app, not just app.politogyvrm.com.\n const orgLogoSrc = resolveOrgLogoUrl(org?.logoUrl)\n // Left-Navigation §6: brand-color gradient strip along the logo band's\n // bottom edge; the Politogy gradient (blue → purple → red) until the org\n // sets its own Brand Kit colors.\n const orgGradient = org?.brandColor\n ? `linear-gradient(to right, ${org.brandColor}, ${org.brandColorSecondary || org.brandColor})`\n : 'linear-gradient(to right, #007BFF, #A54B7A, #E63946)'\n // Design rail: the org card border is the org's brand color at 42% alpha\n // (`rgba(74,192,231,.42)` in the Specs/Contacts design); hairline otherwise.\n const orgCardStyle = hexToRgba(org?.brandColor, 0.42)\n ? { borderColor: hexToRgba(org?.brandColor, 0.42) as string }\n : undefined\n\n // Single-open accordion for expandable nav groups, mirroring the main VRM\n // app's Chakra sidebar. `activeGroupKey` is the group (if any) that owns the\n // current route; deriving it as a primitive string keeps the auto-expand\n // effect from firing when `nav.items` is a fresh array reference each render\n // (which would otherwise clobber a manual toggle).\n const activeGroupKey = useMemo(() => {\n for (let i = 0; i < nav.items.length; i++) {\n const item = nav.items[i]\n if (item.children && item.children.length > 0 && hasActiveChild(item, pathname, activeFn)) {\n return groupKeyOf(item, i)\n }\n }\n return null\n }, [nav.items, pathname, activeFn])\n\n // Seed the open group from the active route on first paint (no expand flash),\n // then keep it synced as the route changes. Manual toggles between route\n // changes are preserved because the effect only reruns when the *derived*\n // active group actually changes.\n const [openGroup, setOpenGroup] = useState<string | null>(activeGroupKey)\n // Org selector type-to-filter (see ./orgFilter.ts). Reset whenever the popover closes.\n const [orgFilter, setOrgFilter] = useState('')\n useEffect(() => {\n setOpenGroup(activeGroupKey)\n }, [activeGroupKey])\n const toggleGroup = (key: string) =>\n setOpenGroup((prev) => (prev === key ? null : key))\n\n return (\n <RailCollapsibleContext.Provider value={collapsible}>\n {/* Backdrop — small-screen drawer only, dismisses on click. */}\n {open ? (\n <div\n aria-hidden\n className=\"fixed inset-0 z-40 bg-black/40 md:hidden\"\n onClick={onClose}\n />\n ) : null}\n <aside\n ref={asideRef}\n id=\"politogy-nav-drawer\"\n role={open ? 'dialog' : undefined}\n aria-modal={open ? 'true' : undefined}\n aria-label={open ? 'Navigation' : undefined}\n className={clsx(\n 'fixed inset-y-0 left-0 flex flex-col border-r border-[color:var(--sidebar-line,var(--line))] bg-[color:var(--sidebar-bg,var(--nav-surface))]',\n // Never hidden: the 64px icon rail below `md`, the full rail from\n // `md` up, and the full rail as a drawer when expanded below `md`.\n open\n ? 'z-50 w-[var(--sidebar-width,236px)]'\n : 'z-30 w-[var(--sidebar-collapsed-width,64px)] md:w-[var(--sidebar-width,236px)]',\n )}\n // Pin the rail's own font explicitly to the Brand token (Reference/UI-Platform\n // \"Typography\") rather than relying on inherited `body` styles. An app that\n // sets its own body font on a sub-view (e.g. Contacts) would otherwise leak\n // into the rail purely by inheritance — one shell definition, never app-derived.\n style={{ fontFamily: 'var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif)' }}\n onKeyDown={trapTab}\n onClick={(e) => {\n // Any nav-link click closes the drawer — including a click on the\n // CURRENT route's link, which would otherwise strand it open since\n // `pathname` never changes to trigger NavAppShell's close effect.\n if (open && (e.target as HTMLElement).closest('a[href]')) (onNavigate ?? onClose)?.()\n }}\n >\n {/* Close button — small-screen drawer only. */}\n {open ? (\n <button\n type=\"button\"\n ref={closeButtonRef}\n onClick={onClose}\n aria-label=\"Collapse navigation\"\n className=\"absolute right-3 top-3 flex h-8 w-8 items-center justify-center rounded-full text-[color:var(--muted)] transition hover:bg-[color:var(--panel-elevated)] hover:text-[color:var(--foreground)] md:hidden\"\n >\n <CloseIcon />\n </button>\n ) : null}\n {/* Header — brand, org card, mode switcher (Specs/Contacts design\n rail: padding 16px 18px, 14px between blocks, hairline below). */}\n <div className={`flex flex-shrink-0 flex-col gap-[14px] border-b border-[color:var(--sidebar-line,var(--line))] px-[18px] py-4 ${rc('max-md:items-center max-md:px-[10px]')}`}>\n {/* Brand — the lockup directly on the rail, no plate; the square\n tile when collapsed. Badge only when no logo was supplied at all. */}\n {/* Below `md` the collapsed rail's logo tile is the expand control\n (Left-Navigation §11.6: the rail is never hidden; the user expands\n it from the rail itself). Hidden while expanded and from `md` up. */}\n {onOpen ? (\n <button\n type=\"button\"\n onClick={onOpen}\n aria-label=\"Expand navigation\"\n aria-expanded={open ?? false}\n data-rail-toggle=\"expand\"\n className={`hidden h-8 w-8 items-center justify-center rounded-lg ${rc('max-md:flex')}`}\n >\n {brand.logoSquareSrc ? (\n <img src={brand.logoSquareSrc} alt=\"\" draggable={false} className=\"h-8 w-8 object-contain\" />\n ) : brand.logoPending ? (\n <span aria-hidden className=\"block h-8 w-8\" />\n ) : (\n <span className=\"flex h-8 w-8 items-center justify-center rounded-xl bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-sm font-black text-[#FFFFFF]\">\n {brand.badgeLabel}\n </span>\n )}\n </button>\n ) : null}\n <Link\n href={brand.homeHref ?? '/'}\n aria-label={brand.logoAlt ?? brand.title}\n className={`flex items-center gap-2.5 ${rc('max-md:justify-center')} ${onOpen ? rc('max-md:hidden') : ''}`}\n >\n {brand.logoSquareSrc ? (\n <img\n src={brand.logoSquareSrc}\n alt=\"\"\n draggable={false}\n data-rail-logo=\"square\"\n className={`hidden h-8 w-8 object-contain ${rc('max-md:block')}`}\n />\n ) : brand.logoPending ? (\n <span aria-hidden className={`hidden h-8 w-8 ${rc('max-md:block')}`} />\n ) : null}\n {brand.logoSrc ? (\n <img\n src={brand.logoSrc}\n alt={brand.logoAlt ?? brand.title}\n draggable={false}\n data-rail-logo=\"horizontal\"\n className={`h-[var(--sidebar-brand-logo-height,24px)] w-auto object-contain ${rc('max-md:hidden')}`}\n />\n ) : brand.logoPending ? (\n <span\n aria-hidden\n className={`block h-[var(--sidebar-brand-logo-height,24px)] ${rc('max-md:hidden')}`}\n />\n ) : (\n <>\n <span\n className={`flex h-9 w-9 items-center justify-center rounded-xl bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-base font-black text-[#FFFFFF] shadow-sm ${brand.logoSquareSrc ? rc('max-md:hidden') : ''}`}\n >\n {brand.badgeLabel}\n </span>\n <span className={`flex flex-col leading-tight ${rc('max-md:hidden')}`}>\n <span className=\"text-base font-extrabold tracking-[-0.01em] text-[color:var(--color-accent-fg,var(--color-accent))]\">\n {brand.title}\n </span>\n {brand.subtitle ? (\n <span className=\"text-[11px] font-semibold uppercase tracking-[0.16em] text-[color:var(--muted)]\">\n {brand.subtitle}\n </span>\n ) : null}\n </span>\n </>\n )}\n </Link>\n\n {/* Organization switcher */}\n {org ? (\n <div className={rc('max-md:flex max-md:justify-center')}>\n <div className={`mb-[7px] mt-[7px] flex items-center justify-between ${rc('max-md:hidden')}`}>\n <p className={NAV_EYEBROW_CLASS}>\n Organization\n </p>\n </div>\n {org.loading ? (\n <div className={`flex w-full items-center gap-2.5 rounded-md border border-[color:var(--line)] bg-[color:var(--panel-elevated)] px-2.5 py-2 shadow-sm ${rc('max-md:w-auto max-md:border-0 max-md:bg-transparent max-md:p-0 max-md:shadow-none')}`}>\n <span\n aria-hidden\n className=\"h-7 w-7 shrink-0 animate-pulse rounded-full bg-[color:var(--panel)]\"\n />\n <span\n aria-hidden\n className={`h-4 flex-1 animate-pulse rounded bg-[color:var(--panel)] ${rc('max-md:hidden')}`}\n />\n <span className=\"sr-only\">Loading organization</span>\n </div>\n ) : org.organizations && org.organizations.length > 0 && org.onSwitch ? (\n <details data-nav-details className=\"group relative\">\n <summary\n style={orgCardStyle}\n title={org.name ?? undefined}\n className={`flex w-full cursor-pointer list-none flex-col overflow-hidden rounded-[5px] border border-[color:var(--sidebar-card-border,var(--sidebar-line,var(--line)))] bg-[color:var(--sidebar-card-bg,var(--panel-elevated))] text-left text-[color:var(--sidebar-text,var(--foreground))] transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))] [&::-webkit-details-marker]:hidden ${rc('max-md:w-auto max-md:items-center max-md:overflow-visible max-md:border-0 max-md:bg-transparent')}`}\n >\n <OrgIconMark org={org} logoSrc={orgLogoSrc} />\n {/* Logo band: white, org's Primary Brand Kit logo ≤70px, never\n cropped/stretched/recolored; \"Upload logo\" for an Admin\n with no logo yet; otherwise the org's display name. */}\n <span className={`relative flex h-[var(--sidebar-org-band-height,70px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc('max-md:hidden')}`}>\n {orgLogoSrc ? (\n <img src={orgLogoSrc} alt=\"\" className=\"max-h-full max-w-[132px] object-contain\" />\n ) : org.canUploadLogo ? (\n <a\n href={org.uploadLogoHref ?? '#'}\n onClick={(e) => e.stopPropagation()}\n className=\"text-xs font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] underline\"\n >\n Upload logo\n </a>\n ) : (\n <span className=\"truncate text-sm font-semibold text-neutral-800\">\n {org.name ?? 'Organization'}\n </span>\n )}\n <span aria-hidden className=\"absolute inset-x-0 bottom-0 h-[3px]\" style={{ backgroundImage: orgGradient }} />\n </span>\n <span className={`flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-[10px] ${rc('max-md:hidden')}`}>\n <span className=\"flex min-w-0 flex-col\">\n <span\n title={org.name ?? undefined}\n className=\"truncate text-[12px] font-semibold leading-[1.2]\"\n >\n {orgPillLabel(org)}\n </span>\n {org.id && !org.loading ? <OrgIdCopyButton id={org.id} /> : null}\n </span>\n <ChevronDown size={14} />\n </span>\n </summary>\n <div className={`absolute left-0 right-0 z-40 mt-1 max-h-[min(60vh,520px)] overflow-y-auto rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)] ${rc('max-md:right-auto max-md:w-[236px]')}`}>\n {shouldShowOrgFilter(org.organizations.length) ? (\n <div className=\"sticky top-0 z-10 bg-[color:var(--panel-elevated)] px-2 pb-1 pt-1\">\n <input\n type=\"search\"\n value={orgFilter}\n onChange={(e) => setOrgFilter(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') {\n setOrgFilter('')\n e.currentTarget.closest('details')?.removeAttribute('open')\n }\n }}\n placeholder={`Filter ${org.organizations.length} organizations`}\n aria-label=\"Filter organizations\"\n autoComplete=\"off\"\n className=\"w-full rounded-lg border border-[color:var(--line)] bg-[color:var(--panel)] px-3 py-1.5 text-sm text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n </div>\n ) : null}\n {filterOrgs(org.organizations, orgFilter).length === 0 ? (\n <p className=\"px-3 py-2 text-sm text-[color:var(--muted)]\">No organization matches “{orgFilter}”.</p>\n ) : null}\n {filterOrgs(org.organizations, orgFilter).map((o) => {\n const selected = o.id === org.id\n return (\n <button\n key={o.id}\n type=\"button\"\n onClick={(e) => {\n // Close the <details> popover, then switch.\n e.currentTarget.closest('details')?.removeAttribute('open')\n setOrgFilter('')\n if (!selected) org.onSwitch?.(o.id)\n }}\n aria-current={selected ? 'true' : undefined}\n className={[\n 'flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm',\n selected\n ? 'font-semibold text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n <span\n style={{ backgroundColor: o.brandColor || ORG_PILL_DEFAULT }}\n className=\"flex h-6 w-6 shrink-0 items-center justify-center overflow-hidden rounded-full text-[10px] font-bold text-[#FFFFFF]\"\n >\n {resolveOrgLogoUrl(o.logoUrl) ? (\n <img\n src={resolveOrgLogoUrl(o.logoUrl)}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n (o.name ?? 'Org').slice(0, 2).toUpperCase()\n )}\n </span>\n <span title={o.name ?? o.id} className=\"truncate\">\n {o.name ?? o.id.slice(0, 8)}\n </span>\n </button>\n )\n })}\n </div>\n </details>\n ) : (\n <button\n type=\"button\"\n onClick={org.onClick}\n style={orgCardStyle}\n title={org.name ?? undefined}\n className={`flex w-full flex-col overflow-hidden rounded-[5px] border border-[color:var(--sidebar-card-border,var(--sidebar-line,var(--line)))] bg-[color:var(--sidebar-card-bg,var(--panel-elevated))] text-left text-[color:var(--sidebar-text,var(--foreground))] transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))] ${rc('max-md:w-auto max-md:items-center max-md:overflow-visible max-md:border-0 max-md:bg-transparent')}`}\n >\n <OrgIconMark org={org} logoSrc={orgLogoSrc} />\n <span className={`relative flex h-[var(--sidebar-org-band-height,70px)] w-full items-center justify-center bg-[#FFFFFF] px-3 py-[7px] ${rc('max-md:hidden')}`}>\n {orgLogoSrc ? (\n <img src={orgLogoSrc} alt=\"\" className=\"max-h-full max-w-[132px] object-contain\" />\n ) : org.canUploadLogo ? (\n <a\n href={org.uploadLogoHref ?? '#'}\n onClick={(e) => e.stopPropagation()}\n className=\"text-xs font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] underline\"\n >\n Upload logo\n </a>\n ) : (\n <span className=\"truncate text-sm font-semibold text-neutral-800\">\n {org.name ?? 'Organization'}\n </span>\n )}\n <span aria-hidden className=\"absolute inset-x-0 bottom-0 h-[3px]\" style={{ backgroundImage: orgGradient }} />\n </span>\n <span className={`flex w-full min-w-0 items-center justify-between gap-[9px] px-[10px] py-[10px] ${rc('max-md:hidden')}`}>\n <span className=\"flex min-w-0 flex-col\">\n <span\n title={org.name ?? undefined}\n className=\"truncate text-[12px] font-semibold leading-[1.2]\"\n >\n {orgPillLabel(org)}\n </span>\n {org.id && !org.loading ? <OrgIdCopyButton id={org.id} /> : null}\n </span>\n <ChevronDown size={14} />\n </span>\n </button>\n )}\n </div>\n ) : null}\n\n {/* Mode selector — Reference/UI-Platform: \"A row of three icon buttons\n — Relationship · Campaign · Petition — under the org card, never a\n dropdown, with the current mode's name beneath.\" Identical in every\n app, mode-scoped apps included: the app's own mode is selected and\n the other available modes navigate to that mode's landing page. */}\n {mode ? (\n <div className={rc('max-md:w-full')}>\n <div\n role=\"radiogroup\"\n aria-label=\"Mode\"\n className={`flex w-full items-center gap-1 rounded-lg border border-[color:var(--border-inverse,var(--sidebar-line,var(--line)))] bg-[color:var(--mode-track-bg,var(--panel-elevated))] p-[3px] ${rc('max-md:flex-col max-md:items-stretch')}`}\n >\n {(mode.options && mode.options.length > 0 ? mode.options : [{ id: mode.label, label: mode.label, icon: ModeIcon }]).map(\n (opt) => {\n const selected = opt.label === mode.label\n const OptIcon = opt.icon\n const available = opt.available ?? true\n const title = !available\n ? opt.unavailableTooltip ?? `${opt.label} isn't active for this organization.`\n : opt.label\n return (\n <button\n key={opt.id}\n type=\"button\"\n role=\"radio\"\n title={title}\n aria-label={title}\n aria-checked={selected}\n aria-current={selected ? 'true' : undefined}\n onClick={() => {\n if (available && !selected) mode.onSelect?.(opt.id)\n }}\n disabled={!available}\n className={[\n `flex flex-none items-center justify-center rounded-[5px] px-[9px] py-[6px] transition ${rc('max-md:flex-1')}`,\n !available\n ? 'cursor-not-allowed text-[color:var(--sidebar-text-muted,var(--muted))] opacity-35'\n : selected\n ? 'bg-[color:var(--sidebar-mode-selected-bg,var(--mode-accent,var(--color-accent)))] text-[color:var(--mode-on-accent,var(--color-accent-bg-safe,white))]'\n : 'text-[color:var(--sidebar-text-muted,var(--muted))] hover:bg-[#FFFFFF]/5 hover:text-[color:var(--sidebar-text,var(--foreground))]',\n ].join(' ')}\n >\n {OptIcon ? <OptIcon size={15} className=\"shrink-0\" /> : null}\n </button>\n )\n },\n )}\n </div>\n {/* Sentence-case caption, left-aligned under the switcher\n (\"Relationship mode\") — Specs/Contacts design rail. */}\n <p className={`mt-1.5 text-left text-[11px] leading-[1.2] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] ${rc('max-md:hidden')}`}>\n {modeCaption(mode.label)}\n </p>\n </div>\n ) : null}\n </div>\n\n {/* Scroll region: nav only — the header above stays put. */}\n <div className=\"flex flex-1 flex-col overflow-y-auto px-[10px] py-3\">\n {/* Nav list */}\n <nav className=\"flex flex-col gap-0.5\">\n {nav.groupLabel ? (\n <p className={`${NAV_EYEBROW_CLASS} px-2 pb-1.5 pt-1 ${rc('max-md:hidden')}`}>\n {nav.groupLabel}\n </p>\n ) : null}\n {nav.items.map((item, idx) => {\n // Section heading: groups the rows beneath it. Non-interactive and\n // not focusable, so it is skipped by tab order and never reads as a\n // dead control. Top margin except on the first row, so the groups\n // separate without a stray gap at the top of the rail.\n if (item.kind === 'section') {\n return (\n <NavSectionRow\n key={`section-${idx}-${item.label}`}\n label={item.label}\n first={idx === 0}\n />\n )\n }\n // Flattened tree: the group's children ARE the rail. See nav.flatten.\n if (nav.flatten && item.children && item.children.length > 0) {\n return item.children.map((child, i) => {\n if (child.kind === 'section') {\n return (\n <NavSectionRow\n key={`flat-section-${idx}-${i}-${child.label}`}\n label={child.label}\n first={idx === 0 && i === 0}\n />\n )\n }\n return (\n <NavRow\n key={child.href ?? `flat-${idx}-${i}-${child.label}`}\n item={child}\n active={child.href ? activeFn(pathname, child.href) : false}\n Link={Link}\n variant=\"flat\"\n />\n )\n })\n }\n // Left-Navigation §8.2: the bar is flat — no sub-menus, no\n // accordions, no chevrons. A row with children renders as one row\n // linking to its own page (or its first child's) and is active\n // whenever any page beneath it is (§11.3, by route prefix). The\n // children stay in the tree for breadcrumbs and in-page tabs.\n if (item.children && item.children.length > 0) {\n const selfActive = item.href ? activeFn(pathname, item.href) : false\n const parentActive = selfActive || hasActiveChild(item, pathname, activeFn)\n return (\n <NavRow\n key={item.href ?? groupKeyOf(item, idx)}\n item={{ ...item, href: item.href ?? firstLeafHref(item), children: undefined }}\n active={parentActive}\n Link={Link}\n />\n )\n }\n const active = item.href ? activeFn(pathname, item.href) : false\n return (\n <NavRow\n key={item.href ?? `nav-${idx}-${item.label}`}\n item={item}\n active={active}\n Link={Link}\n />\n )\n })}\n </nav>\n </div>\n\n {/* Footer — user card (account menu opens upward), then the links row,\n then the build meta (non-production only). Specs/Contacts design rail. */}\n {footer ? (\n <div className={`relative flex-shrink-0 border-t border-[color:var(--sidebar-line,var(--line))] px-[14px] py-3 ${rc('max-md:px-[10px]')}`}>\n {footer.user ? (\n <NavSidebarUserCard\n user={footer.user}\n userMenu={footer.userMenu ?? undefined}\n onSignOut={footer.onSignOut}\n />\n ) : null}\n {footer.links && footer.links.length > 0 ? (\n <div className={`flex flex-wrap items-center justify-center gap-[6px] text-[11px] leading-[1.2] ${footer.user ? 'mt-3' : ''} ${rc('max-md:hidden')}`}>\n {footer.links.map((l, i) => (\n <Fragment key={l.label}>\n {i > 0 ? <span aria-hidden className=\"text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))]\">·</span> : null}\n <a\n href={safeHref(l.href)}\n className=\"text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] hover:text-[color:var(--sidebar-text,var(--foreground))] hover:underline\"\n >\n {l.label}\n </a>\n </Fragment>\n ))}\n </div>\n ) : null}\n {footer.envLabel || footer.commit || footer.version ? (\n <div\n data-shell-meta\n className={`mt-1.5 flex flex-col items-center gap-0.5 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] text-[color:var(--sidebar-meta-text,rgba(255,255,255,0.72))] ${rc('max-md:hidden')}`}\n >\n {/* Row 1: env | commit | version — Specs/Left-Navigation §9:\n plain mono text, centered, no leading or trailing pipes. */}\n <div className=\"flex items-center gap-1.5\">\n {[\n footer.envLabel ? shortEnvLabel(footer.envLabel) : null,\n footer.commit ? footer.commit.slice(-4) : null,\n footer.version ? `v${footer.version.replace(/^v/, '')}` : null,\n ]\n .filter((v): v is string => Boolean(v))\n .map((v, i) => (\n <Fragment key={i}>\n {i > 0 ? <span>|</span> : null}\n <span>{v}</span>\n </Fragment>\n ))}\n </div>\n {/* Row 2: date | author (only when supplied) */}\n {footer.commitDate || footer.commitAuthor ? (\n <div className=\"flex items-center gap-1.5\">\n {footer.commitDate ? (\n <span>\n {new Date(footer.commitDate).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n })}\n </span>\n ) : null}\n {footer.commitDate && footer.commitAuthor ? (\n <span>|</span>\n ) : null}\n {footer.commitAuthor ? (\n <span>{footer.commitAuthor.split(/\\s+/)[0]}</span>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </div>\n ) : null}\n </aside>\n </RailCollapsibleContext.Provider>\n )\n}\n\n// Inline hamburger / close glyphs for the mobile nav drawer — no icon\n// dependency, same idiom as every other inline SVG in this file.\nfunction HamburgerIcon() {\n return (\n <svg\n width={24}\n height={24}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\" />\n <line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\" />\n <line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\" />\n </svg>\n )\n}\n\n/** 14px book-open glyph for the \"Build notes\" quiet button (design). */\nfunction BookOpenIcon() {\n return (\n <svg\n width={14}\n height={14}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"shrink-0\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 7v14\" />\n <path d=\"M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z\" />\n </svg>\n )\n}\n\nfunction SearchIcon({ className }: { className?: string } = {}) {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden=\"true\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n )\n}\n\nfunction CloseIcon() {\n return (\n <svg\n width={20}\n height={20}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n )\n}\n\n// Inline chevron-down (mirrors lucide `ChevronDown`) — no icon dependency.\n// Callers may override `className` to add a rotation (used by expandable groups).\nfunction ChevronDown({ className, size = 16 }: { className?: string; size?: number } = {}) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className ?? 'shrink-0 opacity-80'}\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n )\n}\n\n// A single sidebar nav row. Renders as a routed <Link> (href) or a <button>\n// (onClick), styled identically. Inactive rows animate a left→right gradient\n// sweep on hover (matching the main app); active rows keep the solid accent.\n//\n// `variant=\"sub\"` renders the smaller child rows inside an expanded group: a\n// tighter row whose ACTIVE state is a lighter elevated surface with accent\n// text (not a solid fill — that stays reserved for top-level/parent rows,\n// exactly as the main VRM app's Chakra sidebar treats active sub-items).\n//\n// The gradient was hardcoded to the race-red 400/500 stops; it now reads the\n// token so a Mode with its own accent sweeps in its own colour. chrome.css\n// defaults it to those same two stops, so nothing moves for anyone else.\nconst NAV_HOVER_GRADIENT = 'var(--nav-hover-gradient)'\n\n// A non-interactive section heading. Groups the rows beneath it; not a control,\n// so it is not focusable and carries no hover, no aria-disabled and no role.\n//\n// Rendered at BOTH levels: an app whose routes are nested under a standard nav\n// entry (Petitions nests its whole tree under the Petition Mode row) needs its\n// sections inside the expanded group, not only at the top level.\n//\n// `first` suppresses the leading margin so a rail that opens with a section\n// does not start with a gap.\n// Rail typography/geometry — Specs/Contacts design rail (Reference/UI-Platform\n// v30 → Left bar). Every token has an inline fallback so an app that is not\n// mode-scoped (white rail) keeps a sane rendering.\nconst NAV_EYEBROW_CLASS =\n 'text-[11px] font-bold uppercase leading-[1.2] tracking-[0.09em] text-[color:var(--sidebar-eyebrow,var(--sidebar-text-muted,var(--muted)))]'\nconst NAV_TOP_ICON_SIZE = 17\nconst NAV_TOP_ROW_CLASS = (active: boolean) =>\n `gap-[11px] px-[10px] py-[9px] text-[13px] leading-none ${active ? 'font-semibold' : 'font-normal'}`\nconst NAV_TOP_ACTIVE_CLASS =\n 'bg-[color:var(--sidebar-active-bg,var(--color-accent-bg-safe,var(--color-accent)))] text-[color:var(--sidebar-active-text,white)]'\nconst NAV_TOP_INACTIVE_CLASS =\n 'text-[color:var(--sidebar-row-text,var(--sidebar-text,var(--muted)))] hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel-elevated))] hover:text-[color:var(--sidebar-text,var(--foreground))]'\n\n/** \"Relationship Mode\" → \"Relationship mode\" (design caption is sentence case). */\nfunction modeCaption(label: string): string {\n return label.replace(/\\s+Mode$/i, ' mode')\n}\n\n/** 2px inset rail on the active row, in the Mode accent (design: inset 2px 0 0 0). */\nfunction NavActiveRail() {\n // `--mode-accent` is only set by a declared Mode chrome group; the inline\n // `transparent` fallback is what every other app gets — present but\n // invisible, and absolutely positioned so it moves nothing.\n return (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 w-[2px]\"\n style={{ background: 'var(--mode-accent, transparent)' }}\n />\n )\n}\n\n/** Right-aligned mono count on a nav row (`Contacts · 31.9K`). */\nfunction NavRowBadge({ value }: { value?: string | number | null }) {\n const rc = useRailCollapse()\n if (value === undefined || value === null || value === '') return null\n return (\n <span className={`ml-auto shrink-0 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] font-semibold leading-none text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] ${rc('max-md:hidden')}`}>\n {value}\n </span>\n )\n}\n\nfunction NavSectionRow({\n label,\n first,\n variant = 'top',\n}: {\n label: string\n first: boolean\n variant?: 'top' | 'sub'\n}) {\n const rc = useRailCollapse()\n // Collapsed rail: the eyebrow becomes a 1px divider (Left-Navigation §11.6).\n // The divider is its OWN decorative element (aria-hidden) now, not the\n // heading's text painted transparent over it — a live capture on Forms at\n // 375px (light theme) measured that transparent heading text as a real\n // rgba(0,0,0,0)-on-rgb(63,64,68) 1.00:1 contrast failure (\"Collect\"/\n // \"Account\"), because a contrast scan sees the painted (if invisible)\n // glyphs, not the 1px overflow-hidden box clipping them. Moving the label\n // itself to `sr-only` (truly off-screen, same treatment the first section\n // already used) removes it from the visual contrast surface entirely while\n // it stays in the DOM as a heading for screen readers, same as before.\n const labelCollapsed = variant === 'sub' ? '' : rc('max-md:sr-only')\n return (\n <>\n {variant !== 'sub' && !first ? (\n <div\n aria-hidden\n className={rc('max-md:mx-2 max-md:my-2 max-md:h-px max-md:bg-[color:var(--sidebar-line,var(--line))]')}\n />\n ) : null}\n <p\n className={[\n NAV_EYEBROW_CLASS,\n variant === 'sub' ? 'px-3 pb-0.5' : 'px-2 pb-1.5 pt-1',\n first ? '' : variant === 'sub' ? 'mt-3' : 'mt-[14px]',\n labelCollapsed,\n ].join(' ')}\n >\n {label}\n </p>\n </>\n )\n}\n\nfunction NavRow({\n item,\n active,\n Link,\n variant = 'top',\n}: {\n item: NavItem\n active: boolean\n Link: NavLinkComponent\n variant?: 'top' | 'sub' | 'flat'\n}) {\n const rc = useRailCollapse()\n const Icon = item.icon\n const isSub = variant === 'sub'\n // 'flat' rows keep top-level geometry but take the wash active treatment —\n // tinted surface + accent text — the way V1's full-height rail rows did,\n // rather than the solid fill reserved for parent rows.\n const washActive = variant !== 'top'\n // The active sub-row surface follows the Mode when one is declared.\n //\n // The fallback is INLINE, and has to be. `--mode-accent-surface` is only ever\n // set inside `[data-politogy-mode]`, so an app that is not mode-scoped never\n // has it — and a bare `var(--x)` with no fallback is invalid at\n // computed-value time, which would drop `background-color` all the way to\n // `transparent` and silently delete the active highlight for Contacts, Forms,\n // Surveys and Polls. Nor can the fallback be hoisted into a `:root`\n // declaration: `.dark` is a separate top-level selector here, so a `:root`\n // alias would freeze the LIGHT `--panel-elevated` and inherit it into dark.\n // Resolving at the point of use is the only placement that is correct in both\n // themes, scoped and unscoped.\n const activeClasses = washActive\n ? 'bg-[color:var(--mode-accent-surface,var(--panel-elevated))] text-[color:var(--color-accent-fg,var(--color-accent))] shadow-sm'\n : NAV_TOP_ACTIVE_CLASS\n const wrapperClasses = [\n 'group relative block overflow-hidden transition',\n isSub ? 'rounded-md' : 'rounded-[5px]',\n active ? activeClasses : isSub ? 'text-[color:var(--sidebar-text,var(--muted))] hover:text-[#FFFFFF]' : NAV_TOP_INACTIVE_CLASS,\n ].join(' ')\n\n const rowPadding = isSub ? 'gap-3 px-3 py-1.5 text-[13px] font-semibold' : NAV_TOP_ROW_CLASS(active)\n const iconSize = isSub ? 16 : NAV_TOP_ICON_SIZE\n // Glyphs inherit the row's text color in every variant.\n const iconClass = 'text-current'\n\n const inner = (\n <>\n {!active ? (\n // Sub rows keep the left→right gradient sweep; top-level rows take a\n // flat wash on hover (design rail: rgba(255,255,255,.05)).\n isSub ? (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-y-0 left-0 w-0 transition-[width] duration-300 group-hover:w-full\"\n style={{ background: NAV_HOVER_GRADIENT }}\n />\n ) : null\n ) : (\n <NavActiveRail />\n )}\n <span className={`relative z-10 flex items-center ${rowPadding} ${rc('max-md:justify-center max-md:px-0')}`}>\n {Icon ? (\n <Icon size={iconSize} className={`shrink-0 ${iconClass}`} />\n ) : (\n // A row with no glyph still needs something on the icon rail.\n <span aria-hidden className={`hidden text-[11px] font-semibold uppercase ${rc('max-md:inline')}`}>\n {item.label.slice(0, 2)}\n </span>\n )}\n <span className={`min-w-0 flex-1 truncate ${rc('max-md:hidden')}`}>{item.label}</span>\n <NavRowBadge value={item.badge} />\n </span>\n </>\n )\n\n // A gated row renders as a non-interactive span: dimmed, not focusable, and\n // carrying its reason as a tooltip. Same treatment a disabled NavTab gets, so\n // gating reads identically in the sidebar and in a tab strip.\n if (item.disabled) {\n return (\n <span\n aria-disabled=\"true\"\n title={item.disabledTitle ?? item.label}\n className={`${wrapperClasses} cursor-not-allowed opacity-50`}\n >\n {inner}\n </span>\n )\n }\n\n if (item.onClick && !item.href) {\n return (\n <button\n type=\"button\"\n onClick={item.onClick}\n title={item.label}\n className={`w-full text-left ${wrapperClasses}`}\n >\n {inner}\n </button>\n )\n }\n\n return (\n <Link\n href={item.href ?? '#'}\n aria-current={active ? 'page' : undefined}\n // The tooltip names the row; on the collapsed rail it is also the\n // row's accessible name, since the label is not displayed.\n title={item.label}\n className={wrapperClasses}\n >\n {inner}\n </Link>\n )\n}\n\n// An expandable nav GROUP: a toggle header + a collapsible list of child rows.\n// Faithful twin of the main VRM app's Chakra accordion (Sidebar.tsx /\n// NavItem.tsx):\n// - Clicking the header toggles the children — it never navigates, even when\n// the group carries an `href`.\n// - A right-aligned chevron rotates 180° when open.\n// - The header goes solid accent (white text) when the group owns the active\n// route (its own href OR any child), matching top-level active rows; when\n// merely open it lifts onto the `--panel` surface; otherwise it's a muted row\n// with the same left→right gradient hover sweep as every other nav row.\n// - Children sit on the lighter `--panel` surface, indented and rounded, each\n// rendered through the SAME injected LinkComponent (or as a button for\n// `onClick` children) via <NavRow variant=\"sub\" />.\nfunction NavGroup({\n item,\n active,\n open,\n onToggle,\n pathname,\n activeFn,\n Link,\n}: {\n item: NavItem\n active: boolean\n open: boolean\n onToggle: () => void\n pathname: string\n activeFn: (pathname: string, href: string) => boolean\n Link: NavLinkComponent\n}) {\n const rc = useRailCollapse()\n const Icon = item.icon\n const headerClasses = [\n 'group relative block w-full overflow-hidden text-left transition',\n open ? 'rounded-t-[5px]' : 'rounded-[5px]',\n active\n ? NAV_TOP_ACTIVE_CLASS\n : open\n ? 'bg-[color:var(--sidebar-row-hover-bg,var(--panel))] text-[color:var(--sidebar-text,var(--foreground))]'\n : NAV_TOP_INACTIVE_CLASS,\n ].join(' ')\n\n return (\n <div>\n <button\n type=\"button\"\n // A group header ALWAYS toggles. When the item also carries its own\n // onClick, that runs too — so a parent can navigate to its section\n // dashboard (e.g. Email Broadcast → /relationship/email/dashboard) and\n // expand in one click. Existing apps pass no parent onClick, so their\n // behavior is unchanged (shell-nav-handoff §2).\n onClick={() => {\n onToggle()\n item.onClick?.()\n }}\n aria-expanded={open}\n title={item.label}\n className={headerClasses}\n >\n {active ? <NavActiveRail /> : null}\n <span className={`relative z-10 flex items-center ${NAV_TOP_ROW_CLASS(active)} ${rc('max-md:justify-center max-md:px-0')}`}>\n {Icon ? (\n <Icon size={NAV_TOP_ICON_SIZE} className=\"shrink-0 text-current\" />\n ) : null}\n <span className={`min-w-0 flex-1 truncate ${rc('max-md:hidden')}`}>{item.label}</span>\n <NavRowBadge value={item.badge} />\n <ChevronDown\n className={[\n 'shrink-0 opacity-80 transition-transform duration-200',\n open ? 'rotate-180' : '',\n rc('max-md:hidden'),\n ].join(' ')}\n />\n </span>\n </button>\n\n {open ? (\n <div className={`overflow-hidden rounded-b-md bg-[color:var(--nav-submenu-bg)] p-1 ${rc('max-md:hidden')}`}>\n <div className=\"flex flex-col gap-0.5\">\n {item.children!.map((child, i) => {\n if (child.kind === 'section') {\n return (\n <NavSectionRow\n key={`sub-section-${i}-${child.label}`}\n label={child.label}\n first={i === 0}\n variant=\"sub\"\n />\n )\n }\n const childActive = child.href ? activeFn(pathname, child.href) : false\n // Depth-3: a child that carries its own children renders as a\n // NESTED collapsible sub-group (e.g. Organization Settings →\n // Subscription & Billing → Wallet). Deeper levels are not\n // rendered — three is the platform maximum.\n if (child.children && child.children.length > 0) {\n return (\n <NavSubGroup\n key={child.href ?? `subgrp-${i}-${child.label}`}\n item={child}\n pathname={pathname}\n activeFn={activeFn}\n Link={Link}\n />\n )\n }\n return (\n <NavRow\n key={child.href ?? `sub-${i}-${child.label}`}\n item={child}\n active={childActive}\n Link={Link}\n variant=\"sub\"\n />\n )\n })}\n </div>\n </div>\n ) : null}\n </div>\n )\n}\n\n// A second-level group INSIDE an expanded group — the depth-3 renderer\n// (Reference/UI-Platform: sub-sub items). Auto-expands when it owns the active\n// route; otherwise toggles locally. Grandchildren render as further-indented\n// sub rows on the same panel surface.\nfunction NavSubGroup({\n item,\n pathname,\n activeFn,\n Link,\n}: {\n item: NavItem\n pathname: string\n activeFn: (pathname: string, href: string) => boolean\n Link: NavLinkComponent\n}) {\n const ownsActive =\n (item.href ? activeFn(pathname, item.href) : false) ||\n (item.children ?? []).some((c) => (c.href ? activeFn(pathname, c.href) : false))\n const [open, setOpen] = useState(ownsActive)\n useEffect(() => {\n if (ownsActive) setOpen(true)\n }, [ownsActive])\n const Icon = item.icon\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n aria-expanded={open}\n className={[\n 'flex w-full items-center gap-2.5 rounded px-3 py-1.5 text-left text-[13px] font-medium transition',\n ownsActive\n ? 'text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'text-[color:var(--sidebar-text,var(--muted))] hover:bg-[color:var(--nav-row-hover)] hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {Icon ? <Icon size={15} className=\"shrink-0 text-current\" /> : null}\n <span className=\"flex-1\">{item.label}</span>\n <ChevronDown\n className={[\n 'shrink-0 opacity-70 transition-transform duration-200',\n open ? 'rotate-180' : '',\n ].join(' ')}\n />\n </button>\n {open ? (\n <div className=\"ml-4 flex flex-col gap-0.5 border-l border-[color:var(--line)] pl-2\">\n {item.children!.map((leaf, i) => (\n <NavRow\n key={leaf.href ?? `subsub-${i}-${leaf.label}`}\n item={leaf}\n active={leaf.href ? activeFn(pathname, leaf.href) : false}\n Link={Link}\n variant=\"sub\"\n />\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\n// Right-aligned copy affordance for the org id, shown beside the \"Organization\"\n// label. Copies the full id and briefly swaps its text to \"Copied\".\nfunction OrgIdCopyButton({ id }: { id: string }) {\n const [copied, setCopied] = useState(false)\n return (\n <button\n type=\"button\"\n onClick={() => {\n try {\n void navigator.clipboard?.writeText(id)\n } catch {\n /* clipboard unavailable — ignore */\n }\n setCopied(true)\n setTimeout(() => setCopied(false), 1500)\n }}\n title=\"Copy organization id\"\n className=\"-ml-1 rounded px-1 text-left font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel))]\"\n >\n {copied ? 'Copied' : `…${id.slice(-8)}`}\n </button>\n )\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavUser = {\n name: string | null\n email?: string | null\n /** Profile PHOTO url — highest-precedence avatar source. */\n avatarUrl?: string | null\n /** Memoji url — used when no photo is set; falls back to initials. */\n memojiUrl?: string | null\n tier?: string | null\n role?: string | null\n}\n\nexport type NavTopBarAction = {\n key: string\n /**\n * Canonical top-bar slot. When set, the glyph is sourced by NAME from the\n * Brand API via `--topbar-icon-<slot>`; `icon` becomes the fallback used\n * until the runtime Brand stylesheet lands (or when the token is unset).\n */\n slot?: TopBarIconSlot\n icon: NavIcon\n label: string\n onClick?: () => void\n href?: string\n badge?: number | null\n tone?: 'default' | 'warning' | 'danger'\n /** Tooltip body shown under the icon (label is the tooltip title). */\n description?: string\n}\n\nexport type NavLinkedAccount = {\n id: string\n name: string | null\n email?: string | null\n avatarUrl?: string | null\n active?: boolean\n}\n\nexport type NavRoleBadge = {\n role: string\n orgName?: string | null\n}\n\n/**\n * The My Account menu (avatar dropdown) — mirrors the main VRM app's user\n * menu: My Profile / Organization Settings links, a ROLES & ORGANIZATIONS\n * section, an ACCOUNTS switcher, an optional theme control, then Sign out.\n * Every section renders only when its data is supplied.\n */\nexport type NavUserMenu = {\n myProfileHref?: string\n organizationSettingsHref?: string\n roles?: NavRoleBadge[]\n accounts?: NavLinkedAccount[]\n onSwitchAccount?: (id: string) => void\n onRemoveAccount?: (id: string) => void\n addAccountHref?: string\n onAddAccount?: () => void\n /**\n * Navigation display (Sub Menu / Tabs Only / Both) — lives in the account\n * menu since 0.68.0; the top-bar `NavDisplayAction` popover is retired from\n * the standard cluster (design: 4 icon buttons + Help).\n */\n navDisplay?: {\n value: NavDisplayMode\n onChange: (next: NavDisplayMode) => void\n }\n /** Theme preference segmented control (Light / System / Dark). */\n theme?: {\n value: ThemePreference\n onChange: (next: ThemePreference) => void\n }\n}\n\nexport type NavBreadcrumb = {\n label: string\n href?: string\n}\n\nexport type NavTopBarProps = {\n /**\n * Chrome-owned page title line (`<h1>` above main). Omit when the page body\n * owns its own title (registry `pageTitle: false`, e.g. Contacts).\n */\n title?: string\n subtitle?: string\n /**\n * Breadcrumb trail rendered UNDER the page title (Reference/UI-Platform:\n * every page and sub-page/tab shows its location). Last crumb = current\n * location (non-link); earlier crumbs may carry hrefs.\n */\n breadcrumbs?: NavBreadcrumb[]\n user?: NavUser | null\n userMenu?: NavUserMenu\n onSignOut?: () => void\n /**\n * Structured icon-button action cluster (32×32 circular buttons with optional\n * count badges), rendered before the `actions` slot. Matches the main app's\n * topbar action icons.\n */\n actionsList?: NavTopBarAction[]\n /** App-specific action cluster rendered left of the theme toggle. */\n actions?: ReactNode\n /** Theme toggle slot (injected so this package needs no theme dependency). */\n themeToggle?: ReactNode\n /**\n * Mobile drawer trigger (owned by `NavAppShell`). Supplying it renders a\n * hamburger button, hidden at `lg` and up, as the first thing in the header\n * — below `lg` the sidebar is otherwise unreachable. Omit to render no\n * hamburger at all (e.g. `NavTopBar` used standalone).\n */\n onOpenNav?: () => void\n /** Whether the drawer `onOpenNav` opens is currently open (drives `aria-expanded`). */\n navOpen?: boolean\n /**\n * Universal search — Reference/UI-Platform \"Top bar → required elements\":\n * the search field, 320px wide, at the left end of the bar; nothing else\n * sits on the left. Omit `onChange`/`onSubmit` for a decorative field (an\n * app that has not wired search yet still gets the correct chrome).\n */\n search?: {\n placeholder?: string\n value?: string\n onChange?: (value: string) => void\n onSubmit?: (value: string) => void\n }\n /**\n * Build notes — a quiet text button that starts the right-hand group\n * (Reference/UI-Platform \"Top bar → required elements\").\n */\n /**\n * Where the My Account trigger lives. `'topbar'` (default for a standalone\n * `NavTopBar`) keeps the avatar + name + chevron at the right end of the bar;\n * `'sidebar'` / `'none'` hide it here — `NavAppShell` passes `'sidebar'` and\n * draws the user card in the left-bar footer instead (UI-Platform v30:\n * \"There is no My Account badge in the top bar\").\n */\n accountMenu?: 'topbar' | 'sidebar' | 'none'\n buildNotes?: {\n label?: string\n onOpen?: () => void\n }\n}\n\nexport function NavTopBar({\n title,\n subtitle,\n breadcrumbs,\n user,\n userMenu,\n onSignOut,\n actionsList,\n actions,\n themeToggle,\n onOpenNav,\n navOpen,\n search,\n buildNotes,\n accountMenu = 'topbar',\n}: NavTopBarProps) {\n // Real name = anything that isn't empty and isn't an email address. The\n // trigger shows \"First L.\" — never the email on both lines.\n const rawName = user?.name?.trim() || ''\n const hasRealName = rawName.length > 0 && !rawName.includes('@')\n const displayName = hasRealName ? formatFirstLast(rawName) : (user?.email ?? 'Signed in')\n const initials = (hasRealName ? rawName : (user?.email ?? 'P')).slice(0, 2).toUpperCase()\n const secondary = hasRealName\n ? user?.email || [user?.tier, user?.role].filter(Boolean).join(' · ') || 'member'\n : [user?.tier, user?.role].filter(Boolean).join(' · ') || 'member'\n // `title` / `subtitle` / `breadcrumbs` are no longer rendered here —\n // Reference/UI-Platform \"Page header\" moved the title into the main body\n // (22px below this bar) and retired the breadcrumb trail entirely. They\n // stay accepted on the prop type so apps mid-migration do not break the\n // build; the chrome just stops drawing them.\n void title\n void subtitle\n void breadcrumbs\n return (\n <div className=\"sticky top-0 z-20\">\n <header className=\"flex min-w-0 h-[var(--topbar-height,60px)] items-center justify-between gap-[8px] md:gap-[14px] border-b border-[color:var(--line)] bg-[color:var(--panel)] px-[var(--topbar-padding-x,20px)]\">\n {onOpenNav ? (\n <button\n type=\"button\"\n onClick={onOpenNav}\n aria-label=\"Open menu\"\n aria-expanded={navOpen ?? false}\n aria-controls=\"politogy-nav-drawer\"\n className={`${topBarIconButtonClass('default')} mr-1 shrink-0 md:hidden`}\n >\n <HamburgerIcon />\n </button>\n ) : null}\n\n {/* Universal search — the only thing on the left end of the bar. 320px\n (Reference/UI-Platform); below md it shrinks so the bar never pushes\n the page wider than a 390px phone. */}\n <label className=\"relative flex h-9 w-[320px] min-w-0 max-w-full shrink items-center md:shrink-0\">\n <SearchIcon className=\"pointer-events-none absolute left-[10px] h-[15px] w-[15px] text-[color:var(--muted)]\" />\n <input\n type=\"search\"\n placeholder={search?.placeholder ?? 'Search'}\n value={search?.value}\n onChange={search?.onChange ? (e) => search.onChange?.(e.target.value) : undefined}\n onKeyDown={\n search?.onSubmit\n ? (e) => {\n if (e.key === 'Enter') search.onSubmit?.((e.target as HTMLInputElement).value)\n }\n : undefined\n }\n readOnly={!search?.onChange}\n className=\"h-full w-full rounded-[5px] border border-[color:var(--line)] bg-[color:var(--surface-sunken,var(--panel-elevated))] pl-[33px] pr-10 text-[13px] text-[color:var(--foreground)] placeholder:text-[color:var(--muted)] focus:outline-none focus:ring-2 focus:ring-[color:var(--color-accent)]\"\n />\n <kbd\n aria-hidden\n className=\"pointer-events-none absolute right-[10px] hidden md:block rounded-[3px] border border-[color:var(--line)] px-[5px] py-px font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[12px] leading-[1.2] text-[color:var(--muted)]\"\n >\n /\n </kbd>\n </label>\n\n <div className=\"relative ml-auto flex shrink-0 items-center gap-[var(--topbar-icon-gap,8px)]\">\n {/* Reference/UI-Platform \"Top bar — required elements\" (2026-10-03):\n there is no Build notes control. Rendered only if an app opts in. */}\n {buildNotes ? (\n <button\n type=\"button\"\n onClick={buildNotes?.onOpen}\n className=\"inline-flex h-8 shrink-0 items-center gap-1.5 rounded-[5px] px-3 text-xs font-semibold text-[color:var(--muted)] transition hover:bg-[color:var(--surface-sunken,var(--panel-elevated))] hover:text-[color:var(--foreground)]\"\n >\n <BookOpenIcon />\n {buildNotes?.label ?? 'Build notes'}\n </button>\n ) : null}\n {actionsList && actionsList.length > 0\n ? actionsList.map((action) => (\n <NavTopBarActionButton key={action.key} action={action} />\n ))\n : null}\n {actions}\n {themeToggle}\n\n {/* My Account menu — avatar + name/email + chevron trigger, with the\n full account dropdown (profile/org links, roles, account switcher,\n appearance, sign out). Native <details> popover. Hidden when the\n shell draws the user card in the left-bar footer instead. */}\n {accountMenu === 'topbar' ? (\n <details data-nav-details className=\"group/acct relative\">\n <summary className=\"group/tbtip relative flex cursor-pointer list-none items-center gap-2.5 rounded-full py-1 pl-1 pr-2 transition hover:bg-[color:var(--panel-elevated)] [&::-webkit-details-marker]:hidden\">\n {/* Same circle size as every top-bar icon button (one shared var).\n Avatar precedence: photo → memoji → initials. */}\n <span className=\"flex h-[var(--topbar-icon-button-size,32px)] w-[var(--topbar-icon-button-size,32px)] items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-xs font-bold text-[#FFFFFF]\">\n {user?.avatarUrl || user?.memojiUrl ? (\n <img\n src={(user.avatarUrl || user.memojiUrl) as string}\n alt=\"\"\n className=\"h-full w-full object-cover\"\n />\n ) : (\n initials\n )}\n </span>\n <span className=\"hidden flex-col leading-tight md:flex\">\n <span className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n {displayName}\n </span>\n <span className=\"text-xs text-[color:var(--muted)]\">{secondary}</span>\n </span>\n <ChevronDown />\n <span className=\"group-open/acct:hidden\">\n <TopBarTooltip\n title=\"My Account\"\n description={\n <>\n {hasRealName ? rawName : user?.email ?? 'Signed in'}\n {user?.email ? (\n <>\n <br />\n {user.email}\n </>\n ) : null}\n <br />\n Profile, organizations, appearance and sign out.\n </>\n }\n />\n </span>\n </summary>\n {/*\n The menu grows with the user's data — roles, linked accounts, the\n theme control — and on a short viewport (or a user in many orgs) it\n ran past the bottom of the screen with no way to scroll, putting\n Sign out permanently out of reach. Cap the panel at the viewport,\n scroll the SECTIONS, and keep Sign out outside that scroll area so\n it is always on screen no matter how long the list gets.\n */}\n <NavAccountMenuPanel userMenu={userMenu} onSignOut={onSignOut} placement=\"below\" />\n </details>\n ) : null}\n {accountMenu === 'topbar' && !hasRealName && user ? (\n <NamePromptBubble profileHref={userMenu?.myProfileHref} />\n ) : null}\n </div>\n </header>\n {/* Brand gradient rule — Reference/UI-Platform \"Top bar → required\n elements\": \"A 3px strip of the brand gradient (blue → red) runs\n directly beneath it.\" Chrome-owned token, never the party-identity\n race-red. */}\n <div\n aria-hidden\n className=\"h-[3px] w-full shrink-0\"\n style={{\n background:\n 'var(--chrome-gradient, linear-gradient(to right, #007BFF, #A54B7A, #E63946))',\n }}\n />\n </div>\n )\n}\n\n/**\n * The account menu body — profile/org links, roles, account switcher,\n * appearance, navigation display, sign out. One definition drawn from two\n * triggers: the top-bar avatar (`placement=\"below\"`, legacy) and the left-bar\n * footer user card (`placement=\"above\"`, Reference/UI-Platform v30).\n */\nfunction NavAccountMenuPanel({\n userMenu,\n onSignOut,\n placement,\n}: {\n userMenu?: NavUserMenu\n onSignOut?: () => void\n placement: 'below' | 'above'\n}) {\n const rc = useRailCollapse()\n const wrapper =\n placement === 'above'\n ? rc('max-md:right-auto max-md:w-64') + ' absolute bottom-full left-0 right-0 z-40 mb-2 flex max-h-[calc(100vh-5rem)] flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 text-[color:var(--foreground)] shadow-[var(--shadow-soft)]'\n : 'absolute right-0 z-30 mt-2 flex max-h-[calc(100vh-5rem)] w-72 flex-col overflow-hidden rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] py-1 shadow-[var(--shadow-soft)]'\n return (\n <div className={wrapper}>\n {placement === 'below' ? <TopBarPanelArrow /> : null}\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n {userMenu?.myProfileHref ? (\n <a\n href={safeHref(userMenu.myProfileHref)}\n className=\"flex w-full items-center gap-2.5 px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n <ProfileIcon />\n My Profile\n </a>\n ) : null}\n {userMenu?.organizationSettingsHref ? (\n <a\n href={safeHref(userMenu.organizationSettingsHref)}\n className=\"flex w-full items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n <BriefcaseIcon />\n Organization Settings\n </a>\n ) : null}\n\n {userMenu?.roles && userMenu.roles.length > 0 ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Roles & Organizations\n </p>\n <ul className=\"flex flex-col gap-1.5\">\n {userMenu.roles.map((r, i) => (\n <li key={`${r.role}-${i}`} className=\"flex flex-wrap items-center gap-1.5 text-sm\">\n <span className=\"rounded-md bg-[color:var(--panel)] px-2 py-0.5 text-xs font-bold uppercase tracking-wide text-[color:var(--foreground)]\">\n {r.role}\n </span>\n {r.orgName ? (\n <span className=\"text-[color:var(--muted)]\">in {r.orgName}</span>\n ) : null}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n\n {userMenu?.accounts && userMenu.accounts.length > 0 ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Accounts\n </p>\n <ul className=\"flex flex-col gap-1\">\n {userMenu.accounts.map((a) => (\n <li key={a.id} className=\"flex items-center gap-2.5\">\n <button\n type=\"button\"\n onClick={() => {\n if (!a.active) userMenu.onSwitchAccount?.(a.id)\n }}\n className=\"flex min-w-0 flex-1 items-center gap-2.5 rounded-lg px-1 py-1 text-left hover:bg-[color:var(--panel)]\"\n >\n <span className=\"flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] text-[11px] font-bold text-[#FFFFFF]\">\n {a.avatarUrl ? (\n <img src={a.avatarUrl} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n (a.name ?? a.email ?? '?').slice(0, 2).toUpperCase()\n )}\n </span>\n <span className=\"flex min-w-0 flex-col leading-tight\">\n <span\n className={[\n 'truncate text-sm font-semibold',\n a.active\n ? 'text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {a.name ?? a.email ?? a.id.slice(0, 8)}\n </span>\n <span className=\"truncate text-xs text-[color:var(--muted)]\">\n {a.active ? 'Active' : a.email ?? ''}\n </span>\n </span>\n </button>\n {!a.active && userMenu.onRemoveAccount ? (\n <button\n type=\"button\"\n aria-label={`Remove ${a.name ?? a.email ?? 'account'}`}\n onClick={() => userMenu.onRemoveAccount?.(a.id)}\n className=\"shrink-0 rounded p-1 text-[color:var(--color-accent-fg,var(--color-accent))] hover:bg-[color:var(--panel)]\"\n >\n <TrashIcon />\n </button>\n ) : null}\n </li>\n ))}\n </ul>\n {userMenu.addAccountHref || userMenu.onAddAccount ? (\n userMenu.addAccountHref ? (\n <a\n href={safeHref(userMenu.addAccountHref)}\n className=\"mt-1.5 flex items-center gap-2.5 rounded-lg px-1 py-1.5 text-sm font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:bg-[color:var(--panel)]\"\n >\n <AddUserIcon />\n Add Account\n </a>\n ) : (\n <button\n type=\"button\"\n onClick={userMenu.onAddAccount}\n className=\"mt-1.5 flex w-full items-center gap-2.5 rounded-lg px-1 py-1.5 text-left text-sm font-semibold text-[color:var(--color-accent-fg,var(--color-accent))] hover:bg-[color:var(--panel)]\"\n >\n <AddUserIcon />\n Add Account\n </button>\n )\n ) : null}\n </div>\n ) : null}\n\n {userMenu?.theme ? (\n <div className=\"border-t border-[color:var(--line)]\">\n <NavThemeControl\n value={userMenu.theme.value}\n onChange={userMenu.theme.onChange}\n />\n </div>\n ) : null}\n {userMenu?.navDisplay ? (\n <div className=\"border-t border-[color:var(--line)] px-4 py-3\">\n <p className=\"mb-2 text-[11px] font-semibold uppercase tracking-[0.08em] text-[color:var(--muted)]\">\n Navigation display\n </p>\n <div role=\"radiogroup\" aria-label=\"Navigation display\" className=\"flex flex-col gap-0.5\">\n {NAV_DISPLAY_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={userMenu.navDisplay?.value === opt.value}\n onClick={() => userMenu.navDisplay?.onChange(opt.value)}\n className={[\n 'flex w-full items-center justify-between rounded-md px-2 py-1.5 text-left text-sm font-medium',\n userMenu.navDisplay?.value === opt.value\n ? 'text-[color:var(--color-accent-fg,var(--color-accent))]'\n : 'text-[color:var(--foreground)] hover:bg-[color:var(--panel)]',\n ].join(' ')}\n >\n {opt.label}\n {userMenu.navDisplay?.value === opt.value ? <span aria-hidden>✓</span> : null}\n </button>\n ))}\n </div>\n </div>\n ) : null}\n </div>\n\n {onSignOut ? (\n <button\n type=\"button\"\n onClick={onSignOut}\n className=\"flex w-full shrink-0 items-center gap-2.5 border-t border-[color:var(--line)] px-4 py-2.5 text-left text-sm font-medium text-[color:var(--foreground)] hover:bg-[color:var(--panel)] hover:text-[color:var(--color-accent-fg,var(--color-accent))]\"\n >\n <SignOutIcon />\n Sign out\n </button>\n ) : null}\n </div>\n )\n}\n\n/**\n * Left-bar footer user card: 28px avatar · name · email · chevron-up. Opens\n * the account menu upward (Specs/Contacts design rail; UI-Platform v30 →\n * \"The user … lives in the left bar footer\").\n */\nfunction NavSidebarUserCard({\n user,\n userMenu,\n onSignOut,\n}: {\n user: NavUser\n userMenu?: NavUserMenu\n onSignOut?: () => void\n}) {\n const rawName = user.name?.trim() || ''\n const hasRealName = rawName.length > 0 && !rawName.includes('@')\n // Left-Navigation §10: \"First L.\" — first name plus last initial.\n const displayName = hasRealName ? shortUserName(rawName) : (user.email ?? 'Signed in')\n const initials = hasRealName\n ? rawName.split(/\\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join('').toUpperCase()\n : (user.email ?? 'P').slice(0, 2).toUpperCase()\n const secondary = hasRealName\n ? user.email || [user.tier, user.role].filter(Boolean).join(' · ') || 'member'\n : [user.tier, user.role].filter(Boolean).join(' · ') || 'member'\n const rc = useRailCollapse()\n return (\n <details data-nav-details className=\"group/acct relative\">\n <summary\n aria-label=\"My Account\"\n className={`flex w-full cursor-pointer list-none items-center gap-[9px] rounded-[5px] px-1 py-1 text-left transition hover:bg-[color:var(--sidebar-row-hover-bg,var(--panel-elevated))] [&::-webkit-details-marker]:hidden ${rc('max-md:justify-center max-md:px-0')}`}\n >\n <span className=\"flex h-7 w-7 shrink-0 items-center justify-center overflow-hidden rounded-full bg-[color:var(--sidebar-avatar-bg,var(--color-accent-bg-safe,var(--color-accent)))] text-[11px] font-bold text-[#FFFFFF]\">\n {user.avatarUrl || user.memojiUrl ? (\n <img src={(user.avatarUrl || user.memojiUrl) as string} alt=\"\" className=\"h-full w-full object-cover\" />\n ) : (\n initials\n )}\n </span>\n <span className={`flex min-w-0 flex-1 flex-col ${rc('max-md:hidden')}`}>\n <span className=\"truncate text-[12px] font-semibold leading-[1.2] text-[color:var(--sidebar-text,var(--foreground))]\">\n {displayName}\n </span>\n <span className=\"truncate text-[11px] leading-[1.3] text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))]\">\n {secondary}\n </span>\n </span>\n <ChevronDown size={14} className={`shrink-0 rotate-180 text-[color:var(--sidebar-caption,var(--sidebar-text-muted,var(--muted)))] transition group-open/acct:rotate-0 ${rc('max-md:hidden')}`} />\n </summary>\n <NavAccountMenuPanel userMenu={userMenu} onSignOut={onSignOut} placement=\"above\" />\n {!hasRealName ? <NamePromptBubble profileHref={userMenu?.myProfileHref} placement=\"above\" /> : null}\n </details>\n )\n}\n\n/** `#RRGGBB` (+ optional alpha) → `rgba(r,g,b,a)`; undefined for anything else. */\nfunction hexToRgba(hex: string | null | undefined, alpha: number): string | undefined {\n if (!hex) return undefined\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim())\n if (!m) return undefined\n const n = parseInt(m[1], 16)\n return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${alpha})`\n}\n\n/**\n * Floating, per-session-dismissable bubble under the account trigger that\n * prompts a user with no display name to set their first + last name. The\n * arrow points up at the avatar; dismissal is remembered in sessionStorage\n * until they actually set a name.\n */\nfunction NamePromptBubble({ profileHref, placement = 'below' }: { profileHref?: string; placement?: 'below' | 'above' }) {\n const KEY = 'politogy_name_prompt_dismissed'\n const [dismissed, setDismissed] = useState(true)\n useEffect(() => {\n try {\n setDismissed(sessionStorage.getItem(KEY) === '1')\n } catch {\n setDismissed(false)\n }\n }, [])\n if (dismissed) return null\n return (\n <div\n className={\n placement === 'above'\n ? 'absolute bottom-full left-0 z-30 mb-2 w-64 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-3 text-left shadow-[var(--shadow-soft)]'\n : 'absolute right-4 top-full z-30 mt-2 w-64 rounded-xl border border-[color:var(--line)] bg-[color:var(--panel-elevated)] p-3 shadow-[var(--shadow-soft)]'\n }\n >\n <span\n aria-hidden\n className={\n placement === 'above'\n ? 'absolute -bottom-[5px] left-[14px] h-2.5 w-2.5 rotate-45 border-b border-r border-[color:var(--line)] bg-[color:var(--panel-elevated)]'\n : 'absolute -top-[5px] right-[11px] h-2.5 w-2.5 rotate-45 border-l border-t border-[color:var(--line)] bg-[color:var(--panel-elevated)]'\n }\n />\n <p className=\"text-sm font-semibold text-[color:var(--foreground)]\">\n Add your name\n </p>\n <p className=\"mt-0.5 text-xs leading-snug text-[color:var(--muted)]\">\n Set your first and last name so teammates see you — not your email.\n </p>\n <div className=\"mt-2 flex items-center gap-2\">\n {profileHref ? (\n <a\n href={safeHref(profileHref)}\n className=\"rounded-full bg-[color:var(--color-accent-bg-safe,var(--color-accent))] px-3 py-1 text-xs font-semibold text-[#FFFFFF] hover:opacity-90\"\n >\n Set name\n </a>\n ) : null}\n <button\n type=\"button\"\n onClick={() => {\n setDismissed(true)\n try {\n sessionStorage.setItem(KEY, '1')\n } catch {\n /* session-only dismiss */\n }\n }}\n className=\"rounded-full border border-[color:var(--line)] px-3 py-1 text-xs font-semibold text-[color:var(--foreground)] hover:bg-[color:var(--panel)]\"\n >\n Dismiss\n </button>\n </div>\n </div>\n )\n}\n\n/** \"Spencer Hill\" → \"Spencer H.\" — first name + last initial. */\nfunction formatFirstLast(name: string): string {\n const parts = name.split(/\\s+/).filter(Boolean)\n if (parts.length === 1) return parts[0]\n return `${parts[0]} ${parts[parts.length - 1][0].toUpperCase()}.`\n}\n\nfunction ProfileIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\" />\n <circle cx=\"12\" cy=\"7\" r=\"4\" />\n </svg>\n )\n}\n\nfunction BriefcaseIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <rect x=\"2\" y=\"7\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\" />\n <path d=\"M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\" />\n </svg>\n )\n}\n\nfunction TrashIcon() {\n return (\n <svg width={14} height={14} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\" />\n </svg>\n )\n}\n\nfunction AddUserIcon() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden>\n <path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\" />\n <circle cx=\"8.5\" cy=\"7\" r=\"4\" />\n <line x1=\"20\" y1=\"8\" x2=\"20\" y2=\"14\" />\n <line x1=\"23\" y1=\"11\" x2=\"17\" y2=\"11\" />\n </svg>\n )\n}\n\n// Inline log-out glyph (mirrors lucide `LogOut`) to avoid an icon dependency.\nfunction SignOutIcon() {\n return (\n <svg\n width={15}\n height={15}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\" />\n <polyline points=\"16 17 21 12 16 7\" />\n <line x1=\"21\" x2=\"9\" y1=\"12\" y2=\"12\" />\n </svg>\n )\n}\n\n// A single 32×32 circular icon button for the top bar's structured action list.\n// Renders an <a> when `href` is present (external links open in a new tab),\n// otherwise a <button>. Shows a red count badge when `badge > 0`.\nfunction NavTopBarActionButton({ action }: { action: NavTopBarAction }) {\n const Icon = action.icon\n // Universal treatment (Global Rules v9): size, color and hover are a single\n // shared value across every top-bar slot — only the glyph varies per slot.\n // Tone is a semantic state, not a bespoke per-slot style. The class comes\n // from the ONE shared builder in chromeActions so the data-backed widgets\n // and this structured list can never drift apart.\n const className = topBarIconButtonClass(action.tone ?? 'default')\n\n // Per-slot glyph from Brand; `icon` is the fallback until the token resolves.\n // Brand emits Feather/Lucide glyph NAMES, not asset paths.\n const glyphName = useTopBarIconSlotGlyph(action.slot ?? 'apps')\n const BrandGlyph = action.slot ? resolveBrandGlyph(glyphName) : null\n const Glyph = BrandGlyph ?? Icon\n\n const content = (\n <>\n <Glyph size={TOPBAR_GLYPH_SIZE} className=\"text-current\" />\n {typeof action.badge === 'number' && action.badge > 0 ? (\n <span className=\"absolute -top-[5px] -right-[5px] flex h-4 min-w-4 items-center justify-center rounded-full bg-[color:var(--chrome-danger,var(--color-accent))] px-1 text-[10px] font-bold leading-4 text-[#FFFFFF]\">\n {action.badge}\n </span>\n ) : null}\n <TopBarTooltip title={action.label} description={action.description} />\n </>\n )\n\n const isExternal = action.href ? /^https?:\\/\\//.test(action.href) : false\n\n if (action.href) {\n return (\n <a\n href={safeHref(action.href)}\n aria-label={action.label}\n className={className}\n {...(isExternal ? { target: '_blank', rel: 'noreferrer' } : {})}\n >\n {content}\n </a>\n )\n }\n\n return (\n <button\n type=\"button\"\n onClick={action.onClick}\n aria-label={action.label}\n className={className}\n >\n {content}\n </button>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Page tab strip — THE canonical page tab strip (shell 0.69.0).\n//\n// Brand guideline \"Tabs are an underlined strip\" (components-tabs-geometry):\n// a row of text tabs, each with an optional mono count pill, above a 1px G3\n// rule, with no folder or card chrome. Tabs are 13px semibold with 12px\n// vertical padding (12px / 8px when small). The selected tab is Graphite with\n// a 2px underline in the MODE COLOR (`modes.<mode>.primary`), read as\n// `--mode-accent` — never `modes.<mode>.accent`, which is white and only for\n// highlights on the dark rail. Unselected tabs are G4 and turn Graphite on\n// hover.\n//\n// It sits in the page body, below the page header, aligned to the content\n// gutter (Brand guideline \"UX Navigation\"). Apps render it inside the frame's\n// `children`; they never hand-roll or restyle a tab strip.\n//\n// Why this one and not the main entry's `HeaderTabBar` (now @deprecated): it\n// has no Chakra or react-router dependency, so every app can import it\n// whatever its framework; it renders `href` tabs through the app's own link\n// primitive, so sub-views are URL-addressable; and it already carries the\n// tablist / tab / disabled semantics. `HeaderTabBar` is icon-only by\n// construction (its label is only a tooltip) and state-only (no links).\n//\n// Colors come from the Brand `--tab-*` / `--color-*` vars emitted by\n// `/api/tokens?format=css`, with literal fallbacks so the strip still renders\n// before the runtime token sheet loads.\n// ---------------------------------------------------------------------------\n\nexport type NavTab = {\n /** Stable identity (used as the React key). */\n key: string\n /** The tab's visible text. */\n label: string\n /**\n * A Lucide icon rendered 6px left of the label (Reference/UI-Platform →\n * Tabs, decided 2026-10-06: \"Icon + label. Each tab is a Lucide icon.\"),\n * 15px / 1.75 stroke (13px on a small strip), following the label's\n * selected / unselected / hover color via `currentColor`. Icon-ONLY tabs\n * (no label) are retired — this always pairs with `label`.\n */\n icon?: NavIcon\n /** Optional count, drawn as a mono pill after the label. */\n count?: string | number | null\n /** Route to link to (rendered through `linkComponent`). */\n href?: string\n /** Click handler — rendered as a `<button>` when there's no `href`. */\n onSelect?: () => void\n /** Whether this tab is the active one (drives the mode-color underline). */\n selected?: boolean\n /**\n * Non-interactive, dimmed tab (e.g. Surveys' Canvas/Results before a survey\n * is chosen). Renders a non-navigating span; `disabledTitle` is the tooltip\n * explaining why.\n */\n disabled?: boolean\n disabledTitle?: string\n}\n\nexport type NavTabStripProps = {\n tabs: NavTab[]\n /** Accessible name for the tablist. */\n 'aria-label'?: string\n /** Routing primitive for `href` tabs (Next `<Link>`, etc). Defaults to <a>. */\n linkComponent?: NavLinkComponent\n /** `'sm'`: 12px text with 8px vertical padding. Default `'md'` (13px / 12px). */\n size?: 'md' | 'sm'\n /** Extra classes on the tablist container. */\n className?: string\n /**\n * Optional tab panel rendered directly below the strip, on the page\n * surface with no card chrome. Omit to render only the strip and compose\n * the page body yourself.\n */\n children?: ReactNode\n}\n\n/** The mode color on light surfaces (Reference/UI-Platform → Per-mode branding). */\nconst TAB_UNDERLINE_COLOR = 'var(--mode-accent, var(--color-accent))'\n\nfunction NavTabButton({\n tab,\n Link,\n size,\n}: {\n tab: NavTab\n Link: NavLinkComponent\n size: 'md' | 'sm'\n}) {\n const { label, icon: Icon, count, href, onSelect, selected, disabled, disabledTitle } = tab\n\n // The 2px underline sits on the strip's 1px rule (`-mb-px`), so the selected\n // tab's underline replaces the rule beneath it rather than stacking on it.\n // Color/border/text-align are set inline, not via arbitrary-bracket Tailwind\n // classes (`text-[color:var(...)]`) — a style-diff against design (Specs,\n // 2026-10-09, phonebank-dashboard-desktop) found a live color/border/align\n // mismatch, and a consuming app's Tailwind content scan not catching a\n // bracketed `var()`-with-fallback utility is a known failure mode for this\n // pattern (see UI-Platform `@source` contract). Inline styles can't be\n // dropped by a content scanner.\n const base = '-mb-px inline-flex shrink-0 items-center gap-2 font-semibold leading-none transition-colors'\n const sizeClass = size === 'sm' ? 'py-2 text-[12px]' : 'py-3 text-[13px]'\n const stateClass = disabled ? 'cursor-not-allowed opacity-50' : 'hover:text-[color:var(--tab-hover-color,#2F3136)]'\n const className = `${base} ${sizeClass} ${stateClass}`\n // Unselected/disabled tab text used --color-g4 (#929599), the Brand\n // content-neutral gray — correct for body copy but only 2.58-2.76:1 against\n // the tab strip's light surfaces, failing WCAG AA (4.5:1 minimum, axe scan\n // 2026-10-09, 26 violations). --tab-text-muted is a dedicated nav-tab token\n // (not a --color-g4 edit, which stays as-is for the rest of the Brand ramp)\n // defaulting to --muted (#5C6B80), already measured at 5.42:1 on the light\n // rail and ~4.8:1+ on the tab-row surfaces — same muted blue-gray family,\n // just dark enough to clear AA.\n const color = disabled\n ? 'var(--tab-text-muted,#5C6B80)'\n : selected\n ? 'var(--tab-selected-color,#2F3136)'\n : 'var(--tab-text-muted,#5C6B80)'\n // Design has NO border on an unselected tab (border-width/style 0/none),\n // not a 2px transparent one — a transparent-color border still reports a\n // non-zero width/solid style to a computed-style diff (Specs style_diff,\n // 2026-10-09, email-builder-desktop). Only the selected tab gets the 2px\n // underline.\n const style: CSSProperties =\n selected && !disabled\n ? {\n textAlign: 'center',\n borderBottomWidth: 2,\n borderBottomStyle: 'solid',\n borderBottomColor: TAB_UNDERLINE_COLOR,\n color,\n }\n : {\n textAlign: 'center',\n borderBottomWidth: 0,\n borderBottomStyle: 'none',\n borderBottomColor: 'transparent',\n color,\n }\n\n const iconSize = size === 'sm' ? 13 : 15\n const content = (\n <>\n {Icon ? (\n <Icon size={iconSize} className=\"shrink-0 text-current\" strokeWidth={1.75} />\n ) : null}\n <span>{label}</span>\n {count !== undefined && count !== null && count !== '' ? (\n <span className=\"rounded-full bg-[color:var(--color-g2,#ECEEEF)] px-1.5 py-0.5 font-[family-name:var(--font-mono,ui-monospace,monospace)] text-[11px] font-semibold leading-none\">\n {count}\n </span>\n ) : null}\n </>\n )\n\n // Disabled: non-navigating span, still exposed as a tab for AT.\n if (disabled) {\n return (\n <span\n role=\"tab\"\n aria-selected={false}\n aria-disabled=\"true\"\n aria-label={label}\n title={disabledTitle}\n className={className}\n style={style}\n >\n {content}\n </span>\n )\n }\n\n if (href) {\n return (\n <Link\n href={href}\n role=\"tab\"\n aria-selected={selected ? true : false}\n aria-label={label}\n className={className}\n style={style}\n >\n {content}\n </Link>\n )\n }\n\n return (\n <button\n type=\"button\"\n role=\"tab\"\n aria-selected={selected ? true : false}\n aria-label={label}\n onClick={onSelect}\n className={className}\n style={style}\n >\n {content}\n </button>\n )\n}\n\n/**\n * The canonical page tab strip: underlined text tabs on a 1px rule. Render it\n * in the page body below the page header; pass the app's `Link` as\n * `linkComponent` for `href` tabs.\n */\nexport function NavTabStrip({\n tabs,\n 'aria-label': ariaLabel,\n linkComponent,\n size = 'md',\n className,\n children,\n}: NavTabStripProps) {\n const Link = linkComponent ?? DefaultLink\n return (\n <>\n <div\n role=\"tablist\"\n aria-label={ariaLabel}\n className={[\n // 26px, not 24px: a style_diff against design (email-builder-desktop,\n // 2026-10-09) measured the rendered row gap 4px short of spec (48 vs\n // 52) at the 24px default.\n 'flex items-end gap-[var(--tab-gap,26px)] border-b border-[color:var(--tab-border-color,#D7DADF)]',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n {tabs.map((tab) => (\n <NavTabButton key={tab.key} tab={tab} Link={Link} size={size} />\n ))}\n </div>\n {children !== undefined ? <div className=\"pt-5\">{children}</div> : null}\n </>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Beta banner — a full-width amber NOTICE strip rendered directly below the top\n// bar (a semantic notice, not a chrome surface, so it keeps its amber hue in\n// both themes via the --beta-banner-* tokens in chrome.css). One line, centered,\n// with a bold + underlined link to the Beta Terms & Conditions.\n// ---------------------------------------------------------------------------\n\nconst BETA_BANNER_DEFAULTS = {\n text: 'Our product is in Beta. Thank you for participating in the Pilot Program. ',\n linkLabel: 'You can click here to see the Terms & Conditions for Beta users.',\n href: 'https://app.politogyvrm.com/beta-terms-and-conditions',\n} as const\n\n/**\n * sessionStorage key holding the Beta-banner dismissal. sessionStorage — not\n * localStorage — so the dismissal lasts only for the browser session; and it is\n * additionally cleared on sign-out (see `clearBetaBannerDismissal`, called from\n * the chrome frame) so a fresh LOGIN always re-shows the notice.\n */\nexport const BETA_BANNER_DISMISS_KEY = 'politogy_beta_banner_dismissed'\n\n/**\n * Re-arm the Beta banner. The chrome frame calls this on sign-out so the notice\n * reappears at the next login rather than staying hidden across the boundary\n * (sessionStorage survives an in-tab logout→login round trip on its own).\n */\nexport function clearBetaBannerDismissal(): void {\n if (typeof window === 'undefined') return\n try {\n window.sessionStorage.removeItem(BETA_BANNER_DISMISS_KEY)\n } catch {\n /* storage unavailable (private mode / disabled) — nothing to clear */\n }\n}\n\nexport type NavBetaBannerProps = {\n /** Leading sentence(s) before the link. Defaults to the standard Beta copy. */\n text?: string\n /** Bold + underlined link label. Defaults to the standard Terms copy. */\n linkLabel?: string\n /** Terms & Conditions URL (opens in a new tab). Defaults to the app T&C page. */\n href?: string\n /**\n * Show a dismiss (×) button that hides the banner for the rest of the browser\n * session. Cleared on sign-out, so it returns at the next login. Default true.\n */\n dismissible?: boolean\n}\n\nexport function NavBetaBanner({ text, linkLabel, href, dismissible = true }: NavBetaBannerProps) {\n const body = text ?? BETA_BANNER_DEFAULTS.text\n const label = linkLabel ?? BETA_BANNER_DEFAULTS.linkLabel\n const target = href ?? BETA_BANNER_DEFAULTS.href\n\n // Start visible on both server and first client render (sessionStorage is not\n // readable during SSR), then hide in an effect if this session already\n // dismissed it — this keeps hydration markup identical and avoids a mismatch.\n const [dismissed, setDismissed] = useState(false)\n useEffect(() => {\n if (!dismissible) return\n try {\n if (window.sessionStorage.getItem(BETA_BANNER_DISMISS_KEY) === '1') setDismissed(true)\n } catch {\n /* storage unavailable — leave the banner visible */\n }\n }, [dismissible])\n\n if (dismissible && dismissed) return null\n\n const onDismiss = () => {\n setDismissed(true)\n try {\n window.sessionStorage.setItem(BETA_BANNER_DISMISS_KEY, '1')\n } catch {\n /* storage unavailable — banner still hides for this render */\n }\n }\n\n return (\n <div\n role=\"note\"\n className=\"relative w-full px-10 py-2 text-center text-sm\"\n style={{\n // Amber warning fill, matching the \"10DLC Registration Required\" notice\n // (HITL 2026-07-29). This used to fall through to `--color-accent`, the\n // brand RED, so a participation notice read as an error. The\n // --beta-banner-* tokens carry the amber defaults (chrome.css) and a\n // Brand edit still wins over them.\n background: 'var(--beta-banner-bg, #FEEBC8)',\n color: 'var(--beta-banner-text, #1A202C)',\n }}\n >\n <span>{body}</span>\n <a\n href={safeHref(target)}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-bold underline\"\n style={{ color: 'var(--beta-banner-text, #1A202C)' }}\n >\n {label}\n </a>\n {dismissible ? (\n <button\n type=\"button\"\n onClick={onDismiss}\n aria-label=\"Dismiss this notice\"\n title=\"Dismiss\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 flex h-6 w-6 items-center justify-center rounded text-base leading-none opacity-70 hover:opacity-100\"\n style={{ color: 'var(--beta-banner-text, #1A202C)' }}\n >\n ×\n </button>\n ) : null}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n\nexport type NavAppShellProps = {\n sidebar: NavSidebarProps\n topBar: NavTopBarProps\n /**\n * When supplied, a full-width Beta notice strip renders directly below the top\n * bar. Presence of the prop enables it; all fields fall back to the standard\n * Beta copy + Terms & Conditions link.\n */\n betaBanner?: NavBetaBannerProps\n /**\n * @deprecated The frame's content area is one fluid `<main>` (Brand\n * guideline \"Content width is fluid\"): the 24px gutter (16px below `md`),\n * no max-width and no centered container. Apps never emit their own page\n * container, so there is nothing left to choose here.\n *\n * `'bare'` is still honored — it renders `children` with no `<main>` and no\n * gutter — only so VRM core, which renders `NavAppShell` directly around\n * pages that still carry their own `PageContainer`, does not get a nested\n * `<main>` before it migrates. It warns in development and will be removed.\n * `'padded'` is now the same as omitting the prop.\n */\n contentWrapper?: 'padded' | 'bare'\n /**\n * The operating Mode this frame is scoped to, stamped on the root as\n * `data-politogy-mode` so the Brand API's per-Mode chrome tokens can target\n * it (Reference/UI-Platform → \"Per-mode branding — one accent per Mode\").\n *\n * This is app IDENTITY, not app configuration: `PolitogyAppFrame` passes it\n * from the `POLITOGY_APPS` registry, never from a prop an app supplies, so an\n * app still cannot choose its own chrome colour.\n *\n * Omitted (or a Mode that declares no chrome group in the Brand API) => every\n * accent falls back to the global one, exactly as before 0.47.\n */\n modeId?: string\n /**\n * Where the user card / account menu renders. `'sidebar'` (default since\n * 0.68.0) draws it in the left-bar footer and hides the top-bar trigger\n * (Reference/UI-Platform v30); `'topbar'` restores the 0.67 top-right badge.\n */\n accountMenuPlacement?: 'sidebar' | 'topbar'\n children: ReactNode\n}\n\n/**\n * Full chrome: branded left sidebar + sticky top navbar + scrollable content\n * region. Presentational only — wrap it in app-level auth/gating as needed.\n */\n/**\n * Closes any open chrome <details data-nav-details> (org switcher, mode\n * selector, My Account) when the pointer lands outside it or Escape is\n * pressed — dropdowns must deselect on outside click (HITL 2026-07-23).\n */\nfunction useCloseNavDetailsOnOutsideClick() {\n useEffect(() => {\n const close = (target: Node | null) => {\n document.querySelectorAll('details[data-nav-details][open]').forEach((d) => {\n if (!target || !d.contains(target)) d.removeAttribute('open')\n })\n }\n const onPointerDown = (e: MouseEvent) => close(e.target as Node)\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') close(null)\n }\n document.addEventListener('mousedown', onPointerDown)\n document.addEventListener('keydown', onKey)\n return () => {\n document.removeEventListener('mousedown', onPointerDown)\n document.removeEventListener('keydown', onKey)\n }\n }, [])\n}\n\nexport function NavAppShell({\n sidebar,\n topBar,\n betaBanner,\n contentWrapper = 'padded',\n accountMenuPlacement = 'sidebar',\n modeId,\n children,\n}: NavAppShellProps) {\n useCloseNavDetailsOnOutsideClick()\n if (contentWrapper === 'bare') {\n warnDeprecated(\n 'contentWrapper',\n \"`contentWrapper: 'bare'` is deprecated: the frame's <main> is fluid and apps must not emit their own page container. Remove the app's PageContainer and drop the prop.\",\n )\n }\n // Below `md` the rail is the 64px icon rail (see NavSidebar). The shell owns\n // the expanded-drawer state so the hamburger (NavTopBar) and the drawer\n // (NavSidebar) can stay presentational.\n const [navOpen, setNavOpen] = useState(false)\n const expandRail = () => {\n writeRailPreference('expanded')\n setNavOpen(true)\n }\n const collapseRail = () => {\n writeRailPreference('collapsed')\n setNavOpen(false)\n }\n // Route navigation closes the drawer — a stale open drawer over a new page\n // reads as broken, not as \"still browsing\".\n useEffect(() => {\n setNavOpen(false)\n }, [sidebar.pathname])\n // Left-Navigation §11.6: the expand choice is remembered per user. Read it\n // back after mount (no hydration mismatch); it only applies below `md`,\n // where the rail is collapsed. Explicit Expand / Collapse writes it.\n useEffect(() => {\n if (readRailPreference() !== 'expanded') return\n const narrow =\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia('(max-width: 767.98px)').matches\n : false\n if (narrow) setNavOpen(true)\n }, [])\n // The page behind a mobile drawer must not scroll while it's open.\n useEffect(() => {\n if (!navOpen) return\n const previous = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n return () => {\n document.body.style.overflow = previous\n }\n }, [navOpen])\n // The user card lives in the left-bar footer (UI-Platform v30). Lift the\n // top bar's user / menu / sign-out into the sidebar footer unless the app\n // already supplied them there or opted back into the top-bar badge.\n const sidebarFooter: NavFooter | null | undefined =\n accountMenuPlacement === 'sidebar' && topBar.user\n ? {\n ...(sidebar.footer ?? {}),\n user: sidebar.footer?.user ?? topBar.user,\n userMenu: sidebar.footer?.userMenu ?? topBar.userMenu,\n onSignOut: sidebar.footer?.onSignOut ?? topBar.onSignOut,\n }\n : sidebar.footer\n return (\n <div\n data-politogy-mode={modeId ?? modeIdFromLabel(sidebar.mode?.label)}\n className=\"min-h-screen bg-[color:var(--background)] text-[color:var(--foreground)]\"\n >\n {/* Cross-app sidebar nav speculation: every consumer rendering\n NavAppShell gets this for free (no per-app opt-in) — see\n src/speculation/SpeculationRulesScript.tsx. */}\n <SpeculationRulesScript items={sidebar.nav.items} />\n <NavSidebar\n {...sidebar}\n footer={sidebarFooter}\n open={navOpen}\n onClose={collapseRail}\n onOpen={expandRail}\n onNavigate={() => setNavOpen(false)}\n />\n {/* The rail is never hidden, so content is always offset by it: 64px\n below `md`, the full rail from `md` up. */}\n <div className=\"pl-[var(--sidebar-collapsed-width,64px)] md:pl-[var(--sidebar-width,236px)]\">\n <NavTopBar\n {...topBar}\n accountMenu={topBar.accountMenu ?? (accountMenuPlacement === 'sidebar' ? 'sidebar' : 'topbar')}\n />\n {betaBanner ? <NavBetaBanner {...betaBanner} /> : null}\n {/* Reference/UI-Platform \"Page header\": the title lives in the page\n body now, 22px below the top bar, not in the bar itself and never\n as a breadcrumb trail. Rendered here — above both wrapper modes —\n so a 'bare' app (which owns its own content furniture) still gets\n the required chrome-owned title line. */}\n {topBar.title ? (\n <h1 className=\"px-4 pt-7 text-xl font-semibold text-[color:var(--foreground)] md:px-6\">\n {topBar.title}\n </h1>\n ) : null}\n {contentWrapper === 'bare' ? (\n <div data-shell-content=\"\" className={topBar.title ? 'mt-[22px]' : undefined}>\n {children}\n </div>\n ) : (\n // Brand guidelines \"Content width is fluid\" + \"Content body\n // padding\": `<main>` fills the space beside the rail with ONE\n // gutter — 24px, or 16px below `md`, horizontally and vertically —\n // and has no max-width and no centered container. Form and settings\n // pages constrain themselves with <FormColumn> (960px, left-aligned).\n // The shell owns the page background and the gutter; an app's own\n // cards are its own furniture and stay app-owned.\n <main\n data-shell-content=\"\"\n className={`min-h-[calc(100vh-63px)] bg-[color:var(--chrome-page-bg,#F4F5F7)] px-4 pb-4 md:px-6 md:pb-6 ${topBar.title ? 'pt-[22px]' : 'pt-4 md:pt-6'}`}\n >\n {children}\n </main>\n )}\n </div>\n </div>\n )\n}\n\n// The one constrained layout inside the fluid <main>: a 960px left-aligned\n// column for form and settings pages. Re-exported here (as well as from the\n// main entry) so an app needs no Chakra / react-router peer to use it.\nexport { default as FormColumn } from '../components/FormColumn'\n\n// Canonical Politogy VRM menu — the standard nav structure every politogy app\n// renders, per operating Mode, with hooks for the app-owned \"Contacts\" item and\n// Support handler, plus the Campaign feature-availability config.\nexport {\n standardPolitogyNav,\n CAMPAIGN_FEATURE_AVAILABILITY,\n type StandardNavIconKey,\n type StandardNavOptions,\n type StandardNavMode,\n type CampaignFeatureAvailability,\n} from './standardNav'\n","// Breadcrumb derivation — pure, dependency-free logic (no React, no DevNotes),\n// so it is importable from a server module and testable in isolation.\n//\n// The standard is Dashboard > Sub > Item (HITL 2026-07-23), derived from the\n// same nav tree the sidebar renders. Apps previously hand-built their own\n// trails and disagreed: forms rendered \"Forms > Dashboard\" while polls rendered\n// a lone \"Polls\" crumb under a \"Polls\" title (\"Polls / Polls\").\n\nimport type { NavBreadcrumb, NavItem } from '../native/index'\n\nexport function deriveBreadcrumbs(\n items: NavItem[],\n pathname: string,\n opts?: { search?: string; origin?: string },\n): NavBreadcrumb[] {\n const search = opts?.search ?? (typeof window !== 'undefined' ? window.location.search : '')\n const origin = opts?.origin ?? (typeof window !== 'undefined' ? window.location.origin : '')\n\n // Same-origin comparison: cross-app hrefs are absolute, local ones relative.\n const matches = (href?: string): boolean => {\n if (!href) return false\n let path = href\n let query = ''\n if (/^https?:\\/\\//i.test(href)) {\n try {\n const u = new URL(href)\n if (origin && u.origin !== origin) return false\n path = u.pathname\n query = u.search\n } catch {\n return false\n }\n } else {\n const qi = href.indexOf('?')\n if (qi >= 0) {\n path = href.slice(0, qi) || '/'\n query = href.slice(qi)\n }\n }\n if (path !== pathname) return false\n if (!query) return true\n const want = new URLSearchParams(query)\n const have = new URLSearchParams(search)\n for (const [k, v] of want) if (have.get(k) !== v) return false\n return true\n }\n\n // Depth-first walk for the deepest item owning the current route.\n const walk = (nodes: NavItem[], trail: NavItem[]): NavItem[] | null => {\n for (const node of nodes) {\n const here = [...trail, node]\n if (node.children?.length) {\n const deeper = walk(node.children, here)\n if (deeper) return deeper\n }\n if (matches(node.href)) return here\n }\n return null\n }\n\n const trail = walk(items, [])\n // Always anchored at Dashboard; the last crumb is the current location and\n // carries no href (the shell marks it aria-current=\"page\").\n const dashboard = items.find((i) => i.label === 'Dashboard')\n const crumbs: NavBreadcrumb[] = [{ label: 'Dashboard', href: dashboard?.href }]\n if (!trail) return crumbs\n for (const node of trail) {\n if (node.label === 'Dashboard') continue\n crumbs.push({ label: node.label, href: node.href })\n }\n const last = crumbs[crumbs.length - 1]\n if (last) delete (last as { href?: string }).href\n return crumbs\n}\n","// Identity resolution — pure logic, shared by the chrome hook.\n//\n// The chrome API (VRM-core profile) is the AUTHORITY for a user's display name;\n// what an app knows from its own session token is a pre-hydration fallback. An\n// email is never a name: forms passed `user.name ?? user.email`, so a user with\n// no name set had their email rendered as their name in the top bar and the\n// shell's \"add your name\" affordance never fired (HITL 2026-07-23).\n\nexport type ResolvedIdentity = {\n userName: string | null\n email: string | null\n avatarUrl: string | null\n loaded: boolean\n}\n\n/** True when a \"name\" is really just an email address. */\nexport function looksLikeEmail(value: string | null | undefined): boolean {\n return typeof value === 'string' && /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value.trim())\n}\n\nexport function resolveIdentity(input: {\n apiName?: string | null\n fallbackName?: string | null\n email?: string | null\n avatarUrl?: string | null\n loaded?: boolean\n}): ResolvedIdentity {\n const apiName = looksLikeEmail(input.apiName) ? null : input.apiName ?? null\n const fallbackName = looksLikeEmail(input.fallbackName) ? null : input.fallbackName ?? null\n return {\n userName: apiName ?? fallbackName,\n email: input.email ?? null,\n avatarUrl: input.avatarUrl ?? null,\n loaded: input.loaded ?? false,\n }\n}\n","// Universal sign-out propagation — the ONE cross-app logout contract.\n//\n// Every Politogy app holds its OWN host-only session cookie with a long sliding\n// window, so signing out of one app used to leave every other open tab — and\n// every other subdomain — signed in until its cookie happened to expire. A user\n// who signs out in Contacts and switches to the Forms tab they already had open\n// is still fully authenticated there. That is the bug this module closes.\n//\n// The vehicle mirrors the active-org contract: a `.politogyvrm.com` cookie that\n// every subdomain can read. It carries a single monotonic value — the epoch\n// milliseconds at which the user signed out.\n//\n// politogy_logout_at = <epoch ms of the most recent sign-out>\n//\n// Two layers cooperate, and BOTH are required:\n//\n// 1. SERVER (authoritative). Each app's middleware compares this cookie\n// against the session's `auth_time`. A session minted BEFORE the last\n// sign-out is dead, whatever its own expiry says — so a reload, a\n// bookmark, or a restored tab can never resurrect it. See\n// `isSessionRevoked`.\n//\n// 2. CLIENT (immediacy). Open tabs are not making requests, so the server\n// layer alone only takes effect on their next navigation. `watchLogout`\n// notices the cookie change within ~1s and navigates the tab out.\n//\n// The cookie is deliberately NOT HttpOnly: it holds no secret — just a\n// timestamp — and every tab on every subdomain must be able to read it from\n// JavaScript. It grants nothing; it only ever revokes.\n//\n// Server-safe (no 'use client'): the constants and `isSessionRevoked` are\n// importable from middleware and server components; the browser helpers no-op\n// on the server.\n\nexport const LOGOUT_COOKIE = 'politogy_logout_at'\n\n/** Same-origin instant channel; cross-subdomain falls back to the cookie poll. */\nconst LOGOUT_CHANNEL = 'politogy-logout'\n\n/** How often a tab re-reads the cookie. Cheap: a string compare, no I/O. */\nconst POLL_MS = 1000\n\nfunction parseTimestamp(value: string | null | undefined): number | null {\n if (!value) return null\n const n = Number(value)\n return Number.isFinite(n) && n > 0 ? n : null\n}\n\n/**\n * Server-side authority. Given the logout-cookie value and the moment this\n * session was authenticated, is the session revoked?\n *\n * `authTime` is the OIDC `auth_time` (seconds) or an equivalent millisecond\n * timestamp captured when the session was minted. Sessions with no recorded\n * auth time are treated as revoked whenever a logout is on record: we cannot\n * prove they postdate it, and failing closed is the only safe direction for a\n * sign-out.\n */\nexport function isSessionRevoked(\n logoutCookieValue: string | null | undefined,\n authTime: number | null | undefined,\n): boolean {\n const loggedOutAt = parseTimestamp(logoutCookieValue)\n if (loggedOutAt === null) return false\n if (authTime == null || !Number.isFinite(authTime) || authTime <= 0) return true\n // Accept either seconds (OIDC auth_time) or milliseconds.\n const authMs = authTime < 1e12 ? authTime * 1000 : authTime\n return authMs < loggedOutAt\n}\n\n/** Read the shared logout timestamp (browser only; null on server or unset). */\nexport function readLogoutCookie(): number | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(new RegExp(`(?:^|;\\\\s*)${LOGOUT_COOKIE}=([^;]+)`))\n return parseTimestamp(m ? decodeURIComponent(m[1]) : null)\n } catch {\n return null\n }\n}\n\n/**\n * Record a sign-out for every tab on every Politogy subdomain. Call this\n * BEFORE navigating to the app's sign-out route, so tabs that are already open\n * see it immediately rather than after the round trip.\n *\n * Scoping mirrors the active-org and theme cookies: parent-domain on\n * *.politogyvrm.com so all app subdomains read it, host-only anywhere else\n * (localhost, *.pages.dev previews).\n */\nexport function broadcastLogout(at: number = Date.now()): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n // 30 days: comfortably longer than the longest app session window, so a tab\n // resumed from sleep still sees the revocation. Shorter than that and a stale\n // session could outlive the signal that killed it.\n document.cookie = `${LOGOUT_COOKIE}=${at}; Path=/; Max-Age=2592000; SameSite=Lax${domainAttr}${secure}`\n try {\n new BroadcastChannel(LOGOUT_CHANNEL).postMessage(at)\n } catch {\n // No BroadcastChannel (older Safari) — the cookie poll covers it.\n }\n}\n\n/**\n * Clear the signal. Call after a successful LOGIN: the new session postdates\n * the old sign-out, and leaving the cookie behind would make every future\n * `isSessionRevoked` check depend on clock skew between the two.\n */\nexport function clearLogoutSignal(): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n document.cookie = `${LOGOUT_COOKIE}=; Path=/; Max-Age=0; SameSite=Lax${domainAttr}`\n}\n\nexport type WatchLogoutOptions = {\n /**\n * Sessions minted at or before this moment are revoked by a sign-out. Pass\n * the session's auth time; when omitted, ANY logout signal observed after the\n * watcher starts fires the callback (correct for an already-open tab, which\n * by definition authenticated earlier).\n */\n authTime?: number | null\n /** Poll interval override, for tests. */\n intervalMs?: number\n}\n\n/**\n * Watch for a sign-out that happened in ANY other tab or window, on this or any\n * sibling Politogy subdomain, and invoke `onLogout` once.\n *\n * Returns an unsubscribe function.\n *\n * Three signals, cheapest first:\n * - BroadcastChannel — instant, same-origin only.\n * - visibility/focus/pageshow — the moment a backgrounded tab is looked at.\n * - a ~1s cookie poll — the cross-subdomain path, and the backstop for a\n * visible tab the user is staring at but not interacting with.\n */\nexport function watchLogout(\n onLogout: () => void,\n options: WatchLogoutOptions = {},\n): () => void {\n if (typeof document === 'undefined' || typeof window === 'undefined') {\n return () => {}\n }\n\n const { authTime = null, intervalMs = POLL_MS } = options\n // Anything already on record when this tab started is not news: the server\n // layer decides whether THIS session is revoked, and it has already let the\n // page render. Only a signal newer than our baseline means \"someone just\n // signed out\".\n const baseline = readLogoutCookie() ?? 0\n let done = false\n\n const fire = (at: number) => {\n if (done) return\n if (at <= baseline) return\n if (authTime != null && !isSessionRevoked(String(at), authTime)) return\n done = true\n cleanup()\n onLogout()\n }\n\n const check = () => {\n const at = readLogoutCookie()\n if (at !== null) fire(at)\n }\n\n let channel: BroadcastChannel | null = null\n try {\n channel = new BroadcastChannel(LOGOUT_CHANNEL)\n channel.onmessage = (event) => {\n const at = typeof event.data === 'number' ? event.data : readLogoutCookie()\n if (at !== null) fire(at)\n }\n } catch {\n channel = null\n }\n\n const timer = window.setInterval(check, intervalMs)\n window.addEventListener('visibilitychange', check)\n window.addEventListener('focus', check)\n window.addEventListener('pageshow', check)\n\n function cleanup() {\n window.clearInterval(timer)\n window.removeEventListener('visibilitychange', check)\n window.removeEventListener('focus', check)\n window.removeEventListener('pageshow', check)\n try {\n channel?.close()\n } catch {\n /* already closed */\n }\n }\n\n return cleanup\n}\n","// Active-mode continuity — the cross-app \"which mode am I in\" contract.\n//\n// A DUAL-MODE app (today: a2p, Specs/A2P — \"the SMS/MMS delivery engine for\n// Relationship Mode and Campaign Mode\") has no single registry `mode`: its\n// nav tree and Mode pill must follow the user's LAST-SELECTED mode instead of\n// a fixed value. The resolution order, cheapest/most-explicit first:\n// 1. `?mode=` query param on the current URL (an explicit cross-app link,\n// e.g. the Relationship tree's SMS/MMS Blast row linking into a2p).\n// 2. `politogy_active_mode` cookie — the same cross-subdomain pattern as\n// `politogy_theme` / `politogy_active_org` (see theme-preference.ts):\n// `.politogyvrm.com` on a *.politogyvrm.com host, host-only elsewhere.\n// 3. The dual app's own configured default mode.\n//\n// Every PINNED app (one with a fixed `meta.mode`, e.g. petitions/email) and\n// core (`vrm`, whose mode switches client-side) write this cookie whenever\n// their resolved mode is known/changes, so arriving at a dual app later\n// resolves to whatever mode the user was last actually in.\n\nimport type { StandardNavMode } from './native/standardNav'\n\nexport const ACTIVE_MODE_COOKIE = 'politogy_active_mode'\n\nconst VALID_MODES: readonly StandardNavMode[] = ['relationship', 'campaign', 'petition']\n\nexport function isStandardNavMode(v: unknown): v is StandardNavMode {\n return typeof v === 'string' && (VALID_MODES as readonly string[]).includes(v)\n}\n\n/** Read the shared cookie (browser only; null on the server or when unset). */\nexport function readActiveModeCookie(): StandardNavMode | null {\n if (typeof document === 'undefined') return null\n try {\n const m = document.cookie.match(\n new RegExp(`(?:^|;\\\\s*)${ACTIVE_MODE_COOKIE}=([^;]+)`),\n )\n const v = m ? decodeURIComponent(m[1]) : null\n return isStandardNavMode(v) ? v : null\n } catch {\n return null\n }\n}\n\n/**\n * Write the cross-subdomain cookie with the same scoping rules as the theme\n * cookie (parent domain on *.politogyvrm.com, host-only elsewhere). 1-year,\n * SameSite=Lax, Secure on https. No-op on the server.\n */\nexport function writeActiveModeCookie(mode: StandardNavMode): void {\n if (typeof document === 'undefined' || typeof window === 'undefined') return\n const host = window.location.hostname\n const domainAttr = /(^|\\.)politogyvrm\\.com$/i.test(host) ? '; Domain=.politogyvrm.com' : ''\n const secure = window.location.protocol === 'https:' ? '; Secure' : ''\n document.cookie = `${ACTIVE_MODE_COOKIE}=${encodeURIComponent(\n mode,\n )}; Path=/; Max-Age=31536000; SameSite=Lax${domainAttr}${secure}`\n}\n\n/** Read `?mode=` from a query string (`search`, with or without a leading `?`). */\nfunction modeFromSearch(search: string | undefined): string | null {\n if (!search) return null\n try {\n const params = new URLSearchParams(search.startsWith('?') ? search.slice(1) : search)\n return params.get('mode')\n } catch {\n return null\n }\n}\n\n/**\n * Resolve a dual-mode app's effective mode: `?mode=` query param (must be one\n * of `modes`) → `politogy_active_mode` cookie (must be one of `modes`) →\n * `defaultMode`. Client-side only; on the server (or when nothing resolves)\n * this simply falls through to `defaultMode`.\n */\nexport function resolveActiveMode({\n search,\n modes,\n defaultMode,\n}: {\n search?: string\n modes: readonly StandardNavMode[]\n defaultMode: StandardNavMode\n}): StandardNavMode {\n const fromQuery = modeFromSearch(search)\n if (fromQuery && isStandardNavMode(fromQuery) && modes.includes(fromQuery)) {\n return fromQuery\n }\n const fromCookie = readActiveModeCookie()\n if (fromCookie && modes.includes(fromCookie)) {\n return fromCookie\n }\n return defaultMode\n}\n","// ---------------------------------------------------------------------------\n// LoadingScreen — the platform's boot handshake (Specs/Loading-Screen).\n//\n// Mounted once by PolitogyAppFrame (see frame.tsx), never hand-rolled per app\n// (Global-Rules \"Boot Screen Exception\": one screen, one owner). It renders on\n// the four triggers that replace the account context wholesale — cold start,\n// hard reload, organization switch, mode switch — and never for an in-page\n// fetch or plain navigation, which stay on scoped skeletons.\n//\n// Progress is a REPORT, not an animation (spec §4): determinate, monotonic,\n// weighted across boot stages. An app that has real pipeline signals passes\n// `bootProgress`; an app that does not (V1: every consumer but core's own\n// pipeline work is still to come) gets a synthetic two-stage report driven by\n// the same chrome-state signal FrameBody already computes (org list resolved),\n// so the screen still tells the truth — it just has fewer stages to report —\n// and no consumer app can regress to a spinner or a hand-rolled splash.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport { useEffect, useMemo, useRef, useState } from 'react'\n\n/** One stage in the boot pipeline (spec §7). */\nexport type BootStageId =\n | 's0_session'\n | 's1_org'\n | 's2_uvp_connect'\n | 's3_district'\n | 's4_universe'\n | 's5_layers'\n | 's6_verified'\n | 's7_tribes'\n | 's8_intelligence'\n | 's9_shell'\n\nexport type BootPhase = 'booting' | 'slow' | 'error' | 'done'\n\n/**\n * The boot pipeline weight table (spec §7). Stages run in catalog order;\n * weights sum to 100 for a full cold boot. \"Waits on\" documents the real\n * signal a caller must have before it may claim the stage is progressing or\n * complete — the status line may not claim a stage the client isn't actually\n * waiting on.\n */\nexport const BOOT_STAGE_TABLE: readonly {\n id: BootStageId\n weight: number\n critical: boolean\n waitsOn: string\n}[] = [\n { id: 's0_session', weight: 5, critical: true, waitsOn: 'Politogy ID session resolution' },\n { id: 's1_org', weight: 10, critical: true, waitsOn: 'Chrome API /api/chrome/me + orgs' },\n { id: 's2_uvp_connect', weight: 10, critical: true, waitsOn: 'UVP data layer connection' },\n { id: 's3_district', weight: 5, critical: true, waitsOn: 'uvp_geo_entitlements / uvp_boundaries scope' },\n { id: 's4_universe', weight: 25, critical: true, waitsOn: 'UVP universe load + total count' },\n { id: 's5_layers', weight: 15, critical: false, waitsOn: 'UVP enrichment layer joins' },\n { id: 's6_verified', weight: 10, critical: false, waitsOn: 'VRM Verified tier computation' },\n { id: 's7_tribes', weight: 10, critical: false, waitsOn: 'Tribes member_count + Hot Tribes warm-up' },\n { id: 's8_intelligence', weight: 5, critical: false, waitsOn: 'Mode intelligence signals (Polling/Relationship/Petition)' },\n { id: 's9_shell', weight: 5, critical: true, waitsOn: 'Shell paint-ready handoff' },\n]\n\nconst BOOT_STAGE_ORDER: readonly BootStageId[] = BOOT_STAGE_TABLE.map((s) => s.id)\nconst BOOT_STAGE_WEIGHTS: Record<BootStageId, number> = Object.fromEntries(\n BOOT_STAGE_TABLE.map((s) => [s.id, s.weight]),\n) as Record<BootStageId, number>\n\n/**\n * Weighted, monotonic, redistributing progress (spec §4.1 principles 3 & 5).\n * `completedStageIds` are fully done (their full weight counts); `skippedStageIds`\n * don't apply to this account/mode and have their weight redistributed\n * proportionally across the stages that DO apply; `currentStageId` is in\n * flight and contributes `currentStageProgress` (0–1) of its own weight.\n * Pure function — no fake motion, no timers.\n */\nexport function computeWeightedPct(args: {\n completedStageIds: readonly BootStageId[]\n skippedStageIds?: readonly BootStageId[]\n currentStageId?: BootStageId\n currentStageProgress?: number\n}): number {\n const skipped = new Set(args.skippedStageIds ?? [])\n const applicable = BOOT_STAGE_ORDER.filter((id) => !skipped.has(id))\n const applicableWeightTotal = applicable.reduce((sum, id) => sum + BOOT_STAGE_WEIGHTS[id], 0)\n if (applicableWeightTotal <= 0) return 100\n // Redistribute each skipped stage's weight proportionally across the\n // remaining applicable stages so the bar still ends at 100.\n const redistributionFactor = 100 / applicableWeightTotal\n\n const completed = new Set(args.completedStageIds)\n let pct = 0\n for (const id of applicable) {\n const effectiveWeight = BOOT_STAGE_WEIGHTS[id] * redistributionFactor\n if (completed.has(id)) {\n pct += effectiveWeight\n } else if (id === args.currentStageId) {\n const progress = Math.min(1, Math.max(0, args.currentStageProgress ?? 0))\n pct += effectiveWeight * progress\n }\n }\n return Math.min(100, pct)\n}\n\n/**\n * The progress-reporting contract (spec §14, Shell package integration\n * point). An app with a real pipeline drives this; the shape is intentionally\n * small so a future per-app pipeline can report into it without a shell\n * release.\n */\nexport type BootProgress = {\n stageId: BootStageId\n /**\n * 0–100, real, monotonic. Callers that already know the weighted value\n * (e.g. by calling `computeWeightedPct` themselves) pass it directly here;\n * callers that only know stage completion/skip state may omit `pct` and\n * pass `completedStageIds`/`skippedStageIds`/`currentStageProgress`\n * instead, and the screen computes the weighted value itself.\n */\n pct?: number\n /** Stages fully completed so far this boot (spec §7 weight table). */\n completedStageIds?: readonly BootStageId[]\n /** Stages that don't apply to this account/mode; their weight redistributes\n * proportionally across the remaining stages (spec §4.1 principle 5). */\n skippedStageIds?: readonly BootStageId[]\n /** 0–1 sub-stage progress within `stageId`, for stages that stream a real\n * counter (S4 universe records, S7 Tribes warmed) (spec §4.1 principle 4). */\n currentStageProgress?: number\n /** The account's own status line for this stage (spec §8; tokens already\n * filled, fallback already applied by the caller). */\n label: string\n phase: BootPhase\n /** Critical-stage failure: Retry / Sign out (spec §9.1). */\n onRetry?: () => void\n onSignOut?: () => void\n /** Footer (spec §6, §14 `version.ts` + deploy environment). */\n version?: string\n region?: string\n}\n\n/** Default synthetic pipeline used when no app supplies `bootProgress` yet.\n * UNCHANGED from the shipped V1 behavior — do not alter without a spec\n * amendment; consumers that haven't wired the real pipeline must keep seeing\n * exactly this. */\nconst SYNTHETIC_STAGES: readonly { pct: number; label: string }[] = [\n { pct: 20, label: 'Connecting to your organization…' },\n { pct: 100, label: 'Ready.' },\n]\n\n/** Spec §11: announcements throttled to one per 1.5s so a fast boot doesn't\n * read five lines at once; \"Ready.\" is always announced regardless. */\nconst ANNOUNCE_THROTTLE_MS = 1500\n/** Spec §4.1 principle 7: minimum dwell time per status line. */\nconst MIN_DWELL_MS = 450\n/** Spec §10: exit transition timings. */\nconst FILL_EASE_MS = 380\nconst HOLD_MS = 240\nconst FADE_MS = 300\n\nfunction usePrefersReducedMotion(): boolean {\n const [reduced, setReduced] = useState(false)\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return\n const mq = window.matchMedia('(prefers-reduced-motion: reduce)')\n setReduced(mq.matches)\n const onChange = () => setReduced(mq.matches)\n mq.addEventListener('change', onChange)\n return () => mq.removeEventListener('change', onChange)\n }, [])\n return reduced\n}\n\n/**\n * Announces `label` on an `aria-live=\"polite\"` cadence: never more than once\n * per ANNOUNCE_THROTTLE_MS, except the terminal \"Ready.\" line, which always\n * gets announced (spec §11).\n */\nfunction useThrottledAnnouncement(label: string, isFinal: boolean): string {\n const [announced, setAnnounced] = useState(label)\n const lastAtRef = useRef(0)\n useEffect(() => {\n const now = Date.now()\n if (isFinal || now - lastAtRef.current >= ANNOUNCE_THROTTLE_MS) {\n lastAtRef.current = now\n setAnnounced(label)\n return\n }\n const wait = ANNOUNCE_THROTTLE_MS - (now - lastAtRef.current)\n const t = setTimeout(() => {\n lastAtRef.current = Date.now()\n setAnnounced(label)\n }, wait)\n return () => clearTimeout(t)\n }, [label, isFinal])\n return announced\n}\n\n/**\n * Enforces the minimum-dwell floor on the DISPLAYED label only — the bar\n * itself is never delayed (spec §4.1 \"the copy is throttled; the bar is not\").\n */\nfunction useDwelledLabel(label: string): string {\n const [displayed, setDisplayed] = useState(label)\n const shownAtRef = useRef(0)\n const pendingRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n useEffect(() => {\n if (label === displayed) return\n const elapsed = Date.now() - shownAtRef.current\n if (pendingRef.current) clearTimeout(pendingRef.current)\n if (elapsed >= MIN_DWELL_MS) {\n shownAtRef.current = Date.now()\n setDisplayed(label)\n } else {\n pendingRef.current = setTimeout(() => {\n shownAtRef.current = Date.now()\n setDisplayed(label)\n }, MIN_DWELL_MS - elapsed)\n }\n return () => {\n if (pendingRef.current) clearTimeout(pendingRef.current)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [label])\n return displayed\n}\n\nexport type LoadingScreenProps = {\n /** Real pipeline progress, when the host app has one wired. */\n bootProgress?: BootProgress\n /**\n * Fallback completion signal used when `bootProgress` is absent: the\n * screen dismisses once this flips true. Callers pass the same \"org list\n * resolved\" signal FrameBody already computes, so a consumer that never\n * wires the full contract still gets a truthful (if coarse) boot report\n * instead of a spinner.\n */\n syntheticReady?: boolean\n /** True while the screen should be mounted at all (trigger gate lives in\n * frame.tsx; this component only renders its own exit transition). */\n visible: boolean\n /** Called after the fade-out completes and the DOM node should unmount. */\n onExitComplete: () => void\n}\n\nexport function LoadingScreen({\n bootProgress,\n syntheticReady,\n visible,\n onExitComplete,\n}: LoadingScreenProps) {\n const reducedMotion = usePrefersReducedMotion()\n\n const synthetic = useMemo(() => {\n const stage = syntheticReady ? SYNTHETIC_STAGES[1] : SYNTHETIC_STAGES[0]\n return {\n pct: stage.pct,\n label: stage.label,\n phase: (syntheticReady ? 'done' : 'booting') as BootPhase,\n }\n }, [syntheticReady])\n\n const weightedPct = useMemo(() => {\n if (!bootProgress) return undefined\n if (typeof bootProgress.pct === 'number') return bootProgress.pct\n if (!bootProgress.completedStageIds && !bootProgress.skippedStageIds) return undefined\n return computeWeightedPct({\n completedStageIds: bootProgress.completedStageIds ?? [],\n skippedStageIds: bootProgress.skippedStageIds,\n currentStageId: bootProgress.stageId,\n currentStageProgress: bootProgress.currentStageProgress,\n })\n }, [\n bootProgress,\n bootProgress?.pct,\n bootProgress?.completedStageIds,\n bootProgress?.skippedStageIds,\n bootProgress?.stageId,\n bootProgress?.currentStageProgress,\n ])\n\n const pct = weightedPct ?? synthetic.pct\n const rawLabel = bootProgress?.label ?? synthetic.label\n const phase = bootProgress?.phase ?? synthetic.phase\n const isFinal = phase === 'done' && pct >= 100\n\n // Monotonic clamp: a re-render can never show a lower value than the last\n // one painted, even if a caller's own state briefly regresses.\n const highWaterRef = useRef(0)\n const clampedPct = Math.max(pct, highWaterRef.current)\n useEffect(() => {\n highWaterRef.current = clampedPct\n }, [clampedPct])\n\n const displayedLabel = useDwelledLabel(rawLabel)\n const announced = useThrottledAnnouncement(displayedLabel, isFinal)\n\n // Exit transition: hold at 100 for HOLD_MS, then fade, then unmount.\n const [fading, setFading] = useState(false)\n useEffect(() => {\n if (!isFinal) return\n const holdMs = reducedMotion ? 0 : HOLD_MS\n const fadeMs = reducedMotion ? 0 : FADE_MS\n const holdTimer = setTimeout(() => {\n setFading(true)\n const fadeTimer = setTimeout(onExitComplete, fadeMs)\n return () => clearTimeout(fadeTimer)\n }, holdMs)\n return () => clearTimeout(holdTimer)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isFinal, reducedMotion])\n\n if (!visible) return null\n\n const isError = phase === 'error'\n\n return (\n <div\n data-testid=\"politogy-loading-screen\"\n style={{\n position: 'fixed',\n inset: 0,\n zIndex: 2147483000,\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '2rem',\n background: 'var(--color-ink-900, #0a0a0c)',\n color: '#fff',\n opacity: fading ? 0 : 1,\n transition: reducedMotion ? undefined : `opacity ${FADE_MS}ms ease-out`,\n }}\n >\n {/*\n Inline lockup, not an <img>: the screen mounts in every consumer app and\n none of them serves a shared asset at a fixed path, so an asset URL\n rendered as a broken image (the alt text) on every boot. Inline markup\n needs no network and cannot 404.\n */}\n <div\n aria-label=\"Politogy\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.6rem',\n fontFamily: \"var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)\",\n }}\n >\n <span\n aria-hidden=\"true\"\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 34,\n height: 26,\n borderRadius: 6,\n background: '#fff',\n color: 'var(--color-ink-900, #0a0a0c)',\n fontSize: '0.8125rem',\n fontWeight: 800,\n letterSpacing: '-0.02em',\n }}\n >\n vrm\n </span>\n <span style={{ fontSize: '1.375rem', fontWeight: 700, letterSpacing: '-0.02em' }}>Politogy</span>\n </div>\n <div style={{ width: 320, maxWidth: '80vw' }}>\n <div\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={Math.round(clampedPct)}\n aria-label=\"Loading your workspace\"\n style={{\n height: 3,\n width: '100%',\n borderRadius: 2,\n background: 'rgba(255,255,255,0.12)',\n overflow: 'hidden',\n }}\n >\n <div\n style={{\n height: '100%',\n width: `${clampedPct}%`,\n background:\n 'linear-gradient(90deg, var(--color-race-blue, #1d4ed8), var(--color-race-red, #dc2626))',\n transition: reducedMotion ? undefined : `width ${FILL_EASE_MS}ms ease-out`,\n }}\n />\n </div>\n <div\n role=\"status\"\n aria-live=\"polite\"\n style={{\n marginTop: '0.75rem',\n fontFamily: 'var(--font-mono, ui-monospace, monospace)',\n fontSize: '0.8125rem',\n color: isError ? 'var(--color-race-red, #dc2626)' : 'rgba(255,255,255,0.72)',\n textAlign: 'center',\n }}\n >\n {announced}\n </div>\n {isError && (bootProgress?.onRetry || bootProgress?.onSignOut) && (\n <div\n style={{\n marginTop: '1.25rem',\n display: 'flex',\n flexDirection: 'column',\n gap: '0.75rem',\n alignItems: 'center',\n }}\n >\n {bootProgress?.onRetry && (\n <button\n type=\"button\"\n onClick={bootProgress.onRetry}\n style={{\n height: 40,\n padding: '0 1.25rem',\n borderRadius: 'var(--radius-md, 8px)',\n border: 'none',\n background: 'var(--color-race-red, #dc2626)',\n color: '#fff',\n fontFamily: \"var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)\",\n fontSize: '0.875rem',\n fontWeight: 600,\n cursor: 'pointer',\n }}\n >\n Retry\n </button>\n )}\n {bootProgress?.onSignOut && (\n <button\n type=\"button\"\n onClick={bootProgress.onSignOut}\n style={{\n height: 'auto',\n padding: 0,\n border: 'none',\n background: 'transparent',\n // 0.38 alpha was 3.51:1 on the ink-900 loading background —\n // below WCAG 2.2 AA 4.5:1. 0.72 clears it.\n color: 'rgba(255,255,255,0.72)',\n fontFamily: \"var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)\",\n fontSize: '12.5px',\n textDecoration: 'underline',\n cursor: 'pointer',\n }}\n >\n Sign out\n </button>\n )}\n </div>\n )}\n </div>\n <div\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n bottom: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '0 32px 30px',\n fontFamily: \"var(--font-family, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif)\",\n fontSize: '12.5px',\n // 0.38 alpha was 3.51:1 on the ink-900 loading background — below\n // WCAG 2.2 AA 4.5:1. 0.72 clears it.\n color: 'rgba(255,255,255,0.72)',\n }}\n >\n <span>Politogy VRM. Built for the long game.</span>\n <span style={{ fontFamily: 'var(--font-mono, ui-monospace, monospace)', letterSpacing: '0.04em' }}>\n {(bootProgress?.version ?? 'v—') + ' · ' + (bootProgress?.region ?? '—')}\n </span>\n </div>\n </div>\n )\n}\n","// Brand assets — logo URLs read at RUNTIME from the Brand token sheet.\n//\n// Brand guideline \"Logo standard: use the uploaded Brand assets as-is\": apps\n// (and the shell) never bundle their own copy of a logo; they read the URLs\n// from the Brand `assets` group. `/api/tokens?format=css` emits each set asset\n// as `--asset-<kebab>: url(\"…\")` on `:root`, and every app already loads that\n// sheet at runtime (see ../runtime-tokens.ts), so the rail logo is resolved\n// from the same live sheet as every other chrome value — a Brand upload swaps\n// the logo in every app without a deploy, and there is nothing to fall back to\n// that could drift.\n\n'use client'\n\nimport { useEffect, useState } from 'react'\n\n/** Brand `assets` keys the chrome renders, by their `--asset-<kebab>` name. */\nexport type BrandAssetKind = 'logo-horizontal' | 'logo-square'\n\n/** `url(\"https://…\")` / `url(https://…)` → the bare https URL, else null. */\nexport function parseCssUrl(value: string | null | undefined): string | null {\n if (!value) return null\n const m = /^url\\(\\s*(['\"]?)(.*?)\\1\\s*\\)$/i.exec(value.trim())\n const url = m?.[2]?.trim()\n return url && /^https:\\/\\//i.test(url) ? url : null\n}\n\n/** One Brand asset URL from the live token sheet, or null while it is unset. */\nexport function readBrandAsset(kind: BrandAssetKind): string | null {\n if (typeof document === 'undefined') return null\n try {\n return parseCssUrl(\n window.getComputedStyle(document.documentElement).getPropertyValue(`--asset-${kind}`),\n )\n } catch {\n return null\n }\n}\n\nexport type BrandAssets = {\n /** `assets.logoHorizontal` — the all-white lockup at the top of the rail. */\n logoHorizontal: string | null\n /** `assets.logoSquare` — the all-white vrm tile on the collapsed rail. */\n logoSquare: string | null\n}\n\nconst EMPTY: BrandAssets = { logoHorizontal: null, logoSquare: null }\n\n// The token sheet is a <link> the app appends at startup, so it may still be\n// in flight on first paint. Re-read when it loads, and a few times after, to\n// cover a link that is inserted after this effect ran.\nconst RETRY_MS = [0, 250, 1000, 3000]\n\n/**\n * The Brand logo URLs, resolved after mount (null on the server and until the\n * runtime token sheet has loaded). Callers reserve the logo's box and draw\n * nothing while a value is null — never a stand-in image.\n */\nexport function useBrandAssets(): BrandAssets {\n const [assets, setAssets] = useState<BrandAssets>(EMPTY)\n useEffect(() => {\n let done = false\n const read = () => {\n if (done) return\n const next = {\n logoHorizontal: readBrandAsset('logo-horizontal'),\n logoSquare: readBrandAsset('logo-square'),\n }\n setAssets((prev) =>\n prev.logoHorizontal === next.logoHorizontal && prev.logoSquare === next.logoSquare\n ? prev\n : next,\n )\n }\n const links = Array.from(\n document.querySelectorAll<HTMLLinkElement>('link[rel=\"stylesheet\"][href*=\"api/tokens\"]'),\n )\n links.forEach((l) => l.addEventListener('load', read))\n const timers = RETRY_MS.map((ms) => window.setTimeout(read, ms))\n read()\n return () => {\n done = true\n links.forEach((l) => l.removeEventListener('load', read))\n timers.forEach((t) => window.clearTimeout(t))\n }\n }, [])\n return assets\n}\n","// ---------------------------------------------------------------------------\n// PolitogyAppFrame — ONE component that renders the entire app frame.\n//\n// Why this exists (HITL directive 2026-07-23): shipping the same npm package at\n// the same version is necessary but NOT sufficient. The package exposed\n// PRIMITIVES (NavAppShell + a dozen hooks) and every app hand-assembled them in\n// its own ~150-line Shell.tsx. Identical inputs were never guaranteed, so the\n// outputs diverged — measured on production: forms rendered its user's EMAIL as\n// their name, polls' breadcrumb read \"Polls / Polls\", forms and surveys pinned\n// the mode pill to a hardcoded \"relationship\", and each app declared its own\n// chrome CSS variables (surveys' accent was #C8102E where everyone else was\n// #E63946).\n//\n// The fix is to stop exporting assembly as an app responsibility. An app now\n// renders:\n//\n// <PolitogyAppFrame app=\"forms\" pathname={pathname} linkComponent={Link}\n// session={{ userId, email, role, accountName, accountId }}\n// onSignOut={signOut}>\n// {children}\n// </PolitogyAppFrame>\n//\n// and passes NOTHING about the chrome: no nav, no breadcrumbs, no title, no\n// mode, no user menu, no footer, no theme. Those are derived here, identically,\n// for every app. Anything an app cannot pass is something it cannot drift on.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\n\nimport { broadcastLogout, watchLogout } from '../logout-signal'\nimport { resolveActiveMode, writeActiveModeCookie } from '../mode-preference'\nimport { clearBetaBannerDismissal, isNavItemActive } from '../native/index'\nimport { LoadingScreen, type BootProgress } from './loading-screen'\nimport {\n NavAppShell,\n standardPolitogyNav,\n type NavLinkComponent,\n} from '../native/index'\nimport {\n ChromeTopBarActions,\n PolitogyAppChrome,\n standardNavIcons,\n useChromeFooter,\n useChromeIdentity,\n useChromeMode,\n useChromeState,\n useChromeUserMenu,\n type ChromeDevNotesConfig,\n type ControlledOrgState,\n type TokenOrgState,\n} from './index'\nimport type {\n NavBreadcrumb,\n NavChromeFetcher,\n NavItem,\n NavMode,\n NavUserMenu,\n} from '../native/index'\nimport type { StandardNavMode } from '../native/standardNav'\nimport { deriveBreadcrumbs } from '../lib/breadcrumbs'\nimport { useBrandAssets } from '../lib/brandAssets'\nimport { warnDeprecated } from '../lib/deprecation'\n\n/**\n * The core app — the one that OWNS the canonical nav tree and routes in-app.\n * `PolitogyFrameData.core` is honored for this key and no other.\n */\nconst CORE_APP: PolitogyAppKey = 'vrm'\n\n/**\n * Template A convention: every feature app exposes GET /auth/signout, which\n * clears its session cookie and 302s to the IdP's end_session endpoint. Apps\n * that route sign-out elsewhere (core: /api/auth/logout) pass `signOutUrl`.\n */\nconst DEFAULT_SIGN_OUT_URL = '/auth/signout'\n\n/** Every app that renders the shared chrome. Keyed by its subdomain. */\nexport type PolitogyAppKey =\n | 'vrm'\n | 'contacts'\n | 'forms'\n | 'surveys'\n | 'polls'\n | 'petitions'\n // V2 apps that replace retired app.politogyvrm.com pages (Reference/\n // UI-Platform v42 \"Retirement of app.politogyvrm.com\").\n | 'dashboard'\n | 'settings'\n // Relationship Mode standalone apps.\n | 'email'\n // Campaign Mode standalone apps.\n | 'a2p'\n | 'phonebank'\n | 'canvass'\n | 'signs'\n // Relationship Mode CTAs (Specs/CTAs) — the new standalone acquisition app,\n // same \"forms./surveys./polls.\" pattern (unscoped, own subdomain).\n | 'ctas'\n\n/**\n * The operating Mode an app is scoped to, if any. It drives two things,\n * BOTH derived here from app identity so no app passes chrome config:\n * 1. the standardPolitogyNav tree the sidebar renders, and\n * 2. the static Mode pill the app shows (a campaign app shows a Campaign\n * pill, never Relationship).\n * An UNSCOPED app (no `mode`) keeps its prior behavior exactly: the\n * Relationship tree + an entitlement-driven Mode pill.\n */\nexport type PolitogyAppMode = StandardNavMode\n\n/**\n * A frame input a feature app is allowed to supply, because the answer is a\n * fact only the app has — not a styling choice.\n *\n * The grant list is the COMPLETE set of exceptions to \"an app never passes\n * chrome configuration\", and it lives here, in the shell, in one greppable\n * table. That is what keeps the no-drift guarantee: an app cannot grant itself,\n * so widening the surface takes a shell release and a review by whoever owns\n * the shell.\n *\n * Never add a grant for a visual input. `breadcrumbs` qualifies because only\n * the app knows which record a deep link points at. \"Petitions wants a wider\n * box\" would not qualify — that is a look, and looks come from tokens.\n *\n * RETIRED (0.69.0): the `contentWrapper` grant. The frame's `<main>` is fluid\n * and apps never emit their own page container (Brand guideline \"Content\n * width is fluid\"; Reference/UI-Platform → PolitogyAppFrame), so no app may be\n * granted one. Do not re-add it.\n */\nexport type PolitogyFrameGrant = 'breadcrumbs' | 'title'\n\n/**\n * The per-app registry — the ONLY place app identity lives. A new app adds a\n * row here and inherits every chrome behavior; it never re-derives one.\n */\nexport const POLITOGY_APPS: Record<\n PolitogyAppKey,\n {\n title: string\n origin: string\n storagePrefix: string\n mode?: PolitogyAppMode\n /**\n * DUAL-MODE apps (today: a2p — Specs/A2P: \"the SMS/MMS delivery engine\n * for Relationship Mode and Campaign Mode\") have no single fixed mode.\n * `mode` above stays the fallback/default identity for any code that\n * still reads `meta.mode` directly; FrameBody instead resolves the\n * EFFECTIVE mode via `resolveActiveMode` (?mode= query → the\n * `politogy_active_mode` cookie → `defaultMode`) and uses that for the\n * nav tree, the Mode pill, and the brand lockup.\n */\n dual?: { modes: readonly StandardNavMode[]; defaultMode: StandardNavMode }\n /** See PolitogyFrameGrant. Omitted => the app may pass no frame input. */\n grants?: readonly PolitogyFrameGrant[]\n /**\n * 'flat': the app's whole tree nests under one standard entry, and the rail\n * renders that entry's CHILDREN at the root — no parent header row, no\n * accordion (see NavSidebar nav.flatten). V1's petition rail was flat;\n * the parent row duplicated its first child's route.\n */\n navShape?: 'flat'\n /**\n * false: this app does not render the Beta banner strip. A registry\n * declaration, not an app prop, for the same reason as grants — whether a\n * product shows the platform's Beta notice is a platform decision.\n */\n beta?: boolean\n /**\n * false: the chrome does NOT draw its own page-title line (the 56px\n * `<h1>` above `main`); the app's page body owns its title. Specs/Contacts\n * design: the page opens on its own \"RELATIONSHIP MODE\" eyebrow + H1, so\n * a chrome-owned \"Contacts\" line above it was a second heading not in the\n * design. Registry-level (platform decision), like `beta`.\n */\n pageTitle?: false\n }\n> = {\n vrm: { title: 'Politogy VRM', origin: 'https://app.politogyvrm.com', storagePrefix: 'vrm' },\n contacts: {\n title: 'Contacts',\n origin: 'https://contacts.politogyvrm.com',\n storagePrefix: 'contacts',\n pageTitle: false,\n },\n // 'title' for forms/surveys/polls/ctas for the same reason as petitions\n // below: their pages have real names (\"Volunteer Signup\", \"Q3 Satisfaction\"),\n // where the registry can only say the app's own name. Without the grant the\n // page header falls back to the static registry title forever, so the\n // designed \"<mode> mode\" eyebrow + H2 + subtitle block never gets the real\n // per-page title an app passes it (UI-Platform → Page header).\n forms: { title: 'Forms', origin: 'https://forms.politogyvrm.com', storagePrefix: 'forms', grants: ['title'] },\n surveys: { title: 'Surveys', origin: 'https://surveys.politogyvrm.com', storagePrefix: 'surveys', grants: ['title'] },\n // Specs/Left-Navigation §9.2: Polling is a Campaign row (Research).\n polls: { title: 'Polls', origin: 'https://polls.politogyvrm.com', storagePrefix: 'polls', mode: 'campaign', grants: ['title'] },\n ctas: { title: 'CTAs', origin: 'https://ctas.politogyvrm.com', storagePrefix: 'ctas', grants: ['title'] },\n // V2 apps that replace retired app.politogyvrm.com pages (Reference/\n // UI-Platform v42 \"Retirement of app.politogyvrm.com\"). Dashboard hosts the\n // Relationship Dashboard + Campaign Battleground/District data/Campaigns\n // (Specs/Relationship-Dashboard); Settings hosts org settings & billing\n // (Specs/Organization-Settings).\n dashboard: { title: 'Dashboard', origin: 'https://dashboard.politogyvrm.com', storagePrefix: 'dashboard' },\n settings: { title: 'Settings', origin: 'https://settings.politogyvrm.com', storagePrefix: 'settings' },\n petitions: {\n title: 'Petitions',\n origin: 'https://petition-mode.politogyvrm.com',\n storagePrefix: 'petitions',\n mode: 'petition',\n // Its adjudication case is addressed per sheet and per line — a trail\n // derived from the nav tree reads \"Dashboard › Adjudication\" on every one\n // of those URLs and cannot name the record you are actually on. 'title'\n // for the same reason: its pages have real names (\"Batches\"), where the\n // registry can only say \"Petitions\".\n grants: ['breadcrumbs', 'title'],\n navShape: 'flat',\n beta: false,\n },\n // Relationship Mode Email Engine (Specs/Email-Engine) — the V2 standalone\n // app, running in parallel to VRM core's V1 Email Broadcast.\n email: { title: 'Email', origin: 'https://email.politogyvrm.com', storagePrefix: 'email', mode: 'relationship', grants: ['title'] },\n // Campaign Mode apps — each scoped to Campaign, so they render the Campaign\n // tree and a static Campaign pill. Not yet deployed; hidden from the Campaign\n // nav by CAMPAIGN_FEATURE_AVAILABILITY until their launch flips the flag.\n // Dual-mode: a2p is the SMS/MMS delivery engine for BOTH Relationship Mode\n // and Campaign Mode (Specs/A2P). `mode: 'campaign'` stays the fallback for\n // anything reading `meta.mode` directly; the effective mode a user sees is\n // resolved per-visit (see `dual`, resolveActiveMode).\n a2p: {\n title: 'A2P Messaging',\n origin: 'https://a2p.politogyvrm.com',\n storagePrefix: 'a2p',\n mode: 'campaign',\n dual: { modes: ['relationship', 'campaign'], defaultMode: 'campaign' },\n grants: ['title'],\n },\n phonebank: { title: 'Phone Banking', origin: 'https://phonebank.politogyvrm.com', storagePrefix: 'phonebank', mode: 'campaign', grants: ['title'] },\n canvass: { title: 'Field Canvassing', origin: 'https://canvass.politogyvrm.com', storagePrefix: 'canvass', mode: 'campaign', grants: ['title'] },\n signs: { title: 'Sign Mapping', origin: 'https://signs.politogyvrm.com', storagePrefix: 'signs', mode: 'campaign', grants: ['title'] },\n}\n\nexport type PolitogyAppSession = {\n /** Stable IdP subject (`sub`). */\n userId: string\n email: string | null\n /** The app's own role string — feeds DevNotes admin gating. */\n role: string\n /** The app's own workspace label, used only until core orgs resolve. */\n accountName: string\n accountId: string\n /**\n * Pre-hydration display name ONLY. The chrome API is the authority; an email\n * passed here is discarded rather than rendered as a name.\n */\n userName?: string | null\n}\n\n/**\n * Optional DATA plumbing for apps whose session/auth differs — never styling.\n *\n * Everything here is about WHERE data comes from (which fetcher, which org\n * state, which routes an app owns), not what the chrome looks like. Adding a\n * visual option to this type would re-open the drift this component exists to\n * close.\n */\n/** Per-app universal-search placeholder (design copy); \"Search\" elsewhere. */\nconst DEFAULT_SEARCH_PLACEHOLDER: Partial<Record<PolitogyAppKey, string>> = {\n contacts: 'Search contacts, segments, forms',\n}\n\nexport type PolitogyFrameData = {\n /** Chrome-API fetcher override for apps that authenticate client-side. */\n fetchJson?: NavChromeFetcher\n /** DevNotes wiring override for those same direct-auth apps. */\n devNotes?: ChromeDevNotesConfig\n /** Controlled org state for apps that own active-org + switching. */\n org?: ControlledOrgState\n /** Auth-owned active org from verified token claims (v2). Wins over `org`. */\n tokenOrg?: TokenOrgState\n /**\n * App-owned children for a standard nav entry this app owns (Contacts).\n * `count` is the live contact total, pre-formatted (\"31.9K\"), drawn\n * right-aligned on the Contacts row (Specs/Contacts design rail).\n */\n contactsItem?: { href?: string; children?: NavItem[]; count?: string | number | null }\n /**\n * Top-level standard-nav rows to omit, by label (e.g. `['Polls', 'CTAs']`).\n * The Specs/Contacts design rail shows exactly Dashboard · Contacts · Email\n * broadcast · SMS/MMS blast / Calls to action · Forms · Surveys / My profile\n * · Organization settings. Default: nothing hidden.\n */\n hiddenNavItems?: string[]\n /**\n * Universal-search placeholder. Defaults per app (Contacts: \"Search\n * contacts, segments, forms\"), else \"Search\".\n */\n searchPlaceholder?: string\n /**\n * true: render the rail as flat rows — every standard entry's `children`\n * are stripped before the sidebar draws, so no row carries an accordion\n * chevron (Specs/Contacts design rail: nine plain rows). Routing data is\n * untouched: active-row matching still uses the unstripped tree, exactly\n * as the 'tabs only' preference does. Default: children kept.\n */\n flatNav?: boolean\n /** Petitions app: nest its own routes under the Petition-mode entry. */\n petitionsItem?: { href?: string; children?: NavItem[] }\n /** Avatar fallback when the profile has no uploaded photo (memoji, default). */\n fallbackAvatarUrl?: string | null\n /**\n * Frame inputs this app has been GRANTED in the registry.\n *\n * Each field is honored only when the app's `POLITOGY_APPS` row lists it in\n * `grants`; an undeclared field is dropped before it reaches the chrome, so\n * passing one has no effect rather than a silent effect. Nothing here is\n * styling — see PolitogyFrameGrant for what qualifies.\n *\n * This is deliberately NOT a widening of the `app === CORE_APP` gate below.\n * That gate makes core's props inert for every other app; this makes a named\n * input live for a named app, listed in one place the shell owns.\n */\n frame?: PolitogyGrantedFrame\n /**\n * CORE-ONLY frame inputs. **Honored only when `app` is the core app (`vrm`)\n * — silently ignored for every other app**, which is what keeps the\n * no-drift guarantee intact: a feature app cannot re-specify a chrome\n * element even by passing this, so the props are inert for it.\n *\n * Core is genuinely different, and pretending otherwise would have meant\n * REMOVING shipped behavior from app.politogyvrm.com to satisfy packaging —\n * which Reference/UI-Platform forbids (\"migration may not drop a shipped\n * element … extend the shell first, then migrate\"). Specifically, core:\n * - owns the canonical nav tree AND decorates it with live entitlement\n * state a static tree cannot express (10DLC gating, contact/group\n * counts, org-lock),\n * - routes in-app (react-router), so its rows must be app-relative paths,\n * not the absolute cross-app URLs `standardPolitogyNav` emits,\n * - publishes per-page title/breadcrumbs from 66 page components,\n * - switches Mode client-side rather than by full-page navigation,\n * - owns real linked-account switching (with its own modals).\n *\n * Everything here is still DATA or app-owned STATE. There is no styling\n * input, no ordering input, and no way to change the top-bar action cluster\n * — those stay identical for every app, core included.\n */\n core?: PolitogyCoreFrame\n}\n\n/** See `PolitogyFrameData.frame` — honored per the app's registry `grants`. */\nexport type PolitogyGrantedFrame = {\n /**\n * @deprecated RETIRED in 0.69.0 and ignored: no app holds a `contentWrapper`\n * grant any more. The frame's `<main>` is fluid; remove the app's own page\n * container (`PageContainer`) and stop passing this. Still typed so an app\n * that passes it keeps compiling until it is cleaned up.\n */\n contentWrapper?: 'padded' | 'bare'\n /**\n * The trail for pages whose location is finer-grained than their nav row —\n * a specific record, not a section. For an app granted 'breadcrumbs' the\n * published trail REPLACES the derived one entirely: a page that publishes\n * none shows none, exactly as core's pages do. (Falling back to the derived\n * trail put \"Dashboard › Batches\" under the title of every list page — a\n * parent nobody chose, on apps whose pages already say where they are.)\n */\n breadcrumbs?: NavBreadcrumb[]\n /** The page's own name for the top bar (\"Batches\"), not the app's. */\n title?: string\n}\n\n/** See `PolitogyFrameData.core` — core app (`vrm`) only. */\nexport type PolitogyCoreFrame = {\n /** The canonical nav tree, decorated with core's live entitlement state. */\n nav?: NavItem[]\n /** Per-page identity published by core's own pages. */\n page?: { title?: string; breadcrumbs?: NavBreadcrumb[]; actions?: ReactNode }\n /** Client-side Mode switching (core navigates in-app, not cross-origin). */\n mode?: NavMode\n /** Real linked-account switching + core's theme persistence. */\n userMenu?: NavUserMenu\n /**\n * @deprecated Ignored since 0.69.0. The rail logo is the all-white lockup\n * from Brand `assets.logoHorizontal`, read at runtime, in every Mode —\n * never a mode-specific or bundled wordmark (Left-Navigation §5).\n */\n brandLogoSrc?: string\n /**\n * @deprecated Core still wraps its pages in `PageContainer`, which emits its\n * own `<main>`, so `'bare'` is honored for core until those pages are\n * migrated to the frame's fluid `<main>`. Not available to any other app.\n */\n contentWrapper?: 'padded' | 'bare'\n}\n\nexport type PolitogyBuildMeta = {\n envLabel?: string\n version?: string\n commit?: string\n commitDate?: string\n commitAuthor?: string\n}\n\nexport function PolitogyAppFrame({\n app,\n pathname,\n search,\n linkComponent,\n session,\n onSignOut,\n signOutUrl = DEFAULT_SIGN_OUT_URL,\n buildMeta,\n data,\n bootProgress,\n appReady,\n children,\n}: {\n app: PolitogyAppKey\n /** Current path from the app's router (Next: usePathname()). */\n pathname: string\n /** Current query string, when the app routes by query (forms' ?tab=). */\n search?: string\n /** The app's routing primitive (Next: <Link>). */\n linkComponent: NavLinkComponent\n session: PolitogyAppSession\n onSignOut: () => void\n /**\n * The app's sign-out ROUTE — a GET endpoint that clears the session cookie\n * and redirects to RP-initiated logout at the IdP. Defaults to the Template A\n * convention; core overrides it. This, not `onSignOut`, is what actually\n * signs the user out (see handleSignOut).\n */\n signOutUrl?: string\n buildMeta?: PolitogyBuildMeta\n /** Optional DATA plumbing (never styling) — see PolitogyFrameData. */\n data?: PolitogyFrameData\n /**\n * Real boot-pipeline progress (Specs/Loading-Screen §14 contract). Absent\n * for apps that have not wired their own pipeline yet — the frame then\n * reports a truthful but coarse two-stage boot instead of a spinner.\n */\n bootProgress?: BootProgress\n /**\n * Explicit \"the host app is ready to be shown\" signal. When omitted (every\n * app today), the Loading Screen dismisses itself once the chrome's own\n * org/nav state resolves, so none of the 14 consumer apps has to opt in to\n * keep working.\n */\n appReady?: boolean\n children: ReactNode\n}) {\n const meta = POLITOGY_APPS[app]\n return (\n <PolitogyAppChrome\n storagePrefix={meta.storagePrefix}\n fetchJson={data?.fetchJson}\n devNotes={data?.devNotes}\n org={data?.org}\n tokenOrg={data?.tokenOrg}\n identity={{\n userId: session.userId,\n userName: session.userName ?? null,\n email: session.email,\n role: session.role,\n }}\n >\n <FrameBody\n app={app}\n pathname={pathname}\n search={search}\n linkComponent={linkComponent}\n session={session}\n onSignOut={onSignOut}\n signOutUrl={signOutUrl}\n buildMeta={buildMeta}\n data={data}\n bootProgress={bootProgress}\n appReady={appReady}\n >\n {children}\n </FrameBody>\n </PolitogyAppChrome>\n )\n}\n\nfunction FrameBody({\n app,\n pathname,\n search,\n linkComponent,\n session,\n onSignOut,\n signOutUrl,\n buildMeta,\n data,\n bootProgress,\n appReady,\n children,\n}: {\n app: PolitogyAppKey\n pathname: string\n search?: string\n linkComponent: NavLinkComponent\n session: PolitogyAppSession\n onSignOut: () => void\n signOutUrl: string\n buildMeta?: PolitogyBuildMeta\n data?: PolitogyFrameData\n bootProgress?: BootProgress\n appReady?: boolean\n children: ReactNode\n}) {\n const meta = POLITOGY_APPS[app]\n const chrome = useChromeState()\n // Left-Navigation §5: the rail logo is Brand `assets.logoHorizontal` (and\n // `assets.logoSquare` on the collapsed rail), read at runtime from the Brand\n // token sheet — the same white lockup in every Mode and every app, never a\n // bundled or mode-specific copy.\n const brandAssets = useBrandAssets()\n if (data?.frame?.contentWrapper !== undefined) {\n warnDeprecated(\n 'frame.contentWrapper',\n \"`data.frame.contentWrapper` is retired and ignored: the frame's <main> is fluid. Remove the app's own page container and drop the prop.\",\n )\n }\n if (data?.core?.brandLogoSrc !== undefined) {\n warnDeprecated(\n 'core.brandLogoSrc',\n '`data.core.brandLogoSrc` is ignored: the rail logo is read at runtime from Brand `assets.logoHorizontal`.',\n )\n }\n\n // Loading Screen trigger gate (Specs/Loading-Screen §5, Global-Rules \"Boot\n // Screen Exception\"): shown on mount (cold start / hard reload both remount\n // this component fresh) and re-shown on organization switch or mode switch —\n // the two events that replace the account context after mount. A plain\n // route change never touches these refs, so it never re-arms the screen.\n const bootAppMode = meta.mode\n const bootOrgId = chrome?.orgId ?? null\n const [bootVisible, setBootVisible] = useState(true)\n // Remounts LoadingScreen on every new trigger so its internal monotonic\n // high-water mark and exit-transition state start clean for the new boot.\n const [bootGeneration, setBootGeneration] = useState(0)\n const seenOrgRef = useRef(bootOrgId)\n const seenModeRef = useRef(bootAppMode)\n useEffect(() => {\n if (seenOrgRef.current !== null && seenOrgRef.current !== bootOrgId) {\n setBootVisible(true)\n setBootGeneration((g) => g + 1)\n }\n seenOrgRef.current = bootOrgId\n }, [bootOrgId])\n useEffect(() => {\n if (seenModeRef.current !== undefined && seenModeRef.current !== bootAppMode) {\n setBootVisible(true)\n setBootGeneration((g) => g + 1)\n }\n seenModeRef.current = bootAppMode\n }, [bootAppMode])\n // Default dismiss signal when the app has not wired a real pipeline: the\n // chrome's own org list has resolved, i.e. the same state FrameBody already\n // needed to render the sidebar/org switcher truthfully. `chrome` is null\n // for an app rendered without a chrome/org provider at all (no org state to\n // wait on), which must count as resolved — otherwise the screen never\n // dismisses and blocks the app forever.\n const chromeResolved = chrome == null || !chrome.orgsLoading\n\n // Sign-out is a PLATFORM event, not an app event. Each app holds its own\n // host-only session cookie with a long sliding window, so without this a user\n // who signed out in one tab stayed fully signed in in every other open tab\n // and on every other subdomain. Announce the sign-out to all of them, then\n // run the app's own sign-out.\n //\n // Every app reaches sign-out through this frame, so wiring it here covers the\n // whole estate without an app having to opt in — the same guarantee the rest\n // of the chrome relies on.\n const signOutRef = useRef(onSignOut)\n signOutRef.current = onSignOut\n // This tab started the sign-out, so its own watcher must not also fire and\n // run the app's sign-out a second time concurrently.\n const signingOutRef = useRef(false)\n\n const handleSignOut = useCallback(() => {\n signingOutRef.current = true\n // Re-arm the Beta banner so it reappears at the next login rather than\n // staying hidden across an in-tab logout→login (sessionStorage survives it).\n clearBetaBannerDismissal()\n broadcastLogout()\n // Navigate to the app's sign-out ROUTE. Apps also pass an onSignOut\n // handler, but it cannot be relied on: they wire it as\n // `onSignOut={() => { void signOutAction(); }}`, and a server action\n // invoked outside a transition can never have its redirect() applied by\n // the client. Measured against production 2026-07-25: clicking Sign out\n // left the user signed in, and an app they had never opened authenticated\n // with no credentials — the IdP session was still alive because the\n // browser never reached its end-session endpoint.\n //\n // A plain navigation to a GET route cannot fail that way: the route drops\n // the session cookie and 302s to RP-initiated logout at the IdP.\n signOutRef.current()\n window.location.assign(signOutUrl)\n }, [signOutUrl])\n\n useEffect(\n () =>\n // A tab that learns of a sign-out elsewhere ends its own session for\n // real, by navigating to the same sign-out route.\n //\n // Measured against production before this landed: calling the app's\n // handler did nothing at all. Apps wire it as\n // `onSignOut={() => { void signOutAction(); }}` — a server action invoked\n // outside a transition, so the `redirect()` inside it can never be\n // applied by the client and the tab just sits there. Building cross-tab\n // logout on that path made the whole feature a no-op.\n //\n // A hard navigation cannot fail that way, and it hands the decision to\n // the authority rather than guessing: the app's middleware sees a session\n // whose auth_time predates `politogy_logout_at`, treats it as revoked,\n // and redirects to Politogy ID. Server-side truth decides; the client\n // only forces the request. No re-broadcast — the signal that woke us is\n // already on record for every tab.\n watchLogout(() => {\n if (signingOutRef.current) return\n clearBetaBannerDismissal()\n window.location.assign(signOutUrl)\n }),\n [signOutUrl],\n )\n // Core-only inputs are read through this ONE gate. For every other app it is\n // undefined no matter what the app passed, so the \"an app cannot re-specify a\n // chrome element\" guarantee holds by construction, not by convention.\n const core = app === CORE_APP ? data?.core : undefined\n\n // Registry-granted inputs run through the SAME shape of gate, one field at a\n // time: the registry decides, the app only supplies. An app that passes\n // `frame.breadcrumbs` without the grant gets `undefined` here, so the failure\n // mode is \"no effect\", never \"an app quietly re-specified the chrome\".\n const grants = meta.grants\n const granted = <K extends keyof PolitogyGrantedFrame>(\n key: K & PolitogyFrameGrant,\n ): PolitogyGrantedFrame[K] | undefined =>\n grants?.includes(key) ? data?.frame?.[key] : undefined\n\n // Identity: chrome API wins, app claims are a fallback, an email is never a\n // name (that is what forms was rendering in the top right).\n const identity = useChromeIdentity({ userName: session.userName, email: session.email })\n const derivedUserMenu = useChromeUserMenu({\n userId: session.userId,\n userName: identity.userName,\n email: identity.email,\n })\n const userMenu = core?.userMenu ?? derivedUserMenu\n const footer = useChromeFooter(buildMeta ?? {})\n // A mode-scoped app (Campaign apps, Petitions) pins its pill to its own mode;\n // an unscoped app stays entitlement + user-selection driven. Either way no\n // app passes a mode — it is read from the registry (app identity).\n //\n // A DUAL-MODE app (a2p — Specs/A2P) has no single fixed mode: its EFFECTIVE\n // mode is resolved per-visit, ?mode= query → politogy_active_mode cookie →\n // the app's own default, and that resolved value stands in for `meta.mode`\n // everywhere below (nav tree, Mode pill, brand lockup). Every other app is\n // unaffected — `appMode` is exactly `meta.mode`, as before.\n const resolvedDualMode = meta.dual\n ? resolveActiveMode({\n search: search ?? (typeof window !== 'undefined' ? window.location.search : undefined),\n modes: meta.dual.modes,\n defaultMode: meta.dual.defaultMode,\n })\n : undefined\n const appMode = resolvedDualMode ?? meta.mode\n const derivedMode = useChromeMode(appMode ? { pinnedModeId: appMode } : undefined)\n // Core switches Mode client-side; every other app jumps to the mode's home.\n const mode = core?.mode ?? derivedMode\n\n // PINNED apps (a fixed `meta.mode`, no `dual`) write their own mode to the\n // shared cookie whenever it is known, so a dual app visited next (a2p)\n // resolves to it instead of its own default — that is what makes \"SMS/MMS\n // Blast\" clicked from Relationship Mode land on the Relationship tree in\n // a2p even without a `?mode=` link.\n //\n // Core (`vrm`) has no `meta.mode` — it switches mode client-side via\n // in-app routing, not the registry — so its live mode is read from its own\n // route namespace (`/relationship/...` vs `/campaign/...`, the same split\n // `standardPolitogyNav`'s trees use) rather than `core?.mode` (a `NavMode`\n // describing the PILL's label/options, not which mode is currently active).\n // Re-runs on every pathname change, so switching mode in-app (a route\n // change, not a remount) still updates the cookie.\n const coreLiveMode: StandardNavMode | undefined =\n app === CORE_APP\n ? pathname.startsWith('/campaign')\n ? 'campaign'\n : pathname.startsWith('/relationship')\n ? 'relationship'\n : undefined\n : undefined\n const cookieMode = coreLiveMode ?? (meta.dual ? undefined : meta.mode)\n useEffect(() => {\n if (cookieMode) writeActiveModeCookie(cookieMode)\n }, [cookieMode])\n\n const coreOrgs = chrome?.orgs ?? []\n const activeCoreOrg = coreOrgs.find((o) => o.id === chrome?.orgId) ?? null\n const navDisplay = chrome?.navDisplay ?? 'both'\n\n // The nav tree follows the app's OWN mode (registry), not the live pill\n // selection — so it is deterministic from app identity. Unscoped apps render\n // Relationship exactly as before. Cross-app links in the Campaign/Petition\n // trees carry the active org the way the switcher/account menu do.\n const navMode: StandardNavMode = appMode ?? 'relationship'\n const activeOrgId = chrome?.orgId ?? null\n const derivedNavItems = useMemo(\n () =>\n standardPolitogyNav({\n coreBaseUrl: POLITOGY_APPS.vrm.origin,\n icons: standardNavIcons,\n // An app that OWNS a standard nav entry (Contacts) nests its own routes\n // under it. This is routing data, not chrome configuration.\n contactsItem: data?.contactsItem,\n petitionsItem: data?.petitionsItem,\n hiddenItems: data?.hiddenNavItems,\n mode: navMode,\n activeOrgId,\n }),\n [data?.contactsItem, data?.petitionsItem, data?.hiddenNavItems, navMode, activeOrgId],\n )\n // Core supplies the canonical tree already decorated with its live gating\n // state (and with app-relative hrefs so its router handles them in-app).\n const navItems = core?.nav ?? derivedNavItems\n\n // Left-Navigation §11.3: a row is active when the current route belongs to\n // its feature, by route prefix, never by exact URL — so a parent whose\n // OWN route is \"/\" still lights up on every child route it owns. The\n // 'tabs' display strips `children` before handing rows to the sidebar\n // (below), which would otherwise leave `isNavItemActive` with nothing to\n // prefix-match against and no row active on a child page (DevNotes\n // ebb036a1: Contacts' rail row went dark on /tribes, /import, /fields…).\n // Built from the UNSTRIPPED tree so the parent's activeness still reflects\n // routes its children (and grandchildren) own, independent of stripping.\n const navIsActive = useMemo(() => {\n const childHrefs = new Map<string, string[]>()\n for (const item of navItems) {\n if (!item.href || !item.children?.length) continue\n const hrefs: string[] = []\n for (const child of item.children) {\n if (child.href) hrefs.push(child.href)\n for (const leaf of child.children ?? []) {\n if (leaf.href) hrefs.push(leaf.href)\n }\n }\n childHrefs.set(item.href, hrefs)\n }\n return (pathname: string, href: string) =>\n isNavItemActive(pathname, href) ||\n (childHrefs.get(href) ?? []).some((h) => isNavItemActive(pathname, h))\n }, [navItems])\n\n // Dashboard › Sub › Item, derived from the same tree the sidebar renders.\n // Core publishes its trail from the page itself, because a core page's\n // location is finer-grained than its nav row (e.g. a contact detail view).\n const derivedBreadcrumbs = useMemo(\n () => deriveBreadcrumbs(navItems, pathname, { search, origin: meta.origin }),\n [navItems, pathname, search, meta.origin],\n )\n // An app granted 'breadcrumbs' behaves like core: the page's published\n // trail IS the trail, and a page that publishes nothing shows nothing.\n // (First cut fell back to the derived trail, which put \"Dashboard › Batches\"\n // under every list-page title — a parent nobody chose.) Ungranted apps keep\n // the derived trail exactly as before.\n const breadcrumbs = core\n ? core.page?.breadcrumbs\n : grants?.includes('breadcrumbs')\n ? granted('breadcrumbs')\n : derivedBreadcrumbs\n\n return (\n <>\n <LoadingScreen\n key={bootGeneration}\n visible={bootVisible}\n bootProgress={bootProgress}\n syntheticReady={appReady ?? chromeResolved}\n onExitComplete={() => setBootVisible(false)}\n />\n <NavAppShell\n sidebar={{\n pathname,\n brand: {\n logoSrc: brandAssets.logoHorizontal ?? undefined,\n logoSquareSrc: brandAssets.logoSquare ?? undefined,\n // Reserve the logo's box while the token sheet loads; never draw a\n // stand-in.\n logoPending: true,\n logoAlt: 'Politogy',\n badgeLabel: 'P',\n title: 'Politogy',\n },\n nav: {\n // A flat rail's sub-menu IS the nav, so the 'tabs only' preference\n // (which strips children) would leave one childless parent row —\n // flat apps ignore the stripping.\n items:\n (navDisplay === 'tabs' || data?.flatNav === true) && meta.navShape !== 'flat'\n ? navItems.map(({ children: _sub, ...item }) => item)\n : navItems,\n isActive: navIsActive,\n flatten: meta.navShape === 'flat',\n },\n // The app's own workspace is NOT the organization — it is a per-app\n // bootstrap account with a different id in every app. Showing it while\n // the chrome API resolves flashed the wrong org on every load (\"not\n // connected to the account\"). Shimmer while in flight; only fall back\n // to the app label once the chrome lookup has actually failed.\n org: activeCoreOrg\n ? {\n name: activeCoreOrg.name,\n id: activeCoreOrg.id,\n logoUrl: activeCoreOrg.logoUrl,\n brandColor: activeCoreOrg.brandColor,\n organizations: coreOrgs,\n onSwitch: chrome?.setOrgId,\n }\n : chrome?.orgsLoading\n ? { name: null, id: null, loading: true }\n : { name: session.accountName, id: session.accountId },\n mode,\n footer,\n linkComponent,\n }}\n // Reference/UI-Platform: the Beta banner is opt-in — it shows only\n // when the app's own POLITOGY_APPS registry entry sets `beta: true`,\n // not by default minus an opt-out.\n betaBanner={meta.beta === true ? {} : undefined}\n // Mode identity, straight from the registry — this is what lets the Brand\n // API's per-Mode chrome tokens target this frame. Not app-supplied: an app\n // still cannot pick its own accent, it inherits its Mode's.\n modeId={appMode}\n // Fluid <main> for every app. Core alone may still opt out while its\n // pages carry their own PageContainer (see PolitogyCoreFrame).\n contentWrapper={core?.contentWrapper}\n topBar={{\n // Core's pages publish their own identity; every other app is one\n // product surface and takes its registry title.\n // TITLEBAR (Design is truth): the chrome no longer draws a page-title\n // <h1> strip above the page for feature apps. Specs/Design shows the\n // page opening on its own eyebrow + H2 (app content), so only core's\n // own page title is passed. The 'title' grant is retained but inert.\n title: core?.page?.title,\n breadcrumbs,\n user: {\n name: identity.userName,\n email: identity.email,\n // The chrome API's avatar wins; the app may supply a fallback chain\n // (e.g. a stored memoji) for users with no uploaded photo.\n avatarUrl: identity.avatarUrl ?? data?.fallbackAvatarUrl ?? null,\n role: session.role,\n },\n userMenu,\n onSignOut: handleSignOut,\n // Reference/UI-Platform \"Top bar — required elements\": Universal\n // search is the only thing on the left end of the bar. No app wires\n // search yet, so this stays decorative (`NavTopBarProps.search` — \"an\n // app that has not wired search yet still gets the correct chrome\").\n search: { placeholder: data?.searchPlaceholder ?? DEFAULT_SEARCH_PLACEHOLDER[app] ?? 'Search' },\n // No Build notes control (Reference/UI-Platform, decided 2026-10-03).\n // The action cluster is IDENTICAL everywhere — core included. Page\n // actions sit BEFORE it, never inside it, so the Alerts bell keeps its\n // required position: farthest right, immediately before My Account.\n actions: (\n <>\n {core?.page?.actions}\n <ChromeTopBarActions />\n </>\n ),\n }}\n >\n {children}\n </NavAppShell>\n </>\n )\n}\n","// ---------------------------------------------------------------------------\n// App chrome wiring — the ONE shared implementation of the per-app glue that\n// previously lived as a copied ChromeWidgets.tsx in every Next.js feature app\n// (forms / surveys / polls / contacts). Copies drifted (org dropdown, badges);\n// this module makes that class of drift impossible: apps configure, never\n// re-implement (Reference/UI-Platform: consume via npm, never vendored).\n//\n// Provides:\n// <PolitogyAppChrome> — NavChromeProvider (same-origin proxy fetcher) +\n// chrome state (active core org, nav display) +\n// DevNotes provider, in one wrapper.\n// <ChromeTopBarActions> — the canonical top-bar cluster, in canonical order\n// (Fuel · Nav display · DevNotes · Support · Alerts\n// LAST, immediately left of My Account).\n// useChromeState / useChromeUserMenu / useIsSuperAdmin / useChromeFooter.\n//\n// The app still owns: its session (the /api/chrome proxy), page frames, build\n// metadata (env/commit/version), tab strips, and its own icons.\n// ---------------------------------------------------------------------------\n\n'use client'\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport type { NotificationsAdapter } from '../notifications/adapter'\nimport {\n NavChromeProvider,\n FuelAction,\n NotificationsAction,\n SupportAction,\n SpecOverlayAction,\n NavDisplayAction,\n TopBarWidgetSlot,\n useChromeOrgs,\n type NavChromeFetcher,\n type NavDisplayMode,\n type NavOrgOption,\n type NavUserMenu,\n type NavFooter,\n type NavFooterLink,\n} from '../native/index'\nimport {\n DevNotesProvider,\n DevNotesMenu,\n DevNotesOverlay,\n DevNotesTaskListModal,\n createDevNotesClient,\n type DevNotesConfig,\n} from '@the-portland-company/devnotes'\nimport {\n LuActivity,\n LuChartColumn,\n LuBriefcase,\n LuClock,\n LuCreditCard,\n LuDollarSign,\n LuPencil,\n LuFileText,\n LuFlag,\n LuLayoutGrid,\n LuHouse,\n LuLayoutDashboard,\n LuLifeBuoy,\n LuList,\n LuMail,\n LuMap,\n LuMapPin,\n LuMessageSquare,\n LuPhone,\n LuSend,\n LuSettings,\n LuShare2,\n LuTarget,\n LuUpload,\n LuUser,\n LuUsers,\n LuContactRound,\n LuUsersRound,\n LuMousePointerClick,\n LuClipboardList,\n LuCircleUser,\n LuCrosshair,\n LuLandmark,\n LuChartNoAxesColumn,\n LuDoorOpen,\n LuSignpost,\n LuMegaphone,\n LuFilePenLine,\n LuNotebookPen,\n} from 'react-icons/lu'\nimport { useChromeMe, useNavChromeDedupedFetch, useNavChromeFetcher } from '../native/index'\nimport {\n ACTIVE_ORG_QUERY_PARAM,\n ORG_ID_QUERY_PARAM,\n isOrgId,\n matchOrgSelector,\n orgIdTail,\n readActiveOrgCookie,\n readOrgSelectorFromUrl,\n resolveActiveOrg,\n switchActiveOrg,\n writeActiveOrgCookie,\n syncOrgIdInUrl,\n} from '../active-org'\nimport {\n NAV_DISPLAY_DEFAULT,\n NAV_DISPLAY_STORAGE_KEY,\n isNavDisplayPreference,\n readNavDisplayCookie,\n resolveNavDisplay,\n writeNavDisplayCookie,\n writeNavDisplayLocal,\n} from '../nav-preference'\nimport type { StandardNavIconKey } from '../native/standardNav'\nimport type { NavBreadcrumb, NavIcon, NavItem, NavMode } from '../native/index'\n\nexport { standardNavIcons } from '../native/standardNavIcons'\nimport { standardNavIcons } from '../native/standardNavIcons'\n\nconst ORG_STORAGE_KEY = 'vrm.activeOrg'\n// The user's mode choice, shared by every app on the origin's localStorage.\nconst MODE_STORAGE_KEY = 'vrm.activeMode'\nconst CORE_BASE_URL = 'https://app.politogyvrm.com'\nconst CORE_BASE_URL_STAGING = 'https://staging-app.politogyvrm.com'\n\n/**\n * VRM-core base for the CURRENT environment, resolved at call time from the\n * host. A staging app (e.g. `surveys-staging.politogyvrm.com`,\n * `staging-app.politogyvrm.com`) targets the staging core, so cross-app links\n * into core — My Profile, Organization Settings, Add Account, the mode\n * dashboards — stay in staging instead of bouncing the user to production.\n * Everything else (prod hosts, localhost, previews) keeps the production core.\n *\n * Runtime, not build-time: the shell is one shared bundle consumed by every\n * app, so the environment can only be known from the host it runs on.\n */\nfunction getCoreBaseUrl(): string {\n if (typeof window !== 'undefined') {\n if (window.location.hostname.toLowerCase().includes('staging')) {\n return CORE_BASE_URL_STAGING\n }\n }\n return CORE_BASE_URL\n}\n\nexport type ChromeIdentity = {\n userId: string\n userName: string | null\n email: string | null\n /** The APP's own role string (any casing) — feeds DevNotes admin gating. */\n role: string\n}\n\ntype ChromeState = {\n orgId: string | null\n setOrgId: (id: string) => void\n orgs: (NavOrgOption & { rawRole?: string | null })[]\n /**\n * The org list is still in flight. Consumers must render a skeleton rather\n * than fall back to the app's own workspace label, which is a DIFFERENT\n * account and flashes as the wrong organization.\n */\n orgsLoading: boolean\n navDisplay: NavDisplayMode\n setNavDisplay: (m: NavDisplayMode) => void\n}\n\nconst ChromeStateContext = createContext<ChromeState | null>(null)\n\nexport function useChromeState(): ChromeState | null {\n return useContext(ChromeStateContext)\n}\n\nexport type ControlledOrgState = {\n orgId: string | null\n onSwitch: (id: string) => void\n /** Override the org list (e.g. the app's own session-scoped list). */\n orgs?: (NavOrgOption & { rawRole?: string | null })[]\n /**\n * Applied for EXTERNAL org changes (another tab/app switched the shared\n * cookie, or the profile preference was adopted at boot). Unlike `onSwitch`\n * (a user gesture), this fires on tab focus — wire it WITHOUT navigation\n * side effects (e.g. vrm/core's switch without the dashboard redirect).\n * Falls back to `onSwitch` when absent.\n */\n onExternalSwitch?: (id: string) => void\n}\n\n/**\n * Auth-owned active org (Global-Rules v38, UI-Platform v46). The app server\n * passes the VERIFIED token claims; the shell never resolves the org itself.\n */\nexport type TokenOrgState = {\n /** `org_id` claim from the app's verified token (full uuid). */\n orgId: string | null\n /** `org_role` claim (raw VRM Core role). */\n orgRole?: string | null\n /**\n * The switcher list from the app server (names for the pill). When given,\n * the chrome `/api/orgs` call is skipped. When absent it is the fallback.\n */\n orgs?: (NavOrgOption & { rawRole?: string | null })[]\n /**\n * Server action that re-exchanges for tokens on `orgId`. Called after the\n * IdP accepted the switch (shared) or for a per-tab override (`perTab`).\n */\n onReexchange: (orgId: string, opts: { perTab: boolean }) => void | Promise<void>\n /** IdP base override (default: auth / auth-staging by host). */\n authBaseUrl?: string\n /** Called when the IdP refuses a switch (403 not a member, 401 no session). */\n onSwitchError?: (err: unknown) => void\n}\n\nfunction TokenChromeStateProvider({\n tokenOrg,\n children,\n}: {\n tokenOrg: TokenOrgState\n children: ReactNode\n}) {\n const { orgs: fetchedOrgs, loading: orgsFetching, error: orgsError } = useChromeOrgs({\n enabled: !tokenOrg.orgs,\n })\n const [navDisplay, setNavDisplayState] = useState<NavDisplayMode>(NAV_DISPLAY_DEFAULT)\n const [pendingOrg, setPendingOrg] = useState<string | null>(null)\n const tokenOrgRef = useRef(tokenOrg)\n tokenOrgRef.current = tokenOrg\n\n useEffect(() => {\n setNavDisplayState(resolveNavDisplay())\n }, [])\n\n const orgs = useMemo(\n () =>\n tokenOrg.orgs ??\n (fetchedOrgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n [tokenOrg.orgs, fetchedOrgs],\n )\n\n // Per-tab override: `?org_id=` (or legacy `?org=`) in THIS tab's URL. It\n // scopes this tab only and never changes the shared active org. A selector\n // that is not one of the user's orgs is ignored.\n //\n // `urlSelector` used to be read once at mount (`useState(() => ...)`),\n // which froze whatever org was in the URL at that moment. A later shared\n // switch (setOrgId) rewrites the URL to the new org but never told this\n // state about it, so the stale selector kept winning at line ~264 forever\n // — repro: switch A -> B, reload (urlSelector now \"B\"), switch B -> A: the\n // pill stayed on B because overrideOrg was still matching the frozen \"B\"\n // from mount. Re-read on every URL change (a switch calls\n // history.replaceState, which doesn't fire `popstate`, so setOrgId clears\n // this directly on success below instead of relying on the listener for\n // that case) and on back/forward navigation.\n const [urlSelector, setUrlSelector] = useState<string | null>(() =>\n typeof window === 'undefined' ? null : readOrgSelectorFromUrl(window.location.search),\n )\n useEffect(() => {\n if (typeof window === 'undefined') return\n const onLocationChange = () => setUrlSelector(readOrgSelectorFromUrl(window.location.search))\n window.addEventListener('popstate', onLocationChange)\n return () => window.removeEventListener('popstate', onLocationChange)\n }, [])\n const overrideOrg = useMemo(\n () => (urlSelector ? matchOrgSelector(urlSelector, orgs)?.id ?? null : null),\n [urlSelector, orgs],\n )\n const orgId = pendingOrg ?? (tokenOrg.orgId && overrideOrg ? overrideOrg : tokenOrg.orgId)\n\n // A per-tab override that differs from the token org: ask the app server for\n // a tab-scoped token once (the IdP shared active org stays as it is).\n const reexchangedFor = useRef<string | null>(null)\n useEffect(() => {\n if (!overrideOrg || !tokenOrg.orgId || overrideOrg === tokenOrg.orgId) return\n if (reexchangedFor.current === overrideOrg) return\n reexchangedFor.current = overrideOrg\n void Promise.resolve(tokenOrgRef.current.onReexchange(overrideOrg, { perTab: true })).catch(\n () => {},\n )\n }, [overrideOrg, tokenOrg.orgId])\n\n // Clear the optimistic value once the app's new token carries it.\n useEffect(() => {\n if (pendingOrg && tokenOrg.orgId === pendingOrg) setPendingOrg(null)\n }, [pendingOrg, tokenOrg.orgId])\n\n const setOrgId = useCallback((id: string) => {\n const current = tokenOrgRef.current\n if (!isOrgId(id) || id === (current.orgId ?? null)) return\n setPendingOrg(id)\n void (async () => {\n try {\n const claims = await switchActiveOrg(id, { authBaseUrl: current.authBaseUrl })\n // The switch is shared: drop this tab's URL override so it follows.\n // Clear it here directly (not only via the popstate listener above)\n // because the URL rewrite below is a `history.replaceState`, which\n // never fires `popstate` — so this is the only place in the\n // shared-switch path that would otherwise see the stale selector.\n setUrlSelector(null)\n try {\n const url = new URL(window.location.href)\n url.searchParams.delete(ACTIVE_ORG_QUERY_PARAM)\n url.searchParams.set(ORG_ID_QUERY_PARAM, orgIdTail(claims.orgId) as string)\n window.history.replaceState(window.history.state, '', url.toString())\n } catch {\n /* SSR / no window */\n }\n await tokenOrgRef.current.onReexchange(claims.orgId, { perTab: false })\n } catch (err) {\n setPendingOrg(null)\n tokenOrgRef.current.onSwitchError?.(err)\n }\n })()\n }, [])\n\n const setNavDisplay = useCallback((m: NavDisplayMode) => {\n setNavDisplayState(m)\n writeNavDisplayLocal(m)\n writeNavDisplayCookie(m)\n }, [])\n\n // Address bar carries the 7-char `org_id` (UI-Platform \"URL state\") ONLY\n // when the user brought a selector or a real switch put one there; a bare\n // load stays bare (see syncOrgIdInUrl). A legacy `?org=<uuid>` is rewritten\n // with a replace, never a navigation.\n useEffect(() => {\n try {\n const next = syncOrgIdInUrl(window.location.href, orgId)\n if (next) window.history.replaceState(window.history.state, '', next)\n } catch {\n /* SSR / no window */\n }\n }, [orgId])\n\n // Legacy cookie mirror for apps not yet on v2 — the SHARED org only, never a\n // per-tab override.\n useEffect(() => {\n if (isOrgId(tokenOrg.orgId) && !pendingOrg) writeActiveOrgCookie(tokenOrg.orgId as string)\n }, [tokenOrg.orgId, pendingOrg])\n\n // Follow a SHARED switch made in another app/tab (Forge 773bf0eb). Unlike\n // the legacy `ChromeStateProvider`, this provider never re-read the mirror\n // cookie on wake, so an already-open tab kept its own stale `tokenOrg.orgId`\n // until the next full reload — reload-driven routes work because they\n // re-fetch `scope.account` from the server, bypassing this cookie entirely.\n // Re-exchange shared (never perTab) whenever the cookie disagrees with the\n // token on wake; the dedup/membership judgment is the IdP's own job inside\n // `onReexchange`, not this listener's.\n useEffect(() => {\n const onWake = () => {\n const cookieOrg = readActiveOrgCookie()\n const current = tokenOrgRef.current\n if (!isOrgId(cookieOrg) || cookieOrg === (current.orgId ?? null)) return\n if (pendingOrg === cookieOrg) return\n void Promise.resolve(current.onReexchange(cookieOrg as string, { perTab: false })).catch(\n () => {},\n )\n }\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [pendingOrg])\n\n const value = useMemo<ChromeState>(\n () => ({\n orgId,\n setOrgId,\n orgs,\n orgsLoading: !tokenOrg.orgs && orgsFetching && !orgsError && !fetchedOrgs,\n navDisplay,\n setNavDisplay,\n }),\n [orgId, setOrgId, orgs, tokenOrg.orgs, orgsFetching, orgsError, fetchedOrgs, navDisplay, setNavDisplay],\n )\n\n return <ChromeStateContext.Provider value={value}>{children}</ChromeStateContext.Provider>\n}\n\nfunction ChromeStateProvider({\n controlledOrg,\n children,\n}: {\n controlledOrg?: ControlledOrgState\n children: ReactNode\n}) {\n const { orgs, loading: orgsFetching, error: orgsError } = useChromeOrgs()\n const chromeMe = useChromeMe()\n const chromeFetch = useNavChromeFetcher()\n const [orgId, setOrgIdState] = useState<string | null>(null)\n const [navDisplay, setNavDisplayState] = useState<NavDisplayMode>(NAV_DISPLAY_DEFAULT)\n const navReconciled = useRef(false)\n const orgReconciled = useRef(false)\n // Whether boot found an explicit selector (URL `?org=` or the shared cookie).\n // The mirror effect writes the cookie right after first resolve, so a later\n // `resolveActiveOrg()` read is a false positive — this ref is the only\n // reliable \"was there a pre-existing selector?\" signal for the profile tier.\n const hadBootSelector = useRef(false)\n\n // Boot: restore persisted choices. The cross-app active org (URL `?org=` or\n // the `.politogyvrm.com` cookie) wins over host-only localStorage so every\n // app + subdomain resolves the SAME org instead of each defaulting to its own\n // earliest-joined org. Nav display follows the same cross-subdomain contract\n // as theme (cookie → localStorage → default) — it used to be localStorage\n // only, which is per-origin, so it reset on every app the user opened.\n useEffect(() => {\n try {\n const selector = resolveActiveOrg()\n if (selector) hadBootSelector.current = true\n const storedOrg = selector ?? localStorage.getItem(ORG_STORAGE_KEY)\n if (storedOrg) setOrgIdState(storedOrg)\n } catch {\n /* storage unavailable */\n }\n setNavDisplayState(resolveNavDisplay())\n }, [])\n\n // Once per session: converge on the profile's saved choice (authoritative),\n // reusing the provider's single `me` fetch — the theme reconcile pattern.\n useEffect(() => {\n if (navReconciled.current || !chromeMe.me) return\n const pref = chromeMe.me.navDisplay\n if (!isNavDisplayPreference(pref)) return\n navReconciled.current = true\n setNavDisplayState(pref)\n writeNavDisplayCookie(pref)\n writeNavDisplayLocal(pref)\n }, [chromeMe])\n\n // Live sync: `storage` events for same-app tabs, cookie re-reads on\n // focus/visibility for tabs on OTHER app subdomains.\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === NAV_DISPLAY_STORAGE_KEY && isNavDisplayPreference(e.newValue)) {\n setNavDisplayState(e.newValue)\n }\n }\n const onWake = () => {\n const cookie = readNavDisplayCookie()\n if (cookie) setNavDisplayState(cookie)\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [])\n\n // Once orgs resolve: validate the stored org, default to the first.\n useEffect(() => {\n if (!orgs || orgs.length === 0) return\n setOrgIdState((prev) => (prev && orgs.some((o) => o.id === prev) ? prev : orgs[0].id))\n }, [orgs])\n\n // Refs for the live-sync wake handler: registered once (theme/nav precedent)\n // but acting on CURRENT state, so listeners never re-subscribe per render.\n const activeOrgRef = useRef<string | null>(null)\n const memberOrgsRef = useRef<{ id: string }[]>([])\n const controlledOrgRef = useRef<ControlledOrgState | undefined>(controlledOrg)\n controlledOrgRef.current = controlledOrg\n\n // Apply an EXTERNAL org change (another tab/app, or the adopted profile\n // preference). Membership-guarded and change-guarded; silent fall-through\n // otherwise — a non-member cookie value is normal, not an error.\n const applyExternalOrg = useCallback((next: string | null) => {\n if (!isOrgId(next)) return\n const members = memberOrgsRef.current\n if (members.length === 0) return\n if (!members.some((o) => o.id === next)) return\n if (next === activeOrgRef.current) return\n const controlled = controlledOrgRef.current\n if (controlled) (controlled.onExternalSwitch ?? controlled.onSwitch)(next as string)\n else setOrgIdState(next as string)\n }, [])\n\n // Live org sync: `storage` events for same-origin tabs, cookie re-reads on\n // focus/visibility for tabs on OTHER app subdomains — the same two channels\n // theme and nav display use. A user switching orgs in one app re-scopes\n // every other open tab the moment it regains focus.\n useEffect(() => {\n const onStorage = (e: StorageEvent) => {\n if (e.key === ORG_STORAGE_KEY) applyExternalOrg(e.newValue)\n }\n const onWake = () => {\n applyExternalOrg(readActiveOrgCookie())\n }\n window.addEventListener('storage', onStorage)\n window.addEventListener('focus', onWake)\n document.addEventListener('visibilitychange', onWake)\n return () => {\n window.removeEventListener('storage', onStorage)\n window.removeEventListener('focus', onWake)\n document.removeEventListener('visibilitychange', onWake)\n }\n }, [applyExternalOrg])\n\n // Once per session: adopt the profile's saved org (me.activeOrg) — but ONLY\n // when this load carried no explicit selector. Precedence is URL → cookie →\n // profile → default; theme's unconditional adopt is wrong for org because an\n // explicit per-request selector must always win.\n //\n // Membership is judged against the FETCHED chrome-API org list, not the\n // controlled app's list: controlled apps seed a provisional single-org list\n // (their session default) before their real fetch settles, and judging the\n // preference against that dropped it every time (verified live 2026-08-07).\n useEffect(() => {\n if (orgReconciled.current || !chromeMe.me) return\n if (hadBootSelector.current) {\n orgReconciled.current = true\n return\n }\n const pref = (chromeMe.me as { activeOrg?: string | null }).activeOrg\n if (!isOrgId(pref)) {\n orgReconciled.current = true\n return\n }\n // Wait until the chrome-API org fetch settles (success or error) — do NOT\n // latch while it is in flight, or the preference is silently dropped.\n if (!orgs && !orgsError) return\n orgReconciled.current = true\n const members = [...(orgs ?? []), ...(controlledOrg?.orgs ?? [])]\n if (!members.some((o) => o.id === pref)) return\n const controlled = controlledOrgRef.current\n if (controlled) (controlled.onExternalSwitch ?? controlled.onSwitch)(pref as string)\n else setOrgIdState(pref as string)\n }, [chromeMe.me, orgs, orgsError, controlledOrg])\n\n const setOrgId = useCallback((id: string) => {\n setOrgIdState(id)\n try {\n localStorage.setItem(ORG_STORAGE_KEY, id)\n } catch {\n /* best effort */\n }\n // Remember the choice cross-subdomain so the next app opens on the same org.\n writeActiveOrgCookie(id)\n }, [])\n\n const setNavDisplay = useCallback(\n (m: NavDisplayMode) => {\n setNavDisplayState(m)\n writeNavDisplayLocal(m)\n // Cross-subdomain, so the next app opens on the same choice.\n writeNavDisplayCookie(m)\n // Best-effort durable persistence on the user's profile — a nav toggle\n // never errors, and the cookie already carries the choice meanwhile.\n chromeFetch?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ navDisplay: m }),\n })?.catch(() => {})\n },\n [chromeFetch],\n )\n\n const value = useMemo<ChromeState>(() => {\n // CONTROLLED mode (Contacts): the APP owns the active org + switching —\n // its switch does a full session re-scope. The shared widgets read the\n // app's state so there is exactly one org truth (unification directive).\n if (controlledOrg) {\n return {\n orgId: controlledOrg.orgId,\n setOrgId: controlledOrg.onSwitch,\n orgs:\n controlledOrg.orgs ??\n (orgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n orgsLoading: false,\n navDisplay,\n setNavDisplay,\n }\n }\n return {\n orgId,\n setOrgId,\n orgs: (orgs ?? []).map((o) => ({\n id: o.id,\n name: o.name,\n logoUrl: o.logoUrl,\n brandColor: o.brandColor,\n role: o.role,\n rawRole: o.rawRole ?? null,\n })),\n // Loading until the fetch settles. On error we stop loading so the frame\n // falls back to the app label rather than shimmering forever.\n orgsLoading: orgsFetching && !orgsError && !orgs,\n navDisplay,\n setNavDisplay,\n }\n }, [controlledOrg, orgId, setOrgId, orgs, orgsFetching, orgsError, navDisplay, setNavDisplay])\n\n // Keep the shared cookie + address-bar `?org=` in sync with the ACTIVE org —\n // whichever path owns it, controlled (Contacts) or uncontrolled (feature\n // apps) — so every app + tab resolves the same org and every URL is\n // bookmarkable/shareable with its org context. Idempotent; no-op on server.\n const activeOrgId = value.orgId\n activeOrgRef.current = activeOrgId\n memberOrgsRef.current = value.orgs\n const lastPatchedOrg = useRef<string | null>(null)\n useEffect(() => {\n if (!isOrgId(activeOrgId)) return\n writeActiveOrgCookie(activeOrgId as string)\n try {\n // Same-origin storage channel for OTHER tabs of this app (the cookie\n // write emits no event) — mirrors the choice whichever branch owns it.\n localStorage.setItem(ORG_STORAGE_KEY, activeOrgId as string)\n } catch {\n /* best effort */\n }\n try {\n const url = new URL(window.location.href)\n if (url.searchParams.get(ACTIVE_ORG_QUERY_PARAM) !== activeOrgId) {\n url.searchParams.set(ACTIVE_ORG_QUERY_PARAM, activeOrgId as string)\n window.history.replaceState(window.history.state, '', url.toString())\n }\n } catch {\n /* SSR / no window */\n }\n // Durable profile write (the theme/nav pattern): one call site covers both\n // the controlled and uncontrolled branches. Best-effort, deduped against\n // the profile's known value and our own last write; a fresh browser with\n // no cookie then boots on this org via the profile tier.\n //\n // GATED on the reconcile having resolved: before that, activeOrgId is the\n // app's boot DEFAULT, and patching it overwrote the user's stored\n // preference with the default on every fresh session (verified live\n // 2026-08-07 — the preference lasted exactly one login).\n const known = (chromeMe.me as { activeOrg?: string | null } | null)?.activeOrg ?? null\n if (\n orgReconciled.current &&\n chromeMe.me &&\n activeOrgId !== known &&\n activeOrgId !== lastPatchedOrg.current\n ) {\n lastPatchedOrg.current = activeOrgId as string\n chromeFetch?.('me/preferences', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ activeOrg: activeOrgId }),\n })?.catch(() => {})\n }\n }, [activeOrgId, chromeMe.me, chromeFetch])\n\n return <ChromeStateContext.Provider value={value}>{children}</ChromeStateContext.Provider>\n}\n\nexport type ChromeDevNotesConfig = {\n /** Override the DevNotes API base (default: `${proxyBasePath}/devnotes`). */\n basePath?: string\n /** Client-side token supplier (default: empty — same-origin proxy injects). */\n getAuthToken?: () => Promise<string> | string\n /** Custom fetch (e.g. credentials:'include' against a cross-origin API). */\n fetch?: typeof globalThis.fetch\n /**\n * The app already mounts its own `<DevNotesProvider>` ABOVE this chrome, so\n * the chrome must not mount a second one (VRM core, whose provider carries\n * capabilities the generic client has no equivalent for — user stories, its\n * own role gating). The working SURFACE still comes from here, so the\n * launcher, the overlay and the task modal behave identically everywhere;\n * only the data adapter is the app's.\n */\n providedByApp?: boolean\n}\n\nfunction AppDevNotes({\n storagePrefix,\n proxyBasePath,\n devNotes,\n identity,\n children,\n}: {\n storagePrefix: string\n proxyBasePath: string\n devNotes?: ChromeDevNotesConfig\n identity: ChromeIdentity\n children: ReactNode\n}) {\n const adapter = useMemo(\n () =>\n createDevNotesClient({\n basePath: devNotes?.basePath ?? `${proxyBasePath}/devnotes`,\n // Default: the same-origin proxy attaches the session's Bearer.\n getAuthToken: devNotes?.getAuthToken ?? (async () => ''),\n ...(devNotes?.fetch ? { fetch: devNotes.fetch } : {}),\n }),\n [proxyBasePath, devNotes?.basePath, devNotes?.getAuthToken, devNotes?.fetch],\n )\n\n const user = useMemo(\n () => ({\n id: identity.userId,\n email: identity.email ?? '',\n fullName: identity.userName ?? undefined,\n }),\n [identity.userId, identity.email, identity.userName],\n )\n\n const config = useMemo<DevNotesConfig>(\n () => ({\n storagePrefix,\n role: identity.role.toLowerCase() === 'admin' ? 'admin' : 'reporter',\n disableAi: true,\n getPagePath: () => window.location.pathname,\n }),\n [storagePrefix, identity.role],\n )\n\n // `<DevNotesProvider>` hydrates tasks/task-types/task-lists/collaborators/\n // app-link/capabilities unconditionally on mount — 5-6 requests, one 6.8s\n // cold, even when the panel is never opened (nav-latency-report.md Table 2).\n // Gate those specific adapter methods behind the panel's FIRST open; the\n // launcher button (`ChromeDevNotesMenu` below) still renders and responds\n // instantly, it just flips `activate()` on pointerdown before its own click\n // handler runs. `fetchUnreadCounts` (the launcher badge count) is exempt\n // from the open-gate — it still needs a number before the user opens\n // anything — but its first call is pushed off the boot path onto\n // requestIdleCallback so it never competes with first paint.\n const activatedRef = useRef(false)\n const activationWaitersRef = useRef<Array<() => void>>([])\n const activate = useCallback(() => {\n if (activatedRef.current) return\n activatedRef.current = true\n const waiters = activationWaitersRef.current\n activationWaitersRef.current = []\n waiters.forEach((resolve) => resolve())\n }, [])\n const waitForActivation = useCallback((): Promise<void> => {\n if (activatedRef.current) return Promise.resolve()\n return new Promise((resolve) => {\n activationWaitersRef.current.push(resolve)\n })\n }, [])\n\n const lazyAdapter = useMemo<typeof adapter>(() => {\n const GATED_METHODS = [\n 'fetchTasks',\n 'fetchTaskTypes',\n 'fetchTaskLists',\n 'fetchCollaborators',\n 'fetchCapabilities',\n 'getAppLinkStatus',\n 'fetchBugReports',\n 'fetchBugReportTypes',\n ] as const\n const wrapped: Record<string, unknown> = { ...adapter }\n for (const method of GATED_METHODS) {\n const original = (adapter[method] as (...args: unknown[]) => Promise<unknown>).bind(adapter)\n wrapped[method] = (...args: unknown[]) => waitForActivation().then(() => original(...args))\n }\n let idleScheduled = false\n const originalUnreadCounts = adapter.fetchUnreadCounts.bind(adapter)\n wrapped.fetchUnreadCounts = () => {\n if (idleScheduled || typeof window === 'undefined') return originalUnreadCounts()\n idleScheduled = true\n return new Promise((resolve, reject) => {\n const run = () => originalUnreadCounts().then(resolve, reject)\n const ric = (window as { requestIdleCallback?: (cb: () => void) => number })\n .requestIdleCallback\n if (ric) ric(run)\n else setTimeout(run, 0)\n })\n }\n return wrapped as unknown as typeof adapter\n }, [adapter, waitForActivation])\n\n // The app brought its own provider — mount only the surface, so a second\n // DevNotesProvider never shadows the app's adapter. (The app's own adapter\n // is out of this chrome's control, so the open-gate above does not apply.)\n if (devNotes?.providedByApp) return <DevNotesSurface activate={activate}>{children}</DevNotesSurface>\n\n return (\n <DevNotesProvider adapter={lazyAdapter} user={user} config={config}>\n <DevNotesSurface activate={activate}>{children}</DevNotesSurface>\n </DevNotesProvider>\n )\n}\n\n// \"View All Tasks\" is triggered from the menu in the top bar but the modal has\n// to render at the chrome ROOT, or it would be trapped inside the top bar's\n// stacking/blur context. The menu publishes the request through this context.\nconst DevNotesTasksContext = createContext<{\n ready: boolean\n openTasks: () => void\n activate: () => void\n}>({\n ready: false,\n openTasks: () => {},\n activate: () => {},\n})\n\n/**\n * The DevNotes working surface, mounted once at the chrome root.\n *\n * `<DevNotesMenu>` only TOGGLES creation mode — `<DevNotesOverlay>` is what\n * renders the click-to-place capture layer, the report dots and the report\n * form. The shell shipped the provider and the menu but never the overlay, so\n * on every app that used this chrome (forms / surveys / polls) \"Create Task\"\n * closed the menu and did nothing at all: the mode flipped on with nothing\n * listening (HITL bug report 2026-07-23). Contacts didn't hit it only because\n * it still had its own hand-rolled surface.\n */\nfunction DevNotesSurface({\n activate,\n children,\n}: {\n /** Flips the DevNotes data adapter open for the first time (no-op after). */\n activate: () => void\n children: ReactNode\n}) {\n const [tasksOpen, setTasksOpen] = useState(false)\n const openTasks = useCallback(() => {\n activate()\n setTasksOpen(true)\n }, [activate])\n const tasksCtx = useMemo(() => ({ ready: true, openTasks, activate }), [openTasks, activate])\n\n return (\n <DevNotesTasksContext.Provider value={tasksCtx}>\n {children}\n {/* Mounted only while open: the modal loads data on mount regardless of\n its `open` prop, so keeping it unmounted avoids fetching every user's\n tasks before they ask for them. */}\n {tasksOpen ? <DevNotesTaskListModal open onClose={() => setTasksOpen(false)} /> : null}\n <DevNotesOverlay />\n </DevNotesTasksContext.Provider>\n )\n}\n\n/**\n * The app-chrome root. Wrap the authenticated frame once:\n *\n * <PolitogyAppChrome storagePrefix=\"forms\" identity={{userId, userName, email, role}}>\n * <ShellFrame …/>\n * </PolitogyAppChrome>\n */\nexport function PolitogyAppChrome({\n storagePrefix,\n proxyBasePath = '/api/chrome',\n fetchJson: fetchJsonOverride,\n notificationsAdapter,\n devNotes,\n org,\n tokenOrg,\n identity,\n children,\n}: {\n storagePrefix: string\n proxyBasePath?: string\n /**\n * Override the same-origin proxy fetcher for apps that talk to the chrome\n * API directly with their own auth (Contacts sends a client-side Bearer).\n * Paths stay relative ('orgs', 'me', …) — the override owns base + auth.\n */\n fetchJson?: NavChromeFetcher\n /**\n * The bell's feed adapter. Omitted: the comms feed over the same proxy.\n * `null`: the legacy contacts-shaped feed. See NotificationsAdapter.\n */\n notificationsAdapter?: NotificationsAdapter | null\n /** DevNotes wiring override for direct-auth apps (Contacts). */\n devNotes?: ChromeDevNotesConfig\n /** Controlled org state — the app owns active-org + switching (Contacts). */\n org?: ControlledOrgState\n /** Auth-owned active org from verified token claims (v2). Wins over `org`. */\n tokenOrg?: TokenOrgState\n identity: ChromeIdentity\n children: ReactNode\n}) {\n const proxyFetchJson = useMemo<NavChromeFetcher>(\n () =>\n async (path, init) => {\n const res = await fetch(`${proxyBasePath}/${path}`, {\n method: init?.method ?? 'GET',\n headers: init?.headers,\n body: init?.body,\n })\n if (!res.ok) throw new Error(`chrome ${path}: ${res.status}`)\n if (res.status === 204) return null\n const text = await res.text()\n return text ? JSON.parse(text) : null\n },\n [proxyBasePath],\n )\n const fetchJson = fetchJsonOverride ?? proxyFetchJson\n const devNotesTree = (\n <AppDevNotes\n storagePrefix={storagePrefix}\n proxyBasePath={proxyBasePath}\n devNotes={devNotes}\n identity={identity}\n >\n {children}\n </AppDevNotes>\n )\n\n return (\n <NavChromeProvider fetchJson={fetchJson} notificationsAdapter={notificationsAdapter}>\n {tokenOrg ? (\n <TokenChromeStateProvider tokenOrg={tokenOrg}>{devNotesTree}</TokenChromeStateProvider>\n ) : (\n <ChromeStateProvider controlledOrg={org}>{devNotesTree}</ChromeStateProvider>\n )}\n </NavChromeProvider>\n )\n}\n\n/** The standard top-bar action cluster — Reference/UI-Platform v30 \"Top bar\":\n * Search | Dev notes | Credits | Notifications | Help (farthest right). The\n * Navigation Display switcher moved into the account menu (0.68.0); the Spec\n * overlay slot still renders between Credits and Notifications when the\n * signed-in user is allowed it (it draws nothing otherwise). */\nexport function ChromeTopBarActions() {\n const state = useChromeState()\n if (!state) return null\n // Org-scoped widgets read only once the org list settled: before that the\n // boot org (stored/URL) can still be replaced, and each change was a second\n // fuel-status / notifications request on the same page load.\n const settledOrgId = state.orgsLoading ? null : state.orgId\n return (\n <>\n <TopBarWidgetSlot\n title=\"DevNotes\"\n description=\"Capture bugs and notes, filed straight to Forge.\"\n >\n <ChromeDevNotesMenu />\n </TopBarWidgetSlot>\n <FuelAction orgId={settledOrgId} />\n <SpecOverlayAction orgId={state.orgId} orgName={state.orgs.find((o) => o.id === state.orgId)?.name ?? null} />\n <NotificationsAction orgId={settledOrgId} />\n <SupportAction orgId={state.orgId} orgs={state.orgs.length ? state.orgs : undefined} />\n </>\n )\n}\n\n/**\n * The DevNotes launcher. Renders nothing until the surface above is mounted, so\n * it never touches DevNotes context before the provider exists, and forwards\n * \"View All Tasks\" to the root-level modal.\n */\nfunction ChromeDevNotesMenu() {\n const { ready, openTasks, activate } = useContext(DevNotesTasksContext)\n if (!ready) return null\n // `onPointerDownCapture` fires before DevNotesMenu's own click handler, so\n // the adapter is already unblocked by the time the menu's first \"Create\n // Task\" click reaches it. `display: contents` keeps the wrapper out of\n // layout entirely — the launcher renders exactly as before.\n return (\n <span style={{ display: 'contents' }} onPointerDownCapture={activate} onFocusCapture={activate} onKeyDownCapture={activate}>\n <DevNotesMenu position=\"top-right\" icon={LuNotebookPen} onViewTasks={openTasks} />\n </span>\n )\n}\n\n/** True when any core-org membership carries a super-admin tier. */\nexport function useIsSuperAdmin(): boolean {\n const state = useChromeState()\n return (state?.orgs ?? []).some((o) => /super/i.test(o.rawRole ?? ''))\n}\n\nconst FOOTER_LINKS: NavFooterLink[] = [\n { label: 'Privacy', href: `${CORE_BASE_URL}/privacy-policy`, external: true },\n { label: 'Terms', href: `${CORE_BASE_URL}/terms-and-conditions`, external: true },\n {\n label: 'Subscriptions',\n href: 'https://politogyvrm.com/subscription-cancellation-policy',\n external: true,\n },\n]\n\n/**\n * Sidebar footer: legal links AND build metadata (env / commit / version /\n * date / author) for every user. Reference/UI-Platform \"Left bar — required\n * elements\" lists Meta unconditionally — it carries no Super Administrator\n * gate. Gating it here (pre-2026-09-30) silently dropped the whole Meta row\n * for every non-admin viewer, which is exactly the \"Left Nav not adhering to\n * UI/UX rules\" violation DevNotes 83a4713 filed against Contacts. Pass the\n * app's build-time metadata in; it now always reaches the rail.\n */\nexport function useChromeFooter(meta: {\n envLabel?: string\n version?: string\n commit?: string\n commitDate?: string\n commitAuthor?: string\n}): NavFooter {\n return useMemo<NavFooter>(\n () => ({ links: FOOTER_LINKS, ...meta }),\n [meta.envLabel, meta.version, meta.commit, meta.commitDate, meta.commitAuthor],\n )\n}\n\n// ---------------------------------------------------------------------------\n// Identity — resolved by the PACKAGE, from the chrome API.\n//\n// Apps used to pass a display name straight from their own session claims, and\n// forms passed `user.name ?? user.email` — so a user with no name set had their\n// EMAIL rendered as their name, and the chrome API's real profile name could\n// never win (HITL 2026-07-23). The chrome API is the authority; what the app\n// passes is a pre-hydration fallback only, and an email is never a name.\n// ---------------------------------------------------------------------------\n\nexport function useChromeIdentity(fallback?: {\n userName?: string | null\n email?: string | null\n}): ResolvedIdentity {\n const { me, loaded } = useChromeMe()\n return resolveIdentity({\n apiName: me?.userName,\n fallbackName: fallback?.userName,\n email: fallback?.email,\n avatarUrl: me?.avatarUrl,\n loaded,\n })\n}\n\n// Breadcrumbs live in ../lib/breadcrumbs (pure, dependency-free) and are\n// re-exported here so apps keep a single import surface.\nexport { deriveBreadcrumbs } from '../lib/breadcrumbs'\nexport { looksLikeEmail, resolveIdentity, type ResolvedIdentity } from '../lib/identity'\nimport { resolveIdentity, type ResolvedIdentity } from '../lib/identity'\n\n// ---------------------------------------------------------------------------\n// Breadcrumbs — derived by the PACKAGE from the nav tree + the current path.\n//\n// Every app hand-built its own trail, so they disagreed: forms rendered\n// \"Forms › Dashboard\" while polls rendered \"Polls\" under a \"Polls\" title\n// (\"Polls / Polls\"). The standard is Dashboard › Sub › Item (HITL 2026-07-23),\n// derived from the same nav tree the sidebar renders, so no app can drift.\n// ---------------------------------------------------------------------------\n\n/**\n * The My Account menu config — profile/org links into VRM core, real roles\n * from the user's core organizations and the signed-in account. No theme\n * control: the product is light only (Reference/UI-Platform).\n */\nexport function useChromeUserMenu({\n userId,\n userName,\n email,\n}: {\n userId: string\n userName: string | null\n email: string | null\n}): NavUserMenu {\n const state = useChromeState()\n const activeOrg = state?.orgs.find((o) => o.id === state.orgId) ?? null\n const orgSuffix = activeOrg ? `?org=${activeOrg.id}` : ''\n // Environment-aware: on a staging app these must point at the staging core,\n // not production (HITL: editing Profile from a staging app redirected to prod).\n const coreBase = getCoreBaseUrl()\n return {\n // My Profile is global — NOT org-suffixed (main-app ShellChromeBridge).\n myProfileHref: `${coreBase}/my-profile`,\n organizationSettingsHref: `${coreBase}/organization-settings${orgSuffix}`,\n roles: (state?.orgs ?? [])\n .filter((o) => o.rawRole || o.role)\n .map((o) => ({ role: (o.rawRole ?? o.role) as string, orgName: o.name })),\n accounts: [{ id: userId, name: userName, email, avatarUrl: null, active: true }],\n addAccountHref: `${coreBase}/my-profile#accounts`,\n // No theme control: the product is light only (Reference/UI-Platform\n // \"Theme — light only\"; shell 0.73.0 stopped applying dark). The account\n // menu rendered an \"Appearance\" radio with one option until 0.77.0.\n navDisplay: state ? { value: state.navDisplay, onChange: state.setNavDisplay } : undefined,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Mode selector — entitlement-driven (HITL 2026-07-23: an org with multiple\n// active modes selects them from the left nav). Entitlements come from the\n// chrome API: GET me with the active org header → modes booleans\n// {relationship, campaign, petition, polling}. Selecting a mode navigates to\n// that mode's VRM-core dashboard carrying the active org.\n// ---------------------------------------------------------------------------\n\nconst MODE_DEFS: {\n id: string\n label: string\n icon: NavIcon\n /** Absolute destination, or a VRM-core path prefixed with CORE_BASE_URL. */\n href: string\n orgQuery: boolean\n}[] = [\n {\n id: 'relationship',\n label: 'Relationship Mode',\n icon: LuContactRound,\n href: `${CORE_BASE_URL}/relationship/dashboard`,\n orgQuery: true,\n },\n {\n id: 'campaign',\n label: 'Campaign Mode',\n icon: LuMegaphone,\n href: `${CORE_BASE_URL}/campaign/dashboard`,\n orgQuery: true,\n },\n {\n // Petition Mode lives in its own standalone app on its own subdomain — the\n // petitions repo deploys production to petition-mode.politogyvrm.com.\n id: 'petition',\n label: 'Petition Mode',\n icon: LuFilePenLine,\n href: 'https://petition-mode.politogyvrm.com/',\n orgQuery: true,\n },\n]\n\ntype ModeId = 'relationship' | 'campaign' | 'petition'\n\ntype UseChromeModeArg =\n | ModeId\n | {\n /** Pre-entitlement fallback for first paint (default 'relationship'). */\n fallbackModeId?: ModeId\n /**\n * Registry-pinned mode for a MODE-SCOPED app (e.g. the Campaign apps\n * a2p / phonebank / canvass / signs, from `POLITOGY_APPS[app].mode`). The\n * pill DISPLAYS this mode regardless of the cross-app selection, so a\n * campaign app never shows a Relationship pill. The switcher still appears\n * when the active org is entitled to more than one mode, so the user can\n * jump out to another mode's home.\n */\n pinnedModeId?: ModeId\n }\n\n/**\n * The active mode pill / selector.\n *\n * For an UNSCOPED app the current mode is the USER'S OWN SELECTION (persisted\n * cross-app in localStorage under `vrm.activeMode`), narrowed to what the active\n * org is entitled to — never a literal an app hardcodes. Apps used to call\n * `useChromeMode('relationship')`, which pinned the pill to Relationship even\n * for an org entitled to Campaign or Petition (HITL 2026-07-23); the string\n * argument now only supplies the pre-entitlement fallback for first paint.\n *\n * A MODE-SCOPED app passes `{ pinnedModeId }` so its pill displays that mode\n * (its own mode from the app registry) rather than the cross-app selection —\n * while a multi-mode org still gets the switcher to leave.\n */\nexport function useChromeMode(arg: UseChromeModeArg = {}): NavMode {\n const { fallbackModeId = 'relationship', pinnedModeId } =\n typeof arg === 'string' ? { fallbackModeId: arg, pinnedModeId: undefined } : arg\n const ctx = useContext(ChromeStateContext)\n const dedupedFetch = useNavChromeDedupedFetch()\n const { me, loaded: meLoaded } = useChromeMe()\n const orgId = ctx?.orgId ?? null\n const [entitled, setEntitled] = useState<Record<string, boolean> | null>(null)\n const [selectedModeId, setSelectedModeId] = useState<string | null>(null)\n\n // Restore the user's last mode choice (shared key across every app).\n useEffect(() => {\n try {\n const stored = localStorage.getItem(MODE_STORAGE_KEY)\n if (stored && MODE_DEFS.some((m) => m.id === stored)) setSelectedModeId(stored)\n } catch {\n /* storage unavailable */\n }\n }, [])\n\n useEffect(() => {\n // Wait for the boot `me` so the reuse check below can decide.\n if (!dedupedFetch || !orgId || !meLoaded) return\n // The provider's boot `me` already carries `modes` for its resolved org:\n // reuse it instead of a second `me` call when that org is the active one.\n const bootMe = me as { account?: string | null; modes?: Record<string, boolean> | null } | null\n if (bootMe && bootMe.account === orgId && bootMe.modes !== undefined) {\n setEntitled(bootMe.modes ?? null)\n return\n }\n let cancelled = false\n dedupedFetch('me', { headers: { 'x-contacts-org': orgId } }, { orgId })\n .then((data) => {\n if (cancelled) return\n const modes = (data as { modes?: Record<string, boolean> | null })?.modes ?? null\n setEntitled(modes)\n })\n .catch(() => {\n /* entitlements unavailable — single-mode pill stands */\n })\n return () => {\n cancelled = true\n }\n }, [dedupedFetch, me, meLoaded, orgId])\n\n const options = MODE_DEFS.filter((m) => entitled?.[m.id])\n // Resolution order: a registry pin (mode-scoped app) wins outright → then the\n // user's selection (if the org is still entitled to it) → the first entitled\n // mode → the app's fallback. Entitlements are async, so before they land the\n // pin/fallback holds the pill's shape (no layout shift).\n const pinned = pinnedModeId ? MODE_DEFS.find((m) => m.id === pinnedModeId) ?? null : null\n const selected = selectedModeId\n ? options.find((m) => m.id === selectedModeId) ?? null\n : null\n const current =\n pinned ??\n selected ??\n options[0] ??\n MODE_DEFS.find((m) => m.id === fallbackModeId) ??\n MODE_DEFS[0]\n const suffix = orgId ? `?org=${orgId}` : ''\n\n return {\n label: current.label,\n icon: current.icon,\n // Left-Navigation §7 / Reference/UI-Platform: always the row of three icon\n // buttons. A mode the organization does not hold is shown dimmed and not\n // selectable, never hidden. Before entitlements land only the current mode\n // reads as available (no layout shift, nothing clickable it shouldn't be).\n options: MODE_DEFS.map((o) => ({\n id: o.id,\n label: o.label,\n icon: o.icon,\n available: entitled ? Boolean(entitled[o.id]) || o.id === current.id : o.id === current.id,\n })),\n onSelect:\n options.length > 0\n ? (id: string) => {\n const def = MODE_DEFS.find((m) => m.id === id)\n if (!def || !entitled?.[def.id]) return\n // Remember the choice BEFORE navigating so the destination app —\n // and every app after it — opens in the mode the user picked.\n setSelectedModeId(id)\n try {\n localStorage.setItem(MODE_STORAGE_KEY, id)\n } catch {\n /* storage unavailable */\n }\n // Env-aware: the two VRM-core dashboards are baked with the prod\n // base at module load; on a staging app rewrite it to the staging\n // core so a mode switch stays in staging (petition mode is a fully\n // absolute URL and is left untouched by the replace).\n const href = def.href.replace(CORE_BASE_URL, getCoreBaseUrl())\n const sep = href.includes('?') ? '&' : '?'\n window.location.assign(\n def.orgQuery && suffix ? `${href}${sep}${suffix.slice(1)}` : href,\n )\n }\n : undefined,\n }\n}\n\n// The one-component app frame (see ./frame.tsx). Re-exported here so apps have\n// a single import surface: `@the-portland-company/shell/app-chrome`.\nexport {\n PolitogyAppFrame,\n POLITOGY_APPS,\n type PolitogyAppKey,\n type PolitogyAppMode,\n type PolitogyAppSession,\n type PolitogyBuildMeta,\n type PolitogyFrameData,\n type PolitogyFrameGrant,\n type PolitogyGrantedFrame,\n} from './frame'\n\n// The boot-screen surface (Specs/Loading-Screen), mounted by PolitogyAppFrame.\n// Re-exported so an app with a real pipeline can type its `bootProgress` prop.\nexport { LoadingScreen, type BootProgress, type BootStageId, type BootPhase } from './loading-screen'\n"]}
|