H-Style 워드프레스 테마 기획 및 파일

워드프레스 작성일: 2026-03-19 수정일: 2026-03-19 07:09
수정

H 스타일 워드프레스 디자인 가이드


1. 글보기(Single Post) — 이미지 확장 레이아웃

지시 내용:

싱글 포스트 본문 영역의 콘텐츠 가로폭은 최대 720~760px 정도로 좁게 유지하되, 본문 내 이미지(<figure>, <img>)는 콘텐츠 영역보다 좌우로 각각 80~120px씩 더 넓게 확장 배치해주세요.

구체적 CSS 방향:

  • 본문 컨테이너: max-width: 720px; margin: 0 auto;
  • 본문 내 이미지/figure: width: calc(100% + 200px); margin-left: -100px; margin-right: -100px; 또는 vw 단위 활용
  • 반응형에서는 모바일 기기일 때 이미지가 화면 폭 100%로 자연스럽게 리사이즈
  • 이미지는 border-radius: 0 (모서리 둥글림 없음), 깔끔한 직사각형 유지
  • 이미지 아래 캡션이 있을 경우, 캡션 텍스트는 본문 폭에 맞춰 정렬

2. H2 / H3 헤딩 태그 디자인

지시 내용:

H2 태그: 상단과 하단에 1px 실선(solid) 가로줄을 넣고, 텍스트는 그 사이에 배치합니다. 매우 미니멀한 스타일입니다.

.entry-content h2 {
  border-top: 1px solid #333;
  border-bottom: 1px solid #333;
  padding: 20px 0;
  margin: 60px 0 30px 0;
  font-size: 22px;
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -0.02em;
}

H3 태그: H2와 조화를 이루도록 왼쪽에만 3~4px 두께의 세로 줄(border-left)을 넣는 심플한 스타일로 디자인해주세요. (H2가 위아래 가로줄이니, H3는 방향을 바꿔 좌측 세로줄로 차별화)

.entry-content h3 {
  border-left: 4px solid #333;
  padding: 4px 0 4px 16px;
  margin: 40px 0 20px 0;
  font-size: 18px;
  font-weight: 700;
  line-height: 1.4;
}

