@empoweredvote/ev-ui 0.6.1 → 0.6.3

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/dist/index.js CHANGED
@@ -82,6 +82,7 @@ __export(index_exports, {
82
82
  spacing: () => spacing,
83
83
  textStyles: () => textStyles,
84
84
  tierColors: () => tierColors,
85
+ useEvContextPromotion: () => useEvContextPromotion,
85
86
  useMediaQuery: () => useMediaQuery,
86
87
  zIndex: () => zIndex
87
88
  });
@@ -2967,6 +2968,94 @@ var evContext = {
2967
2968
  async clear() {
2968
2969
  return send({ type: "ev-context:clear" });
2969
2970
  },
2971
+ /**
2972
+ * Read the userId-stamped authed slice for the given user.
2973
+ *
2974
+ * Stored shape:
2975
+ * { compass?, address?, verdicts?, authed?: { userId, compass?, address?, verdicts? } }
2976
+ *
2977
+ * - Returns null if there is no stored value, no `authed` body, or the stored
2978
+ * `authed.userId` does not match the requested `userId` (mismatch = inert).
2979
+ * - Otherwise returns `{ compass, address, verdicts }` with undefined keys
2980
+ * omitted.
2981
+ *
2982
+ * Used by logged-in consumers to do SWR-style hydration: render this slice
2983
+ * synchronously on mount, then replace silently when the API responds.
2984
+ */
2985
+ async getAuthedSlice(userId) {
2986
+ if (!userId) return null;
2987
+ const current = await this.get();
2988
+ if (!current || !current.authed || typeof current.authed !== "object") return null;
2989
+ if (current.authed.userId !== userId) return null;
2990
+ const out = {};
2991
+ if (current.authed.compass !== void 0) out.compass = current.authed.compass;
2992
+ if (current.authed.address !== void 0) out.address = current.authed.address;
2993
+ if (current.authed.verdicts !== void 0) out.verdicts = current.authed.verdicts;
2994
+ if (current.authed.promotionDismissed !== void 0) {
2995
+ out.promotionDismissed = current.authed.promotionDismissed;
2996
+ }
2997
+ return out;
2998
+ },
2999
+ /**
3000
+ * Mirror an authed write into the userId-stamped `authed` slice.
3001
+ *
3002
+ * - `patch` may contain any subset of `{ compass, address, verdicts }`.
3003
+ * Unrecognized keys are dropped.
3004
+ * - If the existing `authed.userId` matches `userId`, the patch is merged
3005
+ * with the prior authed body (per-domain shallow merge — the patch's
3006
+ * compass/address/verdicts replace the prior values).
3007
+ * - If it does not match (user switch), the prior authed body is stomped.
3008
+ * - Guest top-level keys (compass, address, verdicts at the root) are
3009
+ * preserved untouched.
3010
+ *
3011
+ * Returns false on falsy `userId` or empty patch; otherwise returns the
3012
+ * underlying `set()` result.
3013
+ */
3014
+ async setAuthedSlice(userId, patch) {
3015
+ if (!userId) return false;
3016
+ if (!patch || typeof patch !== "object") return false;
3017
+ const allowed = {};
3018
+ if (patch.compass !== void 0) allowed.compass = patch.compass;
3019
+ if (patch.address !== void 0) allowed.address = patch.address;
3020
+ if (patch.verdicts !== void 0) allowed.verdicts = patch.verdicts;
3021
+ if (patch.promotionDismissed !== void 0) {
3022
+ allowed.promotionDismissed = patch.promotionDismissed;
3023
+ }
3024
+ if (Object.keys(allowed).length === 0) return false;
3025
+ const current = await this.get() || {};
3026
+ const priorAuthed = current.authed && current.authed.userId === userId ? current.authed : null;
3027
+ const nextAuthed = { userId };
3028
+ if (priorAuthed) {
3029
+ if (priorAuthed.compass !== void 0) nextAuthed.compass = priorAuthed.compass;
3030
+ if (priorAuthed.address !== void 0) nextAuthed.address = priorAuthed.address;
3031
+ if (priorAuthed.verdicts !== void 0) nextAuthed.verdicts = priorAuthed.verdicts;
3032
+ if (priorAuthed.promotionDismissed !== void 0) {
3033
+ nextAuthed.promotionDismissed = priorAuthed.promotionDismissed;
3034
+ }
3035
+ }
3036
+ if (allowed.compass !== void 0) nextAuthed.compass = allowed.compass;
3037
+ if (allowed.address !== void 0) nextAuthed.address = allowed.address;
3038
+ if (allowed.verdicts !== void 0) nextAuthed.verdicts = allowed.verdicts;
3039
+ if (allowed.promotionDismissed !== void 0 && allowed.promotionDismissed !== null && typeof allowed.promotionDismissed === "object") {
3040
+ const prior = priorAuthed && priorAuthed.promotionDismissed && typeof priorAuthed.promotionDismissed === "object" ? priorAuthed.promotionDismissed : {};
3041
+ nextAuthed.promotionDismissed = { ...prior, ...allowed.promotionDismissed };
3042
+ }
3043
+ return this.set({ ...current, authed: nextAuthed });
3044
+ },
3045
+ /**
3046
+ * Remove the `authed` slice entirely (preserving guest top-level keys).
3047
+ *
3048
+ * Provided for completeness — consumers in the v2026.4.5 wiring plan must
3049
+ * NOT call this on logout. The slice is intended to go inert via userId
3050
+ * mismatch, so a re-login as the same user can rehydrate from cache.
3051
+ */
3052
+ async clearAuthedSlice() {
3053
+ const current = await this.get();
3054
+ if (!current || typeof current !== "object") return true;
3055
+ if (!("authed" in current)) return true;
3056
+ const { authed: _omit, ...rest } = current;
3057
+ return this.set(rest);
3058
+ },
2970
3059
  /**
2971
3060
  * Subscribe to live updates. Fires when this tab or any other tab
2972
3061
  * (any subdomain) writes to the store. Returns an unsubscribe function.
@@ -5719,15 +5808,174 @@ function computeTierCoverage(topics) {
5719
5808
  return counts;
5720
5809
  }
5721
5810
 
5811
+ // src/useEvContextPromotion.js
5812
+ var import_react31 = require("react");
5813
+ function useEvContextPromotion({
5814
+ domain,
5815
+ isLoggedIn,
5816
+ userId,
5817
+ apiData,
5818
+ apiWriter,
5819
+ enabled = true
5820
+ }) {
5821
+ const [shouldPrompt, setShouldPrompt] = (0, import_react31.useState)(false);
5822
+ const [payload, setPayload] = (0, import_react31.useState)(null);
5823
+ const [status, setStatus] = (0, import_react31.useState)("idle");
5824
+ const [error, setError] = (0, import_react31.useState)(null);
5825
+ const apiDataRef = (0, import_react31.useRef)(apiData);
5826
+ apiDataRef.current = apiData;
5827
+ const userIdRef = (0, import_react31.useRef)(userId);
5828
+ userIdRef.current = userId;
5829
+ const isLoggedInRef = (0, import_react31.useRef)(isLoggedIn);
5830
+ isLoggedInRef.current = isLoggedIn;
5831
+ const enabledRef = (0, import_react31.useRef)(enabled);
5832
+ enabledRef.current = enabled;
5833
+ const domainRef = (0, import_react31.useRef)(domain);
5834
+ domainRef.current = domain;
5835
+ const apiWriterRef = (0, import_react31.useRef)(apiWriter);
5836
+ apiWriterRef.current = apiWriter;
5837
+ const detect = (0, import_react31.useCallback)(async () => {
5838
+ const _enabled = enabledRef.current;
5839
+ const _isLoggedIn = isLoggedInRef.current;
5840
+ const _userId = userIdRef.current;
5841
+ const _apiData = apiDataRef.current;
5842
+ const _domain = domainRef.current;
5843
+ if (!_enabled || !_isLoggedIn || !_userId) {
5844
+ setShouldPrompt(false);
5845
+ setPayload(null);
5846
+ return;
5847
+ }
5848
+ if (!isApiEmpty(_domain, _apiData)) {
5849
+ setShouldPrompt(false);
5850
+ setPayload(null);
5851
+ return;
5852
+ }
5853
+ try {
5854
+ const slice = await evContext.getAuthedSlice(_userId);
5855
+ if (slice && slice.promotionDismissed && slice.promotionDismissed[_domain] === true) {
5856
+ setShouldPrompt(false);
5857
+ setPayload(null);
5858
+ return;
5859
+ }
5860
+ } catch {
5861
+ }
5862
+ let guest = null;
5863
+ try {
5864
+ guest = await evContext.get();
5865
+ } catch {
5866
+ guest = null;
5867
+ }
5868
+ if (isGuestPopulated(_domain, guest)) {
5869
+ setShouldPrompt(true);
5870
+ setPayload(guest[_domain]);
5871
+ } else {
5872
+ setShouldPrompt(false);
5873
+ setPayload(null);
5874
+ }
5875
+ }, []);
5876
+ (0, import_react31.useEffect)(() => {
5877
+ detect();
5878
+ }, [detect, isLoggedIn, userId, apiData, enabled, domain]);
5879
+ (0, import_react31.useEffect)(() => {
5880
+ const unsub = evContext.subscribe(() => {
5881
+ detect();
5882
+ });
5883
+ return unsub;
5884
+ }, [detect]);
5885
+ const promote = (0, import_react31.useCallback)(async () => {
5886
+ const _userId = userIdRef.current;
5887
+ const _domain = domainRef.current;
5888
+ const _writer = apiWriterRef.current;
5889
+ const _payload = payload;
5890
+ if (!_userId || !_payload || typeof _writer !== "function") return;
5891
+ setStatus("saving");
5892
+ setError(null);
5893
+ try {
5894
+ await _writer(_payload);
5895
+ try {
5896
+ await evContext.setAuthedSlice(_userId, { [_domain]: _payload });
5897
+ } catch {
5898
+ }
5899
+ try {
5900
+ await evContext.setAuthedSlice(_userId, {
5901
+ promotionDismissed: { [_domain]: false }
5902
+ });
5903
+ } catch {
5904
+ }
5905
+ setStatus("saved");
5906
+ setShouldPrompt(false);
5907
+ } catch (err) {
5908
+ setStatus("error");
5909
+ setError(err instanceof Error ? err : new Error(String(err)));
5910
+ }
5911
+ }, [payload]);
5912
+ const dismiss = (0, import_react31.useCallback)(async () => {
5913
+ const _userId = userIdRef.current;
5914
+ const _domain = domainRef.current;
5915
+ if (!_userId) return;
5916
+ try {
5917
+ await evContext.setAuthedSlice(_userId, {
5918
+ promotionDismissed: { [_domain]: true }
5919
+ });
5920
+ } catch {
5921
+ }
5922
+ setShouldPrompt(false);
5923
+ }, []);
5924
+ return { shouldPrompt, payload, promote, dismiss, status, error };
5925
+ }
5926
+ function isApiEmpty(domain, apiData) {
5927
+ if (apiData === null || apiData === void 0) return true;
5928
+ if (domain === "compass") {
5929
+ if (typeof apiData !== "object") return false;
5930
+ if (Array.isArray(apiData)) return apiData.length === 0;
5931
+ if (apiData.answers && typeof apiData.answers === "object") {
5932
+ return Object.keys(apiData.answers).length === 0;
5933
+ }
5934
+ return Object.keys(apiData).length === 0;
5935
+ }
5936
+ if (domain === "address") {
5937
+ if (typeof apiData === "string") return apiData.trim().length === 0;
5938
+ if (typeof apiData !== "object") return false;
5939
+ const a = apiData;
5940
+ const hasAddr = typeof a.formatted === "string" && a.formatted.length > 0;
5941
+ const hasAddrAlt = typeof a.addr === "string" && a.addr.length > 0;
5942
+ const hasLat = typeof a.lat === "number" || typeof a.latitude === "number";
5943
+ return !(hasAddr || hasAddrAlt || hasLat);
5944
+ }
5945
+ if (domain === "verdicts") {
5946
+ if (typeof apiData !== "object") return false;
5947
+ if (Array.isArray(apiData)) return apiData.length === 0;
5948
+ return Object.keys(apiData).length === 0;
5949
+ }
5950
+ return false;
5951
+ }
5952
+ function isGuestPopulated(domain, fullEvContext) {
5953
+ if (!fullEvContext || typeof fullEvContext !== "object") return false;
5954
+ const slice = fullEvContext[domain];
5955
+ if (!slice || typeof slice !== "object") return false;
5956
+ if (domain === "compass") {
5957
+ const ans = slice.answers || slice.a;
5958
+ if (ans && typeof ans === "object") return Object.keys(ans).length > 0;
5959
+ return false;
5960
+ }
5961
+ if (domain === "address") {
5962
+ return typeof slice.formatted === "string" && slice.formatted.length > 0 || typeof slice.addr === "string" && slice.addr.length > 0;
5963
+ }
5964
+ if (domain === "verdicts") {
5965
+ return Object.keys(slice).length > 0;
5966
+ }
5967
+ return false;
5968
+ }
5969
+
5722
5970
  // src/StanceAccordion.jsx
5723
- var import_react32 = __toESM(require("react"));
5971
+ var import_react33 = __toESM(require("react"));
5724
5972
 
5725
5973
  // src/Favicon.jsx
5726
- var import_react31 = __toESM(require("react"));
5974
+ var import_react32 = __toESM(require("react"));
5727
5975
  function Favicon({ url, size = 16 }) {
5728
5976
  try {
5729
5977
  const domain = new URL(url).hostname;
5730
- return /* @__PURE__ */ import_react31.default.createElement(
5978
+ return /* @__PURE__ */ import_react32.default.createElement(
5731
5979
  "img",
5732
5980
  {
5733
5981
  src: `https://www.google.com/s2/favicons?sz=${size}&domain=${domain}`,
@@ -5738,7 +5986,7 @@ function Favicon({ url, size = 16 }) {
5738
5986
  }
5739
5987
  );
5740
5988
  } catch {
5741
- return /* @__PURE__ */ import_react31.default.createElement(
5989
+ return /* @__PURE__ */ import_react32.default.createElement(
5742
5990
  "svg",
5743
5991
  {
5744
5992
  width: size,
@@ -5749,8 +5997,8 @@ function Favicon({ url, size = 16 }) {
5749
5997
  strokeWidth: "1.5",
5750
5998
  style: { verticalAlign: "middle", flexShrink: 0 }
5751
5999
  },
5752
- /* @__PURE__ */ import_react31.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
5753
- /* @__PURE__ */ import_react31.default.createElement("path", { d: "M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
6000
+ /* @__PURE__ */ import_react32.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
6001
+ /* @__PURE__ */ import_react32.default.createElement("path", { d: "M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
5754
6002
  );
5755
6003
  }
5756
6004
  }
@@ -5781,11 +6029,11 @@ function StanceAccordion({
5781
6029
  apiUrl = "https://api.empowered.vote"
5782
6030
  }) {
5783
6031
  var _a;
5784
- const [expandedTopicId, setExpandedTopicId] = (0, import_react32.useState)(null);
5785
- const [loadingId, setLoadingId] = (0, import_react32.useState)(null);
5786
- const [showAll, setShowAll] = (0, import_react32.useState)(false);
5787
- const contextCache = (0, import_react32.useRef)(/* @__PURE__ */ new Map());
5788
- const quotesCache = (0, import_react32.useRef)(null);
6032
+ const [expandedTopicId, setExpandedTopicId] = (0, import_react33.useState)(null);
6033
+ const [loadingId, setLoadingId] = (0, import_react33.useState)(null);
6034
+ const [showAll, setShowAll] = (0, import_react33.useState)(false);
6035
+ const contextCache = (0, import_react33.useRef)(/* @__PURE__ */ new Map());
6036
+ const quotesCache = (0, import_react33.useRef)(null);
5789
6037
  const polAnswerMap = {};
5790
6038
  if (polAnswers) {
5791
6039
  polAnswers.forEach((a) => {
@@ -5844,7 +6092,7 @@ function StanceAccordion({
5844
6092
  quotesCache.current = [];
5845
6093
  }
5846
6094
  }
5847
- const handleToggle = (0, import_react32.useCallback)(
6095
+ const handleToggle = (0, import_react33.useCallback)(
5848
6096
  async (topicId) => {
5849
6097
  if (expandedTopicId === topicId) {
5850
6098
  setExpandedTopicId(null);
@@ -5861,7 +6109,7 @@ function StanceAccordion({
5861
6109
  },
5862
6110
  [expandedTopicId, politicianId, apiUrl]
5863
6111
  );
5864
- (0, import_react32.useEffect)(() => {
6112
+ (0, import_react33.useEffect)(() => {
5865
6113
  if (initialExpandedTopicId && topics && topics.length > 0) {
5866
6114
  handleToggle(String(initialExpandedTopicId));
5867
6115
  }
@@ -5877,13 +6125,13 @@ function StanceAccordion({
5877
6125
  visibleTopics = [pinned, ...baseTopics.filter((t) => String(t.id) !== String(initialExpandedTopicId))];
5878
6126
  }
5879
6127
  }
5880
- return /* @__PURE__ */ import_react32.default.createElement(
6128
+ return /* @__PURE__ */ import_react33.default.createElement(
5881
6129
  "div",
5882
6130
  {
5883
6131
  className: "flex flex-col",
5884
6132
  style: { fontFamily: "'Manrope', sans-serif" }
5885
6133
  },
5886
- /* @__PURE__ */ import_react32.default.createElement(
6134
+ /* @__PURE__ */ import_react33.default.createElement(
5887
6135
  "h3",
5888
6136
  {
5889
6137
  className: "text-sm font-semibold text-neutral-400 uppercase tracking-wider mb-2",
@@ -5905,15 +6153,15 @@ function StanceAccordion({
5905
6153
  if (topic.topic_key) return q.issue === topic.topic_key;
5906
6154
  return topic.short_title && q.issue.toLowerCase() === topic.short_title.toLowerCase();
5907
6155
  }) : [];
5908
- return /* @__PURE__ */ import_react32.default.createElement("div", { key: topicId, className: "border-b border-neutral-100" }, /* @__PURE__ */ import_react32.default.createElement(
6156
+ return /* @__PURE__ */ import_react33.default.createElement("div", { key: topicId, className: "border-b border-neutral-100" }, /* @__PURE__ */ import_react33.default.createElement(
5909
6157
  "button",
5910
6158
  {
5911
6159
  type: "button",
5912
6160
  onClick: () => handleToggle(topicId),
5913
6161
  className: "w-full flex items-center justify-between py-3 px-2 text-left cursor-pointer hover:bg-neutral-50 transition-colors"
5914
6162
  },
5915
- /* @__PURE__ */ import_react32.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react32.default.createElement("span", { className: "text-sm font-medium text-neutral-800 truncate" }, topic.short_title), questionText && /* @__PURE__ */ import_react32.default.createElement("span", { className: "text-xs text-neutral-400 mt-0.5" }, questionText), /* @__PURE__ */ import_react32.default.createElement("span", { className: "text-xs text-neutral-500 mt-0.5" }, label)),
5916
- /* @__PURE__ */ import_react32.default.createElement(
6163
+ /* @__PURE__ */ import_react33.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react33.default.createElement("span", { className: "text-sm font-medium text-neutral-800 truncate" }, topic.short_title), questionText && /* @__PURE__ */ import_react33.default.createElement("span", { className: "text-xs text-neutral-400 mt-0.5" }, questionText), /* @__PURE__ */ import_react33.default.createElement("span", { className: "text-xs text-neutral-500 mt-0.5" }, label)),
6164
+ /* @__PURE__ */ import_react33.default.createElement(
5917
6165
  "svg",
5918
6166
  {
5919
6167
  width: "16",
@@ -5930,9 +6178,9 @@ function StanceAccordion({
5930
6178
  transition: "transform 0.2s ease"
5931
6179
  }
5932
6180
  },
5933
- /* @__PURE__ */ import_react32.default.createElement("polyline", { points: "9 18 15 12 9 6" })
6181
+ /* @__PURE__ */ import_react33.default.createElement("polyline", { points: "9 18 15 12 9 6" })
5934
6182
  )
5935
- ), /* @__PURE__ */ import_react32.default.createElement(
6183
+ ), /* @__PURE__ */ import_react33.default.createElement(
5936
6184
  "div",
5937
6185
  {
5938
6186
  style: {
@@ -5941,7 +6189,7 @@ function StanceAccordion({
5941
6189
  transition: "grid-template-rows 0.25s ease"
5942
6190
  }
5943
6191
  },
5944
- /* @__PURE__ */ import_react32.default.createElement("div", { style: { overflow: "hidden" } }, /* @__PURE__ */ import_react32.default.createElement("div", { className: "px-2 pb-4" }, isLoading && /* @__PURE__ */ import_react32.default.createElement("div", { className: "flex items-center py-3" }, /* @__PURE__ */ import_react32.default.createElement(
6192
+ /* @__PURE__ */ import_react33.default.createElement("div", { style: { overflow: "hidden" } }, /* @__PURE__ */ import_react33.default.createElement("div", { className: "px-2 pb-4" }, isLoading && /* @__PURE__ */ import_react33.default.createElement("div", { className: "flex items-center py-3" }, /* @__PURE__ */ import_react33.default.createElement(
5945
6193
  "div",
5946
6194
  {
5947
6195
  style: {
@@ -5953,14 +6201,14 @@ function StanceAccordion({
5953
6201
  animation: "ev-spin 0.8s linear infinite"
5954
6202
  }
5955
6203
  }
5956
- )), !isLoading && cached && /* @__PURE__ */ import_react32.default.createElement(import_react32.default.Fragment, null, cached.reasoning ? /* @__PURE__ */ import_react32.default.createElement(
6204
+ )), !isLoading && cached && /* @__PURE__ */ import_react33.default.createElement(import_react33.default.Fragment, null, cached.reasoning ? /* @__PURE__ */ import_react33.default.createElement(
5957
6205
  "p",
5958
6206
  {
5959
6207
  className: "text-sm text-neutral-700 mb-3",
5960
6208
  style: { whiteSpace: "pre-wrap", lineHeight: 1.6 }
5961
6209
  },
5962
6210
  cached.reasoning
5963
- ) : null, cached.sources && cached.sources.length > 0 && /* @__PURE__ */ import_react32.default.createElement("div", { className: "mt-2" }, /* @__PURE__ */ import_react32.default.createElement("p", { className: "text-xs font-semibold text-neutral-500 uppercase tracking-wider mb-1.5" }, "References"), /* @__PURE__ */ import_react32.default.createElement("ol", { className: "list-decimal list-inside space-y-1" }, cached.sources.map((src, i) => /* @__PURE__ */ import_react32.default.createElement("li", { key: i, className: "text-xs text-neutral-600" }, /* @__PURE__ */ import_react32.default.createElement(
6211
+ ) : null, cached.sources && cached.sources.length > 0 && /* @__PURE__ */ import_react33.default.createElement("div", { className: "mt-2" }, /* @__PURE__ */ import_react33.default.createElement("p", { className: "text-xs font-semibold text-neutral-500 uppercase tracking-wider mb-1.5" }, "References"), /* @__PURE__ */ import_react33.default.createElement("ol", { className: "list-decimal list-inside space-y-1" }, cached.sources.map((src, i) => /* @__PURE__ */ import_react33.default.createElement("li", { key: i, className: "text-xs text-neutral-600" }, /* @__PURE__ */ import_react33.default.createElement(
5964
6212
  "a",
5965
6213
  {
5966
6214
  href: src,
@@ -5968,9 +6216,9 @@ function StanceAccordion({
5968
6216
  rel: "noreferrer",
5969
6217
  className: "inline-flex items-center gap-1.5 hover:text-[#00657c] transition-colors"
5970
6218
  },
5971
- /* @__PURE__ */ import_react32.default.createElement(Favicon, { url: src }),
5972
- /* @__PURE__ */ import_react32.default.createElement("span", { className: "underline underline-offset-2" }, getDisplayUrl(src))
5973
- ))))), topicQuotes.length > 0 && /* @__PURE__ */ import_react32.default.createElement("div", { style: { marginTop: "12px" } }, /* @__PURE__ */ import_react32.default.createElement(
6219
+ /* @__PURE__ */ import_react33.default.createElement(Favicon, { url: src }),
6220
+ /* @__PURE__ */ import_react33.default.createElement("span", { className: "underline underline-offset-2" }, getDisplayUrl(src))
6221
+ ))))), topicQuotes.length > 0 && /* @__PURE__ */ import_react33.default.createElement("div", { style: { marginTop: "12px" } }, /* @__PURE__ */ import_react33.default.createElement(
5974
6222
  "p",
5975
6223
  {
5976
6224
  style: {
@@ -5987,7 +6235,7 @@ function StanceAccordion({
5987
6235
  const verdict = verdictsByQuote ? verdictsByQuote[quote.id] : void 0;
5988
6236
  const borderColor = verdict === "agreed" ? "#0e7490" : verdict === "disagreed" ? "#b45309" : "#e2e8f0";
5989
6237
  const sourceName = quote.source_name || quote.sourceName;
5990
- return /* @__PURE__ */ import_react32.default.createElement(
6238
+ return /* @__PURE__ */ import_react33.default.createElement(
5991
6239
  "div",
5992
6240
  {
5993
6241
  key: quote.id,
@@ -5999,7 +6247,7 @@ function StanceAccordion({
5999
6247
  marginBottom: "8px"
6000
6248
  }
6001
6249
  },
6002
- /* @__PURE__ */ import_react32.default.createElement(
6250
+ /* @__PURE__ */ import_react33.default.createElement(
6003
6251
  "p",
6004
6252
  {
6005
6253
  style: {
@@ -6012,7 +6260,7 @@ function StanceAccordion({
6012
6260
  },
6013
6261
  quote.text
6014
6262
  ),
6015
- verdict === "agreed" && /* @__PURE__ */ import_react32.default.createElement(
6263
+ verdict === "agreed" && /* @__PURE__ */ import_react33.default.createElement(
6016
6264
  "span",
6017
6265
  {
6018
6266
  style: {
@@ -6029,10 +6277,10 @@ function StanceAccordion({
6029
6277
  flexShrink: 0
6030
6278
  }
6031
6279
  },
6032
- /* @__PURE__ */ import_react32.default.createElement("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react32.default.createElement("path", { d: "M5 13l4 4L19 7" })),
6280
+ /* @__PURE__ */ import_react33.default.createElement("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react33.default.createElement("path", { d: "M5 13l4 4L19 7" })),
6033
6281
  "Agreed"
6034
6282
  ),
6035
- verdict === "disagreed" && /* @__PURE__ */ import_react32.default.createElement(
6283
+ verdict === "disagreed" && /* @__PURE__ */ import_react33.default.createElement(
6036
6284
  "span",
6037
6285
  {
6038
6286
  style: {
@@ -6049,10 +6297,10 @@ function StanceAccordion({
6049
6297
  flexShrink: 0
6050
6298
  }
6051
6299
  },
6052
- /* @__PURE__ */ import_react32.default.createElement("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react32.default.createElement("path", { d: "M6 18L18 6M6 6l12 12" })),
6300
+ /* @__PURE__ */ import_react33.default.createElement("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round" }, /* @__PURE__ */ import_react33.default.createElement("path", { d: "M6 18L18 6M6 6l12 12" })),
6053
6301
  "Disagreed"
6054
6302
  ),
6055
- sourceName && /* @__PURE__ */ import_react32.default.createElement(
6303
+ sourceName && /* @__PURE__ */ import_react33.default.createElement(
6056
6304
  "a",
6057
6305
  {
6058
6306
  href: quote.source_url || quote.sourceUrl,
@@ -6069,10 +6317,10 @@ function StanceAccordion({
6069
6317
  sourceName
6070
6318
  )
6071
6319
  );
6072
- })), !cached.reasoning && (!cached.sources || cached.sources.length === 0) && topicQuotes.length === 0 && /* @__PURE__ */ import_react32.default.createElement("p", { className: "text-sm text-neutral-400 italic py-2" }, "No detailed reasoning available for this topic."))))
6320
+ })), !cached.reasoning && (!cached.sources || cached.sources.length === 0) && topicQuotes.length === 0 && /* @__PURE__ */ import_react33.default.createElement("p", { className: "text-sm text-neutral-400 italic py-2" }, "No detailed reasoning available for this topic."))))
6073
6321
  ));
6074
6322
  }),
6075
- hasToggle && /* @__PURE__ */ import_react32.default.createElement(
6323
+ hasToggle && /* @__PURE__ */ import_react33.default.createElement(
6076
6324
  "button",
6077
6325
  {
6078
6326
  type: "button",
@@ -6139,6 +6387,7 @@ function StanceAccordion({
6139
6387
  spacing,
6140
6388
  textStyles,
6141
6389
  tierColors,
6390
+ useEvContextPromotion,
6142
6391
  useMediaQuery,
6143
6392
  zIndex
6144
6393
  });