diff --git a/Plugin.php b/Plugin.php
new file mode 100644
index 0000000..f6d67c5
--- /dev/null
+++ b/Plugin.php
@@ -0,0 +1,1165 @@
+footer = array('RelatedPosts_Plugin', 'footer');
+ return _t('插件已激活');
+ }
+
+ public static function deactivate()
+ {
+ return _t('插件已禁用');
+ }
+
+ public static function config(Typecho_Widget_Helper_Form $form)
+ {
+ // 上一篇/下一篇设置
+ $showNav = new Typecho_Widget_Helper_Form_Element_Radio(
+ 'showNav',
+ array('1' => _t('显示'), '0' => _t('不显示')),
+ '1',
+ _t('是否显示上一篇/下一篇导航')
+ );
+ $form->addInput($showNav);
+
+ // 相关推荐设置
+ $showRelated = new Typecho_Widget_Helper_Form_Element_Radio(
+ 'showRelated',
+ array('1' => _t('显示'), '0' => _t('不显示')),
+ '1',
+ _t('是否显示相关推荐')
+ );
+ $form->addInput($showRelated);
+
+ // 显示数量
+ $postsNum = new Typecho_Widget_Helper_Form_Element_Text(
+ 'postsNum', NULL, '6',
+ _t('相关文章显示数量'),
+ _t('每次显示的相关文章数量')
+ );
+ $form->addInput($postsNum->addRule('isInteger', _t('请输入整数')));
+
+ // 卡片尺寸
+ $cardSize = new Typecho_Widget_Helper_Form_Element_Radio(
+ 'cardSize',
+ array(
+ 'small' => _t('小卡片'),
+ 'medium' => _t('中卡片'),
+ 'large' => _t('大卡片')
+ ),
+ 'small',
+ _t('相关推荐卡片尺寸')
+ );
+ $form->addInput($cardSize);
+ }
+
+ public static function personalConfig(Typecho_Widget_Helper_Form $form){}
+
+ /**
+ * 获取上一篇/下一篇文章
+ */
+ private static function getAdjacentPosts($cid)
+ {
+ $db = Typecho_Db::get();
+
+ $prevPost = $db->fetchRow($db->select()->from('table.contents')
+ ->where('cid < ?', $cid)
+ ->where('type = ?', 'post')
+ ->where('status = ?', 'publish')
+ ->order('cid', Typecho_Db::SORT_DESC)
+ ->limit(1));
+
+ $nextPost = $db->fetchRow($db->select()->from('table.contents')
+ ->where('cid > ?', $cid)
+ ->where('type = ?', 'post')
+ ->where('status = ?', 'publish')
+ ->order('cid', Typecho_Db::SORT_ASC)
+ ->limit(1));
+
+ return array(
+ 'prev' => $prevPost,
+ 'next' => $nextPost
+ );
+ }
+
+ /**
+ * 获取文章封面 - 增强版:支持各种图片格式和插件排版
+ */
+ private static function getPostThumbnail($postArray)
+ {
+ if (!is_array($postArray) || empty($postArray)) {
+ return '';
+ }
+
+ // 方法1:优先检查自定义字段缩略图
+ $thumbnail = self::getThumbnailFromFields($postArray);
+ if (!empty($thumbnail)) {
+ return $thumbnail;
+ }
+
+ $text = isset($postArray['text']) ? $postArray['text'] : '';
+
+ // 如果文章内容为空,返回空
+ if (empty($text)) {
+ return '';
+ }
+
+ // 方法2:使用DOM解析器提取图片(最可靠的方法)
+ $thumbnail = self::extractImageWithDom($text);
+ if (!empty($thumbnail)) {
+ return $thumbnail;
+ }
+
+ // 方法3:使用正则表达式匹配多种格式
+ $thumbnail = self::extractImageWithRegex($text);
+ if (!empty($thumbnail)) {
+ return $thumbnail;
+ }
+
+ // 没有找到图片
+ return '';
+ }
+
+ /**
+ * 从自定义字段获取缩略图
+ */
+ private static function getThumbnailFromFields($postArray)
+ {
+ if (isset($postArray['fields'])) {
+ try {
+ if (is_string($postArray['fields'])) {
+ $fields = @unserialize($postArray['fields']);
+ if (is_array($fields)) {
+ // 尝试常见的缩略图字段名
+ $thumbnailFields = ['thumb', 'thumbnail', 'cover', 'image', 'featured_image'];
+ foreach ($thumbnailFields as $field) {
+ if (!empty($fields[$field])) {
+ $thumb = trim($fields[$field]);
+ return self::processImageUrl($thumb);
+ }
+ }
+
+ // 检查所有字段,寻找可能的图片URL
+ foreach ($fields as $fieldValue) {
+ if (is_string($fieldValue) && !empty($fieldValue)) {
+ $fieldValue = trim($fieldValue);
+ // 检查是否是图片URL
+ if (preg_match('/\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i', $fieldValue) ||
+ preg_match('/
]+src=["\']([^"\']+)["\']/i', $fieldValue, $matches)) {
+
+ $thumb = !empty($matches[1]) ? $matches[1] : $fieldValue;
+ return self::processImageUrl($thumb);
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception $e) {
+ // 忽略错误,继续其他方法
+ }
+ }
+
+ return '';
+ }
+
+ /**
+ * 使用DOM解析器提取图片(最可靠)
+ */
+ private static function extractImageWithDom($html)
+ {
+ // 检查是否支持DOMDocument
+ if (!class_exists('DOMDocument')) {
+ return '';
+ }
+
+ try {
+ $dom = new DOMDocument();
+ libxml_use_internal_errors(true); // 抑制HTML解析错误
+
+ // 添加HTML包装,确保能正确解析片段
+ $wrappedHtml = '
' . $html . '';
+ $dom->loadHTML($wrappedHtml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
+
+ $images = $dom->getElementsByTagName('img');
+
+ // 查找第一张合适的图片
+ foreach ($images as $img) {
+ // 尝试多个可能的src属性
+ $src = $img->getAttribute('src');
+ if (empty($src)) {
+ $src = $img->getAttribute('data-src'); // 懒加载图片
+ }
+ if (empty($src)) {
+ $src = $img->getAttribute('data-lazy-src'); // WordPress懒加载
+ }
+ if (empty($src)) {
+ $src = $img->getAttribute('data-original'); // 其他懒加载
+ }
+
+ // 跳过base64图片和空src
+ if (!empty($src) && strpos($src, 'data:image') !== 0) {
+ // 检查图片尺寸,跳过太小的图标
+ $width = $img->getAttribute('width');
+ $height = $img->getAttribute('height');
+
+ // 如果不是图标大小,返回它
+ if ((empty($width) || $width > 50) && (empty($height) || $height > 50)) {
+ $processedUrl = self::processImageUrl($src);
+ if (!empty($processedUrl)) {
+ return $processedUrl;
+ }
+ }
+ }
+ }
+
+ // 如果没有找到合适的img标签,检查背景图片
+ $elements = $dom->getElementsByTagName('*');
+ foreach ($elements as $element) {
+ $style = $element->getAttribute('style');
+ if (preg_match('/background(-image)?\s*:\s*url\(["\']?([^"\'()]+)["\']?\)/i', $style, $matches)) {
+ if (!empty($matches[2])) {
+ $processedUrl = self::processImageUrl($matches[2]);
+ if (!empty($processedUrl)) {
+ return $processedUrl;
+ }
+ }
+ }
+ }
+
+ } catch (Exception $e) {
+ // 忽略DOM解析错误
+ }
+
+ return '';
+ }
+
+ /**
+ * 使用正则表达式提取图片
+ */
+ private static function extractImageWithRegex($text)
+ {
+ // 解码HTML实体
+ $text = html_entity_decode($text, ENT_QUOTES, 'UTF-8');
+
+ // 定义多个匹配模式(按优先级排序)
+ $patterns = [
+ // 标准img标签,支持各种属性
+ '/
]+(?:src|data-src|data-lazy-src|data-original)=["\']([^"\'>]+)["\'][^>]*>/i',
+
+ // Markdown图片格式
+ '/!\[[^\]]*\]\(([^)]+)\)/i',
+
+ // 背景图片
+ '/background(-image)?:\s*url\(["\']?([^"\'()]+)["\']?\)/i',
+
+ // 简化的img标签(没有引号)
+ '/
]+(?:src|data-src|data-lazy-src|data-original)=([^ >]+)[^>]*>/i',
+
+ // 直接匹配图片URL(最后的手段)
+ '/(https?:\/\/[^\s<>"\']+\.(?:jpg|jpeg|png|gif|webp|bmp|svg)(?:\?[^\s<>"\']*)?)/i'
+ ];
+
+ foreach ($patterns as $pattern) {
+ if (preg_match($pattern, $text, $matches)) {
+ // 确定哪个分组包含URL
+ $url = null;
+ for ($i = 1; $i < count($matches); $i++) {
+ if (!empty($matches[$i]) && strpos($matches[$i], 'http') !== false) {
+ $url = trim($matches[$i]);
+ break;
+ }
+ }
+
+ if (!empty($url)) {
+ // 清理URL
+ $url = preg_replace('/["\']$/', '', $url); // 移除末尾的引号
+ $url = preg_replace('/\?.*$/', '', $url); // 移除查询参数
+
+ // 跳过base64和占位符
+ if (strpos($url, 'data:image') === 0 ||
+ strpos($url, 'placeholder') !== false ||
+ strpos($url, 'blank') !== false) {
+ continue;
+ }
+
+ $processedUrl = self::processImageUrl($url);
+ if (!empty($processedUrl)) {
+ return $processedUrl;
+ }
+ }
+ }
+ }
+
+ return '';
+ }
+
+ /**
+ * 处理图片URL,将相对路径转为绝对路径
+ */
+ private static function processImageUrl($url)
+ {
+ if (empty($url)) {
+ return '';
+ }
+
+ $url = trim($url);
+
+ // 跳过base64图片
+ if (strpos($url, 'data:image') === 0) {
+ return '';
+ }
+
+ // 已经是完整URL或协议相对URL
+ if (strpos($url, 'http') === 0 || strpos($url, '//') === 0) {
+ return filter_var($url, FILTER_VALIDATE_URL) ? $url : '';
+ }
+
+ // 相对路径处理
+ $options = Helper::options();
+ $siteUrl = rtrim($options->siteUrl, '/');
+
+ // 清理URL
+ $url = ltrim($url, './');
+
+ // 如果以斜杠开头,直接拼接
+ if (strpos($url, '/') === 0) {
+ return $siteUrl . $url;
+ }
+
+ // 否则添加到站点URL后
+ return $siteUrl . '/' . $url;
+ }
+
+ /**
+ * 获取相关文章 - 确保按分类推荐
+ */
+ public static function getRelatedPosts($cid, $limit = 6)
+ {
+ $db = Typecho_Db::get();
+
+ try {
+ // 首先获取当前文章的所有分类ID
+ $currentCats = $db->fetchAll($db->select('mid')
+ ->from('table.relationships')
+ ->where('cid = ?', $cid));
+
+ $related = array();
+
+ if (!empty($currentCats)) {
+ $catIds = array();
+ foreach ($currentCats as $cat) {
+ $catIds[] = $cat['mid'];
+ }
+
+ // 获取这些分类下的所有文章(不包括当前文章)
+ $postsInCats = $db->fetchAll($db->select('DISTINCT c.cid')
+ ->from('table.contents AS c')
+ ->join('table.relationships AS r', 'c.cid = r.cid')
+ ->where('c.type = ?', 'post')
+ ->where('c.status = ?', 'publish')
+ ->where('c.cid != ?', $cid)
+ ->where('r.mid IN ?', $catIds)
+ ->order('RAND()'));
+
+ // 如果分类下的文章足够,直接随机选取
+ if (count($postsInCats) >= $limit) {
+ shuffle($postsInCats);
+ $selectedCids = array_slice($postsInCats, 0, $limit);
+ $selectedCids = array_column($selectedCids, 'cid');
+
+ // 获取这些文章的完整信息
+ $related = $db->fetchAll($db->select()
+ ->from('table.contents')
+ ->where('type = ?', 'post')
+ ->where('status = ?', 'publish')
+ ->where('cid IN ?', $selectedCids));
+ }
+ // 如果分类下的文章不足,先显示分类下的,再补充随机
+ else {
+ // 先获取分类下的所有文章
+ $related = $db->fetchAll($db->select('c.*')
+ ->from('table.contents AS c')
+ ->join('table.relationships AS r', 'c.cid = r.cid')
+ ->where('c.type = ?', 'post')
+ ->where('c.status = ?', 'publish')
+ ->where('c.cid != ?', $cid)
+ ->where('r.mid IN ?', $catIds)
+ ->group('c.cid')
+ ->limit($limit));
+
+ // 如果还不够,补充随机文章
+ if (count($related) < $limit) {
+ $need = $limit - count($related);
+ $exclude = array($cid);
+ foreach ($related as $post) {
+ $exclude[] = $post['cid'];
+ }
+
+ $random = $db->fetchAll($db->select()
+ ->from('table.contents')
+ ->where('type = ?', 'post')
+ ->where('status = ?', 'publish')
+ ->where('cid NOT IN ?', $exclude)
+ ->order('RAND()')
+ ->limit($need));
+
+ $related = array_merge($related, $random);
+ }
+ }
+ }
+ // 如果文章没有分类,直接返回随机文章
+ else {
+ $related = $db->fetchAll($db->select()
+ ->from('table.contents')
+ ->where('type = ?', 'post')
+ ->where('status = ?', 'publish')
+ ->where('cid != ?', $cid)
+ ->order('RAND()')
+ ->limit($limit));
+ }
+
+ // 确保返回数量正确
+ if (count($related) > $limit) {
+ $related = array_slice($related, 0, $limit);
+ }
+
+ } catch (Exception $e) {
+ // 出错时返回随机文章
+ $related = $db->fetchAll($db->select()
+ ->from('table.contents')
+ ->where('type = ?', 'post')
+ ->where('status = ?', 'publish')
+ ->where('cid != ?', $cid)
+ ->order('RAND()')
+ ->limit($limit));
+ }
+
+ return $related;
+ }
+
+ /**
+ * 生成文章链接
+ */
+ private static function getPermalink($postArray)
+ {
+ if (!is_array($postArray) || empty($postArray)) {
+ return '#';
+ }
+
+ $options = Helper::options();
+ $slug = isset($postArray['slug']) ? $postArray['slug'] : '';
+
+ if (!empty($slug)) {
+ return Typecho_Common::url($slug . '.html', $options->index);
+ } else {
+ $cid = isset($postArray['cid']) ? $postArray['cid'] : 0;
+ return Typecho_Common::url('archives/' . $cid . '/', $options->index);
+ }
+ }
+
+ /**
+ * 输出文章导航和相关推荐
+ */
+ public static function output()
+ {
+ if (!Typecho_Widget::widget('Widget_Archive')->is('single')) {
+ return;
+ }
+
+ $widget = Typecho_Widget::widget('Widget_Archive');
+ $options = Helper::options();
+ $config = $options->plugin('RelatedPosts');
+ $currentCid = $widget->cid;
+
+ // 生成随机种子,确保每次刷新都不同
+ $randomSeed = isset($_GET['refresh_related']) ? intval($_GET['refresh_related']) : 1;
+
+ $html = '';
+
+ // 输出CSS样式(内联在HTML中,避免FOUC)
+ $html .= '';
+
+ // 输出上一篇/下一篇导航(如果启用)
+ if ($config->showNav) {
+ $adjacent = self::getAdjacentPosts($currentCid);
+
+ $html .= '
';
+
+ // 上一篇
+ if (!empty($adjacent['prev'])) {
+ $prev = $adjacent['prev'];
+ $prevPermalink = self::getPermalink($prev);
+ $prevTitle = isset($prev['title']) ? $prev['title'] : '';
+
+ $html .= '
';
+ $html .= '';
+ $html .= '上一篇';
+ $html .= '' . htmlspecialchars(self::truncateText($prevTitle, 20)) . '';
+ $html .= '
';
+ $html .= '';
+ } else {
+ $html .= '
';
+ $html .= '
';
+ $html .= '上一篇';
+ $html .= '没有更多了';
+ $html .= '
';
+ $html .= '
';
+ }
+
+ // 首页链接 - 更换为更简单好看的图标
+ $html .= '
';
+ $html .= '';
+ $html .= '';
+
+ // 下一篇
+ if (!empty($adjacent['next'])) {
+ $next = $adjacent['next'];
+ $nextPermalink = self::getPermalink($next);
+ $nextTitle = isset($next['title']) ? $next['title'] : '';
+
+ $html .= '
';
+ $html .= '';
+ $html .= '下一篇';
+ $html .= '' . htmlspecialchars(self::truncateText($nextTitle, 20)) . '';
+ $html .= '
';
+ $html .= '';
+ } else {
+ $html .= '
';
+ $html .= '
';
+ $html .= '下一篇';
+ $html .= '没有更多了';
+ $html .= '
';
+ $html .= '
';
+ }
+
+ $html .= '
';
+ }
+
+ // 输出相关推荐(如果启用)
+ if ($config->showRelated) {
+ $relatedPosts = self::getRelatedPosts($currentCid, $config->postsNum);
+
+ if (!empty($relatedPosts)) {
+ $cardSize = isset($config->cardSize) ? $config->cardSize : 'small';
+
+ $html .= '
';
+ $html .= '';
+ $html .= '
';
+
+ foreach ($relatedPosts as $post) {
+ $html .= self::getPostCardHtml($post);
+ }
+
+ $html .= '
';
+ $html .= '
';
+ }
+ }
+
+ $html .= '
';
+
+ echo $html;
+ }
+
+ /**
+ * 生成文章卡片HTML
+ */
+ private static function getPostCardHtml($postArray)
+ {
+ if (!is_array($postArray) || empty($postArray)) {
+ return '';
+ }
+
+ $title = isset($postArray['title']) ? $postArray['title'] : '无标题';
+ $created = isset($postArray['created']) ? $postArray['created'] : time();
+ $commentsNum = isset($postArray['commentsNum']) ? $postArray['commentsNum'] : 0;
+
+ $permalink = self::getPermalink($postArray);
+
+ // 获取封面图 - 使用增强的方法
+ $thumbnail = self::getPostThumbnail($postArray);
+
+ $html = '';
+
+ if (!empty($thumbnail)) {
+ $html .= '
';
+ } else {
+ $html .= '
';
+ }
+
+ $html .= '
';
+ $html .= '
';
+ $html .= '
';
+
+ $html .= '
';
+
+ return $html;
+ }
+
+ /**
+ * 截断文本
+ */
+ private static function truncateText($text, $length = 20)
+ {
+ if (mb_strlen($text, 'UTF-8') > $length) {
+ return mb_substr($text, 0, $length, 'UTF-8') . '...';
+ }
+ return $text;
+ }
+
+ /**
+ * 输出CSS
+ */
+ public static function footer()
+ {
+ // 保留footer方法,但不输出任何内容(因为CSS已经内联了)
+ // 这个方法只是为了保持向后兼容性
+ }
+
+ /**
+ * 获取CSS样式
+ */
+ private static function getStyles()
+ {
+ // 返回您原始的CSS,完全不变
+ return '
+ /* 上一篇下一篇标题只显示一行 */
+ .posts-navigation .nav-title {
+ font-size: 15px;
+ font-weight: 500;
+ line-height: 1.3;
+ display: -webkit-box;
+ -webkit-line-clamp: 1;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ .posts-navigation .nav-title.single-line {
+ -webkit-line-clamp: 1;
+ }
+
+ /* 导航和相关推荐容器 */
+ .posts-navigation-container {
+ margin: 30px 0 0px;
+ max-width: 100%;
+ }
+
+ /* 上一篇/下一篇导航 */
+ .posts-navigation {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 20px;
+ margin-bottom: 30px;
+ padding: 20px;
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
+ border-radius: 20px;
+ border: 1px solid #dc2626;
+ border-bottom: 0px solid #dc2626;
+ border-top: 0px solid #dc2626;
+ }
+
+ .posts-navigation .nav-prev,
+ .posts-navigation .nav-next {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ padding: 15px;
+ background: #fff;
+ border-radius: 8px;
+ text-decoration: none;
+ color: #333;
+ border: 1px solid #e1e5e9;
+ transition: all 0.3s ease;
+ min-height: 70px;
+ }
+
+ .posts-navigation .nav-prev:hover,
+ .posts-navigation .nav-next:hover {
+ transform: translateY(-2px);
+ border-color: #1e87f0;
+ color: #1e87f0;
+ }
+
+ .posts-navigation .nav-prev.disabled,
+ .posts-navigation .nav-next.disabled {
+ background: #f8f9fa;
+ color: #999;
+ cursor: not-allowed;
+ opacity: 0.7;
+ }
+
+ .posts-navigation .nav-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .posts-navigation .nav-label {
+ font-size: 12px;
+ color:rgb(156 163 175 / var(--tw-text-opacity));
+ margin-bottom: 4px;
+ }
+
+ /* 首页链接 - 更换为更简单大气的图标 */
+ .posts-navigation .nav-home {
+ width: 50px;
+ height: 50px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(135deg, #1e87f0 0%, #0d6efd 100%);
+ border-radius: 50%;
+ text-decoration: none;
+ color: white;
+ border: 1px solid #1e87f0;
+ transition: all 0.3s ease;
+ font-size: 20px;
+ }
+
+ .posts-navigation .nav-home:hover {
+ background: linear-gradient(135deg, #0d6efd 0%, #0b5ed7 100%);
+ transform: scale(1.1);
+ border-color: #0d6efd;
+ }
+
+ /* 相关推荐部分 */
+ .related-posts-section {
+ background: #f8f9fa;
+ border-radius: 20px;
+ padding: 25px;
+ border: 1px solid #dc2626;
+ border-bottom: 0px solid #dc2626;
+ border-top: 0px solid #dc2626;
+ }
+
+ .related-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 25px;
+ padding-bottom: 15px;
+ border-bottom: 2px solid #e8e8e8;
+ }
+
+ .related-title {
+ margin: 0;
+ font-size: 20px;
+ font-weight: 600;
+ color: #333;
+ position: relative;
+ padding-left: 0; /* 移除左边的内边距 */
+ }
+
+ /* 移除相关推荐标题前的竖线 */
+ .related-title:before {
+ display: none; /* 隐藏竖线 */
+ }
+
+ .refresh-btn {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 20px;
+ background: #fff;
+ border: 1px solid #ddd;
+ border-radius: 6px;
+ color: #666;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 500;
+ transition: all 0.3s ease;
+ text-decoration: none;
+ }
+
+ .refresh-btn:hover {
+ background: #1e87f0;
+ color: #fff;
+ transform: translateY(-1px);
+ box-shadow: 0 3px 10px rgba(30, 135, 240, 0.2);
+ border-color: #1e87f0;
+ }
+
+ .refresh-icon {
+ font-size: 16px;
+ font-weight: bold;
+ display: inline-block;
+ animation: spin 1.5s linear infinite;
+ }
+
+ @keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+ }
+
+ .refresh-btn:hover .refresh-icon {
+ animation: spin 0.8s linear infinite;
+ }
+
+ /* 相关文章网格 */
+ .related-posts-grid {
+ display: grid;
+ gap: 20px;
+ }
+
+ /* 小卡片样式 */
+ .card-size-small .related-posts-grid {
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
+ }
+
+ .card-size-small .related-post-card {
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ transition: all 0.3s ease;
+ border: 1px solid #eee;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ }
+
+ .card-size-small .post-thumb {
+ width: 100%;
+ height: 120px;
+ overflow: hidden;
+ background: #f5f5f5;
+ position: relative;
+ }
+
+ .card-size-small .post-thumb img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.6s ease;
+ }
+
+ /* 中卡片样式 */
+ .card-size-medium .related-posts-grid {
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
+ }
+
+ .card-size-medium .related-post-card {
+ background: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ transition: all 0.3s ease;
+ border: 1px solid #eee;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ }
+
+ .card-size-medium .post-thumb {
+ width: 100%;
+ height: 160px;
+ overflow: hidden;
+ background: #f5f5f5;
+ position: relative;
+ }
+
+ .card-size-medium .post-thumb img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.6s ease;
+ }
+
+ /* 大卡片样式 */
+ .card-size-large .related-posts-grid {
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+ gap: 24px;
+ }
+
+ .card-size-large .related-post-card {
+ background: #fff;
+ border-radius: 10px;
+ overflow: hidden;
+ transition: all 0.3s ease;
+ border: 1px solid #eee;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ }
+
+ .card-size-large .post-thumb {
+ width: 100%;
+ height: 180px;
+ overflow: hidden;
+ background: #f5f5f5;
+ position: relative;
+ }
+
+ .card-size-large .post-thumb img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.6s ease;
+ }
+
+ /* 通用卡片悬停效果 */
+ .related-post-card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 25px rgba(0,0,0,0.1);
+ border-color: #1e87f0;
+ }
+
+ .related-post-card:hover .post-thumb img {
+ transform: scale(1.08);
+ }
+
+ /* 封面图片上的标签 - 添加透明度 */
+ .post-date-overlay {
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ background: #f15a22;
+ opacity:0.5;
+ color: white;
+ font-size: 12px;
+ padding: 3px 8px;
+ border-radius: 3px;
+ font-weight: 500;
+ }
+
+ .post-comments-overlay {
+ position: absolute;
+ top: 8px;
+ right: 8px;
+ background:#f15a22;
+ color: white;
+ opacity:0.5;
+ font-size: 12px;
+ padding: 3px 8px;
+ border-radius: 3px;
+ font-weight: 500;
+ }
+
+ /* 无缩略图样式 */
+ .post-thumb.no-thumb {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ }
+
+ .no-thumb-placeholder {
+ font-size: 32px;
+ opacity: 0.7;
+ color: white;
+ }
+
+ /* 内容区域 */
+ .post-content {
+ padding: 15px;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .post-title {
+ margin: 0;
+ font-size: 14px;
+ line-height: 1.4;
+ font-weight: 500;
+ }
+
+ .card-size-medium .post-title {
+ font-size: 16px;
+ }
+
+ .card-size-large .post-title {
+ font-size: 17px;
+ }
+
+ .post-title a {
+ color: #333;
+ text-decoration: none;
+ transition: color 0.3s;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ }
+
+ .post-title a:hover {
+ color: #1e87f0;
+ }
+
+ /* 响应式设计 */
+ @media (max-width: 768px) {
+ .posts-navigation {
+ flex-direction: column;
+ gap: 15px;
+ }
+
+ .posts-navigation .nav-prev,
+ .posts-navigation .nav-next {
+ width: 100%;
+ }
+
+ .posts-navigation .nav-home {
+ order: 3;
+ width: 100%;
+ height: auto;
+ border-radius: 8px;
+ padding: 12px;
+ }
+
+ .related-header {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 15px;
+ }
+
+ .refresh-btn {
+ align-self: flex-start;
+ }
+
+ .card-size-large .related-posts-grid,
+ .card-size-medium .related-posts-grid,
+ .card-size-small .related-posts-grid {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 15px;
+ }
+ }
+
+ @media (max-width: 480px) {
+ .related-posts-section {
+ padding: 20px;
+ }
+
+ .card-size-large .related-posts-grid,
+ .card-size-medium .related-posts-grid,
+ .card-size-small .related-posts-grid {
+ grid-template-columns: 1fr;
+ gap: 15px;
+ }
+
+ .posts-navigation {
+ padding: 15px;
+ }
+ }
+
+ /* 夜间模式支持 */
+ .dark .posts-navigation {
+ background: #1d1d1e;
+ border: 1px solid #dc2626;
+ border-bottom: 0px solid #dc2626;
+ border-top: 0px solid #dc2626;
+ }
+
+ .dark .posts-navigation .nav-prev,
+ .dark .posts-navigation .nav-next,
+ .dark .posts-navigation .nav-home {
+ background: rgb(10 12 25 / 1);
+ border-color: #333;
+ color:rgb(156 163 175 / var(--tw-text-opacity));
+ }
+
+
+ .dark .posts-navigation .nav-prev.disabled,
+ .dark .posts-navigation .nav-next.disabled {
+ background: #4a5568;
+ color: #a0aec0;
+ }
+
+ .dark .posts-navigation .nav-home {
+ background: rgb(10 12 25 / 1);
+ border-color: #333;
+ }
+ .dark .related-posts-section {
+ background: #1d1d1e;
+ border: 1px solid #dc2626;
+ border-bottom: 0px solid #dc2626;
+ border-top: 0px solid #dc2626;
+ }
+
+ .dark .related-header {
+ border-color: #333;
+ }
+
+ .dark .related-title {
+ color: rgb(156 163 175 / var(--tw-text-opacity));
+ }
+
+ .dark .refresh-btn {
+ background: rgb(10 12 25 / 1);
+ color:rgb(156 163 175 / var(--tw-text-opacity));
+ border-color: #333;
+ }
+
+
+ .dark .related-post-card {
+ background: rgb(10 12 25 / 1);
+ border-color: #333;
+ }
+
+ .dark .post-title a {
+ color: rgb(156 163 175 / var(--tw-text-opacity));
+ }
+
+ .dark .post-title a:hover {
+ color: #f15a22;
+ }
+
+ .dark .post-thumb {
+ background: #718096;
+ }
+
+ .dark .post-thumb.no-thumb {
+ background: linear-gradient(135deg, #4c51bf 0%, #805ad5 100%);
+ }
+
+ .dark .post-date-overlay {
+ background:#f15a22;
+ color: #fff;
+ }
+
+ .dark .post-comments-overlay {
+ background: #f15a22;
+ color:#fff;
+ }
+ ';
+ }
+}
\ No newline at end of file