전체적으로 다크 컬러(#222 ~ #333) 텍스트, 배경은 화이트, 장식 요소는 최소화합니다.


3. 하단 관련글(Related Posts) — 풀 와이드 그리드

지시 내용:

싱글 포스트 하단의 관련글 영역은 화면 전체 폭(full-width)을 사용합니다. 본문의 좁은 컨테이너를 벗어나 브라우저 전체 너비로 확장됩니다.

디자인 스펙:

  • 배경색: 다크(#1a1a1a ~ #222) — 본문 화이트 배경과 대비
  • 섹션 제목: "연관 기사" 형태, 중앙 정렬, 흰색 텍스트, 상단에 여백 충분히
  • 그리드: 4열(데스크탑), 카드 간 간격(gap) 약 20~24px
  • 각 카드 구성:
    • 썸네일 이미지 (16:9 비율, object-fit: cover)
    • 카테고리 라벨 (작은 태그/뱃지 형태, border 스타일)
    • 제목 (흰색, 2~3줄 말줄임)
    • 해시태그 목록 (회색 텍스트, 작은 폰트)
    • 날짜 (회색, 가장 하단)
  • 반응형: 태블릿 2열 → 모바일 1열
.related-posts-section {
  width: 100vw;
  margin-left: calc(-50vw + 50%);
  background: #1a1a1a;
  padding: 60px 40px;
}
.related-posts-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  max-width: 1280px;
  margin: 0 auto;
}

4. 상단 헤더 & 내비게이션 — 풀스크린 히어로 + 플로팅 네비

지시 내용:

싱글 포스트 상단 히어로 영역:

  • 대표 이미지(Featured Image)를 화면 전체 폭, 높이 약 70~80vh로 배경 처리
  • 이미지 위에 어두운 그라데이션 오버레이 (하단에서 상단으로 rgba(0,0,0,0.5)transparent) 적용
  • 오버레이 위에 카테고리 뱃지, 글 제목, 해시태그, 날짜, 작성자 등 메타정보를 흰색 텍스트로 표시
  • 제목은 큰 폰트(32~40px), font-weight: 700, 줄간격 1.3~1.4

글로벌 내비게이션:

  • 화면 최상단에 고정(fixed/sticky) 배치
  • 배경: 투명 → 스크롤 시 다크 배경(#000 또는 #111)으로 전환 (스크롤 이벤트 또는 backdrop-filter 활용)
  • 로고 중앙 배치, 메뉴 항목은 로고 좌우 대칭 또는 로고 아래 중앙 정렬
  • 메뉴 중 현재 활성 카테고리에는 하이라이트 배경(예: 빨간 라운드 뱃지) 적용
  • 우측에 검색 아이콘, 언어 전환 등 유틸 메뉴
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 1000;
  transition: background-color 0.3s ease;
}
.site-header.scrolled {
  background-color: rgba(0, 0, 0, 0.95);
}

5. 메인 페이지 인트로 — 풀스크린 그리드 최신글

지시 내용:

메인 페이지 상단은 "WHAT'S NEW" 섹션으로, 풀 와이드 다크 배경 위에 최신 글을 그리드로 나열합니다.

디자인 스펙:

  • 배경: 다크(#111 ~ #1a1a1a), 전체 화면 폭 사용
  • 섹션 타이틀: "WHAT'S NEW" — 대형 볼드 텍스트, 중앙 정렬, 세리프 또는 산세리프 대문자
  • 타이틀 하단에 카테고리 필터 탭 (All / FACT / PRESS / TECH&AI / STORY / IR 등) — 텍스트 버튼 형태, 선택 시 밑줄 또는 볼드 활성화
  • 카드 그리드: 4열 × 2행 = 8개 (또는 4열 × 3행 = 12개)
  • 카드 스타일은 관련글 영역과 동일 (썸네일 + 제목 + 카테고리 뱃지 + 해시태그 + 날짜)
  • 카드 호버 시 이미지 살짝 확대(transform: scale(1.05)) + 밝기 변화
.main-intro {
  background: #111;
  padding: 80px 40px;
  min-height: 100vh;
}
.main-intro h2 {
  font-size: 48px;
  font-weight: 800;
  color: #fff;
  text-align: center;
  margin-bottom: 30px;
}
.category-filter {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin-bottom: 40px;
}
.category-filter a {
  color: #888;
  text-decoration: none;
  font-size: 14px;
}
.category-filter a.active {
  color: #fff;
  border-bottom: 2px solid #fff;
}

6. 메인 하단 — "더보기" 페이징

지시 내용:

메인 페이지의 최신글 목록 하단에는 기존 페이지네이션(1, 2, 3...) 대신 "기사 더 보기" (Load More) 버튼을 중앙에 배치합니다.

디자인 스펙:

  • 버튼 스타일: 원형 아이콘(+) + 텍스트 조합 또는 텍스트만 심플하게
  • 참고 사이트는 (+) 기사 더 보기 형태 — 플러스 아이콘을 원형 테두리 안에 넣고 옆에 텍스트
  • 색상: 밝은 회색 텍스트, 호버 시 흰색으로 전환
  • 클릭 시 AJAX로 다음 글 묶음을 기존 그리드 아래에 추가 로드 (페이지 이동 없음)
  • 로딩 중일 때 버튼에 스피너 또는 로딩 애니메이션 표시
.load-more-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 60px auto;
  color: #888;
  font-size: 16px;
  cursor: pointer;
  transition: color 0.3s;
  background: none;
  border: none;
}
.load-more-btn:hover {
  color: #fff;
}
.load-more-btn .icon {
  width: 40px;
  height: 40px;
  border: 1px solid #555;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

워드프레스 구현 시: WP_Queryoffset/paged 파라미터와 wp_ajax 훅을 활용하여 REST API 또는 admin-ajax.php로 추가 글을 불러오는 방식으로 구현해주세요.


종합 — AI에게 한 번에 전달할 통합 프롬프트 (요약본)

아래는 위 내용을 하나의 지시서로 압축한 버전입니다. 실제 AI 코딩 도구에 붙여넣기 용도로 활용하세요:


워드프레스 테마 커스터마이징 요청

참고 디자인: SK Hynix Newsroom (news.skhynix.co.kr) 스타일

전체 톤: 다크 모드 기반, 미니멀, 뉴스룸/매거진 스타일. 본문은 화이트 배경.

① 싱글 포스트 본문

  • 콘텐츠 폭 720px, 이미지만 좌우 100px씩 확장 (약 920px)
  • 이미지는 직각 모서리, 캡션은 본문 폭 기준 정렬

② 헤딩 태그

  • H2: 위아래 1px 실선 border, 패딩 20px, 매우 심플
  • H3: 좌측 4px 세로선(border-left), 패딩-left 16px

③ 관련글 (싱글 하단)

  • Full-width 다크 배경, 4열 그리드 카드
  • 카드: 썸네일 + 카테고리 뱃지 + 제목 + 해시태그 + 날짜

④ 글 상단 히어로

  • Featured Image를 full-width 70~80vh 배경으로 사용
  • 어두운 그라데이션 오버레이 위에 제목/메타 정보 (흰색)
  • 내비게이션은 fixed, 투명 → 스크롤 시 다크 배경 전환

⑤ 메인 페이지

  • 다크 배경 풀스크린, "WHAT'S NEW" 타이틀 + 카테고리 필터 탭
  • 4열 그리드 최신글 카드, 호버 시 이미지 확대 효과

⑥ 더보기 버튼

  • 하단 중앙 (+) 아이콘 + "기사 더 보기" 텍스트
  • AJAX load more 방식, 페이지 이동 없이 추가 로드

H-Style 워드프레스 테마

파일 구조

h-style/
├── style.css
├── functions.php
├── index.php
├── front-page.php
├── single.php
├── header.php
├── footer.php
├── searchform.php
├── search.php
├── archive.php
├── 404.php
├── page.php
├── comments.php
├── sidebar.php
├── screenshot.png
├── template-parts/
│   ├── content-card.php
│   ├── content-none.php
│   └── related-posts.php
├── inc/
│   ├── customizer.php
│   ├── template-tags.php
│   └── ajax-load-more.php
├── assets/
│   ├── css/
│   │   ├── main.css
│   │   ├── single.css
│   │   ├── front-page.css
│   │   ├── header.css
│   │   ├── archive.css
│   │   └── responsive.css
│   ├── js/
│   │   ├── navigation.js
│   │   ├── load-more.js
│   │   └── hero-scroll.js
│   └── images/
│       └── default-thumbnail.jpg

1. style.css (테마 메타 + 기본 리셋)

/*
Theme Name: H-Style
Theme URI: https://example.com/h-style
Author: Your Name
Author URI: https://example.com
Description: SK Hynix Newsroom 스타일에서 영감을 받은 다크 매거진/뉴스룸 워드프레스 테마. 풀스크린 히어로, 다크 그리드 레이아웃, 미니멀 타이포그래피.
Version: 1.0.0
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: h-style
Tags: dark, magazine, newsroom, grid-layout, full-width, custom-header, featured-images, blog
*/

/* ========== RESET & BASE ========== */
*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    /* Colors */
    --color-bg-dark: #111111;
    --color-bg-darker: #0a0a0a;
    --color-bg-card: #1a1a1a;
    --color-bg-light: #ffffff;
    --color-text-primary: #ffffff;
    --color-text-secondary: #999999;
    --color-text-muted: #666666;
    --color-text-dark: #222222;
    --color-text-body: #444444;
    --color-border-light: #333333;
    --color-border-dark: #222222;
    --color-accent: #e63946;
    --color-accent-hover: #c1121f;

    /* Typography */
    --font-primary: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-heading: 'Pretendard', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-display: 'Playfair Display', Georgia, serif;

    /* Spacing */
    --content-width: 720px;
    --content-wide: 920px;
    --site-max-width: 1280px;
    --grid-gap: 24px;
    --section-padding: 80px 40px;

    /* Transitions */
    --transition-fast: 0.2s ease;
    --transition-normal: 0.3s ease;
    --transition-slow: 0.5s ease;
}

html {
    font-size: 16px;
    scroll-behavior: smooth;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    font-family: var(--font-primary);
    line-height: 1.7;
    color: var(--color-text-dark);
    background-color: var(--color-bg-light);
    overflow-x: hidden;
}

a {
    text-decoration: none;
    color: inherit;
    transition: color var(--transition-fast);
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

ul, ol {
    list-style: none;
}

button {
    cursor: pointer;
    border: none;
    background: none;
    font-family: inherit;
}

/* Screen Reader Text */
.screen-reader-text {
    border: 0;
    clip: rect(1px, 1px, 1px, 1px);
    clip-path: inset(50%);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute !important;
    width: 1px;
    word-wrap: normal !important;
}

2. functions.php

<?php
/**
 * H-Style Theme Functions
 *
 * @package H-Style
 * @version 1.0.0
 */

if (!defined('ABSPATH')) exit;

define('HSTYLE_VERSION', '1.0.0');
define('HSTYLE_DIR', get_template_directory());
define('HSTYLE_URI', get_template_directory_uri());

/**
 * Theme Setup
 */
function hstyle_setup() {
    // 번역 지원
    load_theme_textdomain('h-style', HSTYLE_DIR . '/languages');

    // HTML5 지원
    add_theme_support('html5', array(
        'search-form', 'comment-form', 'comment-list', 'gallery', 'caption', 'style', 'script'
    ));

    // 타이틀 태그
    add_theme_support('title-tag');

    // 썸네일 지원
    add_theme_support('post-thumbnails');

    // 이미지 사이즈
    add_image_size('hstyle-hero', 1920, 1080, true);
    add_image_size('hstyle-card', 600, 400, true);
    add_image_size('hstyle-card-large', 800, 500, true);

    // 메뉴 등록
    register_nav_menus(array(
        'primary' => __('주 내비게이션', 'h-style'),
        'footer'  => __('푸터 메뉴', 'h-style'),
    ));

    // 커스텀 로고
    add_theme_support('custom-logo', array(
        'height'      => 50,
        'width'       => 200,
        'flex-height' => true,
        'flex-width'  => true,
    ));

    // 에디터 스타일
    add_theme_support('editor-styles');
    add_editor_style('assets/css/editor-style.css');

    // 와이드/풀 정렬
    add_theme_support('align-wide');

    // 반응형 임베드
    add_theme_support('responsive-embeds');
}
add_action('after_setup_theme', 'hstyle_setup');

/**
 * 콘텐츠 폭 설정
 */
function hstyle_content_width() {
    $GLOBALS['content_width'] = apply_filters('hstyle_content_width', 720);
}
add_action('after_setup_theme', 'hstyle_content_width', 0);

/**
 * 스타일 & 스크립트 등록
 */
function hstyle_scripts() {
    // Google Fonts - Pretendard
    wp_enqueue_style(
        'pretendard-font',
        'https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/static/pretendard.min.css',
        array(),
        null
    );

    // Playfair Display (디스플레이용)
    wp_enqueue_style(
        'google-fonts-display',
        'https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;800;900&display=swap',
        array(),
        null
    );

    // 메인 스타일
    wp_enqueue_style('hstyle-main', HSTYLE_URI . '/style.css', array(), HSTYLE_VERSION);
    wp_enqueue_style('hstyle-header', HSTYLE_URI . '/assets/css/header.css', array('hstyle-main'), HSTYLE_VERSION);

    if (is_front_page()) {
        wp_enqueue_style('hstyle-front', HSTYLE_URI . '/assets/css/front-page.css', array('hstyle-main'), HSTYLE_VERSION);
    }

    if (is_singular()) {
        wp_enqueue_style('hstyle-single', HSTYLE_URI . '/assets/css/single.css', array('hstyle-main'), HSTYLE_VERSION);
    }

    if (is_archive() || is_search()) {
        wp_enqueue_style('hstyle-archive', HSTYLE_URI . '/assets/css/archive.css', array('hstyle-main'), HSTYLE_VERSION);
    }

    wp_enqueue_style('hstyle-responsive', HSTYLE_URI . '/assets/css/responsive.css', array('hstyle-main'), HSTYLE_VERSION);

    // 스크립트
    wp_enqueue_script('hstyle-navigation', HSTYLE_URI . '/assets/js/navigation.js', array(), HSTYLE_VERSION, true);

    if (is_front_page() || is_home() || is_archive()) {
        wp_enqueue_script('hstyle-load-more', HSTYLE_URI . '/assets/js/load-more.js', array('jquery'), HSTYLE_VERSION, true);
        wp_localize_script('hstyle-load-more', 'hstyleAjax', array(
            'ajaxurl'  => admin_url('admin-ajax.php'),
            'nonce'    => wp_create_nonce('hstyle_load_more'),
            'per_page' => get_option('posts_per_page'),
        ));
    }

    if (is_singular()) {
        wp_enqueue_script('hstyle-hero-scroll', HSTYLE_URI . '/assets/js/hero-scroll.js', array(), HSTYLE_VERSION, true);
        if (comments_open()) {
            wp_enqueue_script('comment-reply');
        }
    }
}
add_action('wp_enqueue_scripts', 'hstyle_scripts');

/**
 * 위젯 영역
 */
function hstyle_widgets_init() {
    register_sidebar(array(
        'name'          => __('푸터 위젯 1', 'h-style'),
        'id'            => 'footer-1',
        'before_widget' => '<div id="%1$s" class="widget %2$s">',
        'after_widget'  => '</div>',
        'before_title'  => '<h4 class="widget-title">',
        'after_title'   => '</h4>',
    ));

    register_sidebar(array(
        'name'          => __('푸터 위젯 2', 'h-style'),
        'id'            => 'footer-2',
        'before_widget' => '<div id="%1$s" class="widget %2$s">',
        'after_widget'  => '</div>',
        'before_title'  => '<h4 class="widget-title">',
        'after_title'   => '</h4>',
    ));
}
add_action('widgets_init', 'hstyle_widgets_init');

/**
 * 발췌문 길이
 */
function hstyle_excerpt_length($length) {
    return 20;
}
add_filter('excerpt_length', 'hstyle_excerpt_length');

function hstyle_excerpt_more($more) {
    return '…';
}
add_filter('excerpt_more', 'hstyle_excerpt_more');

/**
 * Include files
 */
require HSTYLE_DIR . '/inc/customizer.php';
require HSTYLE_DIR . '/inc/template-tags.php';
require HSTYLE_DIR . '/inc/ajax-load-more.php';

3. header.php

<?php
/**
 * Header Template
 * 
 * @package H-Style
 */
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="profile" href="https://gmpg.org/xfn/11">
    <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>

<div id="page" class="site">
    <a class="skip-link screen-reader-text" href="#content">
        <?php esc_html_e('콘텐츠로 건너뛰기', 'h-style'); ?>
    </a>

    <!-- Fixed Navigation -->
    <header id="masthead" class="site-header">
        <div class="header-inner">
            <!-- Logo -->
            <div class="site-branding">
                <?php if (has_custom_logo()) : ?>
                    <?php the_custom_logo(); ?>
                <?php else : ?>
                    <a href="<?php echo esc_url(home_url('/')); ?>" class="site-title-link">
                        <span class="site-title"><?php bloginfo('name'); ?></span>
                    </a>
                <?php endif; ?>
            </div>

            <!-- Primary Navigation -->
            <nav id="site-navigation" class="main-navigation" aria-label="<?php esc_attr_e('주 메뉴', 'h-style'); ?>">
                <?php
                wp_nav_menu(array(
                    'theme_location' => 'primary',
                    'menu_class'     => 'primary-menu',
                    'container'      => false,
                    'depth'          => 2,
                    'fallback_cb'    => 'hstyle_fallback_menu',
                ));
                ?>
            </nav>

            <!-- Utility -->
            <div class="header-utility">
                <button class="search-toggle" aria-label="<?php esc_attr_e('검색', 'h-style'); ?>">
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <circle cx="11" cy="11" r="8"></circle>
                        <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
                    </svg>
                </button>
                <button class="menu-toggle" aria-label="<?php esc_attr_e('메뉴', 'h-style'); ?>" aria-expanded="false">
                    <span class="hamburger">
                        <span></span>
                        <span></span>
                        <span></span>
                    </span>
                </button>
            </div>
        </div>

        <!-- Search Overlay -->
        <div class="search-overlay" aria-hidden="true">
            <div class="search-overlay-inner">
                <?php get_search_form(); ?>
                <button class="search-close" aria-label="<?php esc_attr_e('검색 닫기', 'h-style'); ?>">
                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <line x1="18" y1="6" x2="6" y2="18"></line>
                        <line x1="6" y1="6" x2="18" y2="18"></line>
                    </svg>
                </button>
            </div>
        </div>
    </header>

    <div id="content" class="site-content">

4. footer.php

<?php
/**
 * Footer Template
 *
 * @package H-Style
 */
?>
    </div><!-- #content -->

    <footer id="colophon" class="site-footer">
        <div class="footer-inner">
            <!-- Footer Top -->
            <div class="footer-top">
                <div class="footer-branding">
                    <?php if (has_custom_logo()) : ?>
                        <?php the_custom_logo(); ?>
                    <?php else : ?>
                        <a href="<?php echo esc_url(home_url('/')); ?>" class="footer-logo-text">
                            <?php bloginfo('name'); ?>
                        </a>
                    <?php endif; ?>
                    <p class="footer-description"><?php bloginfo('description'); ?></p>
                </div>

                <?php if (has_nav_menu('footer')) : ?>
                <nav class="footer-navigation" aria-label="<?php esc_attr_e('푸터 메뉴', 'h-style'); ?>">
                    <?php
                    wp_nav_menu(array(
                        'theme_location' => 'footer',
                        'menu_class'     => 'footer-menu',
                        'container'      => false,
                        'depth'          => 1,
                    ));
                    ?>
                </nav>
                <?php endif; ?>

                <div class="footer-widgets">
                    <?php if (is_active_sidebar('footer-1')) : ?>
                        <div class="footer-widget-area">
                            <?php dynamic_sidebar('footer-1'); ?>
                        </div>
                    <?php endif; ?>

                    <?php if (is_active_sidebar('footer-2')) : ?>
                        <div class="footer-widget-area">
                            <?php dynamic_sidebar('footer-2'); ?>
                        </div>
                    <?php endif; ?>
                </div>
            </div>

            <!-- Footer Bottom -->
            <div class="footer-bottom">
                <p class="copyright">
                    &copy; <?php echo date('Y'); ?> <?php bloginfo('name'); ?>. All rights reserved.
                </p>
                <button class="back-to-top" aria-label="<?php esc_attr_e('맨 위로', 'h-style'); ?>">
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <polyline points="18 15 12 9 6 15"></polyline>
                    </svg>
                </button>
            </div>
        </div>
    </footer>
</div><!-- #page -->

<?php wp_footer(); ?>
</body>
</html>

5. front-page.php (메인 페이지)

<?php
/**
 * Front Page Template
 * 풀스크린 다크 그리드 메인
 *
 * @package H-Style
 */

get_header();

// 최신 글 쿼리
$per_page = get_option('posts_per_page', 8);
$featured_query = new WP_Query(array(
    'posts_per_page' => $per_page,
    'post_status'    => 'publish',
    'ignore_sticky_posts' => true,
));

// 카테고리 목록 (필터 탭용)
$categories = get_categories(array(
    'orderby'    => 'count',
    'order'      => 'DESC',
    'hide_empty' => true,
    'number'     => 6,
));
?>

<!-- Hero / What's New Section -->
<section class="main-hero-section">
    <div class="main-hero-inner">
        <!-- Section Title -->
        <h2 class="main-section-title">WHAT'S NEW</h2>

        <!-- Category Filter Tabs -->
        <div class="category-filter" role="tablist">
            <button class="filter-tab active" data-category="all" role="tab" aria-selected="true">
                All
            </button>
            <?php foreach ($categories as $cat) : ?>
                <button class="filter-tab" data-category="<?php echo esc_attr($cat->slug); ?>" role="tab" aria-selected="false">
                    <?php echo esc_html($cat->name); ?>
                </button>
            <?php endforeach; ?>
        </div>

        <!-- Posts Grid -->
        <?php if ($featured_query->have_posts()) : ?>
            <div class="posts-grid" id="main-posts-grid">
                <?php while ($featured_query->have_posts()) : $featured_query->the_post(); ?>
                    <?php get_template_part('template-parts/content', 'card'); ?>
                <?php endwhile; ?>
            </div>

            <!-- Load More -->
            <?php if ($featured_query->max_num_pages > 1) : ?>
                <div class="load-more-wrapper">
                    <button class="load-more-btn" data-page="1" data-max="<?php echo esc_attr($featured_query->max_num_pages); ?>">
                        <span class="load-more-icon">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <line x1="12" y1="5" x2="12" y2="19"></line>
                                <line x1="5" y1="12" x2="19" y2="12"></line>
                            </svg>
                        </span>
                        <span class="load-more-text"><?php esc_html_e('기사 더 보기', 'h-style'); ?></span>
                    </button>
                </div>
            <?php endif; ?>

        <?php else : ?>
            <?php get_template_part('template-parts/content', 'none'); ?>
        <?php endif; ?>

        <?php wp_reset_postdata(); ?>
    </div>
</section>

<?php get_footer(); ?>

6. single.php (글 보기)

<?php
/**
 * Single Post Template
 * 풀스크린 히어로 + 확장 이미지 본문
 *
 * @package H-Style
 */

get_header();

while (have_posts()) : the_post();
    $featured_img_url = get_the_post_thumbnail_url(get_the_ID(), 'hstyle-hero');
    $categories = get_the_category();
    $tags = get_the_tags();
?>

<!-- Hero Section -->
<article id="post-<?php the_ID(); ?>" <?php post_class('single-article'); ?>>
    <header class="single-hero" <?php if ($featured_img_url) : ?>style="background-image: url('<?php echo esc_url($featured_img_url); ?>');"<?php endif; ?>>
        <div class="hero-overlay"></div>
        <div class="hero-content">
            <?php if ($categories) : ?>
                <div class="hero-category">
                    <?php foreach (array_slice($categories, 0, 2) as $cat) : ?>
                        <a href="<?php echo esc_url(get_category_link($cat->term_id)); ?>" class="category-badge">
                            <?php echo esc_html($cat->name); ?>
                        </a>
                    <?php endforeach; ?>
                </div>
            <?php endif; ?>

            <h1 class="single-title"><?php the_title(); ?></h1>

            <div class="hero-meta">
                <?php if ($tags) : ?>
                    <div class="hero-tags">
                        <?php foreach (array_slice($tags, 0, 5) as $tag) : ?>
                            <a href="<?php echo esc_url(get_tag_link($tag->term_id)); ?>" class="tag-link">
                                #<?php echo esc_html($tag->name); ?>
                            </a>
                        <?php endforeach; ?>
                    </div>
                <?php endif; ?>

                <div class="hero-date-author">
                    <time datetime="<?php echo get_the_date('c'); ?>">
                        <?php echo get_the_date('Y-m-d'); ?>
                    </time>
                    <span class="meta-separator">|</span>
                    <span class="author"><?php the_author(); ?></span>
                </div>
            </div>

            <!-- AI 요약 / 공유 버튼 영역 -->
            <div class="hero-actions">
                <button class="share-btn" aria-label="<?php esc_attr_e('공유하기', 'h-style'); ?>">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                        <circle cx="18" cy="5" r="3"></circle>
                        <circle cx="6" cy="12" r="3"></circle>
                        <circle cx="18" cy="19" r="3"></circle>
                        <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line>
                        <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line>
                    </svg>
                </button>
            </div>
        </div>
    </header>

    <!-- Article Content -->
    <div class="single-content-wrapper">
        <div class="single-content entry-content">
            <?php the_content(); ?>
        </div>

        <!-- Post Navigation -->
        <nav class="post-navigation">
            <div class="nav-links">
                <?php
                $prev_post = get_previous_post();
                $next_post = get_next_post();
                ?>
                <?php if ($prev_post) : ?>
                    <a href="<?php echo get_permalink($prev_post); ?>" class="nav-previous">
                        <span class="nav-label"><?php esc_html_e('이전 글', 'h-style'); ?></span>
                        <span class="nav-title"><?php echo esc_html($prev_post->post_title); ?></span>
                    </a>
                <?php endif; ?>

                <?php if ($next_post) : ?>
                    <a href="<?php echo get_permalink($next_post); ?>" class="nav-next">
                        <span class="nav-label"><?php esc_html_e('다음 글', 'h-style'); ?></span>
                        <span class="nav-title"><?php echo esc_html($next_post->post_title); ?></span>
                    </a>
                <?php endif; ?>
            </div>
        </nav>

        <!-- Comments -->
        <?php if (comments_open() || get_comments_number()) : ?>
            <div class="comments-area-wrapper">
                <?php comments_template(); ?>
            </div>
        <?php endif; ?>
    </div>

    <!-- Related Posts (Full Width Dark) -->
    <?php get_template_part('template-parts/related', 'posts'); ?>

</article>

<?php endwhile; ?>

<?php get_footer(); ?>

7. template-parts/content-card.php

<?php
/**
 * Card Template Part
 * 그리드 카드 아이템
 *
 * @package H-Style
 */

$categories = get_the_category();
$tags = get_the_tags();
?>

<article <?php post_class('card-item'); ?> data-category="<?php echo $categories ? esc_attr($categories[0]->slug) : ''; ?>">
    <a href="<?php the_permalink(); ?>" class="card-link" aria-label="<?php the_title_attribute(); ?>">
        <div class="card-thumbnail">
            <?php if (has_post_thumbnail()) : ?>
                <?php the_post_thumbnail('hstyle-card', array('loading' => 'lazy')); ?>
            <?php else : ?>
                <div class="card-no-thumb">
                    <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="#555" stroke-width="1">
                        <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                        <circle cx="8.5" cy="8.5" r="1.5"></circle>
                        <polyline points="21 15 16 10 5 21"></polyline>
                    </svg>
                </div>
            <?php endif; ?>
        </div>

        <div class="card-body">
            <?php if ($categories) : ?>
                <div class="card-category">
                    <span class="category-badge">
                        <?php echo esc_html($categories[0]->name); ?>
                    </span>
                </div>
            <?php endif; ?>

            <h3 class="card-title"><?php the_title(); ?></h3>

            <?php if ($tags) : ?>
                <div class="card-tags">
                    <?php foreach (array_slice($tags, 0, 4) as $tag) : ?>
                        <span class="card-tag">#<?php echo esc_html($tag->name); ?></span>
                    <?php endforeach; ?>
                </div>
            <?php endif; ?>

            <time class="card-date" datetime="<?php echo get_the_date('c'); ?>">
                <?php echo get_the_date('Y-m-d'); ?>
            </time>
        </div>
    </a>
</article>

8. template-parts/related-posts.php

<?php
/**
 * Related Posts Section
 * 풀 와이드 다크 배경 관련글
 *
 * @package H-Style
 */

$categories = get_the_category();
if (!$categories) return;

$cat_ids = array_map(function($cat) { return $cat->term_id; }, $categories);

$related = new WP_Query(array(
    'category__in'        => $cat_ids,
    'post__not_in'        => array(get_the_ID()),
    'posts_per_page'      => 4,
    'ignore_sticky_posts' => true,
    'orderby'             => 'rand',
));

if (!$related->have_posts()) return;
?>

<section class="related-posts-section">
    <div class="related-posts-inner">
        <h2 class="related-title"><?php esc_html_e('연관 기사', 'h-style'); ?></h2>

        <div class="related-posts-grid">
            <?php while ($related->have_posts()) : $related->the_post(); ?>
                <?php get_template_part('template-parts/content', 'card'); ?>
            <?php endwhile; ?>
        </div>
    </div>
    <?php wp_reset_postdata(); ?>
</section>

9. template-parts/content-none.php

<?php
/**
 * No Content Template Part
 *
 * @package H-Style
 */
?>

<div class="no-results">
    <h2 class="no-results-title">
        <?php esc_html_e('게시글이 없습니다', 'h-style'); ?>
    </h2>
    <p class="no-results-desc">
        <?php esc_html_e('아직 등록된 게시글이 없습니다. 곧 새로운 콘텐츠가 업데이트됩니다.', 'h-style'); ?>
    </p>
</div>

10. index.php

<?php
/**
 * Main Index Template
 *
 * @package H-Style
 */

get_header();
?>

<section class="main-hero-section">
    <div class="main-hero-inner">
        <h2 class="main-section-title">
            <?php
            if (is_home() && !is_front_page()) {
                single_post_title();
            } else {
                esc_html_e("WHAT'S NEW", 'h-style');
            }
            ?>
        </h2>

        <?php if (have_posts()) : ?>
            <div class="posts-grid" id="main-posts-grid">
                <?php while (have_posts()) : the_post(); ?>
                    <?php get_template_part('template-parts/content', 'card'); ?>
                <?php endwhile; ?>
            </div>

            <?php if ($wp_query->max_num_pages > 1) : ?>
                <div class="load-more-wrapper">
                    <button class="load-more-btn" data-page="1" data-max="<?php echo esc_attr($wp_query->max_num_pages); ?>">
                        <span class="load-more-icon">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <line x1="12" y1="5" x2="12" y2="19"></line>
                                <line x1="5" y1="12" x2="19" y2="12"></line>
                            </svg>
                        </span>
                        <span class="load-more-text"><?php esc_html_e('기사 더 보기', 'h-style'); ?></span>
                    </button>
                </div>
            <?php endif; ?>

        <?php else : ?>
            <?php get_template_part('template-parts/content', 'none'); ?>
        <?php endif; ?>
    </div>
</section>

<?php get_footer(); ?>

11. archive.php

<?php
/**
 * Archive Template
 *
 * @package H-Style
 */

get_header();
?>

<section class="main-hero-section">
    <div class="main-hero-inner">
        <header class="archive-header">
            <?php the_archive_title('<h2 class="main-section-title">', '</h2>'); ?>
            <?php the_archive_description('<p class="archive-description">', '</p>'); ?>
        </header>

        <?php if (have_posts()) : ?>
            <div class="posts-grid" id="main-posts-grid">
                <?php while (have_posts()) : the_post(); ?>
                    <?php get_template_part('template-parts/content', 'card'); ?>
                <?php endwhile; ?>
            </div>

            <?php if ($wp_query->max_num_pages > 1) : ?>
                <div class="load-more-wrapper">
                    <button class="load-more-btn" data-page="1" data-max="<?php echo esc_attr($wp_query->max_num_pages); ?>">
                        <span class="load-more-icon">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <line x1="12" y1="5" x2="12" y2="19"></line>
                                <line x1="5" y1="12" x2="19" y2="12"></line>
                            </svg>
                        </span>
                        <span class="load-more-text"><?php esc_html_e('기사 더 보기', 'h-style'); ?></span>
                    </button>
                </div>
            <?php endif; ?>

        <?php else : ?>
            <?php get_template_part('template-parts/content', 'none'); ?>
        <?php endif; ?>
    </div>
</section>

<?php get_footer(); ?>

12. page.php

<?php
/**
 * Page Template
 *
 * @package H-Style
 */

get_header();

while (have_posts()) : the_post();
    $featured_img_url = get_the_post_thumbnail_url(get_the_ID(), 'hstyle-hero');
?>

<article id="post-<?php the_ID(); ?>" <?php post_class('single-article page-article'); ?>>
    <header class="single-hero" <?php if ($featured_img_url) : ?>style="background-image: url('<?php echo esc_url($featured_img_url); ?>');"<?php endif; ?>>
        <div class="hero-overlay"></div>
        <div class="hero-content">
            <h1 class="single-title"><?php the_title(); ?></h1>
        </div>
    </header>

    <div class="single-content-wrapper">
        <div class="single-content entry-content">
            <?php the_content(); ?>
        </div>
    </div>
</article>

<?php endwhile; ?>

<?php get_footer(); ?>

13. search.php

<?php
/**
 * Search Results Template
 *
 * @package H-Style
 */

get_header();
?>

<section class="main-hero-section">
    <div class="main-hero-inner">
        <h2 class="main-section-title">
            <?php printf(esc_html__('"%s" 검색 결과', 'h-style'), get_search_query()); ?>
        </h2>

        <?php if (have_posts()) : ?>
            <div class="posts-grid" id="main-posts-grid">
                <?php while (have_posts()) : the_post(); ?>
                    <?php get_template_part('template-parts/content', 'card'); ?>
                <?php endwhile; ?>
            </div>

            <?php if ($wp_query->max_num_pages > 1) : ?>
                <div class="load-more-wrapper">
                    <button class="load-more-btn" data-page="1" data-max="<?php echo esc_attr($wp_query->max_num_pages); ?>" data-search="<?php echo esc_attr(get_search_query()); ?>">
                        <span class="load-more-icon">
                            <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
                                <line x1="12" y1="5" x2="12" y2="19"></line>
                                <line x1="5" y1="12" x2="19" y2="12"></line>
                            </svg>
                        </span>
                        <span class="load-more-text"><?php esc_html_e('더 보기', 'h-style'); ?></span>
                    </button>
                </div>
            <?php endif; ?>

        <?php else : ?>
            <div class="no-results">
                <h3 class="no-results-title"><?php esc_html_e('검색 결과가 없습니다', 'h-style'); ?></h3>
                <p class="no-results-desc"><?php esc_html_e('다른 검색어로 시도해보세요.', 'h-style'); ?></p>
                <?php get_search_form(); ?>
            </div>
        <?php endif; ?>
    </div>
</section>

<?php get_footer(); ?>

14. searchform.php

<?php
/**
 * Search Form Template
 *
 * @package H-Style
 */
?>

<form role="search" method="get" class="search-form" action="<?php echo esc_url(home_url('/')); ?>">
    <label class="screen-reader-text" for="search-field">
        <?php esc_html_e('검색:', 'h-style'); ?>
    </label>
    <input type="search" id="search-field" class="search-field" 
           placeholder="<?php esc_attr_e('검색어를 입력하세요…', 'h-style'); ?>" 
           value="<?php echo get_search_query(); ?>" 
           name="s" 
           autocomplete="off" />
    <button type="submit" class="search-submit" aria-label="<?php esc_attr_e('검색', 'h-style'); ?>">
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <circle cx="11" cy="11" r="8"></circle>
            <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
        </svg>
    </button>
</form>

15. 404.php

<?php
/**
 * 404 Template
 *
 * @package H-Style
 */

get_header();
?>

<section class="error-404-section">
    <div class="error-404-inner">
        <h1 class="error-code">404</h1>
        <h2 class="error-title"><?php esc_html_e('페이지를 찾을 수 없습니다', 'h-style'); ?></h2>
        <p class="error-desc"><?php esc_html_e('요청하신 페이지가 존재하지 않거나 이동되었을 수 있습니다.', 'h-style'); ?></p>
        <a href="<?php echo esc_url(home_url('/')); ?>" class="error-home-link">
            <?php esc_html_e('홈으로 돌아가기', 'h-style'); ?>
        </a>
    </div>
</section>

<?php get_footer(); ?>

16. comments.php

<?php
/**
 * Comments Template
 *
 * @package H-Style
 */

if (post_password_required()) return;
?>

<div id="comments" class="comments-area">
    <?php if (have_comments()) : ?>
        <h3 class="comments-title">
            <?php
            printf(
                esc_html(_n('댓글 %d개', '댓글 %d개', get_comments_number(), 'h-style')),
                get_comments_number()
            );
            ?>
        </h3>

        <ol class="comment-list">
            <?php
            wp_list_comments(array(
                'style'      => 'ol',
                'short_ping' => true,
                'avatar_size' => 50,
            ));
            ?>
        </ol>

        <?php the_comments_navigation(); ?>
    <?php endif; ?>

    <?php
    comment_form(array(
        'title_reply'          => __('댓글 남기기', 'h-style'),
        'title_reply_to'       => __('%s에게 답글', 'h-style'),
        'cancel_reply_link'    => __('답글 취소', 'h-style'),
        'label_submit'         => __('댓글 작성', 'h-style'),
        'comment_notes_before' => '',
    ));
    ?>
</div>

17. sidebar.php

<?php
/**
 * Sidebar (minimal - 이 테마는 사이드바 없는 풀 레이아웃)
 *
 * @package H-Style
 */

if (!is_active_sidebar('sidebar-1')) return;
?>

<aside id="secondary" class="widget-area" role="complementary">
    <?php dynamic_sidebar('sidebar-1'); ?>
</aside>

18. assets/css/header.css

/* ========== HEADER & NAVIGATION ========== */

.site-header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 9999;
    background-color: transparent;
    transition: background-color var(--transition-normal), box-shadow var(--transition-normal);
}

.site-header.scrolled {
    background-color: rgba(0, 0, 0, 0.95);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.05);
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    max-width: var(--site-max-width);
    margin: 0 auto;
    padding: 0 40px;
    height: 70px;
}

