@neowhale/storefront 0.2.54 → 0.2.56

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.
@@ -496,6 +496,11 @@ var WhaleStorefront = (function (exports) {
496
496
  source: c.inline_form?.source || "landing_page",
497
497
  landing_page_slug: slug || void 0,
498
498
  tags: c.inline_form?.tags || void 0,
499
+ segment_id: c.inline_form?.segment_id || void 0,
500
+ campaign_id: c.inline_form?.campaign_id || void 0,
501
+ preferred_location_id: c.inline_form?.preferred_location_id || void 0,
502
+ template_slug: c.inline_form?.template_slug || void 0,
503
+ acquisition_campaign: c.inline_form?.acquisition_campaign || void 0,
499
504
  visitor_id: data?.analyticsContext?.visitorId || void 0,
500
505
  session_id: data?.analyticsContext?.sessionId || void 0,
501
506
  utm_source: urlParams?.get("utm_source") || void 0,
@@ -594,10 +599,11 @@ var WhaleStorefront = (function (exports) {
594
599
  ] });
595
600
  }
596
601
  function HeroInlineForm({ ctaText, formOpen, setFormOpen, firstName, setFirstName, email, setEmail, status, errorMsg, onSubmit, successHeading, successMessage, submitText, theme, onEvent, tracking }) {
602
+ const formMaxW = "min(480px, 90vw)";
597
603
  if (status === "success") {
598
- return /* @__PURE__ */ jsx("div", { style: { padding: "1.25rem 2rem", background: `${theme.fg}08`, border: `1px solid ${theme.fg}15`, maxWidth: 420, margin: "0 auto" }, children: [
599
- /* @__PURE__ */ jsx("p", { style: { fontSize: "1.1rem", fontWeight: 300, color: theme.fg, margin: "0 0 0.25rem", fontFamily: theme.fontDisplay || "inherit" }, children: successHeading }),
600
- /* @__PURE__ */ jsx("p", { style: { fontSize: "0.8rem", color: `${theme.fg}80`, margin: 0 }, children: successMessage })
604
+ return /* @__PURE__ */ jsx("div", { style: { maxWidth: formMaxW, margin: "0 auto", padding: "1.5rem 2rem", background: `${theme.fg}06`, border: `1px solid ${theme.fg}10` }, children: [
605
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "clamp(1rem, 3vw, 1.25rem)", fontWeight: 300, color: theme.fg, margin: "0 0 0.375rem", fontFamily: theme.fontDisplay || "inherit" }, children: successHeading }),
606
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "0.85rem", color: `${theme.fg}70`, margin: 0, lineHeight: 1.5 }, children: successMessage })
601
607
  ] });
602
608
  }
603
609
  if (!formOpen) {
@@ -611,37 +617,39 @@ var WhaleStorefront = (function (exports) {
611
617
  },
612
618
  style: {
613
619
  display: "inline-block",
614
- padding: "0.875rem 2rem",
620
+ padding: "clamp(0.875rem, 2.5vw, 1.125rem) clamp(2rem, 5vw, 3rem)",
615
621
  background: theme.fg,
616
622
  color: theme.bg,
617
623
  border: "none",
618
624
  cursor: "pointer",
619
- fontSize: "0.85rem",
625
+ fontSize: "clamp(0.85rem, 2vw, 1rem)",
620
626
  fontWeight: 500,
621
- letterSpacing: "0.08em",
627
+ letterSpacing: "0.06em",
622
628
  textTransform: "uppercase",
623
- fontFamily: "inherit",
624
- transition: "transform 0.2s"
629
+ fontFamily: "inherit"
625
630
  },
626
631
  children: ctaText
627
632
  }
628
633
  );
629
634
  }
