From 6d4368fbd151f41ff4116ad03f8926ee5f8f6f9d Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 18 Aug 2026 16:05:14 +0800 Subject: [PATCH] Initial commit: TechBlog Pro WordPress theme Features: - Modern UI with dark mode support - Code highlighting with copy button - Auto table of contents - Reading time & views counter - Responsive design - Admin settings page - AJAX search --- 404.php | 83 +++ README.md | 191 ++++++ archive.php | 143 ++++ comments.php | 118 ++++ css/admin.css | 194 ++++++ footer.php | 130 ++++ functions.php | 459 +++++++++++++ header.php | 104 +++ inc/admin-options.php | 424 ++++++++++++ index.php | 99 +++ js/main.js | 334 ++++++++++ page.php | 25 + screenshot.png | Bin 0 -> 33473 bytes screenshot.svg | 68 ++ search.php | 102 +++ single.php | 154 +++++ style.css | 1475 +++++++++++++++++++++++++++++++++++++++++ 17 files changed, 4103 insertions(+) create mode 100755 404.php create mode 100755 README.md create mode 100755 archive.php create mode 100755 comments.php create mode 100644 css/admin.css create mode 100755 footer.php create mode 100755 functions.php create mode 100755 header.php create mode 100644 inc/admin-options.php create mode 100755 index.php create mode 100755 js/main.js create mode 100755 page.php create mode 100644 screenshot.png create mode 100755 screenshot.svg create mode 100755 search.php create mode 100755 single.php create mode 100755 style.css diff --git a/404.php b/404.php new file mode 100755 index 0000000..6f48516 --- /dev/null +++ b/404.php @@ -0,0 +1,83 @@ + + +
+
🚀
+

404

+

页面未找到

+
+

抱歉,您访问的页面不存在。可能已被移动或删除。

+
+ +
+ + + + + + 返回首页 + + +
+ + +
+

或者搜索您想要的内容:

+
+
+ + +
+
+
+ + +
+

📖 最近发布的文章

+
+ 3, + 'post_status' => 'publish', + )); + if ($recent->have_posts()) : + while ($recent->have_posts()) : $recent->the_post(); + ?> + +
+ +
+
+ +
+
+ +
+
+
+ + diff --git a/README.md b/README.md new file mode 100755 index 0000000..e03581a --- /dev/null +++ b/README.md @@ -0,0 +1,191 @@ +# TechBlog Pro - WordPress Theme + +一个专为IT技术分享设计的现代化WordPress主题,具有清爽的界面、强大的代码高亮支持和优秀的阅读体验。 + +![TechBlog Pro](screenshot.png) + +## ✨ 特性 + +### 🎨 设计特色 +- **现代化UI** - 清爽简洁的设计风格 +- **暗色模式** - 一键切换深色/浅色主题 +- **响应式布局** - 完美适配各种设备 +- **流畅动画** - 细腻的过渡效果 + +### 📝 博客功能 +- **代码高亮** - 专门优化的代码块样式 +- **一键复制** - 代码块支持快速复制 +- **阅读时间** - 自动计算文章阅读时间 +- **阅读进度** - 顶部进度条显示 +- **文章目录** - 自动生成TOC目录导航 +- **阅读统计** - 记录文章浏览次数 + +### 🔧 技术特性 +- **SEO友好** - 语义化HTML结构 +- **性能优化** - 图片懒加载、平滑滚动 +- **键盘快捷键** - Ctrl+K 搜索、ESC 关闭 +- **AJAX搜索** - 实时搜索建议 +- **自定义小工具** - 分类、标签、最新文章 + +## 📦 安装 + +### 方法一:后台上传 +1. 下载主题zip文件 +2. 进入 WordPress 后台 → 外观 → 主题 +3. 点击「添加」→「上传主题」 +4. 选择下载的zip文件并安装 +5. 激活主题 + +### 方法二:FTP上传 +1. 解压主题文件 +2. 通过FTP上传到 `/wp-content/themes/techblog-wp-theme/` +3. 进入 WordPress 后台 → 外观 → 主题 +4. 激活 TechBlog Pro 主题 + +## ⚙️ 配置 + +### 菜单设置 +进入 **外观 → 菜单**: +- 创建一个新菜单 +- 选择「主导航菜单」位置 +- 添加分类/页面/自定义链接 + +### 小工具设置 +进入 **外观 → 小工具**: +- **主侧边栏** - 文章页面右侧显示 +- **页脚栏 1/2/3** - 页脚三列布局 + +### 自定义设置 +进入 **外观 → 自定义**: +- **首页横幅** - 设置首页标题和描述 +- **社交媒体** - 添加社交链接(GitHub、Twitter等) + +### 代码块语言 +在编辑器中使用代码块时,设置语言可以显示对应的标签: +``` +// 语言会自动显示在代码块左上角 +console.log('Hello World'); +``` + +## 🎯 推荐分类结构 + +适合IT技术博客的分类建议: + +``` +├── Linux +│ ├── 系统管理 +│ ├── Shell脚本 +│ └── 性能优化 +├── DevOps +│ ├── Docker +│ ├── Kubernetes +│ ├── CI/CD +│ └── 监控运维 +├── 编程开发 +│ ├── Python +│ ├── Go +│ ├── JavaScript +│ └── 数据库 +├── 云计算 +│ ├── AWS +│ ├── Azure +│ └── 阿里云 +└── 网络安全 + ├── 防火墙 + └── 渗透测试 +``` + +## 📁 文件结构 + +``` +techblog-wp-theme/ +├── style.css # 主样式表 +├── functions.php # 主题函数 +├── header.php # 页头模板 +├── footer.php # 页脚模板 +├── index.php # 首页模板 +├── single.php # 文章详情模板 +├── page.php # 页面模板 +├── archive.php # 归档模板 +├── search.php # 搜索结果模板 +├── 404.php # 404页面模板 +├── comments.php # 评论模板 +├── js/ +│ └── main.js # 主脚本文件 +└── README.md # 主题说明文档 +``` + +## 🛠️ 开发指南 + +### 添加自定义样式 +在子主题或自定义CSS中添加: + +```css +/* 自定义主色调 */ +:root { + --primary-color: #your-color; + --secondary-color: #your-color; +} + +/* 自定义代码块背景 */ +.post-content pre { + background: #your-code-bg; +} +``` + +### 添加自定义功能 +在子主题的 `functions.php` 中添加: + +```php +// 添加自定义功能 +function my_custom_features() { + // 你的代码 +} +add_action('after_setup_theme', 'my_custom_features'); +``` + +## 🌐 浏览器支持 + +- Chrome (最新) +- Firefox (最新) +- Safari (最新) +- Edge (最新) + +## 📝 更新日志 + +### v1.0.0 (2024) +- 初始版本发布 +- 暗色模式支持 +- 代码高亮和复制功能 +- 目录自动生成 +- 响应式设计 + +## 💡 使用技巧 + +### 快捷键 +- `Ctrl + K` / `Cmd + K` - 打开搜索 +- `ESC` - 关闭搜索/弹窗 + +### Markdown 支持 +主题完美支持 Gutenberg 编辑器中的代码块,建议使用 WordPress 内置的代码块功能。 + +### 图片优化 +- 建议文章图片宽度 780px +- 使用 WebP 格式可提升加载速度 +- 主题自动支持图片懒加载 + +## 🤝 贡献 + +欢迎提交 Issue 和 Pull Request! + +## 📄 许可证 + +GPL v2 or later + +## 👨‍💻 作者 + +TechBlog Team + +--- + +**享受你的技术写作之旅!** 🚀 diff --git a/archive.php b/archive.php new file mode 100755 index 0000000..678192b --- /dev/null +++ b/archive.php @@ -0,0 +1,143 @@ + + + +
+ +

+ 📂 +

+ +

+ +

+ 共 found_posts; ?> 篇文章 +

+ + +

+ 🏷️ 标签: +

+

+ 共 found_posts; ?> 篇文章 +