/* Branding */
.site-branding {
    flex-shrink: 0;
}

.site-title-link {
    display: flex;
    align-items: center;
}

.site-title {
    font-size: 20px;
    font-weight: 800;
    color: var(--color-text-primary);
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.custom-logo-link img {
    height: 36px;
    width: auto;
}

/* Navigation */
.main-navigation {
    flex: 1;
    display: flex;
    justify-content: center;
}

.primary-menu {
    display: flex;
    align-items: center;
    gap: 8px;
}

.primary-menu li {
    position: relative;
}

.primary-menu li a {
    display: block;
    padding: 8px 16px;
    font-size: 14px;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.8);
    letter-spacing: 0.02em;
    border-radius: 20px;
    transition: all var(--transition-fast);
}

.primary-menu li a:hover,
.primary-menu li.current-menu-item > a,
.primary-menu li.current_page_item > a {
    color: #fff;
    background-color: var(--color-accent);
}

/* Submenu */
.primary-menu li .sub-menu {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%) translateY(10px);
    min-width: 180px;
    background: rgba(20, 20, 20, 0.98);
    backdrop-filter: blur(10px);
    border-radius: 8px;
    padding: 8px 0;
    opacity: 0;
    visibility: hidden;
    transition: all var(--transition-fast);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
}