630
- const inputStyle = {
631
- flex: 1,
632
- minWidth: 0,
633
- padding: "0.875rem 1rem",
635
+ const inputBase = {
636
+ padding: "clamp(0.75rem, 2vw, 0.875rem) clamp(0.75rem, 2vw, 1rem)",
634
637
  background: theme.surface,
635
- border: `1px solid ${theme.fg}25`,
638
+ border: `1px solid ${theme.fg}20`,
636
639
  color: theme.fg,
637
- fontSize: "0.9rem",
640
+ fontSize: "clamp(0.8rem, 2vw, 0.9rem)",
638
641
  fontWeight: 300,
639
642
  outline: "none",
640
643
  fontFamily: "inherit",
641
- boxSizing: "border-box"
644
+ boxSizing: "border-box",
645
+ width: "100%"
642
646
  };
643
- return /* @__PURE__ */ jsx("form", { onSubmit, style: { maxWidth: 480, margin: "0 auto" }, children: [
644
- /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 0 }, children: [
647
+ return /* @__PURE__ */ jsx("form", { onSubmit, style: { maxWidth: formMaxW, margin: "0 auto", width: "100%" }, children: [
648
+ /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: `
649
+ .hero-form-row{display:flex;gap:0}
650
+ @media(max-width:480px){.hero-form-row{flex-direction:column;gap:0.5rem}}
651
+ ` } }),
652
+ /* @__PURE__ */ jsx("div", { className: "hero-form-row", children: [
645
653
  /* @__PURE__ */ jsx(
646
654
  "input",
647
655
  {
@@ -650,7 +658,7 @@ var WhaleStorefront = (function (exports) {
650
658
  value: firstName,
651
659
  autoFocus: true,
652
660
  onChange: (e) => setFirstName(e.target.value),
653
- style: { ...inputStyle, borderRight: "none" }
661
+ style: { ...inputBase, flex: 1, minWidth: 0, borderRight: "none" }
654
662
  }
655
663
  ),
656
664
  /* @__PURE__ */ jsx(
@@ -661,33 +669,33 @@ var WhaleStorefront = (function (exports) {
661
669
  value: email,
662
670
  required: true,
663
671
  onChange: (e) => setEmail(e.target.value),
664
- style: { ...inputStyle, borderRight: "none" }
665
- }
666
- ),
667
- /* @__PURE__ */ jsx(
668
- "button",
669
- {
670
- type: "submit",
671
- disabled: status === "loading",
672
- style: {
673
- padding: "0.875rem 1.25rem",
674
- background: theme.fg,
675
- color: theme.bg,
676
- border: "none",
677
- fontSize: "0.75rem",
678
- fontWeight: 600,
679
- letterSpacing: "0.08em",
680
- textTransform: "uppercase",
681
- cursor: status === "loading" ? "wait" : "pointer",
682
- fontFamily: "inherit",
683
- whiteSpace: "nowrap",
684
- flexShrink: 0,
685
- opacity: status === "loading" ? 0.7 : 1
686
- },
687
- children: status === "loading" ? "..." : submitText
672
+ style: { ...inputBase, flex: 1.2, minWidth: 0 }
688
673
  }
689
674
  )
690
675
  ] }),
676
+ /* @__PURE__ */ jsx(
677
+ "button",
678
+ {
679
+ type: "submit",
680
+ disabled: status === "loading",
681
+ style: {
682
+ width: "100%",
683
+ padding: "clamp(0.75rem, 2vw, 0.875rem)",
684
+ background: theme.fg,
685
+ color: theme.bg,
686
+ border: "none",
687
+ fontSize: "clamp(0.8rem, 2vw, 0.85rem)",
688
+ fontWeight: 600,
689
+ letterSpacing: "0.08em",
690
+ textTransform: "uppercase",
691
+ cursor: status === "loading" ? "wait" : "pointer",
692
+ fontFamily: "inherit",
693
+ marginTop: "0.5rem",
694
+ opacity: status === "loading" ? 0.7 : 1
695
+ },
696
+ children: status === "loading" ? "..." : submitText
697
+ }
698
+ ),
691
699
  status === "error" && errorMsg && /* @__PURE__ */ jsx("p", { style: { fontSize: "0.75rem", color: "#e55", margin: "0.5rem 0 0", textAlign: "left" }, children: errorMsg })
692
700
  ] });
693
701
  }
@@ -792,29 +800,100 @@ var WhaleStorefront = (function (exports) {
792
800
  ] })
793
801
  ] });
794
802
  }