+ + +

+ 👤 作者: +

+ +

+ + + +

+ 📅 年 +

+ + +

+ 📅 +

+ + +

+ 📅 +

+ + +

+ 🔍 搜索: +

+

+ 找到 found_posts; ?> 个结果 +

+ + +

+ 📄 归档 +

+ +
+ + +
+ + + + + + + 2, + 'prev_text' => '← 上一页', + 'next_text' => '下一页 →', + )); + ?> + + +
+

暂无文章

+
+

该分类下暂无文章。

+
+
+ +
+ + diff --git a/comments.php b/comments.php new file mode 100755 index 0000000..20a26de --- /dev/null +++ b/comments.php @@ -0,0 +1,118 @@ + + +
+ + +

+ + + + +

+ +
    + 'ol', + 'short_ping' => true, + 'avatar_size' => 48, + 'callback' => 'techblog_comment_template', + )); + ?> +
+ + '← 较旧的评论', + 'next_text' => '较新的评论 →', + )); + ?> + + + + +

评论已关闭

+ + + 'comment-form', + 'title_reply' => '', + 'comment_notes_before' => '', + 'comment_field' => ' +
+ + +
', + 'submit_button' => '', + )); + ?> +
+ + + < id="comment-" > +
+
+ +
+ +
+
+ + + + +
+ +
+ +
+ +
+ $depth, + 'max_depth' => $args['max_depth'], + ))); + ?> +
+
+
+ diff --git a/css/admin.css b/css/admin.css new file mode 100644 index 0000000..60538f7 --- /dev/null +++ b/css/admin.css @@ -0,0 +1,194 @@ +/* TechBlog Pro Admin Styles */ + +.techblog-admin-wrapper { + display: grid; + grid-template-columns: 200px 1fr; + gap: 20px; + margin-top: 20px; +} + +.nav-tab-wrapper { + display: flex; + flex-direction: column; + background: #fff; + border: 1px solid #ccd0d4; + border-radius: 4px; + overflow: hidden; + height: fit-content; +} + +.nav-tab-wrapper .nav-tab { + display: block; + padding: 12px 16px; + border: none; + border-bottom: 1px solid #ccd0d4; + border-radius: 0; + margin: 0; + font-size: 14px; + cursor: pointer; + transition: all 0.2s; + text-decoration: none; + color: #2271b1; +} + +.nav-tab-wrapper .nav-tab:last-child { + border-bottom: none; +} + +.nav-tab-wrapper .nav-tab:hover { + background: #f0f0f1; + color: #135e96; +} + +.nav-tab-wrapper .nav-tab.nav-tab-active { + background: #2563eb; + color: #fff; + border-color: #2563eb; +} + +.tab-content { + display: none; + background: #fff; + padding: 20px; + border: 1px solid #ccd0d4; + border-radius: 4px; +} + +.tab-content.active { + display: block; +} + +.tab-content .form-table th { + width: 150px; + padding: 15px 10px; +} + +.tab-content .form-table td { + padding: 15px 10px; +} + +.tab-content .form-table input[type="text"], +.tab-content .form-table input[type="url"], +.tab-content .form-table input[type="email"], +.tab-content .form-table textarea, +.tab-content .form-table select { + min-width: 300px; +} + +.tab-content .form-table input[type="color"] { + width: 60px; + height: 36px; + padding: 2px; + cursor: pointer; +} + +.tab-content .form-table fieldset label { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 12px; + cursor: pointer; +} + +.tab-content .form-table fieldset input[type="checkbox"] { + width: 18px; + height: 18px; +} + +/* About Card */ +.techblog-about-card { + max-width: 600px; +} + +.techblog-about-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 16px; +} + +.techblog-about-header h2 { + margin: 0; + font-size: 24px; +} + +.techblog-about-header .version { + background: #2563eb; + color: #fff; + padding: 4px 12px; + border-radius: 100px; + font-size: 12px; + font-weight: 600; +} + +.techblog-about-card h3 { + margin-top: 24px; + margin-bottom: 12px; + font-size: 16px; +} + +.techblog-about-card ul { + padding-left: 20px; +} + +.techblog-about-card li { + margin-bottom: 8px; + line-height: 1.6; +} + +.techblog-about-card a { + color: #2563eb; + text-decoration: none; +} + +.techblog-about-card a:hover { + text-decoration: underline; +} + +/* Submit Button */ +.submit { + margin-top: 20px; +} + +.submit .button-primary { + background: #2563eb; + border-color: #2563eb; + padding: 0 20px; + height: 40px; + font-size: 14px; + border-radius: 4px; +} + +.submit .button-primary:hover { + background: #1d4ed8; + border-color: #1d4ed8; +} + +/* Responsive */ +@media (max-width: 782px) { + .techblog-admin-wrapper { + grid-template-columns: 1fr; + } + + .nav-tab-wrapper { + flex-direction: row; + flex-wrap: wrap; + } + + .nav-tab-wrapper .nav-tab { + border-bottom: none; + border-right: 1px solid #ccd0d4; + } + + .nav-tab-wrapper .nav-tab:last-child { + border-right: none; + } + + .tab-content .form-table input[type="text"], + .tab-content .form-table input[type="url"], + .tab-content .form-table input[type="email"], + .tab-content .form-table textarea, + .tab-content .form-table select { + min-width: 100%; + } +} diff --git a/footer.php b/footer.php new file mode 100755 index 0000000..16ba9a1 --- /dev/null +++ b/footer.php @@ -0,0 +1,130 @@ + + + + + + + + + + + + diff --git a/functions.php b/functions.php new file mode 100755 index 0000000..85f4e24 --- /dev/null +++ b/functions.php @@ -0,0 +1,459 @@ + 40, + 'width' => 200, + 'flex-height' => true, + 'flex-width' => true, + )); + add_theme_support('html5', array( + 'search-form', + 'comment-form', + 'comment-list', + 'gallery', + 'caption', + 'style', + 'script', + )); + add_theme_support('editor-styles'); + add_theme_support('responsive-embeds'); + add_theme_support('wp-block-styles'); + + // Register Navigation Menus + register_nav_menus(array( + 'primary' => esc_html__('主导航菜单', 'techblog'), + 'footer' => esc_html__('页脚菜单', 'techblog'), + )); + + // Set content width + if (!isset($content_width)) { + $content_width = 780; + } +} +add_action('after_setup_theme', 'techblog_setup'); + +/** + * Enqueue Styles and Scripts + */ +function techblog_scripts() { + // Google Fonts + wp_enqueue_style('techblog-fonts', + 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap', + array(), + null + ); + + // Main Stylesheet + wp_enqueue_style('techblog-style', + get_stylesheet_uri(), + array(), + TECHBLOG_VERSION + ); + + // Main JavaScript + wp_enqueue_script('techblog-main', + TECHBLOG_URI . '/js/main.js', + array(), + TECHBLOG_VERSION, + true + ); + + // Localize script + wp_localize_script('techblog-main', 'techblog', array( + 'ajaxurl' => admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('techblog-nonce'), + )); +} +add_action('wp_enqueue_scripts', 'techblog_scripts'); + +/** + * Register Sidebars + */ +function techblog_widgets_init() { + register_sidebar(array( + 'name' => esc_html__('主侧边栏', 'techblog'), + 'id' => 'sidebar-main', + 'description' => esc_html__('文章页面右侧的侧边栏', 'techblog'), + 'before_widget' => '', + 'before_title' => '

', + 'after_title' => '

', + )); + + register_sidebar(array( + 'name' => esc_html__('页脚栏 1', 'techblog'), + 'id' => 'footer-1', + 'description' => esc_html__('页脚第一列', 'techblog'), + 'before_widget' => '', + 'before_title' => '

', + 'after_title' => '

', + )); + + register_sidebar(array( + 'name' => esc_html__('页脚栏 2', 'techblog'), + 'id' => 'footer-2', + 'description' => esc_html__('页脚第二列', 'techblog'), + 'before_widget' => '', + 'before_title' => '

', + 'after_title' => '

', + )); + + register_sidebar(array( + 'name' => esc_html__('页脚栏 3', 'techblog'), + 'id' => 'footer-3', + 'description' => esc_html__('页脚第三列', 'techblog'), + 'before_widget' => '', + 'before_title' => '

', + 'after_title' => '

', + )); +} +add_action('widgets_init', 'techblog_widgets_init'); + +/** + * Custom Excerpt Length + */ +function techblog_excerpt_length($length) { + return 25; +} +add_filter('excerpt_length', 'techblog_excerpt_length'); + +/** + * Custom Excerpt More + */ +function techblog_excerpt_more($more) { + return '...'; +} +add_filter('excerpt_more', 'techblog_excerpt_more'); + +/** + * Add Code Language Class to Pre Tags + */ +function techblog_code_block_attributes($block_content, $block) { + if ($block['blockName'] === 'core/code') { + if (!empty($block['attrs']['language'])) { + $lang = esc_attr($block['attrs']['language']); + $block_content = str_replace( + '
]*>(.*?)<\/h[2-3]>/is', $content, $matches, PREG_SET_ORDER);
+    
+    if (count($matches) < 3) {
+        return $content;
+    }
+    
+    $toc = '
'; + + // Insert TOC after first paragraph or before first heading + $first_p = strpos($content, '