.primary-menu li:hover > .sub-menu {
    opacity: 1;
    visibility: visible;
    transform: translateX(-50%) translateY(0);
}

.primary-menu li .sub-menu li a {
    padding: 10px 20px;
    font-size: 13px;
    font-weight: 500;
    border-radius: 0;
    color: rgba(255, 255, 255, 0.7);
}

.primary-menu li .sub-menu li a:hover {
    color: #fff;
    background-color: rgba(255, 255, 255, 0.08);
}

/* Utility */
.header-utility {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-shrink: 0;
}

.search-toggle,
.menu-toggle {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: rgba(255, 255, 255, 0.8);
    border-radius: 50%;
    transition: all var(--transition-fast);
}

.search-toggle:hover,
.menu-toggle:hover {
    color: #fff;
    background-color: rgba(255, 255, 255, 0.1);
}

/* Hamburger */
.hamburger {
    display: flex;
    flex-direction: column;
    gap: 5px;
    width: 20px;
}

.hamburger span {
    display: block;
    height: 2px;
    background: currentColor;
    border-radius: 1px;
    transition: all var(--transition-fast);
}

.menu-toggle {
    display: none;
}

/* Search Overlay */
.search-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.95);
    z-index: 10000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: all var(--transition-normal);
}

.search-overlay.active {
    opacity: 1;
    visibility: visible;
}

