11"use client" ;
2- import Footer from "@/components/landing-sections/footer" ;
32import Header from "@/components/ui/header" ;
4- import { ShineBorder } from "@/components/ui/shine-borders" ;
5- import { motion } from "framer-motion" ;
63import { Check , CornerDownRight , Target , Terminal } from "lucide-react" ;
74import Image from "next/image" ;
85import Link from "next/link" ;
96import React , { useEffect } from "react" ;
10- import PrimaryButton from "@/components/ui/custom-button" ;
11- import PaymentFlow from "@/components/payment/PaymentFlow" ;
127import { ActiveTag } from "@/components/ui/ActiveTag" ;
138import { usePathname } from "next/navigation" ;
9+ import { motion } from "framer-motion" ;
10+ import { ShineBorder } from "@/components/ui/shine-borders" ;
11+ import PrimaryButton from "@/components/ui/custom-button" ;
12+ import dynamic from "next/dynamic" ;
13+
14+ const Footer = dynamic (
15+ ( ) =>
16+ import ( "@/components/landing-sections/footer" ) . then ( ( mod ) => mod . default ) ,
17+ {
18+ ssr : false ,
19+ loading : ( ) => null ,
20+ }
21+ ) ;
22+
23+ // lazy load PaymentFlow - it's inside pricing card but can wait
24+ const PaymentFlow = dynamic (
25+ ( ) => import ( "@/components/payment/PaymentFlow" ) . then ( ( mod ) => mod . default ) ,
26+ {
27+ ssr : false ,
28+ loading : ( ) => null ,
29+ }
30+ ) ;
1431const opensoxFeatures = [
1532 {
1633 id : 1 ,
@@ -71,7 +88,7 @@ const whySub = [
7188 } ,
7289 {
7390 content :
74- "After the launch, this $49 offer be removed and Opensox Pro will be around ~ $120 for whole year ($10/mo.) " ,
91+ "After the launch, this $49 offer be removed and Opensox Pro will be around ~ $89 for whole year. " ,
7592 } ,
7693 {
7794 content : "The price of the dollar is constantly increasing." ,
@@ -114,60 +131,122 @@ const Pricing = () => {
114131 const callbackUrl = `${ pathname } #pro-price-card` ;
115132
116133 useEffect ( ( ) => {
117- if ( window . location . hash === "#pro-price-card" ) {
118- const element = document . getElementById ( " pro-price-card") ;
119- if ( element ) {
120- setTimeout ( ( ) => {
134+ const handleHashScroll = ( ) => {
135+ if ( window . location . hash === "# pro-price-card") {
136+ const element = document . getElementById ( "pro-price-card" ) ;
137+ if ( element ) {
121138 element . scrollIntoView ( { behavior : "smooth" , block : "start" } ) ;
122- } , 100 ) ;
139+ }
123140 }
124- }
125- if ( window . location . hash === "#testimonials" ) {
126- const element = document . getElementById ( "testimonials" ) ;
127- if ( element ) {
128- setTimeout ( ( ) => {
141+ if ( window . location . hash === "#testimonials" ) {
142+ const element = document . getElementById ( "testimonials" ) ;
143+ if ( element ) {
129144 element . scrollIntoView ( { behavior : "smooth" , block : "start" } ) ;
130- } , 100 ) ;
145+ }
131146 }
147+ } ;
148+
149+ if ( "requestIdleCallback" in window ) {
150+ requestIdleCallback ( handleHashScroll , { timeout : 2000 } ) ;
151+ } else {
152+ setTimeout ( handleHashScroll , 100 ) ;
132153 }
133154 } , [ ] ) ;
134155
135156 return (
136157 < >
158+ < style
159+ dangerouslySetInnerHTML = { {
160+ __html : `
161+ /* critical css for LCP element - inline for fastest rendering */
162+ /* font-family matches Tailwind's font-mono class exactly to ensure consistent fallbacks */
163+ .lcp-feature-item { display: flex; flex-direction: column; gap: 1rem; width: 100%; flex: 1; }
164+ .lcp-feature-content { display: flex; flex-direction: column; gap: 0.5rem; width: 100%; }
165+ .lcp-feature-header { display: flex; gap: 1rem; align-items: center; }
166+ .lcp-feature-number { font-size: 3.75rem; font-family: var(--font-dm-mono), Menlo, Monaco, "Courier New", monospace; font-weight: 600; background: linear-gradient(to bottom, #a472ea, #341e7b); -webkit-background-clip: text; background-clip: text; color: transparent; }
167+ .lcp-feature-title { font-size: 1.5rem; font-weight: 500; }
168+ .lcp-feature-description { font-weight: 500; }
169+ ` ,
170+ } }
171+ />
137172 < main className = "w-full overflow-hidden flex flex-col items-center justify-center relative" >
138173 < Header title = "We are working on Opensox 2.0" />
139- < div className = "flex flex-col bg-[#151515]/20 backdrop-blur-xl relative w-full " >
174+ < div className = "flex flex-col bg-[#151515]/20 relative w-full " >
140175 < div className = "h-full pv relative" >
141176 < div className = " py-8 border-b border-[#252525]" >
142- < motion . h2
143- initial = { { opacity : 0 , y : 30 , filter : "blur(10px)" } }
144- animate = { { opacity : 1 , y : 0 , filter : "blur(0px)" } }
145- transition = { {
146- duration : 0.6 ,
147- ease : "easeOut" ,
148- type : "spring" ,
149- delay : 0.4 ,
150- } }
151- className = "text-center text-3xl tracking-tight font-medium"
152- >
177+ < h2 className = "text-center text-3xl tracking-tight font-medium" >
153178 What is Opensox 2.0?
154- </ motion . h2 >
179+ </ h2 >
155180 </ div >
156181 < div className = " w-full h-full flex flex-col gap-6 border-b border-[#252525]" >
157182 < ul className = "flex flex-col lg:flex-row [&>li]:w-full [&>li]:p-6 divide-y lg:divide-y-0 lg:divide-x divide-[#252525] h-full " >
158183 { opensoxFeatures . map ( ( feature , index ) => {
184+ // render first item (LCP element) immediately without animation
185+ const isLCPElement = index === 0 ;
186+
187+ if ( isLCPElement ) {
188+ return (
189+ < li key = { index } className = "lcp-feature-item" >
190+ < div className = "lcp-feature-content" >
191+ < div className = "lcp-feature-header" >
192+ < div className = "lcp-feature-number" >
193+ { index + 1 }
194+ </ div >
195+ < div className = "flex items-center gap-2" >
196+ < h3 className = "lcp-feature-title" >
197+ { feature . title }
198+ </ h3 >
199+ { feature . title === "OX Newsletter" && (
200+ < ActiveTag text = "completed" />
201+ ) }
202+ </ div >
203+ </ div >
204+ { Array . isArray ( feature . description ) ? (
205+ < div className = "font-medium" >
206+ { feature . description . map (
207+ ( sentence , sentenceIndex ) => (
208+ < p key = { sentenceIndex } className = "mb-2" >
209+ { sentence }
210+ </ p >
211+ )
212+ ) }
213+ </ div >
214+ ) : (
215+ < p className = "lcp-feature-description" >
216+ { feature . description }
217+ </ p >
218+ ) }
219+ </ div >
220+ < div className = "flex flex-col gap-2 w-full h-full" >
221+ < ul className = "flex flex-col gap-3 w-full h-full pb-8" >
222+ { feature . features . map ( ( feature , featureIndex ) => {
223+ return (
224+ < li
225+ key = { featureIndex }
226+ className = "text-sm flex items-center gap-4"
227+ >
228+ < CornerDownRight className = "size-4 flex-shrink-0 text-[#a472ea]" />
229+ { feature }
230+ </ li >
231+ ) ;
232+ } ) }
233+ </ ul >
234+ </ div >
235+ </ li >
236+ ) ;
237+ }
238+
159239 return (
160240 < motion . li
161- initial = { { opacity : 0 , y : 30 , filter : "blur(10px)" } }
162- animate = { { opacity : 1 , y : 0 , filter : "blur(0px)" } }
241+ initial = { { opacity : 0 , y : 20 } }
242+ animate = { { opacity : 1 , y : 0 } }
163243 transition = { {
164- duration : 0.6 ,
244+ duration : 0.3 ,
165245 ease : "easeOut" ,
166- type : "spring" ,
167- delay : 0.5 + index * 0.1 ,
246+ delay : 0.2 + ( index - 1 ) * 0.05 ,
168247 } }
169248 key = { index }
170- className = "flex flex-col gap-4 w-full flex-1 "
249+ className = "flex flex-col gap-4 w-full flex-1"
171250 >
172251 < div className = "flex flex-col gap-2 w-full" >
173252 < div className = "flex gap-4 items-center" >
@@ -199,10 +278,10 @@ const Pricing = () => {
199278 </ div >
200279 < div className = "flex flex-col gap-2 w-full h-full" >
201280 < ul className = "flex flex-col gap-3 w-full h-full pb-8" >
202- { feature . features . map ( ( feature , index ) => {
281+ { feature . features . map ( ( feature , featureIndex ) => {
203282 return (
204283 < li
205- key = { index }
284+ key = { featureIndex }
206285 className = "font- text-sm flex items-center gap-4"
207286 >
208287 < CornerDownRight className = "size-4 flex-shrink-0 text-[#a472ea]" />
@@ -221,13 +300,12 @@ const Pricing = () => {
221300 < div className = "h-full relative " >
222301 < div className = "py-8 border-b border-[#252525]" >
223302 < motion . h2
224- initial = { { opacity : 0 , y : 30 , filter : "blur(10px)" } }
225- animate = { { opacity : 1 , y : 0 , filter : "blur(0px)" } }
303+ initial = { { opacity : 0 , y : 20 } }
304+ animate = { { opacity : 1 , y : 0 } }
226305 transition = { {
227- duration : 0.6 ,
306+ duration : 0.3 ,
228307 ease : "easeOut" ,
229- type : "spring" ,
230- delay : 0.8 ,
308+ delay : 0.15 ,
231309 } }
232310 className = "text-center text-3xl tracking-tight font-medium"
233311 >
@@ -239,13 +317,12 @@ const Pricing = () => {
239317 { whySub . map ( ( sub , index ) => {
240318 return (
241319 < motion . p
242- initial = { { opacity : 0 , y : 30 , filter : "blur(10px)" } }
243- animate = { { opacity : 1 , y : 0 , filter : "blur(0px)" } }
320+ initial = { { opacity : 0 , y : 20 } }
321+ animate = { { opacity : 1 , y : 0 } }
244322 transition = { {
245- duration : 0.6 ,
323+ duration : 0.3 ,
246324 ease : "easeOut" ,
247- type : "spring" ,
248- delay : 0.9 + index * 0.1 ,
325+ delay : 0.2 + index * 0.05 ,
249326 } }
250327 key = { index }
251328 className = "flex items-center gap-4"
@@ -265,6 +342,7 @@ const Pricing = () => {
265342 src = "/assets/layer1.svg"
266343 alt = "background"
267344 fill
345+ loading = "lazy"
268346 className = " w-full h-full -z-10 opacity-90"
269347 />
270348 </ div >
@@ -299,11 +377,11 @@ const PricingCard = () => {
299377 < div className = " border-border-primary w-full mx-auto flex h-full" >
300378 < div className = "border-dashed border-border-primary w-full lg:w-max mx-auto relative h-full" >
301379 < div className = "w-full h-full lg:w-[500px] relative overflow-hidden mx-auto py-10 pb-14 flex flex-col rounded-3xl" >
302- < ShineBorder shineColor = { [ "#7150E7" , "#C89BFF" , "#432BA0" ] } />
303380 < Image
304381 src = "/assets/card_bg.svg"
305382 alt = "background"
306383 fill
384+ loading = "lazy"
307385 className = "object-cover object-bottom w-full h-full absolute -z-10"
308386 />
309387 < div className = "w-full border-dashed border-border-primary px-6 lg:px-10 pb-4" >
@@ -312,10 +390,12 @@ const PricingCard = () => {
312390 src = "/assets/logo_var2.svg"
313391 alt = "background"
314392 fill
393+ loading = "lazy"
315394 className = "object-cover size-full"
316395 />
317396 </ div >
318397 </ div >
398+ < ShineBorder shineColor = { [ "#7150E7" , "#C89BFF" , "#432BA0" ] } />
319399
320400 < div className = "w-full border-dashed border-border-primary px-6 lg:px-10 py-4" >
321401 < h2 className = "text-6xl lg:text-[90px] lg:leading-[82px] tracking-tight font-semibold" >
@@ -362,7 +442,7 @@ const PricingCard = () => {
362442 } ) }
363443 </ div >
364444 </ div >
365- < div className = "bg-white mix-blend-plus-lighter absolute h-[100px ] w-full blur-[50px ] right-0 -bottom-20" > </ div >
445+ < div className = "bg-white mix-blend-plus-lighter absolute h-[120px ] w-full blur-[60px ] right-0 -bottom-20 opacity-80 " > </ div >
366446 </ div >
367447 </ div >
368448 </ div >
@@ -380,11 +460,11 @@ const SecondaryPricingCard = ({ callbackUrl }: { callbackUrl: string }) => {
380460 < div className = " border-border-primary w-full mx-auto flex h-full" >
381461 < div className = "border-dashed border-border-primary w-full lg:w-max mx-auto relative h-full" >
382462 < div className = " w-full lg:w-[500px] relative overflow-hidden mx-auto py-10 pb-14 flex flex-col h-full rounded-3xl" >
383- < ShineBorder shineColor = { [ "#7150E7" , "#C89BFF" , "#432BA0" ] } />
384463 < Image
385464 src = "/assets/card_bg.svg"
386465 alt = "background"
387466 fill
467+ loading = "lazy"
388468 className = "object-cover object-bottom w-full h-full absolute -z-10"
389469 />
390470 < div className = "w-full border-dashed border-border-primary px-6 lg:px-10 pb-4" >
@@ -393,10 +473,12 @@ const SecondaryPricingCard = ({ callbackUrl }: { callbackUrl: string }) => {
393473 src = "/assets/logo_var2.svg"
394474 alt = "background"
395475 fill
476+ loading = "lazy"
396477 className = "object-cover size-full"
397478 />
398479 </ div >
399480 </ div >
481+ < ShineBorder shineColor = { [ "#7150E7" , "#C89BFF" , "#432BA0" ] } />
400482
401483 < div
402484 id = "pro-price-card"
@@ -406,7 +488,7 @@ const SecondaryPricingCard = ({ callbackUrl }: { callbackUrl: string }) => {
406488 < h2 className = "text-6xl lg:text-[90px] lg:leading-[82px] tracking-tight font-semibold" >
407489 $49{ " " }
408490 < span className = "text-3xl lg:text-4xl text-white-400 line-through decoration-2" >
409- $69
491+ $89
410492 </ span > { " " }
411493 < span className = "text-4xl" > / year</ span >
412494 </ h2 >
@@ -470,7 +552,7 @@ const SecondaryPricingCard = ({ callbackUrl }: { callbackUrl: string }) => {
470552 } ) }
471553 </ div >
472554 </ div >
473- < div className = "bg-white mix-blend-plus-lighter absolute h-[100px ] w-full blur-[50px ] right-0 -bottom-20" > </ div >
555+ < div className = "bg-white mix-blend-plus-lighter absolute h-[120px ] w-full blur-[60px ] right-0 -bottom-20 opacity-80 " > </ div >
474556 </ div >
475557 </ div >
476558 </ div >
0 commit comments