diff --git a/docs/CARDSTACK_SECTIONS.md b/docs/CARDSTACK_SECTIONS.md index 8538146..5902e40 100644 --- a/docs/CARDSTACK_SECTIONS.md +++ b/docs/CARDSTACK_SECTIONS.md @@ -269,7 +269,7 @@ Buttons are rendered with automatic primary/secondary styling: ```tsx const buttons: ButtonConfig[] = [ - { text: "Get Started", href: "/signup" }, // Primary + { text: "Download Now", href: "/signup" }, // Primary { text: "Learn More", onClick: () => {} } // Secondary ]; ``` diff --git a/docs/COMPONENT_IMPLEMENTATION.md b/docs/COMPONENT_IMPLEMENTATION.md index f0461a5..0339728 100644 --- a/docs/COMPONENT_IMPLEMENTATION.md +++ b/docs/COMPONENT_IMPLEMENTATION.md @@ -351,7 +351,7 @@ For button text and short labels: { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 15 } diff --git a/docs/PREVIEW_PAGE_STANDARDS.md b/docs/PREVIEW_PAGE_STANDARDS.md index 7ed66ef..a9b9336 100644 --- a/docs/PREVIEW_PAGE_STANDARDS.md +++ b/docs/PREVIEW_PAGE_STANDARDS.md @@ -107,7 +107,7 @@ export default function SectionPreviewPage() { title="Preview Section Title" description="This is a preview of the section component with example content." buttons={[ - { text: "Get Started", href: "#" }, + { text: "Download Now", href: "#" }, { text: "Learn More", onClick: () => console.log("Learn more") } ]} // Add section-specific props @@ -308,7 +308,7 @@ Customize theme settings when: title="Build Amazing Websites Faster" description="Create stunning, responsive websites with our modern component library. Ship faster, iterate quicker." buttons={[ - { text: "Get Started", href: "/signup" }, + { text: "Download Now", href: "/signup" }, { text: "View Demo", onClick: () => window.open("/demo") } ]} /> diff --git a/docs/REGISTRY_STANDARDS.md b/docs/REGISTRY_STANDARDS.md index 865d7a7..77cd185 100644 --- a/docs/REGISTRY_STANDARDS.md +++ b/docs/REGISTRY_STANDARDS.md @@ -163,7 +163,7 @@ Defines text length constraints for string props. "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 15 } @@ -267,12 +267,12 @@ Single-line example showing typical implementation. **Button:** ```json -"usage": " console.log('clicked')} />" +"usage": " console.log('clicked')} />" ``` **Section with minimal props:** ```json -"usage": "" +"usage": "" ``` **CardStack section:** @@ -308,7 +308,7 @@ Single-line example showing typical implementation. "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 15 } @@ -380,7 +380,7 @@ Single-line example showing typical implementation. "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 15 } @@ -396,7 +396,7 @@ Single-line example showing typical implementation. "ariaLabel?": "string", "type?": "'button' | 'submit' | 'reset' (default: 'button')" }, - "usage": " console.log('clicked')} />" + "usage": " console.log('clicked')} />" } ``` diff --git a/registry/components/ButtonBounceEffect.json b/registry/components/ButtonBounceEffect.json index 48ffbfa..c541b02 100644 --- a/registry/components/ButtonBounceEffect.json +++ b/registry/components/ButtonBounceEffect.json @@ -5,7 +5,7 @@ "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 25 } @@ -21,7 +21,7 @@ "ariaLabel?": "string", "type?": "'button' | 'submit' | 'reset' (default: 'button')" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for general use" ], diff --git a/registry/components/ButtonDirectionalHover.json b/registry/components/ButtonDirectionalHover.json index 44830e1..1c565d2 100644 --- a/registry/components/ButtonDirectionalHover.json +++ b/registry/components/ButtonDirectionalHover.json @@ -5,7 +5,7 @@ "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 25 } @@ -21,7 +21,7 @@ "ariaLabel?": "string", "type?": "'button' | 'submit' | 'reset' (default: 'button')" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for general use" ], diff --git a/registry/components/ButtonElasticEffect.json b/registry/components/ButtonElasticEffect.json index 13ad861..08989fe 100644 --- a/registry/components/ButtonElasticEffect.json +++ b/registry/components/ButtonElasticEffect.json @@ -5,7 +5,7 @@ "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 25 } @@ -21,7 +21,7 @@ "ariaLabel?": "string", "type?": "'button' | 'submit' | 'reset' (default: 'button')" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for general use" ], diff --git a/registry/components/ButtonExpandHover.json b/registry/components/ButtonExpandHover.json index c0d0be4..df48cd0 100644 --- a/registry/components/ButtonExpandHover.json +++ b/registry/components/ButtonExpandHover.json @@ -5,7 +5,7 @@ "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 25 } @@ -21,7 +21,7 @@ "ariaLabel?": "string", "type?": "'button' | 'submit' | 'reset' (default: 'button')" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for general use" ], diff --git a/registry/components/ButtonShiftHover.json b/registry/components/ButtonShiftHover.json index fb50a44..3933b20 100644 --- a/registry/components/ButtonShiftHover.json +++ b/registry/components/ButtonShiftHover.json @@ -5,7 +5,7 @@ "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 25 } @@ -21,7 +21,7 @@ "ariaLabel?": "string", "type?": "'button' | 'submit' | 'reset' (default: 'button')" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for general use" ], diff --git a/registry/components/ButtonTextShift.json b/registry/components/ButtonTextShift.json index 9b9e2e0..b47269a 100644 --- a/registry/components/ButtonTextShift.json +++ b/registry/components/ButtonTextShift.json @@ -5,7 +5,7 @@ "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 25 } @@ -21,7 +21,7 @@ "ariaLabel?": "string", "type?": "'button' | 'submit' | 'reset' (default: 'button')" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for general use" ], diff --git a/registry/components/ButtonTextStagger.json b/registry/components/ButtonTextStagger.json index e7eb24c..ec244f0 100644 --- a/registry/components/ButtonTextStagger.json +++ b/registry/components/ButtonTextStagger.json @@ -5,7 +5,7 @@ "textRules": { "text": { "required": true, - "example": "Get Started", + "example": "Download Now", "minChars": 2, "maxChars": 25 } @@ -21,7 +21,7 @@ "ariaLabel?": "string", "type?": "'button' | 'submit' | 'reset' (default: 'button')" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for general use" ], diff --git a/registry/components/HeroBillboardDashboard.json b/registry/components/HeroBillboardDashboard.json index 3756727..c8ad28c 100644 --- a/registry/components/HeroBillboardDashboard.json +++ b/registry/components/HeroBillboardDashboard.json @@ -31,7 +31,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Download Now', href: 'https://example.com' }", "{ text: 'Learn More', href: 'about' }" ], "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." diff --git a/registry/components/HeroBillboardRotatedCarousel.json b/registry/components/HeroBillboardRotatedCarousel.json index 30ec21f..60816a1 100644 --- a/registry/components/HeroBillboardRotatedCarousel.json +++ b/registry/components/HeroBillboardRotatedCarousel.json @@ -60,7 +60,7 @@ "ariaLabel?": "string (default: 'Hero section')", "className?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for landing pages", "Use for feature showcases", diff --git a/registry/components/HeroBillboardScroll.json b/registry/components/HeroBillboardScroll.json index 49f4d47..841bdcb 100644 --- a/registry/components/HeroBillboardScroll.json +++ b/registry/components/HeroBillboardScroll.json @@ -63,7 +63,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', onClick: () => console.log('Get Started clicked') }", + "{ text: 'Download Now', onClick: () => console.log('Download Now clicked') }", "{ text: 'Learn More', href: 'about' }" ], "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." @@ -85,7 +85,7 @@ "ariaLabel?": "string (default: 'Hero section')", "className?": "string" }, - "usageExample": "\n console.log('Get Started clicked') }, { text: 'Learn More', href: 'about' }]} \n />\n", + "usageExample": "\n console.log('Download Now clicked') }, { text: 'Learn More', href: 'about' }]} \n />\n", "do": [ "Use for landing pages", "Use for feature showcases", diff --git a/registry/components/HeroBillboardTestimonial.json b/registry/components/HeroBillboardTestimonial.json index da62065..0ccf8d5 100644 --- a/registry/components/HeroBillboardTestimonial.json +++ b/registry/components/HeroBillboardTestimonial.json @@ -68,7 +68,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Download Now', href: 'https://example.com' }", "{ text: 'Learn More', href: 'about' }" ], "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." @@ -124,7 +124,7 @@ "marqueeTextClassName?": "string", "marqueeIconClassName?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for landing pages with social proof", "Use for product showcases with testimonials", diff --git a/registry/components/HeroCarouselLogo.json b/registry/components/HeroCarouselLogo.json index d9b8915..0004800 100644 --- a/registry/components/HeroCarouselLogo.json +++ b/registry/components/HeroCarouselLogo.json @@ -42,7 +42,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', href: 'https://github.com' }", + "{ text: 'Download Now', href: 'https://github.com' }", "{ text: 'Learn More', href: 'about' }" ], "note": "Buttons are required (cannot be empty array). Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." @@ -59,7 +59,7 @@ "ariaLabel?": "string (default: 'Hero section')", "className?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for landing pages", "Use for feature showcases", diff --git a/registry/components/HeroCentered.json b/registry/components/HeroCentered.json index e43ea33..365722c 100644 --- a/registry/components/HeroCentered.json +++ b/registry/components/HeroCentered.json @@ -82,7 +82,7 @@ "marqueeTextClassName?": "string", "marqueeIconClassName?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for impactful landing pages with social proof emphasis", "Include avatars for social proof", diff --git a/registry/components/HeroLogo.json b/registry/components/HeroLogo.json index 8bb2601..1727c96 100644 --- a/registry/components/HeroLogo.json +++ b/registry/components/HeroLogo.json @@ -47,7 +47,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', href: 'https://github.com' }", + "{ text: 'Download Now', href: 'https://github.com' }", "{ text: 'Learn More', href: 'about' }" ], "note": "Buttons are required (cannot be empty array). Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." @@ -67,7 +67,7 @@ "ariaLabel?": "string (default: 'Hero section')", "className?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for landing pages", "Use for feature showcases", diff --git a/registry/components/HeroLogoBillboardSplit.json b/registry/components/HeroLogoBillboardSplit.json index d9f24b3..2452f82 100644 --- a/registry/components/HeroLogoBillboardSplit.json +++ b/registry/components/HeroLogoBillboardSplit.json @@ -78,7 +78,7 @@ "ariaLabel?": "string (default: 'Hero section')", "className?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for landing pages", "Use for feature showcases", diff --git a/registry/components/HeroOverlay.json b/registry/components/HeroOverlay.json index d82dd65..b04547d 100644 --- a/registry/components/HeroOverlay.json +++ b/registry/components/HeroOverlay.json @@ -67,7 +67,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Download Now', href: 'https://example.com' }", "{ text: 'Learn More', href: 'about' }" ], "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." @@ -91,7 +91,7 @@ "ariaLabel?": "string (default: 'Hero section')", "className?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for landing pages", "Use for feature showcases", diff --git a/registry/components/HeroSignup.json b/registry/components/HeroSignup.json index 6e8713f..e2c3060 100644 --- a/registry/components/HeroSignup.json +++ b/registry/components/HeroSignup.json @@ -43,7 +43,7 @@ "tagIcon?": "LucideIcon", "tagAnimation?": "'none' | 'opacity' | 'slide-up' | 'blur-reveal'", "inputPlaceholder?": "string (default: 'Enter your email')", - "buttonText?": "string (default: 'Get Started')", + "buttonText?": "string (default: 'Download Now')", "onSubmit?": "(email: string) => void", "ariaLabel?": "string (default: 'Hero section')", "className?": "string", diff --git a/registry/components/HeroSplit.json b/registry/components/HeroSplit.json index 0b6adf2..952d9eb 100644 --- a/registry/components/HeroSplit.json +++ b/registry/components/HeroSplit.json @@ -56,7 +56,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Download Now', href: 'https://example.com' }", "{ text: 'Learn More', href: 'about' }" ], "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." diff --git a/registry/components/HeroSplitDoubleCarousel.json b/registry/components/HeroSplitDoubleCarousel.json index 9f056f7..5bf5b10 100644 --- a/registry/components/HeroSplitDoubleCarousel.json +++ b/registry/components/HeroSplitDoubleCarousel.json @@ -60,7 +60,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Download Now', href: 'https://example.com' }", "{ text: 'Learn More', href: 'about' }" ], "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." @@ -86,7 +86,7 @@ "showMarqueeCard?": "boolean (default: true)", "className?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for landing pages with visual portfolios", "Use for image galleries and creative showcases", diff --git a/registry/components/HeroSplitKpi.json b/registry/components/HeroSplitKpi.json index 2e0daf6..d1503aa 100644 --- a/registry/components/HeroSplitKpi.json +++ b/registry/components/HeroSplitKpi.json @@ -89,7 +89,7 @@ "imagePosition?": "'left' | 'right' (default: 'right')", "className?": "string" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for landing pages", "Use for feature showcases", diff --git a/registry/components/HeroSplitTestimonial.json b/registry/components/HeroSplitTestimonial.json index 8309508..97a6117 100644 --- a/registry/components/HeroSplitTestimonial.json +++ b/registry/components/HeroSplitTestimonial.json @@ -76,7 +76,7 @@ "props": "Partial - Additional button props like className, textClassName (optional)" }, "examples": [ - "{ text: 'Get Started', href: 'https://example.com' }", + "{ text: 'Download Now', href: 'https://example.com' }", "{ text: 'Learn More', href: 'about' }" ], "note": "Button variant is controlled by ThemeProvider's defaultButtonVariant. Border radius is controlled by ThemeProvider's borderRadius (options: 'sharp', 'rounded', 'soft', 'pill'). All sections should be wrapped in a single ThemeProvider at the app/page level to maintain consistent styling across the entire site." @@ -134,7 +134,7 @@ "marqueeTextClassName?": "string", "marqueeIconClassName?": "string" }, - "usageExample": "\n \n", + "usageExample": "\n \n", "do": [ "Use for landing pages with social proof", "Use for product showcases with testimonials", diff --git a/registry/components/InlineImageSplitTextAbout.json b/registry/components/InlineImageSplitTextAbout.json index daf1bcc..7e1d144 100644 --- a/registry/components/InlineImageSplitTextAbout.json +++ b/registry/components/InlineImageSplitTextAbout.json @@ -46,7 +46,7 @@ "ariaLabel?": "string (default: 'About section')", "className?": "string" }, - "usageExample": "// Wrap in ThemeProvider\n\n \n", + "usageExample": "// Wrap in ThemeProvider\n\n \n", "do": [ "Use for about pages", "Use for company information", diff --git a/registry/components/NavbarLayoutFloatingInline.json b/registry/components/NavbarLayoutFloatingInline.json index 88ac55d..87ea079 100644 --- a/registry/components/NavbarLayoutFloatingInline.json +++ b/registry/components/NavbarLayoutFloatingInline.json @@ -17,7 +17,7 @@ "required": true, "minChars": 2, "maxChars": 24, - "example": "Get Started" + "example": "Download Now" }, "href": { "required": false, diff --git a/registry/components/NavbarLayoutFloatingOverlay.json b/registry/components/NavbarLayoutFloatingOverlay.json index 16b67d5..33aeed7 100644 --- a/registry/components/NavbarLayoutFloatingOverlay.json +++ b/registry/components/NavbarLayoutFloatingOverlay.json @@ -17,7 +17,7 @@ "required": true, "minChars": 2, "maxChars": 24, - "example": "Get Started" + "example": "Download Now" }, "href": { "required": false, diff --git a/registry/components/NavbarStyleCentered.json b/registry/components/NavbarStyleCentered.json index 9785b4b..1c06f33 100644 --- a/registry/components/NavbarStyleCentered.json +++ b/registry/components/NavbarStyleCentered.json @@ -17,7 +17,7 @@ "required": true, "minChars": 2, "maxChars": 15, - "example": "Get Started" + "example": "Download Now" }, "href": { "required": false, @@ -55,7 +55,7 @@ "brandName?": "string (default: 'Webild')", "className?": "string (default: '')" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for feature showcases", "Use for capability displays", diff --git a/registry/components/PricingCardEight.json b/registry/components/PricingCardEight.json index bab897b..3b50bba 100644 --- a/registry/components/PricingCardEight.json +++ b/registry/components/PricingCardEight.json @@ -65,7 +65,7 @@ "ariaLabel?": "string (default: 'Pricing section')", "className?": "string" }, - "usageExample": "", + "usageExample": "", "do": [ "Use for feature showcases", "Use for capability displays", diff --git a/registry/components/PricingCardTwo.json b/registry/components/PricingCardTwo.json index bd62bfb..ad2300c 100644 --- a/registry/components/PricingCardTwo.json +++ b/registry/components/PricingCardTwo.json @@ -94,7 +94,7 @@ "ariaLabel?": "string (default: 'Pricing section')", "className?": "string" }, - "usageExample": " console.log('clicked') }, { text: 'Chat to Sales', onClick: () => console.log('chat') }], features: ['Up to 10 team members', '100GB storage', 'Priority support'] }]} title=\"Choose Your Plan\" description=\"Find the perfect plan for your needs\" textboxLayout=\"default\" animationType=\"slide-up\" useInvertedBackground={false} />", + "usageExample": " console.log('clicked') }, { text: 'Chat to Sales', onClick: () => console.log('chat') }], features: ['Up to 10 team members', '100GB storage', 'Priority support'] }]} title=\"Choose Your Plan\" description=\"Find the perfect plan for your needs\" textboxLayout=\"default\" animationType=\"slide-up\" useInvertedBackground={false} />", "do": [ "Use for feature showcases", "Use for capability displays", diff --git a/registry/components/TextAbout.json b/registry/components/TextAbout.json index 0fcdbaa..73f1b5c 100644 --- a/registry/components/TextAbout.json +++ b/registry/components/TextAbout.json @@ -32,7 +32,7 @@ "ariaLabel?": "string (default: 'About section')", "className?": "string" }, - "usageExample": "// Wrap in ThemeProvider\n\n \n", + "usageExample": "// Wrap in ThemeProvider\n\n \n", "do": [ "Use for feature showcases", "Use for capability displays", diff --git a/registry/schemas/HeroSignup.schema.json b/registry/schemas/HeroSignup.schema.json index 385d339..d60b8f7 100644 --- a/registry/schemas/HeroSignup.schema.json +++ b/registry/schemas/HeroSignup.schema.json @@ -8,7 +8,7 @@ "tagIcon?": "LucideIcon", "tagAnimation?": "'none' | 'opacity' | 'slide-up' | 'blur-reveal'", "inputPlaceholder?": "string (default: 'Enter your email')", - "buttonText?": "string (default: 'Get Started')", + "buttonText?": "string (default: 'Download Now')", "onSubmit?": "(email: string) => void", "ariaLabel?": "string (default: 'Hero section')", "className?": "string", diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 4883afe..cf46598 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -6,18 +6,8 @@ import "./globals.css"; import { ServiceWrapper } from "@/components/ServiceWrapper"; import Tag from "@/tag/Tag"; -const halant = Halant({ - variable: "--font-halant", subsets: ["latin"], - weight: ["300", "400", "500", "600", "700"], -}); -const inter = Inter({ - variable: "--font-inter", subsets: ["latin"], -}); -const openSans = Open_Sans({ - variable: "--font-open-sans", subsets: ["latin"], -}); export const metadata: Metadata = { title: "Torah Lock - iOS Torah Lock for Jewish Morning Prayers", description: "Start your day with Hashem. Torah Lock is a beautiful iOS app designed to help Jewish users pray every morning with guided prayers, reminders, and community connection.", keywords: "prayer app, iOS, Jewish, morning prayers, spiritual growth, Torah Lock", metadataBase: new URL("https://shachar-prayer.com"), @@ -33,6 +23,15 @@ export const metadata: Metadata = { }, }; +const inter = Inter({ + variable: "--font-inter", + subsets: ["latin"], +}); +const openSans = Open_Sans({ + variable: "--font-open-sans", + subsets: ["latin"], +}); + export default function RootLayout({ children, }: Readonly<{ @@ -41,9 +40,7 @@ export default function RootLayout({ return ( - + {children} @@ -288,9 +285,7 @@ export default function RootLayout({ const getElementInfo = (element, assignId = false) => { const rect = element.getBoundingClientRect(); const tagName = element.tagName.toLowerCase(); - const selector = getUniqueSelector(element, assignId); - const sectionId = getSectionId(element); - + let className = undefined; try { if (element.className) { @@ -318,8 +313,7 @@ export default function RootLayout({ }; if (tagName === 'img') { - const originalSrc = extractOriginalUrl(element.src); - info.imageData = { + info.imageData = { src: originalSrc, alt: element.alt || undefined, naturalWidth: element.naturalWidth, @@ -330,8 +324,7 @@ export default function RootLayout({ if (tagName === 'video') { const rawSrc = element.src || element.currentSrc || (element.querySelector('source') && element.querySelector('source').src) || ''; - const resolvedSrc = extractOriginalUrl(rawSrc); - info.imageData = { + info.imageData = { src: resolvedSrc, alt: element.getAttribute('aria-label') || undefined, isBackground: false, @@ -344,8 +337,7 @@ export default function RootLayout({ if (backgroundImage && backgroundImage !== 'none') { const urlMatch = backgroundImage.match(/url(['"]?([^'")]+)['"]?)/); if (urlMatch) { - const originalBgSrc = extractOriginalUrl(urlMatch[1]); - if (tagName !== 'img') { + if (tagName !== 'img') { info.imageData = { src: originalBgSrc, isBackground: true @@ -357,8 +349,7 @@ export default function RootLayout({ } } - const elementType = getElementType(element); - info.elementType = elementType; + info.elementType = elementType; if (elementType === 'Button') { const buttonText = element.textContent?.trim() || element.value || element.getAttribute('aria-label') || ''; @@ -451,13 +442,11 @@ export default function RootLayout({ }; const isTextElement = (element) => { - const elementType = getElementType(element); - return elementType === 'Text'; + return elementType === 'Text'; }; const isButtonElement = (element) => { - const elementType = getElementType(element); - return elementType === 'Button'; + return elementType === 'Button'; }; const updateButtonText = (element, newText) => { @@ -532,8 +521,7 @@ export default function RootLayout({ }; const handleInput = () => { - const elementInfo = getElementInfo(element); - let currentText = element.textContent; + let currentText = element.textContent; // Ensure there's always at least a space to keep the element editable if (currentText === '' || currentText === null || currentText.length === 0) { @@ -646,8 +634,7 @@ export default function RootLayout({ }, '*'); if (save && originalContent !== element.textContent) { - const elementInfo = getElementInfo(element); - let finalText = element.textContent; + let finalText = element.textContent; // Trim the final text and convert space-only to empty string for saving if (finalText === ' ' || finalText.trim() === '') { @@ -776,7 +763,7 @@ export default function RootLayout({ lastMouseX = e.clientX; lastMouseY = e.clientY; - const target = getMostSpecificElement(e.clientX, e.clientY) || e.target; + || e.target; if (!isValidElement(target) || target === hoveredElement || target === selectedElement) { return; @@ -808,8 +795,7 @@ export default function RootLayout({ hoverOverlay = createHoverOverlay(target); } - const elementType = getElementType(target); - showElementTypeLabel(target, elementType); + showElementTypeLabel(target, elementType); window.parent.postMessage({ type: 'webild-element-hover', @@ -851,7 +837,7 @@ export default function RootLayout({ e.preventDefault(); e.stopPropagation(); - const target = getMostSpecificElement(e.clientX, e.clientY) || e.target; + || e.target; if (!isValidElement(target)) return; if (selectedElement && selectedElement !== target) { @@ -896,8 +882,7 @@ export default function RootLayout({ hoveredElement = null; } - const elementInfo = getElementInfo(target, true); - selectedElement.dataset.webildSelector = elementInfo.selector; + selectedElement.dataset.webildSelector = elementInfo.selector; showElementTypeLabel(target, elementInfo.elementType); window.parent.postMessage({ @@ -980,8 +965,7 @@ export default function RootLayout({ isScrolling = false; if (lastMouseX > 0 && lastMouseY > 0) { - const target = getMostSpecificElement(lastMouseX, lastMouseY); - if (target && isValidElement(target) && target !== selectedElement) { + if (target && isValidElement(target) && target !== selectedElement) { hoveredElement = target; const computedStyle = window.getComputedStyle(target); @@ -995,8 +979,7 @@ export default function RootLayout({ hoveredElement.classList.add(hoverClass); hoverOverlay = createHoverOverlay(target); - const elementType = getElementType(target); - showElementTypeLabel(target, elementType); + showElementTypeLabel(target, elementType); window.parent.postMessage({ type: 'webild-element-hover', @@ -1019,8 +1002,7 @@ export default function RootLayout({ const saveChangeToStorage = (change) => { try { - const storageKey = getStorageKey(); - const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]'); + const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]'); const filteredChanges = existingChanges.filter(c => { return !(c.oldValue === change.oldValue && c.sectionId === change.sectionId); @@ -1040,8 +1022,7 @@ export default function RootLayout({ const clearLocalChanges = () => { try { - const storageKey = getStorageKey(); - localStorage.removeItem(storageKey); + localStorage.removeItem(storageKey); window.parent.postMessage({ type: 'webild-local-changes-cleared', data: {} @@ -1090,8 +1071,7 @@ export default function RootLayout({ if (e.data.type === 'webild-cancel-changes') { try { - const storageKey = getStorageKey(); - const savedChanges = localStorage.getItem(storageKey); + const savedChanges = localStorage.getItem(storageKey); if (savedChanges) { const changes = JSON.parse(savedChanges); changes.forEach(change => { @@ -1113,8 +1093,7 @@ export default function RootLayout({ if (isBackground) { element.style.backgroundImage = change.oldValue ? 'url(' + change.oldValue + ')' : ''; } else { - const oldMediaType = getMediaTypeFromUrl(change.oldValue); - if (revertTag === 'video' && oldMediaType === 'image') { + if (revertTag === 'video' && oldMediaType === 'image') { swapMediaElement(element, 'img', change.oldValue); } else if (revertTag === 'img' && oldMediaType === 'video') { swapMediaElement(element, 'video', change.oldValue); @@ -1162,8 +1141,7 @@ export default function RootLayout({ const el = textElements[i]; if (isTextElement(el) && el.textContent.trim() === (oldValue || '').trim()) { element = el; - const newSelector = getUniqueSelector(element, true); - if (newSelector) { + if (newSelector) { element.dataset.webildSelector = newSelector; } break; @@ -1254,10 +1232,8 @@ export default function RootLayout({ replaced = true; } else if (element.tagName.toLowerCase() === 'img') { oldValue = element.src; - const newMediaType = getMediaTypeFromUrl(newSrc); - if (newMediaType === 'video' && allowMediaTypeSwap) { - const swapped = swapMediaElement(element, 'video', newSrc); - if (selectedElement === element) selectedElement = swapped; + if (newMediaType === 'video' && allowMediaTypeSwap) { + if (selectedElement === element) selectedElement = swapped; element = swapped; } else { element.src = newSrc; @@ -1265,11 +1241,9 @@ export default function RootLayout({ replaced = true; } else if (element.tagName.toLowerCase() === 'video') { oldValue = element.src || element.currentSrc || ''; - const newMediaType = getMediaTypeFromUrl(newSrc); - const sources = element.querySelectorAll('source'); + const sources = element.querySelectorAll('source'); if (newMediaType === 'image' && allowMediaTypeSwap) { - const swapped = swapMediaElement(element, 'img', newSrc); - if (selectedElement === element) selectedElement = swapped; + if (selectedElement === element) selectedElement = swapped; element = swapped; } else { if (sources.length > 0) { @@ -1291,8 +1265,7 @@ export default function RootLayout({ } if (replaced) { - const elementInfo = getElementInfo(element); - + let cleanOldValue = oldValue; if (oldValue.includes('url(')) { const urlMatch = oldValue.match(/url(['"]?([^'")]+)['"]?)/); @@ -1363,13 +1336,7 @@ export default function RootLayout({ } }, true); - const urlCheckInterval = setInterval(() => { - if (lastPathname !== window.location.pathname) { - lastPathname = window.location.pathname; - notifyPageChange(); - } - }, 500); - + notifyPageChange(); window.webildCleanup = () => { @@ -1655,9 +1622,7 @@ export default function RootLayout({ const getElementInfo = (element, assignId = false) => { const rect = element.getBoundingClientRect(); const tagName = element.tagName.toLowerCase(); - const selector = getUniqueSelector(element, assignId); - const sectionId = getSectionId(element); - + let className = undefined; try { if (element.className) { @@ -1685,8 +1650,7 @@ export default function RootLayout({ }; if (tagName === 'img') { - const originalSrc = extractOriginalUrl(element.src); - info.imageData = { + info.imageData = { src: originalSrc, alt: element.alt || undefined, naturalWidth: element.naturalWidth, @@ -1697,8 +1661,7 @@ export default function RootLayout({ if (tagName === 'video') { const rawSrc = element.src || element.currentSrc || (element.querySelector('source') && element.querySelector('source').src) || ''; - const resolvedSrc = extractOriginalUrl(rawSrc); - info.imageData = { + info.imageData = { src: resolvedSrc, alt: element.getAttribute('aria-label') || undefined, isBackground: false, @@ -1711,8 +1674,7 @@ export default function RootLayout({ if (backgroundImage && backgroundImage !== 'none') { const urlMatch = backgroundImage.match(/url(['"]?([^'")]+)['"]?)/); if (urlMatch) { - const originalBgSrc = extractOriginalUrl(urlMatch[1]); - if (tagName !== 'img') { + if (tagName !== 'img') { info.imageData = { src: originalBgSrc, isBackground: true @@ -1724,8 +1686,7 @@ export default function RootLayout({ } } - const elementType = getElementType(element); - info.elementType = elementType; + info.elementType = elementType; if (elementType === 'Button') { const buttonText = element.textContent?.trim() || element.value || element.getAttribute('aria-label') || ''; @@ -1818,13 +1779,11 @@ export default function RootLayout({ }; const isTextElement = (element) => { - const elementType = getElementType(element); - return elementType === 'Text'; + return elementType === 'Text'; }; const isButtonElement = (element) => { - const elementType = getElementType(element); - return elementType === 'Button'; + return elementType === 'Button'; }; const updateButtonText = (element, newText) => { @@ -1899,8 +1858,7 @@ export default function RootLayout({ }; const handleInput = () => { - const elementInfo = getElementInfo(element); - let currentText = element.textContent; + let currentText = element.textContent; // Ensure there's always at least a space to keep the element editable if (currentText === '' || currentText === null || currentText.length === 0) { @@ -2013,8 +1971,7 @@ export default function RootLayout({ }, '*'); if (save && originalContent !== element.textContent) { - const elementInfo = getElementInfo(element); - let finalText = element.textContent; + let finalText = element.textContent; // Trim the final text and convert space-only to empty string for saving if (finalText === ' ' || finalText.trim() === '') { @@ -2143,7 +2100,7 @@ export default function RootLayout({ lastMouseX = e.clientX; lastMouseY = e.clientY; - const target = getMostSpecificElement(e.clientX, e.clientY) || e.target; + || e.target; if (!isValidElement(target) || target === hoveredElement || target === selectedElement) { return; @@ -2175,8 +2132,7 @@ export default function RootLayout({ hoverOverlay = createHoverOverlay(target); } - const elementType = getElementType(target); - showElementTypeLabel(target, elementType); + showElementTypeLabel(target, elementType); window.parent.postMessage({ type: 'webild-element-hover', @@ -2218,7 +2174,7 @@ export default function RootLayout({ e.preventDefault(); e.stopPropagation(); - const target = getMostSpecificElement(e.clientX, e.clientY) || e.target; + || e.target; if (!isValidElement(target)) return; if (selectedElement && selectedElement !== target) { @@ -2263,8 +2219,7 @@ export default function RootLayout({ hoveredElement = null; } - const elementInfo = getElementInfo(target, true); - selectedElement.dataset.webildSelector = elementInfo.selector; + selectedElement.dataset.webildSelector = elementInfo.selector; showElementTypeLabel(target, elementInfo.elementType); window.parent.postMessage({ @@ -2347,8 +2302,7 @@ export default function RootLayout({ isScrolling = false; if (lastMouseX > 0 && lastMouseY > 0) { - const target = getMostSpecificElement(lastMouseX, lastMouseY); - if (target && isValidElement(target) && target !== selectedElement) { + if (target && isValidElement(target) && target !== selectedElement) { hoveredElement = target; const computedStyle = window.getComputedStyle(target); @@ -2362,8 +2316,7 @@ export default function RootLayout({ hoveredElement.classList.add(hoverClass); hoverOverlay = createHoverOverlay(target); - const elementType = getElementType(target); - showElementTypeLabel(target, elementType); + showElementTypeLabel(target, elementType); window.parent.postMessage({ type: 'webild-element-hover', @@ -2386,8 +2339,7 @@ export default function RootLayout({ const saveChangeToStorage = (change) => { try { - const storageKey = getStorageKey(); - const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]'); + const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]'); const filteredChanges = existingChanges.filter(c => { return !(c.oldValue === change.oldValue && c.sectionId === change.sectionId); @@ -2407,8 +2359,7 @@ export default function RootLayout({ const clearLocalChanges = () => { try { - const storageKey = getStorageKey(); - localStorage.removeItem(storageKey); + localStorage.removeItem(storageKey); window.parent.postMessage({ type: 'webild-local-changes-cleared', data: {} @@ -2457,8 +2408,7 @@ export default function RootLayout({ if (e.data.type === 'webild-cancel-changes') { try { - const storageKey = getStorageKey(); - const savedChanges = localStorage.getItem(storageKey); + const savedChanges = localStorage.getItem(storageKey); if (savedChanges) { const changes = JSON.parse(savedChanges); changes.forEach(change => { @@ -2480,8 +2430,7 @@ export default function RootLayout({ if (isBackground) { element.style.backgroundImage = change.oldValue ? 'url(' + change.oldValue + ')' : ''; } else { - const oldMediaType = getMediaTypeFromUrl(change.oldValue); - if (revertTag === 'video' && oldMediaType === 'image') { + if (revertTag === 'video' && oldMediaType === 'image') { swapMediaElement(element, 'img', change.oldValue); } else if (revertTag === 'img' && oldMediaType === 'video') { swapMediaElement(element, 'video', change.oldValue); @@ -2529,8 +2478,7 @@ export default function RootLayout({ const el = textElements[i]; if (isTextElement(el) && el.textContent.trim() === (oldValue || '').trim()) { element = el; - const newSelector = getUniqueSelector(element, true); - if (newSelector) { + if (newSelector) { element.dataset.webildSelector = newSelector; } break; @@ -2621,10 +2569,8 @@ export default function RootLayout({ replaced = true; } else if (element.tagName.toLowerCase() === 'img') { oldValue = element.src; - const newMediaType = getMediaTypeFromUrl(newSrc); - if (newMediaType === 'video' && allowMediaTypeSwap) { - const swapped = swapMediaElement(element, 'video', newSrc); - if (selectedElement === element) selectedElement = swapped; + if (newMediaType === 'video' && allowMediaTypeSwap) { + if (selectedElement === element) selectedElement = swapped; element = swapped; } else { element.src = newSrc; @@ -2632,11 +2578,9 @@ export default function RootLayout({ replaced = true; } else if (element.tagName.toLowerCase() === 'video') { oldValue = element.src || element.currentSrc || ''; - const newMediaType = getMediaTypeFromUrl(newSrc); - const sources = element.querySelectorAll('source'); + const sources = element.querySelectorAll('source'); if (newMediaType === 'image' && allowMediaTypeSwap) { - const swapped = swapMediaElement(element, 'img', newSrc); - if (selectedElement === element) selectedElement = swapped; + if (selectedElement === element) selectedElement = swapped; element = swapped; } else { if (sources.length > 0) { @@ -2658,8 +2602,7 @@ export default function RootLayout({ } if (replaced) { - const elementInfo = getElementInfo(element); - + let cleanOldValue = oldValue; if (oldValue.includes('url(')) { const urlMatch = oldValue.match(/url(['"]?([^'")]+)['"]?)/); @@ -2730,13 +2673,7 @@ export default function RootLayout({ } }, true); - const urlCheckInterval = setInterval(() => { - if (lastPathname !== window.location.pathname) { - lastPathname = window.location.pathname; - notifyPageChange(); - } - }, 500); - + notifyPageChange(); window.webildCleanup = () => { diff --git a/src/app/page.tsx b/src/app/page.tsx index d7c0847..72998d3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -41,11 +41,11 @@ export default function LandingPage() {
diff --git a/src/components/sections/hero/HeroSignup.tsx b/src/components/sections/hero/HeroSignup.tsx index d6867a1..1b109dd 100644 --- a/src/components/sections/hero/HeroSignup.tsx +++ b/src/components/sections/hero/HeroSignup.tsx @@ -60,7 +60,7 @@ const HeroSignup = ({ tagIcon, tagAnimation, inputPlaceholder = "Enter your email", - buttonText = "Get Started", + buttonText = "Download Now", onSubmit, ariaLabel = "Hero section", className = "",