795
- function GallerySection({ section, theme }) {
796
- const { images } = section.content;
803
+ function GallerySection({ section, theme, onEvent }) {
804
+ const c = section.content;
805
+ const images = c.images || [];
797
806
  const columns = section.config?.columns || 3;
798
807
  const layout = section.config?.layout || "grid";
808
+ const loc = c.location_card;
799
809
  if (!images || images.length === 0) return null;
800
810
  if (layout === "collage") {
801
- return /* @__PURE__ */ jsx("div", { style: { padding: "0.375rem", maxWidth: 900, margin: "0 auto" }, children: /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.375rem" }, children: images.map((img, i) => /* @__PURE__ */ jsx("div", { style: {
802
- gridColumn: i === 0 ? "1 / -1" : void 0,
803
- aspectRatio: i === 0 ? "16/9" : i % 3 === 0 ? "3/4" : "1",
804
- overflow: "hidden",
805
- background: theme.surface
806
- }, children: /* @__PURE__ */ jsx(
807
- "img",
808
- {
809
- src: img.url,
810
- alt: img.alt || "",
811
- loading: i < 2 ? "eager" : "lazy",
812
- style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
813
- }
814
- ) }, i)) }) });
811
+ return /* @__PURE__ */ jsx("div", { style: { padding: "0.375rem", maxWidth: 900, margin: "0 auto" }, children: [
812
+ loc && /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.375rem", marginBottom: "0.375rem" }, children: [
813
+ /* @__PURE__ */ jsx(GalleryLocationCard, { loc, theme, onEvent }),
814
+ /* @__PURE__ */ jsx("div", { style: { aspectRatio: "4/5", overflow: "hidden", background: theme.surface }, children: /* @__PURE__ */ jsx(
815
+ "img",
816
+ {
817
+ src: images[0].url,
818
+ alt: images[0].alt || "",
819
+ loading: "eager",
820
+ style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
821
+ }
822
+ ) })
823
+ ] }),
824
+ /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.375rem" }, children: images.slice(loc ? 1 : 0).map((img, i) => /* @__PURE__ */ jsx("div", { style: {
825
+ gridColumn: !loc && i === 0 ? "1 / -1" : void 0,
826
+ aspectRatio: !loc && i === 0 ? "16/9" : i % 3 === 0 ? "3/4" : "1",
827
+ overflow: "hidden",
828
+ background: theme.surface
829
+ }, children: /* @__PURE__ */ jsx(
830
+ "img",
831
+ {
832
+ src: img.url,
833
+ alt: img.alt || "",
834
+ loading: i < 2 ? "eager" : "lazy",
835
+ style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
836
+ }
837
+ ) }, i)) })
838
+ ] });
815
839
  }
