Theme customization based on grouped pages

You can either:

A: Use Posts rather than Pages. WP enables Categories on Posts by default, so it’s easy to select a Category for each Post (all categories are shown with checkboxes, or it’s easy to add a new one).

B: Use Pages, and create a custom “Page Category” taxonomy to categorize them, which also then makes it easy to select a Page Category for each Page (you start typing a category and it autocompletes, or it’s easy to add a new one).

Either way, the simplest way to then add an image for each category is to use Advanced Custom Fields. It will let you use the built-in Media Library to upload or select the image without you having to write a bunch of JavaScript or manually paste in image URLs.

You’ll want to make sure you assign one and only one category to each post/page. Unless you build in a lot of extra logic WP can’t tell what category they were last viewing, so if you have a post assigned to both category A and B, and the visitor has been perusing category B and then happens upon this post, they’ll see the category A header which they won’t necessarily be expecting. But, the code below doesn’t “fail” when there’s more than one category, it just gets the image for whichever category it finds first.

Finally, in your theme header, you’ll check what type of content is being displayed to determine which image to show. Something like this (this version is for option A):

<?php
// If this is a single Post
if(is_single('post')) {
    // get its Category
    $category = get_the_category();
    // set required ACF $post_id to category_#
    $post_id = 'category_' . $category->term_id;
    // get the first Category's ACF image
    $header_image = get_field('header_image', $post_id);
}
// If this is one of the Categories
elseif(is_category) {
    // set required ACF $post_id to category_#
    $post_id = 'category_' . get_queried_object()->term_id;
    // get the first Category's ACF image
    $header_image = get_field('header_image', $post_id);
}
// Now that we have the image ID, we'll use it somehow
// You could output the actual image, or use it as a background like this
?><style>
    header { background-image:url('<?php echo $header_image; ?>'); }
</style>

You may need to adjust, depending on your markup (perhaps you don’t want the image to be the background-image on your header, or perhaps you have a class on the header so that other header tags aren’t affected) but that’s the basic logic.