@@ -36,6 +36,13 @@ import {
3636 SERVICE_Y_OFFSET ,
3737 SERVICE_Y_CENTER ,
3838 SERVICE_HEIGHT ,
39+ LIBRARY_CARD_WIDTH ,
40+ LIBRARY_CARD_HEIGHT ,
41+ LIBRARY_CARD_LOCATIONS ,
42+ SERVER_CARD_Y_OFFSET ,
43+ SERVER_CARD_LOCATIONS ,
44+ SERVER_CARD_WIDTH ,
45+ SERVER_CARD_HEIGHT ,
3946} from '~/stores/aiLibraryHeroAnimation'
4047
4148// Get the store instance for accessing getState in closures
@@ -507,7 +514,7 @@ export function AILibraryHero({ project, cta, actions }: AILibraryHeroProps) {
507514 < div className = "relative flex flex-col items-center gap-8 text-center px-4 overflow-visible" >
508515 { /* Diagram and Chat Panel Container */ }
509516 < div
510- className = "relative z-10 w-full max-w-7xl mx-auto mt-16 flex flex-row flex-wrap gap-8 lg:gap-12"
517+ className = "relative z-10 w-full max-w-7xl mx-auto flex flex-row flex-wrap gap-8 lg:gap-12"
511518 style = { { height : SVG_HEIGHT } }
512519 >
513520 { /* SVG Diagram */ }
@@ -775,67 +782,83 @@ export function AILibraryHero({ project, cta, actions }: AILibraryHeroProps) {
775782
776783 { /* Top layer: Frameworks */ }
777784 < AILibraryHeroCard
778- x = { 0 }
785+ x = { LIBRARY_CARD_LOCATIONS [ 0 ] }
779786 y = { 0 }
780- width = { 120 }
781- height = { 60 }
787+ width = { LIBRARY_CARD_WIDTH }
788+ height = { LIBRARY_CARD_HEIGHT }
782789 label = "Vanilla"
783790 opacity = { getOpacity ( 0 , selectedFramework , rotatingFramework ) }
784791 textColor = { textColor }
785792 strokeColor = { strokeColor }
786793 fontSize = { BOX_FONT_SIZE }
787794 fontWeight = { BOX_FONT_WEIGHT }
788795 logo = { tsLogo }
789- transform = {
790- selectedFramework === 0
791- ? 'translate(60, 30) scale(1.1) translate(-60, -30)'
792- : ''
793- }
796+ transform = { getScaleTransform (
797+ 0 ,
798+ selectedFramework ,
799+ LIBRARY_CARD_LOCATIONS [ 0 ] + LIBRARY_CARD_WIDTH / 2 ,
800+ LIBRARY_CARD_HEIGHT / 2
801+ ) }
794802 />
795803
796804 < AILibraryHeroCard
797- x = { 160 }
805+ x = { LIBRARY_CARD_LOCATIONS [ 1 ] }
798806 y = { 0 }
799- width = { 120 }
800- height = { 60 }
807+ width = { LIBRARY_CARD_WIDTH }
808+ height = { LIBRARY_CARD_HEIGHT }
801809 label = "React"
802810 opacity = { getOpacity ( 1 , selectedFramework , rotatingFramework ) }
803811 textColor = { textColor }
804812 strokeColor = { strokeColor }
805813 fontSize = { BOX_FONT_SIZE }
806814 fontWeight = { BOX_FONT_WEIGHT }
807815 logo = { reactLogo }
808- transform = { getScaleTransform ( 1 , selectedFramework , 220 , 30 ) }
816+ transform = { getScaleTransform (
817+ 1 ,
818+ selectedFramework ,
819+ LIBRARY_CARD_LOCATIONS [ 1 ] + LIBRARY_CARD_WIDTH / 2 ,
820+ LIBRARY_CARD_HEIGHT / 2
821+ ) }
809822 />
810823
811824 < AILibraryHeroCard
812- x = { 320 }
825+ x = { LIBRARY_CARD_LOCATIONS [ 2 ] }
813826 y = { 0 }
814- width = { 120 }
815- height = { 60 }
827+ width = { LIBRARY_CARD_WIDTH }
828+ height = { LIBRARY_CARD_HEIGHT }
816829 label = "Solid"
817830 opacity = { getOpacity ( 2 , selectedFramework , rotatingFramework ) }
818831 textColor = { textColor }
819832 strokeColor = { strokeColor }
820833 fontSize = { BOX_FONT_SIZE }
821834 fontWeight = { BOX_FONT_WEIGHT }
822835 logo = { solidLogo }
823- transform = { getScaleTransform ( 2 , selectedFramework , 380 , 30 ) }
836+ transform = { getScaleTransform (
837+ 2 ,
838+ selectedFramework ,
839+ LIBRARY_CARD_LOCATIONS [ 2 ] + LIBRARY_CARD_WIDTH / 2 ,
840+ LIBRARY_CARD_HEIGHT / 2
841+ ) }
824842 />
825843
826844 < AILibraryHeroCard
827- x = { 480 }
845+ x = { LIBRARY_CARD_LOCATIONS [ 3 ] }
828846 y = { 0 }
829- width = { 120 }
830- height = { 60 }
847+ width = { LIBRARY_CARD_WIDTH }
848+ height = { LIBRARY_CARD_HEIGHT }
831849 label = "?"
832850 opacity = { getOpacity ( 3 , selectedFramework , rotatingFramework ) }
833851 textColor = { textColor }
834852 strokeColor = { strokeColor }
835853 fontSize = { BOX_FONT_SIZE }
836854 fontWeight = { BOX_FONT_WEIGHT }
837855 isDashed = { true }
838- transform = { getScaleTransform ( 3 , selectedFramework , 540 , 30 ) }
856+ transform = { getScaleTransform (
857+ 3 ,
858+ selectedFramework ,
859+ LIBRARY_CARD_LOCATIONS [ 3 ] + LIBRARY_CARD_WIDTH / 2 ,
860+ LIBRARY_CARD_HEIGHT / 2
861+ ) }
839862 />
840863
841864 { /* @tanstack /ai-client box */ }
@@ -1012,25 +1035,30 @@ export function AILibraryHero({ project, cta, actions }: AILibraryHeroProps) {
10121035
10131036 { /* Server layer */ }
10141037 < AILibraryHeroCard
1015- x = { 0 }
1016- y = { 370 }
1017- width = { 120 }
1018- height = { 60 }
1038+ x = { SERVER_CARD_LOCATIONS [ 0 ] }
1039+ y = { SERVER_CARD_Y_OFFSET }
1040+ width = { SERVER_CARD_WIDTH }
1041+ height = { SERVER_CARD_HEIGHT }
10191042 label = "TypeScript"
10201043 opacity = { getOpacity ( 0 , selectedServer , rotatingServer ) }
10211044 textColor = { textColor }
10221045 strokeColor = { strokeColor }
10231046 fontSize = { 16 }
10241047 fontWeight = { BOX_FONT_WEIGHT }
10251048 logo = { tsLogo }
1026- transform = { getScaleTransform ( 0 , selectedServer , 60 , 400 ) }
1049+ transform = { getScaleTransform (
1050+ 0 ,
1051+ selectedServer ,
1052+ SERVER_CARD_LOCATIONS [ 0 ] + SERVER_CARD_WIDTH / 2 ,
1053+ SERVER_CARD_Y_OFFSET + SERVER_CARD_HEIGHT / 2
1054+ ) }
10271055 />
10281056
10291057 < AILibraryHeroCard
1030- x = { 160 }
1031- y = { 370 }
1032- width = { 120 }
1033- height = { 60 }
1058+ x = { SERVER_CARD_LOCATIONS [ 1 ] }
1059+ y = { SERVER_CARD_Y_OFFSET }
1060+ width = { SERVER_CARD_WIDTH }
1061+ height = { SERVER_CARD_HEIGHT }
10341062 label = "PHP"
10351063 opacity = { getOpacity ( 1 , selectedServer , rotatingServer ) }
10361064 textColor = { textColor }
@@ -1039,37 +1067,52 @@ export function AILibraryHero({ project, cta, actions }: AILibraryHeroProps) {
10391067 fontWeight = { BOX_FONT_WEIGHT }
10401068 logoLight = { phpLightLogo }
10411069 logoDark = { phpDarkLogo }
1042- transform = { getScaleTransform ( 1 , selectedServer , 220 , 400 ) }
1070+ transform = { getScaleTransform (
1071+ 1 ,
1072+ selectedServer ,
1073+ SERVER_CARD_LOCATIONS [ 1 ] + SERVER_CARD_WIDTH / 2 ,
1074+ SERVER_CARD_Y_OFFSET + SERVER_CARD_HEIGHT / 2
1075+ ) }
10431076 />
10441077
10451078 < AILibraryHeroCard
1046- x = { 320 }
1047- y = { 370 }
1048- width = { 120 }
1049- height = { 60 }
1079+ x = { SERVER_CARD_LOCATIONS [ 2 ] }
1080+ y = { SERVER_CARD_Y_OFFSET }
1081+ width = { SERVER_CARD_WIDTH }
1082+ height = { SERVER_CARD_HEIGHT }
10501083 label = "Python"
10511084 opacity = { getOpacity ( 2 , selectedServer , rotatingServer ) }
10521085 textColor = { textColor }
10531086 strokeColor = { strokeColor }
10541087 fontSize = { BOX_FONT_SIZE }
10551088 fontWeight = { BOX_FONT_WEIGHT }
10561089 logo = { pythonLogo }
1057- transform = { getScaleTransform ( 2 , selectedServer , 380 , 400 ) }
1090+ transform = { getScaleTransform (
1091+ 2 ,
1092+ selectedServer ,
1093+ SERVER_CARD_LOCATIONS [ 2 ] + SERVER_CARD_WIDTH / 2 ,
1094+ SERVER_CARD_Y_OFFSET + SERVER_CARD_HEIGHT / 2
1095+ ) }
10581096 />
10591097
10601098 < AILibraryHeroCard
1061- x = { 480 }
1062- y = { 370 }
1063- width = { 120 }
1064- height = { 60 }
1099+ x = { SERVER_CARD_LOCATIONS [ 3 ] }
1100+ y = { SERVER_CARD_Y_OFFSET }
1101+ width = { SERVER_CARD_WIDTH }
1102+ height = { SERVER_CARD_HEIGHT }
10651103 label = "?"
10661104 opacity = { getOpacity ( 3 , selectedServer , rotatingServer ) }
10671105 textColor = { textColor }
10681106 strokeColor = { strokeColor }
10691107 fontSize = { BOX_FONT_SIZE }
10701108 fontWeight = { BOX_FONT_WEIGHT }
10711109 isDashed = { true }
1072- transform = { getScaleTransform ( 3 , selectedServer , 540 , 400 ) }
1110+ transform = { getScaleTransform (
1111+ 3 ,
1112+ selectedServer ,
1113+ SERVER_CARD_LOCATIONS [ 3 ] + SERVER_CARD_WIDTH / 2 ,
1114+ SERVER_CARD_Y_OFFSET + SERVER_CARD_HEIGHT / 2
1115+ ) }
10731116 />
10741117 </ svg >
10751118 </ div >
@@ -1082,31 +1125,6 @@ export function AILibraryHero({ project, cta, actions }: AILibraryHeroProps) {
10821125 />
10831126 </ div >
10841127 </ div >
1085-
1086- { /* Content overlay */ }
1087- < div className = "relative z-10 flex flex-col items-center gap-6 mt-8" >
1088- < h2 className = "font-bold text-2xl md:text-4xl max-w-xl xl:max-w-4xl text-balance [letter-spacing:-0.03em]" >
1089- { project . tagline }
1090- </ h2 >
1091- { project . description ? (
1092- < p className = "text opacity-90 max-w-lg xl:max-w-2xl lg:text-base text-balance" >
1093- { project . description }
1094- </ p >
1095- ) : null }
1096- { actions ? (
1097- < div > { actions } </ div >
1098- ) : cta ? (
1099- < Link
1100- { ...cta . linkProps }
1101- className = { twMerge (
1102- 'inline-block py-2 px-4 rounded uppercase font-extrabold transition-colors' ,
1103- cta . className
1104- ) }
1105- >
1106- { cta . label }
1107- </ Link >
1108- ) : null }
1109- </ div >
11101128 </ div >
11111129 </ >
11121130 )
0 commit comments