.search-overlay-inner {
    width: 100%;
    max-width: 600px;
    padding: 0 40px;
    position: relative;
}

.search-overlay .search-form {
    display: flex;
    align-items: center;
    border-bottom: 2px solid #fff;
    padding-bottom: 12px;
}

.search-overlay .search-field {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: #fff;
    font-size: 24px;
    font-family: var(--font-primary);
    font-weight: 300;
}

.search-overlay .search-field::placeholder {
    color: rgba(255, 255, 255, 0.4);
}

.search-overlay .search-submit {
    color: #fff;
    background: none;
    border: none;
    cursor: pointer;
}

.search-close {
    position: absolute;
    top: -60px;
    right: 40px;
    color: #fff;
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
}

19. assets/css/front-page.css

/* ========== FRONT PAGE / MAIN ========== */

.main-hero-section {
    background: var(--color-bg-dark);
    min-height: 100vh;
    padding: 120px 40px 80px;
}

.main-hero-inner {
    max-width: var(--site-max-width);
    margin: 0 auto;
}

/* Section Title */
.main-section-title {
    font-family: var(--font-display);
    font-size: 52px;
    font-weight: 800;
    color: var(--color-text-primary);
    text-align: center;
    margin-bottom: 36px;
    letter-spacing: 0.02em;
}

/* Category Filter */
.category-filter {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 28px;
    margin-bottom: 50px;
    flex-wrap: wrap;
}

.filter-tab {
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-secondary);
    padding: 6px 2px;
    border-bottom: 2px solid transparent;
    transition: all var(--transition-fast);
    letter-spacing: 0.02em;
    background: none;
    cursor: pointer;
}

.filter-tab:hover {
    color: var(--color-text-primary);
}

.filter-tab.active {
    color: var(--color-text-primary);
    border-bottom-color: var(--color-text-primary);
}

/* Posts Grid */
.posts-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--grid-gap);
}

/* Card Item */
.card-item {
    border-radius: 0;
    overflow: hidden;
    transition: transform var(--transition-normal);
}

.card-link {
    display: block;
    height: 100%;
}

.card-thumbnail {
    position: relative;
    padding-top: 66.67%; /* 3:2 ratio */
    overflow: hidden;
    background: var(--color-bg-card);
}

.card-thumbnail img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--transition-slow), opacity var(--transition-normal);
}

.card-item:hover .card-thumbnail img {
    transform: scale(1.05);
    opacity: 0.85;
}

.card-no-thumb {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-bg-card);
}

/* Card Body */
.card-body {
    padding: 20px 4px;
}

.card-category {
    margin-bottom: 10px;
}

.category-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    color: var(--color-text-secondary);
    border: 1px solid var(--color-border-light);
    padding: 3px 10px;
    border-radius: 3px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.card-title {
    font-size: 16px;
    font-weight: 700;
    color: var(--color-text-primary);
    line-height: 1.5;
    margin-bottom: 12px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    transition: color var(--transition-fast);
}

.card-item:hover .card-title {
    color: rgba(255, 255, 255, 0.8);
}

.card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}

.card-tag {
    font-size: 12px;
    color: var(--color-text-muted);
    font-weight: 400;
}

.card-date {
    font-size: 12px;
    color: var(--color-text-muted);
    display: block;
}

/* Archive Description */
.archive-header {
    text-align: center;
    margin-bottom: 20px;
}

.archive-description {
    color: var(--color-text-secondary);
    font-size: 15px;
    margin-top: 12px;
}

/* Load More */
.load-more-wrapper {
    display: flex;
    justify-content: center;
    margin-top: 60px;
}

.load-more-btn {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--color-text-secondary);
    font-size: 15px;
    font-weight: 500;
    cursor: pointer;
    transition: color var(--transition-fast);
    padding: 12px 24px;
}

.load-more-btn:hover {
    color: var(--color-text-primary);
}

.load-more-icon {
    width: 44px;
    height: 44px;
    border: 1px solid var(--color-border-light);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: border-color var(--transition-fast);
}

.load-more-btn:hover .load-more-icon {
    border-color: var(--color-text-primary);
}

.load-more-btn.loading .load-more-icon {
    animation: spin 1s linear infinite;
}

@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* No Results */
.no-results {
    text-align: center;
    padding: 100px 20px;
}

.no-results-title {
    font-size: 28px;
    font-weight: 700;
    color: var(--color-text-primary);
    margin-bottom: 16px;
}

.no-results-desc {
    font-size: 15px;
    color: var(--color-text-secondary);
}

.no-results .search-form {
    max-width: 400px;
    margin: 30px auto 0;
    display: flex;
    border-bottom: 1px solid var(--color-border-light);
    padding-bottom: 8px;
}

.no-results .search-field {
    flex: 1;
    background: transparent;
    border: none;
    outline: none;
    color: #fff;
    font-size: 16px;
    font-family: var(--font-primary);
}

.no-results .search-submit {
    color: var(--color-text-secondary);
}

20. assets/css/single.css

/* ========== SINGLE POST ========== */

/* Hero */
.single-hero {
    position: relative;
    width: 100%;
    min-height: 75vh;
    display: flex;
    align-items: flex-end;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    background-color: var(--color-bg-dark);
}

.hero-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.1) 0%,
        rgba(0, 0, 0, 0.3) 40%,
        rgba(0, 0, 0, 0.7) 80%,
        rgba(0, 0, 0, 0.85) 100%
    );
    z-index: 1;
}

.hero-content {
    position: relative;
    z-index: 2;
    max-width: 900px;
    padding: 60px 60px 60px;
    width: 100%;
}

/* Category Badge in Hero */
.hero-category {
    display: flex;
    gap: 8px;
    margin-bottom: 20px;
}

.hero-category .category-badge {
    font-size: 12px;
    font-weight: 600;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.5);
    padding: 5px 14px;
    border-radius: 3px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.hero-category .category-badge:hover {
    background: rgba(255, 255, 255, 0.15);
}

/* Title */
.single-title {
    font-size: 38px;
    font-weight: 800;
    color: #fff;
    line-height: 1.35;
    letter-spacing: -0.02em;
    margin-bottom: 24px;
}

/* Hero Meta */
.hero-meta {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.hero-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.tag-link {
    font-size: 13px;
    color: rgba(255, 255, 255, 0.6);
    transition: color var(--transition-fast);
}

.tag-link:hover {
    color: #fff;
}

.hero-date-author {
    font-size: 14px;
    color: rgba(255, 255, 255, 0.5);
    display: flex;
    align-items: center;
    gap: 10px;
}

.meta-separator {
    opacity: 0.4;
}

.hero-actions {
    position: absolute;
    bottom: 60px;
    right: 60px;
}

.share-btn {
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.3);
    color: rgba(255, 255, 255, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all var(--transition-fast);
}

.share-btn:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.6);
    color: #fff;
}

