@zerocost/sdk 0.15.0 → 0.17.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.
@@ -13,6 +13,7 @@ export interface ConsentUIResult {
13
13
  usageData: boolean;
14
14
  aiInteractions: boolean;
15
15
  }
16
+ export declare function injectStyles(theme: 'light' | 'dark' | 'auto'): void;
16
17
  export declare function showConsentUI(options: ConsentUIOptions): Promise<ConsentUIResult>;
17
18
  /** Remove any existing consent popup from the DOM */
18
19
  export declare function removeConsentUI(): void;
@@ -1,6 +1,4 @@
1
1
  export declare const ZEROCOST_DOMAINS: {
2
2
  MAIN: string;
3
- APP: string;
4
- DOCS: string;
5
3
  };
6
4
  export declare const ZEROCOST_BASE_URL: string;
package/dist/index.cjs CHANGED
@@ -30,9 +30,9 @@ module.exports = __toCommonJS(index_exports);
30
30
 
31
31
  // src/core/constants.ts
32
32
  var ZEROCOST_DOMAINS = {
33
- MAIN: "https://zerocost.lovable.app",
34
- APP: "https://app.zerocost.com",
35
- DOCS: "https://docs.zerocost.com"
33
+ MAIN: "https://zerocost.lovable.app"
34
+ //APP: 'https://app.zerocost.com',
35
+ //DOCS: 'https://docs.zerocost.com',
36
36
  };
37
37
  var ZEROCOST_BASE_URL = ZEROCOST_DOMAINS.MAIN;
38
38
 
@@ -150,6 +150,12 @@ var TrackModule = class {
150
150
 
151
151
  // src/core/widget-render.ts
152
152
  var SDK_WIDGET_REFRESH_MS = 2e4;
153
+ var CLOSE_ICON_SVG = `
154
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="width:100%;height:100%;">
155
+ <line x1="18" y1="6" x2="6" y2="18"></line>
156
+ <line x1="6" y1="6" x2="18" y2="18"></line>
157
+ </svg>
158
+ `;
153
159
  function escapeHtml(value) {
154
160
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
155
161
  }
@@ -203,7 +209,7 @@ function renderVideoWidget(ad, theme) {
203
209
  <div style="position:relative;width:200px;aspect-ratio:9/16;border-radius:16px;overflow:hidden;background:${palette.bg};border:1px solid rgba(255,255,255,0.12);box-shadow:0 20px 60px rgba(0,0,0,0.45);font-family:Space Grotesk,system-ui,sans-serif;">
204
210
  ${media}
205
211
  <div style="position:absolute;top:10px;right:10px;display:flex;gap:8px;z-index:3;">
206
- <button type="button" data-zc-close style="width:22px;height:22px;border:none;border-radius:999px;background:rgba(0,0,0,0.52);color:#fff;font-size:12px;cursor:pointer;">x</button>
212
+ <button type="button" data-zc-close style="width:24px;height:24px;padding:5px;border:none;border-radius:999px;background:rgba(0,0,0,0.52);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;">${CLOSE_ICON_SVG}</button>
207
213
  </div>
208
214
  <div style="position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,0.04) 0%,rgba(0,0,0,0.12) 35%,rgba(0,0,0,0.85) 100%);"></div>
209
215
  <div style="position:absolute;left:0;right:0;bottom:0;padding:14px;z-index:2;">
@@ -224,7 +230,7 @@ function renderTooltipWidget(ad, theme) {
224
230
  <span style="width:6px;height:6px;border-radius:999px;background:${palette.text};display:inline-block;"></span>
225
231
  Sponsored
226
232
  </div>
227
- <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};font-size:12px;cursor:pointer;padding:0;">x</button>
233
+ <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};width:16px;height:16px;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;">${CLOSE_ICON_SVG}</button>
228
234
  </div>
229
235
  <div style="margin-top:10px;color:${palette.text};font-size:13px;line-height:1.55;">
230
236
  ${escapeHtml(ad.description || ad.title)} <a href="${escapeHtml(ad.landing_url)}" target="_blank" rel="noreferrer noopener" data-zc-cta style="color:${palette.text};font-weight:700;text-decoration:underline;text-underline-offset:2px;">${escapeHtml(ad.cta_text || "Learn More")}</a>
@@ -241,7 +247,7 @@ function renderSponsoredCard(ad, theme) {
241
247
  <div style="padding:12px;">
242
248
  <div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
243
249
  <div style="display:inline-flex;align-items:center;padding:4px 6px;border-radius:999px;background:${palette.badgeBg};color:${palette.textFaint};font-size:9px;font-weight:700;letter-spacing:0.12em;text-transform:uppercase;">Sponsored</div>
244
- <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};font-size:12px;cursor:pointer;padding:0;">x</button>
250
+ <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};width:16px;height:16px;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;">${CLOSE_ICON_SVG}</button>
245
251
  </div>
