adkit-react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -0
- package/dist/index.d.mts +95 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.js +412 -0
- package/dist/index.mjs +373 -0
- package/dist/styles.css +284 -0
- package/dist/styles.d.mts +2 -0
- package/dist/styles.d.ts +2 -0
- package/package.json +56 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/AdSlot.tsx
|
|
4
|
+
import * as React3 from "react";
|
|
5
|
+
|
|
6
|
+
// src/eventClient.ts
|
|
7
|
+
var API_URL = "https://adkit.dev/api/events";
|
|
8
|
+
function sendEvent(payload) {
|
|
9
|
+
try {
|
|
10
|
+
fetch(API_URL, {
|
|
11
|
+
method: "POST",
|
|
12
|
+
headers: { "Content-Type": "application/json" },
|
|
13
|
+
body: JSON.stringify({ ...payload, timestamp: Date.now() }),
|
|
14
|
+
keepalive: true
|
|
15
|
+
}).catch(() => {
|
|
16
|
+
});
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/AdkitContext.tsx
|
|
22
|
+
import * as React from "react";
|
|
23
|
+
var AdkitContext = React.createContext(null);
|
|
24
|
+
function useAdkit() {
|
|
25
|
+
const ctx = React.useContext(AdkitContext);
|
|
26
|
+
if (!ctx) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
'[Adkit] <AdSlot /> must be used inside <AdkitProvider />. Wrap your app with <AdkitProvider siteId="your-site-id">.'
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return ctx;
|
|
32
|
+
}
|
|
33
|
+
function deriveSlotIdentity(siteId, slot) {
|
|
34
|
+
return `${siteId}:${slot}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/BookingModal.tsx
|
|
38
|
+
import * as React2 from "react";
|
|
39
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
40
|
+
function BookingModal({ siteId, slot, price, onClose }) {
|
|
41
|
+
const overlayRef = React2.useRef(null);
|
|
42
|
+
React2.useEffect(() => {
|
|
43
|
+
const handleKey = (e) => {
|
|
44
|
+
if (e.key === "Escape") onClose();
|
|
45
|
+
};
|
|
46
|
+
document.addEventListener("keydown", handleKey);
|
|
47
|
+
return () => document.removeEventListener("keydown", handleKey);
|
|
48
|
+
}, [onClose]);
|
|
49
|
+
React2.useEffect(() => {
|
|
50
|
+
const prev = document.body.style.overflow;
|
|
51
|
+
document.body.style.overflow = "hidden";
|
|
52
|
+
return () => {
|
|
53
|
+
document.body.style.overflow = prev;
|
|
54
|
+
};
|
|
55
|
+
}, []);
|
|
56
|
+
const handleOverlayClick = (e) => {
|
|
57
|
+
if (e.target === overlayRef.current) onClose();
|
|
58
|
+
};
|
|
59
|
+
const dollars = price / 100;
|
|
60
|
+
const formatted = Number.isInteger(dollars) ? `$${dollars}` : `$${dollars.toFixed(2)}`;
|
|
61
|
+
const handleBook = () => {
|
|
62
|
+
const params = new URLSearchParams({
|
|
63
|
+
siteId,
|
|
64
|
+
slot,
|
|
65
|
+
price: String(price),
|
|
66
|
+
ref: window.location.href
|
|
67
|
+
});
|
|
68
|
+
window.location.href = `https://adkit.dev/book?${params.toString()}`;
|
|
69
|
+
};
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
"div",
|
|
72
|
+
{
|
|
73
|
+
ref: overlayRef,
|
|
74
|
+
className: "adkit-modal-overlay",
|
|
75
|
+
onClick: handleOverlayClick,
|
|
76
|
+
role: "dialog",
|
|
77
|
+
"aria-modal": "true",
|
|
78
|
+
"aria-label": "Book this ad space",
|
|
79
|
+
children: /* @__PURE__ */ jsxs("div", { className: "adkit-modal-card", children: [
|
|
80
|
+
/* @__PURE__ */ jsxs("h2", { className: "adkit-modal-headline", children: [
|
|
81
|
+
"Advertise directly on ",
|
|
82
|
+
typeof window !== "undefined" ? window.location.hostname : "this site",
|
|
83
|
+
"."
|
|
84
|
+
] }),
|
|
85
|
+
/* @__PURE__ */ jsxs("p", { className: "adkit-modal-subhead", children: [
|
|
86
|
+
"Rent this ad space for a fixed price and reach your target audience where they really are: ",
|
|
87
|
+
/* @__PURE__ */ jsx("strong", { children: "right here" }),
|
|
88
|
+
"."
|
|
89
|
+
] }),
|
|
90
|
+
/* @__PURE__ */ jsxs("ul", { className: "adkit-modal-bullets", children: [
|
|
91
|
+
/* @__PURE__ */ jsx("li", { children: "Exclusive placement, no other ads will be shown" }),
|
|
92
|
+
/* @__PURE__ */ jsx("li", { children: "Fixed price \u2014 no bidding, auctions, or fees" }),
|
|
93
|
+
/* @__PURE__ */ jsx("li", { children: "See your ad before you pay, no commitments" }),
|
|
94
|
+
/* @__PURE__ */ jsx("li", { children: "Track your ad's performance on your dashboard" }),
|
|
95
|
+
/* @__PURE__ */ jsx("li", { children: "Guaranteed to display 24/7 or your money back" })
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsxs("div", { className: "adkit-modal-price-section", children: [
|
|
98
|
+
/* @__PURE__ */ jsxs("span", { className: "adkit-modal-price", children: [
|
|
99
|
+
formatted,
|
|
100
|
+
" / day"
|
|
101
|
+
] }),
|
|
102
|
+
/* @__PURE__ */ jsx("span", { className: "adkit-modal-price-helper", children: "Zero commitment. No minimum booking period." })
|
|
103
|
+
] }),
|
|
104
|
+
/* @__PURE__ */ jsxs("div", { className: "adkit-modal-actions", children: [
|
|
105
|
+
/* @__PURE__ */ jsx("button", { className: "adkit-modal-cta", onClick: handleBook, children: "Book this ad" }),
|
|
106
|
+
/* @__PURE__ */ jsx("span", { className: "adkit-modal-redirect-hint", children: "You'll be redirected to Adkit to upload your ad and choose dates." }),
|
|
107
|
+
/* @__PURE__ */ jsx("button", { className: "adkit-modal-cancel", onClick: onClose, children: "Cancel" })
|
|
108
|
+
] }),
|
|
109
|
+
/* @__PURE__ */ jsxs("div", { className: "adkit-modal-footer", children: [
|
|
110
|
+
"Powered by ",
|
|
111
|
+
/* @__PURE__ */ jsx("a", { href: "https://adkit.dev", target: "_blank", rel: "noopener noreferrer", children: "Adkit" })
|
|
112
|
+
] })
|
|
113
|
+
] })
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/AdSlot.tsx
|
|
119
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
120
|
+
var RATIO_CSS = {
|
|
121
|
+
"16:9": "16 / 9",
|
|
122
|
+
"4:3": "4 / 3",
|
|
123
|
+
"1:1": "1 / 1",
|
|
124
|
+
"9:16": "9 / 16",
|
|
125
|
+
"banner": "728 / 90"
|
|
126
|
+
};
|
|
127
|
+
var RATIO_VALUE = {
|
|
128
|
+
"16:9": 16 / 9,
|
|
129
|
+
"4:3": 4 / 3,
|
|
130
|
+
"1:1": 1,
|
|
131
|
+
"9:16": 9 / 16,
|
|
132
|
+
"banner": 728 / 90
|
|
133
|
+
};
|
|
134
|
+
var mountedSlots = /* @__PURE__ */ new Set();
|
|
135
|
+
var SERVE_BASE = "https://adkit.dev";
|
|
136
|
+
function useSystemDark() {
|
|
137
|
+
const [isDark, setIsDark] = React3.useState(false);
|
|
138
|
+
React3.useEffect(() => {
|
|
139
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
140
|
+
setIsDark(mq.matches);
|
|
141
|
+
const handler = (e) => setIsDark(e.matches);
|
|
142
|
+
mq.addEventListener("change", handler);
|
|
143
|
+
return () => mq.removeEventListener("change", handler);
|
|
144
|
+
}, []);
|
|
145
|
+
return isDark;
|
|
146
|
+
}
|
|
147
|
+
function AdSlot({
|
|
148
|
+
slot,
|
|
149
|
+
siteId: manualSiteId,
|
|
150
|
+
aspectRatio,
|
|
151
|
+
price = 2500,
|
|
152
|
+
size = "lg",
|
|
153
|
+
theme = "auto",
|
|
154
|
+
className,
|
|
155
|
+
styles,
|
|
156
|
+
silent = false
|
|
157
|
+
}) {
|
|
158
|
+
var _a, _b, _c, _d;
|
|
159
|
+
const slotRef = React3.useRef(null);
|
|
160
|
+
const hasViewedRef = React3.useRef(false);
|
|
161
|
+
const bookingIdRef = React3.useRef(void 0);
|
|
162
|
+
const systemDark = useSystemDark();
|
|
163
|
+
const [servedAd, setServedAd] = React3.useState({ status: "loading" });
|
|
164
|
+
React3.useEffect(() => {
|
|
165
|
+
bookingIdRef.current = servedAd.status === "active" ? servedAd.bookingId : void 0;
|
|
166
|
+
}, [servedAd]);
|
|
167
|
+
if (!aspectRatio) {
|
|
168
|
+
throw new Error("[Adkit] Missing aspectRatio. This prop is required and determines the ad format.");
|
|
169
|
+
}
|
|
170
|
+
if (!/^[A-Za-z0-9_-]+$/.test(slot)) {
|
|
171
|
+
throw new Error(`[Adkit] Invalid slot name "${slot}". Only letters, numbers, hyphens, and underscores allowed.`);
|
|
172
|
+
}
|
|
173
|
+
const ctx = React3.useContext(AdkitContext);
|
|
174
|
+
const siteId = manualSiteId != null ? manualSiteId : ctx == null ? void 0 : ctx.siteId;
|
|
175
|
+
if (!siteId) {
|
|
176
|
+
throw new Error('[Adkit] Missing siteId. Either wrap your app with <AdkitProvider siteId="..."> or pass siteId directly.');
|
|
177
|
+
}
|
|
178
|
+
const slotIdentity = deriveSlotIdentity(siteId, slot);
|
|
179
|
+
const expectedRatio = RATIO_VALUE[aspectRatio];
|
|
180
|
+
React3.useEffect(() => {
|
|
181
|
+
if (!ctx) return;
|
|
182
|
+
const isUnique = ctx.registerSlot(slotIdentity);
|
|
183
|
+
if (!isUnique) {
|
|
184
|
+
console.warn(`[Adkit] Duplicate slot "${slot}" detected on this page.`);
|
|
185
|
+
if (!silent) {
|
|
186
|
+
sendEvent({ type: "slot_duplicate", siteId, slot, pathname: window.location.pathname });
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return () => ctx.unregisterSlot(slotIdentity);
|
|
190
|
+
}, [ctx, siteId, slotIdentity, slot, silent]);
|
|
191
|
+
React3.useEffect(() => {
|
|
192
|
+
if (silent || mountedSlots.has(slotIdentity)) return;
|
|
193
|
+
mountedSlots.add(slotIdentity);
|
|
194
|
+
sendEvent({
|
|
195
|
+
type: "slot_mount",
|
|
196
|
+
siteId,
|
|
197
|
+
slot,
|
|
198
|
+
pathname: typeof window !== "undefined" ? window.location.pathname : "",
|
|
199
|
+
price,
|
|
200
|
+
aspectRatio
|
|
201
|
+
});
|
|
202
|
+
}, [siteId, slotIdentity, slot, silent, price, aspectRatio]);
|
|
203
|
+
React3.useEffect(() => {
|
|
204
|
+
const ac = new AbortController();
|
|
205
|
+
fetch(`${SERVE_BASE}/api/serve?slotId=${encodeURIComponent(slotIdentity)}`, { signal: ac.signal }).then((res) => res.json()).then((data) => {
|
|
206
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
207
|
+
const d = data;
|
|
208
|
+
if (d.status === "active" && typeof d.imageUrl === "string" && typeof d.linkUrl === "string") {
|
|
209
|
+
const bookingId = typeof d.bookingId === "string" ? d.bookingId : void 0;
|
|
210
|
+
setServedAd({ status: "active", bookingId, imageUrl: d.imageUrl, linkUrl: d.linkUrl });
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
setServedAd({ status: "empty" });
|
|
215
|
+
}).catch(() => setServedAd({ status: "empty" }));
|
|
216
|
+
return () => ac.abort();
|
|
217
|
+
}, [slotIdentity]);
|
|
218
|
+
React3.useEffect(() => {
|
|
219
|
+
if (silent) return;
|
|
220
|
+
const el = slotRef.current;
|
|
221
|
+
if (!el || typeof IntersectionObserver === "undefined") return;
|
|
222
|
+
const observer = new IntersectionObserver(
|
|
223
|
+
([entry]) => {
|
|
224
|
+
if (entry.isIntersecting && entry.intersectionRatio >= 0.5 && !hasViewedRef.current) {
|
|
225
|
+
hasViewedRef.current = true;
|
|
226
|
+
const payload = {
|
|
227
|
+
type: "slot_view",
|
|
228
|
+
slotId: slotIdentity,
|
|
229
|
+
pathname: window.location.pathname,
|
|
230
|
+
viewport: { width: window.innerWidth, height: window.innerHeight }
|
|
231
|
+
};
|
|
232
|
+
if (bookingIdRef.current) payload.bookingId = bookingIdRef.current;
|
|
233
|
+
sendEvent(payload);
|
|
234
|
+
observer.disconnect();
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
{ threshold: [0.5] }
|
|
238
|
+
);
|
|
239
|
+
observer.observe(el);
|
|
240
|
+
return () => observer.disconnect();
|
|
241
|
+
}, [slotIdentity, siteId, slot, silent]);
|
|
242
|
+
React3.useEffect(() => {
|
|
243
|
+
const el = slotRef.current;
|
|
244
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
245
|
+
const checkRatio = () => {
|
|
246
|
+
const { width, height } = el.getBoundingClientRect();
|
|
247
|
+
if (width === 0 || height === 0) return;
|
|
248
|
+
const diff = Math.abs(width / height - expectedRatio) / expectedRatio;
|
|
249
|
+
if (diff > 0.05) {
|
|
250
|
+
console.warn("[Adkit] Slot aspect ratio mismatch. External CSS may be interfering.");
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
const observer = new ResizeObserver(checkRatio);
|
|
254
|
+
observer.observe(el);
|
|
255
|
+
checkRatio();
|
|
256
|
+
return () => observer.disconnect();
|
|
257
|
+
}, [expectedRatio]);
|
|
258
|
+
const [modalOpen, setModalOpen] = React3.useState(false);
|
|
259
|
+
const sendSlotClick = (bookingId) => {
|
|
260
|
+
if (typeof window === "undefined") return;
|
|
261
|
+
const payload = {
|
|
262
|
+
type: "slot_click",
|
|
263
|
+
slotId: slotIdentity,
|
|
264
|
+
pathname: window.location.pathname,
|
|
265
|
+
viewport: { width: window.innerWidth, height: window.innerHeight }
|
|
266
|
+
};
|
|
267
|
+
if (bookingId) payload.bookingId = bookingId;
|
|
268
|
+
sendEvent(payload);
|
|
269
|
+
};
|
|
270
|
+
const handlePlaceholderClick = () => {
|
|
271
|
+
if (silent) return;
|
|
272
|
+
sendSlotClick();
|
|
273
|
+
setModalOpen(true);
|
|
274
|
+
};
|
|
275
|
+
const handleAdClick = () => {
|
|
276
|
+
if (!silent && servedAd.status === "active") sendSlotClick(servedAd.bookingId);
|
|
277
|
+
};
|
|
278
|
+
const isDark = theme === "dark" ? true : theme === "light" ? false : systemDark;
|
|
279
|
+
const styleVars = {
|
|
280
|
+
"--adkit-aspect": RATIO_CSS[aspectRatio],
|
|
281
|
+
"--adkit-bg": (_a = styles == null ? void 0 : styles.backgroundColor) != null ? _a : "transparent",
|
|
282
|
+
"--adkit-text-muted": (_b = styles == null ? void 0 : styles.textColorSecondary) != null ? _b : isDark ? "rgba(255,255,255,0.6)" : "rgba(0,0,0,0.6)",
|
|
283
|
+
"--adkit-text": (_c = styles == null ? void 0 : styles.textColorSecondary) != null ? _c : isDark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)",
|
|
284
|
+
"--adkit-text-strong": (_d = styles == null ? void 0 : styles.textColorPrimary) != null ? _d : isDark ? "rgba(255,255,255,0.9)" : "rgba(0,0,0,0.9)",
|
|
285
|
+
"--adkit-border": (styles == null ? void 0 : styles.borderColor) ? `color-mix(in srgb, ${styles.borderColor} 40%, transparent)` : isDark ? "rgba(255,255,255,0.22)" : "rgba(0,0,0,0.1)",
|
|
286
|
+
"--adkit-border-hover": (styles == null ? void 0 : styles.borderColor) ? `color-mix(in srgb, ${styles.borderColor} 60%, transparent)` : isDark ? "rgba(255,255,255,0.38)" : "rgba(0,0,0,0.2)"
|
|
287
|
+
};
|
|
288
|
+
const dollars = price / 100;
|
|
289
|
+
const formattedPrice = Number.isInteger(dollars) ? dollars.toLocaleString() : dollars.toLocaleString(void 0, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
290
|
+
const isBanner = aspectRatio === "banner";
|
|
291
|
+
const isActive = servedAd.status === "active";
|
|
292
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
293
|
+
/* @__PURE__ */ jsx2(
|
|
294
|
+
"div",
|
|
295
|
+
{
|
|
296
|
+
ref: slotRef,
|
|
297
|
+
className: `adkit-slot ${className ? className : "adkit-slot--default-width"}`,
|
|
298
|
+
style: styleVars,
|
|
299
|
+
"data-adkit-site": siteId,
|
|
300
|
+
"data-adkit-slot": slot,
|
|
301
|
+
"data-adkit-ratio": aspectRatio,
|
|
302
|
+
"data-adkit-size": size,
|
|
303
|
+
children: /* @__PURE__ */ jsx2("div", { className: "adkit-canvas", children: isActive ? /* @__PURE__ */ jsx2(
|
|
304
|
+
"a",
|
|
305
|
+
{
|
|
306
|
+
id: slot,
|
|
307
|
+
href: servedAd.linkUrl,
|
|
308
|
+
target: "_blank",
|
|
309
|
+
rel: "noopener noreferrer",
|
|
310
|
+
onClick: handleAdClick,
|
|
311
|
+
style: { display: "block", width: "100%", height: "100%" },
|
|
312
|
+
children: /* @__PURE__ */ jsx2(
|
|
313
|
+
"img",
|
|
314
|
+
{
|
|
315
|
+
src: servedAd.imageUrl,
|
|
316
|
+
alt: "",
|
|
317
|
+
style: { display: "block", width: "100%", height: "100%", objectFit: "contain" }
|
|
318
|
+
}
|
|
319
|
+
)
|
|
320
|
+
}
|
|
321
|
+
) : /* @__PURE__ */ jsx2("div", { id: `${slot}-placeholder`, className: "adkit-box", role: "button", tabIndex: 0, onClick: handlePlaceholderClick, children: /* @__PURE__ */ jsxs2("div", { className: "adkit-content", children: [
|
|
322
|
+
/* @__PURE__ */ jsx2("div", { className: "adkit-label", children: "Your ad here" }),
|
|
323
|
+
/* @__PURE__ */ jsxs2("div", { className: "adkit-price", children: [
|
|
324
|
+
"$",
|
|
325
|
+
formattedPrice,
|
|
326
|
+
"/day"
|
|
327
|
+
] }),
|
|
328
|
+
/* @__PURE__ */ jsxs2("div", { className: "adkit-cta", children: [
|
|
329
|
+
isBanner ? "Rent" : "Rent this spot",
|
|
330
|
+
/* @__PURE__ */ jsx2("span", { className: "adkit-arrow", children: "\u2192" })
|
|
331
|
+
] })
|
|
332
|
+
] }) }) })
|
|
333
|
+
}
|
|
334
|
+
),
|
|
335
|
+
!isActive && modalOpen && /* @__PURE__ */ jsx2(
|
|
336
|
+
BookingModal,
|
|
337
|
+
{
|
|
338
|
+
siteId,
|
|
339
|
+
slot,
|
|
340
|
+
price,
|
|
341
|
+
onClose: () => setModalOpen(false)
|
|
342
|
+
}
|
|
343
|
+
)
|
|
344
|
+
] });
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// src/AdkitProvider.tsx
|
|
348
|
+
import * as React4 from "react";
|
|
349
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
350
|
+
function AdkitProvider({ siteId, children }) {
|
|
351
|
+
const slotsRef = React4.useRef(/* @__PURE__ */ new Set());
|
|
352
|
+
const registerSlot = React4.useCallback((identity) => {
|
|
353
|
+
if (slotsRef.current.has(identity)) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
slotsRef.current.add(identity);
|
|
357
|
+
return true;
|
|
358
|
+
}, []);
|
|
359
|
+
const unregisterSlot = React4.useCallback((identity) => {
|
|
360
|
+
slotsRef.current.delete(identity);
|
|
361
|
+
}, []);
|
|
362
|
+
const value = React4.useMemo(
|
|
363
|
+
() => ({ siteId, registerSlot, unregisterSlot }),
|
|
364
|
+
[siteId, registerSlot, unregisterSlot]
|
|
365
|
+
);
|
|
366
|
+
return /* @__PURE__ */ jsx3(AdkitContext.Provider, { value, children });
|
|
367
|
+
}
|
|
368
|
+
export {
|
|
369
|
+
AdSlot,
|
|
370
|
+
AdkitProvider,
|
|
371
|
+
BookingModal,
|
|
372
|
+
useAdkit
|
|
373
|
+
};
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/* src/styles.css */
|
|
2
|
+
.adkit-slot {
|
|
3
|
+
position: relative;
|
|
4
|
+
display: inline-block;
|
|
5
|
+
max-width: 100%;
|
|
6
|
+
flex: 0 0 auto;
|
|
7
|
+
font-family:
|
|
8
|
+
-apple-system,
|
|
9
|
+
BlinkMacSystemFont,
|
|
10
|
+
"Segoe UI",
|
|
11
|
+
"Noto Sans",
|
|
12
|
+
Helvetica,
|
|
13
|
+
Arial,
|
|
14
|
+
sans-serif;
|
|
15
|
+
-webkit-font-smoothing: antialiased;
|
|
16
|
+
}
|
|
17
|
+
.adkit-slot--default-width {
|
|
18
|
+
width: 100%;
|
|
19
|
+
}
|
|
20
|
+
.adkit-slot,
|
|
21
|
+
.adkit-slot *,
|
|
22
|
+
.adkit-canvas {
|
|
23
|
+
height: auto !important;
|
|
24
|
+
min-height: 0 !important;
|
|
25
|
+
max-height: none !important;
|
|
26
|
+
}
|
|
27
|
+
.adkit-canvas {
|
|
28
|
+
position: relative;
|
|
29
|
+
width: 100%;
|
|
30
|
+
aspect-ratio: var(--adkit-aspect) !important;
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
background: var(--adkit-bg);
|
|
33
|
+
}
|
|
34
|
+
.adkit-canvas img {
|
|
35
|
+
width: auto !important;
|
|
36
|
+
height: auto !important;
|
|
37
|
+
max-width: 100% !important;
|
|
38
|
+
max-height: 100% !important;
|
|
39
|
+
object-fit: contain !important;
|
|
40
|
+
}
|
|
41
|
+
.adkit-box {
|
|
42
|
+
position: absolute;
|
|
43
|
+
inset: 0;
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
justify-content: center;
|
|
47
|
+
border: 1.5px dashed var(--adkit-border);
|
|
48
|
+
border-radius: 10px;
|
|
49
|
+
background: transparent;
|
|
50
|
+
cursor: pointer;
|
|
51
|
+
transition: border-color 0.15s ease;
|
|
52
|
+
}
|
|
53
|
+
.adkit-box:hover {
|
|
54
|
+
border-color: var(--adkit-border-hover);
|
|
55
|
+
}
|
|
56
|
+
.adkit-content {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: column;
|
|
59
|
+
align-items: center;
|
|
60
|
+
text-align: center;
|
|
61
|
+
padding: var(--adkit-padding);
|
|
62
|
+
gap: var(--adkit-gap);
|
|
63
|
+
}
|
|
64
|
+
.adkit-slot[data-adkit-ratio=banner] .adkit-content {
|
|
65
|
+
flex-direction: row;
|
|
66
|
+
align-items: center;
|
|
67
|
+
justify-content: flex-start;
|
|
68
|
+
width: 100%;
|
|
69
|
+
gap: 12px;
|
|
70
|
+
}
|
|
71
|
+
.adkit-slot[data-adkit-ratio=banner] .adkit-cta {
|
|
72
|
+
margin-left: auto;
|
|
73
|
+
margin-top: 0;
|
|
74
|
+
}
|
|
75
|
+
.adkit-label {
|
|
76
|
+
font-size: var(--adkit-label-size);
|
|
77
|
+
line-height: 1.2;
|
|
78
|
+
font-weight: 500;
|
|
79
|
+
letter-spacing: 0.04em;
|
|
80
|
+
color: var(--adkit-text-muted);
|
|
81
|
+
}
|
|
82
|
+
.adkit-price {
|
|
83
|
+
font-size: var(--adkit-price-size);
|
|
84
|
+
line-height: 1.1;
|
|
85
|
+
font-weight: 600;
|
|
86
|
+
letter-spacing: -0.02em;
|
|
87
|
+
color: var(--adkit-text-strong);
|
|
88
|
+
}
|
|
89
|
+
.adkit-cta {
|
|
90
|
+
display: inline-flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
gap: 4px;
|
|
93
|
+
margin-top: var(--adkit-cta-mt);
|
|
94
|
+
font-size: var(--adkit-cta-size);
|
|
95
|
+
line-height: 1.25;
|
|
96
|
+
font-weight: 500;
|
|
97
|
+
color: var(--adkit-text);
|
|
98
|
+
transition: color 0.15s ease;
|
|
99
|
+
}
|
|
100
|
+
.adkit-box:hover .adkit-cta {
|
|
101
|
+
color: var(--adkit-text-strong);
|
|
102
|
+
}
|
|
103
|
+
.adkit-arrow {
|
|
104
|
+
opacity: 0.5;
|
|
105
|
+
transition: transform 0.15s ease, opacity 0.15s ease;
|
|
106
|
+
}
|
|
107
|
+
.adkit-box:hover .adkit-arrow {
|
|
108
|
+
transform: translateX(2px);
|
|
109
|
+
opacity: 0.8;
|
|
110
|
+
}
|
|
111
|
+
.adkit-slot[data-adkit-size=sm] {
|
|
112
|
+
--adkit-label-size: 7px;
|
|
113
|
+
--adkit-price-size: 10px;
|
|
114
|
+
--adkit-cta-size: 6px;
|
|
115
|
+
--adkit-gap: 2px;
|
|
116
|
+
--adkit-cta-mt: 4px;
|
|
117
|
+
--adkit-padding: 0 8px;
|
|
118
|
+
}
|
|
119
|
+
.adkit-slot[data-adkit-size=md] {
|
|
120
|
+
--adkit-label-size: 9px;
|
|
121
|
+
--adkit-price-size: 14px;
|
|
122
|
+
--adkit-cta-size: 8px;
|
|
123
|
+
--adkit-gap: 4px;
|
|
124
|
+
--adkit-cta-mt: 8px;
|
|
125
|
+
--adkit-padding: 0 12px;
|
|
126
|
+
}
|
|
127
|
+
.adkit-slot[data-adkit-size=lg] {
|
|
128
|
+
--adkit-label-size: 11px;
|
|
129
|
+
--adkit-price-size: 18px;
|
|
130
|
+
--adkit-cta-size: 10px;
|
|
131
|
+
--adkit-gap: 4px;
|
|
132
|
+
--adkit-cta-mt: 10px;
|
|
133
|
+
--adkit-padding: 0 12px;
|
|
134
|
+
}
|
|
135
|
+
.adkit-modal-overlay {
|
|
136
|
+
position: fixed;
|
|
137
|
+
inset: 0;
|
|
138
|
+
z-index: 999999;
|
|
139
|
+
display: flex;
|
|
140
|
+
align-items: center;
|
|
141
|
+
justify-content: center;
|
|
142
|
+
background: rgba(0, 0, 0, 0.45);
|
|
143
|
+
font-family:
|
|
144
|
+
-apple-system,
|
|
145
|
+
BlinkMacSystemFont,
|
|
146
|
+
"Segoe UI",
|
|
147
|
+
"Noto Sans",
|
|
148
|
+
Helvetica,
|
|
149
|
+
Arial,
|
|
150
|
+
sans-serif;
|
|
151
|
+
-webkit-font-smoothing: antialiased;
|
|
152
|
+
animation: adkit-fade-in 0.18s ease-out;
|
|
153
|
+
}
|
|
154
|
+
.adkit-modal-card {
|
|
155
|
+
position: relative;
|
|
156
|
+
width: 92%;
|
|
157
|
+
max-width: 420px;
|
|
158
|
+
padding: 32px 28px 24px;
|
|
159
|
+
background: #fff;
|
|
160
|
+
border-radius: 14px;
|
|
161
|
+
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
|
|
162
|
+
color: #1a1a1a;
|
|
163
|
+
animation: adkit-slide-up 0.22s ease-out;
|
|
164
|
+
}
|
|
165
|
+
@keyframes adkit-fade-in {
|
|
166
|
+
from {
|
|
167
|
+
opacity: 0;
|
|
168
|
+
}
|
|
169
|
+
to {
|
|
170
|
+
opacity: 1;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
@keyframes adkit-slide-up {
|
|
174
|
+
from {
|
|
175
|
+
opacity: 0;
|
|
176
|
+
transform: translateY(12px) scale(0.97);
|
|
177
|
+
}
|
|
178
|
+
to {
|
|
179
|
+
opacity: 1;
|
|
180
|
+
transform: translateY(0) scale(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
.adkit-modal-headline {
|
|
184
|
+
margin: 0 0 8px;
|
|
185
|
+
font-size: 20px;
|
|
186
|
+
font-weight: 600;
|
|
187
|
+
line-height: 1.3;
|
|
188
|
+
letter-spacing: -0.01em;
|
|
189
|
+
}
|
|
190
|
+
.adkit-modal-subhead {
|
|
191
|
+
margin: 0 0 20px;
|
|
192
|
+
font-size: 14px;
|
|
193
|
+
line-height: 1.5;
|
|
194
|
+
color: #555;
|
|
195
|
+
}
|
|
196
|
+
.adkit-modal-bullets {
|
|
197
|
+
margin: 0 0 20px;
|
|
198
|
+
padding: 0;
|
|
199
|
+
list-style: none;
|
|
200
|
+
font-size: 14px;
|
|
201
|
+
line-height: 1.6;
|
|
202
|
+
color: #333;
|
|
203
|
+
}
|
|
204
|
+
.adkit-modal-bullets li {
|
|
205
|
+
margin-bottom: 4px;
|
|
206
|
+
padding-left: 24px;
|
|
207
|
+
position: relative;
|
|
208
|
+
}
|
|
209
|
+
.adkit-modal-bullets li::before {
|
|
210
|
+
content: "\2713";
|
|
211
|
+
position: absolute;
|
|
212
|
+
left: 0;
|
|
213
|
+
font-weight: 700;
|
|
214
|
+
color: #333;
|
|
215
|
+
}
|
|
216
|
+
.adkit-modal-price-section {
|
|
217
|
+
display: flex;
|
|
218
|
+
flex-direction: column;
|
|
219
|
+
gap: 2px;
|
|
220
|
+
margin-bottom: 24px;
|
|
221
|
+
}
|
|
222
|
+
.adkit-modal-price {
|
|
223
|
+
font-size: 22px;
|
|
224
|
+
font-weight: 700;
|
|
225
|
+
letter-spacing: -0.02em;
|
|
226
|
+
color: #111;
|
|
227
|
+
}
|
|
228
|
+
.adkit-modal-price-helper {
|
|
229
|
+
font-size: 12px;
|
|
230
|
+
color: #888;
|
|
231
|
+
}
|
|
232
|
+
.adkit-modal-actions {
|
|
233
|
+
display: flex;
|
|
234
|
+
flex-direction: column;
|
|
235
|
+
gap: 8px;
|
|
236
|
+
}
|
|
237
|
+
.adkit-modal-cta {
|
|
238
|
+
display: block;
|
|
239
|
+
width: 100%;
|
|
240
|
+
padding: 12px;
|
|
241
|
+
border: none;
|
|
242
|
+
border-radius: 8px;
|
|
243
|
+
background: #111;
|
|
244
|
+
color: #fff;
|
|
245
|
+
font-size: 15px;
|
|
246
|
+
font-weight: 600;
|
|
247
|
+
cursor: pointer;
|
|
248
|
+
text-align: center;
|
|
249
|
+
transition: background 0.15s ease;
|
|
250
|
+
}
|
|
251
|
+
.adkit-modal-cta:hover {
|
|
252
|
+
background: #333;
|
|
253
|
+
}
|
|
254
|
+
.adkit-modal-redirect-hint {
|
|
255
|
+
display: block;
|
|
256
|
+
text-align: center;
|
|
257
|
+
font-size: 11px;
|
|
258
|
+
color: #999;
|
|
259
|
+
line-height: 1.4;
|
|
260
|
+
}
|
|
261
|
+
.adkit-modal-cancel {
|
|
262
|
+
display: block;
|
|
263
|
+
width: 100%;
|
|
264
|
+
padding: 10px;
|
|
265
|
+
border: none;
|
|
266
|
+
border-radius: 8px;
|
|
267
|
+
background: transparent;
|
|
268
|
+
color: #888;
|
|
269
|
+
font-size: 14px;
|
|
270
|
+
font-weight: 500;
|
|
271
|
+
cursor: pointer;
|
|
272
|
+
text-align: center;
|
|
273
|
+
transition: color 0.15s ease;
|
|
274
|
+
}
|
|
275
|
+
.adkit-modal-cancel:hover {
|
|
276
|
+
color: #333;
|
|
277
|
+
}
|
|
278
|
+
.adkit-modal-footer {
|
|
279
|
+
margin-top: 16px;
|
|
280
|
+
text-align: center;
|
|
281
|
+
font-size: 11px;
|
|
282
|
+
color: #bbb;
|
|
283
|
+
letter-spacing: 0.02em;
|
|
284
|
+
}
|
package/dist/styles.d.ts
ADDED