/* Content Wrapper */
.single-content-wrapper {
    max-width: var(--content-width);
    margin: 0 auto;
    padding: 60px 20px 80px;
}

/* Entry Content - Typography */
.entry-content {
    font-size: 17px;
    line-height: 1.85;
    color: var(--color-text-body);
    word-break: keep-all;
    overflow-wrap: break-word;
}

.entry-content p {
    margin-bottom: 28px;
}

.entry-content a {
    color: var(--color-accent);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.entry-content a:hover {
    color: var(--color-accent-hover);
}

/* H2 - 위아래 실선 */
.entry-content h2 {
    border-top: 1px solid #333;
    border-bottom: 1px solid #333;
    padding: 22px 0;
    margin: 64px 0 32px 0;
    font-size: 22px;
    font-weight: 700;
    line-height: 1.45;
    letter-spacing: -0.02em;
    color: var(--color-text-dark);
}

/* H3 - 좌측 세로줄 */
.entry-content h3 {
    border-left: 4px solid #333;
    padding: 4px 0 4px 18px;
    margin: 48px 0 24px 0;
    font-size: 19px;
    font-weight: 700;
    line-height: 1.45;
    color: var(--color-text-dark);
}

.entry-content h4 {
    font-size: 17px;
    font-weight: 700;
    margin: 36px 0 16px 0;
    color: var(--color-text-dark);
}

/* 이미지 확장 */
.entry-content img,
.entry-content figure {
    width: calc(100% + 200px);
    max-width: calc(100% + 200px);
    margin-left: -100px;
    margin-right: -100px;
    border-radius: 0;
}

.entry-content figure {
    margin-bottom: 32px;
}

.entry-content figure img {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
}

.entry-content figcaption {
    font-size: 13px;
    color: var(--color-text-muted);
    text-align: center;
    padding: 12px 100px 0;
    line-height: 1.5;
}

/* Blockquote */
.entry-content blockquote {
    border-left: 4px solid var(--color-accent);
    padding: 20px 24px;
    margin: 36px 0;
    background: #f8f8f8;
    font-style: italic;
    color: #555;
}

.entry-content blockquote p:last-child {
    margin-bottom: 0;
}

/* Lists */
.entry-content ul,
.entry-content ol {
    margin: 24px 0;
    padding-left: 28px;
}

.entry-content ul {
    list-style: disc;
}

.entry-content ol {
    list-style: decimal;
}

.entry-content li {
    margin-bottom: 8px;
    line-height: 1.7;
}

/* Code */
.entry-content code {
    background: #f4f4f4;
    padding: 2px 6px;
    border-radius: 3px;
    font-size: 14px;
    color: var(--color-accent);
}

.entry-content pre {
    background: #1e1e1e;
    color: #d4d4d4;
    padding: 24px;
    border-radius: 6px;
    overflow-x: auto;
    margin: 32px 0;
    font-size: 14px;
    line-height: 1.6;
}

.entry-content pre code {
    background: none;
    padding: 0;
    border-radius: 0;
    color: inherit;
    font-size: inherit;
}

/* Table */
.entry-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 32px 0;
    font-size: 15px;
}

.entry-content th,
.entry-content td {
    padding: 12px 16px;
    border: 1px solid #e0e0e0;
    text-align: left;
}

.entry-content th {
    background: #f5f5f5;
    font-weight: 700;
}

/* WordPress Alignment */
.entry-content .alignwide {
    width: calc(100% + 200px);
    max-width: calc(100% + 200px);
    margin-left: -100px;
}

.entry-content .alignfull {
    width: 100vw;
    max-width: 100vw;
    margin-left: calc(-50vw + 50%);
}

.entry-content .aligncenter {
    display: block;
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

.entry-content .alignleft {
    float: left;
    margin: 0 24px 16px 0;
    width: auto;
    max-width: 50%;
}

.entry-content .alignright {
    float: right;
    margin: 0 0 16px 24px;
    width: auto;
    max-width: 50%;
}

/* WP Block Image - 기본 이미지도 확장 */
.entry-content .wp-block-image {
    width: calc(100% + 200px);
    max-width: calc(100% + 200px);
    margin-left: -100px;
    margin-right: -100px;
}

.entry-content .wp-block-image img {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
}

.entry-content .wp-block-image figcaption {
    padding: 12px 100px 0;
}

/* Post Navigation */
.post-navigation {
    margin-top: 60px;
    padding-top: 40px;
    border-top: 1px solid #eee;
}

.nav-links {
    display: flex;
    justify-content: space-between;
    gap: 30px;
}

.nav-previous,
.nav-next {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 16px 0;
    transition: color var(--transition-fast);
}

.nav-next {
    text-align: right;
}

.nav-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.nav-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--color-text-dark);
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.nav-previous:hover .nav-title,
.nav-next:hover .nav-title {
    color: var(--color-accent);
}

/* Comments */
.comments-area-wrapper {
    margin-top: 60px;
    padding-top: 40px;
    border-top: 1px solid #eee;
}

.comments-title {
    font-size: 20px;
    font-weight: 700;
    margin-bottom: 30px;
    color: var(--color-text-dark);
}

.comment-list {
    list-style: none;
}

.comment-list .comment {
    padding: 24px 0;
    border-bottom: 1px solid #f0f0f0;
}

.comment-list .comment-body {
    display: flex;
    gap: 16px;
}

.comment-list .comment-author img {
    border-radius: 50%;
}

.comment-list .comment-content p {
    font-size: 15px;
    line-height: 1.6;
    color: var(--color-text-body);
}

/* Comment Form */
.comment-respond {
    margin-top: 40px;
}

.comment-respond .comment-reply-title {
    font-size: 20px;
    font-weight: 700;
    margin-bottom: 20px;
}

.comment-respond .comment-form p {
    margin-bottom: 16px;
}

.comment-respond .comment-form label {
    display: block;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-muted);
    margin-bottom: 6px;
}

.comment-respond .comment-form input[type="text"],
.comment-respond .comment-form input[type="email"],
.comment-respond .comment-form input[type="url"],
.comment-respond .comment-form textarea {
    width: 100%;
    padding: 12px 16px;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 15px;
    font-family: var(--font-primary);
    transition: border-color var(--transition-fast);
}

.comment-respond .comment-form input:focus,
.comment-respond .comment-form textarea:focus {
    outline: none;
    border-color: var(--color-text-dark);
}

.comment-respond .comment-form textarea {
    min-height: 150px;
    resize: vertical;
}

.comment-respond .form-submit .submit {
    background: var(--color-text-dark);
    color: #fff;
    border: none;
    padding: 14px 36px;
    font-size: 14px;
    font-weight: 600;
    border-radius: 4px;
    cursor: pointer;
    transition: background var(--transition-fast);
}

.comment-respond .form-submit .submit:hover {
    background: #000;
}

/* Related Posts Section (Full Width) */
.related-posts-section {
    width: 100vw;
    margin-left: calc(-50vw + 50%);
    background: var(--color-bg-dark);
    padding: 80px 40px;
    margin-top: 80px;
}

.related-posts-inner {
    max-width: var(--site-max-width);
    margin: 0 auto;
}

.related-title {
    font-size: 28px;
    font-weight: 700;
    color: var(--color-text-primary);
    text-align: center;
    margin-bottom: 40px;
}

.related-posts-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--grid-gap);
}

21. assets/css/archive.css

/* ========== ARCHIVE / SEARCH ========== */

/* archive.php와 search.php는 front-page.css의 .main-hero-section 스타일을 공유 */
/* 추가적인 아카이브 전용 스타일 */

.archive .main-section-title,
.search .main-section-title {
    font-family: var(--font-primary);
    font-size: 36px;
}

22. assets/css/responsive.css

/* ========== RESPONSIVE ========== */

/* Tablet Large */
@media (max-width: 1200px) {
    .posts-grid,
    .related-posts-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* Tablet */
@media (max-width: 1024px) {
    :root {
        --section-padding: 60px 30px;
    }

    .header-inner {
        padding: 0 24px;
    }

    .main-hero-section {
        padding: 100px 30px 60px;
    }

    .main-section-title {
        font-size: 40px;
    }

    .single-title {
        font-size: 32px;
    }

    .hero-content {
        padding: 40px 40px 50px;
    }

    .hero-actions {
        bottom: 50px;
        right: 40px;
    }

    .posts-grid,
    .related-posts-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .related-posts-section {
        padding: 60px 30px;
    }
}

/* Mobile Large */
@media (max-width: 768px) {
    .main-navigation {
        display: none;
    }

    .menu-toggle {
        display: flex;
    }

    /* Mobile Menu */
    .main-navigation.toggled {
        display: flex;
        flex-direction: column;
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0, 0, 0, 0.98);
        z-index: 9998;
        justify-content: center;
        align-items: center;
        animation: fadeIn 0.3s ease;
    }

    @keyframes fadeIn {
        from { opacity: 0; }
        to { opacity: 1; }
    }

    .main-navigation.toggled .primary-menu {
        flex-direction: column;
        gap: 4px;
        text-align: center;
    }

    .main-navigation.toggled .primary-menu li a {
        font-size: 20px;
        padding: 14px 28px;
    }

    .main-navigation.toggled .primary-menu li .sub-menu {
        position: static;
        transform: none;
        opacity: 1;
        visibility: visible;
        background: transparent;
        box-shadow: none;
        padding: 0;
        min-width: auto;
    }

    /* Hero */
    .single-hero {
        min-height: 60vh;
    }

    .hero-content {
        padding: 30px 24px 40px;
    }

    .single-title {
        font-size: 26px;
    }

    .hero-actions {
        position: static;
        margin-top: 20px;
    }

    /* Content */
    .single-content-wrapper {
        padding: 40px 20px 60px;
    }

    .entry-content {
        font-size: 16px;
    }

    .entry-content h2 {
        font-size: 20px;
        margin: 48px 0 24px;
    }

    .entry-content h3 {
        font-size: 17px;
        margin: 36px 0 18px;
    }

    /* 모바일에서 이미지 확장 축소 */
    .entry-content img,
    .entry-content figure,
    .entry-content .wp-block-image,
    .entry-content .alignwide {
        width: calc(100% + 40px);
        max-width: calc(100% + 40px);
        margin-left: -20px;
        margin-right: -20px;
    }

    .entry-content figcaption,
    .entry-content .wp-block-image figcaption {
        padding: 10px 20px 0;
    }

    /* Grid */
    .main-hero-section {
        padding: 90px 20px 50px;
    }

    .main-section-title {
        font-size: 32px;
    }

    .category-filter {
        gap: 16px;
        margin-bottom: 36px;
    }

    .filter-tab {
        font-size: 13px;
    }

    .posts-grid,
    .related-posts-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 16px;
    }

    .card-title {
        font-size: 14px;
    }

    .related-posts-section {
        padding: 50px 20px;
    }

    .related-title {
        font-size: 24px;
    }

    /* Navigation */
    .nav-links {
        flex-direction: column;
        gap: 16px;
    }

    .nav-next {
        text-align: left;
    }
}