246
252
  <div style="margin-top:10px;color:${palette.text};font-size:13px;font-weight:700;line-height:1.2;">${escapeHtml(ad.title)}</div>
247
253
  ${ad.description ? `<div style="margin-top:6px;color:${palette.textMuted};font-size:11px;line-height:1.35;">${escapeHtml(ad.description)}</div>` : ""}
@@ -257,7 +263,7 @@ function renderInlineText(ad, theme) {
257
263
  <div style="margin:10px 0;border-radius:14px;overflow:hidden;background:${palette.surface};border:1px solid ${palette.border};font-family:Space Grotesk,system-ui,sans-serif;">
258
264
  <div style="display:flex;align-items:center;justify-content:space-between;padding:9px 12px;border-bottom:1px solid ${palette.border};background:${palette.surfaceStrong};">
259
265
  <span style="color:${palette.textFaint};font-size:9px;font-weight:700;letter-spacing:0.12em;text-transform:uppercase;">Sponsored</span>
260
- <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};font-size:12px;cursor:pointer;padding:0;">x</button>
266
+ <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};width:16px;height:16px;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;">${CLOSE_ICON_SVG}</button>
261
267
  </div>
262
268
  <div style="padding:12px;display:flex;gap:10px;align-items:flex-start;">
263
269
  ${media}