816
840
  return /* @__PURE__ */ jsx("div", { style: { padding: "1.5rem", maxWidth: 800, margin: "0 auto" }, children: /* @__PURE__ */ jsx("div", { style: { display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)`, gap: "0.5rem" }, children: images.map((img, i) => /* @__PURE__ */ jsx("div", { style: { aspectRatio: "1", overflow: "hidden", background: theme.surface }, children: /* @__PURE__ */ jsx("img", { src: img.url, alt: img.alt || "", style: { width: "100%", height: "100%", objectFit: "cover", display: "block" } }) }, i)) }) });
817
841
  }
842
+ function GalleryLocationCard({ loc, theme, onEvent }) {
843
+ const dirUrl = loc.directions_url || `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(loc.address + ", " + loc.city + ", " + loc.state)}`;
844
+ const brandFont = loc.brand_font || "inherit";
845
+ return /* @__PURE__ */ jsx("div", { style: { background: "#0C0C0C", border: "1px solid rgba(255,255,255,0.06)", overflow: "hidden", display: "flex", flexDirection: "column" }, children: [
846
+ /* @__PURE__ */ jsx("div", { style: { position: "relative", flex: 1, minHeight: 0, overflow: "hidden" }, children: [
847
+ /* @__PURE__ */ jsx("img", { src: loc.image, alt: loc.name, style: { width: "100%", height: "100%", objectFit: "cover", display: "block" } }),
848
+ /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: "linear-gradient(to top, rgba(0,0,0,0.6) 0%, transparent 50%)" } }),
849
+ /* @__PURE__ */ jsx("div", { style: { position: "absolute", bottom: 0, left: 0, padding: "clamp(0.75rem, 3vw, 1.25rem)" }, children: [
850
+ /* @__PURE__ */ jsx("p", { className: "loc-card-name", style: { fontFamily: brandFont, fontSize: "clamp(1.25rem, 5vw, 1.75rem)", color: "#fff", margin: 0, lineHeight: 1 }, children: loc.name }),
851
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "0.6rem", letterSpacing: "0.2em", color: "rgba(255,255,255,0.6)", margin: "0.25rem 0 0", fontWeight: 600, textTransform: "uppercase" }, children: [
852
+ loc.city,
853
+ ", ",
854
+ loc.state
855
+ ] })
856
+ ] })
857
+ ] }),
858
+ /* @__PURE__ */ jsx("div", { style: { padding: "clamp(0.625rem, 2vw, 1rem)", display: "flex", flexDirection: "column", gap: "0.4rem" }, children: [
859
+ loc.tagline && /* @__PURE__ */ jsx("p", { style: { fontSize: "0.75rem", color: "rgba(255,255,255,0.5)", fontWeight: 500, fontStyle: "italic", margin: 0 }, children: loc.tagline }),
860
+ loc.rating != null && loc.review_count != null && loc.review_count > 0 && /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", gap: "0.375rem" }, children: [
861
+ /* @__PURE__ */ jsx("span", { style: { display: "inline-flex", gap: "2px" }, children: [1, 2, 3, 4, 5].map((s) => /* @__PURE__ */ jsx("svg", { width: 12, height: 12, viewBox: "0 0 20 20", fill: s <= Math.round(loc.rating) ? theme.accent : "rgba(255,255,255,0.1)", children: /* @__PURE__ */ jsx("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" }) }, s)) }),
862
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.7rem", color: "rgba(255,255,255,0.5)", fontWeight: 500 }, children: `${loc.rating.toFixed(1)} \xB7 ${loc.review_count} reviews` })
863
+ ] }),
864
+ loc.address && /* @__PURE__ */ jsx("a", { href: dirUrl, target: "_blank", rel: "noopener noreferrer", style: { fontSize: "0.7rem", color: "rgba(255,255,255,0.35)", fontWeight: 500, textDecoration: "none" }, children: [
865
+ loc.address,
866
+ ", ",
867
+ loc.city,
868
+ ", ",
869
+ loc.state
870
+ ] }),
871
+ loc.phone && /* @__PURE__ */ jsx("a", { href: loc.phone_href || `tel:${loc.phone}`, style: { fontSize: "0.7rem", color: "rgba(255,255,255,0.35)", fontWeight: 500, textDecoration: "none" }, children: loc.phone }),
872
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "0.375rem", marginTop: "auto", paddingTop: "0.125rem" }, children: [
873
+ /* @__PURE__ */ jsx(
874
+ "a",
875
+ {
876
+ href: dirUrl,
877
+ target: "_blank",
878
+ rel: "noopener noreferrer",
879
+ onClick: () => onEvent?.("cta_click", { label: "directions", location: loc.name }),
880
+ style: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: "0.25rem", padding: "0.5rem", background: "#fff", color: "#000", fontSize: "0.65rem", fontWeight: 700, letterSpacing: "0.1em", textTransform: "uppercase", textDecoration: "none" },
881
+ children: "directions"
882
+ }
883
+ ),
884
+ loc.shop_url && /* @__PURE__ */ jsx(
885
+ "a",
886
+ {
887
+ href: loc.shop_url,
888
+ onClick: () => onEvent?.("cta_click", { label: "shop", location: loc.name }),
889
+ style: { flex: 1, display: "flex", alignItems: "center", justifyContent: "center", gap: "0.25rem", padding: "0.5rem", border: "1px solid rgba(255,255,255,0.15)", color: "rgba(255,255,255,0.8)", fontSize: "0.65rem", fontWeight: 700, letterSpacing: "0.1em", textTransform: "uppercase", textDecoration: "none" },
890
+ children: "shop"
891
+ }
892
+ )
893
+ ] })
894
+ ] })
895
+ ] });
896
+ }
818
897
  function SocialLinksSection({ section, theme }) {
819
898
  const { links } = section.content;
820
899
  if (!links || links.length === 0) return null;
@@ -1239,15 +1318,26 @@ var WhaleStorefront = (function (exports) {
1239
1318
  }
1240
1319
 
1241
1320
  // src/react/components/sections/conversion-sections.tsx
1321
+ var GOOGLE_G_LG = '<svg width="28" height="28" viewBox="0 0 48 48"><path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/><path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/><path fill="#FBBC05" d="M10.53 28.59a14.5 14.5 0 010-9.18l-7.98-6.19a24.03 24.03 0 000 21.56l7.98-6.19z"/><path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/></svg>';
1322
+ var GOOGLE_G_SM = '<svg width="14" height="14" viewBox="0 0 48 48"><path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/><path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/><path fill="#FBBC05" d="M10.53 28.59a14.5 14.5 0 010-9.18l-7.98-6.19a24.03 24.03 0 000 21.56l7.98-6.19z"/><path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/></svg>';
1242
1323
  function TestimonialsSection({ section, theme }) {
1243
1324
  const c = section.content;
1244
- const layout = section.config?.layout || "grid";
1325
+ section.config?.layout || "grid";
1245
1326
  const reviews = c.reviews || [];
1246
1327
  if (reviews.length === 0) return null;
1247
1328
  const overallRating = c.rating ?? 5;
1248
1329
  const reviewCount = c.review_count ?? reviews.length;
1249
- return /* @__PURE__ */ jsx("div", { style: { padding: "3rem 1.5rem", maxWidth: 640, margin: "0 auto" }, children: [
1250
- /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginBottom: "2rem" }, children: [
1330
+ const googleUrl = section.config?.google_url || void 0;
1331
+ const directionsUrl = section.config?.directions_url || void 0;
1332
+ `reviews-${section.id}`;
1333
+ return /* @__PURE__ */ jsx("div", { style: { padding: "3rem 0", overflow: "hidden" }, children: [
1334
+ /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: `
1335
+ .rv-scroll{display:flex;gap:clamp(0.5rem,2vw,0.75rem);overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;padding:0 clamp(1rem,4vw,3rem)}
1336
+ .rv-scroll::-webkit-scrollbar{display:none}
1337
+ .rv-card{flex:0 0 clamp(260px,40vw,320px);scroll-snap-align:start}
1338
+ ` } }),
1339
+ /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginBottom: "2rem", padding: "0 1.5rem" }, children: [
1340
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center", marginBottom: "0.75rem" }, children: /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: GOOGLE_G_LG } }) }),
1251
1341
  c.heading && /* @__PURE__ */ jsx("h2", { style: {
1252
1342
  fontSize: "clamp(1.25rem, 4vw, 1.75rem)",
1253
1343
  fontWeight: 300,
@@ -1258,42 +1348,121 @@ var WhaleStorefront = (function (exports) {
1258
1348
  color: theme.fg
1259
1349
  }, children: /* @__PURE__ */ jsx(AnimatedText, { text: c.heading }) }),
1260
1350
  /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "0.5rem", marginBottom: "0.25rem" }, children: [
1261
- /* @__PURE__ */ jsx(Stars, { rating: overallRating, color: theme.accent, size: 18 }),
1351
+ /* @__PURE__ */ jsx(Stars, { rating: overallRating, color: "#FBBC05", size: 18 }),
1262
1352
  /* @__PURE__ */ jsx("span", { style: { fontSize: "1.1rem", fontWeight: 500, color: theme.fg }, children: /* @__PURE__ */ jsx(AnimatedText, { text: overallRating.toFixed(1) }) })
1263
1353
  ] }),
1264
1354
  c.subtitle ? /* @__PURE__ */ jsx("p", { style: { fontSize: "0.8rem", color: theme.muted, margin: 0, letterSpacing: "0.1em", textTransform: "uppercase" }, children: c.subtitle }) : /* @__PURE__ */ jsx("p", { style: { fontSize: "0.8rem", color: theme.muted, margin: 0, letterSpacing: "0.1em", textTransform: "uppercase" }, children: [
1265
1355
  "from ",
1266
1356
  /* @__PURE__ */ jsx(AnimatedText, { text: String(reviewCount) }),
1267
1357
  " reviews"
1358
+ ] }),
1359
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: "0.625rem", justifyContent: "center", marginTop: "1.5rem", flexWrap: "wrap" }, children: [
1360
+ googleUrl && /* @__PURE__ */ jsx("a", { href: googleUrl, target: "_blank", rel: "noopener noreferrer", style: {
1361
+ display: "inline-flex",
1362
+ alignItems: "center",
1363
+ gap: "0.5rem",
1364
+ padding: "clamp(0.75rem, 2vw, 0.875rem) clamp(1.25rem, 3vw, 2rem)",
1365
+ background: theme.fg,
1366
+ color: theme.bg,
1367
+ textDecoration: "none",
1368
+ fontSize: "clamp(0.8rem, 2vw, 0.9rem)",
1369
+ fontWeight: 600,
1370
+ letterSpacing: "0.06em",
1371
+ textTransform: "uppercase"
1372
+ }, children: [
1373
+ /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: GOOGLE_G_SM } }),
1374
+ `see all ${reviewCount} reviews`
1375
+ ] }),
1376
+ directionsUrl && /* @__PURE__ */ jsx("a", { href: directionsUrl, target: "_blank", rel: "noopener noreferrer", style: {
1377
+ display: "inline-flex",
1378
+ alignItems: "center",
1379
+ gap: "0.5rem",
1380
+ padding: "clamp(0.75rem, 2vw, 0.875rem) clamp(1.25rem, 3vw, 2rem)",
1381
+ border: `1px solid ${theme.fg}25`,
1382
+ color: theme.fg,
1383
+ textDecoration: "none",
1384
+ fontSize: "clamp(0.8rem, 2vw, 0.9rem)",
1385
+ fontWeight: 600,
1386
+ letterSpacing: "0.06em",
1387
+ textTransform: "uppercase"
1388
+ }, children: "get directions" })
1268
1389
  ] })
1269
1390
  ] }),
1270
- /* @__PURE__ */ jsx("div", { style: {
1271
- display: "grid",
1272
- gridTemplateColumns: layout === "list" ? "1fr" : `repeat(${Math.min(reviews.length, 2)}, 1fr)`,
1273
- gap: "0.75rem"
1274
- }, children: reviews.map((review, i) => /* @__PURE__ */ jsx("div", { style: {
1275
- background: theme.surface,
1276
- border: `1px solid ${theme.fg}08`,
1277
- padding: "1.25rem"
1278
- }, children: [
1279
- /* @__PURE__ */ jsx(Stars, { rating: review.rating ?? 5, color: theme.accent, size: 14 }),
1280
- /* @__PURE__ */ jsx("p", { style: {
1281
- fontSize: "0.88rem",
1282
- color: `${theme.fg}CC`,
1283
- margin: "0.75rem 0",
1284
- lineHeight: 1.6,
1285
- fontWeight: 300,
1286
- fontStyle: "italic"
1391
+ /* @__PURE__ */ jsx("div", { className: "rv-scroll", children: [
1392
+ reviews.map((review, i) => /* @__PURE__ */ jsx("div", { className: "rv-card", children: /* @__PURE__ */ jsx("div", { style: {
1393
+ background: theme.surface,
1394
+ border: `1px solid ${theme.fg}08`,
1395
+ padding: "clamp(1rem, 3vw, 1.5rem)",
1396
+ height: "100%",
1397
+ display: "flex",
1398
+ flexDirection: "column"
1287
1399
  }, children: [
1288
- '"',
1289
- review.text,
1290
- '"'
1291
- ] }),
1292
- /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "baseline", gap: "0.375rem" }, children: [
1293
- /* @__PURE__ */ jsx("span", { style: { fontSize: "0.8rem", fontWeight: 500, color: theme.fg }, children: review.name }),
1294
- review.location && /* @__PURE__ */ jsx("span", { style: { fontSize: "0.7rem", color: theme.muted }, children: review.location })
1295
- ] })
1296
- ] }, i)) })
1400
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "0.75rem" }, children: [
1401
+ /* @__PURE__ */ jsx(Stars, { rating: review.rating ?? 5, color: "#FBBC05", size: 13 }),
1402
+ review.location && /* @__PURE__ */ jsx("span", { style: { fontSize: "0.6rem", letterSpacing: "0.15em", textTransform: "uppercase", color: theme.muted, fontWeight: 500 }, children: review.location })
1403
+ ] }),
1404
+ /* @__PURE__ */ jsx("p", { style: {
1405
+ fontSize: "0.9rem",
1406
+ color: `${theme.fg}B0`,
1407
+ margin: "0 0 auto",
1408
+ lineHeight: 1.65,
1409
+ fontWeight: 400,
1410
+ paddingBottom: "1rem"
1411
+ }, children: `\u201C${review.text}\u201D` }),
1412
+ /* @__PURE__ */ jsx("div", { style: { borderTop: `1px solid ${theme.fg}08`, paddingTop: "0.75rem", display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
1413
+ /* @__PURE__ */ jsx("div", { style: {
1414
+ width: 28,
1415
+ height: 28,
1416
+ borderRadius: "50%",
1417
+ background: `${theme.accent}18`,
1418
+ border: `1px solid ${theme.accent}15`,
1419
+ display: "flex",
1420
+ alignItems: "center",
1421
+ justifyContent: "center",
1422
+ flexShrink: 0
1423
+ }, children: /* @__PURE__ */ jsx("span", { style: { fontSize: "0.7rem", fontWeight: 600, color: theme.accent, textTransform: "uppercase" }, children: review.name.charAt(0) }) }),
1424
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.8rem", fontWeight: 500, color: `${theme.fg}AA` }, children: review.name })
1425
+ ] })
1426
+ ] }) }, i)),
1427
+ googleUrl && /* @__PURE__ */ jsx("div", { className: "rv-card", children: /* @__PURE__ */ jsx("a", { href: googleUrl, target: "_blank", rel: "noopener noreferrer", style: {
1428
+ height: "100%",
1429
+ display: "flex",
1430
+ flexDirection: "column",
1431
+ alignItems: "center",
1432
+ justifyContent: "center",
1433
+ gap: "0.75rem",
1434
+ background: theme.surface,
1435
+ border: `1px solid ${theme.fg}08`,
1436
+ padding: "clamp(1rem, 3vw, 1.5rem)",
1437
+ textDecoration: "none"
1438
+ }, children: [
1439
+ /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: GOOGLE_G_LG } }),
1440
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.85rem", color: theme.fg, fontWeight: 500 }, children: `read all ${reviewCount}` }),
1441
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "0.75rem", color: theme.muted, letterSpacing: "0.08em" }, children: "reviews on google" })
1442
+ ] }) })
1443
+ ] }),
1444
+ googleUrl && /* @__PURE__ */ jsx("div", { style: { textAlign: "center", marginTop: "1.5rem", padding: "0 1.5rem" }, children: /* @__PURE__ */ jsx(
1445
+ "a",
1446
+ {
1447
+ href: googleUrl,
1448
+ target: "_blank",
1449
+ rel: "noopener noreferrer",
1450
+ style: {
1451
+ display: "inline-flex",
1452
+ alignItems: "center",
1453
+ gap: "0.5rem",
1454
+ fontSize: "0.8rem",
1455
+ color: theme.muted,
1456
+ textDecoration: "none",
1457
+ letterSpacing: "0.08em",
1458
+ fontWeight: 500
1459
+ },
1460
+ children: [
1461
+ /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: GOOGLE_G_SM } }),
1462
+ `read all ${reviewCount} reviews on google`
1463
+ ]
1464
+ }
1465
+ ) })
1297
1466
  ] });
1298
1467
  }
1299
1468
  function Stars({ rating, color, size }) {
@@ -1729,7 +1898,7 @@ var WhaleStorefront = (function (exports) {
1729
1898
  case "video":
1730
1899
  return /* @__PURE__ */ jsx(VideoSection, { section, theme });
1731
1900
  case "gallery":
1732
- return /* @__PURE__ */ jsx(GallerySection, { section, theme });
1901
+ return /* @__PURE__ */ jsx(GallerySection, { section, theme, onEvent });
1733
1902
  case "cta":
1734
1903
  return /* @__PURE__ */ jsx(CTASection, { section, theme, tracking, onEvent });
1735
1904
  case "stats":
@@ -1761,6 +1930,7 @@ var WhaleStorefront = (function (exports) {
1761
1930
  }
1762
1931
  })();
1763
1932
  const sectionRef = useRef(null);
1933
+ const isHero = section.type === "hero" || section.type === "collage_hero";
1764
1934
  useEffect(() => {
1765
1935
  const el2 = sectionRef.current;
1766
1936
  if (!el2 || typeof IntersectionObserver === "undefined") return;
@@ -1768,18 +1938,28 @@ var WhaleStorefront = (function (exports) {
1768
1938
  ([entry]) => {
1769
1939
  if (entry.isIntersecting) {
1770
1940
  onEvent?.("section_view", { section_id: section.id, section_type: section.type });
1941
+ el2.setAttribute("data-reveal", "visible");
1771
1942
  obs.disconnect();
1772
1943
  }
1773
1944
  },
1774
- { threshold: 0.5 }
1945
+ { threshold: 0.15 }
1775
1946
  );
1776
1947
  obs.observe(el2);
1777
1948
  return () => obs.disconnect();
1778
1949
  }, [section.id, section.type, onEvent]);
1779
- return /* @__PURE__ */ jsx("div", { ref: sectionRef, "data-section-id": section.id, "data-section-type": section.type, children: [
1780
- el,
1781
- showCOA && data?.coa && /* @__PURE__ */ jsx(COAModal, { coa: data.coa, theme, onClose: () => setShowCOA(false) })
1782
- ] });
1950
+ return /* @__PURE__ */ jsx(
1951
+ "div",
1952
+ {
1953
+ ref: sectionRef,
1954
+ "data-section-id": section.id,
1955
+ "data-section-type": section.type,
1956
+ ...!isHero ? { "data-reveal": "" } : {},
1957
+ children: [
1958
+ el,
1959
+ showCOA && data?.coa && /* @__PURE__ */ jsx(COAModal, { coa: data.coa, theme, onClose: () => setShowCOA(false) })
1960
+ ]
1961
+ }
1962
+ );
1783
1963
  }
1784
1964
 
1785
1965
  // src/react/components/landing-page.tsx
@@ -1959,6 +2139,7 @@ var WhaleStorefront = (function (exports) {
1959
2139
  const sorted = [...lp.sections].sort((a, b) => a.order - b.order).filter((s) => isSectionVisible(s, urlParams));
1960
2140
  const sectionData = { ...data, gatewayUrl, landing_page: { slug: lp.slug }, analyticsContext };
1961
2141
  return /* @__PURE__ */ jsx("div", { style: { minHeight: "100dvh", background: theme.bg, color: theme.fg, fontFamily }, children: [
2142
+ /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: LANDING_ANIMATIONS } }),
1962
2143
  lp.custom_css && /* @__PURE__ */ jsx("style", { children: lp.custom_css }),
1963
2144
  logoUrl && /* @__PURE__ */ jsx("div", { style: { padding: "1.5rem", display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsx("img", { src: logoUrl, alt: store?.name || "Store", style: { height: 40, objectFit: "contain" } }) }),
1964
2145
  sorted.map((section) => {
@@ -1982,6 +2163,49 @@ var WhaleStorefront = (function (exports) {
1982
2163
  });
1983
2164
  }
1984
2165
  }
2166
+ var LANDING_ANIMATIONS = `
2167
+ @keyframes lp-fadeUp{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:translateY(0)}}
2168
+ @keyframes lp-fadeIn{from{opacity:0}to{opacity:1}}
2169
+ @keyframes lp-scaleIn{from{opacity:0;transform:scale(0.96)}to{opacity:1;transform:scale(1)}}
2170
+ @keyframes spin{to{transform:rotate(360deg)}}
2171
+
2172
+ /* Hero staggered entrance */
2173
+ [data-section-type="hero"] h1{animation:lp-fadeUp 0.8s cubic-bezier(0.22,1,0.36,1) both}
2174
+ [data-section-type="hero"] p{animation:lp-fadeUp 0.8s cubic-bezier(0.22,1,0.36,1) 0.15s both}
2175
+ [data-section-type="hero"] button,[data-section-type="hero"] a[style*="inline-block"]{animation:lp-fadeUp 0.8s cubic-bezier(0.22,1,0.36,1) 0.3s both}
2176
+ [data-section-type="hero"] form{animation:lp-scaleIn 0.4s cubic-bezier(0.22,1,0.36,1) both}
2177
+
2178
+ /* Scroll reveal \u2014 hidden by default, revealed by IntersectionObserver */
2179
+ [data-reveal]{opacity:0;transform:translateY(20px);transition:opacity 0.7s cubic-bezier(0.22,1,0.36,1),transform 0.7s cubic-bezier(0.22,1,0.36,1)}
2180
+ [data-reveal="visible"]{opacity:1;transform:translateY(0)}
2181
+
2182
+ /* Stagger children inside revealed sections */
2183
+ [data-reveal="visible"] > *{animation:lp-fadeUp 0.6s cubic-bezier(0.22,1,0.36,1) both}
2184
+ [data-reveal="visible"] > *:nth-child(1){animation-delay:0s}
2185
+ [data-reveal="visible"] > *:nth-child(2){animation-delay:0.08s}
2186
+ [data-reveal="visible"] > *:nth-child(3){animation-delay:0.16s}
2187
+ [data-reveal="visible"] > *:nth-child(4){animation-delay:0.24s}
2188
+
2189
+ /* Gallery image hover */
2190
+ [data-section-type="gallery"] img{transition:transform 1.2s cubic-bezier(0.22,1,0.36,1)}
2191
+ [data-section-type="gallery"] div:hover > img{transform:scale(1.03)}
2192
+
2193
+ /* Button hover effects */
2194
+ [data-section-type="cta"] a,[data-section-type="testimonials"] a{transition:opacity 0.3s,background 0.3s,transform 0.2s}
2195
+ [data-section-type="cta"] a:hover{opacity:0.88}
2196
+ [data-section-type="cta"] a:active{transform:scale(0.98)}
2197
+
2198
+ /* Review card hover */
2199
+ .rv-card > div{transition:border-color 0.4s}
2200
+ .rv-card:hover > div{border-color:rgba(255,255,255,0.12)!important}
2201
+
2202
+ /* Location card image hover */
2203
+ [data-section-type="gallery"] [style*="4/5"] img{transition:transform 1.2s cubic-bezier(0.22,1,0.36,1)}
2204
+ [data-section-type="gallery"] [style*="4/5"]:hover img{transform:scale(1.03)}
2205
+
2206
+ /* Smooth logo entrance */
2207
+ [style*="justify-content: center"] > img[alt]{animation:lp-fadeIn 1s cubic-bezier(0.22,1,0.36,1) both}
2208
+ `;
1985
2209
  var screenStyle = {
1986
2210
  minHeight: "100dvh",
1987
2211
  display: "flex",