'); + if ($first_p !== false) { + $content = substr($content, 0, $first_p + 4) . $toc . substr($content, $first_p + 4); + } else { + $content = $toc . $content; + } + + return $content; +} +add_filter('the_content', 'techblog_generate_toc', 20); + +/** + * Add Copy Button to Code Blocks + */ +function techblog_add_code_copy_button($content) { + if (!is_single() && !is_page()) { + return $content; + } + + $content = preg_replace_callback( + '/]*)>(.*?)<\/pre>/is', + function($matches) { + $attrs = $matches[1]; + $code = $matches[2]; + + // Extract language if present + $lang = ''; + if (preg_match('/lang-([a-z0-9]+)/', $attrs, $lang_match)) { + $lang = strtoupper($lang_match[1]); + } + + $header = '
'; + $header .= '' . ($lang ?: 'CODE') . ''; + $header .= '
'; + + return '' . $header . $code . '
'; + }, + $content + ); + + return $content; +} +add_filter('the_content', 'techblog_add_code_copy_button', 25); + +/** + * Custom Walker for Navigation Menu + */ +class TechBlog_Nav_Walker extends Walker_Nav_Menu { + function start_el(&$output, $item, $depth = 0, $args = null, $id = 0) { + $classes = empty($item->classes) ? array() : (array) $item->classes; + $class = join(' ', array_filter($classes)); + + if (in_array('current-menu-item', $classes) || in_array('current_page_item', $classes)) { + $class .= ' current'; + } + + $output .= ''; + $output .= esc_html($item->title); + $output .= ''; + } +} + +/** + * Reading Time + */ +function techblog_reading_time() { + $content = get_the_content(); + $word_count = str_word_count(strip_tags($content)); + $reading_time = ceil($word_count / 200); // Average reading speed + return $reading_time; +} + +/** + * Post Views (Simple implementation) + */ +function techblog_get_post_views() { + $count = get_post_meta(get_the_ID(), 'post_views', true); + return $count ? intval($count) : 0; +} + +function techblog_set_post_views() { + if (!is_single()) return; + + $post_id = get_the_ID(); + $count = get_post_meta($post_id, 'post_views', true); + + if ($count == '') { + $count = 0; + delete_post_meta($post_id, 'post_views'); + add_post_meta($post_id, 'post_views', '0'); + } else { + $count++; + update_post_meta($post_id, 'post_views', $count); + } +} +add_action('wp_head', 'techblog_set_post_views'); + +/** + * Format View Count + */ +function techblog_format_views($count) { + if ($count >= 10000) { + return round($count / 10000, 1) . 'w'; + } elseif ($count >= 1000) { + return round($count / 1000, 1) . 'k'; + } + return $count; +} + +/** + * Custom Comment Form + */ +function techblog_comment_form_defaults($defaults) { + $defaults['comment_notes_before'] = ''; + $defaults['comment_field'] = '
+ +
'; + return $defaults; +} +add_filter('comment_form_defaults', 'techblog_comment_form_defaults'); + +/** + * Theme Customizer + */ +function techblog_customize_register($wp_customize) { + // Hero Section + $wp_customize->add_section('techblog_hero', array( + 'title' => esc_html__('首页横幅', 'techblog'), + 'priority' => 30, + )); + + $wp_customize->add_setting('hero_title', array( + 'default' => '探索技术世界', + 'sanitize_callback' => 'sanitize_text_field', + )); + $wp_customize->add_control('hero_title', array( + 'label' => esc_html__('横幅标题', 'techblog'), + 'section' => 'techblog_hero', + 'type' => 'text', + )); + + $wp_customize->add_setting('hero_description', array( + 'default' => '分享最新的IT技术、编程教程、系统运维经验', + 'sanitize_callback' => 'sanitize_textarea_field', + )); + $wp_customize->add_control('hero_description', array( + 'label' => esc_html__('横幅描述', 'techblog'), + 'section' => 'techblog_hero', + 'type' => 'textarea', + )); + + // Social Links + $wp_customize->add_section('techblog_social', array( + 'title' => esc_html__('社交媒体', 'techblog'), + 'priority' => 35, + )); + + $social_platforms = array( + 'github' => 'GitHub', + 'twitter' => 'Twitter / X', + 'gitee' => 'Gitee', + 'email' => '邮箱', + ); + + foreach ($social_platforms as $key => $label) { + $wp_customize->add_setting('social_' . $key, array( + 'default' => '', + 'sanitize_callback' => 'esc_url_raw', + )); + $wp_customize->add_control('social_' . $key, array( + 'label' => $label, + 'section' => 'techblog_social', + 'type' => 'url', + )); + } +} +add_action('customize_register', 'techblog_customize_register'); + +/** + * Custom Post Type for Projects (optional) + */ +function techblog_register_post_types() { + register_post_type('project', array( + 'labels' => array( + 'name' => esc_html__('项目', 'techblog'), + 'singular_name' => esc_html__('项目', 'techblog'), + 'add_new' => esc_html__('添加项目', 'techblog'), + 'add_new_item' => esc_html__('添加新项目', 'techblog'), + 'edit_item' => esc_html__('编辑项目', 'techblog'), + 'all_items' => esc_html__('所有项目', 'techblog'), + 'view_item' => esc_html__('查看项目', 'techblog'), + 'search_items' => esc_html__('搜索项目', 'techblog'), + ), + 'public' => true, + 'has_archive' => true, + 'menu_icon' => 'dashicons-portfolio', + 'supports' => array('title', 'editor', 'thumbnail', 'excerpt'), + 'rewrite' => array('slug' => 'project'), + )); +} +add_action('init', 'techblog_register_post_types'); + +/** + * AJAX Search + */ +function techblog_ajax_search() { + check_ajax_referer('techblog-nonce', 'nonce'); + + $search_term = sanitize_text_field($_POST['search']); + + if (empty($search_term)) { + wp_send_json_error('请输入搜索关键词'); + } + + $query = new WP_Query(array( + 's' => $search_term, + 'posts_per_page' => 5, + 'post_status' => 'publish', + )); + + $results = array(); + + if ($query->have_posts()) { + while ($query->have_posts()) { + $query->the_post(); + $results[] = array( + 'title' => get_the_title(), + 'url' => get_the_permalink(), + 'excerpt' => wp_trim_words(get_the_excerpt(), 20), + 'date' => get_the_date('Y-m-d'), + ); + } + } + + wp_reset_postdata(); + + wp_send_json_success($results); +} +add_action('wp_ajax_techblog_search', 'techblog_ajax_search'); +add_action('wp_ajax_nopriv_techblog_search', 'techblog_ajax_search'); diff --git a/header.php b/header.php new file mode 100755 index 0000000..1034995 --- /dev/null +++ b/header.php @@ -0,0 +1,104 @@ + + data-theme="light"> + + + + + + +> + + + + + +
+
+
+
+ + + + + +
+
+
+ 输入关键词搜索 + ESC 关闭 +
+
+
+ +
+
diff --git a/inc/admin-options.php b/inc/admin-options.php new file mode 100644 index 0000000..b1a5979 --- /dev/null +++ b/inc/admin-options.php @@ -0,0 +1,424 @@ + '#2563eb' + )); + register_setting('techblog_options', 'techblog_code_theme', array( + 'default' => 'dark' + )); + register_setting('techblog_options', 'techblog_show_toc', array( + 'default' => '1' + )); + register_setting('techblog_options', 'techblog_show_reading_time', array( + 'default' => '1' + )); + register_setting('techblog_options', 'techblog_show_views', array( + 'default' => '1' + )); + register_setting('techblog_options', 'techblog_enable_dark_mode', array( + 'default' => '1' + )); +} +add_action('admin_init', 'techblog_register_settings'); + +// Admin page HTML +function techblog_options_page_html() { + if (!current_user_can('manage_options')) { + return; + } + + if (isset($_GET['settings-updated'])) { + add_settings_error('techblog_messages', 'techblog_message', '设置已保存', 'updated'); + } + + settings_errors('techblog_messages'); + ?> +
+

