restructured to separate component files