/* Mobile Small */
@media (max-width: 480px) {
    .posts-grid,
    .related-posts-grid {
        grid-template-columns: 1fr;
        gap: 20px;
    }

    .main-section-title {
        font-size: 28px;
    }

    .single-hero {
        min-height: 50vh;
    }

    .single-title {
        font-size: 22px;
    }

    .header-inner {
        padding: 0 16px;
        height: 60px;
    }

    .category-filter {
        gap: 12px;
    }

    .filter-tab {
        font-size: 12px;
    }
}

/* Footer Responsive */
@media (max-width: 768px) {
    .footer-top {
        flex-direction: column;
        gap: 30px;
    }

    .footer-widgets {
        flex-direction: column;
    }
}

23. assets/js/navigation.js

/**
 * H-Style Navigation
 * 스크롤 감지 + 모바일 메뉴 + 검색 오버레이
 */
(function () {
    'use strict';

    const header = document.getElementById('masthead');
    const menuToggle = document.querySelector('.menu-toggle');
    const navigation = document.getElementById('site-navigation');
    const searchToggle = document.querySelector('.search-toggle');
    const searchOverlay = document.querySelector('.search-overlay');
    const searchClose = document.querySelector('.search-close');
    const searchField = document.querySelector('.search-overlay .search-field');
    const backToTop = document.querySelector('.back-to-top');

    /**
     * Header Scroll Effect
     */
    let lastScroll = 0;
    const scrollThreshold = 50;

    function handleScroll() {
        const currentScroll = window.pageYOffset;

        if (currentScroll > scrollThreshold) {
            header.classList.add('scrolled');
        } else {
            header.classList.remove('scrolled');
        }

        lastScroll = currentScroll;
    }

    window.addEventListener('scroll', handleScroll, { passive: true });
    handleScroll(); // Initial check

    /**
     * Mobile Menu Toggle
     */
    if (menuToggle && navigation) {
        menuToggle.addEventListener('click', function () {
            const isExpanded = menuToggle.getAttribute('aria-expanded') === 'true';
            menuToggle.setAttribute('aria-expanded', !isExpanded);
            navigation.classList.toggle('toggled');
            document.body.style.overflow = navigation.classList.contains('toggled') ? 'hidden' : '';
        });

        // Close on menu item click
        const menuLinks = navigation.querySelectorAll('.primary-menu > li > a');
        menuLinks.forEach(function (link) {
            link.addEventListener('click', function () {
                if (navigation.classList.contains('toggled')) {
                    navigation.classList.remove('toggled');
                    menuToggle.setAttribute('aria-expanded', 'false');
                    document.body.style.overflow = '';
                }
            });
        });
    }

    /**
     * Search Overlay
     */
    if (searchToggle && searchOverlay) {
        searchToggle.addEventListener('click', function () {
            searchOverlay.classList.add('active');
            searchOverlay.setAttribute('aria-hidden', 'false');
            document.body.style.overflow = 'hidden';
            if (searchField) {
                setTimeout(function () { searchField.focus(); }, 100);
            }
        });

        if (searchClose) {
            searchClose.addEventListener('click', closeSearch);
        }

        searchOverlay.addEventListener('click', function (e) {
            if (e.target === searchOverlay) {
                closeSearch();
            }
        });

        document.addEventListener('keydown', function (e) {
            if (e.key === 'Escape' && searchOverlay.classList.contains('active')) {
                closeSearch();
            }
        });
    }

    function closeSearch() {
        searchOverlay.classList.remove('active');
        searchOverlay.setAttribute('aria-hidden', 'true');
        document.body.style.overflow = '';
    }

    /**
     * Back to Top
     */
    if (backToTop) {
        backToTop.addEventListener('click', function () {
            window.scrollTo({ top: 0, behavior: 'smooth' });
        });
    }

    /**
     * Fallback Menu (메뉴 미설정 시)
     */
})();

/**
 * Fallback menu function (PHP에서 호출)
 */
function hstyle_fallback_menu() {
    // PHP에서 처리
}

24. assets/js/load-more.js

/**
 * H-Style AJAX Load More
 * 더보기 버튼 & 카테고리 필터
 */
(function ($) {
    'use strict';

    const $grid = $('#main-posts-grid');
    const $loadMoreBtn = $('.load-more-btn');
    const $filterTabs = $('.filter-tab');

    let isLoading = false;
    let currentCategory = 'all';

    /**
     * Load More Button
     */
    $loadMoreBtn.on('click', function () {
        if (isLoading) return;

        const $btn = $(this);
        const page = parseInt($btn.data('page')) + 1;
        const maxPages = parseInt($btn.data('max'));
        const searchQuery = $btn.data('search') || '';

        if (page > maxPages) return;

        isLoading = true;
        $btn.addClass('loading');

        $.ajax({
            url: hstyleAjax.ajaxurl,
            type: 'POST',
            data: {
                action: 'hstyle_load_more',
                nonce: hstyleAjax.nonce,
                page: page,
                category: currentCategory !== 'all' ? currentCategory : '',
                search: searchQuery,
            },
            success: function (response) {
                if (response.success && response.data.html) {
                    const $newItems = $(response.data.html);
                    $newItems.css('opacity', 0);
                    $grid.append($newItems);

                    // Fade in animation
                    requestAnimationFrame(function () {
                        $newItems.css({
                            'opacity': 1,
                            'transition': 'opacity 0.4s ease',
                        });
                    });

                    $btn.data('page', page);

                    if (page >= maxPages || !response.data.has_more) {
                        $btn.parent('.load-more-wrapper').fadeOut(300);
                    }
                } else {
                    $btn.parent('.load-more-wrapper').fadeOut(300);
                }
            },
            error: function () {
                console.error('Load more failed');
            },
            complete: function () {
                isLoading = false;
                $btn.removeClass('loading');
            },
        });
    });

    /**
     * Category Filter Tabs
     */
    $filterTabs.on('click', function () {
        if (isLoading) return;

        const $tab = $(this);
        const category = $tab.data('category');

        if (category === currentCategory) return;

        // Update active state
        $filterTabs.removeClass('active').attr('aria-selected', 'false');
        $tab.addClass('active').attr('aria-selected', 'true');
        currentCategory = category;
        isLoading = true;

        // Fade out current
        $grid.css('opacity', 0.3);

        $.ajax({
            url: hstyleAjax.ajaxurl,
            type: 'POST',
            data: {
                action: 'hstyle_filter_posts',
                nonce: hstyleAjax.nonce,
                category: category !== 'all' ? category : '',
            },
            success: function (response) {
                if (response.success && response.data.html) {
                    $grid.html(response.data.html);

                    // Reset load more
                    $loadMoreBtn.data('page', 1);
                    $loadMoreBtn.data('max', response.data.max_pages);

                    if (response.data.max_pages > 1) {
                        $loadMoreBtn.parent('.load-more-wrapper').fadeIn(300);
                    } else {
                        $loadMoreBtn.parent('.load-more-wrapper').fadeOut(300);
                    }
                }
            },
            complete: function () {
                isLoading = false;
                $grid.css({ 'opacity': 1, 'transition': 'opacity 0.4s ease' });
            },
        });
    });
})(jQuery);

25. assets/js/hero-scroll.js

/**
 * H-Style Hero Parallax & Scroll Effects
 * 싱글 포스트 히어로 패럴랙스
 */
(function () {
    'use strict';

    const hero = document.querySelector('.single-hero');
    if (!hero) return;

    const heroContent = hero.querySelector('.hero-content');

    // Parallax on scroll
    function handleParallax() {
        const scrollY = window.pageYOffset;
        const heroHeight = hero.offsetHeight;

        if (scrollY <= heroHeight) {
            const ratio = scrollY / heroHeight;
            hero.style.backgroundPositionY = (50 + ratio * 20) + '%';

            if (heroContent) {
                heroContent.style.opacity = 1 - ratio * 1.2;
                heroContent.style.transform = 'translateY(' + (scrollY * 0.3) + 'px)';
            }
        }
    }

    // Use requestAnimationFrame for smooth performance
    let ticking = false;
    window.addEventListener('scroll', function () {
        if (!ticking) {
            requestAnimationFrame(function () {
                handleParallax();
                ticking = false;
            });
            ticking = true;
        }
    }, { passive: true });
})();

26. inc/customizer.php

<?php
/**
 * Theme Customizer
 *
 * @package H-Style
 */

