diff --git a/modules/blox/blox/cta-card/component.jsx b/modules/blox/blox/cta-card/component.jsx index 58c927c2..c93433aa 100644 --- a/modules/blox/blox/cta-card/component.jsx +++ b/modules/blox/blox/cta-card/component.jsx @@ -47,25 +47,22 @@ export const CtaCardBlock = ({content, design, _id, button_icon_svg}) => { // Legacy detection: design.background.gradient.start using saturated Tailwind tokens const bg = design?.background || {}; const gradientStart = bg.gradient?.start || ""; - const legacyDarkBg = ["primary-7", "primary-8", "primary-9", "secondary-7", "secondary-8", "secondary-9"].some((p) => gradientStart.startsWith(p)); - textColorMode = (looksColored || legacyDarkBg) ? "light" : "dark"; + const legacyDarkBg = ["primary-7", "primary-8", "primary-9", "secondary-7", "secondary-8", "secondary-9"].some((p) => + gradientStart.startsWith(p), + ); + textColorMode = looksColored || legacyDarkBg ? "light" : "dark"; } // Title, body, and button classes — full literals only - const titleClasses = textColorMode === "light" - ? "text-white" - : "text-gray-900 dark:text-white"; - const bodyClasses = textColorMode === "light" - ? "text-white/80" - : "text-gray-700 dark:text-gray-300"; + const titleClasses = textColorMode === "light" ? "text-white" : "text-gray-900 dark:text-white"; + const bodyClasses = textColorMode === "light" ? "text-white/80" : "text-gray-700 dark:text-gray-300"; // Button: in "light" mode (coloured card), keep a white pill across both themes for consistency. // In "dark" mode (light card), use a dark pill. - const buttonBgClasses = textColorMode === "light" - ? "bg-white ring-1 ring-white/40 hover:bg-white/95 hover:ring-white/60 shadow-lg" - : "bg-gray-900 dark:bg-white ring-1 ring-gray-900/10 dark:ring-white/10 hover:bg-gray-800 dark:hover:bg-gray-100 shadow-lg"; - const buttonTextClasses = textColorMode === "light" - ? "text-gray-900" - : "text-white dark:text-gray-900"; + const buttonBgClasses = + textColorMode === "light" + ? "bg-white ring-1 ring-white/40 hover:bg-white/95 hover:ring-white/60 shadow-lg" + : "bg-gray-900 dark:bg-white ring-1 ring-gray-900/10 dark:ring-white/10 hover:bg-gray-800 dark:hover:bg-gray-100 shadow-lg"; + const buttonTextClasses = textColorMode === "light" ? "text-gray-900" : "text-white dark:text-gray-900"; // Button Logic const button = content?.button || {}; diff --git a/modules/blox/blox/cta-image-paragraph/component.jsx b/modules/blox/blox/cta-image-paragraph/component.jsx index 54f0114f..1700d32e 100644 --- a/modules/blox/blox/cta-image-paragraph/component.jsx +++ b/modules/blox/blox/cta-image-paragraph/component.jsx @@ -6,7 +6,6 @@ import {Icon} from "../../shared/components/Icon.jsx"; -// Simple markdown renderer function renderText(text) { if (!text) return ""; return String(text) @@ -16,23 +15,11 @@ function renderText(text) { .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); } -// Arrow icon for CTA buttons -const ArrowIcon = () => ( - -); +const ARROW_SVG = ``; function CtaItem({item, idx, imageData, featureIconSvg}) { const isReversed = idx % 2 === 1; - const hasImage = !!imageData; - const _featureIcon = item.feature_icon || "check"; - // Resolve button link const buttonUrl = item.button?.url || ""; let isExternal = false; if (buttonUrl) { @@ -47,65 +34,78 @@ function CtaItem({item, idx, imageData, featureIconSvg}) { const features = Array.isArray(item.features) ? item.features : typeof item.features === "string" ? [item.features] : []; return ( -
$1');
+ .replace(
+ /`(.*?)`/g,
+ '$1',
+ );
}
function FeatureCard({item, iconSvg, imgData, variant = "grid", large = false}) {
@@ -14,22 +17,18 @@ function FeatureCard({item, iconSvg, imgData, variant = "grid", large = false})
? `relative h-full rounded-2xl ring-1 ring-gray-200 dark:ring-gray-700 bg-white dark:bg-gray-800/50 ${large ? "p-8 lg:p-10" : "p-6"} hover:ring-primary-300 dark:hover:ring-primary-600 hover:shadow-lg transition-all duration-300 overflow-hidden`
: "";
- const iconWrapper = large
- ? "w-14 h-14 lg:w-16 lg:h-16"
- : "w-11 h-11 lg:w-12 lg:h-12";
- const iconSize = large
- ? "height:1.75rem;width:auto"
- : "height:1.4rem;width:auto";
+ const iconWrapper = large ? "w-14 h-14 lg:w-16 lg:h-16" : "w-11 h-11 lg:w-12 lg:h-12";
+ const iconSize = large ? "height:1.75rem;width:auto" : "height:1.4rem;width:auto";
- const titleSize = large
- ? "text-2xl lg:text-3xl"
- : isCard ? "text-lg lg:text-xl" : "text-xl";
+ const titleSize = large ? "text-2xl lg:text-3xl" : isCard ? "text-lg lg:text-xl" : "text-xl";
const descSize = large ? "text-base lg:text-lg" : "text-sm lg:text-base";
return (
- {subtitle} -
- )} + {subtitle &&{subtitle}
} {title && ( )} - {text && ( - - )} + {text && }- {price_note || "Contact us"} -
+{price_note || "Contact us"}
{description}
} +{description}
- )} -${code}`);
+ .replace(
+ /`(.*?)`/g,
+ (_, code) =>
+ `${code}`,
+ );
}
function toRoman(n) {
@@ -47,9 +51,9 @@ function StepMarker({idx, iconSvg, markerStyle, numbering, size = "sm"}) {
);
}
- const dim = size === "lg" ? "w-14 h-14 text-base" : "w-10 h-10 text-sm";
+ const dim = size === "lg" ? "w-14 h-14 text-base" : "w-10 h-10 text-sm";
const iconH = size === "lg" ? "1.75rem" : "1.25rem";
- const base = `${dim} flex items-center justify-center rounded-full flex-shrink-0 font-bold`;
+ const base = `${dim} flex items-center justify-center rounded-full flex-shrink-0 font-bold`;
// Vertical/timeline icon — keep circle for visual anchoring against the connector line
if (markerStyle === "icon" && iconSvg) {
@@ -60,27 +64,17 @@ function StepMarker({idx, iconSvg, markerStyle, numbering, size = "sm"}) {
);
}
- return (
- - {subtitle} -
- )} + {subtitle &&{subtitle}
} {title && ( +$1");
}
-function TestimonialItem({item, avatarUrl, isLast}) {
+function Avatar({item, avatarUrl, size = "lg"}) {
+ const sizeClass = size === "lg" ? "w-14 h-14" : "w-10 h-10";
+ const textSize = size === "lg" ? "text-xl" : "text-base";
+ const initial = item.name ? item.name.trim()[0].toUpperCase() : "?";
+
+ if (avatarUrl) {
+ return (
+ - ++ {initial} ++ ); +} + +function TestimonialFeatured({item, avatarUrl}) { + return ( ++ {/* Decorative large quote mark */} + + ++-- {/* Avatar */} - {avatarUrl ? ( -- ) : ( - - )} -
- {item.name &&+ ); +} + +function TestimonialCard({item, avatarUrl}) { + return ( +{item.name}} - {item.role &&{item.role}} + ++++ + {item.name &&+{item.name}} + {item.role &&{item.role}} ++@@ -55,27 +93,36 @@ export const TestimonialsBlock = ({content, _design, _id, item_images}) => { const items = Array.isArray(content?.items) ? content.items : []; const imageMap = item_images || {}; - return ( -+ ++ +++ + {item.name &&{item.name}} + {item.role &&{item.role}}- + return ( +- {/* Section Header */} - {title && ( ---- )} + const gridCols = + items.length === 1 + ? "" + : items.length === 2 + ? "grid grid-cols-1 sm:grid-cols-2 gap-6 max-w-4xl mx-auto" + : "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"; - {/* Testimonial Items */} - {items.map((item, idx) => ( -- - {text && } --- ))} - + {(title || text) && ( +); }; diff --git a/modules/blox/layouts/_partials/functions/parse_block_v3.html b/modules/blox/layouts/_partials/functions/parse_block_v3.html index e91a7f56..f784c646 100644 --- a/modules/blox/layouts/_partials/functions/parse_block_v3.html +++ b/modules/blox/layouts/_partials/functions/parse_block_v3.html @@ -55,6 +55,16 @@ {{ $gradient_mesh := $bg.gradient_mesh | default dict }} {{ if $gradient_mesh.enable }} {{ $has_gradient_mesh = true }} + + {{/* Stacking-fix: the mesh wrapper sits at z-index:-10, while .home-section-bg sits at z-index:-1. + If we leave bg-color on home-section-bg, the colour paints OVER the mesh and the orbs are hidden. + Migrate the bg-color off home-section-bg and onto the section element itself, so the section's + own background paints BEHIND the mesh layer (orbs visible) and the radial gradient + image layers + on home-section-bg paint ABOVE the mesh (still visible). */}} + {{ if $style_bg }} + {{ $style = print $style $style_bg }} + {{ $style_bg = "" }} + {{ end }} {{ $mesh_style := $gradient_mesh.style | default "orbs" }} {{ $mesh_animation_raw := $gradient_mesh.animation | default "pulse" }} {{ $mesh_intensity := $gradient_mesh.intensity | default "subtle" }}+ {title && ( + + )} + {text && } ++ )} + + {items.length === 1 ? ( ++ ) : ( + + {items.map((item, idx) => ( ++ )} ++ ))} +