UNPKG

admesh-ui-sdk

Version:

Beautiful, modern React components for displaying AI-powered product recommendations with citation-based conversation ads, auto-triggered widgets, floating chat, conversational interfaces, persistent sidebar, and built-in tracking

1,395 lines (1,306 loc) 173 kB
import we, { useState as R, useMemo as te, useCallback as X, useRef as re, useEffect as W } from "react"; function je(t) { return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t; } var se = { exports: {} }, Z = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ue; function Ne() { if (ue) return Z; ue = 1; var t = Symbol.for("react.transitional.element"), r = Symbol.for("react.fragment"); function s(i, n, a) { var d = null; if (a !== void 0 && (d = "" + a), n.key !== void 0 && (d = "" + n.key), "key" in n) { a = {}; for (var c in n) c !== "key" && (a[c] = n[c]); } else a = n; return n = a.ref, { $$typeof: t, type: i, key: d, ref: n !== void 0 ? n : null, props: a }; } return Z.Fragment = r, Z.jsx = s, Z.jsxs = s, Z; } var ee = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ge; function _e() { return ge || (ge = 1, process.env.NODE_ENV !== "production" && function() { function t(l) { if (l == null) return null; if (typeof l == "function") return l.$$typeof === z ? null : l.displayName || l.name || null; if (typeof l == "string") return l; switch (l) { case y: return "Fragment"; case v: return "Profiler"; case g: return "StrictMode"; case C: return "Suspense"; case T: return "SuspenseList"; case I: return "Activity"; } if (typeof l == "object") switch (typeof l.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), l.$$typeof) { case f: return "Portal"; case j: return (l.displayName || "Context") + ".Provider"; case b: return (l._context.displayName || "Context") + ".Consumer"; case M: var N = l.render; return l = l.displayName, l || (l = N.displayName || N.name || "", l = l !== "" ? "ForwardRef(" + l + ")" : "ForwardRef"), l; case w: return N = l.displayName || null, N !== null ? N : t(l.type) || "Memo"; case S: N = l._payload, l = l._init; try { return t(l(N)); } catch { } } return null; } function r(l) { return "" + l; } function s(l) { try { r(l); var N = !1; } catch { N = !0; } if (N) { N = console; var A = N.error, P = typeof Symbol == "function" && Symbol.toStringTag && l[Symbol.toStringTag] || l.constructor.name || "Object"; return A.call( N, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", P ), r(l); } } function i(l) { if (l === y) return "<>"; if (typeof l == "object" && l !== null && l.$$typeof === S) return "<...>"; try { var N = t(l); return N ? "<" + N + ">" : "<...>"; } catch { return "<...>"; } } function n() { var l = E.A; return l === null ? null : l.getOwner(); } function a() { return Error("react-stack-top-frame"); } function d(l) { if (F.call(l, "key")) { var N = Object.getOwnPropertyDescriptor(l, "key").get; if (N && N.isReactWarning) return !1; } return l.key !== void 0; } function c(l, N) { function A() { L || (L = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", N )); } A.isReactWarning = !0, Object.defineProperty(l, "key", { get: A, configurable: !0 }); } function u() { var l = t(this.type); return U[l] || (U[l] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), l = this.props.ref, l !== void 0 ? l : null; } function m(l, N, A, P, H, $, oe, ne) { return A = $.ref, l = { $$typeof: k, type: l, key: N, props: $, _owner: H }, (A !== void 0 ? A : null) !== null ? Object.defineProperty(l, "ref", { enumerable: !1, get: u }) : Object.defineProperty(l, "ref", { enumerable: !1, value: null }), l._store = {}, Object.defineProperty(l._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(l, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(l, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: oe }), Object.defineProperty(l, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: ne }), Object.freeze && (Object.freeze(l.props), Object.freeze(l)), l; } function p(l, N, A, P, H, $, oe, ne) { var B = N.children; if (B !== void 0) if (P) if (V(B)) { for (P = 0; P < B.length; P++) h(B[P]); Object.freeze && Object.freeze(B); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else h(B); if (F.call(N, "key")) { B = t(l); var Q = Object.keys(N).filter(function(ve) { return ve !== "key"; }); P = 0 < Q.length ? "{key: someKey, " + Q.join(": ..., ") + ": ...}" : "{key: someKey}", Y[B + P] || (Q = 0 < Q.length ? "{" + Q.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, P, B, Q, B ), Y[B + P] = !0); } if (B = null, A !== void 0 && (s(A), B = "" + A), d(N) && (s(N.key), B = "" + N.key), "key" in N) { A = {}; for (var le in N) le !== "key" && (A[le] = N[le]); } else A = N; return B && c( A, typeof l == "function" ? l.displayName || l.name || "Unknown" : l ), m( l, B, $, H, n(), A, oe, ne ); } function h(l) { typeof l == "object" && l !== null && l.$$typeof === k && l._store && (l._store.validated = 1); } var o = we, k = Symbol.for("react.transitional.element"), f = Symbol.for("react.portal"), y = Symbol.for("react.fragment"), g = Symbol.for("react.strict_mode"), v = Symbol.for("react.profiler"), b = Symbol.for("react.consumer"), j = Symbol.for("react.context"), M = Symbol.for("react.forward_ref"), C = Symbol.for("react.suspense"), T = Symbol.for("react.suspense_list"), w = Symbol.for("react.memo"), S = Symbol.for("react.lazy"), I = Symbol.for("react.activity"), z = Symbol.for("react.client.reference"), E = o.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, F = Object.prototype.hasOwnProperty, V = Array.isArray, x = console.createTask ? console.createTask : function() { return null; }; o = { "react-stack-bottom-frame": function(l) { return l(); } }; var L, U = {}, O = o["react-stack-bottom-frame"].bind( o, a )(), G = x(i(a)), Y = {}; ee.Fragment = y, ee.jsx = function(l, N, A, P, H) { var $ = 1e4 > E.recentlyCreatedOwnerStacks++; return p( l, N, A, !1, P, H, $ ? Error("react-stack-top-frame") : O, $ ? x(i(l)) : G ); }, ee.jsxs = function(l, N, A, P, H) { var $ = 1e4 > E.recentlyCreatedOwnerStacks++; return p( l, N, A, !0, P, H, $ ? Error("react-stack-top-frame") : O, $ ? x(i(l)) : G ); }; }()), ee; } var fe; function Ce() { return fe || (fe = 1, process.env.NODE_ENV === "production" ? se.exports = Ne() : se.exports = _e()), se.exports; } var e = Ce(), ie = { exports: {} }; /*! Copyright (c) 2018 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames */ var be; function Me() { return be || (be = 1, function(t) { (function() { var r = {}.hasOwnProperty; function s() { for (var a = "", d = 0; d < arguments.length; d++) { var c = arguments[d]; c && (a = n(a, i(c))); } return a; } function i(a) { if (typeof a == "string" || typeof a == "number") return a; if (typeof a != "object") return ""; if (Array.isArray(a)) return s.apply(null, a); if (a.toString !== Object.prototype.toString && !a.toString.toString().includes("[native code]")) return a.toString(); var d = ""; for (var c in a) r.call(a, c) && a[c] && (d = n(d, c)); return d; } function n(a, d) { return d ? a ? a + " " + d : a + d : a; } t.exports ? (s.default = s, t.exports = s) : window.classNames = s; })(); }(ie)), ie.exports; } var Se = Me(); const _ = /* @__PURE__ */ je(Se), Le = "https://api.useadmesh.com/track"; let ce = { apiBaseUrl: Le, enabled: !0, debug: !1, retryAttempts: 3, retryDelay: 1e3 }; const qe = (t) => { ce = { ...ce, ...t }; }, Te = (t) => { const [r, s] = R(!1), [i, n] = R(null), a = te(() => ({ ...ce, ...t }), [t]), d = X((h, o) => { a.debug && console.log(`[AdMesh Tracker] ${h}`, o); }, [a.debug]), c = X(async (h, o) => { if (!a.enabled) { d("Tracking disabled, skipping event", { eventType: h, data: o }); return; } if (!o.adId || !o.admeshLink) { const g = "Missing required tracking data: adId and admeshLink are required"; d(g, o), n(g); return; } s(!0), n(null); const k = { event_type: h, ad_id: o.adId, admesh_link: o.admeshLink, product_id: o.productId, user_id: o.userId, session_id: o.sessionId, revenue: o.revenue, conversion_type: o.conversionType, metadata: o.metadata, timestamp: (/* @__PURE__ */ new Date()).toISOString(), user_agent: navigator.userAgent, referrer: document.referrer, page_url: window.location.href }; d(`Sending ${h} event`, k); let f = null; for (let g = 1; g <= (a.retryAttempts || 3); g++) try { const v = await fetch(`${a.apiBaseUrl}/events`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(k) }); if (!v.ok) throw new Error(`HTTP ${v.status}: ${v.statusText}`); const b = await v.json(); d(`${h} event tracked successfully`, b), s(!1); return; } catch (v) { f = v, d(`Attempt ${g} failed for ${h} event`, v), g < (a.retryAttempts || 3) && await new Promise( (b) => setTimeout(b, (a.retryDelay || 1e3) * g) ); } const y = `Failed to track ${h} event after ${a.retryAttempts} attempts: ${f == null ? void 0 : f.message}`; d(y, f), n(y), s(!1); }, [a, d]), u = X(async (h) => c("click", h), [c]), m = X(async (h) => c("view", h), [c]), p = X(async (h) => (!h.revenue && !h.conversionType && d("Warning: Conversion tracking without revenue or conversion type", h), c("conversion", h)), [c, d]); return { trackClick: u, trackView: m, trackConversion: p, isTracking: r, error: i }; }, Ye = (t, r, s) => { try { const i = new URL(t); return i.searchParams.set("ad_id", r), i.searchParams.set("utm_source", "admesh"), i.searchParams.set("utm_medium", "recommendation"), s && Object.entries(s).forEach(([n, a]) => { i.searchParams.set(n, a); }), i.toString(); } catch (i) { return console.warn("[AdMesh] Invalid URL provided to buildAdMeshLink:", t, i), t; } }, He = (t, r) => ({ adId: t.ad_id, admeshLink: t.admesh_link, productId: t.product_id, ...r }), D = ({ adId: t, admeshLink: r, productId: s, children: i, trackingData: n, className: a, style: d }) => { const { trackClick: c, trackView: u } = Te(), m = re(null), p = re(!1); W(() => { if (!m.current || p.current) return; const o = new IntersectionObserver( (k) => { k.forEach((f) => { f.isIntersecting && !p.current && (p.current = !0, u({ adId: t, admeshLink: r, productId: s, ...n }).catch(console.error)); }); }, { threshold: 0.5, // Track when 50% of the element is visible rootMargin: "0px" } ); return o.observe(m.current), () => { o.disconnect(); }; }, [t, r, s, n, u]); const h = X(async (o) => { try { await c({ adId: t, admeshLink: r, productId: s, ...n }); } catch (y) { console.error("Failed to track click:", y); } o.target.closest("a") || window.open(r, "_blank", "noopener,noreferrer"); }, [t, r, s, n, c]); return /* @__PURE__ */ e.jsx( "div", { ref: m, className: a, onClick: h, style: { cursor: "pointer", ...d }, children: i } ); }; D.displayName = "AdMeshLinkTracker"; const Re = ` /* AdMesh UI SDK - Complete Self-Contained Styles */ /* CSS Reset for AdMesh components */ .admesh-component, .admesh-component * { box-sizing: border-box; } /* CSS Variables */ .admesh-component { --admesh-primary: #6366f1; --admesh-primary-hover: #4f46e5; --admesh-secondary: #8b5cf6; --admesh-accent: #06b6d4; --admesh-background: #ffffff; --admesh-surface: #ffffff; --admesh-border: #e2e8f0; --admesh-text: #0f172a; --admesh-text-muted: #64748b; --admesh-text-light: #94a3b8; --admesh-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); --admesh-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --admesh-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); --admesh-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); --admesh-radius: 0.75rem; --admesh-radius-sm: 0.375rem; --admesh-radius-lg: 1rem; --admesh-radius-xl: 1.5rem; } .admesh-component[data-admesh-theme="dark"] { --admesh-background: #111827; --admesh-surface: #1f2937; --admesh-border: #374151; --admesh-text: #f9fafb; --admesh-text-muted: #9ca3af; --admesh-text-light: #6b7280; --admesh-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.3), 0 1px 2px -1px rgb(0 0 0 / 0.3); --admesh-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.3), 0 2px 4px -2px rgb(0 0 0 / 0.3); --admesh-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.3), 0 4px 6px -4px rgb(0 0 0 / 0.3); --admesh-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.3), 0 8px 10px -6px rgb(0 0 0 / 0.3); } /* Layout Styles */ .admesh-layout { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; color: var(--admesh-text); background-color: var(--admesh-background); border-radius: var(--admesh-radius); padding: 1.5rem; box-shadow: var(--admesh-shadow); border: 1px solid var(--admesh-border); } .admesh-layout__header { margin-bottom: 1.5rem; text-align: center; } .admesh-layout__title { font-size: 1.25rem; font-weight: 600; color: var(--admesh-text); margin-bottom: 0.5rem; } .admesh-layout__subtitle { font-size: 0.875rem; color: var(--admesh-text-muted); } .admesh-layout__cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; } .admesh-layout__more-indicator { text-align: center; padding: 1rem; color: var(--admesh-text-muted); font-size: 0.875rem; } .admesh-layout__empty { text-align: center; padding: 3rem 1rem; } .admesh-layout__empty-content h3 { font-size: 1.125rem; font-weight: 600; color: var(--admesh-text-muted); margin-bottom: 0.5rem; } .admesh-layout__empty-content p { font-size: 0.875rem; color: var(--admesh-text-muted); } /* Product Card Styles */ .admesh-product-card { background-color: var(--admesh-surface); border: 1px solid var(--admesh-border); border-radius: var(--admesh-radius); padding: 1.5rem; transition: all 0.2s ease-in-out; position: relative; overflow: hidden; } .admesh-product-card:hover { box-shadow: var(--admesh-shadow-lg); transform: translateY(-2px); border-color: var(--admesh-primary); } .admesh-product-card__header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1rem; } .admesh-product-card__title { font-size: 1.125rem; font-weight: 600; color: var(--admesh-text); margin-bottom: 0.5rem; line-height: 1.4; } .admesh-product-card__reason { font-size: 0.875rem; color: var(--admesh-text-muted); line-height: 1.5; margin-bottom: 1rem; } .admesh-product-card__match-score { margin-bottom: 1rem; } .admesh-product-card__match-score-label { display: flex; justify-content: space-between; align-items: center; font-size: 0.75rem; color: var(--admesh-text-muted); margin-bottom: 0.25rem; } .admesh-product-card__match-score-bar { width: 100%; height: 0.375rem; background-color: var(--admesh-border); border-radius: var(--admesh-radius-sm); overflow: hidden; } .admesh-product-card__match-score-fill { height: 100%; background: linear-gradient(90deg, var(--admesh-primary), #8b5cf6); border-radius: var(--admesh-radius-sm); transition: width 0.3s ease-in-out; } .admesh-product-card__badges { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem; } .admesh-product-card__badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.25rem 0.5rem; background-color: var(--admesh-primary); color: white; font-size: 0.75rem; font-weight: 500; border-radius: var(--admesh-radius-sm); } .admesh-product-card__badge--secondary { background-color: var(--admesh-secondary); } .admesh-product-card__keywords { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-bottom: 1rem; } .admesh-product-card__keyword { padding: 0.125rem 0.375rem; background-color: var(--admesh-border); color: var(--admesh-text-muted); font-size: 0.75rem; border-radius: var(--admesh-radius-sm); } /* Dark mode specific enhancements */ .admesh-component[data-admesh-theme="dark"] .admesh-product-card__keyword { background-color: #4b5563; color: #d1d5db; } .admesh-component[data-admesh-theme="dark"] .admesh-product-card:hover { border-color: var(--admesh-primary); background-color: #374151; } .admesh-component[data-admesh-theme="dark"] .admesh-product-card__button:hover { background: linear-gradient(90deg, var(--admesh-primary-hover), var(--admesh-primary)); } .admesh-product-card__footer { display: flex; justify-content: flex-end; margin-top: 1.5rem; } /* Mobile-specific sidebar improvements */ @media (max-width: 640px) { .admesh-sidebar { /* Ensure proper mobile viewport handling */ height: 100vh !important; height: 100dvh !important; /* Dynamic viewport height for mobile browsers */ max-height: 100vh !important; max-height: 100dvh !important; width: 100vw !important; max-width: 90vw !important; overflow: hidden !important; } .admesh-sidebar.relative { height: 100% !important; width: 100% !important; max-width: 100% !important; } /* Improve touch scrolling */ .admesh-sidebar .overflow-y-auto { -webkit-overflow-scrolling: touch !important; overscroll-behavior: contain !important; scroll-behavior: smooth !important; } /* Prevent body scroll when sidebar is open */ body:has(.admesh-sidebar[data-mobile-open="true"]) { overflow: hidden !important; position: fixed !important; width: 100% !important; } } /* Tablet improvements */ @media (min-width: 641px) and (max-width: 1024px) { .admesh-sidebar { max-width: 400px !important; } } /* Mobile responsiveness improvements for all components */ @media (max-width: 640px) { /* Product cards mobile optimization */ .admesh-card { padding: 0.75rem !important; margin-bottom: 0.75rem !important; } /* Inline recommendations mobile optimization */ .admesh-inline-recommendation { padding: 0.5rem !important; margin-bottom: 0.5rem !important; } /* Conversation summary mobile optimization */ .admesh-conversation-summary { padding: 1rem !important; } /* Percentage text mobile improvements */ .admesh-component .text-xs { font-size: 0.75rem !important; line-height: 1rem !important; } .admesh-component .text-sm { font-size: 0.875rem !important; line-height: 1.25rem !important; } /* Button mobile improvements */ .admesh-component button { padding: 0.375rem 0.75rem !important; font-size: 0.75rem !important; min-height: 2rem !important; touch-action: manipulation !important; } /* Badge mobile improvements */ .admesh-component .rounded-full { padding: 0.25rem 0.5rem !important; font-size: 0.625rem !important; line-height: 1rem !important; } /* Progress bar mobile improvements */ .admesh-component .bg-gray-200, .admesh-component .bg-slate-600 { height: 0.25rem !important; } /* Flex layout mobile improvements */ .admesh-component .flex { flex-wrap: wrap !important; } .admesh-component .gap-2 { gap: 0.375rem !important; } .admesh-component .gap-3 { gap: 0.5rem !important; } } .admesh-product-card__button { display: inline-flex; align-items: center; gap: 0.5rem; padding: 0.75rem 1.5rem; background: linear-gradient(90deg, var(--admesh-primary), var(--admesh-primary-hover)); color: white; font-size: 0.875rem; font-weight: 500; border: none; border-radius: var(--admesh-radius); cursor: pointer; transition: all 0.2s ease-in-out; text-decoration: none; } .admesh-product-card__button:hover { transform: translateY(-1px); box-shadow: var(--admesh-shadow-lg); } /* Utility Classes */ .admesh-text-xs { font-size: 0.75rem; } .admesh-text-sm { font-size: 0.875rem; } .admesh-text-base { font-size: 1rem; } .admesh-text-lg { font-size: 1.125rem; } .admesh-text-xl { font-size: 1.25rem; } .admesh-font-medium { font-weight: 500; } .admesh-font-semibold { font-weight: 600; } .admesh-font-bold { font-weight: 700; } .admesh-text-muted { color: var(--admesh-text-muted); } /* Comparison Table Styles */ .admesh-compare-table { width: 100%; border-collapse: collapse; background-color: var(--admesh-surface); border: 1px solid var(--admesh-border); border-radius: var(--admesh-radius); overflow: hidden; } .admesh-compare-table th, .admesh-compare-table td { padding: 0.75rem; text-align: left; border-bottom: 1px solid var(--admesh-border); } .admesh-compare-table th { background-color: var(--admesh-background); font-weight: 600; color: var(--admesh-text); font-size: 0.875rem; } .admesh-compare-table td { color: var(--admesh-text); font-size: 0.875rem; } .admesh-compare-table tr:hover { background-color: var(--admesh-border); } /* Dark mode table enhancements */ .admesh-component[data-admesh-theme="dark"] .admesh-compare-table th { background-color: #374151; } .admesh-component[data-admesh-theme="dark"] .admesh-compare-table tr:hover { background-color: #4b5563; } /* Responsive Design */ @media (max-width: 768px) { .admesh-layout { padding: 1rem; } .admesh-layout__cards-grid { grid-template-columns: 1fr; gap: 0.75rem; } .admesh-product-card { padding: 1rem; } .admesh-compare-table { font-size: 0.75rem; } .admesh-compare-table th, .admesh-compare-table td { padding: 0.5rem; } } /* Essential Utility Classes for Self-Contained SDK - High Specificity */ .admesh-component .relative { position: relative !important; } .admesh-component .absolute { position: absolute !important; } .admesh-component .flex { display: flex !important; } .admesh-component .inline-flex { display: inline-flex !important; } .admesh-component .grid { display: grid !important; } .admesh-component .hidden { display: none !important; } .admesh-component .block { display: block !important; } .admesh-component .inline-block { display: inline-block !important; } /* Flexbox utilities */ .admesh-component .flex-col { flex-direction: column !important; } .admesh-component .flex-row { flex-direction: row !important; } .admesh-component .flex-wrap { flex-wrap: wrap !important; } .admesh-component .items-center { align-items: center !important; } .admesh-component .items-start { align-items: flex-start !important; } .admesh-component .items-end { align-items: flex-end !important; } .admesh-component .justify-center { justify-content: center !important; } .admesh-component .justify-between { justify-content: space-between !important; } .admesh-component .justify-end { justify-content: flex-end !important; } .admesh-component .flex-1 { flex: 1 1 0% !important; } .admesh-component .flex-shrink-0 { flex-shrink: 0 !important; } /* Grid utilities */ .admesh-component .grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); } .admesh-component .grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .admesh-component .grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } /* Spacing utilities */ .admesh-component .gap-1 { gap: 0.25rem; } .admesh-component .gap-2 { gap: 0.5rem; } .admesh-component .gap-3 { gap: 0.75rem; } .admesh-component .gap-4 { gap: 1rem; } .admesh-component .gap-6 { gap: 1.5rem; } .admesh-component .gap-8 { gap: 2rem; } /* Padding utilities */ .admesh-component .p-1 { padding: 0.25rem; } .admesh-component .p-2 { padding: 0.5rem; } .admesh-component .p-3 { padding: 0.75rem; } .admesh-component .p-4 { padding: 1rem; } .admesh-component .p-5 { padding: 1.25rem; } .admesh-component .p-6 { padding: 1.5rem; } .admesh-component .px-2 { padding-left: 0.5rem; padding-right: 0.5rem; } .admesh-component .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; } .admesh-component .px-4 { padding-left: 1rem; padding-right: 1rem; } .admesh-component .py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; } .admesh-component .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; } .admesh-component .py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem; } .admesh-component .pt-2 { padding-top: 0.5rem; } .admesh-component .pt-3 { padding-top: 0.75rem; } .admesh-component .pb-2 { padding-bottom: 0.5rem; } .admesh-component .pb-3 { padding-bottom: 0.75rem; } /* Margin utilities */ .admesh-component .m-0 { margin: 0; } .admesh-component .mb-1 { margin-bottom: 0.25rem; } .admesh-component .mb-2 { margin-bottom: 0.5rem; } .admesh-component .mb-3 { margin-bottom: 0.75rem; } .admesh-component .mb-4 { margin-bottom: 1rem; } .admesh-component .mb-6 { margin-bottom: 1.5rem; } .admesh-component .mt-1 { margin-top: 0.25rem; } .admesh-component .mt-2 { margin-top: 0.5rem; } .admesh-component .mt-4 { margin-top: 1rem; } .admesh-component .mt-6 { margin-top: 1.5rem; } .admesh-component .mt-auto { margin-top: auto; } .admesh-component .ml-1 { margin-left: 0.25rem; } .admesh-component .mr-1 { margin-right: 0.25rem; } .admesh-component .mr-2 { margin-right: 0.5rem; } /* Width and height utilities */ .admesh-component .w-2 { width: 0.5rem; } .admesh-component .w-3 { width: 0.75rem; } .admesh-component .w-4 { width: 1rem; } .admesh-component .w-5 { width: 1.25rem; } .admesh-component .w-6 { width: 1.5rem; } .admesh-component .w-full { width: 100%; } .admesh-component .w-fit { width: fit-content; } .admesh-component .h-2 { height: 0.5rem; } .admesh-component .h-3 { height: 0.75rem; } .admesh-component .h-4 { height: 1rem; } .admesh-component .h-5 { height: 1.25rem; } .admesh-component .h-6 { height: 1.5rem; } .admesh-component .h-full { height: 100%; } .admesh-component .min-w-0 { min-width: 0px; } /* Border utilities */ .admesh-component .border { border-width: 1px; } .admesh-component .border-t { border-top-width: 1px; } .admesh-component .border-gray-100 { border-color: #f3f4f6; } .admesh-component .border-gray-200 { border-color: #e5e7eb; } .admesh-component .border-gray-300 { border-color: #d1d5db; } .admesh-component .border-blue-200 { border-color: #bfdbfe; } .admesh-component .border-green-200 { border-color: #bbf7d0; } /* Border radius utilities */ .admesh-component .rounded { border-radius: 0.25rem !important; } .admesh-component .rounded-md { border-radius: 0.375rem !important; } .admesh-component .rounded-lg { border-radius: 0.5rem !important; } .admesh-component .rounded-xl { border-radius: 0.75rem !important; } .admesh-component .rounded-full { border-radius: 9999px !important; } /* Background utilities */ .admesh-component .bg-white { background-color: #ffffff; } .admesh-component .bg-gray-50 { background-color: #f9fafb; } .admesh-component .bg-gray-100 { background-color: #f3f4f6; } .admesh-component .bg-blue-50 { background-color: #eff6ff; } .admesh-component .bg-blue-100 { background-color: #dbeafe; } .admesh-component .bg-green-100 { background-color: #dcfce7; } .admesh-component .bg-green-500 { background-color: #22c55e; } .admesh-component .bg-blue-500 { background-color: #3b82f6; } /* Gradients */ .admesh-component .bg-gradient-to-br { background-image: linear-gradient(to bottom right, var(--tw-gradient-stops)); } .admesh-component .bg-gradient-to-r { background-image: linear-gradient(to right, var(--tw-gradient-stops)); } .admesh-component .from-white { --tw-gradient-from: #ffffff; --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(255, 255, 255, 0)); } .admesh-component .to-gray-50 { --tw-gradient-to: #f9fafb; } .admesh-component .from-purple-500 { --tw-gradient-from: #a855f7; --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(168, 85, 247, 0)); } .admesh-component .to-pink-500 { --tw-gradient-to: #ec4899; } .admesh-component .from-green-400 { --tw-gradient-from: #4ade80; --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(74, 222, 128, 0)); } .admesh-component .to-blue-500 { --tw-gradient-to: #3b82f6; } /* Text utilities */ .admesh-component .text-xs { font-size: 0.75rem; line-height: 1rem; } .admesh-component .text-sm { font-size: 0.875rem; line-height: 1.25rem; } .admesh-component .text-base { font-size: 1rem; line-height: 1.5rem; } .admesh-component .text-lg { font-size: 1.125rem; line-height: 1.75rem; } .admesh-component .text-xl { font-size: 1.25rem; line-height: 1.75rem; } .admesh-component .font-medium { font-weight: 500; } .admesh-component .font-semibold { font-weight: 600; } .admesh-component .font-bold { font-weight: 700; } .admesh-component .leading-relaxed { line-height: 1.625; } /* Text colors */ .admesh-component .text-white { color: #ffffff; } .admesh-component .text-gray-400 { color: #9ca3af; } .admesh-component .text-gray-500 { color: #6b7280; } .admesh-component .text-gray-600 { color: #4b5563; } .admesh-component .text-gray-700 { color: #374151; } .admesh-component .text-gray-800 { color: #1f2937; } .admesh-component .text-blue-600 { color: #2563eb; } .admesh-component .text-blue-700 { color: #1d4ed8; } .admesh-component .text-green-700 { color: #15803d; } /* Shadow utilities */ .admesh-component .shadow-sm { box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); } .admesh-component .shadow { box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); } .admesh-component .shadow-md { box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); } .admesh-component .shadow-lg { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); } .admesh-component .shadow-xl { box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); } /* Transition utilities */ .admesh-component .transition-all { transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; } .admesh-component .transition-colors { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; } .admesh-component .duration-200 { transition-duration: 200ms; } .admesh-component .duration-300 { transition-duration: 300ms; } /* Transform utilities */ .admesh-component .hover\\:-translate-y-1:hover { transform: translateY(-0.25rem); } .admesh-component .hover\\:scale-105:hover { transform: scale(1.05); } /* Hover utilities */ .admesh-component .hover\\:shadow-xl:hover { box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); } .admesh-component .hover\\:bg-gray-100:hover { background-color: #f3f4f6; } .admesh-component .hover\\:text-blue-800:hover { color: #1e40af; } /* Cursor utilities */ .admesh-component .cursor-pointer { cursor: pointer; } /* Overflow utilities */ .admesh-component .overflow-hidden { overflow: hidden; } .admesh-component .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Text decoration */ .admesh-component .underline { text-decoration-line: underline; } /* Whitespace */ .admesh-component .whitespace-nowrap { white-space: nowrap; } /* Dark mode utilities */ @media (prefers-color-scheme: dark) { .admesh-component .dark\\:bg-slate-800 { background-color: #1e293b; } .admesh-component .dark\\:bg-slate-900 { background-color: #0f172a; } .admesh-component .dark\\:border-slate-700 { border-color: #334155; } .admesh-component .dark\\:text-white { color: #ffffff; } .admesh-component .dark\\:text-gray-200 { color: #e5e7eb; } .admesh-component .dark\\:text-gray-300 { color: #d1d5db; } .admesh-component .dark\\:text-gray-400 { color: #9ca3af; } .admesh-component .dark\\:text-blue-400 { color: #60a5fa; } } /* Responsive utilities */ @media (min-width: 640px) { .admesh-component .sm\\:p-5 { padding: 1.25rem; } .admesh-component .sm\\:text-base { font-size: 1rem; line-height: 1.5rem; } .admesh-component .sm\\:text-lg { font-size: 1.125rem; line-height: 1.75rem; } .admesh-component .sm\\:flex-row { flex-direction: row; } .admesh-component .sm\\:items-center { align-items: center; } .admesh-component .sm\\:justify-between { justify-content: space-between; } } @media (min-width: 768px) { .admesh-component .md\\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } } @media (min-width: 1024px) { .admesh-component .lg\\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } .admesh-component .lg\\:col-span-1 { grid-column: span 1 / span 1; } } `; let de = !1; const me = () => { W(() => { if (de) return; const t = document.createElement("style"); return t.id = "admesh-ui-sdk-styles", t.textContent = Re, document.getElementById("admesh-ui-sdk-styles") || (document.head.appendChild(t), de = !0), () => { const r = document.getElementById("admesh-ui-sdk-styles"); r && document.head.contains(r) && (document.head.removeChild(r), de = !1); }; }, []); }, K = (t, r = {}) => { const s = t.intent_match_score || 0, i = r.customLabels || {}; return s >= 0.8 ? i.smartPick || "Smart Pick" : s >= 0.6 ? i.partnerMatch || "Partner Match" : s >= 0.3 ? i.promotedOption || "Promoted Option" : i.relatedOption || "Related Option"; }, ae = (t, r) => { const s = t.intent_match_score || 0; return s >= 0.8 ? "This recommendation is from a partner who compensates us when you engage. We've matched it to your needs based on your query." : s >= 0.6 ? "Top-rated partner solution matched to your specific requirements. Partner compensates us for qualified referrals." : s >= 0.3 ? "This partner solution may be relevant to your needs. The partner compensates us when you take qualifying actions." : "This solution is somewhat related to your query. While not a perfect match, it might still be helpful. This partner compensates us for qualified referrals."; }, Ge = (t = !0, r = !1) => t ? r ? "These curated recommendations are from partners who compensate us for referrals." : "Personalized Partner Recommendations: All results are from vetted partners who compensate us for qualified matches. We've ranked them based on relevance to your specific needs." : "Expanded Results: While these don't perfectly match your query, they're related solutions from our partner network. All partners compensate us for referrals.", xe = (t, r = !1) => { const s = t.intent_match_score || 0; return r ? "Promoted Match" : s >= 0.8 ? "Smart Pick" : s >= 0.6 ? "Partner Match" : "Promoted Option"; }, he = () => "We've partnered with trusted providers to bring you relevant solutions. These partners compensate us for qualified referrals, which helps us keep our service free.", Ae = (t) => ({ "Top Match": "Top Match", "Smart Pick": "Smart Pick", "Perfect Fit": "Perfect Fit", "Great Match": "Great Match", Recommended: "Recommended", "Good Fit": "Good Fit", Featured: "Featured", "Popular Choice": "Popular Choice", "Premium Pick": "Premium Pick", "Free Tier": "Free Tier", "AI Powered": "AI Powered", Popular: "Popular", New: "New", "Trial Available": "Trial Available", "Related Option": "Related Option", "Alternative Solution": "Alternative Solution", "Expanded Match": "Expanded Match" })[t] || t, Ke = (t, r = "button") => { const s = t.recommendation_title || t.title; return r === "link" ? s : t.trial_days && t.trial_days > 0 ? `Try ${s}` : "Learn More"; }, Je = (t) => t.some((r) => (r.intent_match_score || 0) >= 0.8), Qe = (t = !1) => t ? "Powered by AdMesh" : "Recommendations powered by AdMesh", pe = ({ recommendation: t, theme: r, showMatchScore: s = !1, showBadges: i = !0, variation: n = "default", className: a, style: d }) => { var v, b, j, M, C, T, w, S, I, z, E, F, V; me(); const [c, u] = R(!1), m = te(() => { var G; const x = []; K(t) === "Smart Pick" && x.push("Top Match"), t.trial_days && t.trial_days > 0 && x.push("Trial Available"); const U = ["ai", "artificial intelligence", "machine learning", "ml", "automation"]; return (((G = t.keywords) == null ? void 0 : G.some( (Y) => U.some((l) => Y.toLowerCase().includes(l)) )) || t.title.toLowerCase().includes("ai")) && x.push("AI Powered"), t.badges && t.badges.length > 0 && t.badges.forEach((Y) => { ["Top Match", "Free Tier", "AI Powered", "Popular", "New", "Trial Available"].includes(Y) && !x.includes(Y) && x.push(Y); }), x; }, [t]), p = xe(t, !1), h = he(), o = Math.round(t.intent_match_score * 100), f = (() => { const x = t.content_variations; return n === "simple" ? { title: t.recommendation_title || t.title, description: t.recommendation_description || t.description || t.reason, ctaText: t.recommendation_title || t.title, isSimple: !0 } : n === "question" && (x != null && x.question) ? { title: x.question.cta || t.recommendation_title || t.title, description: x.question.text, ctaText: x.question.cta || t.recommendation_title || t.title } : n === "statement" && (x != null && x.statement) ? { title: t.recommendation_title || t.title, description: x.statement.text, ctaText: x.statement.cta || t.recommendation_title || t.title } : { title: t.recommendation_title || t.title, description: t.recommendation_description || t.description || t.reason, ctaText: t.recommendation_title || t.title }; })(), y = _( "admesh-component", "admesh-card", "relative p-4 sm:p-5 rounded-xl bg-gradient-to-br from-white to-gray-50 dark:from-slate-800 dark:to-slate-900 border border-gray-200/50 dark:border-slate-700/50 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1", a ), g = r ? { "--admesh-primary": r.primaryColor || r.accentColor || "#3b82f6", "--admesh-secondary": r.secondaryColor || "#10b981", "--admesh-accent": r.accentColor || "#3b82f6", "--admesh-background": r.backgroundColor, "--admesh-surface": r.surfaceColor, "--admesh-border": r.borderColor, "--admesh-text": r.textColor, "--admesh-text-secondary": r.textSecondaryColor, "--admesh-radius": r.borderRadius || "12px", "--admesh-shadow-sm": (v = r.shadows) == null ? void 0 : v.small, "--admesh-shadow-md": (b = r.shadows) == null ? void 0 : b.medium, "--admesh-shadow-lg": (j = r.shadows) == null ? void 0 : j.large, "--admesh-spacing-sm": (M = r.spacing) == null ? void 0 : M.small, "--admesh-spacing-md": (C = r.spacing) == null ? void 0 : C.medium, "--admesh-spacing-lg": (T = r.spacing) == null ? void 0 : T.large, "--admesh-font-size-sm": (w = r.fontSize) == null ? void 0 : w.small, "--admesh-font-size-base": (S = r.fontSize) == null ? void 0 : S.base, "--admesh-font-size-lg": (I = r.fontSize) == null ? void 0 : I.large, "--admesh-font-size-title": (z = r.fontSize) == null ? void 0 : z.title, fontFamily: r.fontFamily } : void 0; return n === "simple" ? /* @__PURE__ */ e.jsxs( "div", { className: _( "admesh-component admesh-simple-ad", "inline-block text-sm leading-relaxed", a ), style: { fontFamily: (r == null ? void 0 : r.fontFamily) || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', ...(E = r == null ? void 0 : r.components) == null ? void 0 : E.productCard, ...d }, "data-admesh-theme": r == null ? void 0 : r.mode, children: [ /* @__PURE__ */ e.jsx( "span", { style: { fontSize: "11px", fontWeight: "600", color: (r == null ? void 0 : r.accentColor) || "#2563eb", backgroundColor: (r == null ? void 0 : r.mode) === "dark" ? "#374151" : "#f3f4f6", padding: "2px 6px", borderRadius: "4px", marginRight: "8px" }, title: ae(t, K(t)), children: K(t) } ), /* @__PURE__ */ e.jsxs( "span", { style: { color: (r == null ? void 0 : r.mode) === "dark" ? "#f3f4f6" : "#374151", marginRight: "4px" }, children: [ f.description, " " ] } ), /* @__PURE__ */ e.jsx( D, { adId: t.ad_id, admeshLink: t.admesh_link, productId: t.product_id, trackingData: { title: t.title, matchScore: t.intent_match_score, component: "simple_ad_cta" }, children: /* @__PURE__ */ e.jsx( "span", { style: { color: (r == null ? void 0 : r.accentColor) || "#2563eb", textDecoration: "underline", cursor: "pointer", fontSize: "inherit", fontFamily: "inherit" }, children: f.ctaText } ) } ), /* @__PURE__ */ e.jsxs( "span", { style: { fontSize: "10px", color: (r == null ? void 0 : r.mode) === "dark" ? "#9ca3af" : "#6b7280", marginLeft: "8px" }, title: h, children: [ "(", p, ")" ] } ) ] } ) : n === "question" || n === "statement" ? /* @__PURE__ */ e.jsx( "div", { className: _( "admesh-component admesh-expandable-variation transition-all duration-300", c ? "p-4 sm:p-5 rounded-xl bg-gradient-to-br from-white to-gray-50 dark:from-slate-800 dark:to-slate-900 border border-gray-200/50 dark:border-slate-700/50 shadow-lg" : "p-4 rounded-lg bg-white dark:bg-slate-800 border border-gray-200 dark:border-slate-700 shadow-sm hover:shadow-md", a ), style: { fontFamily: (r == null ? void 0 : r.fontFamily) || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', ...(F = r == null ? void 0 : r.components) == null ? void 0 : F.productCard, ...d }, "data-admesh-theme": r == null ? void 0 : r.mode, children: c ? ( // Expanded full card layout (same as default variation) /* @__PURE__ */ e.jsxs( "div", { className: "h-full flex flex-col", style: g, "data-admesh-theme": r == null ? void 0 : r.mode, children: [ /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col sm:flex-row sm:justify-between sm:items-start gap-3 mb-4", children: [ /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center gap-2 flex-1 min-w-0", children: [ i && m.includes("Top Match") && /* @__PURE__ */ e.jsx( "span", { className: "text-xs font-semibold text-white px-3 py-1 rounded-full w-fit shadow-md", style: { backgroundColor: (r == null ? void 0 : r.primaryColor) || (r == null ? void 0 : r.accentColor) || "#f59e0b", borderRadius: (r == null ? void 0 : r.borderRadius) || "9999px" }, title: ae(t), children: Ae("Top Match") } ), /* @__PURE__ */ e.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [ t.product_logo && /* @__PURE__ */ e.jsx( "img", { src: t.product_logo.url, alt: `${t.title} logo`, className: "w-6 h-6 rounded flex-shrink-0", onError: (x) => { x.target.style.display = "none"; } } ), /* @__PURE__ */ e.jsx("h4", { className: "font-semibold text-gray-800 dark:text-gray-200 text-sm sm:text-base truncate", children: f.title }) ] }) ] }), /* @__PURE__ */ e.jsxs("div", { className: "flex gap-3 flex-shrink-0", children: [ /* @__PURE__ */ e.jsxs( "button", { onClick: () => u(!1), className: "flex items-center gap-2 px-3 py-2 text-xs font-medium text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-800/50 rounded-lg transition-all duration-200 border border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600", title: "Show less details", children: [ /* @__PURE__ */ e.jsx("span", { children: "Less Details" }), /* @__PURE__ */ e.jsx("svg", { className: "h-4 w-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20 12H4" }) }) ] } ), /* @__PURE__ */ e.jsx( D, { adId: t.ad_id, admeshLink: t.admesh_link, productId: t.product_id, trackingData: { title: t.title, matchScore: t.intent_match_score, component: "product_card_cta" }, children: /* @__PURE__ */ e.jsxs("button", { className: "text-xs sm:text-sm px-3 py-2 rounded-full bg-gradient-to-r from-purple-500 to-pink-500 text-white hover:from-purple-600 hover:to-pink-600 flex items-center transition-all duration-200 transform hover:scale-105 shadow-md hover:shadow-lg", children: [ n === "question" ? "Try" : "Visit", " ", f.ctaText, /* @__PURE__ */ e.jsx("svg", { className: "ml-1 h-3 w-3", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ e.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" }) }) ] }) } ) ] })