function hstyle_customize_register($wp_customize) {
    // 테마 옵션 패널
    $wp_customize->add_panel('hstyle_options', array(
        'title'    => __('H-Style 테마 설정', 'h-style'),
        'priority' => 30,
    ));

    /**
     * 일반 설정
     */
    $wp_customize->add_section('hstyle_general', array(
        'title'    => __('일반 설정', 'h-style'),
        'panel'    => 'hstyle_options',
        'priority' => 10,
    ));

    // 액센트 컬러
    $wp_customize->add_setting('hstyle_accent_color', array(
        'default'           => '#e63946',
        'sanitize_callback' => 'sanitize_hex_color',
        'transport'         => 'postMessage',
    ));

    $wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'hstyle_accent_color', array(
        'label'   => __('액센트 색상', 'h-style'),
        'section' => 'hstyle_general',
    )));

    // 다크 배경 컬러
    $wp_customize->add_setting('hstyle_dark_bg_color', array(
        'default'           => '#111111',
        'sanitize_callback' => 'sanitize_hex_color',
        'transport'         => 'postMessage',
    ));

    $wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'hstyle_dark_bg_color', array(
        'label'   => __('다크 배경 색상', 'h-style'),
        'section' => 'hstyle_general',
    )));

    /**
     * 메인 페이지 설정
     */
    $wp_customize->add_section('hstyle_frontpage', array(
        'title'    => __('메인 페이지', 'h-style'),
        'panel'    => 'hstyle_options',
        'priority' => 20,
    ));

    // 메인 타이틀
    $wp_customize->add_setting('hstyle_main_title', array(
        'default'           => "WHAT'S NEW",
        'sanitize_callback' => 'sanitize_text_field',
    ));

    $wp_customize->add_control('hstyle_main_title', array(
        'label'   => __('메인 섹션 타이틀', 'h-style'),
        'section' => 'hstyle_frontpage',
        'type'    => 'text',
    ));

    // 글 개수
    $wp_customize->add_setting('hstyle_posts_per_load', array(
        'default'           => 8,
        'sanitize_callback' => 'absint',
    ));

    $wp_customize->add_control('hstyle_posts_per_load', array(
        'label'   => __('더보기 시 로드할 글 수', 'h-style'),
        'section' => 'hstyle_frontpage',
        'type'    => 'number',
        'input_attrs' => array('min' => 4, 'max' => 20, 'step' => 1),
    ));

    /**
     * 싱글 포스트 설정
     */
    $wp_customize->add_section('hstyle_single', array(
        'title'    => __('글 보기 설정', 'h-style'),
        'panel'    => 'hstyle_options',
        'priority' => 30,
    ));

    // 관련글 표시
    $wp_customize->add_setting('hstyle_show_related', array(
        'default'           => true,
        'sanitize_callback' => 'hstyle_sanitize_checkbox',
    ));

    $wp_customize->add_control('hstyle_show_related', array(
        'label'   => __('관련글 표시', 'h-style'),
        'section' => 'hstyle_single',
        'type'    => 'checkbox',
    ));

    // 관련글 개수
    $wp_customize->add_setting('hstyle_related_count', array(
        'default'           => 4,
        'sanitize_callback' => 'absint',
    ));

    $wp_customize->add_control('hstyle_related_count', array(
        'label'   => __('관련글 개수', 'h-style'),
        'section' => 'hstyle_single',
        'type'    => 'number',
        'input_attrs' => array('min' => 2, 'max' => 8, 'step' => 1),
    ));

    /**
     * 푸터 설정
     */
    $wp_customize->add_section('hstyle_footer', array(
        'title'    => __('푸터 설정', 'h-style'),
        'panel'    => 'hstyle_options',
        'priority' => 40,
    ));

    // 저작권 텍스트
    $wp_customize->add_setting('hstyle_copyright', array(
        'default'           => '',
        'sanitize_callback' => 'wp_kses_post',
    ));

    $wp_customize->add_control('hstyle_copyright', array(
        'label'   => __('저작권 텍스트', 'h-style'),
        'section' => 'hstyle_footer',
        'type'    => 'textarea',
    ));
}
add_action('customize_register', 'hstyle_customize_register');

/**
 * 커스텀 CSS 출력
 */
function hstyle_customizer_css() {
    $accent = get_theme_mod('hstyle_accent_color', '#e63946');
    $dark_bg = get_theme_mod('hstyle_dark_bg_color', '#111111');

    $css = "
        :root {
            --color-accent: {$accent};
            --color-bg-dark: {$dark_bg};
        }
    ";

    wp_add_inline_style('hstyle-main', $css);
}
add_action('wp_enqueue_scripts', 'hstyle_customizer_css', 20);

/**
 * Sanitize Checkbox
 */
function hstyle_sanitize_checkbox($checked) {
    return ((isset($checked) && true == $checked) ? true : false);
}

27. inc/template-tags.php

<?php
/**
 * Template Tags
 *
 * @package H-Style
 */

/**
 * 폴백 메뉴
 */
function hstyle_fallback_menu() {
    echo '<ul class="primary-menu">';
    echo '<li><a href="' . esc_url(home_url('/')) . '">' . esc_html__('홈', 'h-style') . '</a></li>';

    $categories = get_categories(array(
        'orderby' => 'count',
        'order'   => 'DESC',
        'number'  => 5,
    ));

    foreach ($categories as $cat) {
        echo '<li><a href="' . esc_url(get_category_link($cat->term_id)) . '">' . esc_html($cat->name) . '</a></li>';
    }

    echo '</ul>';
}

/**
 * 읽기 시간 계산
 */
function hstyle_reading_time($post_id = null) {
    if (!$post_id) $post_id = get_the_ID();

    $content = get_post_field('post_content', $post_id);
    $word_count = mb_strlen(strip_tags($content));
    $reading_time = ceil($word_count / 500); // 한국어 약 500자/분

    return max(1, $reading_time);
}

/**
 * 조회수 (간단 구현)
 */
function hstyle_get_post_views($post_id = null) {
    if (!$post_id) $post_id = get_the_ID();
    $count = get_post_meta($post_id, 'hstyle_post_views', true);
    return $count ? number_format($count) : '0';
}

function hstyle_set_post_views($post_id = null) {
    if (!$post_id) $post_id = get_the_ID();
    $count = (int) get_post_meta($post_id, 'hstyle_post_views', true);
    update_post_meta($post_id, 'hstyle_post_views', $count + 1);
}

// 싱글 페이지 조회수 증가
function hstyle_track_views() {
    if (is_singular('post') && !is_admin()) {
        hstyle_set_post_views(get_the_ID());
    }
}
add_action('wp', 'hstyle_track_views');

/**
 * 아카이브 제목 필터 (접두사 제거)
 */
function hstyle_archive_title($title) {
    if (is_category()) {
        $title = single_cat_title('', false);
    } elseif (is_tag()) {
        $title = '#' . single_tag_title('', false);
    } elseif (is_author()) {
        $title = get_the_author();
    } elseif (is_year()) {
        $title = get_the_date('Y');
    } elseif (is_month()) {
        $title = get_the_date('Y.m');
    } elseif (is_day()) {
        $title = get_the_date('Y.m.d');
    }

    return $title;
}
add_filter('get_the_archive_title', 'hstyle_archive_title');

28. inc/ajax-load-more.php

<?php
/**
 * AJAX Load More & Filter
 *
 * @package H-Style
 */

/**
 * Load More Posts
 */
function hstyle_load_more_handler() {
    check_ajax_referer('hstyle_load_more', 'nonce');

    $page     = isset($_POST['page']) ? absint($_POST['page']) : 1;
    $category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
    $search   = isset($_POST['search']) ? sanitize_text_field($_POST['search']) : '';
    $per_page = get_option('posts_per_page', 8);

    $args = array(
        'posts_per_page'      => $per_page,
        'paged'               => $page,
        'post_status'         => 'publish',
        'ignore_sticky_posts' => true,
    );

    if ($category) {
        $args['category_name'] = $category;
    }

    if ($search) {
        $args['s'] = $search;
    }

    $query = new WP_Query($args);

    ob_start();
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            get_template_part('template-parts/content', 'card');
        }
    }
    $html = ob_get_clean();
    wp_reset_postdata();

    wp_send_json_success(array(
        'html'      => $html,
        'has_more'  => $page < $query->max_num_pages,
        'max_pages' => $query->max_num_pages,
    ));
}
add_action('wp_ajax_hstyle_load_more', 'hstyle_load_more_handler');
add_action('wp_ajax_nopriv_hstyle_load_more', 'hstyle_load_more_handler');

/**
 * Filter Posts by Category
 */
function hstyle_filter_posts_handler() {
    check_ajax_referer('hstyle_load_more', 'nonce');

    $category = isset($_POST['category']) ? sanitize_text_field($_POST['category']) : '';
    $per_page = get_option('posts_per_page', 8);

    $args = array(
        'posts_per_page'      => $per_page,
        'post_status'         => 'publish',
        'ignore_sticky_posts' => true,
    );

    if ($category) {
        $args['category_name'] = $category;
    }

    $query = new WP_Query($args);

    ob_start();
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            get_template_part('template-parts/content', 'card');
        }
    } else {
        get_template_part('template-parts/content', 'none');
    }
    $html = ob_get_clean();
    wp_reset_postdata();

    wp_send_json_success(array(
        'html'      => $html,
        'max_pages' => $query->max_num_pages,
    ));
}
add_action('wp_ajax_hstyle_filter_posts', 'hstyle_filter_posts_handler');
add_action('wp_ajax_nopriv_hstyle_filter_posts', 'hstyle_filter_posts_handler');

설치 방법

1단계: 위의 파일 구조대로 폴더와 파일을 생성합니다.

2단계: h-style 폴더를 압축하여 h-style.zip 파일로 만듭니다.

3단계: 워드프레스 관리자 → 외모 → 테마 → 새로 추가 → 테마 업로드에서 zip 파일을 업로드합니다.

4단계: 테마를 활성화한 뒤 다음을 설정합니다:

  • 외모 → 메뉴: 주 내비게이션 메뉴를 생성하고 "주 내비게이션" 위치에 지정
  • 외모 → 사용자 정의하기 → H-Style 테마 설정: 액센트 색상, 메인 타이틀 등 조정
  • 설정 → 읽기: 홈페이지 표시를 "최근 글"로 설정하거나, "정적 페이지"로 설정 후 프론트 페이지 지정
  • 각 글에 대표 이미지(Featured Image) 설정: 히어로 영역에 표시됩니다

이 테마에는 참고하신 SK Hynix Newsroom의 핵심 디자인 요소가 모두 포함되어 있습니다. 커스터마이저를 통해 색상이나 글 개수 등을 쉽게 조정할 수 있고, 추가로 세부 스타일을 수정하고 싶으시면 말씀해주세요.