@opensite/ui 0.1.2 → 0.1.4
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/components.cjs +1511 -3
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +13 -0
- package/dist/components.d.ts +13 -0
- package/dist/components.js +1499 -4
- package/dist/components.js.map +1 -1
- package/dist/footer-animated-social.cjs +272 -0
- package/dist/footer-animated-social.cjs.map +1 -0
- package/dist/footer-animated-social.d.cts +41 -0
- package/dist/footer-animated-social.d.ts +41 -0
- package/dist/footer-animated-social.js +250 -0
- package/dist/footer-animated-social.js.map +1 -0
- package/dist/footer-background-card.cjs +149 -0
- package/dist/footer-background-card.cjs.map +1 -0
- package/dist/footer-background-card.d.cts +74 -0
- package/dist/footer-background-card.d.ts +74 -0
- package/dist/footer-background-card.js +147 -0
- package/dist/footer-background-card.js.map +1 -0
- package/dist/footer-brand-description.cjs +244 -0
- package/dist/footer-brand-description.cjs.map +1 -0
- package/dist/footer-brand-description.d.cts +65 -0
- package/dist/footer-brand-description.d.ts +65 -0
- package/dist/footer-brand-description.js +222 -0
- package/dist/footer-brand-description.js.map +1 -0
- package/dist/footer-contact-card.cjs +238 -0
- package/dist/footer-contact-card.cjs.map +1 -0
- package/dist/footer-contact-card.d.cts +65 -0
- package/dist/footer-contact-card.d.ts +65 -0
- package/dist/footer-contact-card.js +216 -0
- package/dist/footer-contact-card.js.map +1 -0
- package/dist/footer-cta-banner.cjs +282 -0
- package/dist/footer-cta-banner.cjs.map +1 -0
- package/dist/footer-cta-banner.d.cts +77 -0
- package/dist/footer-cta-banner.d.ts +77 -0
- package/dist/footer-cta-banner.js +260 -0
- package/dist/footer-cta-banner.js.map +1 -0
- package/dist/footer-cta-social.cjs +221 -0
- package/dist/footer-cta-social.cjs.map +1 -0
- package/dist/footer-cta-social.d.cts +45 -0
- package/dist/footer-cta-social.d.ts +45 -0
- package/dist/footer-cta-social.js +199 -0
- package/dist/footer-cta-social.js.map +1 -0
- package/dist/footer-links-grid.cjs +119 -0
- package/dist/footer-links-grid.cjs.map +1 -0
- package/dist/footer-links-grid.d.cts +54 -0
- package/dist/footer-links-grid.d.ts +54 -0
- package/dist/footer-links-grid.js +117 -0
- package/dist/footer-links-grid.js.map +1 -0
- package/dist/footer-nav-social.cjs +273 -0
- package/dist/footer-nav-social.cjs.map +1 -0
- package/dist/footer-nav-social.d.cts +72 -0
- package/dist/footer-nav-social.d.ts +72 -0
- package/dist/footer-nav-social.js +251 -0
- package/dist/footer-nav-social.js.map +1 -0
- package/dist/footer-newsletter-grid.cjs +271 -0
- package/dist/footer-newsletter-grid.cjs.map +1 -0
- package/dist/footer-newsletter-grid.d.cts +74 -0
- package/dist/footer-newsletter-grid.d.ts +74 -0
- package/dist/footer-newsletter-grid.js +249 -0
- package/dist/footer-newsletter-grid.js.map +1 -0
- package/dist/footer-newsletter-minimal.cjs +271 -0
- package/dist/footer-newsletter-minimal.cjs.map +1 -0
- package/dist/footer-newsletter-minimal.d.cts +57 -0
- package/dist/footer-newsletter-minimal.d.ts +57 -0
- package/dist/footer-newsletter-minimal.js +249 -0
- package/dist/footer-newsletter-minimal.js.map +1 -0
- package/dist/footer-simple-centered.cjs +101 -0
- package/dist/footer-simple-centered.cjs.map +1 -0
- package/dist/footer-simple-centered.d.cts +52 -0
- package/dist/footer-simple-centered.d.ts +52 -0
- package/dist/footer-simple-centered.js +99 -0
- package/dist/footer-simple-centered.js.map +1 -0
- package/dist/footer-social-apps.cjs +247 -0
- package/dist/footer-social-apps.cjs.map +1 -0
- package/dist/footer-social-apps.d.cts +75 -0
- package/dist/footer-social-apps.d.ts +75 -0
- package/dist/footer-social-apps.js +225 -0
- package/dist/footer-social-apps.js.map +1 -0
- package/dist/footer-social-newsletter.cjs +267 -0
- package/dist/footer-social-newsletter.cjs.map +1 -0
- package/dist/footer-social-newsletter.d.cts +68 -0
- package/dist/footer-social-newsletter.d.ts +68 -0
- package/dist/footer-social-newsletter.js +245 -0
- package/dist/footer-social-newsletter.js.map +1 -0
- package/dist/index.cjs +1511 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1499 -4
- package/dist/index.js.map +1 -1
- package/dist/pressable.cjs +10 -3
- package/dist/pressable.cjs.map +1 -1
- package/dist/pressable.js +10 -3
- package/dist/pressable.js.map +1 -1
- package/dist/registry.cjs +1971 -1
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +1971 -1
- package/dist/registry.js.map +1 -1
- package/dist/team-media-showcase.cjs +182 -0
- package/dist/team-media-showcase.cjs.map +1 -0
- package/dist/team-media-showcase.d.cts +145 -0
- package/dist/team-media-showcase.d.ts +145 -0
- package/dist/team-media-showcase.js +160 -0
- package/dist/team-media-showcase.js.map +1 -0
- package/package.json +71 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../components/ui/dynamic-icon.tsx","../components/blocks/footers/footer-nav-social.tsx"],"names":["twMerge","clsx","React","iconName","jsx","jsxs","Img"],"mappings":"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","file":"footer-nav-social.cjs","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\ninterface DynamicIconProps {\n /**\n * Icon name in format: prefix/name or prefix:name\n * Examples: \"lucide/home\", \"mdi:account\", \"heroicons/check\"\n */\n name: string;\n /**\n * Icon size in pixels\n * @default 28\n */\n size?: number;\n /**\n * Icon color - accepts any valid CSS color\n * Note: When not specified, the icon inherits color from parent via CSS currentColor\n */\n color?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Alt text for accessibility\n */\n alt?: string;\n}\n\n// Simple in-memory cache for fetched SVGs\nconst svgCache = new Map<string, string>();\n\n/**\n * Lightweight icon component that dynamically loads SVG icons from icons.opensite.ai API.\n *\n * Features:\n * - Pulls SVGs from https://icons.opensite.ai API and inlines them for CSS color inheritance\n * - Supports currentColor - icons inherit color from parent element\n * - Accepts prefix/name or prefix:name format\n * - Customizable size and explicit color via props\n * - In-memory caching to prevent duplicate fetches\n *\n * @example\n * ```tsx\n * // Icon inherits color from parent (recommended for hover states, etc.)\n * <span className=\"text-white hover:text-red-500\">\n * <DynamicIcon name=\"lucide/home\" size={24} />\n * </span>\n *\n * // Icon with explicit color\n * <DynamicIcon name=\"mdi:account\" size={32} color=\"#ff0000\" />\n * ```\n */\nexport function DynamicIcon({\n name,\n size = 28,\n color,\n className,\n alt,\n}: DynamicIconProps) {\n const [svgContent, setSvgContent] = React.useState<string | null>(null);\n const [isLoading, setIsLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n const { url, iconName } = React.useMemo(() => {\n const separator = name.includes(\"/\") ? \"/\" : \":\";\n const [prefix, iconName] = name.split(separator);\n // Don't pass color to API - we'll handle it via CSS\n const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName}?format=svg&width=${size}&height=${size}`;\n\n return {\n url: baseUrl,\n iconName,\n };\n }, [name, size]);\n\n React.useEffect(() => {\n let isMounted = true;\n\n const fetchSvg = async () => {\n // Check cache first\n const cached = svgCache.get(url);\n if (cached) {\n if (isMounted) {\n setSvgContent(cached);\n setIsLoading(false);\n }\n return;\n }\n\n try {\n setIsLoading(true);\n setError(null);\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch icon: ${response.status}`);\n }\n\n let svg = await response.text();\n\n // Process SVG to ensure currentColor works:\n // 1. Replace any hardcoded colors with currentColor\n // 2. Ensure stroke/fill use currentColor where appropriate\n svg = processSvgForCurrentColor(svg);\n\n // Cache the processed SVG\n svgCache.set(url, svg);\n\n if (isMounted) {\n setSvgContent(svg);\n setIsLoading(false);\n }\n } catch (err) {\n if (isMounted) {\n setError(err instanceof Error ? err.message : \"Failed to load icon\");\n setIsLoading(false);\n }\n }\n };\n\n fetchSvg();\n\n return () => {\n isMounted = false;\n };\n }, [url]);\n\n // Loading state - show placeholder with same dimensions\n if (isLoading) {\n return (\n <span\n className={cn(\"inline-block\", className)}\n style={{ width: size, height: size }}\n aria-hidden=\"true\"\n />\n );\n }\n\n // Error state - show nothing or fallback\n if (error || !svgContent) {\n return (\n <span\n className={cn(\"inline-block\", className)}\n style={{ width: size, height: size }}\n role=\"img\"\n aria-label={alt || iconName}\n />\n );\n }\n\n // Render inline SVG\n // The color prop applies an explicit color, otherwise inherits from parent via currentColor\n return (\n <span\n className={cn(\"inline-flex items-center justify-center\", className)}\n style={{\n width: size,\n height: size,\n color: color || \"inherit\",\n }}\n role=\"img\"\n aria-label={alt || iconName}\n dangerouslySetInnerHTML={{ __html: svgContent }}\n />\n );\n}\n\n/**\n * Process SVG to ensure it uses currentColor for proper CSS inheritance.\n * This handles various icon libraries that may use different color approaches.\n */\nfunction processSvgForCurrentColor(svg: string): string {\n // Replace stroke=\"currentColor\" is already correct, but ensure fill also works\n // Some icons use fill=\"none\" with stroke, others use fill with no stroke\n\n // Ensure the SVG doesn't have hardcoded colors that should be currentColor\n // Common patterns to replace:\n // - stroke=\"#000\" or stroke=\"#000000\" or stroke=\"black\" -> stroke=\"currentColor\"\n // - fill=\"#000\" or fill=\"#000000\" or fill=\"black\" -> fill=\"currentColor\"\n\n let processed = svg;\n\n // Replace common black color values with currentColor for stroke\n processed = processed.replace(\n /stroke=[\"'](#000000|#000|black)[\"']/gi,\n 'stroke=\"currentColor\"'\n );\n\n // Replace common black color values with currentColor for fill\n // But be careful not to replace fill=\"none\"\n processed = processed.replace(\n /fill=[\"'](#000000|#000|black)[\"']/gi,\n 'fill=\"currentColor\"'\n );\n\n return processed;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Img } from \"@page-speed/img\";\nimport { DynamicIcon } from \"../../ui/dynamic-icon\";\n\n/**\n * Social link configuration\n */\nexport interface FooterNavSocialLink {\n /** Icon name in format: prefix/name (e.g., \"simple-icons/instagram\") */\n icon: string;\n /** Link URL */\n href: string;\n /** Accessible label */\n label: string;\n}\n\n/**\n * Navigation section configuration\n */\nexport interface FooterNavSocialSection {\n title: string;\n links: {\n name: string;\n href: string;\n }[];\n}\n\n/**\n * Props for the FooterNavSocial component\n */\nexport interface FooterNavSocialProps {\n /** Logo configuration */\n logo?: {\n url: string;\n src: string;\n alt: string;\n title: string;\n };\n /** Additional CSS classes */\n className?: string;\n /** Navigation sections */\n sections?: FooterNavSocialSection[];\n /** Social media links */\n socialLinks?: FooterNavSocialLink[];\n /** Newsletter heading */\n newsletterHeading?: string;\n /** Newsletter description */\n newsletterDescription?: string;\n /** Newsletter placeholder */\n newsletterPlaceholder?: string;\n /** Newsletter button text */\n newsletterButtonText?: string;\n /** Copyright text */\n copyright?: string;\n /** Legal links */\n legalLinks?: {\n name: string;\n href: string;\n }[];\n /** Optional Optix Flow configuration for @page-speed/img */\n optixFlowConfig?: {\n apiKey: string;\n compression?: number;\n };\n}\n\nconst defaultSections: FooterNavSocialSection[] = [\n {\n title: \"Product\",\n links: [\n { name: \"Overview\", href: \"#\" },\n { name: \"Pricing\", href: \"#\" },\n { name: \"Marketplace\", href: \"#\" },\n { name: \"Features\", href: \"#\" },\n ],\n },\n {\n title: \"Company\",\n links: [\n { name: \"About\", href: \"#\" },\n { name: \"Team\", href: \"#\" },\n { name: \"Blog\", href: \"#\" },\n { name: \"Careers\", href: \"#\" },\n ],\n },\n {\n title: \"Resources\",\n links: [\n { name: \"Help\", href: \"#\" },\n { name: \"Sales\", href: \"#\" },\n { name: \"Advertise\", href: \"#\" },\n ],\n },\n];\n\nconst defaultSocialLinks: FooterNavSocialLink[] = [\n { icon: \"simple-icons/instagram\", href: \"#\", label: \"Instagram\" },\n { icon: \"simple-icons/facebook\", href: \"#\", label: \"Facebook\" },\n { icon: \"simple-icons/x\", href: \"#\", label: \"X (Twitter)\" },\n { icon: \"simple-icons/linkedin\", href: \"#\", label: \"LinkedIn\" },\n];\n\nconst defaultLegalLinks = [\n { name: \"Terms and Conditions\", href: \"#\" },\n { name: \"Privacy Policy\", href: \"#\" },\n];\n\n/**\n * FooterNavSocial - A comprehensive footer with logo, navigation, newsletter, and social links.\n *\n * Features a logo with navigation sections, a newsletter signup form with heading and\n * description, social media icons, and legal links. Ideal for SaaS products, corporate\n * websites, and businesses that want a complete footer with all essential elements\n * organized in a clean, professional layout.\n */\nexport function FooterNavSocial({\n logo = {\n url: \"https://opensite.ai\",\n src: \"https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png\",\n alt: \"Opensite AI\",\n title: \"Opensite AI\",\n },\n className,\n sections = defaultSections,\n socialLinks = defaultSocialLinks,\n newsletterHeading = \"Stay Updated\",\n newsletterDescription = \"Subscribe to our newsletter for the latest updates and news.\",\n newsletterPlaceholder = \"Enter your email\",\n newsletterButtonText = \"Subscribe\",\n copyright = `© ${new Date().getFullYear()} Opensite AI. All rights reserved.`,\n legalLinks = defaultLegalLinks,\n optixFlowConfig,\n}: FooterNavSocialProps): React.JSX.Element {\n return (\n <section className={cn(\"py-32\", className)}>\n <div className=\"container\">\n <footer>\n <div className=\"grid gap-10 lg:grid-cols-2\">\n {/* Left Column - Logo and Navigation */}\n <div>\n <a href={logo.url} className=\"mb-8 flex items-center gap-2\">\n <Img\n src={logo.src}\n alt={logo.alt}\n className=\"h-10\"\n optixFlowConfig={optixFlowConfig}\n />\n <span className=\"text-xl font-semibold\">{logo.title}</span>\n </a>\n <div className=\"grid gap-8 sm:grid-cols-3\">\n {sections.map((section, sectionIdx) => (\n <div key={sectionIdx}>\n <h3 className=\"mb-4 font-semibold\">{section.title}</h3>\n <ul className=\"space-y-3 text-sm text-muted-foreground\">\n {section.links.map((link, linkIdx) => (\n <li key={linkIdx}>\n <a href={link.href} className=\"hover:text-primary\">\n {link.name}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n </div>\n\n {/* Right Column - Newsletter and Social */}\n <div className=\"flex flex-col justify-between\">\n <div className=\"mb-8\">\n <h3 className=\"mb-2 text-lg font-semibold\">{newsletterHeading}</h3>\n <p className=\"mb-4 text-sm text-muted-foreground\">\n {newsletterDescription}\n </p>\n <div className=\"flex max-w-md gap-2\">\n <input\n type=\"email\"\n placeholder={newsletterPlaceholder}\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\"\n />\n <button\n type=\"submit\"\n className=\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2\"\n >\n {newsletterButtonText}\n </button>\n </div>\n </div>\n <div>\n <p className=\"mb-4 font-medium\">Follow Us</p>\n <ul className=\"flex items-center gap-4\">\n {socialLinks.map((social, idx) => (\n <li key={idx}>\n <a\n href={social.href}\n aria-label={social.label}\n className=\"text-muted-foreground transition-colors hover:text-primary\"\n >\n <DynamicIcon name={social.icon} size={20} />\n </a>\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n\n {/* Bottom Section */}\n <div className=\"mt-16 flex flex-col justify-between gap-4 border-t pt-8 text-sm text-muted-foreground md:flex-row md:items-center\">\n <div className=\"flex flex-col gap-2 md:flex-row md:items-center md:gap-4\">\n <p>{copyright}</p>\n <a\n href=\"https://opensite.ai\"\n className=\"hover:text-primary\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n AI Website and Automation Platform by Opensite\n </a>\n </div>\n <ul className=\"flex gap-4\">\n {legalLinks.map((link, idx) => (\n <li key={idx}>\n <a href={link.href} className=\"hover:text-primary\">\n {link.name}\n </a>\n </li>\n ))}\n </ul>\n </div>\n </footer>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Social link configuration
|
|
5
|
+
*/
|
|
6
|
+
interface FooterNavSocialLink {
|
|
7
|
+
/** Icon name in format: prefix/name (e.g., "simple-icons/instagram") */
|
|
8
|
+
icon: string;
|
|
9
|
+
/** Link URL */
|
|
10
|
+
href: string;
|
|
11
|
+
/** Accessible label */
|
|
12
|
+
label: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Navigation section configuration
|
|
16
|
+
*/
|
|
17
|
+
interface FooterNavSocialSection {
|
|
18
|
+
title: string;
|
|
19
|
+
links: {
|
|
20
|
+
name: string;
|
|
21
|
+
href: string;
|
|
22
|
+
}[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Props for the FooterNavSocial component
|
|
26
|
+
*/
|
|
27
|
+
interface FooterNavSocialProps {
|
|
28
|
+
/** Logo configuration */
|
|
29
|
+
logo?: {
|
|
30
|
+
url: string;
|
|
31
|
+
src: string;
|
|
32
|
+
alt: string;
|
|
33
|
+
title: string;
|
|
34
|
+
};
|
|
35
|
+
/** Additional CSS classes */
|
|
36
|
+
className?: string;
|
|
37
|
+
/** Navigation sections */
|
|
38
|
+
sections?: FooterNavSocialSection[];
|
|
39
|
+
/** Social media links */
|
|
40
|
+
socialLinks?: FooterNavSocialLink[];
|
|
41
|
+
/** Newsletter heading */
|
|
42
|
+
newsletterHeading?: string;
|
|
43
|
+
/** Newsletter description */
|
|
44
|
+
newsletterDescription?: string;
|
|
45
|
+
/** Newsletter placeholder */
|
|
46
|
+
newsletterPlaceholder?: string;
|
|
47
|
+
/** Newsletter button text */
|
|
48
|
+
newsletterButtonText?: string;
|
|
49
|
+
/** Copyright text */
|
|
50
|
+
copyright?: string;
|
|
51
|
+
/** Legal links */
|
|
52
|
+
legalLinks?: {
|
|
53
|
+
name: string;
|
|
54
|
+
href: string;
|
|
55
|
+
}[];
|
|
56
|
+
/** Optional Optix Flow configuration for @page-speed/img */
|
|
57
|
+
optixFlowConfig?: {
|
|
58
|
+
apiKey: string;
|
|
59
|
+
compression?: number;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* FooterNavSocial - A comprehensive footer with logo, navigation, newsletter, and social links.
|
|
64
|
+
*
|
|
65
|
+
* Features a logo with navigation sections, a newsletter signup form with heading and
|
|
66
|
+
* description, social media icons, and legal links. Ideal for SaaS products, corporate
|
|
67
|
+
* websites, and businesses that want a complete footer with all essential elements
|
|
68
|
+
* organized in a clean, professional layout.
|
|
69
|
+
*/
|
|
70
|
+
declare function FooterNavSocial({ logo, className, sections, socialLinks, newsletterHeading, newsletterDescription, newsletterPlaceholder, newsletterButtonText, copyright, legalLinks, optixFlowConfig, }: FooterNavSocialProps): React.JSX.Element;
|
|
71
|
+
|
|
72
|
+
export { FooterNavSocial, type FooterNavSocialLink, type FooterNavSocialProps, type FooterNavSocialSection };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Social link configuration
|
|
5
|
+
*/
|
|
6
|
+
interface FooterNavSocialLink {
|
|
7
|
+
/** Icon name in format: prefix/name (e.g., "simple-icons/instagram") */
|
|
8
|
+
icon: string;
|
|
9
|
+
/** Link URL */
|
|
10
|
+
href: string;
|
|
11
|
+
/** Accessible label */
|
|
12
|
+
label: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Navigation section configuration
|
|
16
|
+
*/
|
|
17
|
+
interface FooterNavSocialSection {
|
|
18
|
+
title: string;
|
|
19
|
+
links: {
|
|
20
|
+
name: string;
|
|
21
|
+
href: string;
|
|
22
|
+
}[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Props for the FooterNavSocial component
|
|
26
|
+
*/
|
|
27
|
+
interface FooterNavSocialProps {
|
|
28
|
+
/** Logo configuration */
|
|
29
|
+
logo?: {
|
|
30
|
+
url: string;
|
|
31
|
+
src: string;
|
|
32
|
+
alt: string;
|
|
33
|
+
title: string;
|
|
34
|
+
};
|
|
35
|
+
/** Additional CSS classes */
|
|
36
|
+
className?: string;
|
|
37
|
+
/** Navigation sections */
|
|
38
|
+
sections?: FooterNavSocialSection[];
|
|
39
|
+
/** Social media links */
|
|
40
|
+
socialLinks?: FooterNavSocialLink[];
|
|
41
|
+
/** Newsletter heading */
|
|
42
|
+
newsletterHeading?: string;
|
|
43
|
+
/** Newsletter description */
|
|
44
|
+
newsletterDescription?: string;
|
|
45
|
+
/** Newsletter placeholder */
|
|
46
|
+
newsletterPlaceholder?: string;
|
|
47
|
+
/** Newsletter button text */
|
|
48
|
+
newsletterButtonText?: string;
|
|
49
|
+
/** Copyright text */
|
|
50
|
+
copyright?: string;
|
|
51
|
+
/** Legal links */
|
|
52
|
+
legalLinks?: {
|
|
53
|
+
name: string;
|
|
54
|
+
href: string;
|
|
55
|
+
}[];
|
|
56
|
+
/** Optional Optix Flow configuration for @page-speed/img */
|
|
57
|
+
optixFlowConfig?: {
|
|
58
|
+
apiKey: string;
|
|
59
|
+
compression?: number;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* FooterNavSocial - A comprehensive footer with logo, navigation, newsletter, and social links.
|
|
64
|
+
*
|
|
65
|
+
* Features a logo with navigation sections, a newsletter signup form with heading and
|
|
66
|
+
* description, social media icons, and legal links. Ideal for SaaS products, corporate
|
|
67
|
+
* websites, and businesses that want a complete footer with all essential elements
|
|
68
|
+
* organized in a clean, professional layout.
|
|
69
|
+
*/
|
|
70
|
+
declare function FooterNavSocial({ logo, className, sections, socialLinks, newsletterHeading, newsletterDescription, newsletterPlaceholder, newsletterButtonText, copyright, legalLinks, optixFlowConfig, }: FooterNavSocialProps): React.JSX.Element;
|
|
71
|
+
|
|
72
|
+
export { FooterNavSocial, type FooterNavSocialLink, type FooterNavSocialProps, type FooterNavSocialSection };
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import { Img } from '@page-speed/img';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
// lib/utils.ts
|
|
9
|
+
function cn(...inputs) {
|
|
10
|
+
return twMerge(clsx(inputs));
|
|
11
|
+
}
|
|
12
|
+
var svgCache = /* @__PURE__ */ new Map();
|
|
13
|
+
function DynamicIcon({
|
|
14
|
+
name,
|
|
15
|
+
size = 28,
|
|
16
|
+
color,
|
|
17
|
+
className,
|
|
18
|
+
alt
|
|
19
|
+
}) {
|
|
20
|
+
const [svgContent, setSvgContent] = React.useState(null);
|
|
21
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
22
|
+
const [error, setError] = React.useState(null);
|
|
23
|
+
const { url, iconName } = React.useMemo(() => {
|
|
24
|
+
const separator = name.includes("/") ? "/" : ":";
|
|
25
|
+
const [prefix, iconName2] = name.split(separator);
|
|
26
|
+
const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName2}?format=svg&width=${size}&height=${size}`;
|
|
27
|
+
return {
|
|
28
|
+
url: baseUrl,
|
|
29
|
+
iconName: iconName2
|
|
30
|
+
};
|
|
31
|
+
}, [name, size]);
|
|
32
|
+
React.useEffect(() => {
|
|
33
|
+
let isMounted = true;
|
|
34
|
+
const fetchSvg = async () => {
|
|
35
|
+
const cached = svgCache.get(url);
|
|
36
|
+
if (cached) {
|
|
37
|
+
if (isMounted) {
|
|
38
|
+
setSvgContent(cached);
|
|
39
|
+
setIsLoading(false);
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
setIsLoading(true);
|
|
45
|
+
setError(null);
|
|
46
|
+
const response = await fetch(url);
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
throw new Error(`Failed to fetch icon: ${response.status}`);
|
|
49
|
+
}
|
|
50
|
+
let svg = await response.text();
|
|
51
|
+
svg = processSvgForCurrentColor(svg);
|
|
52
|
+
svgCache.set(url, svg);
|
|
53
|
+
if (isMounted) {
|
|
54
|
+
setSvgContent(svg);
|
|
55
|
+
setIsLoading(false);
|
|
56
|
+
}
|
|
57
|
+
} catch (err) {
|
|
58
|
+
if (isMounted) {
|
|
59
|
+
setError(err instanceof Error ? err.message : "Failed to load icon");
|
|
60
|
+
setIsLoading(false);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
fetchSvg();
|
|
65
|
+
return () => {
|
|
66
|
+
isMounted = false;
|
|
67
|
+
};
|
|
68
|
+
}, [url]);
|
|
69
|
+
if (isLoading) {
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
"span",
|
|
72
|
+
{
|
|
73
|
+
className: cn("inline-block", className),
|
|
74
|
+
style: { width: size, height: size },
|
|
75
|
+
"aria-hidden": "true"
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
if (error || !svgContent) {
|
|
80
|
+
return /* @__PURE__ */ jsx(
|
|
81
|
+
"span",
|
|
82
|
+
{
|
|
83
|
+
className: cn("inline-block", className),
|
|
84
|
+
style: { width: size, height: size },
|
|
85
|
+
role: "img",
|
|
86
|
+
"aria-label": alt || iconName
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return /* @__PURE__ */ jsx(
|
|
91
|
+
"span",
|
|
92
|
+
{
|
|
93
|
+
className: cn("inline-flex items-center justify-center", className),
|
|
94
|
+
style: {
|
|
95
|
+
width: size,
|
|
96
|
+
height: size,
|
|
97
|
+
color: color || "inherit"
|
|
98
|
+
},
|
|
99
|
+
role: "img",
|
|
100
|
+
"aria-label": alt || iconName,
|
|
101
|
+
dangerouslySetInnerHTML: { __html: svgContent }
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
function processSvgForCurrentColor(svg) {
|
|
106
|
+
let processed = svg;
|
|
107
|
+
processed = processed.replace(
|
|
108
|
+
/stroke=["'](#000000|#000|black)["']/gi,
|
|
109
|
+
'stroke="currentColor"'
|
|
110
|
+
);
|
|
111
|
+
processed = processed.replace(
|
|
112
|
+
/fill=["'](#000000|#000|black)["']/gi,
|
|
113
|
+
'fill="currentColor"'
|
|
114
|
+
);
|
|
115
|
+
return processed;
|
|
116
|
+
}
|
|
117
|
+
var defaultSections = [
|
|
118
|
+
{
|
|
119
|
+
title: "Product",
|
|
120
|
+
links: [
|
|
121
|
+
{ name: "Overview", href: "#" },
|
|
122
|
+
{ name: "Pricing", href: "#" },
|
|
123
|
+
{ name: "Marketplace", href: "#" },
|
|
124
|
+
{ name: "Features", href: "#" }
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
title: "Company",
|
|
129
|
+
links: [
|
|
130
|
+
{ name: "About", href: "#" },
|
|
131
|
+
{ name: "Team", href: "#" },
|
|
132
|
+
{ name: "Blog", href: "#" },
|
|
133
|
+
{ name: "Careers", href: "#" }
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
title: "Resources",
|
|
138
|
+
links: [
|
|
139
|
+
{ name: "Help", href: "#" },
|
|
140
|
+
{ name: "Sales", href: "#" },
|
|
141
|
+
{ name: "Advertise", href: "#" }
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
];
|
|
145
|
+
var defaultSocialLinks = [
|
|
146
|
+
{ icon: "simple-icons/instagram", href: "#", label: "Instagram" },
|
|
147
|
+
{ icon: "simple-icons/facebook", href: "#", label: "Facebook" },
|
|
148
|
+
{ icon: "simple-icons/x", href: "#", label: "X (Twitter)" },
|
|
149
|
+
{ icon: "simple-icons/linkedin", href: "#", label: "LinkedIn" }
|
|
150
|
+
];
|
|
151
|
+
var defaultLegalLinks = [
|
|
152
|
+
{ name: "Terms and Conditions", href: "#" },
|
|
153
|
+
{ name: "Privacy Policy", href: "#" }
|
|
154
|
+
];
|
|
155
|
+
function FooterNavSocial({
|
|
156
|
+
logo = {
|
|
157
|
+
url: "https://opensite.ai",
|
|
158
|
+
src: "https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png",
|
|
159
|
+
alt: "Opensite AI",
|
|
160
|
+
title: "Opensite AI"
|
|
161
|
+
},
|
|
162
|
+
className,
|
|
163
|
+
sections = defaultSections,
|
|
164
|
+
socialLinks = defaultSocialLinks,
|
|
165
|
+
newsletterHeading = "Stay Updated",
|
|
166
|
+
newsletterDescription = "Subscribe to our newsletter for the latest updates and news.",
|
|
167
|
+
newsletterPlaceholder = "Enter your email",
|
|
168
|
+
newsletterButtonText = "Subscribe",
|
|
169
|
+
copyright = `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} Opensite AI. All rights reserved.`,
|
|
170
|
+
legalLinks = defaultLegalLinks,
|
|
171
|
+
optixFlowConfig
|
|
172
|
+
}) {
|
|
173
|
+
return /* @__PURE__ */ jsx("section", { className: cn("py-32", className), children: /* @__PURE__ */ jsx("div", { className: "container", children: /* @__PURE__ */ jsxs("footer", { children: [
|
|
174
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-10 lg:grid-cols-2", children: [
|
|
175
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
176
|
+
/* @__PURE__ */ jsxs("a", { href: logo.url, className: "mb-8 flex items-center gap-2", children: [
|
|
177
|
+
/* @__PURE__ */ jsx(
|
|
178
|
+
Img,
|
|
179
|
+
{
|
|
180
|
+
src: logo.src,
|
|
181
|
+
alt: logo.alt,
|
|
182
|
+
className: "h-10",
|
|
183
|
+
optixFlowConfig
|
|
184
|
+
}
|
|
185
|
+
),
|
|
186
|
+
/* @__PURE__ */ jsx("span", { className: "text-xl font-semibold", children: logo.title })
|
|
187
|
+
] }),
|
|
188
|
+
/* @__PURE__ */ jsx("div", { className: "grid gap-8 sm:grid-cols-3", children: sections.map((section, sectionIdx) => /* @__PURE__ */ jsxs("div", { children: [
|
|
189
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-4 font-semibold", children: section.title }),
|
|
190
|
+
/* @__PURE__ */ jsx("ul", { className: "space-y-3 text-sm text-muted-foreground", children: section.links.map((link, linkIdx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: link.href, className: "hover:text-primary", children: link.name }) }, linkIdx)) })
|
|
191
|
+
] }, sectionIdx)) })
|
|
192
|
+
] }),
|
|
193
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-between", children: [
|
|
194
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-8", children: [
|
|
195
|
+
/* @__PURE__ */ jsx("h3", { className: "mb-2 text-lg font-semibold", children: newsletterHeading }),
|
|
196
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 text-sm text-muted-foreground", children: newsletterDescription }),
|
|
197
|
+
/* @__PURE__ */ jsxs("div", { className: "flex max-w-md gap-2", children: [
|
|
198
|
+
/* @__PURE__ */ jsx(
|
|
199
|
+
"input",
|
|
200
|
+
{
|
|
201
|
+
type: "email",
|
|
202
|
+
placeholder: newsletterPlaceholder,
|
|
203
|
+
className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
|
204
|
+
}
|
|
205
|
+
),
|
|
206
|
+
/* @__PURE__ */ jsx(
|
|
207
|
+
"button",
|
|
208
|
+
{
|
|
209
|
+
type: "submit",
|
|
210
|
+
className: "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2",
|
|
211
|
+
children: newsletterButtonText
|
|
212
|
+
}
|
|
213
|
+
)
|
|
214
|
+
] })
|
|
215
|
+
] }),
|
|
216
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
217
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 font-medium", children: "Follow Us" }),
|
|
218
|
+
/* @__PURE__ */ jsx("ul", { className: "flex items-center gap-4", children: socialLinks.map((social, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
219
|
+
"a",
|
|
220
|
+
{
|
|
221
|
+
href: social.href,
|
|
222
|
+
"aria-label": social.label,
|
|
223
|
+
className: "text-muted-foreground transition-colors hover:text-primary",
|
|
224
|
+
children: /* @__PURE__ */ jsx(DynamicIcon, { name: social.icon, size: 20 })
|
|
225
|
+
}
|
|
226
|
+
) }, idx)) })
|
|
227
|
+
] })
|
|
228
|
+
] })
|
|
229
|
+
] }),
|
|
230
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-16 flex flex-col justify-between gap-4 border-t pt-8 text-sm text-muted-foreground md:flex-row md:items-center", children: [
|
|
231
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 md:flex-row md:items-center md:gap-4", children: [
|
|
232
|
+
/* @__PURE__ */ jsx("p", { children: copyright }),
|
|
233
|
+
/* @__PURE__ */ jsx(
|
|
234
|
+
"a",
|
|
235
|
+
{
|
|
236
|
+
href: "https://opensite.ai",
|
|
237
|
+
className: "hover:text-primary",
|
|
238
|
+
target: "_blank",
|
|
239
|
+
rel: "noopener noreferrer",
|
|
240
|
+
children: "AI Website and Automation Platform by Opensite"
|
|
241
|
+
}
|
|
242
|
+
)
|
|
243
|
+
] }),
|
|
244
|
+
/* @__PURE__ */ jsx("ul", { className: "flex gap-4", children: legalLinks.map((link, idx) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: link.href, className: "hover:text-primary", children: link.name }) }, idx)) })
|
|
245
|
+
] })
|
|
246
|
+
] }) }) });
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export { FooterNavSocial };
|
|
250
|
+
//# sourceMappingURL=footer-nav-social.js.map
|
|
251
|
+
//# sourceMappingURL=footer-nav-social.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils.ts","../components/ui/dynamic-icon.tsx","../components/blocks/footers/footer-nav-social.tsx"],"names":["iconName","jsx"],"mappings":";;;;;;;AAGO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;AC4BA,IAAM,QAAA,uBAAe,GAAA,EAAoB;AAuBlC,SAAS,WAAA,CAAY;AAAA,EAC1B,IAAA;AAAA,EACA,IAAA,GAAO,EAAA;AAAA,EACP,KAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAU,eAAwB,IAAI,CAAA;AACtE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAU,eAAS,IAAI,CAAA;AACrD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAU,eAAwB,IAAI,CAAA;AAE5D,EAAA,MAAM,EAAE,GAAA,EAAK,QAAA,EAAS,GAAU,cAAQ,MAAM;AAC5C,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,QAAA,CAAS,GAAG,IAAI,GAAA,GAAM,GAAA;AAC7C,IAAA,MAAM,CAAC,MAAA,EAAQA,SAAQ,CAAA,GAAI,IAAA,CAAK,MAAM,SAAS,CAAA;AAE/C,IAAA,MAAM,OAAA,GAAU,sCAAsC,MAAM,CAAA,CAAA,EAAIA,SAAQ,CAAA,kBAAA,EAAqB,IAAI,WAAW,IAAI,CAAA,CAAA;AAEhH,IAAA,OAAO;AAAA,MACL,GAAA,EAAK,OAAA;AAAA,MACL,QAAA,EAAAA;AAAA,KACF;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,IAAI,CAAC,CAAA;AAEf,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,SAAA,GAAY,IAAA;AAEhB,IAAA,MAAM,WAAW,YAAY;AAE3B,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA;AAC/B,MAAA,IAAI,MAAA,EAAQ;AACV,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,aAAA,CAAc,MAAM,CAAA;AACpB,UAAA,YAAA,CAAa,KAAK,CAAA;AAAA,QACpB;AACA,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,IAAI,CAAA;AACjB,QAAA,QAAA,CAAS,IAAI,CAAA;AAEb,QAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAG,CAAA;AAChC,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,QAC5D;AAEA,QAAA,IAAI,GAAA,GAAM,MAAM,QAAA,CAAS,IAAA,EAAK;AAK9B,QAAA,GAAA,GAAM,0BAA0B,GAAG,CAAA;AAGnC,QAAA,QAAA,CAAS,GAAA,CAAI,KAAK,GAAG,CAAA;AAErB,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,aAAA,CAAc,GAAG,CAAA;AACjB,UAAA,YAAA,CAAa,KAAK,CAAA;AAAA,QACpB;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,SAAA,EAAW;AACb,UAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,qBAAqB,CAAA;AACnE,UAAA,YAAA,CAAa,KAAK,CAAA;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,QAAA,EAAS;AAET,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,KAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,GAAG,CAAC,CAAA;AAGR,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,uBACE,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA;AAAA,QACvC,KAAA,EAAO,EAAE,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,QACnC,aAAA,EAAY;AAAA;AAAA,KACd;AAAA,EAEJ;AAGA,EAAA,IAAI,KAAA,IAAS,CAAC,UAAA,EAAY;AACxB,IAAA,uBACE,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA;AAAA,QACvC,KAAA,EAAO,EAAE,KAAA,EAAO,IAAA,EAAM,QAAQ,IAAA,EAAK;AAAA,QACnC,IAAA,EAAK,KAAA;AAAA,QACL,cAAY,GAAA,IAAO;AAAA;AAAA,KACrB;AAAA,EAEJ;AAIA,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAW,EAAA,CAAG,yCAAA,EAA2C,SAAS,CAAA;AAAA,MAClE,KAAA,EAAO;AAAA,QACL,KAAA,EAAO,IAAA;AAAA,QACP,MAAA,EAAQ,IAAA;AAAA,QACR,OAAO,KAAA,IAAS;AAAA,OAClB;AAAA,MACA,IAAA,EAAK,KAAA;AAAA,MACL,cAAY,GAAA,IAAO,QAAA;AAAA,MACnB,uBAAA,EAAyB,EAAE,MAAA,EAAQ,UAAA;AAAW;AAAA,GAChD;AAEJ;AAMA,SAAS,0BAA0B,GAAA,EAAqB;AAStD,EAAA,IAAI,SAAA,GAAY,GAAA;AAGhB,EAAA,SAAA,GAAY,SAAA,CAAU,OAAA;AAAA,IACpB,uCAAA;AAAA,IACA;AAAA,GACF;AAIA,EAAA,SAAA,GAAY,SAAA,CAAU,OAAA;AAAA,IACpB,qCAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,OAAO,SAAA;AACT;ACnIA,IAAM,eAAA,GAA4C;AAAA,EAChD;AAAA,IACE,KAAA,EAAO,SAAA;AAAA,IACP,KAAA,EAAO;AAAA,MACL,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,GAAA,EAAI;AAAA,MAC9B,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,GAAA,EAAI;AAAA,MAC7B,EAAE,IAAA,EAAM,aAAA,EAAe,IAAA,EAAM,GAAA,EAAI;AAAA,MACjC,EAAE,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,GAAA;AAAI;AAChC,GACF;AAAA,EACA;AAAA,IACE,KAAA,EAAO,SAAA;AAAA,IACP,KAAA,EAAO;AAAA,MACL,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,GAAA,EAAI;AAAA,MAC3B,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,GAAA,EAAI;AAAA,MAC1B,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,GAAA,EAAI;AAAA,MAC1B,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM,GAAA;AAAI;AAC/B,GACF;AAAA,EACA;AAAA,IACE,KAAA,EAAO,WAAA;AAAA,IACP,KAAA,EAAO;AAAA,MACL,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,GAAA,EAAI;AAAA,MAC1B,EAAE,IAAA,EAAM,OAAA,EAAS,IAAA,EAAM,GAAA,EAAI;AAAA,MAC3B,EAAE,IAAA,EAAM,WAAA,EAAa,IAAA,EAAM,GAAA;AAAI;AACjC;AAEJ,CAAA;AAEA,IAAM,kBAAA,GAA4C;AAAA,EAChD,EAAE,IAAA,EAAM,wBAAA,EAA0B,IAAA,EAAM,GAAA,EAAK,OAAO,WAAA,EAAY;AAAA,EAChE,EAAE,IAAA,EAAM,uBAAA,EAAyB,IAAA,EAAM,GAAA,EAAK,OAAO,UAAA,EAAW;AAAA,EAC9D,EAAE,IAAA,EAAM,gBAAA,EAAkB,IAAA,EAAM,GAAA,EAAK,OAAO,aAAA,EAAc;AAAA,EAC1D,EAAE,IAAA,EAAM,uBAAA,EAAyB,IAAA,EAAM,GAAA,EAAK,OAAO,UAAA;AACrD,CAAA;AAEA,IAAM,iBAAA,GAAoB;AAAA,EACxB,EAAE,IAAA,EAAM,sBAAA,EAAwB,IAAA,EAAM,GAAA,EAAI;AAAA,EAC1C,EAAE,IAAA,EAAM,gBAAA,EAAkB,IAAA,EAAM,GAAA;AAClC,CAAA;AAUO,SAAS,eAAA,CAAgB;AAAA,EAC9B,IAAA,GAAO;AAAA,IACL,GAAA,EAAK,qBAAA;AAAA,IACL,GAAA,EAAK,2FAAA;AAAA,IACL,GAAA,EAAK,aAAA;AAAA,IACL,KAAA,EAAO;AAAA,GACT;AAAA,EACA,SAAA;AAAA,EACA,QAAA,GAAW,eAAA;AAAA,EACX,WAAA,GAAc,kBAAA;AAAA,EACd,iBAAA,GAAoB,cAAA;AAAA,EACpB,qBAAA,GAAwB,8DAAA;AAAA,EACxB,qBAAA,GAAwB,kBAAA;AAAA,EACxB,oBAAA,GAAuB,WAAA;AAAA,EACvB,YAAY,CAAA,KAAA,EAAA,iBAAK,IAAI,IAAA,EAAK,EAAE,aAAa,CAAA,kCAAA,CAAA;AAAA,EACzC,UAAA,GAAa,iBAAA;AAAA,EACb;AACF,CAAA,EAA4C;AAC1C,EAAA,uBACEC,GAAAA,CAAC,SAAA,EAAA,EAAQ,SAAA,EAAW,GAAG,OAAA,EAAS,SAAS,CAAA,EACvC,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,+BAAC,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,4BAAA,EAEb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAM,IAAA,CAAK,GAAA,EAAK,WAAU,8BAAA,EAC3B,QAAA,EAAA;AAAA,0BAAAA,GAAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,KAAK,IAAA,CAAK,GAAA;AAAA,cACV,KAAK,IAAA,CAAK,GAAA;AAAA,cACV,SAAA,EAAU,MAAA;AAAA,cACV;AAAA;AAAA,WACF;AAAA,0BACAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uBAAA,EAAyB,eAAK,KAAA,EAAM;AAAA,SAAA,EACtD,CAAA;AAAA,wBACAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,EAAS,UAAA,qBACtB,IAAA,CAAC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,oBAAA,EAAsB,kBAAQ,KAAA,EAAM,CAAA;AAAA,0BAClDA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,yCAAA,EACX,QAAA,EAAA,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,OAAA,qBACxBA,GAAAA,CAAC,IAAA,EAAA,EACC,QAAA,kBAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,SAAA,EAAU,oBAAA,EAC3B,QAAA,EAAA,IAAA,CAAK,IAAA,EACR,CAAA,EAAA,EAHO,OAIT,CACD,CAAA,EACH;AAAA,SAAA,EAAA,EAVQ,UAWV,CACD,CAAA,EACH;AAAA,OAAA,EACF,CAAA;AAAA,sBAGA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,+BAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,MAAA,EACb,QAAA,EAAA;AAAA,0BAAAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,4BAAA,EAA8B,QAAA,EAAA,iBAAA,EAAkB,CAAA;AAAA,0BAC9DA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,sCACV,QAAA,EAAA,qBAAA,EACH,CAAA;AAAA,0BACA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACb,QAAA,EAAA;AAAA,4BAAAA,GAAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,OAAA;AAAA,gBACL,WAAA,EAAa,qBAAA;AAAA,gBACb,SAAA,EAAU;AAAA;AAAA,aACZ;AAAA,4BACAA,GAAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,SAAA,EAAU,8VAAA;AAAA,gBAET,QAAA,EAAA;AAAA;AAAA;AACH,WAAA,EACF;AAAA,SAAA,EACF,CAAA;AAAA,6BACC,KAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,kBAAA,EAAmB,QAAA,EAAA,WAAA,EAAS,CAAA;AAAA,0BACzCA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,yBAAA,EACX,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,MAAA,EAAQ,GAAA,qBACxBA,GAAAA,CAAC,QACC,QAAA,kBAAAA,GAAAA;AAAA,YAAC,GAAA;AAAA,YAAA;AAAA,cACC,MAAM,MAAA,CAAO,IAAA;AAAA,cACb,cAAY,MAAA,CAAO,KAAA;AAAA,cACnB,SAAA,EAAU,4DAAA;AAAA,cAEV,0BAAAA,GAAAA,CAAC,WAAA,EAAA,EAAY,MAAM,MAAA,CAAO,IAAA,EAAM,MAAM,EAAA,EAAI;AAAA;AAAA,WAC5C,EAAA,EAPO,GAQT,CACD,CAAA,EACH;AAAA,SAAA,EACF;AAAA,OAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,oBAGA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,mHAAA,EACb,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,0DAAA,EACb,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,OAAG,QAAA,EAAA,SAAA,EAAU,CAAA;AAAA,wBACdA,GAAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,qBAAA;AAAA,YACL,SAAA,EAAU,oBAAA;AAAA,YACV,MAAA,EAAO,QAAA;AAAA,YACP,GAAA,EAAI,qBAAA;AAAA,YACL,QAAA,EAAA;AAAA;AAAA;AAED,OAAA,EACF,CAAA;AAAA,sBACAA,GAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,YAAA,EACX,QAAA,EAAA,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,EAAM,GAAA,qBACrBA,GAAAA,CAAC,IAAA,EAAA,EACC,0BAAAA,GAAAA,CAAC,GAAA,EAAA,EAAE,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,SAAA,EAAU,oBAAA,EAC3B,QAAA,EAAA,IAAA,CAAK,IAAA,EACR,CAAA,EAAA,EAHO,GAIT,CACD,CAAA,EACH;AAAA,KAAA,EACF;AAAA,GAAA,EACF,GACF,CAAA,EACF,CAAA;AAEJ","file":"footer-nav-social.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"../../lib/utils\";\n\ninterface DynamicIconProps {\n /**\n * Icon name in format: prefix/name or prefix:name\n * Examples: \"lucide/home\", \"mdi:account\", \"heroicons/check\"\n */\n name: string;\n /**\n * Icon size in pixels\n * @default 28\n */\n size?: number;\n /**\n * Icon color - accepts any valid CSS color\n * Note: When not specified, the icon inherits color from parent via CSS currentColor\n */\n color?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * Alt text for accessibility\n */\n alt?: string;\n}\n\n// Simple in-memory cache for fetched SVGs\nconst svgCache = new Map<string, string>();\n\n/**\n * Lightweight icon component that dynamically loads SVG icons from icons.opensite.ai API.\n *\n * Features:\n * - Pulls SVGs from https://icons.opensite.ai API and inlines them for CSS color inheritance\n * - Supports currentColor - icons inherit color from parent element\n * - Accepts prefix/name or prefix:name format\n * - Customizable size and explicit color via props\n * - In-memory caching to prevent duplicate fetches\n *\n * @example\n * ```tsx\n * // Icon inherits color from parent (recommended for hover states, etc.)\n * <span className=\"text-white hover:text-red-500\">\n * <DynamicIcon name=\"lucide/home\" size={24} />\n * </span>\n *\n * // Icon with explicit color\n * <DynamicIcon name=\"mdi:account\" size={32} color=\"#ff0000\" />\n * ```\n */\nexport function DynamicIcon({\n name,\n size = 28,\n color,\n className,\n alt,\n}: DynamicIconProps) {\n const [svgContent, setSvgContent] = React.useState<string | null>(null);\n const [isLoading, setIsLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n const { url, iconName } = React.useMemo(() => {\n const separator = name.includes(\"/\") ? \"/\" : \":\";\n const [prefix, iconName] = name.split(separator);\n // Don't pass color to API - we'll handle it via CSS\n const baseUrl = `https://icons.opensite.ai/api/icon/${prefix}/${iconName}?format=svg&width=${size}&height=${size}`;\n\n return {\n url: baseUrl,\n iconName,\n };\n }, [name, size]);\n\n React.useEffect(() => {\n let isMounted = true;\n\n const fetchSvg = async () => {\n // Check cache first\n const cached = svgCache.get(url);\n if (cached) {\n if (isMounted) {\n setSvgContent(cached);\n setIsLoading(false);\n }\n return;\n }\n\n try {\n setIsLoading(true);\n setError(null);\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch icon: ${response.status}`);\n }\n\n let svg = await response.text();\n\n // Process SVG to ensure currentColor works:\n // 1. Replace any hardcoded colors with currentColor\n // 2. Ensure stroke/fill use currentColor where appropriate\n svg = processSvgForCurrentColor(svg);\n\n // Cache the processed SVG\n svgCache.set(url, svg);\n\n if (isMounted) {\n setSvgContent(svg);\n setIsLoading(false);\n }\n } catch (err) {\n if (isMounted) {\n setError(err instanceof Error ? err.message : \"Failed to load icon\");\n setIsLoading(false);\n }\n }\n };\n\n fetchSvg();\n\n return () => {\n isMounted = false;\n };\n }, [url]);\n\n // Loading state - show placeholder with same dimensions\n if (isLoading) {\n return (\n <span\n className={cn(\"inline-block\", className)}\n style={{ width: size, height: size }}\n aria-hidden=\"true\"\n />\n );\n }\n\n // Error state - show nothing or fallback\n if (error || !svgContent) {\n return (\n <span\n className={cn(\"inline-block\", className)}\n style={{ width: size, height: size }}\n role=\"img\"\n aria-label={alt || iconName}\n />\n );\n }\n\n // Render inline SVG\n // The color prop applies an explicit color, otherwise inherits from parent via currentColor\n return (\n <span\n className={cn(\"inline-flex items-center justify-center\", className)}\n style={{\n width: size,\n height: size,\n color: color || \"inherit\",\n }}\n role=\"img\"\n aria-label={alt || iconName}\n dangerouslySetInnerHTML={{ __html: svgContent }}\n />\n );\n}\n\n/**\n * Process SVG to ensure it uses currentColor for proper CSS inheritance.\n * This handles various icon libraries that may use different color approaches.\n */\nfunction processSvgForCurrentColor(svg: string): string {\n // Replace stroke=\"currentColor\" is already correct, but ensure fill also works\n // Some icons use fill=\"none\" with stroke, others use fill with no stroke\n\n // Ensure the SVG doesn't have hardcoded colors that should be currentColor\n // Common patterns to replace:\n // - stroke=\"#000\" or stroke=\"#000000\" or stroke=\"black\" -> stroke=\"currentColor\"\n // - fill=\"#000\" or fill=\"#000000\" or fill=\"black\" -> fill=\"currentColor\"\n\n let processed = svg;\n\n // Replace common black color values with currentColor for stroke\n processed = processed.replace(\n /stroke=[\"'](#000000|#000|black)[\"']/gi,\n 'stroke=\"currentColor\"'\n );\n\n // Replace common black color values with currentColor for fill\n // But be careful not to replace fill=\"none\"\n processed = processed.replace(\n /fill=[\"'](#000000|#000|black)[\"']/gi,\n 'fill=\"currentColor\"'\n );\n\n return processed;\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../../../lib/utils\";\nimport { Img } from \"@page-speed/img\";\nimport { DynamicIcon } from \"../../ui/dynamic-icon\";\n\n/**\n * Social link configuration\n */\nexport interface FooterNavSocialLink {\n /** Icon name in format: prefix/name (e.g., \"simple-icons/instagram\") */\n icon: string;\n /** Link URL */\n href: string;\n /** Accessible label */\n label: string;\n}\n\n/**\n * Navigation section configuration\n */\nexport interface FooterNavSocialSection {\n title: string;\n links: {\n name: string;\n href: string;\n }[];\n}\n\n/**\n * Props for the FooterNavSocial component\n */\nexport interface FooterNavSocialProps {\n /** Logo configuration */\n logo?: {\n url: string;\n src: string;\n alt: string;\n title: string;\n };\n /** Additional CSS classes */\n className?: string;\n /** Navigation sections */\n sections?: FooterNavSocialSection[];\n /** Social media links */\n socialLinks?: FooterNavSocialLink[];\n /** Newsletter heading */\n newsletterHeading?: string;\n /** Newsletter description */\n newsletterDescription?: string;\n /** Newsletter placeholder */\n newsletterPlaceholder?: string;\n /** Newsletter button text */\n newsletterButtonText?: string;\n /** Copyright text */\n copyright?: string;\n /** Legal links */\n legalLinks?: {\n name: string;\n href: string;\n }[];\n /** Optional Optix Flow configuration for @page-speed/img */\n optixFlowConfig?: {\n apiKey: string;\n compression?: number;\n };\n}\n\nconst defaultSections: FooterNavSocialSection[] = [\n {\n title: \"Product\",\n links: [\n { name: \"Overview\", href: \"#\" },\n { name: \"Pricing\", href: \"#\" },\n { name: \"Marketplace\", href: \"#\" },\n { name: \"Features\", href: \"#\" },\n ],\n },\n {\n title: \"Company\",\n links: [\n { name: \"About\", href: \"#\" },\n { name: \"Team\", href: \"#\" },\n { name: \"Blog\", href: \"#\" },\n { name: \"Careers\", href: \"#\" },\n ],\n },\n {\n title: \"Resources\",\n links: [\n { name: \"Help\", href: \"#\" },\n { name: \"Sales\", href: \"#\" },\n { name: \"Advertise\", href: \"#\" },\n ],\n },\n];\n\nconst defaultSocialLinks: FooterNavSocialLink[] = [\n { icon: \"simple-icons/instagram\", href: \"#\", label: \"Instagram\" },\n { icon: \"simple-icons/facebook\", href: \"#\", label: \"Facebook\" },\n { icon: \"simple-icons/x\", href: \"#\", label: \"X (Twitter)\" },\n { icon: \"simple-icons/linkedin\", href: \"#\", label: \"LinkedIn\" },\n];\n\nconst defaultLegalLinks = [\n { name: \"Terms and Conditions\", href: \"#\" },\n { name: \"Privacy Policy\", href: \"#\" },\n];\n\n/**\n * FooterNavSocial - A comprehensive footer with logo, navigation, newsletter, and social links.\n *\n * Features a logo with navigation sections, a newsletter signup form with heading and\n * description, social media icons, and legal links. Ideal for SaaS products, corporate\n * websites, and businesses that want a complete footer with all essential elements\n * organized in a clean, professional layout.\n */\nexport function FooterNavSocial({\n logo = {\n url: \"https://opensite.ai\",\n src: \"https://cdn.ing/assets/i/r/285975/eud79qeya11q5w6ueyhklueardyx/os-suircle-black-white.png\",\n alt: \"Opensite AI\",\n title: \"Opensite AI\",\n },\n className,\n sections = defaultSections,\n socialLinks = defaultSocialLinks,\n newsletterHeading = \"Stay Updated\",\n newsletterDescription = \"Subscribe to our newsletter for the latest updates and news.\",\n newsletterPlaceholder = \"Enter your email\",\n newsletterButtonText = \"Subscribe\",\n copyright = `© ${new Date().getFullYear()} Opensite AI. All rights reserved.`,\n legalLinks = defaultLegalLinks,\n optixFlowConfig,\n}: FooterNavSocialProps): React.JSX.Element {\n return (\n <section className={cn(\"py-32\", className)}>\n <div className=\"container\">\n <footer>\n <div className=\"grid gap-10 lg:grid-cols-2\">\n {/* Left Column - Logo and Navigation */}\n <div>\n <a href={logo.url} className=\"mb-8 flex items-center gap-2\">\n <Img\n src={logo.src}\n alt={logo.alt}\n className=\"h-10\"\n optixFlowConfig={optixFlowConfig}\n />\n <span className=\"text-xl font-semibold\">{logo.title}</span>\n </a>\n <div className=\"grid gap-8 sm:grid-cols-3\">\n {sections.map((section, sectionIdx) => (\n <div key={sectionIdx}>\n <h3 className=\"mb-4 font-semibold\">{section.title}</h3>\n <ul className=\"space-y-3 text-sm text-muted-foreground\">\n {section.links.map((link, linkIdx) => (\n <li key={linkIdx}>\n <a href={link.href} className=\"hover:text-primary\">\n {link.name}\n </a>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n </div>\n\n {/* Right Column - Newsletter and Social */}\n <div className=\"flex flex-col justify-between\">\n <div className=\"mb-8\">\n <h3 className=\"mb-2 text-lg font-semibold\">{newsletterHeading}</h3>\n <p className=\"mb-4 text-sm text-muted-foreground\">\n {newsletterDescription}\n </p>\n <div className=\"flex max-w-md gap-2\">\n <input\n type=\"email\"\n placeholder={newsletterPlaceholder}\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\"\n />\n <button\n type=\"submit\"\n className=\"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-primary text-primary-foreground hover:bg-primary/90 h-10 px-4 py-2\"\n >\n {newsletterButtonText}\n </button>\n </div>\n </div>\n <div>\n <p className=\"mb-4 font-medium\">Follow Us</p>\n <ul className=\"flex items-center gap-4\">\n {socialLinks.map((social, idx) => (\n <li key={idx}>\n <a\n href={social.href}\n aria-label={social.label}\n className=\"text-muted-foreground transition-colors hover:text-primary\"\n >\n <DynamicIcon name={social.icon} size={20} />\n </a>\n </li>\n ))}\n </ul>\n </div>\n </div>\n </div>\n\n {/* Bottom Section */}\n <div className=\"mt-16 flex flex-col justify-between gap-4 border-t pt-8 text-sm text-muted-foreground md:flex-row md:items-center\">\n <div className=\"flex flex-col gap-2 md:flex-row md:items-center md:gap-4\">\n <p>{copyright}</p>\n <a\n href=\"https://opensite.ai\"\n className=\"hover:text-primary\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n AI Website and Automation Platform by Opensite\n </a>\n </div>\n <ul className=\"flex gap-4\">\n {legalLinks.map((link, idx) => (\n <li key={idx}>\n <a href={link.href} className=\"hover:text-primary\">\n {link.name}\n </a>\n </li>\n ))}\n </ul>\n </div>\n </footer>\n </div>\n </section>\n );\n}\n"]}
|