diff --git a/assets/css/build/comments.css b/assets/css/build/comments.css new file mode 100644 index 00000000..d0c5def1 --- /dev/null +++ b/assets/css/build/comments.css @@ -0,0 +1,45 @@ +/* source: assets/css/frontend/comments/shell.css */ +/* ============================================================ + * AKSRT Comments — 补充层 + * + * 评论区的全部样式以 vendor 的 legacy 正版样式为准: + * assets/css/main.min.css(含 #comments/#postcomments + * 桌面规则与移动端媒体查询:.mobile-fixed/.virtual-input/.pagenav/ + * .tab-nav-theme/.dropdown-menu/.line-form/.placeholder 等) + * + bootstrap 3(.list-unstyled/.list-inline) + * + * 本文件只补 AKSRT 特有标记的样式,禁止复制 legacy 规则—— + * 带 #comments id 前缀的副本会覆盖 vendor 正版样式造成 UI 偏差。 + * ============================================================ */ + +/* 身份徽章(AKSRT 渲染于 内,对应 legacy 的认证/等级徽章位) */ +#comments .comment-header .aksrt-identity-chip { + display: inline-flex; + align-items: center; + gap: 3px; + vertical-align: middle; + max-width: 9em; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 11px; +} + +#comments .comment-header .aksrt-identity-medal { + display: inline-block; + width: auto; + height: 1.1em; + max-width: 6em; + object-fit: contain; + vertical-align: -0.15em; +} + +/* source: assets/css/frontend/comments/mobile-item.css */ +/* ============================================================ + * AKSRT Comments 移动端 — 补充层 + * + * 移动端评论样式(.mobile-fixed 弹层、.virtual-input 假输入、 + * 头像/缩进/分页的移动端覆盖)全部由 vendor main.min.css 的 + * @media (max-width:767px) 提供,此处不复制,避免覆盖正版样式。 + * 目前无补充规则,保留文件以维持 enqueue 句柄链。 + * ============================================================ */ diff --git a/assets/css/build/comments.min.css b/assets/css/build/comments.min.css new file mode 100644 index 00000000..cadd8cd2 --- /dev/null +++ b/assets/css/build/comments.min.css @@ -0,0 +1 @@ +#comments .comment-header .aksrt-identity-chip{display:inline-flex;align-items:center;gap:3px;vertical-align:middle;max-width:9em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}#comments .comment-header .aksrt-identity-medal{display:inline-block;width:auto;height:1.1em;max-width:6em;object-fit:contain;vertical-align:-.15em} diff --git a/assets/css/build/single.css b/assets/css/build/single.css new file mode 100644 index 00000000..c65f7150 --- /dev/null +++ b/assets/css/build/single.css @@ -0,0 +1,1405 @@ +/* source: assets/css/frontend/legacy-utilities.css */ +/** + * legacy utility class bridge + * + * Single / author / meta markup still uses legacy utility class names + * (.flex / .ac / .jsb / .abs-right / .muted-2-color / …). Without these + * helpers the author bar and meta row collapse into a vertical mess. + * + * Keep this file tiny and pure utility — domain styles stay in single-post/*. + */ + +/* Layout helpers */ +.relative { position: relative; } +.flex { display: flex; } +.flex.ac, +.ac { align-items: center; } +.flex.jc, +.jc { justify-content: center; } +.flex.jsb, +.jsb { justify-content: space-between; } +.flex.at, +.at { align-items: flex-start; } +.flex.ae, +.ae { align-items: flex-end; } +.flex0 { flex: 0 0 auto; } +.flex1 { flex: 1 1 auto; min-width: 0; } +.flex.column { flex-direction: column; } +.flex.wrap { flex-wrap: wrap; } +.flex.flex-row, +.flex-row { flex-direction: row; } +.flex.jse, +.jse { justify-content: space-evenly; } +.flex.jsa, +.jsa { justify-content: space-around; } +/* Nested flex1 (legacy .flex .flex1) — allow both direct and descendant */ +.flex > .flex1, +.flex .flex1 { flex: 1; overflow: hidden; min-width: 0; } +.relative-h { position: relative; height: 100%; } +.padding-10 { padding: 10px; } +.font-bold { font-weight: bold; } +.mt6 { margin-top: 6px; } +.gutters-5 { margin: -5px; } +.gutters-5 > * { padding: 5px; } +@media (max-width: 767px) { + .flex.flex-row.flex-col-sm-2 { + flex-wrap: wrap; + } + .flex.flex-row.flex-col-sm-2 > * { + flex-basis: 50%; + } +} + +.clearfix::before, +.clearfix::after { + content: ""; + display: table; +} + +.clearfix::after { + clear: both; +} + +.abs-right { + position: absolute; + right: 0; + top: 0; +} + +/* legacy .abs-center: full-width vertical center (translateY only). + * Header search and slide-text rely on this model. Point-center + * (left:50% + translate(-50%,-50%)) is NOT used for these layers. */ +.abs-center { + position: absolute; + left: 0; + width: 100%; + top: 50%; + right: 0.7em; + transform: translateY(-50%); + z-index: 1; +} + +/* legacy abs-center position variants (main.css) */ +.abs-center.left-top, +.abs-center.right-top { + transform: unset; + top: 0; +} + +.abs-center.right-top { + left: auto; + width: auto; + text-align: right; +} + +.abs-center.left-top { + text-align: left; +} + +.abs-center.conter-bottom, +.abs-center.conter-conter { + text-align: center; +} + +.abs-center.right-top, +.abs-center.right-bottom, +.abs-center.right-conter { + text-align: right; +} + +.abs-center.conter-bottom, +.abs-center.right-bottom, +.abs-center.left-bottom { + top: auto; + transform: unset; + bottom: 0; +} + +.abs-center.left-bottom { + left: 0; + right: auto; + text-align: left; +} + +.abs-center.right-bottom, +.abs-center.right-conter { + left: auto; + right: 0; + text-align: right; +} + +/* Graphic ratio box (cover / related thumbs) — legacy .graphic */ +.graphic, +.page-cover { + text-shadow: 0 0 5px rgba(0, 0, 0, 0.2); + --main-color: #fff; + color: #fff; + position: relative; + overflow: hidden; + box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08)); + padding: 0; + padding-bottom: 70%; + border-radius: var(--main-radius, var(--radius, 8px)); +} + +.graphic > .fit-cover, +.graphic > img.fit-cover { + position: absolute; + width: 100%; + height: 100%; + object-fit: cover; + inset: 0; +} + +.fit-cover { + object-fit: cover; + max-width: 100%; +} + +/* title-h-left underline bar (legacy) */ +.title-h-left { + position: relative; + padding-bottom: 8px; +} + +.title-h-left:before { + transition: 0.4s; + transform-origin: left; + position: absolute; + content: ""; + width: 40px; + height: 3px; + background: var(--theme-color, var(--focus-color, #f04494)); + left: 0; + bottom: 3px; + border-radius: 5px; + box-shadow: 1px 1px 3px -1px var(--theme-color, var(--focus-color, #f04494)); +} + +/* line-form-line — legacy absolute bottom rule (author meta separator) */ +.line-form-line, +.line-form-line:before { + position: absolute; + bottom: 0; + left: 0; + height: 1px; + width: 100%; + transition: 0.8s; + background: var(--main-border-color, rgba(50, 50, 50, 0.06)); +} + +.line-form-line:before { + content: ""; + width: 0; + background: var(--focus-color, #f04494); +} + +/* Avatar size primitive */ +.avatar-img { + position: relative; + display: inline-block; + flex-shrink: 0; + --this-size: 38px; + width: var(--this-size); + height: var(--this-size); +} + +.avatar-img .avatar, +.avatar-img img { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; +} + +.avatar-lg { + --this-size: 80px; +} + +.avatar-md { + --this-size: 55px; +} + +.avatar-mini { + --this-size: 20px; +} + +.shrink0 { + flex-shrink: 0; +} + +.opacity8 { + opacity: 0.8; +} + +/* Typography / color helpers */ +.muted-color { color: var(--muted-color, var(--color-ink-3)); } +.muted-2-color { color: var(--muted-2-color, var(--color-ink-4)); } +.muted-3-color { color: var(--muted-3-color, #b1b1b1); } +.muted-4-color { color: var(--muted-4-color, #d2d2d2); } +.text-center { text-align: center; } +.em09 { font-size: 0.9em; } +.em12 { font-size: 1.2em; } +.px12-sm { font-size: 12px; } +.ml3 { margin-left: 3px; } +.ml6 { margin-left: 6px; } +.ml10 { margin-left: 10px; } +.mr3 { margin-right: 3px; } +.mr6 { margin-right: 6px; } +.mt10 { margin-top: 10px; } +.mt20 { margin-top: 20px; } +.mb10 { margin-bottom: 10px; } +.mb20 { margin-bottom: 20px; } + +.text-ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 100%; +} + +.text-ellipsis-2 { + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + word-break: break-word; +} + +/* Surfaces used by single article shell */ +.main-bg { + background-color: var(--main-bg-color, var(--surface-1)); +} + +.separator { + position: relative; + letter-spacing: 0.08em; +} + +/* Compact inline separators inside meta/time rows */ +.icon-circle + .icon-circle::before { + content: "·"; + display: inline-block; + margin: 0 0.45em; + opacity: 0.55; +} + +/* Author name row (was a non-standard element) */ +.article-avatar name, +.article-avatar .name, +.user-name { + display: inline-flex; + align-items: center; + gap: 4px; + min-width: 0; + max-width: 100%; +} + +.pull-right { float: right; } +.pull-left { float: left; } + +/* source: assets/css/frontend/single-post/shell.css */ +/* Single page shell — relies on body.site-layout-1/2/3 float dual-column + * defined in layout.css (legacy 1:1). Page-owned overrides stay minimal. */ + +/* Single article stack lives inside .content-layout as direct children; + * do not re-enable the legacy primary/aside grid here. */ +body.single main.container .content-layout { + display: block; + min-width: 0; +} + +body.single main.container .content-layout > * { + min-width: 0; + max-width: 100%; +} + +/* Breadcrumb sits under fixed header (body.nav-fixed already pads top). */ +body.single main.container .content-layout > .breadcrumb, +body.single main.container .content-layout > ul.breadcrumb, +body.single main.container .content-layout > .breadcrumb-nav, +body.single main.container .content-layout > .breadcrumbs-wrap { + position: relative; + z-index: 1; + margin-top: 0; + margin-bottom: 12px; + padding-top: 2px; +} + +body.single .sidebar .aksrt-panel, +body.single .sidebar .widget { + margin-bottom: 15px; +} + +/* Geometry owned by base/layout — keep single shell free of float overrides. */ +body.single main.container { + box-sizing: border-box; +} + +/* Reading facts below the author row. */ +.article-reading-meta { + display: flex; + flex-wrap: wrap; + gap: 8px 14px; + margin: 12px 0 2px; + color: var(--muted-color, #777); + font-size: 12px; +} + +.article-reading-meta span { + display: inline-flex; + align-items: center; + gap: 5px; +} + +/* source: assets/css/frontend/single-post/content.css */ +/* ========== Single Post ========== */ + +/* legacy .article — card body padding wins over .box-body (main.css order) */ +.article, +article.article.box-body, +.article.main-bg.box-body { + padding: 0 30px; + overflow: hidden; +} + +@media (max-width: 767px) { + .article, + article.article.box-body, + .article.main-bg.box-body { + padding: 0 15px; + } + + .article-header .article-title { + font-size: 18px; + } +} + +.entry-header, +.article-header { + margin-bottom: 10px; + padding-bottom: 0; + border-bottom: none; + /* theme-box is spacing only — never paint a nested card here */ + background: transparent; + box-shadow: none; + border-radius: 0; +} + +/* 标题 — 对齐 legacy: 22px, bold, line-height 1.4 */ +.entry-title, +.article-title { + font-size: 22px; + font-weight: bold; + margin: 0; + line-height: 1.4; + letter-spacing: 0; + color: var(--key-color, var(--color-ink)); +} + +.article-title > a:hover { + color: inherit; +} + +.article-header .article-title { + font-size: 22px; + font-weight: bold; + color: var(--key-color, var(--color-ink)); + margin-top: 15px; +} + +.article-header .article-avatar { + margin-top: 15px; +} + +.entry-meta { + display: flex; + flex-wrap: wrap; + gap: 10px 16px; + font-size: 0.875rem; + color: var(--color-ink-4); +} + +.entry-meta a { + color: var(--color-ink-3); +} + +.entry-meta a:hover { + color: var(--color-primary); +} + +.entry-thumb { + margin: 0 0 28px; + border-radius: var(--radius-btn); + overflow: hidden; +} + +/* 内容区 — 对齐 legacy: 16px, line-height 2 */ +.entry-content, +.wp-posts-content { + font-size: 16px; + line-height: 2; + color: var(--main-color, var(--color-ink)); + overflow-wrap: break-word; + word-wrap: break-word; + min-height: 90px; +} + +/* legacy content heading bars */ +.wp-posts-content > h1:not([class]), +.wp-posts-content > h2:not([class]), +.wp-posts-content > h3:not([class]), +.wp-posts-content > h4:not([class]), +.wp-posts-content > h1.wp-block-heading, +.wp-posts-content > h2.wp-block-heading, +.wp-posts-content > h3.wp-block-heading, +.wp-posts-content > h4.wp-block-heading { + position: relative; + padding-bottom: 8px; +} + +.wp-posts-content > h1:not([class]):before, +.wp-posts-content > h2:not([class]):before, +.wp-posts-content > h3:not([class]):before, +.wp-posts-content > h4:not([class]):before, +.wp-posts-content > h1.wp-block-heading:before, +.wp-posts-content > h2.wp-block-heading:before, +.wp-posts-content > h3.wp-block-heading:before, +.wp-posts-content > h4.wp-block-heading:before { + content: ""; + position: absolute; + left: 0; + bottom: 0; + width: 40px; + height: 3px; + background: var(--theme-color, var(--focus-color, #f04494)); + border-radius: 5px; +} + +.wp-posts-content > h3:not([class]):before, +.wp-posts-content > h4:not([class]):before, +.wp-posts-content > h3.wp-block-heading:before, +.wp-posts-content > h4.wp-block-heading:before { + width: 28px; + height: 2px; +} + +:is(.entry-content, .wp-posts-content) > *:first-child { + margin-top: 0; +} + +:is(.entry-content, .wp-posts-content) p { + margin: 0 0 1.5em; +} + +:is(.entry-content, .wp-posts-content) h2 { + font-size: 20px; + font-weight: 700; + margin: 28px 0 14px; +} + +:is(.entry-content, .wp-posts-content) h3 { + font-size: 18px; + font-weight: 700; + margin: 24px 0 12px; +} + +:is(.entry-content, .wp-posts-content) h4 { + font-size: 16px; + font-weight: 700; + margin: 22px 0 10px; +} + +:is(.entry-content, .wp-posts-content) blockquote { + margin: 0 0 24px; + padding: 18px 20px; + border-left: 4px solid var(--color-primary); + background: var(--surface-4, rgba(0, 0, 0, 0.03)); + border-radius: 0 var(--radius-lg) var(--radius-lg) 0; + color: var(--color-ink-3); +} + +:is(.entry-content, .wp-posts-content) img { + margin: 0 auto; + display: block; + max-width: 100%; + height: auto; + border-radius: min(8px, var(--main-radius, 8px)); +} + +:is(.entry-content, .wp-posts-content) figure { + max-width: 100%; + margin: 1.5em auto; +} + +:is(.entry-content, .wp-posts-content) figcaption { + margin-top: 8px; + color: var(--muted-color, #777); + font-size: 13px; + line-height: 1.6; + text-align: center; +} + +:is(.entry-content, .wp-posts-content) .aksrt-lightbox-target { + cursor: zoom-in; +} + +/* ===== 图片灯箱 ===== */ +.lightbox-overlay { + position: fixed; + inset: 0; + z-index: 9999; + display: none; + align-items: center; + justify-content: center; + flex-direction: column; + gap: 12px; + padding: 24px; + background: rgba(0, 0, 0, 0.85); +} + +.lightbox-overlay.is-open { + display: flex; +} + +.lightbox-img { + max-width: 90vw; + max-height: 85vh; + width: auto; + height: auto; + border-radius: 4px; + object-fit: contain; +} + +.lightbox-caption { + max-width: min(96vw, 1200px); + color: #fff; + font-size: 14px; + line-height: 1.5; + text-align: center; + opacity: 0.92; +} + +.lightbox-close { + position: absolute; + top: 14px; + right: 14px; + width: 40px; + height: 40px; + border: none; + border-radius: 999px; + display: inline-flex; + align-items: center; + justify-content: center; + background: rgba(255, 255, 255, 0.12); + color: #fff; + cursor: pointer; + transition: background-color 0.2s ease; +} + +.lightbox-close:hover { + background: rgba(255, 255, 255, 0.22); +} + +.lightbox-close i { + pointer-events: none; +} + +:is(.entry-content, .wp-posts-content) iframe, +:is(.entry-content, .wp-posts-content) .wp-block-embed iframe, +:is(.entry-content, .wp-posts-content) video { + max-width: 100%; + height: auto; +} + +:is(.entry-content, .wp-posts-content) .wp-block-embed { + position: relative; + width: 100%; + max-width: 100%; + overflow: hidden; + margin: 1.5em 0; +} + +/* 行内代码 — 对齐 legacy: 粉色文字 + 粉色背景 */ +:is(.entry-content, .wp-posts-content) code { + font-family: var(--font-mono); + font-size: 0.9em; + color: #ff3c98; + background: rgba(253, 153, 153, 0.2); + padding: 2px 6px; + border-radius: 4px; +} + +:is(.entry-content, .wp-posts-content) ul, +:is(.entry-content, .wp-posts-content) ol { + padding-left: 1.5em; + margin: 0 0 1.5em; +} + +:is(.entry-content, .wp-posts-content) ul li::marker { + color: var(--color-primary); +} + +.entry-footer { + margin-top: 40px; + padding-top: 24px; + border-top: 1px solid var(--color-line); +} + +.post-tags { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.post-tags a { + padding: 4px 10px; + border-radius: 50px; + background: var(--muted-bg-color, #eee); + border: 1px solid var(--main-border-color, rgba(50, 50, 50, 0.06)); + font-size: 13px; + color: var(--muted-color, #777); +} + +.post-tags a:hover { + border-color: var(--color-primary); + color: var(--color-primary); +} + +.related-posts { + margin-top: 48px; + padding: 20px 0 0; + border-top: 1px solid var(--color-line-soft); +} + +.related-posts__title { + font-size: 15px; + font-weight: 700; + margin: 0 0 10px; + color: var(--key-color, #333); +} + +.related-posts__title::before { + content: ''; + display: inline-block; + width: 40px; + height: 3px; + background: var(--theme-color, #f04494); + border-radius: 5px; + vertical-align: middle; + margin-right: 8px; +} + +.related-posts__grid { + display: flex; + flex-direction: column; + gap: 0; +} + +.related-card { + display: flex; + align-items: center; + gap: 12px; + padding: 10px 0; + border-bottom: 1px solid var(--main-border-color, rgba(50, 50, 50, 0.06)); + transition: 0.15s; +} + +.related-card:last-child { + border-bottom: none; +} + +.related-card a { + display: flex; + align-items: center; + gap: 12px; + color: var(--key-color, #333); + text-decoration: none; + width: 100%; +} + +.related-card:hover a { + color: var(--focus-color, #f04494); +} + +.related-card__thumb { + width: 96px; + min-width: 96px; + height: 64px; + border-radius: var(--main-radius, 8px); + overflow: hidden; + flex-shrink: 0; +} + +.related-card__thumb img { + width: 100%; + height: 100%; + object-fit: cover; + transition: transform 0.3s; +} + +.related-card:hover .related-card__thumb img { + transform: scale(1.05); +} + +.related-card h4 { + font-size: 14px; + font-weight: 600; + margin: 0; + line-height: 1.4; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +/* source: assets/css/frontend/single-post/author-actions.css */ +/* ===== Author Bar (inside article card) ===== */ +.article-author-bar { + display: flex; + align-items: center; + gap: 10px; + margin-bottom: 16px; +} + +.article-author-bar__avatar { + width: 40px; + height: 40px; + border-radius: 50%; + object-fit: cover; + flex-shrink: 0; +} + +.article-author-bar__info { + flex: 1; + min-width: 0; +} + +.article-author-bar__name { + font-weight: 600; + font-size: 14px; + color: var(--color-ink); +} + +.article-author-bar__name:hover { + color: var(--color-primary); +} + +.article-author-bar__meta { + display: flex; + flex-wrap: wrap; + gap: 10px; + font-size: 12px; + color: var(--color-ink-4, var(--color-ink-4)); + margin-top: 2px; +} + +.article-author-bar__meta span { + display: inline-flex; + align-items: center; + gap: 3px; +} + +.article-author-bar__line { + height: 1px; + background: var(--color-line); + margin-bottom: 20px; +} + +/* ===== Content Footer ===== */ +.article-footer { + margin-top: 32px; + padding-top: 20px; + border-top: 1px solid var(--color-line); +} + +.article-copyright { + font-size: 13px; + color: var(--color-ink-4, var(--color-ink-4)); + margin-bottom: 16px; +} + +.article-end-separator { + text-align: center; + margin: 16px 0; + position: relative; +} + +.article-end-separator::before { + content: ''; + position: absolute; + top: 50%; + left: 0; + right: 0; + height: 1px; + background: var(--color-line); +} + +.article-end-separator span { + position: relative; + display: inline-block; + padding: 0 14px; + background: var(--surface-page); + font-size: 11px; + font-weight: 600; + color: var(--color-ink-4, var(--color-ink-4)); + letter-spacing: 2px; +} + +.article-tags { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 12px; +} + +/* ===== Action Buttons Card ===== */ +.post-actions-wrap { + position: relative; + text-align: center; + margin-bottom: 16px; +} + +/* legacy .post-actions — text/icon column buttons, not pill chips */ +.post-actions-card, +.post-actions { + position: relative; + text-align: center; + margin-bottom: 16px; + padding-bottom: 15px; + display: block; +} + +.post-actions-wrap > .post-actions { + margin-bottom: 0; +} + +.post-actions-card__hint { + font-size: 13px; + color: var(--color-ink-4, var(--color-ink-4)); + margin-bottom: 12px; +} + +/* Legacy card-buttons flex only for non-legacy card variant */ +.post-actions-card__buttons { + display: flex; + justify-content: center; + gap: 10px; + margin-bottom: 12px; +} + +/* legacy: .article .action { width:80px; padding:10px 0; inline-block; opacity:.7 } */ +.article .action, +.post-actions .action { + width: 80px; + padding: 10px 0; + display: inline-block; + opacity: 0.7; + vertical-align: top; + min-width: 0; + height: auto; + border-radius: 0; + border: 0; + background: transparent; + color: var(--muted-color, #777); + cursor: pointer; + font-size: 14px; + transition: opacity 0.15s ease, color 0.15s ease; + gap: 0; + text-align: center; +} + +.article .action:hover, +.post-actions .action:hover, +.article .action.is-active, +.post-actions .action.is-active { + color: inherit; + opacity: 1; + background: transparent; + border-color: transparent; +} + +.article .action i, +.post-actions .action i { + font-size: 20px; + display: block; + margin: 0 auto 4px; + line-height: 1; +} + +.post-actions .action .action-btn__count, +.post-actions .action .action-btn__label, +.action-btn__count, +.action-btn__label { + display: block; + font-size: 12px; + line-height: 1.2; + font-weight: 500; +} + +/* Keep pill style for non-article .action-btn if used elsewhere */ +.action-btn { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 0.38em 1.1em; + border-radius: 50px; + border: 1px solid transparent; + background: var(--surface-4, rgba(136, 136, 136, 0.1)); + color: var(--color-ink-3); + cursor: pointer; + font-size: 14px; + transition: all 0.15s ease; +} + +.action-btn:hover { + background: var(--color-primary-soft); + color: var(--color-primary); +} + +.action-btn.is-active { + border-color: var(--color-primary); + color: var(--color-primary); + background: var(--color-primary-soft, rgba(240, 68, 148, 0.08)); +} + +.action-btn i { font-size: 1.2em; } + +/* ===== 分享下拉面板 ===== */ + +/* 确保父容器作为定位参考 */ +.share-dropdown { + position: absolute; + left: 50%; + bottom: calc(100% + 8px); + transform: translateX(-50%); + z-index: 100; + /* 默认隐藏 — 最高优先级确保不被覆盖 */ + display: none !important; +} + +.share-dropdown[aria-hidden="false"] { + display: block !important; + animation: shareDropdownIn 0.2s ease-out forwards; +} + +@keyframes shareDropdownIn { + from { + opacity: 0; + transform: translateX(-50%) translateY(8px); + } + to { + opacity: 1; + transform: translateX(-50%) translateY(0); + } +} + +.share-dropdown__grid { + display: flex; + align-items: center; + gap: 8px; + padding: 12px 16px; + background: var(--surface-page); + border: 1px solid var(--color-line); + border-radius: var(--radius-lg, 8px); + box-shadow: var(--shadow-md, 0 4px 16px rgba(0,0,0,0.1)); +} + +.share-item { + display: inline-flex; + flex-direction: column; + align-items: center; + gap: 4px; + padding: 8px 12px; + border: none; + border-radius: var(--radius-btn, 6px); + background: transparent; + color: var(--color-ink-2, var(--color-ink-3)); + cursor: pointer; + font-size: 11px; + transition: background 0.15s, color 0.15s, transform 0.15s; + white-space: nowrap; +} + +.share-item:hover { + transform: none; +} + +.share-item i { + font-size: 18px; +} + +.share-item[data-platform="qq"]:hover { background: #e8f4fd; color: #12b7f5; } +.share-item[data-platform="weibo"]:hover { background: #fceae9; color: #ff6a00; } +.share-item[data-platform="twitter"]:hover { background: #f0f0f0; color: #000; } +.share-item[data-platform="wechat"]:hover { background: #e6f7ec; color: #07c160; } +.share-item[data-platform="copy"]:hover { background: #f0f2f5; color: #555; } +.share-item[data-platform="poster"]:hover { background: #fff4e8; color: #f59e0b; } + +/* 微信二维码浮层 */ +#share-qrcode-box { + position: absolute; + bottom: calc(100% + 10px); + left: 50%; + transform: translateX(-50%); + padding: 14px; + background: var(--surface-page); + border: 1px solid var(--color-line); + border-radius: var(--radius-lg, 8px); + box-shadow: var(--shadow-md, 0 4px 16px rgba(0,0,0,0.12)); + text-align: center; + z-index: 101; + pointer-events: none; + opacity: 0; + transition: opacity 0.2s ease, transform 0.2s ease; +} + +#share-qrcode-box.is-visible { + pointer-events: auto; + opacity: 1; +} + +#share-qrcode-image { + width: 140px; + height: 140px; + display: block; +} + +/* 暗色模式 */ +.theme-dark .share-dropdown__grid, +html.dark .share-dropdown__grid { + background: var(--surface-1); + border-color: var(--color-line); + box-shadow: 0 4px 16px rgba(0,0,0,0.35); +} + +.theme-dark #share-qrcode-box, +html.dark #share-qrcode-box { + background: var(--surface-1); + border-color: var(--color-line); +} + +.theme-dark .share-item, +html.dark .share-item { + color: var(--color-ink-2, #aaa); +} + +.theme-dark .share-item[data-platform="qq"]:hover { background: rgba(18,183,245,0.12); color: #12b7f5; } +.theme-dark .share-item[data-platform="weibo"]:hover { background: rgba(255,106,0,0.12); color: #ff6a00; } +.theme-dark .share-item[data-platform="twitter"]:hover { background: rgba(255,255,255,0.08); color: #fff; } +.theme-dark .share-item[data-platform="wechat"]:hover { background: rgba(7,193,96,0.12); color: #07c160; } +.theme-dark .share-item[data-platform="copy"]:hover { background: rgba(255,255,255,0.06); color: #ccc; } +.theme-dark .share-item[data-platform="poster"]:hover { background: rgba(245,158,11,0.12); color: #f59e0b; } + +/* Narrow screens: bottom sheet so dropdown never clips off-screen */ +@media (max-width: 767px) { + .share-dropdown { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: auto; + transform: none; + width: 100%; + max-width: none; + z-index: 1200; + padding: 0 0 calc(12px + env(safe-area-inset-bottom, 0px)); + background: transparent; + } + .share-dropdown[aria-hidden="false"] { + animation: shareSheetIn 0.22s ease-out forwards; + } + @keyframes shareSheetIn { + from { opacity: 0; transform: translateY(16px); } + to { opacity: 1; transform: translateY(0); } + } + .share-dropdown__grid { + justify-content: space-around; + flex-wrap: wrap; + gap: 6px; + margin: 0 10px; + padding: 14px 12px 16px; + border-radius: 14px 14px 10px 10px; + box-shadow: 0 -6px 28px rgba(0, 0, 0, 0.16); + } + .share-item { + min-width: 64px; + flex: 1 1 28%; + max-width: 33%; + } + #share-qrcode-box { + position: static; + margin: 10px auto 0; + transform: none; + } + body.aksrt-share-sheet-open { + overflow: hidden; + } + body.aksrt-share-sheet-open::before { + content: ''; + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.35); + z-index: 1190; + } +} + +.theme-dark .post-drop-meta__menu, +html.dark .post-drop-meta__menu { + background: var(--surface-1, #323335); + border-color: var(--color-line); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); +} + +.theme-dark .post-drop-meta__item, +html.dark .post-drop-meta__item { + color: var(--color-ink-2, #ccc); +} + +.theme-dark .post-drop-meta__item:hover, +html.dark .post-drop-meta__item:hover { + background: rgba(255,255,255,0.06); + color: #fff; +} + +/* ===== Author Card — 对齐 legacy 卡片容器 ===== */ +.author-box { + margin-bottom: 16px; + padding: 18px; + background: var(--surface-1, #fff); + border: none; + border-radius: var(--radius-2xl, 16px); + box-shadow: var(--shadow-sm); +} + +.single-metabox { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 8px; +} + +.post-drop-meta { + position: relative; +} + +.post-drop-meta__menu { + position: absolute; + top: calc(100% + 8px); + right: 0; + min-width: 150px; + padding: 8px; + border-radius: var(--radius, 8px); + border: 1px solid var(--color-line); + background: var(--surface-page, #fff); + box-shadow: var(--shadow-md, 0 8px 24px rgba(0, 0, 0, 0.12)); + display: none; + z-index: 20; +} + +.post-drop-meta.is-open .post-drop-meta__menu { + display: grid; + gap: 4px; +} + +.post-drop-meta__item { + width: 100%; + display: inline-flex; + align-items: center; + gap: 8px; + padding: 8px 10px; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--color-ink-2, var(--color-ink)); + text-decoration: none; + font-size: 13px; + text-align: left; + cursor: pointer; +} + +.post-drop-meta__item:hover { + background: var(--color-line, rgba(50, 50, 50, 0.06)); + color: var(--color-primary); +} + +.post-drop-meta__item i { + width: 16px; + text-align: center; +} + +.author-box__header { + display: flex; + align-items: flex-start; + gap: 14px; +} + +.author-box__avatar { + width: 56px; + height: 56px; + border-radius: 50%; + object-fit: cover; + flex-shrink: 0; + border: 3px solid var(--color-primary-soft, rgba(240, 68, 148, 0.2)); +} + +.author-box__info { + flex: 1; + min-width: 0; +} + +.author-box__name { + font-size: 1rem; + font-weight: 700; + color: var(--color-ink); + display: block; + margin-bottom: 4px; +} + +.author-box__name:hover { color: var(--color-primary); } + +.author-box__bio { + font-size: 13px; + color: var(--color-ink-3, var(--color-ink-4)); + line-height: 1.5; + margin: 0 0 6px; +} + +.author-box__stats { + font-size: 12px; + color: var(--color-ink-4, var(--color-ink-4)); +} + +.author-box__stats strong { + color: var(--color-ink); + margin-right: 2px; +} + +.author-box__posts { + margin-top: 14px; + padding-top: 12px; + border-top: 1px solid var(--color-line); +} + +.author-box__posts-title { + font-size: 12px; + font-weight: 600; + color: var(--color-ink-3, var(--color-ink-4)); + margin: 0 0 8px; +} + +.author-box__posts ul { + list-style: none; + margin: 0; + padding: 0; +} + +.author-box__posts li { padding: 3px 0; } + +.author-box__posts a { + font-size: 13px; + color: var(--color-ink); + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.author-box__posts a:hover { color: var(--color-primary); } +.author-box__posts a::before { content: '\2022'; color: var(--color-primary); } + + + +/* ===== legacy single-metabox / author bar ===== */ +.article-avatar .user-info { + width: 100%; +} + +.article-avatar .avatar-img { + --this-size: 42px; +} + +.article-avatar .avatar-img img, +.article-avatar .avatar { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; +} + +.article-avatar .display-name { + font-weight: 600; + color: var(--key-color, #333); +} + +.article-header .article-avatar .relative { + margin-top: 20px; + position: relative; + min-height: 1px; +} + +.single-metabox { + right: 0; + font-size: 15px; + --meta-color: var(--muted-color, #777); +} + +.single-metabox .post-metas { + background: var(--body-bg-color, #f5f5f5); + right: 0; + padding: 2px 6px; + border-radius: 100px; + color: var(--meta-color); + display: inline-flex; + flex-wrap: wrap; + align-items: center; + gap: 0; +} + +.single-metabox .post-metas item, +.single-metabox .post-metas .item { + margin: 0 6px; + font-size: 13px; + display: inline-flex; + align-items: center; + gap: 4px; +} + +.single-metabox .post-drop-meta { + position: relative; + display: inline-block; +} + +.single-metabox.cover-meta { + font-size: 14px; + right: 1em; + top: 1.6em; + --meta-color: rgba(255, 255, 255, 0.8); + --body-bg-color: rgba(0, 0, 0, 0.3); +} + +/* line-form-line owned by legacy-utilities.css — only context here */ +.article-avatar .line-form-line { + display: block; +} + +.article-tags br { flex-basis: 100%; width: 100%; content: ""; display: block; height: 0; } +.article-tags .but.c-blue { color: #2196f3; } +.article-tags .but.c-yellow { color: #f0ad4e; } +.article-tags .but.c-green { color: #5cb85c; } +.article-tags .but.c-purple { color: #9c27b0; } +.article-tags .but.c-red { color: #f44336; } + + +/* ===== legacy user-card after-box ===== */ +.user-card.author { margin-bottom: 16px; overflow: hidden; } +.user-card.author .user-avatar { display: flex; justify-content: center; } +.user-card.author .user-avatar .avatar, +.user-card.author .user-avatar img { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; } +.user-card.author .user-name { display: flex; flex-wrap: nowrap; align-items: center; justify-content: center; gap: 4px; } +.user-card.author .user-name .display-name { font-weight: 700; color: var(--key-color, inherit); } +.user-card.author .user-desc { text-align: center; } +.user-card.author .user-btns { text-align: center; } +.user-card.author .user-card-posts ul { list-style: none; margin: 0; padding: 0; } +.user-card.author .user-card-posts li { padding: 6px 0; border-bottom: 1px dashed var(--color-line, rgba(0,0,0,.06)); } +.user-card.author .user-card-posts li:last-child { border-bottom: 0; } diff --git a/assets/css/build/single.min.css b/assets/css/build/single.min.css new file mode 100644 index 00000000..d99d7fe4 --- /dev/null +++ b/assets/css/build/single.min.css @@ -0,0 +1 @@ +.relative{position:relative}.flex{display:flex}.flex.ac,.ac{align-items:center}.flex.jc,.jc{justify-content:center}.flex.jsb,.jsb{justify-content:space-between}.flex.at,.at{align-items:flex-start}.flex.ae,.ae{align-items:flex-end}.flex0{flex:0 0 auto}.flex1{flex:1 1 auto;min-width:0}.flex.column{flex-direction:column}.flex.wrap{flex-wrap:wrap}.flex.flex-row,.flex-row{flex-direction:row}.flex.jse,.jse{justify-content:space-evenly}.flex.jsa,.jsa{justify-content:space-around}.flex>.flex1,.flex .flex1{flex:1;overflow:hidden;min-width:0}.relative-h{position:relative;height:100%}.padding-10{padding:10px}.font-bold{font-weight:700}.mt6{margin-top:6px}.gutters-5{margin:-5px}.gutters-5>*{padding:5px}@media(max-width:767px){.flex.flex-row.flex-col-sm-2{flex-wrap:wrap}.flex.flex-row.flex-col-sm-2>*{flex-basis:50%}}.clearfix:before,.clearfix:after{content:"";display:table}.clearfix:after{clear:both}.abs-right{position:absolute;right:0;top:0}.abs-center{position:absolute;left:0;width:100%;top:50%;right:.7em;transform:translateY(-50%);z-index:1}.abs-center.left-top,.abs-center.right-top{transform:unset;top:0}.abs-center.right-top{left:auto;width:auto;text-align:right}.abs-center.left-top{text-align:left}.abs-center.conter-bottom,.abs-center.conter-conter{text-align:center}.abs-center.right-top,.abs-center.right-bottom,.abs-center.right-conter{text-align:right}.abs-center.conter-bottom,.abs-center.right-bottom,.abs-center.left-bottom{top:auto;transform:unset;bottom:0}.abs-center.left-bottom{left:0;right:auto;text-align:left}.abs-center.right-bottom,.abs-center.right-conter{left:auto;right:0;text-align:right}.graphic,.page-cover{text-shadow:0 0 5px rgba(0,0,0,.2);--main-color: #fff;color:#fff;position:relative;overflow:hidden;box-shadow:0 0 10px var(--main-shadow, rgba(116, 116, 116, .08));padding:0 0 70%;border-radius:var(--main-radius, var(--radius, 8px))}.graphic>.fit-cover,.graphic>img.fit-cover{position:absolute;width:100%;height:100%;object-fit:cover;inset:0}.fit-cover{object-fit:cover;max-width:100%}.title-h-left{position:relative;padding-bottom:8px}.title-h-left:before{transition:.4s;transform-origin:left;position:absolute;content:"";width:40px;height:3px;background:var(--theme-color, var(--focus-color, #f04494));left:0;bottom:3px;border-radius:5px;box-shadow:1px 1px 3px -1px var(--theme-color, var(--focus-color, #f04494))}.line-form-line,.line-form-line:before{position:absolute;bottom:0;left:0;height:1px;width:100%;transition:.8s;background:var(--main-border-color, rgba(50, 50, 50, .06))}.line-form-line:before{content:"";width:0;background:var(--focus-color, #f04494)}.avatar-img{position:relative;display:inline-block;flex-shrink:0;--this-size: 38px;width:var(--this-size);height:var(--this-size)}.avatar-img .avatar,.avatar-img img{width:100%;height:100%;border-radius:50%;object-fit:cover}.avatar-lg{--this-size: 80px}.avatar-md{--this-size: 55px}.avatar-mini{--this-size: 20px}.shrink0{flex-shrink:0}.opacity8{opacity:.8}.muted-color{color:var(--muted-color, var(--color-ink-3))}.muted-2-color{color:var(--muted-2-color, var(--color-ink-4))}.muted-3-color{color:var(--muted-3-color, #b1b1b1)}.muted-4-color{color:var(--muted-4-color, #d2d2d2)}.text-center{text-align:center}.em09{font-size:.9em}.em12{font-size:1.2em}.px12-sm{font-size:12px}.ml3{margin-left:3px}.ml6{margin-left:6px}.ml10{margin-left:10px}.mr3{margin-right:3px}.mr6{margin-right:6px}.mt10{margin-top:10px}.mt20{margin-top:20px}.mb10{margin-bottom:10px}.mb20{margin-bottom:20px}.text-ellipsis{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.text-ellipsis-2{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}.main-bg{background-color:var(--main-bg-color, var(--surface-1))}.separator{position:relative;letter-spacing:.08em}.icon-circle+.icon-circle:before{content:"·";display:inline-block;margin:0 .45em;opacity:.55}.article-avatar name,.article-avatar .name,.user-name{display:inline-flex;align-items:center;gap:4px;min-width:0;max-width:100%}.pull-right{float:right}.pull-left{float:left}body.single main.container .content-layout{display:block;min-width:0}body.single main.container .content-layout>*{min-width:0;max-width:100%}body.single main.container .content-layout>.breadcrumb,body.single main.container .content-layout>ul.breadcrumb,body.single main.container .content-layout>.breadcrumb-nav,body.single main.container .content-layout>.breadcrumbs-wrap{position:relative;z-index:1;margin-top:0;margin-bottom:12px;padding-top:2px}body.single .sidebar .aksrt-panel,body.single .sidebar .widget{margin-bottom:15px}body.single main.container{box-sizing:border-box}.article-reading-meta{display:flex;flex-wrap:wrap;gap:8px 14px;margin:12px 0 2px;color:var(--muted-color, #777);font-size:12px}.article-reading-meta span{display:inline-flex;align-items:center;gap:5px}.article,article.article.box-body,.article.main-bg.box-body{padding:0 30px;overflow:hidden}@media(max-width:767px){.article,article.article.box-body,.article.main-bg.box-body{padding:0 15px}.article-header .article-title{font-size:18px}}.entry-header,.article-header{margin-bottom:10px;padding-bottom:0;border-bottom:none;background:transparent;box-shadow:none;border-radius:0}.entry-title,.article-title{font-size:22px;font-weight:700;margin:0;line-height:1.4;letter-spacing:0;color:var(--key-color, var(--color-ink))}.article-title>a:hover{color:inherit}.article-header .article-title{font-size:22px;font-weight:700;color:var(--key-color, var(--color-ink));margin-top:15px}.article-header .article-avatar{margin-top:15px}.entry-meta{display:flex;flex-wrap:wrap;gap:10px 16px;font-size:.875rem;color:var(--color-ink-4)}.entry-meta a{color:var(--color-ink-3)}.entry-meta a:hover{color:var(--color-primary)}.entry-thumb{margin:0 0 28px;border-radius:var(--radius-btn);overflow:hidden}.entry-content,.wp-posts-content{font-size:16px;line-height:2;color:var(--main-color, var(--color-ink));overflow-wrap:break-word;word-wrap:break-word;min-height:90px}.wp-posts-content>h1:not([class]),.wp-posts-content>h2:not([class]),.wp-posts-content>h3:not([class]),.wp-posts-content>h4:not([class]),.wp-posts-content>h1.wp-block-heading,.wp-posts-content>h2.wp-block-heading,.wp-posts-content>h3.wp-block-heading,.wp-posts-content>h4.wp-block-heading{position:relative;padding-bottom:8px}.wp-posts-content>h1:not([class]):before,.wp-posts-content>h2:not([class]):before,.wp-posts-content>h3:not([class]):before,.wp-posts-content>h4:not([class]):before,.wp-posts-content>h1.wp-block-heading:before,.wp-posts-content>h2.wp-block-heading:before,.wp-posts-content>h3.wp-block-heading:before,.wp-posts-content>h4.wp-block-heading:before{content:"";position:absolute;left:0;bottom:0;width:40px;height:3px;background:var(--theme-color, var(--focus-color, #f04494));border-radius:5px}.wp-posts-content>h3:not([class]):before,.wp-posts-content>h4:not([class]):before,.wp-posts-content>h3.wp-block-heading:before,.wp-posts-content>h4.wp-block-heading:before{width:28px;height:2px}:is(.entry-content,.wp-posts-content)>*:first-child{margin-top:0}:is(.entry-content,.wp-posts-content) p{margin:0 0 1.5em}:is(.entry-content,.wp-posts-content) h2{font-size:20px;font-weight:700;margin:28px 0 14px}:is(.entry-content,.wp-posts-content) h3{font-size:18px;font-weight:700;margin:24px 0 12px}:is(.entry-content,.wp-posts-content) h4{font-size:16px;font-weight:700;margin:22px 0 10px}:is(.entry-content,.wp-posts-content) blockquote{margin:0 0 24px;padding:18px 20px;border-left:4px solid var(--color-primary);background:var(--surface-4, rgba(0, 0, 0, .03));border-radius:0 var(--radius-lg) var(--radius-lg) 0;color:var(--color-ink-3)}:is(.entry-content,.wp-posts-content) img{margin:0 auto;display:block;max-width:100%;height:auto;border-radius:min(8px,var(--main-radius, 8px))}:is(.entry-content,.wp-posts-content) figure{max-width:100%;margin:1.5em auto}:is(.entry-content,.wp-posts-content) figcaption{margin-top:8px;color:var(--muted-color, #777);font-size:13px;line-height:1.6;text-align:center}:is(.entry-content,.wp-posts-content) .aksrt-lightbox-target{cursor:zoom-in}.lightbox-overlay{position:fixed;inset:0;z-index:9999;display:none;align-items:center;justify-content:center;flex-direction:column;gap:12px;padding:24px;background:#000000d9}.lightbox-overlay.is-open{display:flex}.lightbox-img{max-width:90vw;max-height:85vh;width:auto;height:auto;border-radius:4px;object-fit:contain}.lightbox-caption{max-width:min(96vw,1200px);color:#fff;font-size:14px;line-height:1.5;text-align:center;opacity:.92}.lightbox-close{position:absolute;top:14px;right:14px;width:40px;height:40px;border:none;border-radius:999px;display:inline-flex;align-items:center;justify-content:center;background:#ffffff1f;color:#fff;cursor:pointer;transition:background-color .2s ease}.lightbox-close:hover{background:#ffffff38}.lightbox-close i{pointer-events:none}:is(.entry-content,.wp-posts-content) iframe,:is(.entry-content,.wp-posts-content) .wp-block-embed iframe,:is(.entry-content,.wp-posts-content) video{max-width:100%;height:auto}:is(.entry-content,.wp-posts-content) .wp-block-embed{position:relative;width:100%;max-width:100%;overflow:hidden;margin:1.5em 0}:is(.entry-content,.wp-posts-content) code{font-family:var(--font-mono);font-size:.9em;color:#ff3c98;background:#fd999933;padding:2px 6px;border-radius:4px}:is(.entry-content,.wp-posts-content) ul,:is(.entry-content,.wp-posts-content) ol{padding-left:1.5em;margin:0 0 1.5em}:is(.entry-content,.wp-posts-content) ul li::marker{color:var(--color-primary)}.entry-footer{margin-top:40px;padding-top:24px;border-top:1px solid var(--color-line)}.post-tags{display:flex;flex-wrap:wrap;gap:8px}.post-tags a{padding:4px 10px;border-radius:50px;background:var(--muted-bg-color, #eee);border:1px solid var(--main-border-color, rgba(50, 50, 50, .06));font-size:13px;color:var(--muted-color, #777)}.post-tags a:hover{border-color:var(--color-primary);color:var(--color-primary)}.related-posts{margin-top:48px;padding:20px 0 0;border-top:1px solid var(--color-line-soft)}.related-posts__title{font-size:15px;font-weight:700;margin:0 0 10px;color:var(--key-color, #333)}.related-posts__title:before{content:"";display:inline-block;width:40px;height:3px;background:var(--theme-color, #f04494);border-radius:5px;vertical-align:middle;margin-right:8px}.related-posts__grid{display:flex;flex-direction:column;gap:0}.related-card{display:flex;align-items:center;gap:12px;padding:10px 0;border-bottom:1px solid var(--main-border-color, rgba(50, 50, 50, .06));transition:.15s}.related-card:last-child{border-bottom:none}.related-card a{display:flex;align-items:center;gap:12px;color:var(--key-color, #333);text-decoration:none;width:100%}.related-card:hover a{color:var(--focus-color, #f04494)}.related-card__thumb{width:96px;min-width:96px;height:64px;border-radius:var(--main-radius, 8px);overflow:hidden;flex-shrink:0}.related-card__thumb img{width:100%;height:100%;object-fit:cover;transition:transform .3s}.related-card:hover .related-card__thumb img{transform:scale(1.05)}.related-card h4{font-size:14px;font-weight:600;margin:0;line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.article-author-bar{display:flex;align-items:center;gap:10px;margin-bottom:16px}.article-author-bar__avatar{width:40px;height:40px;border-radius:50%;object-fit:cover;flex-shrink:0}.article-author-bar__info{flex:1;min-width:0}.article-author-bar__name{font-weight:600;font-size:14px;color:var(--color-ink)}.article-author-bar__name:hover{color:var(--color-primary)}.article-author-bar__meta{display:flex;flex-wrap:wrap;gap:10px;font-size:12px;color:var(--color-ink-4, var(--color-ink-4));margin-top:2px}.article-author-bar__meta span{display:inline-flex;align-items:center;gap:3px}.article-author-bar__line{height:1px;background:var(--color-line);margin-bottom:20px}.article-footer{margin-top:32px;padding-top:20px;border-top:1px solid var(--color-line)}.article-copyright{font-size:13px;color:var(--color-ink-4, var(--color-ink-4));margin-bottom:16px}.article-end-separator{text-align:center;margin:16px 0;position:relative}.article-end-separator:before{content:"";position:absolute;top:50%;left:0;right:0;height:1px;background:var(--color-line)}.article-end-separator span{position:relative;display:inline-block;padding:0 14px;background:var(--surface-page);font-size:11px;font-weight:600;color:var(--color-ink-4, var(--color-ink-4));letter-spacing:2px}.article-tags{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}.post-actions-wrap{position:relative;text-align:center;margin-bottom:16px}.post-actions-card,.post-actions{position:relative;text-align:center;margin-bottom:16px;padding-bottom:15px;display:block}.post-actions-wrap>.post-actions{margin-bottom:0}.post-actions-card__hint{font-size:13px;color:var(--color-ink-4, var(--color-ink-4));margin-bottom:12px}.post-actions-card__buttons{display:flex;justify-content:center;gap:10px;margin-bottom:12px}.article .action,.post-actions .action{width:80px;padding:10px 0;display:inline-block;opacity:.7;vertical-align:top;min-width:0;height:auto;border-radius:0;border:0;background:transparent;color:var(--muted-color, #777);cursor:pointer;font-size:14px;transition:opacity .15s ease,color .15s ease;gap:0;text-align:center}.article .action:hover,.post-actions .action:hover,.article .action.is-active,.post-actions .action.is-active{color:inherit;opacity:1;background:transparent;border-color:transparent}.article .action i,.post-actions .action i{font-size:20px;display:block;margin:0 auto 4px;line-height:1}.post-actions .action .action-btn__count,.post-actions .action .action-btn__label,.action-btn__count,.action-btn__label{display:block;font-size:12px;line-height:1.2;font-weight:500}.action-btn{display:inline-flex;align-items:center;gap:6px;padding:.38em 1.1em;border-radius:50px;border:1px solid transparent;background:var(--surface-4, rgba(136, 136, 136, .1));color:var(--color-ink-3);cursor:pointer;font-size:14px;transition:all .15s ease}.action-btn:hover{background:var(--color-primary-soft);color:var(--color-primary)}.action-btn.is-active{border-color:var(--color-primary);color:var(--color-primary);background:var(--color-primary-soft, rgba(240, 68, 148, .08))}.action-btn i{font-size:1.2em}.share-dropdown{position:absolute;left:50%;bottom:calc(100% + 8px);transform:translate(-50%);z-index:100;display:none!important}.share-dropdown[aria-hidden=false]{display:block!important;animation:shareDropdownIn .2s ease-out forwards}@keyframes shareDropdownIn{0%{opacity:0;transform:translate(-50%) translateY(8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}.share-dropdown__grid{display:flex;align-items:center;gap:8px;padding:12px 16px;background:var(--surface-page);border:1px solid var(--color-line);border-radius:var(--radius-lg, 8px);box-shadow:var(--shadow-md, 0 4px 16px rgba(0,0,0,.1))}.share-item{display:inline-flex;flex-direction:column;align-items:center;gap:4px;padding:8px 12px;border:none;border-radius:var(--radius-btn, 6px);background:transparent;color:var(--color-ink-2, var(--color-ink-3));cursor:pointer;font-size:11px;transition:background .15s,color .15s,transform .15s;white-space:nowrap}.share-item:hover{transform:none}.share-item i{font-size:18px}.share-item[data-platform=qq]:hover{background:#e8f4fd;color:#12b7f5}.share-item[data-platform=weibo]:hover{background:#fceae9;color:#ff6a00}.share-item[data-platform=twitter]:hover{background:#f0f0f0;color:#000}.share-item[data-platform=wechat]:hover{background:#e6f7ec;color:#07c160}.share-item[data-platform=copy]:hover{background:#f0f2f5;color:#555}.share-item[data-platform=poster]:hover{background:#fff4e8;color:#f59e0b}#share-qrcode-box{position:absolute;bottom:calc(100% + 10px);left:50%;transform:translate(-50%);padding:14px;background:var(--surface-page);border:1px solid var(--color-line);border-radius:var(--radius-lg, 8px);box-shadow:var(--shadow-md, 0 4px 16px rgba(0,0,0,.12));text-align:center;z-index:101;pointer-events:none;opacity:0;transition:opacity .2s ease,transform .2s ease}#share-qrcode-box.is-visible{pointer-events:auto;opacity:1}#share-qrcode-image{width:140px;height:140px;display:block}.theme-dark .share-dropdown__grid,html.dark .share-dropdown__grid{background:var(--surface-1);border-color:var(--color-line);box-shadow:0 4px 16px #00000059}.theme-dark #share-qrcode-box,html.dark #share-qrcode-box{background:var(--surface-1);border-color:var(--color-line)}.theme-dark .share-item,html.dark .share-item{color:var(--color-ink-2, #aaa)}.theme-dark .share-item[data-platform=qq]:hover{background:#12b7f51f;color:#12b7f5}.theme-dark .share-item[data-platform=weibo]:hover{background:#ff6a001f;color:#ff6a00}.theme-dark .share-item[data-platform=twitter]:hover{background:#ffffff14;color:#fff}.theme-dark .share-item[data-platform=wechat]:hover{background:#07c1601f;color:#07c160}.theme-dark .share-item[data-platform=copy]:hover{background:#ffffff0f;color:#ccc}.theme-dark .share-item[data-platform=poster]:hover{background:#f59e0b1f;color:#f59e0b}@media(max-width:767px){.share-dropdown{position:fixed;inset:auto 0 0;transform:none;width:100%;max-width:none;z-index:1200;padding:0 0 calc(12px + env(safe-area-inset-bottom,0px));background:transparent}.share-dropdown[aria-hidden=false]{animation:shareSheetIn .22s ease-out forwards}@keyframes shareSheetIn{0%{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}}.share-dropdown__grid{justify-content:space-around;flex-wrap:wrap;gap:6px;margin:0 10px;padding:14px 12px 16px;border-radius:14px 14px 10px 10px;box-shadow:0 -6px 28px #00000029}.share-item{min-width:64px;flex:1 1 28%;max-width:33%}#share-qrcode-box{position:static;margin:10px auto 0;transform:none}body.aksrt-share-sheet-open{overflow:hidden}body.aksrt-share-sheet-open:before{content:"";position:fixed;inset:0;background:#00000059;z-index:1190}}.theme-dark .post-drop-meta__menu,html.dark .post-drop-meta__menu{background:var(--surface-1, #323335);border-color:var(--color-line);box-shadow:0 8px 24px #00000059}.theme-dark .post-drop-meta__item,html.dark .post-drop-meta__item{color:var(--color-ink-2, #ccc)}.theme-dark .post-drop-meta__item:hover,html.dark .post-drop-meta__item:hover{background:#ffffff0f;color:#fff}.author-box{margin-bottom:16px;padding:18px;background:var(--surface-1, #fff);border:none;border-radius:var(--radius-2xl, 16px);box-shadow:var(--shadow-sm)}.single-metabox{display:flex;align-items:center;justify-content:flex-end;gap:8px}.post-drop-meta{position:relative}.post-drop-meta__menu{position:absolute;top:calc(100% + 8px);right:0;min-width:150px;padding:8px;border-radius:var(--radius, 8px);border:1px solid var(--color-line);background:var(--surface-page, #fff);box-shadow:var(--shadow-md, 0 8px 24px rgba(0, 0, 0, .12));display:none;z-index:20}.post-drop-meta.is-open .post-drop-meta__menu{display:grid;gap:4px}.post-drop-meta__item{width:100%;display:inline-flex;align-items:center;gap:8px;padding:8px 10px;border:0;border-radius:6px;background:transparent;color:var(--color-ink-2, var(--color-ink));text-decoration:none;font-size:13px;text-align:left;cursor:pointer}.post-drop-meta__item:hover{background:var(--color-line, rgba(50, 50, 50, .06));color:var(--color-primary)}.post-drop-meta__item i{width:16px;text-align:center}.author-box__header{display:flex;align-items:flex-start;gap:14px}.author-box__avatar{width:56px;height:56px;border-radius:50%;object-fit:cover;flex-shrink:0;border:3px solid var(--color-primary-soft, rgba(240, 68, 148, .2))}.author-box__info{flex:1;min-width:0}.author-box__name{font-size:1rem;font-weight:700;color:var(--color-ink);display:block;margin-bottom:4px}.author-box__name:hover{color:var(--color-primary)}.author-box__bio{font-size:13px;color:var(--color-ink-3, var(--color-ink-4));line-height:1.5;margin:0 0 6px}.author-box__stats{font-size:12px;color:var(--color-ink-4, var(--color-ink-4))}.author-box__stats strong{color:var(--color-ink);margin-right:2px}.author-box__posts{margin-top:14px;padding-top:12px;border-top:1px solid var(--color-line)}.author-box__posts-title{font-size:12px;font-weight:600;color:var(--color-ink-3, var(--color-ink-4));margin:0 0 8px}.author-box__posts ul{list-style:none;margin:0;padding:0}.author-box__posts li{padding:3px 0}.author-box__posts a{font-size:13px;color:var(--color-ink);display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden}.author-box__posts a:hover{color:var(--color-primary)}.author-box__posts a:before{content:"•";color:var(--color-primary)}.article-avatar .user-info{width:100%}.article-avatar .avatar-img{--this-size: 42px}.article-avatar .avatar-img img,.article-avatar .avatar{width:100%;height:100%;border-radius:50%;object-fit:cover}.article-avatar .display-name{font-weight:600;color:var(--key-color, #333)}.article-header .article-avatar .relative{margin-top:20px;position:relative;min-height:1px}.single-metabox{right:0;font-size:15px;--meta-color: var(--muted-color, #777)}.single-metabox .post-metas{background:var(--body-bg-color, #f5f5f5);right:0;padding:2px 6px;border-radius:100px;color:var(--meta-color);display:inline-flex;flex-wrap:wrap;align-items:center;gap:0}.single-metabox .post-metas item,.single-metabox .post-metas .item{margin:0 6px;font-size:13px;display:inline-flex;align-items:center;gap:4px}.single-metabox .post-drop-meta{position:relative;display:inline-block}.single-metabox.cover-meta{font-size:14px;right:1em;top:1.6em;--meta-color: rgba(255, 255, 255, .8);--body-bg-color: rgba(0, 0, 0, .3)}.article-avatar .line-form-line{display:block}.article-tags br{flex-basis:100%;width:100%;content:"";display:block;height:0}.article-tags .but.c-blue{color:#2196f3}.article-tags .but.c-yellow{color:#f0ad4e}.article-tags .but.c-green{color:#5cb85c}.article-tags .but.c-purple{color:#9c27b0}.article-tags .but.c-red{color:#f44336}.user-card.author{margin-bottom:16px;overflow:hidden}.user-card.author .user-avatar{display:flex;justify-content:center}.user-card.author .user-avatar .avatar,.user-card.author .user-avatar img{width:80px;height:80px;border-radius:50%;object-fit:cover}.user-card.author .user-name{display:flex;flex-wrap:nowrap;align-items:center;justify-content:center;gap:4px}.user-card.author .user-name .display-name{font-weight:700;color:var(--key-color, inherit)}.user-card.author .user-desc,.user-card.author .user-btns{text-align:center}.user-card.author .user-card-posts ul{list-style:none;margin:0;padding:0}.user-card.author .user-card-posts li{padding:6px 0;border-bottom:1px dashed var(--color-line, rgba(0,0,0,.06))}.user-card.author .user-card-posts li:last-child{border-bottom:0} diff --git a/src/Core/ScriptsPart1b.php b/src/Core/ScriptsPart1b.php index c6b12ce5..1eaa36ef 100644 --- a/src/Core/ScriptsPart1b.php +++ b/src/Core/ScriptsPart1b.php @@ -111,18 +111,6 @@ trait ScriptsPart1b { } } - - // Print stylesheet — only load on singular pages - if (is_singular()) { - wp_enqueue_style( - 'aksrt-print', - $base_uri . '/assets/css/frontend/print.css', - [], - $version, - 'print' - ); - } - // 4b. 路由判定 $is_home_or_archive = is_home() || is_front_page() || is_archive() || is_search(); // 资源单页(post + _aksrt_is_resource) @@ -166,6 +154,23 @@ trait ScriptsPart1b { // CMS route detection. $is_cms_mode = function_exists('aksrt_is_cms_mode') ? aksrt_is_cms_mode() : false; + $singular_assets = $this->resolve_singular_asset_requirements( + $is_single_post, + $is_single_resource, + $is_paid_content_single + ); + + if (!empty($singular_assets['needs_print'])) { + $print_path = get_template_directory() . '/assets/css/frontend/print.css'; + wp_enqueue_style( + 'aksrt-print', + $base_uri . '/assets/css/frontend/print.css', + [], + file_exists($print_path) ? (string) filemtime($print_path) : $version, + 'print' + ); + } + // 首页/归档/搜索:卡片 + 侧栏 if ($is_home_or_archive && !$is_fixed_homepage) { $enqueue_module('post-card'); @@ -173,55 +178,78 @@ trait ScriptsPart1b { $enqueue_module('breadcrumb'); } - // 单篇文章:所有 single 相关样式 - if ($is_single_post) { - // Prefer discrete enqueues over CSS @import (cache-bust + parallel load). - $single_parts = [ - 'legacy-utilities', - 'single-post/shell', - 'single-post/content', - 'single-post/code-blocks', - 'single-post/navigation', - 'single-post/cover', - 'single-post/author-actions', - 'single-post/related-toc', - 'single-post/hidden-content', - ]; - $single_dep = $deps[0] ?? $core_dep; - foreach ($single_parts as $part) { - $path = get_template_directory() . '/assets/css/frontend/' . $part . '.css'; - if (!file_exists($path)) { - continue; - } - wp_enqueue_style( - 'aksrt-' . str_replace('/', '-', $part), - $base_uri . '/assets/css/frontend/' . $part . '.css', - is_string($single_dep) ? [$single_dep] : (array) $deps, - filemtime($path) ?: $version - ); - } - // Keep aggregator handle for any third-party deps that target it. - $enqueue_module('single-post'); - $enqueue_module('post-card'); // 相关推荐使用 post-card 局部样式 - // Comments pack (legacy 1:1 discrete files). - $comment_parts = ['comments/shell', 'comments/mobile-item']; - $comment_dep = $deps[0] ?? $core_dep; - foreach ($comment_parts as $part) { - $path = get_template_directory() . '/assets/css/frontend/' . $part . '.css'; - if (!file_exists($path)) { - continue; - } - wp_enqueue_style( - 'aksrt-' . str_replace('/', '-', $part), - $base_uri . '/assets/css/frontend/' . $part . '.css', - is_string($comment_dep) ? [$comment_dep] : (array) $deps, - filemtime($path) ?: $version - ); - } - $enqueue_module('comments'); // aggregator handle for third-party deps - $enqueue_module('sidebar'); - $enqueue_module('breadcrumb'); - } + // Normal articles: one small core bundle plus content/settings-driven feature leaves. + if ($is_single_post && !empty($singular_assets['is_article'])) { + $single_filename = file_exists(get_template_directory() . '/assets/css/build/single.min.css') + ? 'single.min.css' + : 'single.css'; + $single_path = get_template_directory() . '/assets/css/build/' . $single_filename; + wp_enqueue_style( + 'aksrt-single-core', + $base_uri . '/assets/css/build/' . $single_filename, + [$core_dep], + file_exists($single_path) ? (string) filemtime($single_path) : $version + ); + + $single_features = [ + 'has_code' => 'single-post/code-blocks', + 'needs_navigation' => 'single-post/navigation', + 'needs_cover' => 'single-post/cover', + 'needs_related_toc' => 'single-post/related-toc', + 'has_hidden_content' => 'single-post/hidden-content', + ]; + $single_feature_handles = []; + foreach ($single_features as $requirement => $part) { + if (empty($singular_assets[$requirement])) { + continue; + } + $path = get_template_directory() . '/assets/css/frontend/' . $part . '.css'; + if (!file_exists($path)) { + continue; + } + $handle = 'aksrt-' . str_replace('/', '-', $part); + wp_enqueue_style( + $handle, + $base_uri . '/assets/css/frontend/' . $part . '.css', + ['aksrt-single-core'], + (string) filemtime($path) + ); + $single_feature_handles[] = $handle; + } + + // Preserve the public aggregate handle without requesting its @import file. + wp_register_style( + 'aksrt-single-post', + false, + array_merge(['aksrt-single-core'], $single_feature_handles), + $version + ); + wp_enqueue_style('aksrt-single-post'); + + if (!empty($singular_assets['needs_post_card'])) { + $enqueue_module('post-card'); + } + + if (!empty($singular_assets['needs_comments'])) { + $comments_filename = file_exists(get_template_directory() . '/assets/css/build/comments.min.css') + ? 'comments.min.css' + : 'comments.css'; + $comments_path = get_template_directory() . '/assets/css/build/' . $comments_filename; + wp_enqueue_style( + 'aksrt-comments', + $base_uri . '/assets/css/build/' . $comments_filename, + ['aksrt-single-post'], + file_exists($comments_path) ? (string) filemtime($comments_path) : $version + ); + } + + if (!empty($singular_assets['needs_sidebar'])) { + $enqueue_module('sidebar'); + } + if (!empty($singular_assets['needs_breadcrumb'])) { + $enqueue_module('breadcrumb'); + } + } // 静态页面 + 用户中心 + 友链等 if ($is_static_page) { @@ -516,9 +544,8 @@ trait ScriptsPart1b { } } - // Unified share-data builder — single payload assembler for every share - // surface (dropdown, copy, WeChat, poster). Loaded on any singular view. - if (is_singular()) { + // Unified share-data builder — only when the article renders share controls. + if (!empty($singular_assets['needs_share'])) { $share_data_js = get_template_directory() . '/assets/js/share-data-builder.js'; if (file_exists($share_data_js)) { wp_enqueue_script( @@ -531,8 +558,8 @@ trait ScriptsPart1b { } } - // 单篇文章 — poster-share.js(海报分享按钮) - if (is_singular('post')) { + // Poster generation is part of the article share dropdown. + if (!empty($singular_assets['needs_share'])) { $poster_js = get_template_directory() . '/assets/js/poster-share.js'; if (file_exists($poster_js)) { wp_enqueue_script( @@ -650,7 +677,17 @@ trait ScriptsPart1b { } } -$this->enqueue_public_fonts_js_and_data($base_uri, $core_dep, $deps, $is_fixed_homepage, $is_home_or_archive, $is_single_post, $is_single_resource, $version); + $this->enqueue_public_fonts_js_and_data( + $base_uri, + $core_dep, + $deps, + $is_fixed_homepage, + $is_home_or_archive, + $is_single_post, + $is_single_resource, + $version, + $singular_assets + ); } } diff --git a/src/Core/ScriptsPart1c.php b/src/Core/ScriptsPart1c.php index a0e54d8d..dca9df73 100644 --- a/src/Core/ScriptsPart1c.php +++ b/src/Core/ScriptsPart1c.php @@ -16,10 +16,136 @@ defined('ABSPATH') || exit; */ trait ScriptsPart1c { + /** + * Resolve the assets required by the current singular response. + * + * @return array + */ + private function resolve_singular_asset_requirements(bool $is_single_post, bool $is_single_resource, bool $is_paid_content_single): array { + $requirements = [ + 'is_article' => false, + 'has_code' => false, + 'has_toc' => false, + 'has_video' => false, + 'has_hidden_content' => false, + 'needs_cover' => false, + 'needs_navigation' => false, + 'needs_related_toc' => false, + 'needs_post_card' => false, + 'needs_sidebar' => false, + 'needs_breadcrumb' => false, + 'needs_comments' => false, + 'needs_comment_tools' => false, + 'needs_page_template' => false, + 'needs_reward' => false, + 'needs_yiyan' => false, + 'needs_share' => false, + 'needs_print' => false, + ]; + + if (!is_singular()) { + return $requirements; + } + + $post_id = (int) get_queried_object_id(); + $post = $post_id > 0 ? get_post($post_id) : null; + if (!$post instanceof \WP_Post) { + return $requirements; + } + + $is_docs_article = $is_single_post + && function_exists('aksrt_single_is_docs_page') + && aksrt_single_is_docs_page($post_id); + $is_article = ($is_single_post || $is_single_resource) && !$is_docs_article; + $settings = function_exists('aksrt_resolve_single_post_display_settings') + ? aksrt_resolve_single_post_display_settings($post_id) + : []; + $content = (string) $post->post_content; + $display_content = $content + . (string) ($settings['front_content'] ?? '') + . (string) ($settings['after_content'] ?? ''); + + $has_code = (bool) preg_match( + '/(?:/i', $content); + $has_related = $is_article && !empty($settings['related_enabled']); + $layout = function_exists('aksrt_get_post_show_layout') + ? (string) aksrt_get_post_show_layout($post_id) + : ''; + + $requirements['is_article'] = $is_article; + $requirements['has_code'] = $has_code; + $requirements['has_toc'] = $is_article && $heading_count >= 2; + $requirements['has_video'] = $has_video; + $requirements['has_hidden_content'] = $has_hidden_content || $has_yiyan || $has_inserted_content; + $requirements['needs_cover'] = $is_article && ( + $show_cover + || !empty($settings['breadcrumbs']) + || $is_paid_content_single + ); + $requirements['needs_navigation'] = $is_article && $has_page_break; + $requirements['needs_related_toc'] = $is_article && ( + !empty($settings['reading_progress']) + || !empty($settings['maxheight_enabled']) + || !empty($settings['prevnext']) + || $has_related + ); + $requirements['needs_post_card'] = $has_related; + $requirements['needs_sidebar'] = $is_article + && get_post_type($post_id) === 'post' + && $layout !== 'no_sidebar' + && function_exists('aksrt_is_show_sidebar') + && aksrt_is_show_sidebar(); + $requirements['needs_breadcrumb'] = $is_article && !empty($settings['breadcrumbs']); + $requirements['needs_comments'] = $has_comments; + $requirements['needs_comment_tools'] = $can_use_comment_form; + $requirements['needs_page_template'] = !empty($settings['lightbox']) || !empty($settings['maxheight_enabled']); + $requirements['needs_reward'] = $is_article && !empty($settings['rewards_enabled']); + $requirements['needs_yiyan'] = $has_yiyan; + $requirements['needs_share'] = $is_article && !empty($settings['share_enabled']); + $requirements['needs_print'] = !empty($settings['print_enabled']); + + return $requirements; + } + /** * Fonts / FA / global JS stack / aksrtData (split from enqueue_public). */ - private function enqueue_public_fonts_js_and_data($base_uri, $core_dep, $deps, $is_fixed_homepage, $is_home_or_archive, $is_single_post, $is_single_resource, $version): void { + private function enqueue_public_fonts_js_and_data($base_uri, $core_dep, $deps, $is_fixed_homepage, $is_home_or_archive, $is_single_post, $is_single_resource, $version, array $singular_assets): void { $runtime_uri = $base_uri . '/assets'; $runtime_main_path = get_template_directory() . '/assets/js/runtime/main.min.js'; $runtime_version = file_exists($runtime_main_path) ? (string) filemtime($runtime_main_path) : $version; @@ -96,7 +222,7 @@ trait ScriptsPart1c { // Code block enhancements (copy button + language label) $precode_js = get_template_directory() . '/assets/js/precode.js'; - if (is_singular() && file_exists($precode_js)) { + if (!empty($singular_assets['has_code']) && file_exists($precode_js)) { wp_enqueue_script( 'aksrt-precode', $base_uri . '/assets/js/precode.js', @@ -108,8 +234,7 @@ trait ScriptsPart1c { // Input field enhancements (auto-resize, counter, validation) $input_expand_js = get_template_directory() . '/assets/js/input-expand.js'; - $needs_input_enhancements = is_singular() - || (bool) get_query_var('aksrt_sign') + $needs_input_enhancements = (bool) get_query_var('aksrt_sign') || (bool) get_query_var('aksrt_user_center') || (bool) get_query_var('aksrt_author_identifier'); if ($needs_input_enhancements && file_exists($input_expand_js)) { @@ -124,7 +249,7 @@ trait ScriptsPart1c { // Section navs: article TOC / scrollspy $section_navs_js = get_template_directory() . '/assets/js/section-navs.js'; - if (is_singular() && file_exists($section_navs_js)) { + if (!empty($singular_assets['has_toc']) && file_exists($section_navs_js)) { wp_enqueue_script( 'aksrt-section-navs', $base_uri . '/assets/js/section-navs.js', @@ -136,7 +261,7 @@ trait ScriptsPart1c { // Video player (MP4/HLS/FLV) $video_player_js = get_template_directory() . '/assets/js/video-player.js'; - if (is_singular() && file_exists($video_player_js)) { + if (!empty($singular_assets['has_video']) && file_exists($video_player_js)) { wp_enqueue_script( 'aksrt-video-player', $base_uri . '/assets/js/video-player.js', @@ -148,7 +273,7 @@ trait ScriptsPart1c { // Reward (打赏) $reward_js = get_template_directory() . '/assets/js/reward.js'; - if (($is_single_post || $is_single_resource) && file_exists($reward_js)) { + if (!empty($singular_assets['needs_reward']) && file_exists($reward_js)) { wp_enqueue_script( 'aksrt-reward', $base_uri . '/assets/js/reward.js', @@ -160,7 +285,7 @@ trait ScriptsPart1c { // Yiyan (一言轮播) $yiyan_js = get_template_directory() . '/assets/js/yiyan.js'; - if (($is_single_post || $is_single_resource) && file_exists($yiyan_js)) { + if (!empty($singular_assets['needs_yiyan']) && file_exists($yiyan_js)) { wp_enqueue_script( 'aksrt-yiyan', $base_uri . '/assets/js/yiyan.js', @@ -242,7 +367,7 @@ trait ScriptsPart1c { // Comment toolbar (smilie/code/image/quick shortcodes) — post form. - $load_comment_tools = (is_singular() && comments_open()); + $load_comment_tools = !empty($singular_assets['needs_comment_tools']); if ($load_comment_tools) { $comment_tools_path = get_template_directory() . '/assets/js/comment-tools.js'; wp_enqueue_script( @@ -265,7 +390,7 @@ trait ScriptsPart1c { // Comment actions client (like / edit / delete / moderate / pin). // Submit path lives in assets/js/core/comments.js (REST). - if (is_singular() && (comments_open() || (int) get_comments_number() > 0)) { + if (!empty($singular_assets['needs_comments'])) { $comment_ajax_path = get_template_directory() . '/assets/js/comment-ajax.js'; if (file_exists($comment_ajax_path)) { wp_enqueue_script( @@ -278,7 +403,7 @@ trait ScriptsPart1c { } } - if (is_singular()) { + if (!empty($singular_assets['needs_page_template'])) { $page_template_path = get_template_directory() . '/assets/js/page-template.js'; if (file_exists($page_template_path)) { wp_enqueue_script( @@ -292,7 +417,7 @@ trait ScriptsPart1c { } // Post/resource share functionality - if ($is_single_post || $is_single_resource) { + if (!empty($singular_assets['needs_share'])) { $weixin_share_path = get_template_directory() . '/assets/js/weixin-share.js'; if (file_exists($weixin_share_path)) { wp_enqueue_script( diff --git a/tests/widget-system/post-visual-contract.test.cjs b/tests/widget-system/post-visual-contract.test.cjs index d2794247..9f53185e 100644 --- a/tests/widget-system/post-visual-contract.test.cjs +++ b/tests/widget-system/post-visual-contract.test.cjs @@ -434,3 +434,62 @@ test('public user home stays param-free and swaps panels via REST fragments', () assert.match(authorJs, /data-uh-sub/); assert.match(authorJs, /AksrtFrontend\.rehydrate\(panel, 'ajax'\)/); }); + +test('single articles enqueue only content and settings driven assets', () => { + const enqueue = read('src/Core/ScriptsPart1b.php'); + const runtime = read('src/Core/ScriptsPart1c.php'); + const builder = read('tools/build-public-assets.mjs'); + const singleStart = enqueue.indexOf('// Normal articles: one small core bundle'); + const staticPageStart = enqueue.indexOf('// 静态页面 + 用户中心', singleStart); + const singleBlock = enqueue.slice(singleStart, staticPageStart); + + assert.ok(singleStart >= 0 && staticPageStart > singleStart); + assert.match(builder, /'single\.css': \[[\s\S]*?single-post\/shell\.css'[\s\S]*?single-post\/content\.css'[\s\S]*?single-post\/author-actions\.css'/); + assert.match(builder, /'comments\.css': \[[\s\S]*?comments\/shell\.css'[\s\S]*?comments\/mobile-item\.css'/); + assert.match(singleBlock, /build\/single\.min\.css/); + assert.match(singleBlock, /wp_register_style\([\s\S]*?'aksrt-single-post'[\s\S]*?array_merge\(\['aksrt-single-core'\], \$single_feature_handles\)/); + assert.doesNotMatch(singleBlock, /\$enqueue_module\('single-post'\)|\$enqueue_module\('comments'\)/); + + for (const requirement of [ + 'has_code', + 'needs_navigation', + 'needs_cover', + 'needs_related_toc', + 'has_hidden_content', + ]) { + assert.match(singleBlock, new RegExp(`'${requirement}'\\s*=>`)); + } + + for (const requirement of [ + 'needs_post_card', + 'needs_comments', + 'needs_sidebar', + 'needs_breadcrumb', + ]) { + assert.match(singleBlock, new RegExp(`singular_assets\\['${requirement}'\\]`)); + } + + assert.match(runtime, /wp:\(\?:code\|preformatted\|aksrt\\\/enlighter\)/); + assert.match(runtime, /preg_match_all\('\/ { assert.match(builder, /loader: 'css'/); assert.match(builder, /minify: true/); - for (const basename of ['public', 'homepage']) { + for (const basename of ['public', 'homepage', 'single', 'comments']) { const readablePath = path.join(root, 'assets', 'css', 'build', `${basename}.css`); const minifiedPath = path.join(root, 'assets', 'css', 'build', `${basename}.min.css`); diff --git a/tools/build-public-assets.mjs b/tools/build-public-assets.mjs index 93b9a623..849bf128 100644 --- a/tools/build-public-assets.mjs +++ b/tools/build-public-assets.mjs @@ -47,6 +47,16 @@ const cssBundles = { 'assets/css/frontend/homepage-fixed/ajax-tab-skeleton-placeholder.css', 'assets/css/frontend/homepage-fixed/ajax-tab-error-state.css', ], + 'single.css': [ + 'assets/css/frontend/legacy-utilities.css', + 'assets/css/frontend/single-post/shell.css', + 'assets/css/frontend/single-post/content.css', + 'assets/css/frontend/single-post/author-actions.css', + ], + 'comments.css': [ + 'assets/css/frontend/comments/shell.css', + 'assets/css/frontend/comments/mobile-item.css', + ], }; const publicScripts = [