+ +
+ + + +
+ + + +
+ + + + + + + + + + + + + +
首页横幅标题 + +

首页顶部横幅的标题文字

+
首页横幅描述 + +

首页顶部横幅的描述文字

+
页脚文字 + +

页脚显示的描述文字

+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+ + +
+ + + + + + + + + + + + + +
主题色 + +

选择主题的主色调

+
代码块主题 + +

代码块的配色方案

+
功能开关 +
+
+
+
+ +
+
+
+ + +
+
+
+

TechBlog Pro

+ v1.0.0 +
+

一个专为IT技术分享设计的现代化WordPress主题。

+ +

✨ 主题特性

+
    +
  • 🎨 现代化UI设计,支持暗色模式
  • +
  • 📝 代码高亮 + 一键复制
  • +
  • 📑 自动生成文章目录
  • +
  • ⏱️ 阅读时间估算
  • +
  • 📊 阅读次数统计
  • +
  • 🔍 AJAX实时搜索
  • +
  • 📱 完美响应式布局
  • +
  • ⚡ 性能优化(懒加载、平滑滚动)
  • +
+ +

🔗 相关链接

+ +
+
+ + +
+
+
+ + + + + + + + +
+

+

+
+ + + +
+ + + + + + + 2, + 'prev_text' => '← 上一页', + 'next_text' => '下一页 →', + )); + ?> + + +
+

暂无文章

+
+

还没有发布任何文章,请稍后再来。

+
+
+ +
+ + diff --git a/js/main.js b/js/main.js new file mode 100755 index 0000000..9b2006b --- /dev/null +++ b/js/main.js @@ -0,0 +1,334 @@ +/** + * TechBlog Pro - Main JavaScript + * + * @package TechBlog Pro + * @version 1.0.0 + */ + +(function() { + 'use strict'; + + // ==================== Theme Toggle ==================== + const ThemeManager = { + init() { + this.toggle = document.getElementById('theme-toggle'); + this.sunIcon = this.toggle?.querySelector('.sun-icon'); + this.moonIcon = this.toggle?.querySelector('.moon-icon'); + + if (!this.toggle) return; + + // Load saved theme + const savedTheme = localStorage.getItem('theme') || 'light'; + this.setTheme(savedTheme); + + // Toggle event + this.toggle.addEventListener('click', () => { + const current = document.documentElement.getAttribute('data-theme'); + this.setTheme(current === 'dark' ? 'light' : 'dark'); + }); + }, + + setTheme(theme) { + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); + + if (this.sunIcon && this.moonIcon) { + this.sunIcon.style.display = theme === 'dark' ? 'none' : 'block'; + this.moonIcon.style.display = theme === 'dark' ? 'block' : 'none'; + } + } + }; + + // ==================== Search Overlay ==================== + const SearchManager = { + init() { + this.overlay = document.getElementById('search-overlay'); + this.toggle = document.getElementById('search-toggle'); + this.input = this.overlay?.querySelector('.search-input'); + + if (!this.overlay || !this.toggle) return; + + // Open search + this.toggle.addEventListener('click', () => this.open()); + + // Close on overlay click + this.overlay.addEventListener('click', (e) => { + if (e.target === this.overlay) this.close(); + }); + + // Keyboard shortcuts + document.addEventListener('keydown', (e) => { + // CMD/CTRL + K to open + if ((e.metaKey || e.ctrlKey) && e.key === 'k') { + e.preventDefault(); + this.open(); + } + + // ESC to close + if (e.key === 'Escape') { + this.close(); + } + }); + }, + + open() { + this.overlay.classList.add('active'); + setTimeout(() => this.input?.focus(), 100); + document.body.style.overflow = 'hidden'; + }, + + close() { + this.overlay.classList.remove('active'); + document.body.style.overflow = ''; + } + }; + + // ==================== Mobile Menu ==================== + const MobileMenu = { + init() { + this.toggle = document.getElementById('mobile-menu-toggle'); + this.nav = document.getElementById('main-nav'); + + if (!this.toggle || !this.nav) return; + + this.toggle.addEventListener('click', () => { + this.nav.classList.toggle('active'); + this.toggle.classList.toggle('active'); + }); + + // Close on outside click + document.addEventListener('click', (e) => { + if (!this.nav.contains(e.target) && !this.toggle.contains(e.target)) { + this.nav.classList.remove('active'); + this.toggle.classList.remove('active'); + } + }); + } + }; + + // ==================== Table of Contents ==================== + const TOCManager = { + init() { + this.tocLinks = document.querySelectorAll('.toc-list a'); + this.headings = []; + + if (this.tocLinks.length === 0) return; + + // Collect headings + this.tocLinks.forEach(link => { + const id = link.getAttribute('href')?.slice(1); + const heading = document.getElementById(id); + if (heading) { + this.headings.push({ id, element: heading, link }); + } + }); + + // Scroll spy + this.observer = new IntersectionObserver( + (entries) => this.handleIntersection(entries), + { rootMargin: '-80px 0px -80% 0px' } + ); + + this.headings.forEach(({ element }) => { + this.observer.observe(element); + }); + + // Smooth scroll + this.tocLinks.forEach(link => { + link.addEventListener('click', (e) => { + e.preventDefault(); + const id = link.getAttribute('href')?.slice(1); + const target = document.getElementById(id); + if (target) { + target.scrollIntoView({ behavior: 'smooth' }); + } + }); + }); + }, + + handleIntersection(entries) { + entries.forEach(entry => { + if (entry.isIntersecting) { + // Remove all active states + this.tocLinks.forEach(link => link.classList.remove('active')); + + // Add active to current + const activeLink = this.headings.find(h => h.id === entry.target.id)?.link; + activeLink?.classList.add('active'); + } + }); + } + }; + + // ==================== Code Copy ==================== + window.copyCode = function(button) { + const pre = button.closest('pre'); + const code = pre?.querySelector('code'); + + if (!code) return; + + const text = code.textContent; + + navigator.clipboard.writeText(text).then(() => { + const originalText = button.innerHTML; + button.innerHTML = ` + + + + 已复制 + `; + button.style.color = '#22c55e'; + + setTimeout(() => { + button.innerHTML = originalText; + button.style.color = ''; + }, 2000); + }).catch(err => { + console.error('Failed to copy:', err); + }); + }; + + // ==================== Reading Progress ==================== + const ReadingProgress = { + init() { + this.progressBar = document.createElement('div'); + this.progressBar.style.cssText = ` + position: fixed; + top: 0; + left: 0; + width: 0%; + height: 3px; + background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); + z-index: 9999; + transition: width 0.1s ease; + `; + document.body.appendChild(this.progressBar); + + window.addEventListener('scroll', () => this.update()); + }, + + update() { + const scrollTop = window.scrollY; + const docHeight = document.documentElement.scrollHeight - window.innerHeight; + const progress = (scrollTop / docHeight) * 100; + + this.progressBar.style.width = `${Math.min(progress, 100)}%`; + } + }; + + // ==================== Lazy Load Images ==================== + const LazyLoad = { + init() { + if ('loading' in HTMLImageElement.prototype) { + // Native lazy loading supported + document.querySelectorAll('img[loading="lazy"]').forEach(img => { + img.src = img.dataset.src; + }); + } else { + // Fallback with IntersectionObserver + this.observer = new IntersectionObserver( + (entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + const img = entry.target; + img.src = img.dataset.src; + this.observer.unobserve(img); + } + }); + }, + { rootMargin: '50px' } + ); + + document.querySelectorAll('img[data-src]').forEach(img => { + this.observer.observe(img); + }); + } + } + }; + + // ==================== Copy Link ==================== + window.copyLink = function() { + const url = window.location.href; + navigator.clipboard.writeText(url).then(() => { + const btn = document.querySelector('.share-copy'); + btn.classList.add('copied'); + btn.title = '已复制'; + + setTimeout(() => { + btn.classList.remove('copied'); + btn.title = '复制链接'; + }, 2000); + }); + }; + + // ==================== Back to Top ==================== + const BackToTop = { + init() { + this.button = document.createElement('button'); + this.button.innerHTML = ` + + + + + `; + this.button.style.cssText = ` + position: fixed; + bottom: 24px; + right: 24px; + width: 44px; + height: 44px; + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + opacity: 0; + visibility: hidden; + transition: all 0.3s ease; + z-index: 100; + color: var(--text-secondary); + box-shadow: var(--shadow-md); + `; + + this.button.addEventListener('click', () => { + window.scrollTo({ top: 0, behavior: 'smooth' }); + }); + + document.body.appendChild(this.button); + + window.addEventListener('scroll', () => this.toggle()); + }, + + toggle() { + if (window.scrollY > 300) { + this.button.style.opacity = '1'; + this.button.style.visibility = 'visible'; + } else { + this.button.style.opacity = '0'; + this.button.style.visibility = 'hidden'; + } + } + }; + + // ==================== Initialize ==================== + document.addEventListener('DOMContentLoaded', () => { + ThemeManager.init(); + SearchManager.init(); + MobileMenu.init(); + TOCManager.init(); + ReadingProgress.init(); + LazyLoad.init(); + BackToTop.init(); + + // Add current page class to nav + const currentPath = window.location.pathname; + document.querySelectorAll('.main-nav a').forEach(link => { + if (link.pathname === currentPath) { + link.classList.add('current'); + } + }); + }); + +})(); diff --git a/page.php b/page.php new file mode 100755 index 0000000..9eea5d4 --- /dev/null +++ b/page.php @@ -0,0 +1,25 @@ + + +
> + + +
+

+
+ +
+ +
+ + +
+ + diff --git a/screenshot.png b/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e0187729cef340f0df73b901762be60a6f0b612c GIT binary patch literal 33473 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 I@nOJ!09-206951J literal 0 HcmV?d00001 diff --git a/screenshot.svg b/screenshot.svg new file mode 100755 index 0000000..3f4107c --- /dev/null +++ b/screenshot.svg @@ -0,0 +1,68 @@ + + + + + + + + TechBlog Pro + + + 首页 博客 Linux Docker K8s + + + + + + + + + + 探索技术世界 + 分享最新的IT技术、编程教程、系统运维经验 + + + + + LINUX + Ubuntu 24.04 LTS 安装配置指南 + 详细介绍如何在服务器上安装和配置 Ubuntu 24.04 LTS... + ⏱ 8 分钟阅读 👁 1.2k 阅读 + + + + + DOCKER + Docker Compose 实战教程 + 使用 Docker Compose 编排多容器应用... + + + + 📂 文章分类 + Linux (24) + Docker (18) + Kubernetes (15) + Python (12) + + + 🏷️ 热门标签 + + Docker + + Kubernetes + + Linux + + + + 一个专注于IT技术分享的博客 + © 2024 TechBlog Pro. All rights reserved. + + + + + + + + + diff --git a/search.php b/search.php new file mode 100755 index 0000000..868aee0 --- /dev/null +++ b/search.php @@ -0,0 +1,102 @@ + + +
+

+ 🔍 搜索结果: +

+

+ found_posts > 0) : ?> + 找到 found_posts; ?> 个相关结果 + + 未找到相关结果 + +

+
+ +
+ + + + + + 2, + 'prev_text' => '← 上一页', + 'next_text' => '下一页 →', + )); + ?> + + +
+
🔍
+

