<?php /** * Blog index template — renders at /blog/ * * Layout (register order): * R5 dark — blog hero + category filter pills * R4 — credibility-bar partial * R1 white — post card grid (client-side category filter, paginated) * R5 dark — dual-cta partial * * The category filter pills and post cards share data-category/data-filter * attributes. blog-filter.js wires them together with no page reload. * * @package EPA_Theme */ get_header(); epa_partial( 'breadcrumbs' ); // Build category list for filter pills (non-empty categories only) $blog_categories = get_categories( array( 'hide_empty' => true, 'orderby' => 'name', 'order' => 'ASC', ) ); ?> <!-- Blog Hero (R5 dark) --> <section class="epa-blog-hero"> <div class="epa-container"> <p class="epa-blog-hero__eyebrow">Atlanta Estate Planning Journal</p> <h1 class="epa-blog-hero__title">Plain-language answers to Georgia estate planning questions</h1> <p class="epa-blog-hero__lead">Written by attorneys. Organized by the situations families actually face.</p> <?php if ( $blog_categories ) : ?> <nav class="epa-blog-filter" id="epa-blog-filter" aria-label="Filter articles by category"> <button class="epa-blog-filter__pill is-active" data-filter="all" aria-pressed="true" type="button">All articles</button> <?php foreach ( $blog_categories as $cat ) : ?> <button class="epa-blog-filter__pill" data-filter="<?php echo esc_attr( $cat->slug ); ?>" aria-pressed="false" type="button"><?php echo esc_html( $cat->name ); ?></button> <?php endforeach; ?> </nav> <?php endif; ?> </div> </section> <?php epa_partial( 'credibility-bar' ); ?> <!-- Post Grid (R1 white) --> <section class="epa-section epa-blog-index"> <div class="epa-container"> <?php if ( have_posts() ) : ?> <div class="epa-post-grid" id="epa-blog-grid"> <?php while ( have_posts() ) : the_post(); $card_category = get_the_category(); $card_cat_name = $card_category ? $card_category[0]->name : ''; $card_cat_slug = $card_category ? $card_category[0]->slug : ''; $card_date = get_the_date( 'F j, Y' ); $card_words = str_word_count( wp_strip_all_tags( get_the_content() ) ); $card_time = max( 1, (int) round( $card_words / 225 ) ); $card_excerpt = get_the_excerpt(); if ( ! $card_excerpt ) { $card_excerpt = wp_trim_words( get_the_content(), 28, '' ); } ?> <article class="epa-post-card" data-category="<?php echo esc_attr( $card_cat_slug ); ?>"> <a href="<?php the_permalink(); ?>" class="epa-post-card__link"> <?php if ( $card_cat_name ) : ?> <span class="epa-post-card__category"><?php echo esc_html( $card_cat_name ); ?></span> <?php endif; ?> <h2 class="epa-post-card__title"><?php the_title(); ?></h2> <p class="epa-post-card__excerpt"><?php echo esc_html( $card_excerpt ); ?></p> <div class="epa-post-card__meta"> <span class="epa-post-card__time"><?php echo esc_html( $card_time ); ?> min read</span> </div> <span class="epa-post-card__cta"> Read Article <svg class="epa-post-card__arrow" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="3" y1="8" x2="13" y2="8"/><polyline points="9,4 13,8 9,12"/></svg> </span> </a> </article> <?php endwhile; ?> </div><!-- /#epa-blog-grid --> <!-- Empty state: shown by blog-filter.js when a category has 0 visible cards --> <div id="epa-filter-empty" hidden> <p>No articles in this category yet.</p> </div> <!-- Pagination — hidden when JS filter is active (filter works client-side) --> <?php $pagination = paginate_links( array( 'prev_text' => '&larr;', 'next_text' => '&rarr;', ) ); if ( $pagination ) : ?> <nav class="epa-blog-pagination" aria-label="Blog navigation"> <?php echo $pagination; ?> </nav> <?php endif; ?> <?php else : ?> <p class="epa-blog-empty" style="font-family:'Poppins',sans-serif;color:#2C3328;">No articles published yet. Check back soon.</p> <?php endif; ?> </div> </section> <?php epa_partial( 'form-cta-block' ); ?> <?php get_footer(); ?>