@@ -286,15 +292,15 @@ function renderWidgetMarkup(ad, options) {
286
292
 
287
293
  // src/modules/widget.ts
288
294
  var POSITION_STYLES = {
289
- "bottom-right": "position:fixed;bottom:24px;right:24px;z-index:9999;",
295
+ "bottom-right": "position:fixed;bottom:24px;right:40px;z-index:9999;",
290
296
  "bottom-left": "position:fixed;bottom:24px;left:80px;z-index:9999;",
291
- "top-right": "position:fixed;top:24px;right:24px;z-index:9999;",
297
+ "top-right": "position:fixed;top:24px;right:40px;z-index:9999;",
292
298
  "top-left": "position:fixed;top:24px;left:24px;z-index:9999;",
293
299
  "bottom-center": "position:fixed;bottom:24px;left:50%;transform:translateX(-50%);z-index:9999;",
294
300
  "top-center": "position:fixed;top:24px;left:50%;transform:translateX(-50%);z-index:9999;",
295
301
  "center": "position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:9999;",
296
302
  "sidebar-left": "position:fixed;top:50%;left:24px;transform:translateY(-50%);z-index:9999;",
297
- "sidebar-right": "position:fixed;top:50%;right:24px;transform:translateY(-50%);z-index:9999;"
303
+ "sidebar-right": "position:fixed;top:50%;right:40px;transform:translateY(-50%);z-index:9999;"
298
304
  };
299
305
  var FORMAT_PRIORITY = ["video-widget", "tooltip-ad", "sponsored-card", "sidebar-display", "inline-text"];
300
306
  var AUTO_SLOT_ID = "zerocost-auto-slot";
@@ -1351,14 +1357,14 @@ function injectStyles(theme) {
1351
1357
  `;
1352
1358
  let themeRule;
1353
1359
  if (theme === "dark") {
1354
- themeRule = `.zc-consent-root { ${darkVars} }`;
1360
+ themeRule = `.zc-consent-root, .zc-settings-btn { ${darkVars} }`;
1355
1361
  } else if (theme === "light") {
1356
- themeRule = `.zc-consent-root { ${lightVars} }`;
1362
+ themeRule = `.zc-consent-root, .zc-settings-btn { ${lightVars} }`;
1357
1363
  } else {
1358
1364
  themeRule = `
1359
- .zc-consent-root { ${lightVars} }
1365
+ .zc-consent-root, .zc-settings-btn { ${lightVars} }
1360
1366
  @media (prefers-color-scheme: dark) {
1361
- .zc-consent-root { ${darkVars} }
1367
+ .zc-consent-root, .zc-settings-btn { ${darkVars} }
1362
1368
  }
1363
1369
  `;
1364
1370
  }
@@ -1723,28 +1729,28 @@ function showConsentUI(options) {
1723
1729
  "zc-toggle-ads",
1724
1730
  "Ads",
1725
1731
  "Contextual, non-intrusive ads. No cookies or browsing history used.",
1726
- `${zerocostBaseUrl}/consent/ads`,
1732
+ `${zerocostBaseUrl}/docs/ads`,
1727
1733
  defaults.ads
1728
1734
  ));
1729
1735
  toggles.appendChild(createToggleCard(
1730
1736
  "zc-toggle-usage",
1731
1737
  "Usage data",
1732
1738
  "Anonymized usage patterns. No personal information is shared.",
1733
- `${zerocostBaseUrl}/consent/usage-data`,
1739
+ `${zerocostBaseUrl}/docs/usage-data`,
1734
1740
  defaults.usageData
1735
1741
  ));
1736
1742
  toggles.appendChild(createToggleCard(
1737
1743
  "zc-toggle-ai",
1738
1744
  "AI interactions",
1739
1745
  "Anonymized conversation data used for AI research.",
1740
- `${zerocostBaseUrl}/consent/ai-interactions`,
1746
+ `${zerocostBaseUrl}/docs/ai-interactions`,
1741
1747
  defaults.aiInteractions
1742
1748
  ));
1743
1749
  card.appendChild(toggles);
1744
1750
  const footer = document.createElement("div");
1745
1751
  footer.className = "zc-consent-footer";
1746
1752
  const ppLink = document.createElement("a");
1747
- ppLink.href = privacyPolicyUrl || `${zerocostBaseUrl}/privacy`;
1753
+ ppLink.href = privacyPolicyUrl || `${zerocostBaseUrl}/docs/privacy`;
1748
1754
  ppLink.target = "_blank";
1749
1755
  ppLink.rel = "noopener noreferrer";
1750
1756
  ppLink.textContent = "Privacy Policy";
@@ -1754,7 +1760,7 @@ function showConsentUI(options) {
1754
1760
  sep1.textContent = "\xB7";
1755
1761
  footer.appendChild(sep1);
1756
1762
  const termsLink = document.createElement("a");
1757
- termsLink.href = `${zerocostBaseUrl}/terms`;
1763
+ termsLink.href = `${zerocostBaseUrl}/docs/terms`;
1758
1764
  termsLink.target = "_blank";
1759
1765
  termsLink.rel = "noopener noreferrer";
1760
1766
  termsLink.textContent = "Terms";
@@ -1764,7 +1770,7 @@ function showConsentUI(options) {
1764
1770
  sep2.textContent = "\xB7";
1765
1771
  footer.appendChild(sep2);
1766
1772
  const dnsLink = document.createElement("a");
1767
- dnsLink.href = `${zerocostBaseUrl}/do-not-sell`;
1773
+ dnsLink.href = `${zerocostBaseUrl}/docs/do-not-sell`;
1768
1774
  dnsLink.target = "_blank";
1769
1775
  dnsLink.rel = "noopener noreferrer";
1770
1776
  dnsLink.textContent = "Do Not Sell My Data";
@@ -1809,6 +1815,7 @@ var ConsentManager = class {
1809
1815
  this.theme = opts.theme ?? "dark";
1810
1816
  this.hydrateFromStorage();
1811
1817
  if (this.consentConfig.showSettingsButton) {
1818
+ injectStyles(this.theme);
1812
1819
  this.injectSettingsButton();
1813
1820
  }
1814
1821
  }
@@ -1959,17 +1966,25 @@ var ConsentManager = class {
1959
1966
  }
1960
1967
  injectSettingsButton() {
1961
1968
  if (typeof document === "undefined") return;
1962
- const existing = document.getElementById("zerocost-privacy-settings-btn");
1963
- if (existing) return;
1964
- const btn = document.createElement("button");
1965
- btn.id = "zerocost-privacy-settings-btn";
1966
- btn.setAttribute("aria-label", "Privacy Settings");
1967
- btn.title = "Privacy Settings";
1968
- const pos = this.consentConfig.buttonPosition || "bottom-left";
1969
- btn.className = `zc-settings-btn zc-settings-${pos}`;
1970
- btn.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>`;
1971
- btn.addEventListener("click", () => this.open());
1972
- document.body.appendChild(btn);
1969
+ const mount = () => {
1970
+ if (!document.body) return;
1971
+ const existing = document.getElementById("zerocost-privacy-settings-btn");
1972
+ if (existing) return;
1973
+ const btn = document.createElement("button");
1974
+ btn.id = "zerocost-privacy-settings-btn";
1975
+ btn.setAttribute("aria-label", "Privacy Settings");
1976
+ btn.title = "Privacy Settings";
1977
+ const pos = this.consentConfig.buttonPosition || "bottom-left";
1978
+ btn.className = `zc-settings-btn zc-settings-${pos}`;
1979
+ btn.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>`;
1980
+ btn.addEventListener("click", () => this.open());
1981
+ document.body.appendChild(btn);
1982
+ };
1983
+ if (document.body) {
1984
+ mount();
1985
+ } else {
1986
+ window.addEventListener("DOMContentLoaded", mount);
1987
+ }
1973
1988
  }
1974
1989
  removeSettingsButton() {
1975
1990
  document.getElementById("zerocost-privacy-settings-btn")?.remove();
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  // src/core/constants.ts
2
2
  var ZEROCOST_DOMAINS = {
3
- MAIN: "https://zerocost.lovable.app",
4
- APP: "https://app.zerocost.com",
5
- DOCS: "https://docs.zerocost.com"
3
+ MAIN: "https://zerocost.lovable.app"
4
+ //APP: 'https://app.zerocost.com',
5
+ //DOCS: 'https://docs.zerocost.com',
6
6
  };
7
7
  var ZEROCOST_BASE_URL = ZEROCOST_DOMAINS.MAIN;
8
8
 
@@ -120,6 +120,12 @@ var TrackModule = class {
120
120
 
121
121
  // src/core/widget-render.ts
122
122
  var SDK_WIDGET_REFRESH_MS = 2e4;
123
+ var CLOSE_ICON_SVG = `
124
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" style="width:100%;height:100%;">
125
+ <line x1="18" y1="6" x2="6" y2="18"></line>
126
+ <line x1="6" y1="6" x2="18" y2="18"></line>
127
+ </svg>
128
+ `;
123
129
  function escapeHtml(value) {
124
130
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
125
131
  }
@@ -173,7 +179,7 @@ function renderVideoWidget(ad, theme) {
173
179
  <div style="position:relative;width:200px;aspect-ratio:9/16;border-radius:16px;overflow:hidden;background:${palette.bg};border:1px solid rgba(255,255,255,0.12);box-shadow:0 20px 60px rgba(0,0,0,0.45);font-family:Space Grotesk,system-ui,sans-serif;">
174
180
  ${media}
175
181
  <div style="position:absolute;top:10px;right:10px;display:flex;gap:8px;z-index:3;">
176
- <button type="button" data-zc-close style="width:22px;height:22px;border:none;border-radius:999px;background:rgba(0,0,0,0.52);color:#fff;font-size:12px;cursor:pointer;">x</button>
182
+ <button type="button" data-zc-close style="width:24px;height:24px;padding:5px;border:none;border-radius:999px;background:rgba(0,0,0,0.52);color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;">${CLOSE_ICON_SVG}</button>
177
183
  </div>
178
184
  <div style="position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,0.04) 0%,rgba(0,0,0,0.12) 35%,rgba(0,0,0,0.85) 100%);"></div>
179
185
  <div style="position:absolute;left:0;right:0;bottom:0;padding:14px;z-index:2;">
@@ -194,7 +200,7 @@ function renderTooltipWidget(ad, theme) {
194
200
  <span style="width:6px;height:6px;border-radius:999px;background:${palette.text};display:inline-block;"></span>
195
201
  Sponsored
196
202
  </div>
197
- <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};font-size:12px;cursor:pointer;padding:0;">x</button>
203
+ <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};width:16px;height:16px;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;">${CLOSE_ICON_SVG}</button>
198
204
  </div>
199
205
  <div style="margin-top:10px;color:${palette.text};font-size:13px;line-height:1.55;">
200
206
  ${escapeHtml(ad.description || ad.title)} <a href="${escapeHtml(ad.landing_url)}" target="_blank" rel="noreferrer noopener" data-zc-cta style="color:${palette.text};font-weight:700;text-decoration:underline;text-underline-offset:2px;">${escapeHtml(ad.cta_text || "Learn More")}</a>
@@ -211,7 +217,7 @@ function renderSponsoredCard(ad, theme) {
211
217
  <div style="padding:12px;">
212
218
  <div style="display:flex;align-items:center;justify-content:space-between;gap:8px;">
213
219
  <div style="display:inline-flex;align-items:center;padding:4px 6px;border-radius:999px;background:${palette.badgeBg};color:${palette.textFaint};font-size:9px;font-weight:700;letter-spacing:0.12em;text-transform:uppercase;">Sponsored</div>
214
- <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};font-size:12px;cursor:pointer;padding:0;">x</button>
220
+ <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};width:16px;height:16px;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;">${CLOSE_ICON_SVG}</button>
215
221
  </div>
216
222
  <div style="margin-top:10px;color:${palette.text};font-size:13px;font-weight:700;line-height:1.2;">${escapeHtml(ad.title)}</div>
217
223
  ${ad.description ? `<div style="margin-top:6px;color:${palette.textMuted};font-size:11px;line-height:1.35;">${escapeHtml(ad.description)}</div>` : ""}
@@ -227,7 +233,7 @@ function renderInlineText(ad, theme) {
227
233
  <div style="margin:10px 0;border-radius:14px;overflow:hidden;background:${palette.surface};border:1px solid ${palette.border};font-family:Space Grotesk,system-ui,sans-serif;">
228
234
  <div style="display:flex;align-items:center;justify-content:space-between;padding:9px 12px;border-bottom:1px solid ${palette.border};background:${palette.surfaceStrong};">
229
235
  <span style="color:${palette.textFaint};font-size:9px;font-weight:700;letter-spacing:0.12em;text-transform:uppercase;">Sponsored</span>
230
- <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};font-size:12px;cursor:pointer;padding:0;">x</button>
236
+ <button type="button" data-zc-close style="background:none;border:none;color:${palette.textFaint};width:16px;height:16px;cursor:pointer;padding:0;display:flex;align-items:center;justify-content:center;">${CLOSE_ICON_SVG}</button>
231
237
  </div>
232
238
  <div style="padding:12px;display:flex;gap:10px;align-items:flex-start;">
233
239
  ${media}
@@ -256,15 +262,15 @@ function renderWidgetMarkup(ad, options) {
256
262
 
257
263
  // src/modules/widget.ts
258
264
  var POSITION_STYLES = {
259
- "bottom-right": "position:fixed;bottom:24px;right:24px;z-index:9999;",
265
+ "bottom-right": "position:fixed;bottom:24px;right:40px;z-index:9999;",
260
266
  "bottom-left": "position:fixed;bottom:24px;left:80px;z-index:9999;",
261
- "top-right": "position:fixed;top:24px;right:24px;z-index:9999;",
267
+ "top-right": "position:fixed;top:24px;right:40px;z-index:9999;",
262
268
  "top-left": "position:fixed;top:24px;left:24px;z-index:9999;",
263
269
  "bottom-center": "position:fixed;bottom:24px;left:50%;transform:translateX(-50%);z-index:9999;",
264
270
  "top-center": "position:fixed;top:24px;left:50%;transform:translateX(-50%);z-index:9999;",
265
271
  "center": "position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:9999;",
266
272
  "sidebar-left": "position:fixed;top:50%;left:24px;transform:translateY(-50%);z-index:9999;",
267
- "sidebar-right": "position:fixed;top:50%;right:24px;transform:translateY(-50%);z-index:9999;"
273
+ "sidebar-right": "position:fixed;top:50%;right:40px;transform:translateY(-50%);z-index:9999;"
268
274
  };
269
275
  var FORMAT_PRIORITY = ["video-widget", "tooltip-ad", "sponsored-card", "sidebar-display", "inline-text"];
270
276
  var AUTO_SLOT_ID = "zerocost-auto-slot";
@@ -1321,14 +1327,14 @@ function injectStyles(theme) {
1321
1327
  `;
1322
1328
  let themeRule;
1323
1329
  if (theme === "dark") {
1324
- themeRule = `.zc-consent-root { ${darkVars} }`;
1330
+ themeRule = `.zc-consent-root, .zc-settings-btn { ${darkVars} }`;
1325
1331
  } else if (theme === "light") {
1326
- themeRule = `.zc-consent-root { ${lightVars} }`;
1332
+ themeRule = `.zc-consent-root, .zc-settings-btn { ${lightVars} }`;
1327
1333
  } else {
1328
1334
  themeRule = `
1329
- .zc-consent-root { ${lightVars} }
1335
+ .zc-consent-root, .zc-settings-btn { ${lightVars} }
1330
1336
  @media (prefers-color-scheme: dark) {
1331
- .zc-consent-root { ${darkVars} }
1337
+ .zc-consent-root, .zc-settings-btn { ${darkVars} }
1332
1338
  }
1333
1339
  `;
1334
1340
  }
@@ -1693,28 +1699,28 @@ function showConsentUI(options) {
1693
1699
  "zc-toggle-ads",
1694
1700
  "Ads",
1695
1701
  "Contextual, non-intrusive ads. No cookies or browsing history used.",
1696
- `${zerocostBaseUrl}/consent/ads`,
1702
+ `${zerocostBaseUrl}/docs/ads`,
1697
1703
  defaults.ads
1698
1704
  ));
1699
1705
  toggles.appendChild(createToggleCard(
1700
1706
  "zc-toggle-usage",
1701
1707
  "Usage data",
1702
1708
  "Anonymized usage patterns. No personal information is shared.",
1703
- `${zerocostBaseUrl}/consent/usage-data`,
1709
+ `${zerocostBaseUrl}/docs/usage-data`,
1704
1710
  defaults.usageData
1705
1711
  ));
1706
1712
  toggles.appendChild(createToggleCard(
1707
1713
  "zc-toggle-ai",
1708
1714
  "AI interactions",
1709
1715
  "Anonymized conversation data used for AI research.",
1710
- `${zerocostBaseUrl}/consent/ai-interactions`,
1716
+ `${zerocostBaseUrl}/docs/ai-interactions`,
1711
1717
  defaults.aiInteractions
1712
1718
  ));
1713
1719
  card.appendChild(toggles);
1714
1720
  const footer = document.createElement("div");
1715
1721
  footer.className = "zc-consent-footer";
1716
1722
  const ppLink = document.createElement("a");
1717
- ppLink.href = privacyPolicyUrl || `${zerocostBaseUrl}/privacy`;
1723
+ ppLink.href = privacyPolicyUrl || `${zerocostBaseUrl}/docs/privacy`;
1718
1724
  ppLink.target = "_blank";
1719
1725
  ppLink.rel = "noopener noreferrer";
1720
1726
  ppLink.textContent = "Privacy Policy";
@@ -1724,7 +1730,7 @@ function showConsentUI(options) {
1724
1730
  sep1.textContent = "\xB7";
1725
1731
  footer.appendChild(sep1);
1726
1732
  const termsLink = document.createElement("a");
1727
- termsLink.href = `${zerocostBaseUrl}/terms`;
1733
+ termsLink.href = `${zerocostBaseUrl}/docs/terms`;
1728
1734
  termsLink.target = "_blank";
1729
1735
  termsLink.rel = "noopener noreferrer";
1730
1736
  termsLink.textContent = "Terms";
@@ -1734,7 +1740,7 @@ function showConsentUI(options) {
1734
1740
  sep2.textContent = "\xB7";
1735
1741
  footer.appendChild(sep2);
1736
1742
  const dnsLink = document.createElement("a");
1737
- dnsLink.href = `${zerocostBaseUrl}/do-not-sell`;
1743
+ dnsLink.href = `${zerocostBaseUrl}/docs/do-not-sell`;
1738
1744
  dnsLink.target = "_blank";
1739
1745
  dnsLink.rel = "noopener noreferrer";
1740
1746
  dnsLink.textContent = "Do Not Sell My Data";
@@ -1779,6 +1785,7 @@ var ConsentManager = class {
1779
1785
  this.theme = opts.theme ?? "dark";
1780
1786
  this.hydrateFromStorage();
1781
1787
  if (this.consentConfig.showSettingsButton) {
1788
+ injectStyles(this.theme);
1782
1789
  this.injectSettingsButton();
1783
1790
  }
1784
1791
  }
@@ -1929,17 +1936,25 @@ var ConsentManager = class {
1929
1936
  }
1930
1937
  injectSettingsButton() {
1931
1938
  if (typeof document === "undefined") return;
1932
- const existing = document.getElementById("zerocost-privacy-settings-btn");
1933
- if (existing) return;
1934
- const btn = document.createElement("button");
1935
- btn.id = "zerocost-privacy-settings-btn";
1936
- btn.setAttribute("aria-label", "Privacy Settings");
1937
- btn.title = "Privacy Settings";
1938
- const pos = this.consentConfig.buttonPosition || "bottom-left";
1939
- btn.className = `zc-settings-btn zc-settings-${pos}`;
1940
- btn.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>`;
1941
- btn.addEventListener("click", () => this.open());
1942
- document.body.appendChild(btn);
1939
+ const mount = () => {
1940
+ if (!document.body) return;
1941
+ const existing = document.getElementById("zerocost-privacy-settings-btn");
1942
+ if (existing) return;
1943
+ const btn = document.createElement("button");
1944
+ btn.id = "zerocost-privacy-settings-btn";
1945
+ btn.setAttribute("aria-label", "Privacy Settings");
1946
+ btn.title = "Privacy Settings";
1947
+ const pos = this.consentConfig.buttonPosition || "bottom-left";
1948
+ btn.className = `zc-settings-btn zc-settings-${pos}`;
1949
+ btn.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>`;
1950
+ btn.addEventListener("click", () => this.open());
1951
+ document.body.appendChild(btn);
1952
+ };
1953
+ if (document.body) {
1954
+ mount();
1955
+ } else {
1956
+ window.addEventListener("DOMContentLoaded", mount);
1957
+ }
1943
1958
  }
1944
1959
  removeSettingsButton() {
1945
1960
  document.getElementById("zerocost-privacy-settings-btn")?.remove();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerocost/sdk",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",