未找到相关内容

+
+

抱歉,没有找到与 "" 相关的文章。

+

您可以尝试:

+
    +
  • 检查关键词是否正确
  • +
  • 尝试其他关键词
  • +
  • 浏览我们的文章分类
  • +
+
+
+ +
+ + diff --git a/single.php b/single.php new file mode 100755 index 0000000..93f573c --- /dev/null +++ b/single.php @@ -0,0 +1,154 @@ + + + + + diff --git a/style.css b/style.css new file mode 100755 index 0000000..6b3c8f0 --- /dev/null +++ b/style.css @@ -0,0 +1,1475 @@ +/* +Theme Name: TechBlog Pro +Theme URI: https://github.com/techblog-pro +Author: TechBlog Team +Author URI: https://github.com +Description: 一个专为IT技术分享设计的现代化WordPress主题,支持代码高亮、暗色模式、响应式布局 +Version: 1.0.0 +License: GNU General Public License v2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html +Text Domain: techblog +Tags: blog, technology, code, dark-mode, responsive +*/ + +/* ==================== CSS Variables ==================== */ +:root { + /* Light Mode Colors */ + --primary-color: #2563eb; + --primary-hover: #1d4ed8; + --secondary-color: #7c3aed; + --accent-color: #06b6d4; + + --bg-primary: #ffffff; + --bg-secondary: #f8fafc; + --bg-tertiary: #f1f5f9; + --bg-code: #1e293b; + + --text-primary: #1e293b; + --text-secondary: #475569; + --text-muted: #94a3b8; + --text-code: #e2e8f0; + + --border-color: #e2e8f0; + --border-hover: #cbd5e1; + + --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + + --radius-sm: 6px; + --radius-md: 8px; + --radius-lg: 12px; + --radius-xl: 16px; + + --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --font-mono: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace; + + --header-height: 64px; + --sidebar-width: 300px; + --content-max-width: 780px; + --container-max-width: 1280px; + + --transition: all 0.2s ease; +} + +/* Dark Mode */ +[data-theme="dark"] { + --bg-primary: #0f172a; + --bg-secondary: #1e293b; + --bg-tertiary: #334155; + --bg-code: #0d1117; + + --text-primary: #f1f5f9; + --text-secondary: #94a3b8; + --text-muted: #64748b; + --text-code: #e2e8f0; + + --border-color: #334155; + --border-hover: #475569; + + --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3); + --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.3); + --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.3); +} + +/* ==================== Base Styles ==================== */ +*, *::before, *::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + font-size: 16px; + scroll-behavior: smooth; + scroll-padding-top: calc(var(--header-height) + 20px); +} + +body { + font-family: var(--font-sans); + background-color: var(--bg-primary); + color: var(--text-primary); + line-height: 1.7; + transition: background-color 0.3s ease, color 0.3s ease; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + color: var(--primary-color); + text-decoration: none; + transition: var(--transition); +} + +a:hover { + color: var(--primary-hover); +} + +img { + max-width: 100%; + height: auto; + display: block; +} + +/* ==================== Header ==================== */ +.site-header { + position: sticky; + top: 0; + z-index: 1000; + background: var(--bg-primary); + border-bottom: 1px solid var(--border-color); + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); +} + +.header-inner { + max-width: var(--container-max-width); + margin: 0 auto; + padding: 0 24px; + height: var(--header-height); + display: flex; + align-items: center; + justify-content: space-between; +} + +.site-logo { + display: flex; + align-items: center; + gap: 10px; + font-size: 1.25rem; + font-weight: 700; + color: var(--text-primary); +} + +.site-logo svg { + width: 32px; + height: 32px; + fill: var(--primary-color); +} + +/* Navigation */ +.main-nav { + display: flex; + align-items: center; + gap: 8px; +} + +.main-nav a { + padding: 8px 16px; + color: var(--text-secondary); + font-size: 0.9375rem; + font-weight: 500; + border-radius: var(--radius-sm); + transition: var(--transition); +} + +.main-nav a:hover, +.main-nav a.current { + color: var(--text-primary); + background: var(--bg-tertiary); +} + +/* Header Actions */ +.header-actions { + display: flex; + align-items: center; + gap: 8px; +} + +.search-toggle, +.theme-toggle, +.mobile-menu-toggle { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + background: none; + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + color: var(--text-secondary); + cursor: pointer; + transition: var(--transition); +} + +.search-toggle:hover, +.theme-toggle:hover, +.mobile-menu-toggle:hover { + background: var(--bg-tertiary); + color: var(--text-primary); + border-color: var(--border-hover); +} + +.theme-toggle svg, +.search-toggle svg { + width: 20px; + height: 20px; +} + +.mobile-menu-toggle { + display: none; +} + +/* ==================== Layout ==================== */ +.site-container { + max-width: var(--container-max-width); + margin: 0 auto; + padding: 32px 24px; + display: grid; + grid-template-columns: 1fr var(--sidebar-width); + gap: 40px; +} + +.content-area { + min-width: 0; +} + +/* ==================== Hero Section ==================== */ +.hero-section { + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + border-radius: var(--radius-xl); + padding: 48px; + margin-bottom: 40px; + color: white; + position: relative; + overflow: hidden; +} + +.hero-section::before { + content: ''; + position: absolute; + top: 0; + right: 0; + width: 300px; + height: 300px; + background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%); + transform: translate(30%, -30%); +} + +.hero-title { + font-size: 2rem; + font-weight: 800; + margin-bottom: 12px; + position: relative; +} + +.hero-description { + font-size: 1.0625rem; + opacity: 0.9; + max-width: 600px; + position: relative; +} + +/* ==================== Post Cards ==================== */ +.posts-grid { + display: grid; + gap: 24px; +} + +.post-card { + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 28px; + transition: var(--transition); +} + +.post-card:hover { + border-color: var(--primary-color); + box-shadow: var(--shadow-md); + transform: translateY(-2px); +} + +.post-card-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 16px; +} + +.post-category { + display: inline-flex; + align-items: center; + padding: 4px 12px; + background: linear-gradient(135deg, var(--primary-color), var(--accent-color)); + color: white; + font-size: 0.75rem; + font-weight: 600; + border-radius: 100px; + text-transform: uppercase; + letter-spacing: 0.5px; +} + +.post-date { + font-size: 0.875rem; + color: var(--text-muted); +} + +.post-card-title { + font-size: 1.375rem; + font-weight: 700; + line-height: 1.4; + margin-bottom: 12px; + color: var(--text-primary); +} + +.post-card-title a { + color: inherit; +} + +.post-card-title a:hover { + color: var(--primary-color); +} + +.post-excerpt { + color: var(--text-secondary); + font-size: 0.9375rem; + line-height: 1.6; + margin-bottom: 20px; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.post-card-footer { + display: flex; + align-items: center; + justify-content: space-between; + padding-top: 16px; + border-top: 1px solid var(--border-color); +} + +.post-meta { + display: flex; + align-items: center; + gap: 16px; + font-size: 0.875rem; + color: var(--text-muted); +} + +.post-meta-item { + display: flex; + align-items: center; + gap: 6px; +} + +.post-meta-item svg { + width: 16px; + height: 16px; +} + +.read-more { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 0.875rem; + font-weight: 600; + color: var(--primary-color); +} + +.read-more svg { + width: 16px; + height: 16px; + transition: transform 0.2s ease; +} + +.read-more:hover svg { + transform: translateX(4px); +} + +/* ==================== Single Post ==================== */ +.single-post { + width: 100%; +} + +/* Post Footer - Tags & Share */ +.post-footer { + margin-top: 40px; + padding-top: 32px; + border-top: 1px solid var(--border-color); +} + +.post-tags { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 24px; + flex-wrap: wrap; +} + +.post-tags svg { + color: var(--text-muted); + flex-shrink: 0; +} + +.post-tags a { + display: inline-block; + padding: 6px 14px; + background: var(--bg-secondary); + color: var(--text-secondary); + border-radius: 100px; + font-size: 0.8125rem; + font-weight: 500; + transition: var(--transition); + border: 1px solid var(--border-color); +} + +.post-tags a:hover { + background: var(--primary-color); + color: white; + border-color: var(--primary-color); + transform: translateY(-1px); +} + +.share-section { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px 24px; + background: var(--bg-secondary); + border-radius: var(--radius-lg); + border: 1px solid var(--border-color); +} + +.share-label { + display: flex; + align-items: center; + gap: 10px; + font-weight: 600; + color: var(--text-primary); + font-size: 0.9375rem; +} + +.share-label svg { + color: var(--text-muted); +} + +.share-buttons { + display: flex; + gap: 10px; +} + +.share-btn { + display: flex; + align-items: center; + justify-content: center; + width: 44px; + height: 44px; + border-radius: var(--radius-md); + border: 1px solid var(--border-color); + background: var(--bg-primary); + color: var(--text-secondary); + cursor: pointer; + transition: var(--transition); +} + +.share-btn:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-md); +} + +.share-twitter:hover { + background: #000; + color: white; + border-color: #000; +} + +.share-linkedin:hover { + background: #0077b5; + color: white; + border-color: #0077b5; +} + +.share-copy:hover { + background: var(--primary-color); + color: white; + border-color: var(--primary-color); +} + +.share-copy.copied { + background: #22c55e; + color: white; + border-color: #22c55e; +} + +/* ==================== Comments Area ==================== */ +.comments-area { + margin-top: 48px; + padding-top: 40px; + border-top: 1px solid var(--border-color); +} + +.comments-title { + display: flex; + align-items: center; + gap: 12px; + font-size: 1.25rem; + font-weight: 700; + margin-bottom: 32px; + color: var(--text-primary); +} + +.comments-title svg { + color: var(--primary-color); +} + +.comment-list { + list-style: none; + padding: 0; + margin: 0; +} + +.comment-item { + margin-bottom: 24px; +} + +.comment-item .children { + list-style: none; + padding-left: 48px; + margin-top: 24px; +} + +.comment-body { + display: flex; + gap: 16px; + padding: 24px; + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + transition: var(--transition); +} + +.comment-body:hover { + border-color: var(--border-hover); + box-shadow: var(--shadow-sm); +} + +.comment-avatar { + flex-shrink: 0; +} + +.comment-avatar img { + width: 48px; + height: 48px; + border-radius: 50%; + border: 2px solid var(--bg-secondary); +} + +.comment-content { + flex: 1; + min-width: 0; +} + +.comment-header { + display: flex; + align-items: center; + gap: 12px; + margin-bottom: 10px; +} + +.comment-author { + font-weight: 600; + color: var(--text-primary); + font-size: 0.9375rem; +} + +.comment-author a { + color: var(--text-primary); + text-decoration: none; +} + +.comment-author a:hover { + color: var(--primary-color); +} + +.comment-header time { + font-size: 0.8125rem; + color: var(--text-muted); +} + +.comment-text { + color: var(--text-secondary); + line-height: 1.7; + font-size: 0.9375rem; +} + +.comment-text p:last-child { + margin-bottom: 0; +} + +.comment-actions { + margin-top: 12px; +} + +.comment-actions a { + display: inline-flex; + align-items: center; + gap: 6px; + font-size: 0.8125rem; + color: var(--text-muted); + font-weight: 500; + padding: 4px 10px; + border-radius: var(--radius-sm); + transition: var(--transition); +} + +.comment-actions a:hover { + color: var(--primary-color); + background: rgba(37, 99, 235, 0.05); +} + +/* Comment Form */ +.comment-form { + margin-top: 40px; + padding: 32px; + background: var(--bg-secondary); + border-radius: var(--radius-xl); + border: 1px solid var(--border-color); +} + +.comment-form-group { + margin-bottom: 20px; +} + +.comment-form-group label { + display: flex; + align-items: center; + gap: 8px; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 12px; + font-size: 0.9375rem; +} + +.comment-form-group label svg { + color: var(--primary-color); +} + +.comment-form-group textarea { + width: 100%; + padding: 16px; + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + font-size: 1rem; + font-family: var(--font-sans); + background: var(--bg-primary); + color: var(--text-primary); + resize: vertical; + min-height: 120px; + transition: var(--transition); +} + +.comment-form-group textarea:focus { + outline: none; + border-color: var(--primary-color); + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); +} + +.comment-form-group textarea::placeholder { + color: var(--text-muted); +} + +.comment-form .comment-form-cookies-consent { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 20px; + font-size: 0.875rem; + color: var(--text-secondary); +} + +.comment-form .comment-form-cookies-consent input[type="checkbox"] { + width: 18px; + height: 18px; + accent-color: var(--primary-color); +} + +.comment-form .submit-btn { + display: inline-flex; + align-items: center; + gap: 10px; + padding: 14px 28px; + background: var(--primary-color); + color: white; + border: none; + border-radius: var(--radius-md); + font-size: 1rem; + font-weight: 600; + font-family: var(--font-sans); + cursor: pointer; + transition: var(--transition); +} + +.comment-form .submit-btn:hover { + background: var(--primary-hover); + transform: translateY(-1px); + box-shadow: var(--shadow-md); +} + +.comment-form .submit-btn svg { + transition: transform 0.2s ease; +} + +.comment-form .submit-btn:hover svg { + transform: translateX(2px) translateY(-2px); +} + +.no-comments { + text-align: center; + padding: 32px; + color: var(--text-muted); + font-size: 0.9375rem; +} + +.post-header { + margin-bottom: 32px; + padding-bottom: 24px; + border-bottom: 1px solid var(--border-color); +} + +.post-header .post-category { + margin-bottom: 16px; +} + +.post-title { + font-size: 2.25rem; + font-weight: 800; + line-height: 1.3; + margin-bottom: 16px; + letter-spacing: -0.02em; +} + +.post-meta-full { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 20px; + color: var(--text-muted); + font-size: 0.9375rem; +} + +.post-meta-full a { + color: var(--text-muted); +} + +.post-meta-full a:hover { + color: var(--primary-color); +} + +.author-avatar { + width: 40px; + height: 40px; + border-radius: 50%; + background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)); + display: flex; + align-items: center; + justify-content: center; + color: white; + font-weight: 600; + font-size: 1rem; +} + +/* ==================== Post Content ==================== */ +.post-content { + font-size: 1.0625rem; + line-height: 1.8; + color: var(--text-primary); +} + +.post-content h2 { + font-size: 1.75rem; + font-weight: 700; + margin-top: 48px; + margin-bottom: 20px; + padding-bottom: 12px; + border-bottom: 2px solid var(--border-color); + letter-spacing: -0.01em; +} + +.post-content h3 { + font-size: 1.375rem; + font-weight: 600; + margin-top: 36px; + margin-bottom: 16px; +} + +.post-content h4 { + font-size: 1.125rem; + font-weight: 600; + margin-top: 28px; + margin-bottom: 12px; +} + +.post-content p { + margin-bottom: 20px; +} + +.post-content a { + color: var(--primary-color); + text-decoration: underline; + text-decoration-color: rgba(37, 99, 235, 0.3); + text-underline-offset: 3px; +} + +.post-content a:hover { + text-decoration-color: var(--primary-color); +} + +.post-content ul, +.post-content ol { + margin-bottom: 20px; + padding-left: 28px; +} + +.post-content li { + margin-bottom: 8px; +} + +.post-content li::marker { + color: var(--primary-color); +} + +.post-content blockquote { + margin: 24px 0; + padding: 20px 24px; + border-left: 4px solid var(--primary-color); + background: var(--bg-secondary); + border-radius: 0 var(--radius-md) var(--radius-md) 0; + font-style: italic; + color: var(--text-secondary); +} + +.post-content blockquote p:last-child { + margin-bottom: 0; +} + +.post-content img { + border-radius: var(--radius-md); + margin: 24px 0; + box-shadow: var(--shadow-md); +} + +.post-content hr { + border: none; + height: 1px; + background: var(--border-color); + margin: 40px 0; +} + +.post-content table { + width: 100%; + border-collapse: collapse; + margin: 24px 0; + font-size: 0.9375rem; +} + +.post-content th, +.post-content td { + padding: 12px 16px; + text-align: left; + border: 1px solid var(--border-color); +} + +.post-content th { + background: var(--bg-secondary); + font-weight: 600; + color: var(--text-primary); +} + +.post-content tr:hover { + background: var(--bg-secondary); +} + +/* Inline Code */ +.post-content code:not(pre code) { + background: var(--bg-tertiary); + color: var(--secondary-color); + padding: 2px 8px; + border-radius: 4px; + font-family: var(--font-mono); + font-size: 0.875em; + font-weight: 500; +} + +/* Code Blocks */ +.post-content pre { + background: var(--bg-code); + color: var(--text-code); + padding: 24px; + border-radius: var(--radius-md); + overflow-x: auto; + margin: 24px 0; + position: relative; + font-family: var(--font-mono); + font-size: 0.9375rem; + line-height: 1.6; + border: 1px solid rgba(255, 255, 255, 0.1); +} + +.post-content pre code { + background: none; + padding: 0; + color: inherit; + font-size: inherit; +} + +.code-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 16px; + background: rgba(0, 0, 0, 0.3); + border-radius: var(--radius-md) var(--radius-md) 0 0; + margin: -24px -24px 16px -24px; + font-size: 0.8125rem; +} + +.code-lang { + color: var(--accent-color); + font-weight: 600; + text-transform: uppercase; +} + +.copy-btn { + display: flex; + align-items: center; + gap: 6px; + background: none; + border: 1px solid rgba(255, 255, 255, 0.2); + color: rgba(255, 255, 255, 0.6); + padding: 6px 12px; + border-radius: var(--radius-sm); + cursor: pointer; + font-size: 0.75rem; + transition: var(--transition); +} + +.copy-btn:hover { + background: rgba(255, 255, 255, 0.1); + color: white; +} + +.copy-btn svg { + width: 14px; + height: 14px; +} + +/* ==================== Table of Contents ==================== */ +.toc-container { + position: sticky; + top: calc(var(--header-height) + 32px); +} + +.toc { + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 24px; + max-height: calc(100vh - var(--header-height) - 64px); + overflow-y: auto; +} + +.toc-title { + font-size: 0.875rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--text-muted); + margin-bottom: 16px; + display: flex; + align-items: center; + gap: 8px; +} + +.toc-title svg { + width: 16px; + height: 16px; +} + +.toc-list { + list-style: none; + padding: 0; +} + +.toc-list li { + margin-bottom: 4px; +} + +.toc-list a { + display: block; + padding: 8px 12px; + color: var(--text-secondary); + font-size: 0.875rem; + border-radius: var(--radius-sm); + border-left: 2px solid transparent; + transition: var(--transition); +} + +.toc-list a:hover { + color: var(--text-primary); + background: var(--bg-secondary); +} + +.toc-list a.active { + color: var(--primary-color); + background: rgba(37, 99, 235, 0.05); + border-left-color: var(--primary-color); + font-weight: 500; +} + +.toc-list .toc-h3 { + padding-left: 24px; + font-size: 0.8125rem; +} + +/* ==================== Sidebar ==================== */ +.sidebar { + position: sticky; + top: calc(var(--header-height) + 32px); + height: fit-content; +} + +.sidebar-widget { + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 24px; + margin-bottom: 24px; +} + +.widget-title { + font-size: 0.875rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--text-muted); + margin-bottom: 20px; + padding-bottom: 12px; + border-bottom: 2px solid var(--border-color); +} + +/* Categories Widget */ +.category-list { + list-style: none; +} + +.category-list li { + margin-bottom: 8px; +} + +.category-list a { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 14px; + color: var(--text-secondary); + background: var(--bg-secondary); + border-radius: var(--radius-sm); + font-size: 0.9375rem; + transition: var(--transition); +} + +.category-list a:hover { + background: var(--primary-color); + color: white; +} + +.category-count { + background: var(--bg-primary); + padding: 2px 10px; + border-radius: 100px; + font-size: 0.75rem; + font-weight: 600; +} + +.category-list a:hover .category-count { + background: rgba(255, 255, 255, 0.2); + color: white; +} + +/* Tags Widget */ +.tag-cloud { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.tag-cloud a { + display: inline-block; + padding: 6px 14px; + background: var(--bg-secondary); + color: var(--text-secondary); + border-radius: 100px; + font-size: 0.8125rem; + transition: var(--transition); +} + +.tag-cloud a:hover { + background: var(--primary-color); + color: white; +} + +/* Recent Posts Widget */ +.recent-posts-list { + list-style: none; +} + +.recent-posts-list li { + padding: 16px 0; + border-bottom: 1px solid var(--border-color); +} + +.recent-posts-list li:last-child { + border-bottom: none; + padding-bottom: 0; +} + +.recent-posts-list li:first-child { + padding-top: 0; +} + +.recent-post-title { + display: block; + font-size: 0.9375rem; + font-weight: 500; + color: var(--text-primary); + line-height: 1.4; + margin-bottom: 6px; +} + +.recent-post-title:hover { + color: var(--primary-color); +} + +.recent-post-date { + font-size: 0.8125rem; + color: var(--text-muted); +} + +/* ==================== Pagination ==================== */ +.pagination { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + margin-top: 48px; + padding-top: 32px; + border-top: 1px solid var(--border-color); +} + +.pagination a, +.pagination span { + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 40px; + padding: 0 12px; + border: 1px solid var(--border-color); + border-radius: var(--radius-sm); + font-size: 0.9375rem; + font-weight: 500; + transition: var(--transition); +} + +.pagination a { + color: var(--text-secondary); +} + +.pagination a:hover { + background: var(--bg-secondary); + color: var(--text-primary); + border-color: var(--border-hover); +} + +.pagination .current { + background: var(--primary-color); + color: white; + border-color: var(--primary-color); +} + +.pagination .dots { + border: none; + color: var(--text-muted); +} + +/* ==================== Search Overlay ==================== */ +.search-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(8px); + z-index: 2000; + display: flex; + align-items: flex-start; + justify-content: center; + padding-top: 20vh; + opacity: 0; + visibility: hidden; + transition: var(--transition); +} + +.search-overlay.active { + opacity: 1; + visibility: visible; +} + +.search-container { + background: var(--bg-primary); + border-radius: var(--radius-xl); + padding: 24px; + width: 90%; + max-width: 640px; + box-shadow: var(--shadow-lg); + transform: translateY(-20px); + transition: transform 0.3s ease; +} + +.search-overlay.active .search-container { + transform: translateY(0); +} + +.search-input-wrapper { + display: flex; + align-items: center; + gap: 12px; + padding: 12px 16px; + background: var(--bg-secondary); + border-radius: var(--radius-md); + border: 2px solid var(--border-color); + transition: var(--transition); +} + +.search-input-wrapper:focus-within { + border-color: var(--primary-color); +} + +.search-input-wrapper svg { + width: 20px; + height: 20px; + color: var(--text-muted); + flex-shrink: 0; +} + +.search-input { + flex: 1; + border: none; + background: none; + font-size: 1.0625rem; + color: var(--text-primary); + outline: none; +} + +.search-input::placeholder { + color: var(--text-muted); +} + +.search-hint { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 12px; + font-size: 0.8125rem; + color: var(--text-muted); +} + +.search-hint kbd { + background: var(--bg-tertiary); + padding: 2px 8px; + border-radius: 4px; + font-family: var(--font-mono); + font-size: 0.75rem; +} + +/* ==================== Footer ==================== */ +.site-footer { + background: var(--bg-secondary); + border-top: 1px solid var(--border-color); + padding: 48px 24px; + margin-top: 64px; +} + +.footer-inner { + max-width: var(--container-max-width); + margin: 0 auto; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 48px; +} + +.footer-section h3 { + font-size: 1rem; + font-weight: 600; + margin-bottom: 20px; + color: var(--text-primary); +} + +.footer-section p { + color: var(--text-secondary); + font-size: 0.9375rem; + line-height: 1.6; +} + +.footer-links { + list-style: none; +} + +.footer-links li { + margin-bottom: 10px; +} + +.footer-links a { + color: var(--text-secondary); + font-size: 0.9375rem; +} + +.footer-links a:hover { + color: var(--primary-color); +} + +.footer-bottom { + max-width: var(--container-max-width); + margin: 32px auto 0; + padding-top: 24px; + border-top: 1px solid var(--border-color); + display: flex; + align-items: center; + justify-content: space-between; + color: var(--text-muted); + font-size: 0.875rem; +} + +/* ==================== Responsive ==================== */ +@media (max-width: 1024px) { + .site-container { + grid-template-columns: 1fr; + } + + .sidebar { + position: static; + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 24px; + } + + .sidebar-widget { + margin-bottom: 0; + } + + .toc-container { + display: none; + } +} + +@media (max-width: 768px) { + :root { + --header-height: 56px; + } + + .header-inner { + padding: 0 16px; + } + + .main-nav { + display: none; + } + + .mobile-menu-toggle { + display: flex; + } + + .main-nav.active { + display: flex; + flex-direction: column; + position: absolute; + top: var(--header-height); + left: 0; + right: 0; + background: var(--bg-primary); + border-bottom: 1px solid var(--border-color); + padding: 16px; + box-shadow: var(--shadow-md); + } + + .main-nav.active a { + padding: 12px 16px; + } + + .site-container { + padding: 20px 16px; + gap: 24px; + } + + .hero-section { + padding: 32px 24px; + } + + .hero-title { + font-size: 1.5rem; + } + + .post-card { + padding: 20px; + } + + .post-title { + font-size: 1.75rem; + } + + .post-content pre { + padding: 16px; + margin-left: -16px; + margin-right: -16px; + border-radius: 0; + } + + .sidebar { + grid-template-columns: 1fr; + } + + .footer-inner { + grid-template-columns: 1fr; + gap: 32px; + } + + .footer-bottom { + flex-direction: column; + gap: 12px; + text-align: center; + } +} + +/* ==================== Animations ==================== */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +.post-card { + animation: fadeIn 0.5s ease forwards; +} + +.post-card:nth-child(2) { animation-delay: 0.1s; } +.post-card:nth-child(3) { animation-delay: 0.2s; } +.post-card:nth-child(4) { animation-delay: 0.3s; } + +/* ==================== Print Styles ==================== */ +@media print { + .site-header, + .sidebar, + .toc-container, + .post-card-footer, + .pagination { + display: none !important; + } + + .site-container { + grid-template-columns: 1fr; + } + + .post-content pre { + white-space: pre-wrap; + word-wrap: break-word; + } +}