Why this matters
The production reason.
query_posts mutates the main query and can break pagination, conditional tags, and global post state.
Use WP_Query for secondary loops or pre_get_posts when you need to adjust the main archive query.
Reset post data after custom loops so template globals return to the expected post.
$featured = new WP_Query([
'posts_per_page' => 3,
'category_name' => 'featured',
]);
while ( $featured->have_posts() ) {
$featured->the_post();
get_template_part( 'template-parts/card' );
}
wp_reset_postdata();