@playruo/embed 1.2.10 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,11 +3,18 @@ import { useEffect, useMemo, useRef, useState, useCallback } from "react";
3
3
 
4
4
  // src/url.ts
5
5
  var PLAYRUO_ORIGIN = "https://playruo.live";
6
- var buildEmbedUrl = ({ operation = "iframe", storeUrl }) => {
6
+ var normalizeOperation = (operation) => {
7
+ const trimmedOperation = operation.trim();
8
+ if (trimmedOperation === "") {
9
+ throw new Error("`operation` is required to build a Playruo embed URL.");
10
+ }
11
+ return trimmedOperation.startsWith("/") ? trimmedOperation.slice(1) : trimmedOperation;
12
+ };
13
+ var buildEmbedUrl = ({ operation, storeUrl }) => {
7
14
  return buildEmbedUrlWithOrigin(PLAYRUO_ORIGIN, { operation, storeUrl });
8
15
  };
9
- var buildEmbedUrlWithOrigin = (origin, { operation = "iframe", storeUrl }) => {
10
- const operationPath = operation.startsWith("/") ? operation.slice(1) : operation;
16
+ var buildEmbedUrlWithOrigin = (origin, { operation, storeUrl }) => {
17
+ const operationPath = normalizeOperation(operation);
11
18
  const url = new URL(`/${operationPath}`, origin);
12
19
  url.searchParams.set("iframe", "true");
13
20
  if (storeUrl) {
@@ -20,7 +27,7 @@ var buildEmbedUrlWithOrigin = (origin, { operation = "iframe", storeUrl }) => {
20
27
  import { jsx, jsxs } from "react/jsx-runtime";
21
28
  var PlayruoEmbed = ({
22
29
  baseUrl,
23
- operation = "iframe",
30
+ operation,
24
31
  storeUrl,
25
32
  showIframe = false,
26
33
  className,
@@ -35,7 +42,6 @@ var PlayruoEmbed = ({
35
42
  const internalIframeRef = useRef(null);
36
43
  const iframeRef = externalIframeRef || internalIframeRef;
37
44
  const wasEmbedFullscreenRef = useRef(false);
38
- const wasEmbedPointerLockedRef = useRef(false);
39
45
  const [isIframeLoaded, setIsIframeLoaded] = useState(false);
40
46
  const [hasPlayedOnce, setHasPlayedOnce] = useState(false);
41
47
  const [showGameIframe, setShowGameIframe] = useState(false);
@@ -117,55 +123,8 @@ var PlayruoEmbed = ({
117
123
  console.warn("[PlayruoEmbed] Failed to lock Escape key:", error);
118
124
  }
119
125
  }, [getKeyboardApi]);
120
- const getPointerLockElement = useCallback(() => {
121
- const doc = document;
122
- return doc.pointerLockElement || doc.mozPointerLockElement || doc.webkitPointerLockElement || null;
123
- }, []);
124
- const releasePointerLock = useCallback(() => {
125
- const doc = document;
126
- const exitPointerLock = doc.exitPointerLock?.bind(doc) || doc.mozExitPointerLock?.bind(doc) || doc.webkitExitPointerLock?.bind(doc);
127
- try {
128
- exitPointerLock?.();
129
- wasEmbedPointerLockedRef.current = false;
130
- } catch (error) {
131
- console.warn("[PlayruoEmbed] Failed to release pointer lock:", error);
132
- }
133
- }, []);
134
126
  const requestImmersiveMode = useCallback(
135
127
  async (iframe) => {
136
- const pointerTarget = iframe;
137
- if (pointerTarget.requestPointerLock) {
138
- try {
139
- const pointerLockResult = pointerTarget.requestPointerLock({ unadjustedMovement: true });
140
- if (pointerLockResult && typeof pointerLockResult.then === "function") {
141
- void pointerLockResult.then(() => {
142
- wasEmbedPointerLockedRef.current = true;
143
- console.log("[PlayruoEmbed] Pointer locked on iframe");
144
- }).catch(async (error) => {
145
- if (error instanceof DOMException && error.name === "NotSupportedError") {
146
- try {
147
- const fallbackResult = pointerTarget.requestPointerLock?.();
148
- if (fallbackResult && typeof fallbackResult.then === "function") {
149
- await fallbackResult;
150
- }
151
- wasEmbedPointerLockedRef.current = true;
152
- console.log("[PlayruoEmbed] Pointer locked on iframe without raw input");
153
- return;
154
- } catch (fallbackError) {
155
- console.warn("[PlayruoEmbed] Failed to lock pointer without raw input:", fallbackError);
156
- return;
157
- }
158
- }
159
- console.warn("[PlayruoEmbed] Failed to lock pointer:", error);
160
- });
161
- } else {
162
- wasEmbedPointerLockedRef.current = true;
163
- console.log("[PlayruoEmbed] Pointer lock requested on iframe");
164
- }
165
- } catch (error) {
166
- console.warn("[PlayruoEmbed] Failed to request pointer lock:", error);
167
- }
168
- }
169
128
  const fullscreenPromise = iframe.requestFullscreen();
170
129
  try {
171
130
  await fullscreenPromise;
@@ -173,11 +132,10 @@ var PlayruoEmbed = ({
173
132
  console.log("[PlayruoEmbed] Fullscreen granted");
174
133
  } catch (error) {
175
134
  releaseEscapeKeyLock();
176
- releasePointerLock();
177
135
  throw error;
178
136
  }
179
137
  },
180
- [releaseEscapeKeyLock, releasePointerLock]
138
+ [releaseEscapeKeyLock]
181
139
  );
182
140
  const handleTryNow = useCallback(async () => {
183
141
  if (!isCompatible) {
@@ -364,10 +322,6 @@ var PlayruoEmbed = ({
364
322
  releaseEscapeKeyLock();
365
323
  if (wasEmbedFullscreenRef.current) {
366
324
  wasEmbedFullscreenRef.current = false;
367
- const isEmbedPointerLocked = Boolean(iframe && getPointerLockElement() === iframe);
368
- if (wasEmbedPointerLockedRef.current || isEmbedPointerLocked) {
369
- releasePointerLock();
370
- }
371
325
  if (iframe) {
372
326
  try {
373
327
  iframe.contentWindow?.postMessage({
@@ -399,33 +353,12 @@ var PlayruoEmbed = ({
399
353
  document.removeEventListener("mozfullscreenchange", handleFullscreenChange);
400
354
  document.removeEventListener("MSFullscreenChange", handleFullscreenChange);
401
355
  };
402
- }, [storeUrl, onDemoCompleted, iframeRef, getPointerLockElement, lockEscapeKey, releaseEscapeKeyLock, releasePointerLock]);
403
- useEffect(() => {
404
- const handlePointerLockChange = () => {
405
- const iframe = iframeRef.current;
406
- wasEmbedPointerLockedRef.current = Boolean(iframe && getPointerLockElement() === iframe);
407
- };
408
- const handlePointerLockError = () => {
409
- wasEmbedPointerLockedRef.current = false;
410
- console.warn("[PlayruoEmbed] Pointer lock request was rejected");
411
- };
412
- document.addEventListener("pointerlockchange", handlePointerLockChange);
413
- document.addEventListener("pointerlockerror", handlePointerLockError);
414
- return () => {
415
- document.removeEventListener("pointerlockchange", handlePointerLockChange);
416
- document.removeEventListener("pointerlockerror", handlePointerLockError);
417
- };
418
- }, [getPointerLockElement, iframeRef]);
356
+ }, [storeUrl, onDemoCompleted, iframeRef, lockEscapeKey, releaseEscapeKeyLock]);
419
357
  useEffect(() => {
420
358
  return () => {
421
359
  releaseEscapeKeyLock();
422
- const iframe = iframeRef.current;
423
- const isEmbedPointerLocked = Boolean(iframe && getPointerLockElement() === iframe);
424
- if (wasEmbedPointerLockedRef.current || isEmbedPointerLocked) {
425
- releasePointerLock();
426
- }
427
360
  };
428
- }, [getPointerLockElement, iframeRef, releaseEscapeKeyLock, releasePointerLock]);
361
+ }, [releaseEscapeKeyLock]);
429
362
  useEffect(() => {
430
363
  const logCrossOriginStatus = () => {
431
364
  const isIsolated = self.crossOriginIsolated;
@@ -575,36 +508,61 @@ var PlayruoEmbed = ({
575
508
  // src/react/embed-tester.tsx
576
509
  import React, { useCallback as useCallback2, useRef as useRef2, useState as useState2 } from "react";
577
510
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
511
+ var createInitialEmbedState = () => ({
512
+ buyNow: { available: false, status: "Not ready" },
513
+ hasPlayedOnce: false,
514
+ isReady: false,
515
+ tryNow: { available: false, status: "Not ready" }
516
+ });
517
+ var createInitialDiagnostics = () => ({
518
+ chromiumBrowser: false,
519
+ crossOriginIsolation: false,
520
+ desktopBrowser: false,
521
+ fullscreenSupported: false,
522
+ gamepadSupported: false,
523
+ iframeAllowsFullscreen: false,
524
+ iframeAllowsGamepad: false,
525
+ iframeAllowsPointerLock: false,
526
+ keyboardLockSupported: false,
527
+ localStorageSupported: false,
528
+ pointerLockSupported: false,
529
+ secureContext: false,
530
+ sharedArrayBufferSupported: false,
531
+ topLevelContext: false,
532
+ webAssemblySupported: false,
533
+ webgl2Supported: false
534
+ });
578
535
  var EmbedTester = (props = {}) => {
579
- const [operation, setOperation] = useState2(props.operation ?? "iframe");
580
- const [storeUrl, setStoreUrl] = useState2(
536
+ const [operationDraft, setOperationDraft] = useState2(props.operation ?? "iframe");
537
+ const [storeUrlDraft, setStoreUrlDraft] = useState2(
538
+ props.storeUrl ?? "https://store.steampowered.com/app/123456"
539
+ );
540
+ const [appliedOperation, setAppliedOperation] = useState2(props.operation ?? "iframe");
541
+ const [appliedStoreUrl, setAppliedStoreUrl] = useState2(
581
542
  props.storeUrl ?? "https://store.steampowered.com/app/123456"
582
543
  );
583
544
  const [key, setKey] = useState2(0);
584
545
  const [hasUserClicked, setHasUserClicked] = useState2(false);
585
546
  const [showIframe, setShowIframe] = useState2(false);
586
- const [embedState, setEmbedState] = useState2({
587
- buyNow: { available: false, status: "Not ready" },
588
- hasPlayedOnce: false,
589
- isReady: false,
590
- tryNow: { available: false, status: "Not ready" }
591
- });
547
+ const [embedState, setEmbedState] = useState2(createInitialEmbedState);
592
548
  const [eventLog, setEventLog] = useState2([]);
593
- const [diagnostics, setDiagnostics] = useState2({
594
- crossOriginIsolation: false,
595
- gamepadSupported: false,
596
- fullscreenSupported: false,
597
- keyboardLockSupported: false
598
- });
549
+ const [diagnostics, setDiagnostics] = useState2(createInitialDiagnostics);
599
550
  const displayHost = props.baseUrl ? new URL(props.baseUrl).host : "playruo.live";
600
551
  const enableConsoleLog = props.enableConsoleLog ?? false;
601
552
  const hasReadyBeenCalled = useRef2(false);
553
+ const nextEventIdRef = useRef2(0);
602
554
  const previousStateRef = useRef2("");
603
555
  const iframeRef = useRef2(null);
556
+ const isOperationPending = operationDraft !== appliedOperation;
557
+ const isStoreUrlPending = storeUrlDraft !== appliedStoreUrl;
558
+ const hasPendingConfigChanges = isOperationPending || isStoreUrlPending;
559
+ const pendingChangeCount = Number(isOperationPending) + Number(isStoreUrlPending);
604
560
  const addEvent = useCallback2(
605
561
  (message) => {
606
562
  const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString();
607
- setEventLog((prev) => [...prev.slice(-10), { message, timestamp }]);
563
+ const id = nextEventIdRef.current;
564
+ nextEventIdRef.current += 1;
565
+ setEventLog((prev) => [...prev.slice(-10), { id, message, timestamp }]);
608
566
  if (enableConsoleLog) {
609
567
  console.log(`[EmbedTester] ${timestamp}: ${message}`);
610
568
  }
@@ -612,18 +570,48 @@ var EmbedTester = (props = {}) => {
612
570
  [enableConsoleLog]
613
571
  );
614
572
  const runDiagnostics = useCallback2(() => {
573
+ const userAgent = navigator.userAgent || navigator.vendor || window.opera || "";
574
+ const isMobileDevice = /android|iPad|iPhone|iPod/i.test(userAgent);
575
+ const hasChrome = !!window.chrome;
576
+ const isChromium = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor);
577
+ const iframeAllow = iframeRef.current?.getAttribute("allow") ?? "";
578
+ const iframeSandbox = iframeRef.current?.getAttribute("sandbox") ?? "";
579
+ const canvas = document.createElement("canvas");
580
+ let localStorageSupported = false;
581
+ try {
582
+ const storageKey = "__playruo_embed_tester__";
583
+ window.localStorage.setItem(storageKey, "1");
584
+ window.localStorage.removeItem(storageKey);
585
+ localStorageSupported = true;
586
+ } catch {
587
+ localStorageSupported = false;
588
+ }
615
589
  const newDiagnostics = {
590
+ chromiumBrowser: hasChrome || isChromium,
616
591
  crossOriginIsolation: !!(window.crossOriginIsolated || window.crossOriginIsolated),
617
- gamepadSupported: "getGamepads" in navigator,
592
+ desktopBrowser: !isMobileDevice,
618
593
  fullscreenSupported: !!(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled),
619
- keyboardLockSupported: "keyboard" in navigator && "lock" in navigator.keyboard
594
+ gamepadSupported: "getGamepads" in navigator,
595
+ iframeAllowsFullscreen: iframeAllow.includes("fullscreen"),
596
+ iframeAllowsGamepad: iframeAllow.includes("gamepad"),
597
+ iframeAllowsPointerLock: iframeSandbox.includes("allow-pointer-lock"),
598
+ keyboardLockSupported: "keyboard" in navigator && "lock" in navigator.keyboard,
599
+ localStorageSupported,
600
+ pointerLockSupported: "requestPointerLock" in HTMLIFrameElement.prototype || "requestPointerLock" in HTMLElement.prototype || "pointerLockElement" in document,
601
+ secureContext: window.isSecureContext,
602
+ sharedArrayBufferSupported: typeof SharedArrayBuffer !== "undefined",
603
+ topLevelContext: window.self === window.top,
604
+ webAssemblySupported: typeof WebAssembly !== "undefined",
605
+ webgl2Supported: !!canvas.getContext("webgl2")
620
606
  };
621
607
  setDiagnostics(newDiagnostics);
622
- addEvent(`\u{1F50D} Diagnostics updated - COI: ${newDiagnostics.crossOriginIsolation}, Gamepad: ${newDiagnostics.gamepadSupported}`);
623
- }, [addEvent]);
608
+ addEvent(
609
+ `\u{1F50D} Diagnostics updated - Browser: ${newDiagnostics.desktopBrowser && newDiagnostics.chromiumBrowser}, COI: ${newDiagnostics.crossOriginIsolation}, Fullscreen: ${newDiagnostics.fullscreenSupported}`
610
+ );
611
+ }, [addEvent, iframeRef]);
624
612
  React.useEffect(() => {
625
613
  runDiagnostics();
626
- }, [runDiagnostics]);
614
+ }, [key, runDiagnostics]);
627
615
  const handleReady = useCallback2(() => {
628
616
  if (!hasReadyBeenCalled.current) {
629
617
  hasReadyBeenCalled.current = true;
@@ -657,279 +645,1068 @@ var EmbedTester = (props = {}) => {
657
645
  addEvent(`Opening store: ${data.storeUrl}`);
658
646
  window.open(data.storeUrl, "_blank");
659
647
  }, [addEvent]);
660
- const handleRestart = useCallback2(() => {
648
+ const resetEmbedSession = useCallback2((message) => {
649
+ setEmbedState(createInitialEmbedState());
661
650
  setKey((prev) => prev + 1);
662
651
  setHasUserClicked(false);
663
652
  setShowIframe(false);
664
653
  hasReadyBeenCalled.current = false;
665
654
  previousStateRef.current = "";
666
- addEvent("Embed restarted");
655
+ addEvent(message);
667
656
  }, [addEvent]);
668
- const buttonStyle = {
669
- padding: "8px 16px",
670
- margin: "4px",
671
- border: "1px solid #404040",
672
- borderRadius: "4px",
673
- backgroundColor: "#2a2a2a",
674
- color: "#e5e5e5",
675
- cursor: "pointer",
676
- fontSize: "14px",
677
- transition: "all 0.2s ease"
657
+ const handleApply = useCallback2(() => {
658
+ if (!hasPendingConfigChanges) {
659
+ return;
660
+ }
661
+ setAppliedOperation(operationDraft);
662
+ setAppliedStoreUrl(storeUrlDraft);
663
+ resetEmbedSession("Applied updated embed settings");
664
+ }, [hasPendingConfigChanges, operationDraft, resetEmbedSession, storeUrlDraft]);
665
+ const handleRestartSession = useCallback2(() => {
666
+ resetEmbedSession("Embed restarted with applied settings");
667
+ }, [resetEmbedSession]);
668
+ const handleResetDrafts = useCallback2(() => {
669
+ setOperationDraft(appliedOperation);
670
+ setStoreUrlDraft(appliedStoreUrl);
671
+ addEvent("Reverted draft changes to the applied configuration");
672
+ }, [addEvent, appliedOperation, appliedStoreUrl]);
673
+ const panelStyle = {
674
+ position: "relative",
675
+ border: "1px solid rgba(148, 163, 184, 0.18)",
676
+ borderRadius: "24px",
677
+ padding: "20px",
678
+ background: "linear-gradient(180deg, rgba(15, 23, 42, 0.88) 0%, rgba(7, 12, 24, 0.96) 100%)",
679
+ boxShadow: "0 24px 80px rgba(0, 0, 0, 0.35)",
680
+ backdropFilter: "blur(18px)"
681
+ };
682
+ const sectionTitleStyle = {
683
+ margin: 0,
684
+ fontSize: "18px",
685
+ fontWeight: 600,
686
+ color: "#f8fafc"
687
+ };
688
+ const labelStyle = {
689
+ display: "flex",
690
+ alignItems: "center",
691
+ justifyContent: "space-between",
692
+ gap: "12px",
693
+ marginBottom: "8px",
694
+ fontSize: "13px",
695
+ fontWeight: 600,
696
+ color: "#dbe7ff"
678
697
  };
698
+ const buildIndicatorStyle = (pending) => ({
699
+ display: "inline-flex",
700
+ alignItems: "center",
701
+ gap: "8px",
702
+ padding: "4px 10px",
703
+ borderRadius: "999px",
704
+ border: pending ? "1px solid rgba(251, 191, 36, 0.28)" : "1px solid rgba(74, 222, 128, 0.22)",
705
+ backgroundColor: pending ? "rgba(245, 158, 11, 0.12)" : "rgba(34, 197, 94, 0.12)",
706
+ color: pending ? "#fbbf24" : "#86efac",
707
+ fontSize: "11px",
708
+ fontWeight: 700,
709
+ letterSpacing: "0.08em",
710
+ textTransform: "uppercase"
711
+ });
712
+ const buildIndicatorDotStyle = (pending) => ({
713
+ width: "8px",
714
+ height: "8px",
715
+ borderRadius: "999px",
716
+ backgroundColor: pending ? "#f59e0b" : "#22c55e",
717
+ boxShadow: pending ? "0 0 0 4px rgba(245, 158, 11, 0.12)" : "0 0 0 4px rgba(34, 197, 94, 0.12)"
718
+ });
719
+ const buildInputShellStyle = (pending) => ({
720
+ display: "flex",
721
+ alignItems: "center",
722
+ gap: "12px",
723
+ border: pending ? "1px solid rgba(245, 158, 11, 0.35)" : "1px solid rgba(148, 163, 184, 0.18)",
724
+ borderRadius: "16px",
725
+ padding: "0 14px",
726
+ background: pending ? "rgba(35, 23, 8, 0.72)" : "rgba(15, 23, 42, 0.7)",
727
+ boxShadow: pending ? "0 0 0 1px rgba(245, 158, 11, 0.08)" : "none"
728
+ });
679
729
  const inputStyle = {
680
730
  width: "100%",
681
- padding: "8px",
682
- margin: "4px 0",
683
- border: "1px solid #404040",
684
- borderRadius: "4px",
685
- backgroundColor: "#1a1a1a",
686
- color: "#e5e5e5",
687
- fontSize: "14px"
731
+ padding: "14px 0",
732
+ border: "none",
733
+ outline: "none",
734
+ backgroundColor: "transparent",
735
+ color: "#f8fafc",
736
+ fontSize: "15px"
688
737
  };
689
- const cardStyle = {
690
- border: "1px solid #333333",
691
- borderRadius: "8px",
692
- padding: "16px",
693
- margin: "8px 0",
694
- backgroundColor: "#1a1a1a"
738
+ const helperTextStyle = {
739
+ margin: "8px 0 0 0",
740
+ color: "#94a3b8",
741
+ fontSize: "12px",
742
+ lineHeight: 1.5
695
743
  };
696
- const statusStyle = {
744
+ const codeStyle = {
697
745
  display: "inline-block",
698
- padding: "4px 8px",
699
- margin: "2px",
700
- borderRadius: "12px",
746
+ padding: "2px 8px",
747
+ borderRadius: "999px",
748
+ backgroundColor: "rgba(148, 163, 184, 0.12)",
749
+ color: "#e2e8f0",
701
750
  fontSize: "12px",
702
- fontWeight: "500"
751
+ fontFamily: '"SF Mono", "Roboto Mono", monospace',
752
+ wordBreak: "break-all"
703
753
  };
704
- const successStatus = { ...statusStyle, backgroundColor: "#0d5d1f", color: "#4ade80" };
705
- const errorStatus = { ...statusStyle, backgroundColor: "#5d1a1a", color: "#f87171" };
706
- return /* @__PURE__ */ jsx2("div", { className: props.className, style: { minHeight: "100vh", padding: "20px", backgroundColor: "#000000", color: "#e5e5e5" }, children: /* @__PURE__ */ jsxs2("div", { style: { maxWidth: "1200px", margin: "0 auto" }, children: [
707
- /* @__PURE__ */ jsx2("h1", { style: { marginBottom: "20px", fontSize: "24px", fontWeight: "bold", color: "#ffffff" }, children: "\u{1F9EA} Playruo Embed Tester" }),
708
- /* @__PURE__ */ jsxs2("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "20px" }, children: [
709
- /* @__PURE__ */ jsxs2("div", { children: [
710
- /* @__PURE__ */ jsxs2("div", { style: cardStyle, children: [
711
- /* @__PURE__ */ jsx2("h3", { style: { margin: "0 0 16px 0", fontSize: "18px", fontWeight: "600", color: "#ffffff" }, children: "Test Controls" }),
712
- /* @__PURE__ */ jsxs2("div", { style: { marginBottom: "12px" }, children: [
713
- /* @__PURE__ */ jsx2("label", { htmlFor: "operation", style: { display: "block", marginBottom: "4px", fontWeight: "500", color: "#d4d4d4" }, children: "Operation" }),
714
- /* @__PURE__ */ jsx2(
715
- "input",
716
- {
717
- style: inputStyle,
718
- onChange: (e) => setOperation(e.target.value),
719
- placeholder: "e.g., iframe",
720
- value: operation
721
- }
722
- )
723
- ] }),
724
- /* @__PURE__ */ jsxs2("div", { style: { marginBottom: "12px" }, children: [
725
- /* @__PURE__ */ jsx2("label", { htmlFor: "storeUrl", style: { display: "block", marginBottom: "4px", fontWeight: "500", color: "#d4d4d4" }, children: "Store URL" }),
726
- /* @__PURE__ */ jsx2(
727
- "input",
728
- {
729
- style: inputStyle,
730
- onChange: (e) => setStoreUrl(e.target.value),
731
- placeholder: "https://store.example.com",
732
- value: storeUrl
733
- }
734
- )
735
- ] }),
754
+ const buildButtonStyle = (variant, disabled = false) => {
755
+ const palette = {
756
+ ghost: {
757
+ background: "rgba(15, 23, 42, 0.5)",
758
+ border: "1px solid rgba(148, 163, 184, 0.18)",
759
+ color: "#dbe7ff"
760
+ },
761
+ primary: {
762
+ background: "linear-gradient(135deg, #38bdf8 0%, #2563eb 100%)",
763
+ border: "1px solid rgba(125, 211, 252, 0.32)",
764
+ color: "#eff6ff"
765
+ },
766
+ secondary: {
767
+ background: "linear-gradient(135deg, rgba(30, 41, 59, 0.92) 0%, rgba(15, 23, 42, 0.98) 100%)",
768
+ border: "1px solid rgba(148, 163, 184, 0.18)",
769
+ color: "#e2e8f0"
770
+ }
771
+ }[variant];
772
+ return {
773
+ display: "inline-flex",
774
+ alignItems: "center",
775
+ justifyContent: "center",
776
+ gap: "10px",
777
+ minHeight: "44px",
778
+ padding: "0 18px",
779
+ borderRadius: "14px",
780
+ background: palette.background,
781
+ border: palette.border,
782
+ color: palette.color,
783
+ cursor: disabled ? "not-allowed" : "pointer",
784
+ opacity: disabled ? 0.45 : 1,
785
+ fontSize: "14px",
786
+ fontWeight: 700,
787
+ letterSpacing: "0.01em",
788
+ transition: "all 0.2s ease",
789
+ boxShadow: variant === "primary" && !disabled ? "0 16px 32px rgba(37, 99, 235, 0.28)" : "none"
790
+ };
791
+ };
792
+ const buildStatusChipStyle = (active) => ({
793
+ display: "inline-flex",
794
+ alignItems: "center",
795
+ gap: "8px",
796
+ padding: "8px 12px",
797
+ borderRadius: "999px",
798
+ backgroundColor: active ? "rgba(34, 197, 94, 0.12)" : "rgba(248, 113, 113, 0.12)",
799
+ border: active ? "1px solid rgba(34, 197, 94, 0.22)" : "1px solid rgba(248, 113, 113, 0.22)",
800
+ color: active ? "#86efac" : "#fca5a5",
801
+ fontSize: "12px",
802
+ fontWeight: 700
803
+ });
804
+ const statusItems = [
805
+ { label: "Ready", value: Boolean(embedState.isReady) },
806
+ { label: "Played", value: Boolean(embedState.hasPlayedOnce) },
807
+ { label: "Try Now", value: Boolean(embedState.tryNow?.available) },
808
+ { label: "Buy Now", value: Boolean(embedState.buyNow?.available) }
809
+ ];
810
+ const diagnosticGroups = [
811
+ {
812
+ title: "Compatibility",
813
+ items: [
814
+ {
815
+ detail: "Playruo currently expects a non-mobile browser.",
816
+ label: "Desktop browser",
817
+ value: diagnostics.desktopBrowser
818
+ },
819
+ {
820
+ detail: "The embed flow is tuned for Chromium-based browsers.",
821
+ label: "Chromium browser",
822
+ value: diagnostics.chromiumBrowser
823
+ },
824
+ {
825
+ detail: "Keyboard lock works best when the page is not itself embedded.",
826
+ label: "Top-level tab",
827
+ value: diagnostics.topLevelContext
828
+ },
829
+ {
830
+ detail: "HTTPS or localhost unlocks the best browser APIs.",
831
+ label: "Secure context",
832
+ value: diagnostics.secureContext
833
+ }
834
+ ]
835
+ },
836
+ {
837
+ title: "Gameplay APIs",
838
+ items: [
839
+ {
840
+ detail: "Needed for the immersive play flow.",
841
+ label: "Fullscreen API",
842
+ value: diagnostics.fullscreenSupported
843
+ },
844
+ {
845
+ detail: "Needed for raw mouse capture on the iframe.",
846
+ label: "Pointer lock",
847
+ value: diagnostics.pointerLockSupported
848
+ },
849
+ {
850
+ detail: "Used to keep Escape reserved while fullscreen is active.",
851
+ label: "Keyboard lock",
852
+ value: diagnostics.keyboardLockSupported
853
+ },
854
+ {
855
+ detail: "Lets the game read connected controllers.",
856
+ label: "Gamepad API",
857
+ value: diagnostics.gamepadSupported
858
+ }
859
+ ]
860
+ },
861
+ {
862
+ title: "Performance",
863
+ items: [
864
+ {
865
+ detail: "Improves the overall runtime budget for the experience.",
866
+ label: "Cross-origin isolated",
867
+ value: diagnostics.crossOriginIsolation
868
+ },
869
+ {
870
+ detail: "Important for heavier threaded workloads.",
871
+ label: "SharedArrayBuffer",
872
+ value: diagnostics.sharedArrayBufferSupported
873
+ },
874
+ {
875
+ detail: "Confirms modern rendering features are reachable.",
876
+ label: "WebGL2",
877
+ value: diagnostics.webgl2Supported
878
+ },
879
+ {
880
+ detail: "Confirms the runtime can execute compiled game code paths.",
881
+ label: "WebAssembly",
882
+ value: diagnostics.webAssemblySupported
883
+ }
884
+ ]
885
+ },
886
+ {
887
+ title: "Embed wiring",
888
+ items: [
889
+ {
890
+ detail: "The iframe allow list includes fullscreen access.",
891
+ label: "Iframe fullscreen allow",
892
+ value: diagnostics.iframeAllowsFullscreen
893
+ },
894
+ {
895
+ detail: "The iframe allow list includes gamepad access.",
896
+ label: "Iframe gamepad allow",
897
+ value: diagnostics.iframeAllowsGamepad
898
+ },
899
+ {
900
+ detail: "The iframe sandbox includes pointer-lock permission.",
901
+ label: "Iframe pointer-lock allow",
902
+ value: diagnostics.iframeAllowsPointerLock
903
+ },
904
+ {
905
+ detail: "Needed for UUID persistence and session continuity.",
906
+ label: "Local storage",
907
+ value: diagnostics.localStorageSupported
908
+ }
909
+ ]
910
+ }
911
+ ];
912
+ const criticalDiagnosticChecks = [
913
+ { label: "Desktop browser", value: diagnostics.desktopBrowser },
914
+ { label: "Chromium browser", value: diagnostics.chromiumBrowser },
915
+ { label: "Fullscreen API", value: diagnostics.fullscreenSupported },
916
+ { label: "Pointer lock", value: diagnostics.pointerLockSupported }
917
+ ];
918
+ const warningDiagnosticChecks = [
919
+ { label: "Top-level tab", value: diagnostics.topLevelContext },
920
+ { label: "Secure context", value: diagnostics.secureContext },
921
+ { label: "Cross-origin isolation", value: diagnostics.crossOriginIsolation },
922
+ { label: "SharedArrayBuffer", value: diagnostics.sharedArrayBufferSupported },
923
+ { label: "Keyboard lock", value: diagnostics.keyboardLockSupported },
924
+ { label: "Gamepad API", value: diagnostics.gamepadSupported },
925
+ { label: "WebGL2", value: diagnostics.webgl2Supported }
926
+ ];
927
+ const blockingDiagnostics = criticalDiagnosticChecks.filter((item) => !item.value);
928
+ const advisoryDiagnostics = warningDiagnosticChecks.filter((item) => !item.value);
929
+ const diagnosticsVerdict = blockingDiagnostics.length > 0 ? {
930
+ label: "Blocked",
931
+ tone: "#fca5a5",
932
+ background: "rgba(127, 29, 29, 0.28)",
933
+ border: "1px solid rgba(248, 113, 113, 0.24)",
934
+ text: "A core requirement is missing for the intended embed flow."
935
+ } : advisoryDiagnostics.length > 0 ? {
936
+ label: "Limited",
937
+ tone: "#fde68a",
938
+ background: "rgba(120, 53, 15, 0.24)",
939
+ border: "1px solid rgba(245, 158, 11, 0.22)",
940
+ text: "The embed should run, but some features or performance may be reduced."
941
+ } : {
942
+ label: "Ready",
943
+ tone: "#86efac",
944
+ background: "rgba(20, 83, 45, 0.24)",
945
+ border: "1px solid rgba(34, 197, 94, 0.22)",
946
+ text: "All key browser, performance, and iframe capabilities are present."
947
+ };
948
+ return /* @__PURE__ */ jsxs2(
949
+ "div",
950
+ {
951
+ className: props.className,
952
+ style: {
953
+ position: "relative",
954
+ minHeight: "100vh",
955
+ overflow: "hidden",
956
+ padding: "32px 20px 48px",
957
+ background: "radial-gradient(circle at top left, rgba(56, 189, 248, 0.18) 0%, rgba(2, 6, 23, 0) 34%), radial-gradient(circle at 85% 10%, rgba(37, 99, 235, 0.18) 0%, rgba(2, 6, 23, 0) 26%), linear-gradient(180deg, #020617 0%, #050816 48%, #020617 100%)",
958
+ color: "#e5e7eb"
959
+ },
960
+ children: [
961
+ /* @__PURE__ */ jsxs2(
962
+ "div",
963
+ {
964
+ style: {
965
+ position: "absolute",
966
+ inset: 0,
967
+ overflow: "hidden",
968
+ pointerEvents: "none"
969
+ },
970
+ children: [
971
+ /* @__PURE__ */ jsx2(
972
+ "div",
973
+ {
974
+ style: {
975
+ position: "absolute",
976
+ top: "-120px",
977
+ left: "-120px",
978
+ width: "320px",
979
+ height: "320px",
980
+ borderRadius: "999px",
981
+ background: "rgba(56, 189, 248, 0.12)",
982
+ filter: "blur(60px)"
983
+ }
984
+ }
985
+ ),
986
+ /* @__PURE__ */ jsx2(
987
+ "div",
988
+ {
989
+ style: {
990
+ position: "absolute",
991
+ right: "-80px",
992
+ top: "120px",
993
+ width: "280px",
994
+ height: "280px",
995
+ borderRadius: "999px",
996
+ background: "rgba(37, 99, 235, 0.12)",
997
+ filter: "blur(60px)"
998
+ }
999
+ }
1000
+ )
1001
+ ]
1002
+ }
1003
+ ),
1004
+ /* @__PURE__ */ jsxs2("div", { style: { position: "relative", maxWidth: "1280px", margin: "0 auto" }, children: [
736
1005
  /* @__PURE__ */ jsx2(
737
- "button",
1006
+ "div",
738
1007
  {
739
- type: "button",
740
1008
  style: {
741
- ...buttonStyle,
742
- backgroundColor: "#0066cc",
743
- color: "#ffffff",
744
- border: "none",
745
- fontWeight: "600"
1009
+ ...panelStyle,
1010
+ marginBottom: "24px",
1011
+ padding: "28px",
1012
+ background: "linear-gradient(135deg, rgba(15, 23, 42, 0.92) 0%, rgba(8, 15, 30, 0.98) 55%, rgba(15, 23, 42, 0.92) 100%)"
746
1013
  },
747
- onClick: handleRestart,
748
- onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "#0052a3",
749
- onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "#0066cc",
750
- children: "\u{1F504} Restart Embed"
1014
+ children: /* @__PURE__ */ jsxs2(
1015
+ "div",
1016
+ {
1017
+ style: {
1018
+ display: "flex",
1019
+ flexWrap: "wrap",
1020
+ gap: "20px",
1021
+ justifyContent: "space-between",
1022
+ alignItems: "flex-start"
1023
+ },
1024
+ children: [
1025
+ /* @__PURE__ */ jsxs2("div", { style: { maxWidth: "720px" }, children: [
1026
+ /* @__PURE__ */ jsx2(
1027
+ "div",
1028
+ {
1029
+ style: {
1030
+ display: "inline-flex",
1031
+ alignItems: "center",
1032
+ gap: "10px",
1033
+ padding: "6px 12px",
1034
+ borderRadius: "999px",
1035
+ backgroundColor: "rgba(56, 189, 248, 0.12)",
1036
+ border: "1px solid rgba(125, 211, 252, 0.18)",
1037
+ color: "#7dd3fc",
1038
+ fontSize: "11px",
1039
+ fontWeight: 700,
1040
+ letterSpacing: "0.12em",
1041
+ textTransform: "uppercase"
1042
+ },
1043
+ children: "\u{1F9EA} Playruo QA Surface"
1044
+ }
1045
+ ),
1046
+ /* @__PURE__ */ jsx2(
1047
+ "h1",
1048
+ {
1049
+ style: {
1050
+ margin: "16px 0 12px 0",
1051
+ fontSize: "clamp(32px, 4vw, 46px)",
1052
+ lineHeight: 1.05,
1053
+ letterSpacing: "-0.04em",
1054
+ color: "#f8fafc"
1055
+ },
1056
+ children: "Embed Tester"
1057
+ }
1058
+ ),
1059
+ /* @__PURE__ */ jsx2(
1060
+ "p",
1061
+ {
1062
+ style: {
1063
+ margin: 0,
1064
+ maxWidth: "640px",
1065
+ color: "#94a3b8",
1066
+ fontSize: "16px",
1067
+ lineHeight: 1.7
1068
+ },
1069
+ children: "Edit configuration safely, apply changes only when you decide to, and keep runtime feedback visible without the UI fighting your typing."
1070
+ }
1071
+ )
1072
+ ] }),
1073
+ /* @__PURE__ */ jsxs2(
1074
+ "div",
1075
+ {
1076
+ style: {
1077
+ display: "grid",
1078
+ gap: "12px",
1079
+ gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))",
1080
+ flex: "1 1 320px"
1081
+ },
1082
+ children: [
1083
+ /* @__PURE__ */ jsxs2(
1084
+ "div",
1085
+ {
1086
+ style: {
1087
+ padding: "16px",
1088
+ borderRadius: "18px",
1089
+ backgroundColor: "rgba(15, 23, 42, 0.72)",
1090
+ border: "1px solid rgba(148, 163, 184, 0.14)"
1091
+ },
1092
+ children: [
1093
+ /* @__PURE__ */ jsx2("div", { style: { fontSize: "12px", color: "#94a3b8", marginBottom: "8px" }, children: "Active host" }),
1094
+ /* @__PURE__ */ jsx2("div", { style: { color: "#f8fafc", fontSize: "16px", fontWeight: 700 }, children: displayHost })
1095
+ ]
1096
+ }
1097
+ ),
1098
+ /* @__PURE__ */ jsxs2(
1099
+ "div",
1100
+ {
1101
+ style: {
1102
+ padding: "16px",
1103
+ borderRadius: "18px",
1104
+ backgroundColor: hasPendingConfigChanges ? "rgba(35, 23, 8, 0.72)" : "rgba(15, 23, 42, 0.72)",
1105
+ border: hasPendingConfigChanges ? "1px solid rgba(245, 158, 11, 0.24)" : "1px solid rgba(148, 163, 184, 0.14)"
1106
+ },
1107
+ children: [
1108
+ /* @__PURE__ */ jsx2("div", { style: { fontSize: "12px", color: "#94a3b8", marginBottom: "8px" }, children: "Config state" }),
1109
+ /* @__PURE__ */ jsxs2(
1110
+ "div",
1111
+ {
1112
+ style: {
1113
+ display: "flex",
1114
+ alignItems: "center",
1115
+ gap: "10px",
1116
+ color: hasPendingConfigChanges ? "#fbbf24" : "#86efac",
1117
+ fontSize: "16px",
1118
+ fontWeight: 700
1119
+ },
1120
+ children: [
1121
+ /* @__PURE__ */ jsx2("span", { style: buildIndicatorDotStyle(hasPendingConfigChanges) }),
1122
+ hasPendingConfigChanges ? `${pendingChangeCount} pending change(s)` : "Everything applied"
1123
+ ]
1124
+ }
1125
+ )
1126
+ ]
1127
+ }
1128
+ )
1129
+ ]
1130
+ }
1131
+ )
1132
+ ]
1133
+ }
1134
+ )
751
1135
  }
752
- )
753
- ] }),
754
- /* @__PURE__ */ jsxs2("div", { style: cardStyle, children: [
755
- /* @__PURE__ */ jsx2("h3", { style: { margin: "0 0 16px 0", fontSize: "18px", fontWeight: "600", color: "#ffffff" }, children: "Status" }),
756
- /* @__PURE__ */ jsxs2("div", { children: [
757
- /* @__PURE__ */ jsx2("span", { style: embedState.isReady ? successStatus : errorStatus, children: embedState.isReady ? "\u2705 Ready" : "\u274C Not Ready" }),
758
- /* @__PURE__ */ jsx2("span", { style: embedState.hasPlayedOnce ? successStatus : errorStatus, children: embedState.hasPlayedOnce ? "\u2705 Played" : "\u274C Not Played" }),
759
- /* @__PURE__ */ jsx2("span", { style: embedState.tryNow?.available ? successStatus : errorStatus, children: embedState.tryNow?.available ? "\u2705 Try Now" : "\u274C Try Now" }),
760
- /* @__PURE__ */ jsx2("span", { style: embedState.buyNow?.available ? successStatus : errorStatus, children: embedState.buyNow?.available ? "\u2705 Buy Now" : "\u274C Buy Now" })
761
- ] }),
762
- !embedState.tryNow?.available && embedState.tryNow?.status && /* @__PURE__ */ jsxs2("p", { style: { margin: "8px 0 0 0", fontSize: "12px", color: "#a3a3a3" }, children: [
763
- "Try Now reason: ",
764
- embedState.tryNow.status
765
- ] })
766
- ] }),
767
- /* @__PURE__ */ jsxs2("div", { style: cardStyle, children: [
768
- /* @__PURE__ */ jsx2("h3", { style: { margin: "0 0 16px 0", fontSize: "18px", fontWeight: "600", color: "#ffffff" }, children: "\u{1F50D} Browser Diagnostics" }),
769
- /* @__PURE__ */ jsxs2("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "8px" }, children: [
770
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
771
- /* @__PURE__ */ jsx2("span", { style: diagnostics.crossOriginIsolation ? successStatus : errorStatus, children: diagnostics.crossOriginIsolation ? "\u2705" : "\u274C" }),
772
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "12px", color: "#d4d4d4" }, children: "Cross-Origin Isolation" })
773
- ] }),
774
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
775
- /* @__PURE__ */ jsx2("span", { style: diagnostics.gamepadSupported ? successStatus : errorStatus, children: diagnostics.gamepadSupported ? "\u2705" : "\u274C" }),
776
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "12px", color: "#d4d4d4" }, children: "Gamepad API" })
777
- ] }),
778
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
779
- /* @__PURE__ */ jsx2("span", { style: diagnostics.fullscreenSupported ? successStatus : errorStatus, children: diagnostics.fullscreenSupported ? "\u2705" : "\u274C" }),
780
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "12px", color: "#d4d4d4" }, children: "Fullscreen API" })
781
- ] }),
782
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
783
- /* @__PURE__ */ jsx2("span", { style: diagnostics.keyboardLockSupported ? successStatus : errorStatus, children: diagnostics.keyboardLockSupported ? "\u2705" : "\u274C" }),
784
- /* @__PURE__ */ jsx2("span", { style: { fontSize: "12px", color: "#d4d4d4" }, children: "Keyboard Lock" })
785
- ] })
786
- ] })
787
- ] }),
788
- /* @__PURE__ */ jsxs2("div", { style: cardStyle, children: [
789
- /* @__PURE__ */ jsx2("h3", { style: { margin: "0 0 16px 0", fontSize: "18px", fontWeight: "600", color: "#ffffff" }, children: "Event Log" }),
790
- /* @__PURE__ */ jsx2("div", { style: {
791
- backgroundColor: "#0a0a0a",
792
- padding: "12px",
793
- borderRadius: "4px",
794
- minHeight: "200px",
795
- height: "min(50vh, 480px)",
796
- overflowY: "auto",
797
- fontFamily: "monospace",
798
- fontSize: "12px",
799
- border: "1px solid #333333"
800
- }, children: eventLog.length ? /* @__PURE__ */ jsx2("div", { children: eventLog.map((event) => /* @__PURE__ */ jsxs2("div", { style: { marginBottom: "4px" }, children: [
801
- /* @__PURE__ */ jsxs2("span", { style: { color: "#737373" }, children: [
802
- "[",
803
- event.timestamp,
804
- "]"
805
- ] }),
806
- " ",
807
- /* @__PURE__ */ jsx2("span", { style: { color: "#e5e5e5" }, children: event.message })
808
- ] }, event.timestamp)) }) : /* @__PURE__ */ jsx2("div", { style: { color: "#737373" }, children: "No events yet..." }) })
809
- ] })
810
- ] }),
811
- /* @__PURE__ */ jsx2("div", { children: /* @__PURE__ */ jsxs2("div", { style: cardStyle, children: [
812
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "16px" }, children: [
813
- /* @__PURE__ */ jsx2("h3", { style: { margin: "0", fontSize: "18px", fontWeight: "600", color: "#ffffff" }, children: "Embed Container" }),
814
- /* @__PURE__ */ jsxs2("span", { style: {
815
- backgroundColor: "#2a2a2a",
816
- color: "#e5e5e5",
817
- padding: "4px 8px",
818
- borderRadius: "12px",
819
- fontSize: "12px",
820
- fontWeight: "500",
821
- border: "1px solid #404040"
822
- }, children: [
823
- "\u{1F9EA} ",
824
- displayHost
825
- ] })
826
- ] }),
827
- /* @__PURE__ */ jsx2("div", { style: {
828
- position: "relative",
829
- minHeight: "500px",
830
- overflow: "hidden",
831
- borderRadius: "8px",
832
- border: "1px solid #333333",
833
- backgroundColor: "#0a0a0a"
834
- }, children: /* @__PURE__ */ jsx2(
835
- PlayruoEmbed,
836
- {
837
- baseUrl: props.baseUrl,
838
- className: "w-full h-full absolute inset-0",
839
- iframeRef,
840
- onDemoCompleted: handleDemoCompleted,
841
- onError: handleError,
842
- onPurchaseRequest: handlePurchaseRequest,
843
- onReady: handleReady,
844
- onStateChange: handleStateChange,
845
- operation,
846
- renderState: ({ actions, message, status }) => /* @__PURE__ */ jsx2(Fragment, { children: !hasUserClicked && /* @__PURE__ */ jsxs2("div", { style: {
847
- position: "absolute",
848
- inset: "0",
849
- display: "flex",
850
- flexDirection: "column",
851
- alignItems: "center",
852
- justifyContent: "center",
853
- gap: "16px",
854
- backgroundColor: "rgba(0, 0, 0, 0.85)",
855
- backdropFilter: "blur(8px)",
856
- zIndex: 50,
857
- padding: "20px"
858
- }, children: [
859
- /* @__PURE__ */ jsxs2("p", { style: { margin: "0", fontSize: "14px", color: "#d4d4d4" }, children: [
860
- "Status: ",
861
- /* @__PURE__ */ jsx2("span", { style: { color: "#ffffff", fontWeight: "600" }, children: status })
1136
+ ),
1137
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexWrap: "wrap", gap: "24px", alignItems: "flex-start" }, children: [
1138
+ /* @__PURE__ */ jsxs2("div", { style: { flex: "1 1 380px", minWidth: "320px" }, children: [
1139
+ /* @__PURE__ */ jsxs2("div", { style: { ...panelStyle, marginBottom: "18px" }, children: [
1140
+ /* @__PURE__ */ jsxs2(
1141
+ "div",
1142
+ {
1143
+ style: {
1144
+ display: "flex",
1145
+ flexWrap: "wrap",
1146
+ justifyContent: "space-between",
1147
+ gap: "12px",
1148
+ marginBottom: "18px"
1149
+ },
1150
+ children: [
1151
+ /* @__PURE__ */ jsxs2("div", { children: [
1152
+ /* @__PURE__ */ jsx2("h3", { style: sectionTitleStyle, children: "Configuration" }),
1153
+ /* @__PURE__ */ jsxs2("p", { style: { ...helperTextStyle, marginTop: "6px" }, children: [
1154
+ "Draft values stay local until you press ",
1155
+ /* @__PURE__ */ jsx2("strong", { style: { color: "#e2e8f0" }, children: "Apply" }),
1156
+ "."
1157
+ ] })
1158
+ ] }),
1159
+ /* @__PURE__ */ jsxs2("div", { style: buildIndicatorStyle(hasPendingConfigChanges), children: [
1160
+ /* @__PURE__ */ jsx2("span", { style: buildIndicatorDotStyle(hasPendingConfigChanges) }),
1161
+ hasPendingConfigChanges ? "Not applied" : "Applied"
1162
+ ] })
1163
+ ]
1164
+ }
1165
+ ),
1166
+ /* @__PURE__ */ jsxs2("div", { style: { display: "grid", gap: "16px" }, children: [
1167
+ /* @__PURE__ */ jsxs2("div", { children: [
1168
+ /* @__PURE__ */ jsxs2("label", { htmlFor: "operation", style: labelStyle, children: [
1169
+ /* @__PURE__ */ jsx2("span", { children: "Operation" }),
1170
+ /* @__PURE__ */ jsxs2("span", { style: buildIndicatorStyle(isOperationPending), children: [
1171
+ /* @__PURE__ */ jsx2("span", { style: buildIndicatorDotStyle(isOperationPending) }),
1172
+ isOperationPending ? "Pending" : "Live"
1173
+ ] })
1174
+ ] }),
1175
+ /* @__PURE__ */ jsxs2("div", { style: buildInputShellStyle(isOperationPending), children: [
1176
+ /* @__PURE__ */ jsx2(
1177
+ "input",
1178
+ {
1179
+ id: "operation",
1180
+ style: inputStyle,
1181
+ onChange: (e) => setOperationDraft(e.target.value),
1182
+ placeholder: "e.g. iframe",
1183
+ value: operationDraft
1184
+ }
1185
+ ),
1186
+ isOperationPending && /* @__PURE__ */ jsx2(
1187
+ "span",
1188
+ {
1189
+ "aria-hidden": "true",
1190
+ style: {
1191
+ fontSize: "16px",
1192
+ color: "#fbbf24",
1193
+ fontWeight: 700
1194
+ },
1195
+ children: "!"
1196
+ }
1197
+ )
1198
+ ] }),
1199
+ /* @__PURE__ */ jsxs2("p", { style: helperTextStyle, children: [
1200
+ "Applied value: ",
1201
+ /* @__PURE__ */ jsx2("code", { style: codeStyle, children: appliedOperation })
1202
+ ] })
1203
+ ] }),
1204
+ /* @__PURE__ */ jsxs2("div", { children: [
1205
+ /* @__PURE__ */ jsxs2("label", { htmlFor: "storeUrl", style: labelStyle, children: [
1206
+ /* @__PURE__ */ jsx2("span", { children: "Store URL" }),
1207
+ /* @__PURE__ */ jsxs2("span", { style: buildIndicatorStyle(isStoreUrlPending), children: [
1208
+ /* @__PURE__ */ jsx2("span", { style: buildIndicatorDotStyle(isStoreUrlPending) }),
1209
+ isStoreUrlPending ? "Pending" : "Live"
1210
+ ] })
1211
+ ] }),
1212
+ /* @__PURE__ */ jsxs2("div", { style: buildInputShellStyle(isStoreUrlPending), children: [
1213
+ /* @__PURE__ */ jsx2(
1214
+ "input",
1215
+ {
1216
+ id: "storeUrl",
1217
+ style: inputStyle,
1218
+ onChange: (e) => setStoreUrlDraft(e.target.value),
1219
+ placeholder: "https://store.example.com",
1220
+ value: storeUrlDraft
1221
+ }
1222
+ ),
1223
+ isStoreUrlPending && /* @__PURE__ */ jsx2(
1224
+ "span",
1225
+ {
1226
+ "aria-hidden": "true",
1227
+ style: {
1228
+ fontSize: "16px",
1229
+ color: "#fbbf24",
1230
+ fontWeight: 700
1231
+ },
1232
+ children: "!"
1233
+ }
1234
+ )
1235
+ ] }),
1236
+ /* @__PURE__ */ jsxs2("p", { style: helperTextStyle, children: [
1237
+ "Applied value: ",
1238
+ /* @__PURE__ */ jsx2("code", { style: codeStyle, children: appliedStoreUrl })
1239
+ ] })
1240
+ ] })
1241
+ ] }),
1242
+ /* @__PURE__ */ jsxs2(
1243
+ "div",
1244
+ {
1245
+ style: {
1246
+ display: "flex",
1247
+ flexWrap: "wrap",
1248
+ gap: "12px",
1249
+ marginTop: "20px"
1250
+ },
1251
+ children: [
1252
+ /* @__PURE__ */ jsx2(
1253
+ "button",
1254
+ {
1255
+ type: "button",
1256
+ style: buildButtonStyle("primary", !hasPendingConfigChanges),
1257
+ disabled: !hasPendingConfigChanges,
1258
+ onClick: handleApply,
1259
+ children: "Apply"
1260
+ }
1261
+ ),
1262
+ /* @__PURE__ */ jsx2(
1263
+ "button",
1264
+ {
1265
+ type: "button",
1266
+ style: buildButtonStyle("secondary"),
1267
+ onClick: handleRestartSession,
1268
+ children: "Restart Session"
1269
+ }
1270
+ ),
1271
+ /* @__PURE__ */ jsx2(
1272
+ "button",
1273
+ {
1274
+ type: "button",
1275
+ style: buildButtonStyle("ghost", !hasPendingConfigChanges),
1276
+ disabled: !hasPendingConfigChanges,
1277
+ onClick: handleResetDrafts,
1278
+ children: "Reset Drafts"
1279
+ }
1280
+ )
1281
+ ]
1282
+ }
1283
+ )
1284
+ ] }),
1285
+ /* @__PURE__ */ jsxs2("div", { style: { ...panelStyle, marginBottom: "18px" }, children: [
1286
+ /* @__PURE__ */ jsx2("h3", { style: sectionTitleStyle, children: "Runtime status" }),
1287
+ /* @__PURE__ */ jsx2("div", { style: { display: "flex", flexWrap: "wrap", gap: "10px", marginTop: "16px" }, children: statusItems.map((item) => /* @__PURE__ */ jsxs2("span", { style: buildStatusChipStyle(item.value), children: [
1288
+ /* @__PURE__ */ jsx2("span", { children: item.value ? "\u25CF" : "\u25CB" }),
1289
+ item.label
1290
+ ] }, item.label)) }),
1291
+ !embedState.tryNow?.available && embedState.tryNow?.status && /* @__PURE__ */ jsxs2("p", { style: { ...helperTextStyle, marginTop: "14px" }, children: [
1292
+ "Try Now reason: ",
1293
+ /* @__PURE__ */ jsx2("span", { style: { color: "#cbd5e1" }, children: embedState.tryNow.status })
1294
+ ] })
862
1295
  ] }),
863
- message && /* @__PURE__ */ jsx2("p", { style: { margin: "0", fontSize: "14px", color: "#d4d4d4" }, children: message }),
1296
+ /* @__PURE__ */ jsxs2("div", { style: { ...panelStyle, marginBottom: "18px" }, children: [
1297
+ /* @__PURE__ */ jsx2("h3", { style: sectionTitleStyle, children: "Browser diagnostics" }),
1298
+ /* @__PURE__ */ jsxs2(
1299
+ "div",
1300
+ {
1301
+ style: {
1302
+ marginTop: "16px",
1303
+ padding: "16px 18px",
1304
+ borderRadius: "20px",
1305
+ background: diagnosticsVerdict.background,
1306
+ border: diagnosticsVerdict.border
1307
+ },
1308
+ children: [
1309
+ /* @__PURE__ */ jsxs2(
1310
+ "div",
1311
+ {
1312
+ style: {
1313
+ display: "flex",
1314
+ flexWrap: "wrap",
1315
+ justifyContent: "space-between",
1316
+ gap: "12px",
1317
+ alignItems: "center"
1318
+ },
1319
+ children: [
1320
+ /* @__PURE__ */ jsxs2("div", { children: [
1321
+ /* @__PURE__ */ jsx2(
1322
+ "div",
1323
+ {
1324
+ style: {
1325
+ color: diagnosticsVerdict.tone,
1326
+ fontSize: "12px",
1327
+ fontWeight: 700,
1328
+ letterSpacing: "0.1em",
1329
+ textTransform: "uppercase"
1330
+ },
1331
+ children: "Diagnostics verdict"
1332
+ }
1333
+ ),
1334
+ /* @__PURE__ */ jsx2("div", { style: { color: "#f8fafc", fontSize: "20px", fontWeight: 700, marginTop: "6px" }, children: diagnosticsVerdict.label })
1335
+ ] }),
1336
+ /* @__PURE__ */ jsx2("div", { style: { color: "#cbd5e1", fontSize: "13px", maxWidth: "420px", lineHeight: 1.6 }, children: diagnosticsVerdict.text })
1337
+ ]
1338
+ }
1339
+ ),
1340
+ (blockingDiagnostics.length > 0 || advisoryDiagnostics.length > 0) && /* @__PURE__ */ jsxs2(
1341
+ "div",
1342
+ {
1343
+ style: {
1344
+ display: "grid",
1345
+ gap: "10px",
1346
+ marginTop: "16px"
1347
+ },
1348
+ children: [
1349
+ blockingDiagnostics.length > 0 && /* @__PURE__ */ jsxs2("div", { style: { color: "#fca5a5", fontSize: "13px", lineHeight: 1.6 }, children: [
1350
+ "Blocking: ",
1351
+ blockingDiagnostics.map((item) => item.label).join(", ")
1352
+ ] }),
1353
+ advisoryDiagnostics.length > 0 && /* @__PURE__ */ jsxs2("div", { style: { color: "#fde68a", fontSize: "13px", lineHeight: 1.6 }, children: [
1354
+ "Worth checking: ",
1355
+ advisoryDiagnostics.map((item) => item.label).join(", ")
1356
+ ] })
1357
+ ]
1358
+ }
1359
+ )
1360
+ ]
1361
+ }
1362
+ ),
1363
+ /* @__PURE__ */ jsx2(
1364
+ "div",
1365
+ {
1366
+ style: {
1367
+ display: "grid",
1368
+ gap: "14px",
1369
+ marginTop: "18px"
1370
+ },
1371
+ children: diagnosticGroups.map((group) => /* @__PURE__ */ jsxs2(
1372
+ "div",
1373
+ {
1374
+ style: {
1375
+ padding: "16px",
1376
+ borderRadius: "20px",
1377
+ backgroundColor: "rgba(15, 23, 42, 0.42)",
1378
+ border: "1px solid rgba(148, 163, 184, 0.12)"
1379
+ },
1380
+ children: [
1381
+ /* @__PURE__ */ jsx2(
1382
+ "div",
1383
+ {
1384
+ style: {
1385
+ color: "#e2e8f0",
1386
+ fontSize: "14px",
1387
+ fontWeight: 700,
1388
+ marginBottom: "14px"
1389
+ },
1390
+ children: group.title
1391
+ }
1392
+ ),
1393
+ /* @__PURE__ */ jsx2(
1394
+ "div",
1395
+ {
1396
+ style: {
1397
+ display: "grid",
1398
+ gridTemplateColumns: "repeat(auto-fit, minmax(190px, 1fr))",
1399
+ gap: "12px"
1400
+ },
1401
+ children: group.items.map((item) => /* @__PURE__ */ jsxs2(
1402
+ "div",
1403
+ {
1404
+ style: {
1405
+ padding: "14px 16px",
1406
+ borderRadius: "18px",
1407
+ backgroundColor: item.value ? "rgba(8, 31, 17, 0.72)" : "rgba(42, 12, 12, 0.52)",
1408
+ border: item.value ? "1px solid rgba(34, 197, 94, 0.18)" : "1px solid rgba(248, 113, 113, 0.18)"
1409
+ },
1410
+ children: [
1411
+ /* @__PURE__ */ jsx2("div", { style: { color: "#94a3b8", fontSize: "12px", marginBottom: "8px" }, children: item.label }),
1412
+ /* @__PURE__ */ jsxs2(
1413
+ "div",
1414
+ {
1415
+ style: {
1416
+ display: "flex",
1417
+ alignItems: "center",
1418
+ gap: "8px",
1419
+ color: item.value ? "#86efac" : "#fca5a5",
1420
+ fontWeight: 700
1421
+ },
1422
+ children: [
1423
+ /* @__PURE__ */ jsx2("span", { children: item.value ? "\u2713" : "\u2715" }),
1424
+ item.value ? "Available" : "Missing"
1425
+ ]
1426
+ }
1427
+ ),
1428
+ /* @__PURE__ */ jsx2("div", { style: { color: "#94a3b8", fontSize: "12px", lineHeight: 1.5, marginTop: "10px" }, children: item.detail })
1429
+ ]
1430
+ },
1431
+ item.label
1432
+ ))
1433
+ }
1434
+ )
1435
+ ]
1436
+ },
1437
+ group.title
1438
+ ))
1439
+ }
1440
+ )
1441
+ ] }),
1442
+ /* @__PURE__ */ jsxs2("div", { style: panelStyle, children: [
1443
+ /* @__PURE__ */ jsxs2(
1444
+ "div",
1445
+ {
1446
+ style: {
1447
+ display: "flex",
1448
+ justifyContent: "space-between",
1449
+ alignItems: "center",
1450
+ gap: "12px",
1451
+ marginBottom: "16px"
1452
+ },
1453
+ children: [
1454
+ /* @__PURE__ */ jsx2("h3", { style: sectionTitleStyle, children: "Event log" }),
1455
+ /* @__PURE__ */ jsxs2("span", { style: { ...codeStyle, padding: "4px 10px" }, children: [
1456
+ eventLog.length,
1457
+ " recent events"
1458
+ ] })
1459
+ ]
1460
+ }
1461
+ ),
1462
+ /* @__PURE__ */ jsx2(
1463
+ "div",
1464
+ {
1465
+ style: {
1466
+ background: "linear-gradient(180deg, rgba(2, 6, 23, 0.88) 0%, rgba(2, 6, 23, 0.64) 100%)",
1467
+ padding: "14px",
1468
+ borderRadius: "18px",
1469
+ minHeight: "220px",
1470
+ height: "min(46vh, 420px)",
1471
+ overflowY: "auto",
1472
+ fontFamily: '"SF Mono", "Roboto Mono", monospace',
1473
+ fontSize: "12px",
1474
+ border: "1px solid rgba(148, 163, 184, 0.12)"
1475
+ },
1476
+ children: eventLog.length ? /* @__PURE__ */ jsx2("div", { style: { display: "grid", gap: "10px" }, children: eventLog.map((event) => /* @__PURE__ */ jsxs2(
1477
+ "div",
1478
+ {
1479
+ style: {
1480
+ paddingBottom: "10px",
1481
+ borderBottom: "1px solid rgba(148, 163, 184, 0.08)"
1482
+ },
1483
+ children: [
1484
+ /* @__PURE__ */ jsx2("div", { style: { color: "#64748b", marginBottom: "4px" }, children: event.timestamp }),
1485
+ /* @__PURE__ */ jsx2("div", { style: { color: "#e2e8f0", lineHeight: 1.6 }, children: event.message })
1486
+ ]
1487
+ },
1488
+ event.id
1489
+ )) }) : /* @__PURE__ */ jsx2("div", { style: { color: "#64748b" }, children: "No events yet. Start a session or apply a config change." })
1490
+ }
1491
+ )
1492
+ ] })
1493
+ ] }),
1494
+ /* @__PURE__ */ jsx2("div", { style: { flex: "1 1 560px", minWidth: "320px" }, children: /* @__PURE__ */ jsxs2("div", { style: { ...panelStyle, padding: "24px" }, children: [
864
1495
  /* @__PURE__ */ jsxs2(
865
- "button",
1496
+ "div",
866
1497
  {
867
- type: "button",
868
1498
  style: {
869
- ...buttonStyle,
870
- backgroundColor: "#16a34a",
871
- color: "#ffffff",
872
- border: "none",
873
- padding: "12px 24px",
874
- fontSize: "16px",
875
- fontWeight: "600",
876
- cursor: actions.canTryNow ? "pointer" : "not-allowed",
877
- opacity: actions.canTryNow ? 1 : 0.5
878
- },
879
- disabled: !actions.canTryNow,
880
- onMouseEnter: (e) => {
881
- if (actions.canTryNow) {
882
- e.currentTarget.style.backgroundColor = "#15803d";
883
- }
884
- },
885
- onMouseLeave: (e) => {
886
- if (actions.canTryNow) {
887
- e.currentTarget.style.backgroundColor = "#16a34a";
888
- }
889
- },
890
- onClick: () => {
891
- setHasUserClicked(true);
892
- setShowIframe(true);
893
- addEvent(embedState.hasPlayedOnce ? "User clicked - Resuming game" : "User clicked - Starting game with tryNow");
894
- actions.tryNow();
1499
+ display: "flex",
1500
+ flexWrap: "wrap",
1501
+ justifyContent: "space-between",
1502
+ alignItems: "center",
1503
+ gap: "12px",
1504
+ marginBottom: "16px"
895
1505
  },
896
1506
  children: [
897
- "\u{1F3AE} ",
898
- embedState.hasPlayedOnce ? "Resume Game" : "Try Demo Now"
1507
+ /* @__PURE__ */ jsxs2("div", { children: [
1508
+ /* @__PURE__ */ jsx2("h3", { style: sectionTitleStyle, children: "Embed preview" }),
1509
+ /* @__PURE__ */ jsx2("p", { style: { ...helperTextStyle, marginTop: "6px" }, children: "The live iframe always reflects the applied configuration." })
1510
+ ] }),
1511
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexWrap: "wrap", gap: "10px" }, children: [
1512
+ /* @__PURE__ */ jsxs2("span", { style: { ...codeStyle, padding: "6px 10px" }, children: [
1513
+ "Host: ",
1514
+ displayHost
1515
+ ] }),
1516
+ /* @__PURE__ */ jsxs2("span", { style: { ...codeStyle, padding: "6px 10px" }, children: [
1517
+ "Operation: ",
1518
+ appliedOperation
1519
+ ] })
1520
+ ] })
899
1521
  ]
900
1522
  }
901
1523
  ),
902
- actions.canBuyNow && /* @__PURE__ */ jsx2(
903
- "button",
1524
+ hasPendingConfigChanges && /* @__PURE__ */ jsxs2(
1525
+ "div",
904
1526
  {
905
- type: "button",
906
1527
  style: {
907
- ...buttonStyle,
908
- backgroundColor: "#525252",
909
- color: "#ffffff",
910
- border: "none",
911
- padding: "8px 16px",
912
- fontSize: "14px",
913
- fontWeight: "500"
1528
+ display: "flex",
1529
+ alignItems: "center",
1530
+ gap: "12px",
1531
+ padding: "14px 16px",
1532
+ marginBottom: "16px",
1533
+ borderRadius: "18px",
1534
+ backgroundColor: "rgba(35, 23, 8, 0.72)",
1535
+ border: "1px solid rgba(245, 158, 11, 0.22)",
1536
+ color: "#fde68a"
914
1537
  },
915
- onMouseEnter: (e) => e.currentTarget.style.backgroundColor = "#404040",
916
- onMouseLeave: (e) => e.currentTarget.style.backgroundColor = "#525252",
917
- onClick: () => {
918
- addEvent("Buy Now clicked");
919
- actions.buyNow();
1538
+ children: [
1539
+ /* @__PURE__ */ jsx2("span", { style: buildIndicatorDotStyle(true) }),
1540
+ "Draft values are ready but not applied to the iframe yet."
1541
+ ]
1542
+ }
1543
+ ),
1544
+ /* @__PURE__ */ jsxs2(
1545
+ "div",
1546
+ {
1547
+ style: {
1548
+ position: "relative",
1549
+ minHeight: "640px",
1550
+ overflow: "hidden",
1551
+ borderRadius: "24px",
1552
+ border: "1px solid rgba(148, 163, 184, 0.14)",
1553
+ background: "linear-gradient(180deg, rgba(3, 7, 18, 0.86) 0%, rgba(2, 6, 23, 1) 100%)",
1554
+ boxShadow: "inset 0 1px 0 rgba(255, 255, 255, 0.04)"
920
1555
  },
921
- children: "Buy Now"
1556
+ children: [
1557
+ /* @__PURE__ */ jsxs2(
1558
+ "div",
1559
+ {
1560
+ style: {
1561
+ display: "flex",
1562
+ alignItems: "center",
1563
+ justifyContent: "space-between",
1564
+ gap: "12px",
1565
+ padding: "14px 18px",
1566
+ borderBottom: "1px solid rgba(148, 163, 184, 0.08)",
1567
+ backgroundColor: "rgba(15, 23, 42, 0.52)"
1568
+ },
1569
+ children: [
1570
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
1571
+ /* @__PURE__ */ jsx2("span", { style: { width: "10px", height: "10px", borderRadius: "999px", backgroundColor: "#f97316" } }),
1572
+ /* @__PURE__ */ jsx2("span", { style: { width: "10px", height: "10px", borderRadius: "999px", backgroundColor: "#facc15" } }),
1573
+ /* @__PURE__ */ jsx2("span", { style: { width: "10px", height: "10px", borderRadius: "999px", backgroundColor: "#4ade80" } })
1574
+ ] }),
1575
+ /* @__PURE__ */ jsxs2("span", { style: { color: "#94a3b8", fontSize: "12px", fontFamily: '"SF Mono", "Roboto Mono", monospace' }, children: [
1576
+ "/embed?operation=",
1577
+ appliedOperation
1578
+ ] })
1579
+ ]
1580
+ }
1581
+ ),
1582
+ /* @__PURE__ */ jsx2(
1583
+ PlayruoEmbed,
1584
+ {
1585
+ baseUrl: props.baseUrl,
1586
+ className: "w-full h-full absolute inset-0",
1587
+ iframeRef,
1588
+ onDemoCompleted: handleDemoCompleted,
1589
+ onError: handleError,
1590
+ onPurchaseRequest: handlePurchaseRequest,
1591
+ onReady: handleReady,
1592
+ onStateChange: handleStateChange,
1593
+ operation: appliedOperation,
1594
+ renderState: ({ actions, message, status }) => /* @__PURE__ */ jsx2(Fragment, { children: !hasUserClicked && /* @__PURE__ */ jsx2(
1595
+ "div",
1596
+ {
1597
+ style: {
1598
+ position: "absolute",
1599
+ inset: "53px 0 0 0",
1600
+ display: "flex",
1601
+ alignItems: "center",
1602
+ justifyContent: "center",
1603
+ padding: "24px",
1604
+ background: "linear-gradient(180deg, rgba(2, 6, 23, 0.4) 0%, rgba(2, 6, 23, 0.84) 70%, rgba(2, 6, 23, 0.9) 100%)",
1605
+ backdropFilter: "blur(12px)",
1606
+ zIndex: 50
1607
+ },
1608
+ children: /* @__PURE__ */ jsxs2(
1609
+ "div",
1610
+ {
1611
+ style: {
1612
+ width: "min(100%, 420px)",
1613
+ padding: "28px",
1614
+ borderRadius: "28px",
1615
+ border: "1px solid rgba(148, 163, 184, 0.18)",
1616
+ background: "linear-gradient(180deg, rgba(15, 23, 42, 0.94) 0%, rgba(7, 12, 24, 0.98) 100%)",
1617
+ boxShadow: "0 32px 72px rgba(0, 0, 0, 0.35)"
1618
+ },
1619
+ children: [
1620
+ /* @__PURE__ */ jsx2(
1621
+ "div",
1622
+ {
1623
+ style: {
1624
+ display: "inline-flex",
1625
+ alignItems: "center",
1626
+ gap: "10px",
1627
+ padding: "6px 12px",
1628
+ borderRadius: "999px",
1629
+ backgroundColor: "rgba(56, 189, 248, 0.12)",
1630
+ border: "1px solid rgba(125, 211, 252, 0.18)",
1631
+ color: "#7dd3fc",
1632
+ fontSize: "11px",
1633
+ fontWeight: 700,
1634
+ letterSpacing: "0.08em",
1635
+ textTransform: "uppercase"
1636
+ },
1637
+ children: "Live overlay"
1638
+ }
1639
+ ),
1640
+ /* @__PURE__ */ jsx2(
1641
+ "h4",
1642
+ {
1643
+ style: {
1644
+ margin: "18px 0 10px 0",
1645
+ color: "#f8fafc",
1646
+ fontSize: "28px",
1647
+ letterSpacing: "-0.03em"
1648
+ },
1649
+ children: embedState.hasPlayedOnce ? "Resume the session" : "Start the demo"
1650
+ }
1651
+ ),
1652
+ /* @__PURE__ */ jsxs2("p", { style: { margin: 0, color: "#94a3b8", lineHeight: 1.7 }, children: [
1653
+ "Status: ",
1654
+ /* @__PURE__ */ jsx2("span", { style: { color: "#f8fafc", fontWeight: 700 }, children: status })
1655
+ ] }),
1656
+ message && /* @__PURE__ */ jsx2("p", { style: { margin: "10px 0 0 0", color: "#cbd5e1", lineHeight: 1.7 }, children: message }),
1657
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexWrap: "wrap", gap: "12px", marginTop: "24px" }, children: [
1658
+ /* @__PURE__ */ jsxs2(
1659
+ "button",
1660
+ {
1661
+ type: "button",
1662
+ style: buildButtonStyle("primary", !actions.canTryNow),
1663
+ disabled: !actions.canTryNow,
1664
+ onClick: () => {
1665
+ setHasUserClicked(true);
1666
+ setShowIframe(true);
1667
+ addEvent(
1668
+ embedState.hasPlayedOnce ? "User clicked - Resuming game" : "User clicked - Starting game with tryNow"
1669
+ );
1670
+ actions.tryNow();
1671
+ },
1672
+ children: [
1673
+ "\u{1F3AE} ",
1674
+ embedState.hasPlayedOnce ? "Resume game" : "Try demo now"
1675
+ ]
1676
+ }
1677
+ ),
1678
+ actions.canBuyNow && /* @__PURE__ */ jsx2(
1679
+ "button",
1680
+ {
1681
+ type: "button",
1682
+ style: buildButtonStyle("secondary"),
1683
+ onClick: () => {
1684
+ addEvent("Buy Now clicked");
1685
+ actions.buyNow();
1686
+ },
1687
+ children: "Buy Now"
1688
+ }
1689
+ )
1690
+ ] })
1691
+ ]
1692
+ }
1693
+ )
1694
+ }
1695
+ ) }),
1696
+ showIframe,
1697
+ storeUrl: appliedStoreUrl
1698
+ },
1699
+ key
1700
+ )
1701
+ ]
922
1702
  }
923
1703
  )
924
- ] }) }),
925
- showIframe,
926
- storeUrl
927
- },
928
- key
929
- ) })
930
- ] }) })
931
- ] })
932
- ] }) });
1704
+ ] }) })
1705
+ ] })
1706
+ ] })
1707
+ ]
1708
+ }
1709
+ );
933
1710
  };
934
1711
 
935
1712
  // src/post-message-types.ts