diff --git a/components/SelfGuidedTours-backup.tsx b/components/SelfGuidedTours-backup.tsx
new file mode 100644
index 0000000000..0d0192c5c6
--- /dev/null
+++ b/components/SelfGuidedTours-backup.tsx
@@ -0,0 +1,309 @@
+'use client';
+import React from 'react';
+import Image from 'next/image';
+import Script from 'next/script';
+
+/**
+ * Card data shape passed from MDX.
+ * - navatticOpen: the Navattic demo id (e.g., "cmfkxwfa5000004lc8408f5wi")
+ * - navatticTitle: optional; title for the Navattic popup chrome
+ * - img: optional; if omitted, a dark placeholder fills the media area
+ */
+type Card = {
+ badge: string;
+ title: string;
+ blurb?: string;
+ img?: string;
+ href?: string;
+ navatticOpen?: string;
+ navatticTitle?: string;
+};
+
+interface Props {
+ cards: Card[];
+}
+
+/* ---- Constants / design tokens (keep in sync with MDX usage) ---- */
+const MP_PURPLE = 'rgb(139 92 246)';
+const BORDER_RADIUS = 14;
+const CARD_W = 296;
+const CARD_H = 319;
+/** Image height is fixed for consistent badge anchoring */
+const IMAGE_H = 140;
+/** Image width is indented left and bleeds to the right edge */
+const IMAGE_W = 276;
+
+/* ---- Inline “CSS-in-TS” styles (layout is pixel-exact to your spec) ---- */
+const styles = {
+ grid: {
+ display: 'grid',
+ gap: 20,
+ gridTemplateColumns: 'repeat(auto-fit, minmax(296px, 1fr))',
+ justifyContent: 'center',
+ marginTop: 32,
+ } as React.CSSProperties,
+
+ card: {
+ position: 'relative',
+ width: CARD_W,
+ height: CARD_H,
+ borderRadius: BORDER_RADIUS,
+ overflow: 'hidden',
+ border: `2px solid ${MP_PURPLE}`,
+ boxShadow: '0 10px 30px rgba(0,0,0,.25)',
+ transition: 'transform .25s ease, box-shadow .25s ease, background .3s ease, color .3s ease',
+ } as React.CSSProperties,
+
+ dogEar: {
+ position: 'absolute',
+ right: 10,
+ top: 10,
+ width: 22,
+ height: 22,
+ background: 'var(--sgt-dogear)',
+ clipPath: 'polygon(0 0, 100% 0, 100% 100%)',
+ boxShadow: '0 0 0 2px rgba(0,0,0,.15) inset',
+ zIndex: 5,
+ pointerEvents: 'none',
+ } as React.CSSProperties,
+
+ mediaWrap: {
+ position: 'absolute',
+ top: 18, // aligns the image to the badge’s left indent
+ height: IMAGE_H,
+ width: IMAGE_W,
+ marginLeft: 16, // left indent (aligns with badge)
+ marginRight: -16, // bleed to right edge (no right indent)
+ borderTopLeftRadius: 8,
+ borderBottomLeftRadius: 8,
+ overflow: 'hidden',
+ background: 'var(--sgt-media-bg)', // placeholder color behind images
+ zIndex: 1,
+ } as React.CSSProperties,
+
+ mediaImg: {
+ width: '100%',
+ height: '100%',
+ objectFit: 'cover',
+ objectPosition: 'left top',
+ display: 'block',
+ } as React.CSSProperties,
+
+ placeholder: {
+ width: '100%',
+ height: '100%',
+ background: 'var(--sgt-media-bg)',
+ } as React.CSSProperties,
+
+ /**
+ * Anchored text block:
+ * - Badge top is locked to IMAGE_H + offset so all cards align visually
+ * - Title and blurb naturally flow below the badge
+ */
+ bottom: {
+ position: 'absolute' as const,
+ top: IMAGE_H + 22,
+ left: 0,
+ right: 0,
+ bottom: 0,
+ padding: '16px 18px 22px',
+ zIndex: 3,
+ },
+
+ /* Badge = stronger weight + tighter tracking for a pill look */
+ badge: {
+ display: 'inline-block',
+ background: 'var(--sgt-badge-bg)',
+ color: 'var(--sgt-badge-fg)',
+ fontWeight: 800,
+ letterSpacing: '.04em',
+ fontSize: '11.5px',
+ lineHeight: 1,
+ borderRadius: 8,
+ padding: '8px 10px',
+ marginBottom: 10,
+ } as React.CSSProperties,
+
+ title: {
+ fontSize: 23,
+ fontWeight: 700,
+ lineHeight: 1.2,
+ margin: 0,
+ color: 'var(--sgt-title)',
+ } as React.CSSProperties,
+
+ blurb: {
+ marginTop: 8,
+ fontSize: 15,
+ color: 'var(--sgt-blurb)',
+ opacity: 0.75,
+ } as React.CSSProperties,
+
+ clickable: {
+ display: 'block',
+ width: '100%',
+ height: '100%',
+ background: 'transparent',
+ border: 0,
+ padding: 0,
+ cursor: 'pointer',
+ textAlign: 'inherit',
+ } as React.CSSProperties,
+};
+
+/* ---- One card view (supports Navattic popup or plain link) ---- */
+function CardView({ c }: { c: Card }) {
+ const inside = (
+ <>
+
+
+ {c.img ? (
+
+ ) : (
+
+ )}
+
+
+
+
{c.badge}
+
{c.title}
+ {c.blurb ?
{c.blurb}
: null}
+
+ >
+ );
+
+ // Use Navattic popup if navatticOpen is provided
+ if (c.navatticOpen) {
+ const navatticUrl = c.navatticOpen.startsWith('http')
+ ? c.navatticOpen
+ : `https://capture.navattic.com/${c.navatticOpen}`;
+
+ return (
+
+
+
+ );
+ }
+
+ // Fallback to href links if needed
+ if (c.href) {
+ return (
+
+ );
+ }
+
+ // Static (non-clickable) card
+ return (
+
+ {inside}
+
+ );
+}
+
+/**
+ * SelfGuidedTours
+ * - Renders a responsive grid of product-tour cards
+ * - Loads Navattic's embed script once (popup mode)
+ * - Exposes a simple props API so MDX controls the content
+ */
+export default function SelfGuidedTours({ cards }: Props) {
+ return (
+ <>
+ {/* Navattic embed loader (newer API) */}
+
+
+ {/* Grid */}
+
+ {cards.map((c, i) => (
+
+ ))}
+
+
+ {/* Theme variables + interactions */}
+
+ >
+ );
+}
diff --git a/components/SelfGuidedTours.tsx b/components/SelfGuidedTours.tsx
index 33d154a0a5..455b2ea087 100644
--- a/components/SelfGuidedTours.tsx
+++ b/components/SelfGuidedTours.tsx
@@ -1,7 +1,7 @@
'use client';
-import React from 'react';
+import React, { useEffect, useState, useCallback } from 'react';
import Image from 'next/image';
-import Script from 'next/script';
+import { useRouter } from 'next/router';
/**
* Card data shape passed from MDX.
@@ -152,7 +152,13 @@ const styles = {
};
/* ---- One card view (supports Navattic popup or plain link) ---- */
-function CardView({ c }: { c: Card }) {
+function CardView({
+ c,
+ openInline, // inline overlay opener (provided by parent)
+}: {
+ c: Card;
+ openInline?: (url: string, title: string) => void;
+}) {
const inside = (
<>
@@ -172,26 +178,30 @@ function CardView({ c }: { c: Card }) {
>
);
- // Use Navattic popup if navatticOpen is provided
+ // Always open inline overlay if a Navattic URL is provided (consistent UX)
if (c.navatticOpen) {
- const navatticUrl = c.navatticOpen.startsWith('http')
- ? c.navatticOpen
- : `https://capture.navattic.com/${c.navatticOpen}`;
-
- return (
-
-
-
- );
- }
+ const navatticUrl = c.navatticOpen.startsWith('http')
+ ? c.navatticOpen
+ : `https://capture.navattic.com/${c.navatticOpen}`;
+
+ return (
+
+
+
+ );
+ }
// Fallback to href links if needed
if (c.href) {
@@ -215,22 +225,201 @@ function CardView({ c }: { c: Card }) {
/**
* SelfGuidedTours
* - Renders a responsive grid of product-tour cards
- * - Loads Navattic's embed script once (popup mode)
- * - Exposes a simple props API so MDX controls the content
+ * - Shows a modal overlay for tours for a consistent experience
*/
export default function SelfGuidedTours({ cards }: Props) {
+ const router = useRouter();
+
+ // Inline overlay state
+ const [inlineUrl, setInlineUrl] = useState(null);
+ const [inlineTitle, setInlineTitle] = useState('');
+
+ const openInline = useCallback((url: string, title: string) => {
+ setInlineTitle(title);
+ setInlineUrl(url);
+ }, []);
+ const closeInline = useCallback(() => setInlineUrl(null), []);
+
+ // Close modal on route changes (avoid lingering overlay)
+ useEffect(() => {
+ const onStart = () => closeInline();
+ router.events.on('routeChangeStart', onStart);
+ return () => router.events.off('routeChangeStart', onStart);
+ }, [router.events, closeInline]);
+
+ // ESC to close + lock background scroll while open
+ useEffect(() => {
+ if (inlineUrl) {
+ const prevOverflow = document.body.style.overflow;
+ document.body.style.overflow = 'hidden';
+ const onKey = (e: KeyboardEvent) => {
+ if (e.key === 'Escape') closeInline();
+ };
+ window.addEventListener('keydown', onKey);
+ return () => {
+ window.removeEventListener('keydown', onKey);
+ document.body.style.overflow = prevOverflow;
+ };
+ }
+ }, [inlineUrl, closeInline]);
+
return (
<>
- {/* Navattic embed loader (newer API) */}
-
-
{/* Grid */}
{cards.map((c, i) => (
-
+
))}
+ {/* Inline overlay */}
+ {inlineUrl && (
+
+
e.stopPropagation()}
+ style={{
+ width: 'calc(100vw - 160px)',
+ height: 'calc(100vh - 144px)',
+ background: '#F3F4F6',
+ borderRadius: 12,
+ overflow: 'hidden',
+ boxShadow: '0 10px 40px rgba(0,0,0,.5)',
+ position: 'relative',
+ }}
+ >
+ {/* Header bar styled to closely match Navattic's */}
+
+
+ {/* Left icon + label (no pill) */}
+
+
+ {/* SVG from original Navattic header (adjusted to TSX) */}
+
+
+
+ Viewing Interactive Demo
+
+
+
+ {/* Title pill */}
+
+ {inlineTitle}
+
+
+
+
+
+
+ {/* iframe body, positioned below header */}
+
+
+
+ )}
+
{/* Theme variables + interactions */}
>
);
-}
\ No newline at end of file
+}