How to remove slug from CPT correctly?

This is a two-step process. First, you need to remove the slug from the default URL. (use a unique slug while registering the CPT).

function wpse413969_remove_cpt_slug( $post_link, $post ) {
    if ( $post->post_type == 'YOUR_CPT' && $post->post_status == 'publish') {
        $post_link = str_replace( "https://wordpress.stackexchange.com/" . $post->post_type . "https://wordpress.stackexchange.com/", "https://wordpress.stackexchange.com/", $post_link );
    }
    return $post_link;
}
add_filter( 'post_type_link', 'wpse413969_remove_cpt_slug', 10, 2 );

Then include your CPT in main query.

function wpse413969_add_cpt_names_to_main_query( $query ) {
   
    // Return if this is not the main query.
    if ( ! $query->is_main_query() ) {
        return;
    }
    
    // Return if this query doesn't match our very specific rewrite rule.
    if ( ! isset( $query->query['page'] ) || 2 !== count( $query->query ) ) {
        return;
    }
    
    // Return if we're not querying based on the post name.
    if ( empty( $query->query['name'] ) ) {
        return;
    }
    
    // Add CPT to the list of post types WP will include when it queries based on the post name.
    $query->set( 'post_type', array( 'post', 'page', 'YOUR_CPT' ) );
}
add_action( 'pre_get_posts', 'wpse413969_add_cpt_names_to_main_query' );

This, IMHO, is a bad practice. There are some good reasons why WordPress includes the slug in CPTs. To avoid conflict with default post and pages, always use unique slugs for your CPT posts.