diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..ba0b509c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+# Local tooling / agent workspace
+.claude/
+.compare/
+
+# Project planning / internal docs
+CLAUDE.md
+ask-*.md
+docs/
+
+# Frontend build output and installed dependencies
+assets/admin/build/
+assets/admin/node_modules/
+assets/admin/.vite-temp/
+
+# PHP installed dependencies
+vendor/
+
+# Temporary / recovery helpers
+restore-helper-monoliths.php
+
+# OS / editor noise
+.DS_Store
+Thumbs.db
+*.log
\ No newline at end of file
diff --git a/assets/css/admin/admin-panel.css b/assets/css/admin/admin-panel.css
new file mode 100644
index 00000000..8d876934
--- /dev/null
+++ b/assets/css/admin/admin-panel.css
@@ -0,0 +1,83 @@
+body.toplevel_page_aksrt-settings {
+ background: #f5f7fb;
+}
+
+body.toplevel_page_aksrt-settings #wpcontent {
+ padding-left: 0;
+}
+
+body.toplevel_page_aksrt-settings #wpbody-content {
+ padding-bottom: 0;
+}
+
+body.toplevel_page_aksrt-settings #wpbody-content .wrap {
+ margin: 0;
+ padding: 0;
+}
+
+body.toplevel_page_aksrt-settings #wpbody-content .wrap > h1:first-child {
+ display: none !important;
+}
+
+body.toplevel_page_aksrt-settings #wpbody-content .notice,
+body.toplevel_page_aksrt-settings #wpbody-content .updated,
+body.toplevel_page_aksrt-settings #wpbody-content .error {
+ position: relative;
+ z-index: 3;
+ margin: 18px 20px 0 0;
+}
+
+body.toplevel_page_aksrt-settings #collapse-menu {
+ display: none !important;
+}
+
+#aksrt-admin-app {
+ position: relative;
+ min-height: calc(100vh - 32px);
+ isolation: isolate;
+ background: transparent;
+}
+
+#aksrt-admin-app:empty::before {
+ content: "AKSRT 管理台加载中...";
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: calc(100vh - 32px);
+ color: #64748b;
+ font-size: 14px;
+ letter-spacing: 0.04em;
+}
+
+.n-modal-mask,
+.n-modal,
+.n-message-container,
+.n-notification-container,
+.n-dialog-mask,
+.n-dialog,
+.n-popover,
+.n-drawer-mask,
+.n-drawer {
+ z-index: 100000 !important;
+}
+
+@media screen and (max-width: 782px) {
+ /* 隐藏 WP 后台默认顶栏的多余间距 */
+ body.toplevel_page_aksrt-settings #wpbody {
+ padding-top: 0;
+ }
+
+ body.toplevel_page_aksrt-settings #wpcontent {
+ margin-left: 0 !important;
+ }
+
+ #aksrt-admin-app,
+ #aksrt-admin-app:empty::before {
+ min-height: calc(100vh - 46px);
+ }
+
+ /* 移动端把 WP 折叠菜单按钮藏掉,避免与自定义菜单按钮重叠 */
+ body.toplevel_page_aksrt-settings #wp-admin-bar-menu-toggle {
+ display: none;
+ }
+}
diff --git a/assets/css/build/core.min.css.disabled b/assets/css/build/core.min.css.disabled
new file mode 100644
index 00000000..63489b6e
--- /dev/null
+++ b/assets/css/build/core.min.css.disabled
@@ -0,0 +1,1032 @@
+/**
+ * AKSRT Design Tokens v7 — 1:1 Zibll Alignment
+ * ------------------------------------------------------------
+ * 单一真理源(Single Source of Truth)
+ * 所有颜色、字体、间距、动效都从此处读取,禁止在组件内硬编码。
+ * 严格对齐 zibll main.css 的视觉值。
+ */
+
+:root {
+ /* ===== Primary — Zibll theme-color (#f04494 pink) ===== */
+ --color-primary: #f04494;
+ --color-primary-hover: #e0307e;
+ --color-primary-active: #c9206d;
+ --color-primary-soft: rgba(240, 68, 148, 0.10);
+ --color-primary-softer: rgba(240, 68, 148, 0.05);
+ --color-on-primary: #FFFFFF;
+
+ /* ===== Ink (text) — 对齐 zibll --key-color / --main-color / --muted-color ===== */
+ --color-ink: #333333; /* zibll --key-color */
+ --color-ink-2: #4e5358; /* zibll --main-color */
+ --color-ink-3: #777777; /* zibll --muted-color */
+ --color-ink-4: #999999; /* zibll --muted-2-color */
+
+ /* ===== Surface — 对齐 zibll --body-bg-color / --main-bg-color / --muted-bg-color ===== */
+ --surface-page: #f5f6f7; /* zibll --body-bg-color */
+ --surface-1: #FFFFFF; /* zibll --main-bg-color */
+ --surface-2: #eeeeee; /* zibll --muted-bg-color */
+ --surface-3: #e8e8e8; /* 输入框 / code */
+
+ /* ===== Borders — 对齐 zibll --main-border-color ===== */
+ --color-line: rgba(50, 50, 50, 0.06);
+ --color-line-soft: rgba(0, 0, 0, 0.03);
+
+ /* ===== State colors ===== */
+ --color-success: #10B981;
+ --color-warning: #F59E0B;
+ --color-error: #EF4444;
+ --color-info: #3B82F6;
+
+ /* ===== Accent (action green — zibll tabbar/CTA) ===== */
+ --color-accent: #18a058;
+ --color-accent-soft: rgba(24, 160, 88, 0.12);
+ --color-accent-shadow: rgba(24, 160, 88, 0.28);
+
+ /* ===== Fonts — 对齐 zibll(系统默认字体栈)===== */
+ --font-display: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
+ --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
+ --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
+ --font-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+
+ /* ===== Type scale ===== */
+ --text-xs: 0.75rem; /* 12 */
+ --text-sm: 0.875rem; /* 14 */
+ --text-base: 1rem; /* 16 */
+ --text-md: 1.125rem; /* 18 */
+ --text-lg: 1.25rem; /* 20 */
+ --text-xl: 1.5rem; /* 24 */
+ --text-2xl: 1.875rem; /* 30 */
+ --text-3xl: 2.25rem; /* 36 */
+ --text-4xl: 3rem; /* 48 */
+ --text-5xl: 3.75rem; /* 60 */
+ --leading-tight: 1.2;
+ --leading-snug: 1.4;
+ --leading-normal: 1.6; /* zibll body line-height */
+ --leading-relaxed: 1.6;
+
+ /* ===== Spacing (4px base) ===== */
+ --space-1: 4px;
+ --space-2: 8px;
+ --space-3: 12px;
+ --space-4: 16px;
+ --space-5: 20px;
+ --space-6: 24px;
+ --space-7: 32px;
+ --space-8: 40px;
+ --space-9: 48px;
+ --space-10: 64px;
+ --space-11: 80px;
+ --space-12: 96px;
+
+ /* ===== Radius — 对齐 zibll --main-radius: 8px ===== */
+ --radius-sm: 4px;
+ --radius: 8px;
+ --radius-lg: 8px;
+ --radius-xl: 12px;
+ --radius-pill: 100px;
+ --radius-avatar: 50%;
+
+ /* ===== Shadows — 对齐 zibll --main-shadow: rgba(116,116,116,0.08) ===== */
+ --shadow-sm: 0 0 10px rgba(116, 116, 116, 0.08);
+ --shadow: 0 0 10px rgba(116, 116, 116, 0.08);
+ --shadow-lg: 0 0 10px rgba(116, 116, 116, 0.12);
+ --shadow-drawer: 0 8px 40px rgba(0, 0, 0, 0.20);
+
+ /* ===== Layout — 对齐 zibll --mian-max-width: 1200px ===== */
+ --nav-height: 60px;
+ --container: 1200px;
+ --container-wide: 1440px;
+ --container-read: 720px;
+ --container-page: 860px;
+ --sidebar-width: 300px;
+ --content-gap: 48px;
+ --sidebar-bp: 1024px;
+
+ /* ===== Motion ===== */
+ --ease: cubic-bezier(.4, 0, .2, 1);
+ --ease-out: cubic-bezier(.16, 1, .3, 1);
+ --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
+ --dur-fast: 0.15s;
+ --dur: 0.25s;
+ --dur-slow: 0.4s;
+
+ /* ===== Focus Ring — 对齐 zibll focus-shadow-color ===== */
+ --focus-ring: 0 0 2px 3px rgba(253, 83, 161, 0.4);
+
+ /* ===== Z-index layers ===== */
+ --z-dropdown: 100;
+ --z-sticky: 200;
+ --z-fixed: 300;
+ --z-overlay: 400;
+ --z-modal: 500;
+ --z-popover: 600;
+ --z-toast: 700;
+ --z-tooltip: 800;
+
+ /* ===== Button sizes — 对齐 zibll ===== */
+ --radius-btn: 4px;
+ --btn-sm-h: 28px;
+ --btn-md-h: 34px;
+ --btn-lg-h: 44px;
+
+ /* ===== Card density — 对齐 zibll .box-body { padding: 15px } ===== */
+ --card-padding: 15px;
+ --card-padding-sm: 10px;
+ --card-gap: 16px;
+
+ /* ===== Skeleton loader ===== */
+ --skeleton-base: var(--surface-2);
+ --skeleton-shine: var(--surface-1);
+
+ /* ===== Extended tokens (used by components) ===== */
+ --color-primary-light: var(--color-primary-soft);
+ --color-surface: var(--surface-1);
+ --color-line-strong: var(--color-line);
+ --color-bg-hover: var(--surface-2);
+ --color-border-light: var(--color-line-soft);
+ --color-fill: var(--surface-2);
+ --color-warning-bg: #fffbe6;
+ --color-warning-text: #ad6800;
+
+ --text-secondary: var(--color-ink-3);
+ --text-tertiary: var(--color-ink-4);
+
+ --surface-active: var(--surface-2);
+ --surface-card: var(--surface-1);
+ --surface-hover: var(--surface-2);
+ --surface-secondary: var(--surface-2);
+
+ --radius-code: var(--radius);
+ --radius-full: 100px;
+ --shadow-xl: 0 0 10px rgba(116, 116, 116, 0.12);
+ --space-16: 64px;
+ --z-floating: 900;
+
+ --transition-fast: 0.15s ease;
+ --transition-base: 0.25s ease;
+
+ /* ===== Composite / Context tokens — 对齐 zibll ===== */
+ --header-bg: var(--blur-bg);
+ --header-color: var(--color-ink-2);
+ --footer-bg: var(--surface-1);
+ --footer-color: var(--color-ink-4);
+ --blur-bg: rgba(255, 255, 255, 0.80);
+ --float-btn-bg: rgba(200, 200, 200, 0.40);
+
+ /* ===== AKSRT-to-AKSRT canonical aliases ===== */
+ --content-max: var(--container);
+ --font-heading: var(--font-ui);
+ --radius-card: var(--radius);
+ --radius-md: var(--radius);
+ --color-primary-50: var(--color-primary-soft);
+ --color-primary-dark: var(--color-primary-active);
+ --shadow-md: var(--shadow);
+ --mini-radius: calc(var(--radius) / 1.4);
+ --single-cover-scale: 35%;
+
+ /* ===== Avatar size system — Zibll --this-size 等价 ===== */
+ --aksrt-avatar-size-xs: 24px;
+ --aksrt-avatar-size-sm: 32px;
+ --aksrt-avatar-size: 40px;
+ --aksrt-avatar-size-lg: 56px;
+ --aksrt-avatar-size-xl: 80px;
+
+ /* ===== Post card thumbnail scale ===== */
+ --aksrt-card-thumb-scale: 56.25%; /* 16:9 */
+
+ /* ===== Multi-color palette (for buttons / badges / gradients) ===== */
+ --aksrt-rose: #f43f5e;
+ --aksrt-rose-soft: rgba(244, 63, 94, 0.12);
+ --aksrt-blue: #3b82f6;
+ --aksrt-blue-soft: rgba(59, 130, 246, 0.12);
+ --aksrt-green: #10b981;
+ --aksrt-green-soft: rgba(16, 185, 129, 0.12);
+ --aksrt-orange: #f97316;
+ --aksrt-orange-soft:rgba(249, 115, 22, 0.12);
+ --aksrt-purple: #8b5cf6;
+ --aksrt-purple-soft:rgba(139, 92, 246, 0.12);
+ --aksrt-cyan: #06b6d4;
+ --aksrt-cyan-soft: rgba(6, 182, 212, 0.12);
+ --aksrt-yellow: #eab308;
+ --aksrt-yellow-soft:rgba(234, 179, 8, 0.12);
+ --aksrt-red: #ef4444;
+ --aksrt-red-soft: rgba(239, 68, 68, 0.12);
+ --aksrt-teal: #14b8a6;
+ --aksrt-teal-soft: rgba(20, 184, 166, 0.12);
+ --aksrt-indigo: #6366f1;
+ --aksrt-indigo-soft:rgba(99, 102, 241, 0.12);
+ --aksrt-pink: #ec4899;
+ --aksrt-pink-soft: rgba(236, 72, 153, 0.12);
+
+ /* ===== VIP / special gradients ===== */
+ --aksrt-vip-gold-1: #f6d365;
+ --aksrt-vip-gold-2: #fda085;
+ --aksrt-grad-sunset-1: #f093fb;
+ --aksrt-grad-sunset-2: #f5576c;
+ --aksrt-grad-ocean-1: #4facfe;
+ --aksrt-grad-ocean-2: #00f2fe;
+ --aksrt-grad-forest-1: #43e97b;
+ --aksrt-grad-forest-2: #38f9d7;
+ --aksrt-grad-night-1: #a18cd1;
+ --aksrt-grad-night-2: #fbc2eb;
+ --aksrt-grad-fire-1: #f83600;
+ --aksrt-grad-fire-2: #f9d423;
+
+ /* ===== Component sizing ===== */
+ --aksrt-toggle-w: 44px;
+ --aksrt-toggle-h: 24px;
+ --aksrt-stepper-h: 36px;
+ --aksrt-badge-h: 22px;
+
+ /* ===== Legacy name bridge ===== */
+ --text-1: var(--color-ink);
+ --text-2: var(--color-ink-2);
+ --text-3: var(--color-ink-3);
+ --border: var(--color-line);
+ --color-text-1: var(--color-ink);
+ --color-text-2: var(--color-ink-2);
+ --color-text-3: var(--color-ink-3);
+ --color-primary-bg: var(--color-primary-softer);
+ --color-danger: var(--color-error);
+}
+
+/* ============================================================
+ * Blur-bg fallback cascade (mirrors zibll behaviour)
+ * ============================================================ */
+@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
+ :root {
+ --blur-bg: var(--surface-1);
+ --header-bg: var(--surface-1);
+ }
+}
+
+body.modal-open,
+body.dialog-open {
+ --blur-bg: var(--surface-1);
+ --header-bg: var(--surface-1);
+}
+
+body.modal-open .site-nav,
+body.modal-open .footer-tabbar,
+body.modal-open .float-right .float-btn,
+body.dialog-open .site-nav,
+body.dialog-open .footer-tabbar,
+body.dialog-open .float-right .float-btn {
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
+}
+
+/* ============================================================
+ * Dark Theme — 对齐 zibll .dark-theme (#292a2d 范围)
+ * ============================================================ */
+html.dark {
+ --color-ink: #f8fafc;
+ --color-ink-2: #e5eef7;
+ --color-ink-3: #b4b6bb;
+ --color-ink-4: #888a8f;
+
+ --surface-page: #292a2d;
+ --surface-1: #323335;
+ --surface-2: #2d2e31;
+ --surface-3: #3a3b3e;
+
+ --color-line: rgba(114, 114, 114, 0.1);
+ --color-line-soft: rgba(184, 184, 184, 0.02);
+
+ --color-primary-soft: rgba(240, 68, 148, 0.16);
+ --color-primary-softer: rgba(240, 68, 148, 0.08);
+
+ --color-primary-light: var(--color-primary-soft);
+ --color-surface: var(--surface-1);
+ --color-line-strong: var(--color-line);
+ --color-bg-hover: var(--surface-2);
+ --color-border-light: var(--color-line-soft);
+ --color-fill: var(--surface-2);
+
+ --text-secondary: var(--color-ink-3);
+ --text-tertiary: var(--color-ink-4);
+
+ --surface-active: var(--surface-2);
+ --surface-card: var(--surface-1);
+ --surface-hover: var(--surface-2);
+ --surface-secondary: var(--surface-2);
+
+ --shadow-xl: 0 0 10px rgba(24, 24, 24, 0.15);
+
+ --shadow-sm: 0 0 10px rgba(24, 24, 24, 0.1);
+ --shadow: 0 0 10px rgba(24, 24, 24, 0.1);
+ --shadow-lg: 0 0 10px rgba(24, 24, 24, 0.15);
+ --shadow-drawer: 0 8px 40px rgba(0, 0, 0, 0.55);
+
+ --blur-bg: rgba(50, 51, 53, 0.80);
+ --float-btn-bg: rgba(70, 70, 70, 0.40);
+ --header-bg: var(--blur-bg);
+ --footer-bg: var(--surface-1);
+ --footer-color: var(--color-ink-4);
+ --shadow-md: var(--shadow);
+
+ --skeleton-base: #3a3b3e;
+ --skeleton-shine: #444548;
+
+ /* Multi-color palette — dark mode: same hue, softer tint backgrounds */
+ --aksrt-rose-soft: rgba(244, 63, 94, 0.18);
+ --aksrt-blue-soft: rgba(59, 130, 246, 0.18);
+ --aksrt-green-soft: rgba(16, 185, 129, 0.18);
+ --aksrt-orange-soft:rgba(249, 115, 22, 0.18);
+ --aksrt-purple-soft:rgba(139, 92, 246, 0.18);
+ --aksrt-cyan-soft: rgba(6, 182, 212, 0.18);
+ --aksrt-yellow-soft:rgba(234, 179, 8, 0.18);
+ --aksrt-red-soft: rgba(239, 68, 68, 0.18);
+ --aksrt-teal-soft: rgba(20, 184, 166, 0.18);
+ --aksrt-indigo-soft:rgba(99, 102, 241, 0.18);
+ --aksrt-pink-soft: rgba(236, 72, 153, 0.18);
+}
+
+/* Dark mode component refinements */
+html.dark .site-nav {
+ border-bottom-color: var(--color-line);
+ box-shadow: none;
+}
+
+html.dark .footer-tabbar {
+ background: rgba(50, 51, 53, 0.80);
+ box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.20);
+}
+
+html.dark .n-drawer,
+html.dark .n-modal,
+html.dark .n-dialog {
+ background: var(--surface-1);
+}
+
+html.dark .post-card,
+html.dark .widget,
+html.dark .aksrt-theme-box,
+html.dark .theme-box {
+ border-color: var(--color-line);
+}
+/**
+ * AKSRT Reset
+ * 现代精简 reset,结合 box-sizing 与 a11y 友好的默认值。
+ */
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 16px;
+ scroll-behavior: smooth;
+ -webkit-text-size-adjust: 100%;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ overflow-x: hidden;
+ text-rendering: optimizeLegibility;
+}
+
+body {
+ margin: 0;
+ font-family: var(--font-body);
+ font-size: var(--text-base);
+ line-height: var(--leading-normal);
+ background-color: var(--surface-page);
+ color: var(--color-ink-2);
+ transition: background-color 0.25s ease, color 0.25s ease;
+ overflow-x: hidden;
+}
+
+/* 媒体元素 */
+img,
+picture,
+video,
+canvas,
+svg {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+
+/* 表单元素继承字体 */
+input,
+button,
+textarea,
+select {
+ font: inherit;
+ color: inherit;
+}
+
+button {
+ background: none;
+ border: 0;
+ padding: 0;
+ cursor: pointer;
+}
+
+/* 链接 */
+a {
+ color: inherit;
+ text-decoration: none;
+ transition: color var(--dur-fast) var(--ease);
+}
+
+a:hover {
+ color: var(--color-primary);
+}
+
+/* 焦点环:a11y 关键 */
+:focus {
+ outline: none;
+}
+
+:focus-visible {
+ outline: none;
+ box-shadow: var(--focus-ring);
+ border-radius: 4px;
+}
+
+/* 选区色 */
+::selection {
+ background: var(--color-primary-soft);
+ color: var(--color-ink);
+}
+
+/* 屏幕阅读器隐藏 */
+.screen-reader-text,
+.sr-only {
+ position: absolute !important;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border: 0;
+}
+
+.screen-reader-text:focus,
+.sr-only:focus {
+ position: fixed !important;
+ top: 16px;
+ left: 16px;
+ width: auto;
+ height: auto;
+ padding: 8px 16px;
+ background: var(--surface-1);
+ color: var(--color-ink);
+ z-index: 100000;
+ clip: auto;
+ box-shadow: var(--shadow-lg);
+ border-radius: var(--radius);
+}
+
+/* 减少动效偏好 */
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+}
+/**
+ * AKSRT Typography — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll main.css 的排版系统
+ */
+
+/* ===== 全局标题 — 对齐 zibll line 8947 ===== */
+h1, h2, h3, h4, h5, h6 {
+ font-weight: 700;
+ margin: 20px 0 10px;
+ color: var(--key-color, #333);
+}
+
+h1 { font-size: 22px; }
+h2 { font-size: 20px; }
+h3 { font-size: 18px; }
+h4 { font-size: 16px; }
+h5 { font-size: 15px; }
+h6 { font-size: 14px; }
+
+/* ===== 文章正文 — 对齐 zibll line 8740 ===== */
+.wp-posts-content,
+.entry-content,
+.prose {
+ font-size: 16px;
+ line-height: 2;
+ color: var(--main-color, #4e5358);
+ min-height: 90px;
+}
+
+/* ===== 文章内标题 — 对齐 zibll line 8947 ===== */
+.wp-posts-content h1,
+.wp-posts-content h2,
+.wp-posts-content h3,
+.wp-posts-content h4,
+.wp-posts-content h5,
+.entry-content h1,
+.entry-content h2,
+.entry-content h3,
+.entry-content h4,
+.entry-content h5,
+.prose h1,
+.prose h2,
+.prose h3,
+.prose h4,
+.prose h5 {
+ font-weight: 700;
+ margin: 20px 0 10px;
+ color: var(--key-color, #333);
+}
+
+.wp-posts-content h1,
+.entry-content h1,
+.prose h1 { font-size: 22px; }
+
+.wp-posts-content h2,
+.entry-content h2,
+.prose h2 { font-size: 20px; }
+
+.wp-posts-content h3,
+.entry-content h3,
+.prose h3 { font-size: 18px; }
+
+.wp-posts-content h4,
+.entry-content h4,
+.prose h4 { font-size: 16px; }
+
+/* ===== 段落 — 对齐 zibll line 8999 ===== */
+.wp-posts-content p,
+.entry-content p,
+.prose p {
+ margin: 0 0 20px;
+ word-wrap: break-word;
+}
+
+/* ===== 链接 — 对齐 zibll line 8836 ===== */
+.wp-posts-content a,
+.entry-content a,
+.prose a {
+ color: var(--focus-color, #f04494);
+ text-decoration: none;
+}
+
+.wp-posts-content a:hover,
+.entry-content a:hover,
+.prose a:hover {
+ color: var(--focus-color, #f04494);
+}
+
+/* ===== 图片 — 对齐 zibll line 8850 ===== */
+.wp-posts-content img,
+.entry-content img,
+.prose img {
+ max-width: 100%;
+ height: auto;
+ display: block;
+ margin: auto;
+}
+
+/* ===== 内联代码 — 对齐 zibll line 8844 ===== */
+.wp-posts-content code:not(pre code),
+.entry-content code:not(pre code),
+.prose code:not(pre code) {
+ color: #ff3c98;
+ background: rgba(253, 153, 153, 0.2);
+ font-family: var(--font-mono, monospace);
+ font-size: 0.9em;
+}
+
+/* ===== 代码块 — 对齐 zibll ===== */
+.wp-posts-content pre,
+.entry-content pre,
+.prose pre {
+ position: relative;
+ background: #282c34;
+ color: #abb2bf;
+ padding: 15px;
+ border-radius: var(--main-radius, 8px);
+ overflow-x: auto;
+ font-size: 14px;
+ line-height: 1.5;
+ margin: 0 0 20px;
+}
+
+.wp-posts-content pre code,
+.entry-content pre code,
+.prose pre code {
+ color: inherit;
+ background: none;
+ padding: 0;
+ font-size: inherit;
+}
+
+/* ===== 表格 — 对齐 zibll line 8897 ===== */
+.wp-posts-content table,
+.entry-content table,
+.prose table {
+ font-size: 14px;
+ width: 100%;
+ border-collapse: collapse;
+ margin: 0 0 20px;
+}
+
+.wp-posts-content th,
+.wp-posts-content td,
+.entry-content th,
+.entry-content td,
+.prose th,
+.prose td {
+ border: 1px solid var(--main-border-color, rgba(50, 50, 50, 0.06));
+ padding: 8px;
+}
+
+.wp-posts-content th,
+.entry-content th,
+.prose th {
+ background: var(--muted-border-color, rgba(0, 0, 0, 0.03));
+ font-weight: 700;
+}
+
+.wp-posts-content tr:hover,
+.entry-content tr:hover,
+.prose tr:hover {
+ background-color: rgba(240, 68, 148, 0.05);
+}
+
+/* ===== 列表 — 对齐 zibll line 8977 ===== */
+.wp-posts-content ul,
+.wp-posts-content ol,
+.entry-content ul,
+.entry-content ol,
+.prose ul,
+.prose ol {
+ margin: 10px 0 20px 15px;
+ padding-left: 15px;
+}
+
+.wp-posts-content li,
+.entry-content li,
+.prose li {
+ margin-bottom: 10px;
+}
+
+/* ===== 引用 — 对齐 zibll line 680 ===== */
+.wp-posts-content blockquote,
+.entry-content blockquote,
+.prose blockquote {
+ padding: 15px 20px;
+ margin: 0 0 20px;
+ border-left: 4px solid var(--main-border-color, rgba(50, 50, 50, 0.06));
+ background: var(--muted-border-color, rgba(0, 0, 0, 0.03));
+ font-size: 16px;
+ color: var(--muted-color, #777);
+ border-radius: 0;
+}
+
+.wp-posts-content blockquote p:last-child,
+.entry-content blockquote p:last-child,
+.prose blockquote p:last-child {
+ margin-bottom: 0;
+}
+
+/* ===== 水平分割线 — 对齐 zibll line 676 ===== */
+hr {
+ border-color: var(--main-border-color, rgba(50, 50, 50, 0.06));
+}
+
+/* ===== Strong / Bold ===== */
+strong, b {
+ font-weight: 700;
+}
+/**
+ * AKSRT Buttons — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll .but 系统:
+ * - 正常字重 (normal)
+ * - 4px 圆角
+ * - 灰色默认背景
+ * - opacity hover
+ */
+
+.btn,
+.btn-primary,
+.btn-outline,
+.btn-ghost,
+.btn-danger {
+ --btn-h: 34px;
+ --btn-px: 12px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ height: var(--btn-h);
+ padding: 0 var(--btn-px);
+ font-size: var(--text-sm);
+ font-weight: normal;
+ line-height: 1.44;
+ border: 1px solid transparent;
+ border-radius: var(--radius-btn);
+ cursor: pointer;
+ white-space: nowrap;
+ user-select: none;
+ text-decoration: none;
+ transition: opacity var(--dur-fast) var(--ease),
+ background var(--dur-fast) var(--ease),
+ border-color var(--dur-fast) var(--ease),
+ color var(--dur-fast) var(--ease);
+}
+
+/* 尺寸变体 */
+.btn-sm { --btn-h: 28px; --btn-px: 8px; font-size: var(--text-xs); }
+.btn-lg { --btn-h: 44px; --btn-px: 18px; font-size: var(--text-base); }
+
+/* === Default (gray background, like zibll .but default) === */
+.btn {
+ background: rgba(136, 136, 136, 0.1);
+ color: #888;
+}
+
+.btn:hover {
+ opacity: 0.8;
+}
+
+/* === Primary === */
+.btn-primary {
+ background: var(--color-primary);
+ color: var(--color-on-primary);
+ border-color: var(--color-primary);
+}
+
+.btn-primary:hover {
+ opacity: 0.85;
+ color: var(--color-on-primary);
+}
+
+.btn-primary:active {
+ opacity: 1;
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15);
+}
+
+/* === Outline === */
+.btn-outline {
+ background: transparent;
+ color: var(--color-ink-2);
+ border-color: var(--color-line);
+}
+
+.btn-outline:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+ opacity: 1;
+}
+
+/* === Ghost === */
+.btn-ghost {
+ background: transparent;
+ color: var(--color-ink-2);
+ border-color: transparent;
+}
+
+.btn-ghost:hover {
+ background: rgba(136, 136, 136, 0.1);
+ opacity: 1;
+}
+
+/* === Danger === */
+.btn-danger {
+ background: var(--color-error);
+ color: #fff;
+ border-color: var(--color-error);
+}
+
+.btn-danger:hover {
+ opacity: 0.85;
+ color: #fff;
+}
+
+/* === Disabled === */
+.btn:disabled,
+.btn-primary:disabled,
+.btn-outline:disabled,
+.btn-ghost:disabled,
+.btn-danger:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ pointer-events: none;
+}
+
+/* === Icon button === */
+.btn-icon {
+ width: var(--btn-h);
+ padding: 0;
+ justify-content: center;
+}
+
+.btn-icon.btn-sm { width: 28px; }
+.btn-icon.btn-lg { width: 44px; }
+
+/* === Full width === */
+.btn-block {
+ width: 100%;
+}
+/**
+ * AKSRT Forms — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll .form-control:
+ * - 灰色背景 (#f5f6f7)
+ * - 透明边框
+ * - 34px 高度
+ * - 8px 圆角
+ * - focus 时粉色边框 + 光晕
+ */
+
+/* ===== Field Wrapper ===== */
+.field {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ margin-bottom: var(--space-4);
+}
+
+.field-label {
+ font-size: var(--text-sm);
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.field-help {
+ font-size: var(--text-xs);
+ color: var(--color-ink-3);
+}
+
+.field-error {
+ font-size: var(--text-xs);
+ color: var(--color-error);
+}
+
+/* ===== Input / Textarea / Select — 对齐 zibll .form-control ===== */
+.input,
+.textarea,
+.select,
+input[type="text"].form-input,
+input[type="email"].form-input,
+input[type="password"].form-input,
+input[type="search"].form-input,
+input[type="url"].form-input,
+input[type="tel"].form-input,
+textarea.form-textarea,
+select.form-select {
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ color: var(--color-ink);
+ background: var(--surface-page);
+ border: 1px solid transparent;
+ border-radius: var(--radius);
+ transition: border-color var(--dur-fast) var(--ease),
+ box-shadow var(--dur-fast) var(--ease);
+}
+
+.textarea,
+textarea.form-textarea {
+ height: auto;
+ min-height: 120px;
+ padding: 12px;
+ line-height: var(--leading-snug);
+ resize: vertical;
+}
+
+.input:hover,
+.textarea:hover,
+.select:hover {
+ border-color: var(--color-primary);
+}
+
+.input:focus,
+.textarea:focus,
+.select:focus {
+ outline: none;
+ border-color: var(--color-primary);
+ box-shadow: 0 0 2px 3px rgba(253, 83, 161, 0.4);
+}
+
+.input::placeholder,
+.textarea::placeholder {
+ color: var(--color-ink-4);
+}
+
+/* ===== Select ===== */
+.select,
+select.form-select {
+ appearance: none;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23777' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: right 12px center;
+ padding-right: 32px;
+}
+
+/* ===== Checkbox / Radio ===== */
+.checkbox,
+.radio {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ cursor: pointer;
+ font-size: var(--text-sm);
+ color: var(--color-ink-2);
+}
+
+.checkbox input,
+.radio input {
+ width: 16px;
+ height: 16px;
+ accent-color: var(--color-primary);
+ cursor: pointer;
+}
+
+/* ===== Input Group ===== */
+.input-group {
+ display: flex;
+ align-items: stretch;
+}
+
+.input-group .input {
+ border-radius: var(--radius) 0 0 var(--radius);
+}
+
+.input-group .btn {
+ border-radius: 0 var(--radius) var(--radius) 0;
+}
+
+/* ===== Form Layout ===== */
+.form-row {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: var(--space-4);
+}
+
+.form-actions {
+ display: flex;
+ gap: var(--space-3);
+ margin-top: var(--space-5);
+}
+/**
+ * AKSRT Alerts
+ * 统一提示组件:error / warning / info / success
+ * 用于替代各页面 inline 的 .login-error / .bind-error 等
+ */
+
+.alert {
+ display: flex;
+ align-items: flex-start;
+ gap: 10px;
+ padding: 12px 14px;
+ margin-bottom: var(--space-4);
+ font-size: var(--text-sm);
+ line-height: var(--leading-snug);
+ border-radius: var(--radius);
+ border: 1px solid transparent;
+}
+
+.alert > svg {
+ flex-shrink: 0;
+ width: 18px;
+ height: 18px;
+ margin-top: 1px;
+}
+
+.alert--error {
+ color: #B91C1C;
+ background: rgba(239, 68, 68, 0.08);
+ border-color: rgba(239, 68, 68, 0.3);
+}
+
+.alert--warning {
+ color: #B45309;
+ background: rgba(245, 158, 11, 0.08);
+ border-color: rgba(245, 158, 11, 0.3);
+}
+
+.alert--success {
+ color: #047857;
+ background: rgba(16, 185, 129, 0.08);
+ border-color: rgba(16, 185, 129, 0.3);
+}
+
+.alert--info {
+ color: #1D4ED8;
+ background: rgba(59, 130, 246, 0.08);
+ border-color: rgba(59, 130, 246, 0.3);
+}
+
+html.dark .alert--error { color: #FCA5A5; }
+html.dark .alert--warning { color: #FCD34D; }
+html.dark .alert--success { color: #6EE7B7; }
+html.dark .alert--info { color: #93C5FD; }
diff --git a/assets/css/build/frontend-base.min.css.disabled b/assets/css/build/frontend-base.min.css.disabled
new file mode 100644
index 00000000..0c121953
--- /dev/null
+++ b/assets/css/build/frontend-base.min.css.disabled
@@ -0,0 +1,5701 @@
+/**
+ * AKSRT Main v5 — 博客/个人站完整前端
+ */
+
+/* 防止 hero 等使用 100vw / full-bleed 时产生横向滚动条 */
+html,
+body {
+ overflow-x: clip;
+}
+
+@supports not (overflow-x: clip) {
+ html,
+ body {
+ overflow-x: hidden;
+ }
+}
+
+/* ========== 阅读进度条(单篇文章顶 fixed)========== */
+.reading-progress-bar {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 3px;
+ width: 0%;
+ z-index: 9999;
+ pointer-events: none;
+ background: linear-gradient(90deg, var(--color-primary), var(--color-primary-light));
+ transition: width 0.1s ease-out;
+}
+
+/* 折叠 body 内注入的 BOM / 空白文本节点,防止产生多余行高间距 */
+body {
+ font-size: 0;
+ line-height: 0;
+}
+
+/* ========== 站点外壳 ========== */
+.site-wrapper {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ font-size: var(--text-base);
+ line-height: var(--leading-normal);
+}
+
+.site-main {
+ flex: 1;
+}
+
+.container {
+ width: 100%;
+ max-width: var(--container);
+ margin: 0 auto;
+ padding: 0 16px;
+}
+
+@media (min-width: 768px) {
+ .container {
+ padding: 0 24px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .container {
+ padding: 0 32px;
+ }
+}
+
+/* ========== 通用空状态 ========== */
+.no-results {
+ padding: 48px 20px;
+ text-align: center;
+ color: var(--color-ink-3);
+}/**
+ * Zibll Variable Compatibility Layer — Global Bridge
+ *
+ * Maps Zibll CSS variable names to AKSRT design tokens.
+ * This file allows existing Zibll-style markup and third-party components
+ * that reference Zibll variables to work correctly in AKSRT.
+ *
+ * @package AKSRT
+ */
+
+/* ============================================================
+ * Global bridge (all pages)
+ * Maps Zibll variables → AKSRT tokens so any Zibll-style markup works.
+ * ============================================================ */
+:root {
+ /* Layout (zibll typo preserved for compat) */
+ --mian-max-width: var(--container, 1200px);
+
+ /* Theme color — now matches zibll #f04494 */
+ --theme-color: var(--color-primary, #f04494);
+ --focus-color: var(--color-primary, #f04494);
+ --focus-shadow-color: var(--color-primary-soft, rgba(253, 83, 161, 0.4));
+
+ /* Text hierarchy */
+ --key-color: var(--color-ink);
+ --main-color: var(--color-ink-2);
+ --muted-color: var(--color-ink-3);
+ --muted-2-color: var(--color-ink-4);
+ --muted-3-color: #b1b1b1;
+ --muted-4-color: #d2d2d2;
+
+ /* Surfaces & borders */
+ --body-bg-color: var(--surface-page);
+ --main-bg-color: var(--surface-1);
+ --muted-bg-color: var(--surface-2);
+ --main-border-color: var(--color-line);
+ --muted-border-color: var(--color-line-soft);
+ --main-shadow: rgba(116, 116, 116, 0.08);
+ --main-radius: var(--radius, 8px);
+
+ /* Radius variants */
+ --mini-radius: calc(var(--main-radius) / 1.4);
+
+ /* Blur / glass */
+ --blur-bg: rgba(255, 255, 255, 0.8);
+ --float-btn-bg: rgba(200, 200, 200, 0.4);
+
+ /* Header / footer composites */
+ --header-bg: var(--blur-bg);
+ --header-color: var(--color-ink-2);
+ --footer-bg: var(--surface-1);
+ --footer-color: var(--color-ink-4);
+
+ /* Cards — 对齐 zibll 70% */
+ --posts-card-scale: 70%;
+ --posts-list-scale: 70%;
+ --single-cover-scale: 35%;
+}
+
+/* ============================================================
+ * Dark mode bridge — 对齐 zibll dark theme
+ * ============================================================ */
+html.dark {
+ --theme-color: var(--color-primary);
+ --focus-color: var(--color-primary);
+ --focus-shadow-color: rgba(253, 83, 161, 0.25);
+ --key-color: var(--color-ink);
+ --main-color: var(--color-ink-2);
+ --muted-color: var(--color-ink-3);
+ --muted-2-color: var(--color-ink-4);
+ --muted-3-color: #666;
+ --muted-4-color: #555;
+ --body-bg-color: var(--surface-page);
+ --main-bg-color: var(--surface-1);
+ --muted-bg-color: var(--surface-2);
+ --main-border-color: var(--color-line);
+ --muted-border-color: var(--color-line-soft);
+ --main-shadow: rgba(24, 24, 24, 0.1);
+ --blur-bg: rgba(50, 51, 53, 0.8);
+ --float-btn-bg: rgba(70, 70, 70, 0.4);
+ --header-color: var(--color-ink-2);
+ --footer-color: var(--color-ink-4);
+}
+/**
+ * AKSRT Card Primitives — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll 的 .theme-box / .box-bg / .box-body / .box-header:
+ * 阴影优先,无边框,8px 圆角,15px 内边距。
+ *
+ * @package AKSRT
+ */
+
+/* ============================================================
+ * .aksrt-theme-box — 完整卡片原语(阴影 + 圆角 + 表面)
+ * 对齐 zibll .theme-box + .box-bg
+ * ============================================================ */
+.aksrt-theme-box {
+ border: none;
+ border-radius: var(--radius);
+ background: var(--surface-1);
+ box-shadow: var(--shadow-sm);
+ transition: box-shadow var(--dur) var(--ease);
+}
+
+.aksrt-theme-box:hover {
+ box-shadow: var(--shadow);
+}
+
+/* ============================================================
+ * .aksrt-box-bg — 表面原语(仅背景 + 阴影)
+ * ============================================================ */
+.aksrt-box-bg {
+ background-color: var(--surface-1);
+ box-shadow: var(--shadow-sm);
+}
+
+/* ============================================================
+ * .aksrt-box-body / .aksrt-box-header — 内边距区段
+ * 对齐 zibll .box-body / .box-header { padding: 15px }
+ * ============================================================ */
+.aksrt-box-body,
+.aksrt-box-header {
+ padding: var(--card-padding);
+}
+
+.aksrt-box-header {
+ border-bottom: 1px solid var(--color-line-soft);
+}
+
+.aksrt-box-header + .aksrt-box-body {
+ padding-top: 0;
+}
+
+.aksrt-box-body.notop,
+.aksrt-box-header.notop { padding-top: 0; }
+.aksrt-box-body.nobottom,
+.aksrt-box-header.nobottom { padding-bottom: 0; }
+
+/* ============================================================
+ * .aksrt-muted-box — 柔和背景嵌套
+ * 对齐 zibll .muted-box
+ * ============================================================ */
+.aksrt-muted-box {
+ background-color: var(--surface-2);
+ border-radius: var(--radius);
+ padding: var(--card-padding);
+}
+
+/* ============================================================
+ * .aksrt-noshadow — 去除阴影
+ * ============================================================ */
+.aksrt-noshadow {
+ box-shadow: none !important;
+}
+
+/* ============================================================
+ * Zibll 兼容别名
+ * ============================================================ */
+.theme-box {
+ background: var(--surface-1);
+ border: none;
+ border-radius: var(--radius);
+ box-shadow: var(--shadow-sm);
+ margin-bottom: 20px;
+ transition: box-shadow var(--dur) var(--ease);
+}
+
+.theme-box:hover {
+ box-shadow: var(--shadow);
+}
+
+.box-bg {
+ background-color: var(--surface-1);
+ box-shadow: var(--shadow-sm);
+}
+
+.box-body {
+ padding: var(--card-padding);
+}
+
+.box-header {
+ padding: var(--card-padding);
+ border-bottom: 1px solid var(--color-line-soft);
+}
+
+.box-header + .box-body {
+ padding-top: 0;
+}
+
+.radius8 {
+ border-radius: var(--radius);
+}
+
+.main-shadow {
+ box-shadow: var(--shadow);
+}
+
+.muted-box {
+ background-color: var(--surface-2);
+ border-radius: var(--radius);
+ padding: var(--card-padding);
+}
+
+/* ============================================================
+ * 暗色模式
+ * ============================================================ */
+html.dark .aksrt-theme-box,
+html.dark .theme-box,
+html.dark .box-bg {
+ box-shadow: var(--shadow-sm);
+}
+
+html.dark .aksrt-theme-box:hover,
+html.dark .theme-box:hover {
+ box-shadow: var(--shadow);
+}
+
+/* ============================================================
+ * 卡片 hover 动效
+ * ============================================================ */
+.aksrt-theme-box,
+.theme-box {
+ transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
+}
+
+.aksrt-card-hover:hover,
+.aksrt-card-hover:focus-within {
+ box-shadow: var(--shadow);
+ transform: translateY(-2px);
+}
+
+.aksrt-card-hover-lg:hover,
+.aksrt-card-hover-lg:focus-within {
+ box-shadow: var(--shadow-lg);
+ transform: translateY(-4px);
+}
+
+.aksrt-noshadow:hover {
+ box-shadow: none !important;
+ transform: none !important;
+}
+/**
+ * AKSRT Overlay / Glass Primitives
+ *
+ * Provides backdrop-filter glass surfaces used by header, footer-tabbar,
+ * floating buttons and search overlays — matching zibll's blur system.
+ *
+ * @package AKSRT
+ */
+
+/* ============================================================
+ * .aksrt-blur-bg — generic glass surface
+ * Use on any element that needs a translucent blurred background.
+ * ============================================================ */
+.aksrt-blur-bg {
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+ background: var(--blur-bg);
+}
+
+/* ============================================================
+ * Glass on site-nav (when using fixed/sticky mode)
+ * Applied via .site-nav--blur already; this adds the zibll-grade
+ * saturate(5) blur(20px) instead of the lighter saturate(1.5) blur(18px).
+ * ============================================================ */
+.site-nav--glass {
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+ background: var(--blur-bg);
+ border-bottom-color: transparent;
+}
+
+.site-nav--glass.is-scrolled {
+ box-shadow: 0 4px 10px rgba(20, 28, 48, 0.06);
+ border-bottom-color: var(--color-line-soft);
+}
+
+html.dark .site-nav--glass.is-scrolled,
+html.dark .site-nav--glass.is-scrolled {
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
+}
+
+/* ============================================================
+ * Glass on footer-tabbar (already uses backdrop-filter in footer.css;
+ * this class can be toggled to match zibll's exact blur spec)
+ * ============================================================ */
+.footer-tabbar--glass {
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+ background: var(--blur-bg);
+ box-shadow: 0 -4px 5px rgba(20, 28, 48, 0.06);
+}
+
+html.dark .footer-tabbar--glass,
+html.dark .footer-tabbar--glass {
+ box-shadow: 0 -4px 5px rgba(0, 0, 0, 0.25);
+}
+
+/* ============================================================
+ * Glass on floating buttons (lighter blur: saturate(2) blur(10px))
+ * ============================================================ */
+.float-right--glass .float-btn {
+ -webkit-backdrop-filter: saturate(2) blur(10px);
+ backdrop-filter: saturate(2) blur(10px);
+ background: var(--float-btn-bg);
+ border-color: transparent;
+}
+
+/* ============================================================
+ * Scroll shadow on glass header (zibll: .body-scroll .header)
+ * ============================================================ */
+body.has-scrolled .site-nav--glass {
+ box-shadow: 0 4px 10px rgba(20, 28, 48, 0.06);
+}
+
+html.dark body.has-scrolled .site-nav--glass,
+html.dark body.has-scrolled .site-nav--glass {
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
+}
+/* ============================================================
+ * AKSRT Navigation — Editorial v3.4
+ *
+ * - 高度 60px (--nav-h)
+ * - 字体使用 --font-ui (Inter / 思源黑体)
+ * - 主色蓝调,hover 改为 primary-soft 浅底
+ * - 永远实心:白底深字 + 1px 分隔线,滚动后追加 box-shadow
+ * - 移动端:≤768 显示汉堡菜单
+ * ============================================================ */
+
+.site-nav {
+ position: sticky;
+ top: 0;
+ z-index: 1000;
+ min-height: var(--nav-height, 60px);
+ border-bottom: 1px solid var(--color-line);
+ background-color: var(--blur-bg);
+ backdrop-filter: saturate(5) blur(20px);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ transition: background-color 0.25s ease,
+ border-color 0.25s ease,
+ color 0.25s ease,
+ box-shadow 0.25s ease;
+}
+
+.site-nav--static {
+ position: relative;
+}
+
+.site-nav--transparent {
+ background: var(--blur-bg);
+ border-bottom-color: var(--color-line-soft);
+}
+
+.site-nav--transparent.is-scrolled {
+ background: var(--blur-bg);
+}
+
+.site-nav--blur {
+ background: var(--blur-bg);
+ backdrop-filter: saturate(5) blur(20px);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ border-bottom-color: transparent;
+}
+
+html.dark .site-nav--transparent,
+html.dark .site-nav--blur,
+html.dark .site-nav--transparent,
+html.dark .site-nav--blur {
+ background: var(--blur-bg);
+ border-bottom-color: var(--color-line-soft);
+}
+
+/* 滚动后追加轻阴影作为状态反馈(颜色不变) */
+.site-nav.is-scrolled {
+ box-shadow: var(--shadow-sm, 0 1px 6px rgba(0, 0, 0, 0.06));
+}
+
+/* WordPress Admin Bar 已全局禁用,无需偏移规则 */
+
+/* ============================================================
+ * Inner / Row layout
+ * ============================================================ */
+.site-nav__inner {
+ max-width: var(--nav-max-width, var(--container));
+ margin: 0 auto;
+ padding: 0 15px;
+ display: flex;
+ flex-direction: column;
+ gap: 0;
+}
+
+.site-nav__row {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 12px;
+ width: 100%;
+ min-height: var(--nav-height, 60px);
+}
+
+/* ============================================================
+ * Brand
+ * ============================================================ */
+.site-brand {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ min-width: 0;
+ max-width: min(48vw, 360px);
+ padding: 7px 10px;
+ color: var(--color-ink);
+ font-size: 1.0625rem;
+ font-weight: 700;
+ letter-spacing: -0.01em;
+ flex-shrink: 0;
+ text-decoration: none;
+}
+
+.site-brand:hover {
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.site-brand--has-logo {
+ gap: 0;
+}
+
+.site-brand__logo {
+ width: 36px;
+ height: 36px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 800;
+ font-size: 13px;
+ color: var(--color-on-primary, #fff);
+ background: linear-gradient(135deg, var(--color-primary), var(--color-primary-active, var(--color-primary-dark)));
+ letter-spacing: 0.02em;
+ overflow: hidden;
+}
+
+.site-brand__media {
+ display: block;
+ flex: 0 1 auto;
+ max-width: 100%;
+ padding: 0 30px;
+ line-height: 0;
+ box-sizing: border-box;
+ background: transparent !important;
+ border: 0;
+ border-radius: 0;
+ box-shadow: none;
+ filter: none !important;
+ opacity: 1;
+}
+
+.site-brand__img {
+ display: block;
+ height: 36px;
+ width: auto;
+ max-width: 100%;
+ object-fit: contain;
+ object-position: left center;
+ background: transparent !important;
+ border-radius: 0;
+ box-shadow: none;
+ filter: none !important;
+ mix-blend-mode: normal !important;
+ opacity: 1;
+ transform: none !important;
+}
+
+.site-brand__name {
+ font-weight: 700;
+ letter-spacing: -0.01em;
+ white-space: nowrap;
+}
+
+/* ============================================================
+ * Desktop menu
+ * ============================================================ */
+ul.nav-desktop {
+ display: none;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ align-items: center;
+ flex: 1 1 auto;
+ min-width: 0;
+}
+
+.nav-desktop--fallback {
+ display: none;
+ align-items: center;
+ flex: 1 1 auto;
+ min-width: 0;
+}
+
+ul.nav-desktop a,
+.nav-desktop--fallback a {
+ color: var(--color-ink-3);
+ font-size: 15px;
+ font-weight: 500;
+ padding: 8px 10px;
+ border-radius: 4px;
+ transition: color var(--dur-fast, 0.15s) var(--ease),
+ background var(--dur-fast, 0.15s) var(--ease);
+}
+
+/* Hover — 对齐 zibll: 仅变色,无背景 */
+ul.nav-desktop a:hover,
+.nav-desktop--fallback a:hover {
+ color: var(--color-primary);
+ background: transparent;
+}
+
+/* Active page — 对齐 zibll: 顶部彩色条指示器 */
+ul.nav-desktop .current-menu-item > a,
+ul.nav-desktop .current_page_item > a {
+ color: var(--color-primary);
+ background: transparent;
+ position: relative;
+}
+
+ul.nav-desktop .current-menu-item > a::before,
+ul.nav-desktop .current_page_item > a::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 3px;
+ background: var(--color-primary);
+ border-radius: 0 0 2px 2px;
+}
+
+/* ============================================================
+ * Desktop submenu (dropdown)
+ * ============================================================ */
+ul.nav-desktop .menu-item {
+ position: relative;
+}
+
+ul.nav-desktop .sub-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 998;
+ min-width: 200px;
+ list-style: none;
+ margin: 4px 0 0;
+ padding: 8px;
+ background: var(--main-bg-color, #fff);
+ border: 1px solid var(--main-border-color, rgba(50, 50, 50, 0.06));
+ border-radius: var(--main-radius, 8px);
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(6px);
+ transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
+}
+
+ul.nav-desktop .menu-item:hover > .sub-menu {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+ul.nav-desktop .sub-menu .menu-item > a {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 15px;
+ font-size: 14px;
+ border-radius: 4px;
+ white-space: nowrap;
+}
+
+ul.nav-desktop .sub-menu .menu-item > a:hover {
+ background: var(--color-primary-soft, rgba(24, 144, 255, 0.08));
+ color: var(--color-primary);
+}
+
+/* Nested submenus fly out to the right */
+ul.nav-desktop .sub-menu .sub-menu {
+ top: -6px;
+ left: 100%;
+ margin: 0 0 0 4px;
+}
+
+/* Dark mode submenu */
+html.dark ul.nav-desktop .sub-menu,
+html.dark ul.nav-desktop .sub-menu {
+ background: var(--surface-page);
+ border-color: var(--color-line, #2d2d3f);
+}
+
+/* ============================================================
+ * Mega Menu (图文超级菜单)
+ * ============================================================ */
+
+/* Mega Menu 容器:全宽定位 */
+ul.nav-desktop .mega-menu-item {
+ position: static;
+}
+
+ul.nav-desktop .mega-menu-item > .mega-menu__panel {
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 100%;
+ max-width: var(--container);
+ min-width: auto;
+ padding: 16px;
+ margin-top: 4px;
+}
+
+/* 列布局 */
+.mega-menu__columns-2 {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 8px;
+}
+
+.mega-menu__columns-3 {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 8px;
+}
+
+.mega-menu__columns-4 {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 8px;
+}
+
+.mega-menu__columns-5 {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 8px;
+}
+
+/* Mega Menu 子项(卡片样式) */
+.mega-menu__panel > .menu-item {
+ border-radius: 8px;
+ transition: background 0.15s;
+}
+
+.mega-menu__panel > .menu-item:hover {
+ background: var(--surface-2, #F4F5F7);
+}
+
+.mega-menu__panel > .menu-item > a {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 12px;
+ font-size: 14px;
+ border-radius: 8px;
+ white-space: normal;
+ line-height: 1.4;
+}
+
+.mega-menu__panel > .menu-item > a i {
+ width: 20px;
+ text-align: center;
+ color: var(--color-primary, var(--color-primary));
+ flex-shrink: 0;
+}
+
+/* 描述文字 */
+.mega-menu__item-desc {
+ display: block;
+ font-size: 12px;
+ color: var(--color-ink-4, #8A8F98);
+ margin-top: 2px;
+ line-height: 1.3;
+}
+
+/* Mega Menu 标题分组 */
+.mega-menu__panel .mega-menu__group-title {
+ grid-column: 1 / -1;
+ padding: 8px 12px 4px;
+ font-size: 12px;
+ font-weight: 600;
+ color: var(--color-ink-3);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+/* Mega Menu 底部区域(可放图片/CTA) */
+.mega-menu__panel .mega-menu__footer {
+ grid-column: 1 / -1;
+ padding: 12px 0 0;
+ margin-top: 8px;
+ border-top: 1px solid var(--color-line);
+}
+
+/* Dark mode Mega Menu */
+html.dark ul.nav-desktop .mega-menu-item > .mega-menu__panel,
+html.dark ul.nav-desktop .mega-menu-item > .mega-menu__panel {
+ background: var(--surface-page);
+ border-color: var(--color-line, #2d2d3f);
+}
+
+html.dark .mega-menu__panel > .menu-item:hover,
+html.dark .mega-menu__panel > .menu-item:hover {
+ background: var(--surface-2);
+}
+
+/* Responsive Mega Menu */
+@media (max-width: 767px) {
+ ul.nav-desktop .mega-menu-item > .mega-menu__panel {
+ position: static;
+ transform: none;
+ width: 100%;
+ max-width: none;
+ }
+
+ .mega-menu__columns-2,
+ .mega-menu__columns-3,
+ .mega-menu__columns-4,
+ .mega-menu__columns-5 {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* ============================================================
+ * Right actions (icons + auth)
+ * ============================================================ */
+.nav-actions {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ flex-shrink: 0;
+ margin-left: auto;
+}
+
+.nav-settings-link,
+.nav-publish-btn {
+ flex-shrink: 0;
+}
+
+.nav-settings-link svg {
+ width: 18px;
+ height: 18px;
+}
+
+.nav-publish-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ height: 36px;
+ padding: 0 14px;
+ font-size: 0.875rem;
+ font-weight: 600;
+}
+
+.nav-publish-btn i {
+ font-size: 0.8125rem;
+}
+
+.theme-toggle.is-animating svg {
+ transform: rotate(360deg);
+}
+
+/* ============================================================
+ * Auth buttons (in nav, when logged out)
+ * ============================================================ */
+.nav-auth {
+ display: none;
+ align-items: center;
+ gap: 8px;
+}
+
+/* btn-outline / btn-primary 复用 core/buttons.css 的定义,
+ * 这里仅做导航专用调整(高度对齐、字体) */
+.nav-auth .btn-outline,
+.nav-auth .btn-primary {
+ height: 36px;
+ font-size: 0.875rem;
+ padding: 0 16px;
+}
+
+/* Mobile toggle */
+.nav-toggle {
+ display: flex;
+}
+
+@media (max-width: 991px) {
+ .site-brand {
+ max-width: min(46vw, 300px);
+ }
+
+ .site-brand__media {
+ padding: 0 8px;
+ }
+
+ .nav-publish-btn {
+ display: none;
+ }
+}
+
+/* Desktop search icon: hide on mobile (use drawer search instead) */
+@media (max-width: 767px) {
+ .site-brand {
+ max-width: min(62vw, 260px);
+ padding: 7px 0;
+ }
+
+ .site-brand__media {
+ padding: 0;
+ }
+
+ #search-toggle {
+ display: none;
+ }
+ /* Search panel only makes sense alongside the desktop search icon */
+ .nav-search-panel {
+ display: none !important;
+ }
+}
+
+@media (min-width: 768px) {
+ ul.nav-desktop,
+ .nav-desktop--fallback {
+ display: flex;
+ }
+
+ .nav-auth {
+ display: flex;
+ }
+
+ .nav-toggle {
+ display: none;
+ }
+}
+
+.nav-mobile-strip {
+ display: none;
+ width: calc(100% + 8px);
+ margin: 0 -4px;
+ padding: 0 0 12px;
+}
+
+.nav-mobile-strip__menu,
+.nav-mobile-strip__menu ul {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ overflow-x: auto;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+}
+
+.nav-mobile-strip__menu::-webkit-scrollbar,
+.nav-mobile-strip__menu ul::-webkit-scrollbar {
+ display: none;
+}
+
+.nav-mobile-strip__menu a {
+ display: inline-flex;
+ align-items: center;
+ min-height: 34px;
+ padding: 0 12px;
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-2);
+ color: var(--color-ink-2);
+ white-space: nowrap;
+ text-decoration: none;
+ font-size: 0.875rem;
+ font-weight: 500;
+}
+
+.nav-mobile-strip__menu .current-menu-item > a,
+.nav-mobile-strip__menu .current_page_item > a {
+ background: var(--color-primary);
+ color: var(--color-on-primary, #fff);
+}
+
+@media (max-width: 767px) {
+ .nav-mobile-strip {
+ display: block;
+ }
+}
+
+/* ============================================================
+ * User avatar + dropdown
+ * ============================================================ */
+.nav-user {
+ position: relative;
+}
+
+.nav-user__toggle {
+ width: 40px;
+ height: 40px;
+ border-radius: var(--radius-avatar);
+ padding: 0;
+ border: 2px solid var(--color-line);
+ cursor: pointer;
+ overflow: hidden;
+ background: var(--surface-2);
+ transition: border-color var(--dur-fast, 0.15s) var(--ease);
+}
+
+.nav-user__toggle:hover {
+ border-color: var(--color-primary);
+}
+
+.nav-user__toggle img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+}
+
+.user-dropdown {
+ position: absolute;
+ top: calc(100% + 8px);
+ right: 0;
+ width: 260px;
+ max-width: calc(100vw - 32px);
+ padding: 12px 0;
+ background: var(--surface-1);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-lg, 8px);
+ box-shadow: var(--shadow-lg);
+ z-index: 1100;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(-6px);
+ transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
+}
+
+.user-dropdown.is-open {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.user-dropdown__profile {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 16px 14px;
+}
+
+.user-dropdown__profile img {
+ width: 44px;
+ height: 44px;
+ border-radius: var(--radius-avatar);
+ object-fit: cover;
+ flex-shrink: 0;
+}
+
+.user-dropdown__name {
+ font-weight: 700;
+ font-size: 0.9375rem;
+ color: var(--color-ink);
+}
+
+.user-dropdown__email {
+ font-size: 0.75rem;
+ color: var(--color-ink-4);
+ word-break: break-all;
+ margin-top: 2px;
+}
+
+.user-dropdown__sep {
+ height: 1px;
+ background: var(--color-line);
+ margin: 6px 0;
+}
+
+.user-dropdown a,
+.user-dropdown button {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ width: 100%;
+ padding: 0 16px;
+ height: 44px;
+ border: none;
+ background: none;
+ font-size: 0.875rem;
+ color: var(--color-ink);
+ text-align: left;
+ cursor: pointer;
+ transition: background var(--dur-fast, 0.15s) var(--ease),
+ color var(--dur-fast, 0.15s) var(--ease);
+}
+
+.user-dropdown a:hover,
+.user-dropdown button:hover {
+ background: var(--surface-3);
+ color: var(--color-primary-active);
+}
+
+/* dropdown 项内的 SVG 图标 */
+.user-dropdown__item svg {
+ width: 16px;
+ height: 16px;
+ flex-shrink: 0;
+ opacity: 0.85;
+}
+
+.user-dropdown__item span:first-of-type:not(.user-dropdown__pill) {
+ flex: 1;
+ min-width: 0;
+}
+
+/* 未读消息数 badge */
+.user-dropdown__badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 18px;
+ height: 18px;
+ padding: 0 5px;
+ margin-left: auto;
+ font-size: 11px;
+ font-weight: 600;
+ color: #fff;
+ background: var(--color-error, #ef4444);
+ border-radius: 9px;
+ line-height: 1;
+}
+
+.user-dropdown__credits {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 0 16px;
+ height: 44px;
+ font-size: 0.875rem;
+ color: var(--color-ink-2);
+}
+
+.user-dropdown__credits i {
+ color: var(--color-warning);
+ flex-shrink: 0;
+}
+
+.user-dropdown__credits-label {
+ flex: 1;
+}
+
+.user-dropdown__credits-value {
+ font-weight: 600;
+ color: var(--color-primary);
+}
+
+.user-dropdown__logout {
+ color: var(--color-error) !important;
+}
+
+.user-dropdown__logout svg {
+ color: var(--color-error);
+}
+
+.user-dropdown__logout:hover {
+ background: rgba(239, 68, 68, 0.08) !important;
+ color: var(--color-error) !important;
+}
+
+.user-dropdown .badge-dot {
+ margin-left: auto;
+ min-width: 8px;
+ height: 8px;
+ border-radius: var(--radius-pill);
+ background: var(--color-error);
+}
+
+/* ============================================================
+ * Search panel
+ * ============================================================ */
+.nav-search-panel {
+ display: none;
+ padding: 12px 0 16px;
+ border-top: 1px solid var(--color-line);
+}
+
+.nav-search-panel.is-open {
+ display: block;
+}
+
+.nav-searchbox {
+ margin: 0;
+}
+
+.nav-searchbox__field {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ min-height: 42px;
+ padding: 0 6px 0 14px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-3);
+ box-sizing: border-box;
+ transition: border-color var(--dur-fast, 0.15s) var(--ease), box-shadow var(--dur-fast, 0.15s) var(--ease), background var(--dur-fast, 0.15s) var(--ease);
+}
+
+.nav-searchbox__icon {
+ order: 1;
+ flex: 0 0 16px;
+ width: 16px;
+ height: 16px;
+ color: var(--color-ink-4);
+ pointer-events: none;
+}
+
+.nav-searchbox__input {
+ order: 2;
+ flex: 1;
+ min-width: 0;
+ width: auto;
+ height: 40px;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: var(--color-ink);
+ font-size: 0.9rem;
+ line-height: 1.2;
+ box-sizing: border-box;
+}
+
+.nav-searchbox__input:focus {
+ outline: none;
+}
+
+.nav-searchbox__input::placeholder {
+ color: var(--color-ink-4);
+}
+
+.nav-searchbox__submit {
+ order: 3;
+ flex: 0 0 auto;
+ height: 30px;
+ min-width: 64px;
+ padding: 0 14px;
+ border: 0;
+ border-radius: var(--radius-pill, 999px);
+ background: var(--color-primary);
+ color: #fff;
+ font-size: 0.8125rem;
+ font-weight: 600;
+ line-height: 1;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.nav-searchbox__field:focus-within {
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 3px var(--color-primary-soft);
+ background: var(--surface-1);
+}
+
+.nav-searchbox__submit:hover {
+ background: var(--color-primary-active);
+}
+
+/* ============================================================
+ * Mobile drawer
+ * ============================================================ */
+.nav-drawer-backdrop {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.45);
+ z-index: 1200;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s ease, visibility 0.3s;
+}
+
+.nav-drawer-backdrop.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.nav-drawer {
+ position: fixed;
+ top: 0;
+ right: 0;
+ width: min(100vw, 360px);
+ height: 100vh;
+ max-height: 100dvh;
+ background: var(--surface-page);
+ z-index: 1210;
+ box-shadow: var(--shadow-drawer);
+ transform: translateX(100%);
+ transition: transform 0.32s var(--ease-out, ease);
+ display: flex;
+ flex-direction: column;
+ overflow: auto;
+ pointer-events: none;
+ visibility: hidden;
+}
+
+.nav-drawer.is-open {
+ transform: translateX(0);
+ pointer-events: auto;
+ visibility: visible;
+}
+
+.nav-drawer__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 16px;
+ padding: 16px 20px;
+ border-bottom: 1px solid var(--color-line);
+ font-weight: 700;
+ font-size: 1rem;
+}
+
+.site-brand--drawer {
+ max-width: calc(100% - 52px);
+ padding: 7px 0;
+}
+
+.site-brand--drawer .site-brand__media {
+ padding: 0;
+}
+
+.nav-drawer__search {
+ padding: 16px 20px 0;
+}
+
+.nav-drawer__search .nav-searchbox__field {
+ min-height: 40px;
+}
+
+.nav-drawer__search .nav-searchbox__input {
+ height: 38px;
+}
+
+.nav-drawer__search .nav-searchbox__submit {
+ height: 28px;
+ min-width: 58px;
+ padding: 0 12px;
+ font-size: 0.75rem;
+}
+
+.nav-drawer__menu {
+ flex: 1;
+ padding: 16px 20px 32px;
+}
+
+.nav-drawer__menu a {
+ display: block;
+ padding: 14px 0;
+ font-size: 1rem;
+ font-weight: 500;
+ color: var(--color-ink);
+ border-bottom: 1px solid var(--color-line-soft);
+}
+
+.nav-drawer__menu a:hover {
+ color: var(--color-primary-active);
+}
+
+.nav-drawer__menu ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.nav-drawer__auth {
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ border-top: 1px solid var(--color-line);
+}
+
+.nav-drawer__auth .btn-outline,
+.nav-drawer__auth .btn-primary {
+ width: 100%;
+ height: 44px;
+}
+
+.nav-drawer__publish {
+ padding: 0 20px 20px;
+}
+
+.nav-drawer__publish .btn-primary {
+ width: 100%;
+ min-height: 44px;
+ justify-content: center;
+ gap: 8px;
+}
+
+/* ============================================================
+ * Menu Decoration — Icons, Badges, Hover Effects
+ * ============================================================ */
+
+/* Menu item icon */
+.aksrt-nav__icon {
+ font-size: 0.85em;
+ width: 1.2em;
+ text-align: center;
+ margin-right: 4px;
+ opacity: 0.7;
+ transition: opacity 0.2s;
+}
+
+.aksrt-nav__item--has-icon > a {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.aksrt-nav__item--has-icon:hover .aksrt-nav__icon {
+ opacity: 1;
+}
+
+/* Menu item badge */
+.aksrt-nav__badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 10px;
+ font-weight: 600;
+ line-height: 1;
+ padding: 2px 5px;
+ border-radius: 3px;
+ margin-left: 4px;
+ white-space: nowrap;
+ vertical-align: middle;
+ transform: translateY(-1px);
+}
+
+.aksrt-nav__badge--new {
+ color: #fff;
+ background: var(--color-error);
+}
+
+.aksrt-nav__badge--hot {
+ color: #fff;
+ background: var(--color-warning);
+}
+
+.aksrt-nav__badge--info {
+ color: #fff;
+ background: var(--color-info);
+}
+
+.aksrt-nav__badge--success {
+ color: #fff;
+ background: var(--color-success);
+}
+
+.aksrt-nav__badge--vip {
+ color: #fff;
+ background: linear-gradient(135deg, var(--color-warning), var(--color-error));
+}
+
+/* Hover effects */
+.aksrt-nav__item--hover-underline > a::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ width: 0;
+ height: 2px;
+ background: var(--color-primary);
+ transition: width 0.2s ease, left 0.2s ease;
+ border-radius: 1px;
+}
+
+.aksrt-nav__item--hover-underline:hover > a::after {
+ width: 60%;
+ left: 20%;
+}
+
+.aksrt-nav__item--hover-background > a {
+ transition: background-color 0.2s;
+ border-radius: 4px;
+}
+
+.aksrt-nav__item--hover-background:hover > a {
+ background-color: var(--color-primary-soft, rgba(24, 144, 255, 0.08));
+}
+
+.aksrt-nav__item--hover-color > a {
+ transition: color 0.2s;
+}
+
+.aksrt-nav__item--hover-color:hover > a {
+ color: var(--color-primary);
+}
+
+/* Mega submenu */
+.aksrt-nav__mega {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1001;
+ background: var(--surface-1);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow-lg);
+ padding: 16px;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(8px);
+ transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
+}
+
+.aksrt-nav__item:hover > .aksrt-nav__mega {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.aksrt-nav__mega--columns {
+ display: grid;
+ gap: 16px;
+}
+
+/* Cards submenu */
+.aksrt-nav__cards {
+ display: grid;
+ gap: 12px;
+ padding: 8px;
+}
+
+.aksrt-nav__card {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 10px 12px;
+ border-radius: 6px;
+ text-decoration: none;
+ color: inherit;
+ transition: background 0.15s;
+}
+
+.aksrt-nav__card:hover {
+ background: var(--color-primary-soft, rgba(24, 144, 255, 0.06));
+}
+
+.aksrt-nav__card-icon {
+ width: 36px;
+ height: 36px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--color-primary-soft, #e6f4ff);
+ color: var(--color-primary);
+ font-size: 16px;
+ flex-shrink: 0;
+}
+
+.aksrt-nav__card-text {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-nav__card-title {
+ font-size: 13px;
+ font-weight: 600;
+ color: var(--color-ink);
+ margin: 0;
+}
+
+.aksrt-nav__card-desc {
+ font-size: 11px;
+ color: var(--color-ink-4);
+ margin: 2px 0 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+/* ============================================================
+ * 导航溢出「更多」下拉
+ * ============================================================ */
+.aksrt-nav-more {
+ position: relative;
+}
+
+.aksrt-nav-more__btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 12px;
+ border: none;
+ background: none;
+ color: var(--color-ink-2);
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ border-radius: var(--radius, 8px);
+ transition: background 0.15s, color 0.15s;
+}
+
+.aksrt-nav-more__btn:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+ color: var(--color-primary);
+}
+
+.aksrt-nav-more__dropdown {
+ display: none;
+ position: absolute;
+ top: 100%;
+ right: 0;
+ min-width: 160px;
+ padding: 6px 0;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
+ border-radius: var(--radius, 8px);
+ box-shadow: var(--shadow-lg, 0 0 10px rgba(116, 116, 116, 0.12));
+ z-index: var(--z-dropdown, 100);
+ list-style: none;
+ margin: 4px 0 0;
+}
+
+.aksrt-nav-more__dropdown.is-open {
+ display: block;
+}
+
+.aksrt-nav-more__dropdown li {
+ display: block;
+}
+
+.aksrt-nav-more__dropdown li a,
+.aksrt-nav-more__dropdown li button {
+ display: block;
+ width: 100%;
+ padding: 8px 16px;
+ border: none;
+ background: none;
+ color: var(--color-ink-2);
+ font-size: 14px;
+ text-align: left;
+ text-decoration: none;
+ cursor: pointer;
+ transition: background 0.15s, color 0.15s;
+}
+
+.aksrt-nav-more__dropdown li a:hover,
+.aksrt-nav-more__dropdown li button:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+ color: var(--color-primary);
+}
+/* ========== 面包屑 — 对齐 zibll .breadcrumb ========== */
+.breadcrumbs {
+ font-size: 13px;
+ color: var(--muted-2-color, #999);
+ margin-bottom: 12px;
+ opacity: 0.8;
+}
+
+.breadcrumbs a {
+ color: var(--muted-2-color, #999);
+}
+
+.breadcrumbs a:hover {
+ color: var(--focus-color, #f04494);
+}
+
+.breadcrumbs__sep {
+ margin: 0 0 0 6px;
+ opacity: 0.6;
+}
+
+@media (max-width: 767px) {
+ .breadcrumbs {
+ font-size: 12px;
+ }
+}
+
+/* 封面内面包屑 */
+.single-cover-con .breadcrumbs {
+ font-size: 13px;
+ margin: 5px 0 0 -6px;
+ opacity: unset;
+}
+
+/* ========== 主布局 ========== */
+.content-shell {
+ width: 100%;
+ margin: 0 auto;
+ padding: 32px 16px 48px;
+ max-width: var(--container);
+}
+
+@media (min-width: 768px) {
+ .content-shell {
+ padding: 40px 24px 56px;
+ }
+}
+
+/* page.php 专用:阅读宽度收窄 */
+.content-shell--page {
+ max-width: var(--container-page, 860px);
+}
+
+.content-shell--cms {
+ max-width: 100%;
+ padding: 0;
+}
+
+/* page.php 内的元素 */
+.entry-page .entry-thumb {
+ margin: 0 0 var(--space-6, 24px);
+ border-radius: var(--radius-lg, 12px);
+ overflow: hidden;
+}
+
+.entry-page .page-links {
+ margin-top: var(--space-6, 24px);
+ font-size: var(--text-sm, 0.875rem);
+ color: var(--color-ink-3, var(--color-ink-3));
+}
+
+.entry-page .page-links-title {
+ margin-right: 8px;
+ font-weight: 600;
+}
+
+.content-layout {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 20px;
+ align-items: start;
+}
+
+@media (min-width: 992px) {
+ .content-layout {
+ grid-template-columns: minmax(0, 1fr) 300px;
+ gap: 20px;
+ }
+}
+
+.content-layout__primary {
+ min-width: 0;
+}
+
+.content-layout__aside {
+ min-width: 0;
+}
+
+@media (min-width: 992px) {
+ .content-layout__aside {
+ position: sticky;
+ top: calc(var(--nav-height, 60px) + 16px);
+ align-self: start;
+ }
+
+ /* WordPress Admin Bar 已全局禁用,无需偏移规则 */
+}
+
+@media (min-width: 992px) {
+ .has-static-nav .content-layout__aside {
+ top: 16px;
+ }
+}
+
+.content-layout--no-sidebar {
+ grid-template-columns: 1fr;
+}
+
+.content-layout--no-sidebar .content-layout__primary {
+ width: 100%;
+ max-width: var(--content-no-sidebar-max, 1080px);
+ margin: 0 auto;
+}
+
+/* 三栏布局变体:侧边栏在左侧 */
+@media (min-width: 992px) {
+ .content-layout--sidebar-left {
+ grid-template-columns: 300px minmax(0, 1fr);
+ }
+
+ .content-layout--sidebar-left .content-layout__aside {
+ order: -1;
+ }
+}
+
+/* ========== 分页 ========== */
+.pagination,
+.navigation.pagination .nav-links {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ margin: 40px 0 8px;
+}
+
+.pagination a,
+.pagination span,
+.navigation.pagination a,
+.navigation.pagination span {
+ min-width: 40px;
+ height: 40px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--radius-btn);
+ border: 1px solid var(--color-line);
+ color: var(--color-ink);
+ font-size: 14px;
+ font-weight: 500;
+ transition: border-color 0.2s, color 0.2s, background 0.2s;
+}
+
+.pagination a:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.pagination .current,
+.navigation.pagination span.current {
+ background: var(--color-primary);
+ border-color: var(--color-primary);
+ color: #fff;
+}
+
+.pagination .dots,
+.navigation.pagination .dots {
+ border: none;
+ color: var(--color-ink-4);
+ min-width: auto;
+ padding: 0 4px;
+}
+
+.pagination .prev,
+.pagination .next,
+.navigation.pagination a.prev,
+.navigation.pagination a.next {
+ min-width: 44px;
+}
+
+.pagination .disabled,
+.navigation.pagination span.disabled {
+ opacity: 0.4;
+ pointer-events: none;
+}
+
+/* ========== 页面标题区 ========== */
+.page-header {
+ margin-bottom: 28px;
+}
+
+.page-header .entry-title {
+ margin-bottom: 8px;
+}
+
+.page-header p {
+ color: var(--color-ink-3);
+ margin: 0;
+ max-width: 720px;
+}
+
+.term-page-header {
+ position: relative;
+ overflow: hidden;
+ border: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.08));
+ border-radius: var(--radius-lg);
+ background: var(--surface-1);
+ box-shadow: var(--shadow-sm, 0 1px 6px rgba(15, 23, 42, 0.04));
+}
+
+.term-page-header__body {
+ position: relative;
+ z-index: 1;
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 16px;
+ padding: 24px;
+}
+
+.term-page-header__eyebrow {
+ margin: 0 0 8px;
+ font-size: 0.8125rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ color: var(--color-primary);
+}
+
+.term-page-header__desc {
+ margin-top: 10px;
+}
+
+.term-page-header__cover {
+ min-height: 140px;
+ background-position: center;
+ background-size: cover;
+ border-top: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.08));
+}
+
+.term-page-header--simple .term-page-header__cover {
+ display: none;
+}
+
+.aksrt-admin-quicklink {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ min-height: 36px;
+ padding: 0 14px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-2);
+ color: var(--color-ink-2);
+ text-decoration: none;
+ white-space: nowrap;
+ font-size: 0.875rem;
+ font-weight: 600;
+}
+
+.aksrt-admin-quicklink:hover {
+ color: var(--color-primary);
+ border-color: var(--color-primary);
+ background: var(--color-primary-soft, rgba(59, 130, 246, 0.08));
+}
+
+.archive-filter-bar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 16px;
+ flex-wrap: wrap;
+ margin: -8px 0 24px;
+ padding: 16px 18px;
+ border-radius: var(--radius-lg);
+ background: var(--surface-2);
+ border: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.06));
+}
+
+.archive-filter-bar__main {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ flex-wrap: wrap;
+}
+
+.archive-filter-bar__label {
+ color: var(--color-ink-4);
+ font-size: 0.8125rem;
+ font-weight: 600;
+}
+
+.archive-filter-bar__chips {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.archive-filter-bar__chip {
+ display: inline-flex;
+ align-items: center;
+ min-height: 34px;
+ padding: 0 12px;
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-1);
+ color: var(--color-ink-2);
+ text-decoration: none;
+ font-size: 0.875rem;
+ font-weight: 500;
+}
+
+.archive-filter-bar__chip.is-active,
+.archive-filter-bar__chip:hover {
+ background: var(--color-primary);
+ color: var(--color-on-primary, #fff);
+}
+
+.archive-filter-bar__meta {
+ color: var(--color-ink-4);
+ font-size: 0.8125rem;
+ font-weight: 600;
+}
+
+@media (max-width: 767px) {
+ .term-page-header__body {
+ flex-direction: column;
+ align-items: stretch;
+ padding: 20px;
+ }
+
+ .aksrt-admin-quicklink {
+ width: fit-content;
+ }
+}
+
+/* ========== AJAX 分页(加载更多 / 无限滚动) ========== */
+.aksrt-pagination-ajax {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 16px;
+ margin: 40px 0 8px;
+}
+
+.aksrt-load-more-btn {
+ min-width: 180px;
+ height: 44px;
+ padding: 0 32px;
+ border-radius: var(--radius-btn);
+ border: 1px solid var(--color-line);
+ background: var(--surface-page);
+ color: var(--color-ink);
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: border-color 0.2s, color 0.2s, background 0.2s;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+}
+
+.aksrt-load-more-btn:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.aksrt-load-more-btn:disabled {
+ opacity: 0.5;
+ pointer-events: none;
+}
+
+.aksrt-loading-indicator {
+ display: none;
+ align-items: center;
+ gap: 8px;
+ font-size: 14px;
+ color: var(--color-ink-4);
+}
+
+.aksrt-loading-indicator i {
+ font-size: 16px;
+}
+
+.aksrt-scroll-sentinel {
+ width: 100%;
+ height: 1px;
+ pointer-events: none;
+}
+
+/* ========== 移动端/平板隐藏侧栏(与 zibll 一致:991px 以下隐藏) ========== */
+@media (max-width: 991px) {
+ .content-layout__aside {
+ display: none;
+ }
+}
+
+/* CMS 模块在侧栏布局中的适配 */
+.content-layout__primary--cms {
+ min-width: 0;
+}
+
+.content-layout__primary--cms .home-modules {
+ gap: var(--space-7, 32px);
+}
+
+.content-layout__primary--cms .home-modules > .home-module {
+ max-width: 100%;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+/* ============================================================
+ * Phase 2 — 背景遮罩层级修正
+ * body.aksrt-bg-overlay 的 ::before 需要 z-index: -1 让内容在其上方
+ * ============================================================ */
+body.aksrt-bg-overlay {
+ position: relative;
+}
+
+body.aksrt-bg-overlay::before {
+ z-index: -1;
+}
+
+body.aksrt-bg-overlay .site-wrapper {
+ position: relative;
+ z-index: 0;
+}
+
+/* ============================================================
+ * Phase 2 — 侧栏 widget 内链接增强
+ * ============================================================ */
+.content-layout__aside .widget a {
+ transition: color var(--dur-fast, 0.15s) var(--ease);
+}
+
+.content-layout__aside .widget a:hover {
+ color: var(--color-primary);
+}
+
+/* ============================================================
+ * Phase 5 — 文章操作卡片增强
+ * ============================================================ */
+
+/* ============================================================
+ * Phase 6 — 评论卡片容器
+ * ============================================================ */
+.comments-card {
+ overflow: hidden;
+}
+/* ============================================================
+ * AKSRT Footer — v4.0 Zibll-Inspired
+ *
+ * 包含:
+ * - 页脚主体(Bootstrap Grid)
+ * - 浮动右侧按钮组
+ * - 移动端底部 Tab 栏
+ * ============================================================ */
+
+/* ============================================================
+ * 页脚主体
+ * ============================================================ */
+.site-footer {
+ margin-top: auto;
+ background: var(--surface-1);
+ border-top: 1px solid var(--color-line);
+ padding: 30px 0 0;
+}
+
+.site-footer__inner {
+ max-width: var(--container);
+ margin: 0 auto;
+ padding: 0 16px;
+}
+
+@media (min-width: 768px) {
+ .site-footer__inner {
+ padding: 0 24px;
+ }
+}
+
+.site-footer__grid {
+ padding-bottom: 32px;
+}
+
+.site-footer__brand {
+ margin-bottom: 24px;
+}
+
+.site-footer__title {
+ font-size: 1rem;
+ font-weight: 700;
+ margin: 0 0 12px;
+ color: var(--color-ink);
+}
+
+.site-footer__desc {
+ font-size: 0.875rem;
+ color: var(--color-ink-4);
+ line-height: 1.6;
+ margin: 0 0 16px;
+ max-width: 360px;
+}
+
+.site-footer__col {
+ margin-bottom: 24px;
+}
+
+.site-footer__col ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.site-footer__col li {
+ margin-bottom: 8px;
+}
+
+.site-footer__col a {
+ font-size: 0.875rem;
+ color: var(--color-ink-3);
+ transition: color 0.15s ease;
+}
+
+.site-footer__col a:hover {
+ color: var(--color-primary);
+}
+
+/* 社交链接行 */
+.social-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 16px;
+}
+
+.social-row a {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ background: var(--surface-3);
+ color: var(--color-ink-3);
+ transition: background 0.2s, color 0.2s, transform 0.2s;
+}
+
+.social-row a:hover {
+ background: var(--color-primary);
+ color: #fff;
+ transform: translateY(-2px);
+}
+
+.social-row .social-icon-link {
+ background: var(--surface-3);
+ color: var(--color-ink-3);
+}
+
+.social-row .social-icon-link:hover {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+/* 友情链接 */
+.site-footer__friends {
+ margin-top: 16px;
+}
+
+.site-footer__friends-title {
+ font-size: 0.8125rem;
+ font-weight: 600;
+ color: var(--color-ink-4);
+ margin: 0 0 8px;
+}
+
+.site-footer__friends-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px 12px;
+}
+
+.site-footer__friends-list a {
+ font-size: 0.8125rem;
+ color: var(--color-ink-4);
+}
+
+.site-footer__friends-list a:hover {
+ color: var(--color-primary);
+}
+
+/* 底部栏 */
+.site-footer__bottom {
+ border-top: 1px solid var(--color-line);
+ padding: 20px 0;
+ text-align: center;
+}
+
+.site-footer__filings {
+ display: flex;
+ justify-content: center;
+ gap: 16px;
+ margin-bottom: 8px;
+ flex-wrap: wrap;
+}
+
+.site-footer__filings a {
+ font-size: 0.75rem;
+ color: var(--color-ink-4);
+}
+
+.site-footer__filings a:hover {
+ color: var(--color-primary);
+}
+
+.site-footer__copyright {
+ font-size: 0.75rem;
+ color: var(--color-ink-4);
+ margin: 0;
+}
+
+/* ============================================================
+ * 浮动右侧按钮组(模仿 zibll float-right)
+ * ============================================================ */
+/* 对齐 zibll: bottom 60px, z-index 1030 */
+.float-right-btns {
+ position: fixed;
+ right: 20px;
+ bottom: 60px;
+ z-index: 1030;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ transition: opacity 0.3s ease;
+}
+
+/* 对齐 zibll: 40px, 1.4em icon */
+.float-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ min-height: 40px;
+ border-radius: 50%;
+ border: none;
+ background: var(--float-btn-bg);
+ color: var(--color-ink-3);
+ box-shadow: var(--shadow-sm);
+ cursor: pointer;
+ transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
+ font-size: 1.4em;
+ text-decoration: none;
+}
+
+.float-btn:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow);
+ color: var(--color-primary);
+ background: var(--surface-page);
+ text-decoration: none;
+}
+
+.float-btn:active {
+ transform: scale(0.95);
+}
+
+/* 回到顶部按钮 — 滚动后显示 */
+.float-btn--top {
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.2s ease;
+}
+
+.float-btn--top.is-visible {
+ opacity: 1;
+ visibility: visible;
+ display: flex;
+}
+
+/* 主题切换按钮 */
+#float-theme-toggle .float-btn__icon-moon {
+ display: none !important;
+}
+
+#float-theme-toggle .float-btn__icon-sun {
+ display: inline-block !important;
+}
+
+#float-theme-toggle[aria-pressed="true"] .float-btn__icon-moon,
+.theme-dark #float-theme-toggle .float-btn__icon-moon,
+html.dark #float-theme-toggle .float-btn__icon-moon {
+ display: inline-block !important;
+}
+
+#float-theme-toggle[aria-pressed="true"] .float-btn__icon-sun,
+.theme-dark #float-theme-toggle .float-btn__icon-sun,
+html.dark #float-theme-toggle .float-btn__icon-sun {
+ display: none !important;
+}
+
+/* 移动端隐藏浮动按钮(用 tabbar 代替) */
+@media (max-width: 767px) {
+ .float-right-btns {
+ right: 12px;
+ bottom: 80px;
+ }
+
+ .float-btn {
+ width: 38px;
+ height: 38px;
+ font-size: 14px;
+ }
+}
+
+/* ============================================================
+ * 移动端底部 Tab 栏(模仿 zibll footer-tabbar)
+ * ============================================================ */
+.footer-tabbar {
+ display: none;
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 1035;
+ min-height: 49px;
+ background: var(--blur-bg);
+ border-top: 1px solid var(--color-line-soft);
+ padding: 0 0 env(safe-area-inset-bottom, 0px);
+ justify-content: space-around;
+ align-items: center;
+ box-shadow: var(--shadow-sm);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+}
+
+.footer-tabbar-placeholder {
+ display: none;
+ height: calc(49px + env(safe-area-inset-bottom, 0px));
+}
+
+@media (max-width: 767px) {
+ .footer-tabbar {
+ display: flex;
+ }
+
+ .footer-tabbar-placeholder {
+ display: block;
+ }
+
+ /* 有 tabbar 时页脚需要额外底部间距 */
+ .site-footer {
+ padding-bottom: calc(49px + env(safe-area-inset-bottom, 0px));
+ }
+}
+
+.tabbar-item {
+ display: flex;
+ flex: 1 1 0;
+ min-width: 0;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 1px;
+ min-height: 49px;
+ padding: 4px 0 3px;
+ color: var(--color-ink-4);
+ font-size: 13px;
+ text-decoration: none;
+ border: none;
+ background: none;
+ cursor: pointer;
+ transition: color 0.15s ease;
+ -webkit-tap-highlight-color: transparent;
+ position: relative;
+}
+
+/* 对齐 zibll: 24px 图标 */
+.tabbar-item i {
+ font-size: 24px;
+ line-height: 1;
+}
+
+.tabbar-item span {
+ display: block;
+ font-weight: 500;
+ line-height: 1;
+ transform: scale(0.8);
+ transform-origin: center top;
+}
+
+.tabbar-item:hover,
+.tabbar-item.active {
+ color: var(--color-primary);
+ text-decoration: none;
+}
+
+.tabbar-item.active i {
+ font-weight: 900;
+}
+
+.tabbar-badge {
+ position: absolute;
+ top: 2px;
+ right: 8px;
+ min-width: 16px;
+ height: 16px;
+ padding: 0 4px;
+ border-radius: 999px;
+ background: var(--color-error);
+ color: #fff;
+ font-size: 10px;
+ line-height: 16px;
+ font-style: normal;
+ font-weight: 700;
+ text-align: center;
+ box-shadow: 0 2px 8px rgba(239, 68, 68, 0.20);
+}
+
+.tabbar-item--add {
+ margin-top: -22px;
+ width: 62px;
+ height: 62px;
+ min-height: 62px;
+ border-radius: 50%;
+ background: var(--color-accent);
+ color: #fff;
+ box-shadow: 0 12px 24px var(--color-accent-shadow);
+ flex: 0 0 62px;
+ z-index: 1;
+}
+
+.tabbar-item--add i {
+ font-size: 22px;
+}
+
+.tabbar-item--add span {
+ font-size: 11px;
+}
+
+.tabbar-item--add:hover,
+.tabbar-item--add.active {
+ color: #fff;
+}
+
+.tabbar-add-backdrop {
+ position: fixed;
+ inset: 0;
+ z-index: 951;
+ background: rgba(15, 23, 42, 0.38);
+}
+
+.tabbar-add-panel {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 952;
+ padding: 0 12px calc(84px + env(safe-area-inset-bottom, 0px));
+}
+
+.tabbar-add-panel__sheet {
+ border-radius: 20px;
+ background: var(--surface-page);
+ box-shadow: 0 18px 50px rgba(15, 23, 42, 0.18);
+ overflow: hidden;
+}
+
+.tabbar-add-panel__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 16px 18px 12px;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.tabbar-add-panel__close {
+ width: 32px;
+ height: 32px;
+ border: 0;
+ border-radius: 50%;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+}
+
+.tabbar-add-panel__list {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 12px;
+ padding: 18px;
+}
+
+.tabbar-add-panel__item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ min-height: 88px;
+ border-radius: 18px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ text-decoration: none;
+}
+
+.tabbar-add-panel__item i {
+ font-size: 22px;
+ color: var(--color-accent);
+}
+
+.tabbar-add-panel__item span {
+ font-size: 13px;
+ font-weight: 600;
+}
+
+.tabbar-search-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 953;
+ background: rgba(15, 23, 42, 0.58);
+ display: flex;
+ align-items: stretch;
+ justify-content: center;
+}
+
+.tabbar-search-overlay__dialog {
+ width: 100%;
+ min-height: 100%;
+ background: var(--surface-page);
+ padding: 18px 16px calc(24px + env(safe-area-inset-bottom, 0px));
+}
+
+.tabbar-search-overlay__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 16px;
+}
+
+.tabbar-search-overlay__close {
+ width: 36px;
+ height: 36px;
+ border: 0;
+ border-radius: 50%;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+}
+
+.tabbar-search-overlay__form {
+ display: grid;
+ grid-template-columns: 20px 1fr auto;
+ gap: 10px;
+ align-items: center;
+ padding: 14px 14px 14px 12px;
+ border-radius: 18px;
+ background: var(--surface-2);
+}
+
+.tabbar-search-overlay__icon {
+ color: var(--color-ink-4);
+}
+
+.tabbar-search-overlay__form input {
+ min-width: 0;
+ border: 0;
+ background: transparent;
+ color: var(--color-ink);
+ font-size: 15px;
+ outline: none;
+}
+
+.tabbar-search-overlay__submit {
+ border: 0;
+ border-radius: 12px;
+ padding: 10px 14px;
+ background: var(--color-accent);
+ color: #fff;
+ font-weight: 700;
+}
+
+.tabbar-search-overlay__types {
+ display: flex;
+ gap: 8px;
+ margin-top: 14px;
+}
+
+.tabbar-search-overlay__type {
+ border: 0;
+ border-radius: 999px;
+ padding: 9px 14px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ font-size: 13px;
+ font-weight: 600;
+}
+
+.tabbar-search-overlay__type.is-active {
+ background: var(--color-accent-soft);
+ color: var(--color-accent);
+}
+
+.tabbar-search-overlay__section {
+ margin-top: 20px;
+}
+
+.tabbar-search-overlay__section-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 12px;
+}
+
+.tabbar-search-overlay__label {
+ color: var(--color-ink-3);
+ font-size: 13px;
+ font-weight: 700;
+}
+
+.tabbar-search-overlay__clear {
+ border: 0;
+ background: transparent;
+ color: var(--color-accent);
+ font-size: 12px;
+ font-weight: 700;
+}
+
+.tabbar-search-overlay__history,
+.tabbar-search-overlay__suggestions {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.tabbar-search-overlay__history-item,
+.tabbar-search-overlay__suggestion-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ width: 100%;
+ border: 0;
+ border-radius: 16px;
+ padding: 12px 14px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ text-decoration: none;
+ text-align: left;
+}
+
+.tabbar-search-overlay__history-item i {
+ color: var(--color-accent);
+}
+
+.tabbar-search-overlay__history-item span,
+.tabbar-search-overlay__suggestion-item span {
+ flex: 1;
+ min-width: 0;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.tabbar-search-overlay__suggestion-item small {
+ color: var(--color-ink-4);
+ font-size: 12px;
+}
+
+.tabbar-search-overlay__empty {
+ padding: 14px;
+ border-radius: 16px;
+ background: var(--surface-2);
+ color: var(--color-ink-4);
+ font-size: 13px;
+ text-align: center;
+}
+
+.tabbar-search-overlay__tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.tabbar-search-overlay__tag {
+ padding: 10px 14px;
+ border-radius: 999px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ text-decoration: none;
+ font-size: 13px;
+}
+
+body.tabbar-search-open,
+body.tabbar-add-open {
+ overflow: hidden;
+}
+
+/* 滚动时隐藏 tabbar(可选,通过 JS 添加 class) */
+.footer-tabbar.scrolling-hide {
+ transform: translateY(100%);
+ transition: transform 0.3s ease;
+}
+
+/* 向下滚动隐藏,向上滚动显示 */
+.footer-tabbar.scroll-down-hide {
+ transition: transform 0.3s ease;
+}
+
+.footer-tabbar.scroll-down-hide.is-hidden {
+ transform: translateY(120%);
+}
+
+/* 返回顶部包裹项(首页按钮 + 返回顶部切换) */
+.tabbar-ontop-wrap {
+ position: relative;
+}
+
+.tabbar-ontop-wrap .tabbar-ontop-btn {
+ display: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 2px;
+ padding: 4px 12px;
+ color: var(--color-primary);
+ font-size: 13px;
+ text-decoration: none;
+ cursor: pointer;
+ -webkit-tap-highlight-color: transparent;
+}
+
+.tabbar-ontop-wrap .tabbar-ontop-btn i {
+ font-size: 18px;
+ line-height: 1;
+}
+
+.tabbar-ontop-wrap .tabbar-ontop-btn span {
+ font-weight: 500;
+ line-height: 1;
+ transform: scale(0.8);
+ transform-origin: center top;
+}
+
+.tabbar-ontop-wrap.is-scrolled .tabbar-ontop-btn {
+ display: flex;
+}
+
+.tabbar-ontop-wrap.is-scrolled > .tabbar-item:not(.tabbar-ontop-btn) {
+ opacity: 0;
+ pointer-events: none;
+}
+
+/* ============================================================
+ * 暗色模式适配
+ * ============================================================ */
+.theme-dark .site-footer,
+html.dark .site-footer {
+ background: var(--surface-1);
+}
+
+.theme-dark .float-btn,
+html.dark .float-btn {
+ background: var(--float-btn-bg);
+ box-shadow: var(--shadow-sm);
+}
+
+.theme-dark .footer-tabbar,
+html.dark .footer-tabbar {
+ background: var(--blur-bg);
+ box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.20);
+}
+
+/* ============================================================
+ * 旧版 back-to-top 按钮兼容(隐藏,用浮动按钮代替)
+ * ============================================================ */
+.back-to-top {
+ display: none !important;
+}
+
+/* ============================================================
+ * 页脚布局模板变体
+ * ============================================================ */
+
+/* 紧凑模板:单行版权 + 链接 */
+.site-footer--compact .site-footer__grid {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 16px;
+}
+
+.site-footer--compact .site-footer__brand {
+ flex: 1 1 100%;
+}
+
+.site-footer--compact .site-footer__brand .site-footer__desc,
+.site-footer--compact .site-footer__brand .social-row,
+.site-footer--compact .site-footer__brand .site-footer__friends {
+ display: none;
+}
+
+.site-footer--compact .site-footer__col {
+ flex: 0 0 auto;
+}
+
+.site-footer--compact .site-footer__col ul {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.site-footer--compact .site-footer__bottom {
+ border-top: 1px solid var(--color-line);
+ padding-top: 12px;
+ margin-top: 12px;
+}
+
+/* 中央模板:居中品牌 + 链接 */
+.site-footer--centered .site-footer__grid {
+ text-align: center;
+}
+
+.site-footer--centered .site-footer__brand {
+ flex: 1 1 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.site-footer--centered .site-footer__col {
+ flex: 1 1 auto;
+}
+
+.site-footer--centered .site-footer__col ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 16px;
+}
+/* ============================================================
+ * Floating Buttons
+ * ============================================================ */
+
+.float-right {
+ --float-btn-size: 42px;
+ --float-btn-color: var(--color-ink-3);
+ position: fixed;
+ right: 20px;
+ bottom: 96px;
+ z-index: 900;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ transition: transform var(--dur, 0.25s) var(--ease, ease), opacity var(--dur, 0.25s) var(--ease, ease);
+ padding-bottom: env(safe-area-inset-bottom, 0px);
+}
+
+.float-right.position-center {
+ top: 50%;
+ bottom: auto;
+ transform: translateY(-50%);
+}
+
+.float-right.square {
+ gap: 0;
+ overflow: hidden;
+ border-radius: var(--radius-lg, 8px);
+ box-shadow: var(--shadow-md, 0 10px 30px rgba(17, 24, 39, 0.12));
+}
+
+.float-right .float-btn {
+ width: var(--float-btn-size);
+ min-height: var(--float-btn-size);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ color: var(--this-color, var(--float-btn-color));
+ background: var(--this-bg, var(--float-btn-bg));
+ border: 1px solid var(--color-line-soft, #f0f1f3);
+ text-decoration: none;
+ box-shadow: var(--shadow, 0 8px 24px rgba(17, 24, 39, 0.08));
+ transition: transform var(--dur-fast, 0.15s) var(--ease, ease), box-shadow var(--dur-fast, 0.15s) var(--ease, ease), color var(--dur-fast, 0.15s) var(--ease, ease), background var(--dur-fast, 0.15s) var(--ease, ease);
+ cursor: pointer;
+ outline: none;
+ overflow: visible;
+}
+
+.float-right.round .float-btn {
+ border-radius: 12px;
+}
+
+.float-right.square .float-btn {
+ border-radius: 0;
+ box-shadow: none;
+ border-top-width: 0;
+}
+
+.float-right.square .float-btn:first-child {
+ border-top-width: 1px;
+}
+
+.float-right .float-btn:hover {
+ transform: translateY(-2px);
+ color: var(--color-primary, var(--color-primary));
+ text-decoration: none;
+ box-shadow: var(--shadow-md, 0 10px 30px rgba(17, 24, 39, 0.12));
+ z-index: 2;
+}
+
+.float-right .float-btn:active {
+ transform: scale(0.96);
+}
+
+.float-right .float-btn::after {
+ content: "";
+ position: absolute;
+ inset: auto;
+ width: 6px;
+ height: 6px;
+ border-radius: 999px;
+ background: currentColor;
+ opacity: 0;
+ transform: scale(1);
+ pointer-events: none;
+}
+
+.float-right .float-btn.is-rippling::after {
+ animation: float-btn-ripple 0.55s ease-out;
+}
+
+.float-right .float-btn i {
+ font-size: 16px;
+ line-height: 1;
+}
+
+.float-right .float-btn.ontop {
+ opacity: 0;
+ visibility: hidden;
+ pointer-events: none;
+}
+
+.float-right .float-btn.ontop.is-visible {
+ opacity: 1;
+ visibility: visible;
+ pointer-events: auto;
+}
+
+.float-right.has-blur-pc .float-btn {
+ backdrop-filter: saturate(1.5) blur(10px);
+ -webkit-backdrop-filter: saturate(1.5) blur(10px);
+}
+
+.float-right .hover-show-con {
+ position: absolute;
+ display: block;
+ right: calc(100% + 12px);
+ top: 50%;
+ transform: translateY(-50%);
+ min-width: 180px;
+ max-width: 280px;
+ padding: 12px;
+ border-radius: var(--radius-lg, 8px);
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ box-shadow: var(--shadow-lg, 0 18px 40px rgba(17, 24, 39, 0.18));
+ color: var(--color-ink-2);
+ opacity: 0;
+ visibility: hidden;
+ pointer-events: none;
+ transition: opacity var(--dur-fast, 0.15s) var(--ease, ease), transform var(--dur-fast, 0.15s) var(--ease, ease), visibility var(--dur-fast, 0.15s) var(--ease, ease);
+}
+
+.float-right .hover-show-con::before {
+ content: "";
+ position: absolute;
+ top: 50%;
+ right: -8px;
+ width: 16px;
+ height: 16px;
+ background: inherit;
+ border-top: 1px solid var(--color-line);
+ border-right: 1px solid var(--color-line);
+ transform: translateY(-50%) rotate(45deg);
+}
+
+.float-right .hover-show-con img {
+ display: block;
+ width: 100%;
+ max-width: 160px;
+ height: auto;
+ margin: 0 auto 10px;
+ border-radius: var(--radius, 10px);
+}
+
+.float-right .hover-show-con p {
+ margin: 0;
+ font-size: 13px;
+ line-height: 1.6;
+ color: var(--color-ink-3);
+}
+
+.float-btn-qrcode {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ min-height: 120px;
+ margin: 0 auto 10px;
+ background: #fff;
+ border-radius: var(--radius, 10px);
+}
+
+.float-right .service-wechat .hover-show-con,
+.float-right .service-qq .hover-show-con,
+.float-right .qrcode-btn .hover-show-con {
+ padding: 14px;
+}
+
+.float-right .service-wechat .hover-show-con img,
+.float-right .service-qq .hover-show-con img {
+ margin: 0 auto;
+ box-shadow: 0 10px 24px rgba(17, 24, 39, 0.12);
+}
+
+.float-right .service-wechat .hover-show-con p,
+.float-right .service-qq .hover-show-con p {
+ display: none;
+}
+
+.float-right .newadd-btns .hover-show-con {
+ min-width: 196px;
+ padding: 10px;
+}
+
+.float-add-menu {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.float-add-menu__item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 12px;
+ border-radius: 10px;
+ color: var(--color-ink-2);
+ text-decoration: none;
+ transition: background var(--dur-fast, 0.15s) var(--ease, ease), color var(--dur-fast, 0.15s) var(--ease, ease), transform var(--dur-fast, 0.15s) var(--ease, ease);
+}
+
+.float-add-menu__item i {
+ width: 18px;
+ text-align: center;
+ color: var(--color-primary, var(--color-primary));
+}
+
+.float-add-menu__item:hover {
+ background: var(--color-primary-soft, rgba(136, 171, 218, 0.1));
+ color: var(--color-primary, var(--color-primary));
+ transform: translateX(-2px);
+}
+
+.float-btn-qrcode :deep(canvas),
+.float-btn-qrcode :deep(img),
+.float-btn-qrcode svg {
+ display: block;
+ margin: 0 auto;
+}
+
+.float-right .float-btn:hover .hover-show-con,
+.float-right .float-btn:focus-visible .hover-show-con {
+ opacity: 1;
+ visibility: visible;
+ pointer-events: auto;
+ transform: translateY(-50%) translateX(-4px);
+}
+
+.float-right.scrolling-hide.is-hidden,
+.float-right.scroll-down-hide.is-hidden {
+ transform: translateX(calc(100% + 24px));
+}
+
+.float-right.position-center.scrolling-hide.is-hidden,
+.float-right.position-center.scroll-down-hide.is-hidden {
+ transform: translateX(calc(100% + 24px)) translateY(-50%);
+}
+
+.float-right__html {
+ font-size: 13px;
+ line-height: 1.6;
+}
+
+.float-right__html a {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.float-right__html a:hover {
+ color: var(--color-primary-hover, #7099CC);
+}
+
+@keyframes float-btn-ripple {
+ 0% {
+ opacity: 0.22;
+ transform: scale(1);
+ }
+ 100% {
+ opacity: 0;
+ transform: scale(14);
+ }
+}
+
+.float-btn__icon-moon {
+ display: none;
+}
+
+.float-btn__icon-sun {
+ display: inline-block;
+}
+
+.theme-dark .float-btn__icon-moon,
+html.dark .float-btn__icon-moon {
+ display: inline-block;
+}
+
+.theme-dark .float-btn__icon-sun,
+html.dark .float-btn__icon-sun {
+ display: none;
+}
+
+.theme-dark .float-right,
+html.dark .float-right {
+ --float-btn-color: var(--color-ink-4);
+}
+
+.theme-dark .float-right .hover-show-con,
+html.dark .float-right .hover-show-con {
+ background: var(--surface-2, #1f2430);
+ border-color: rgba(255, 255, 255, 0.08);
+}
+
+@media (max-width: 767px) {
+ .float-right {
+ right: 12px;
+ bottom: 84px;
+ --float-btn-size: 40px;
+ }
+
+ .float-right.has-blur-mobile .float-btn {
+ backdrop-filter: saturate(1.5) blur(10px);
+ -webkit-backdrop-filter: saturate(1.5) blur(10px);
+ }
+
+ .float-right .hover-show-con {
+ max-width: min(240px, calc(100vw - 84px));
+ }
+}
+/**
+ * AKSRT Theme Background System
+ *
+ * 全局背景图、夜间背景图、页面背景色/背景图。
+ * 所有选择器均带 aksrt- 命名空间。
+ */
+
+/* ========== 全局背景 ========== */
+.aksrt-bg-body {
+ background-color: var(--aksrt-bg-color, transparent);
+ background-image: var(--aksrt-bg-image, none);
+ background-size: var(--aksrt-bg-size, cover);
+ background-position: var(--aksrt-bg-position, center center);
+ background-repeat: var(--aksrt-bg-repeat, no-repeat);
+ background-attachment: var(--aksrt-bg-attachment, fixed);
+}
+
+/* ========== 夜间模式背景 ========== */
+.aksrt-bg-dark {
+ background-color: var(--aksrt-bg-dark-color, transparent);
+ background-image: var(--aksrt-bg-dark-image, none);
+}
+
+/* ========== 页面级背景 ========== */
+.aksrt-bg-page {
+ background-color: var(--aksrt-page-bg-color, transparent);
+ background-image: var(--aksrt-page-bg-image, none);
+ background-size: cover;
+ background-position: center center;
+ background-repeat: no-repeat;
+}
+
+/* ========== 模块级背景 ========== */
+.aksrt-bg-module {
+ background-color: var(--aksrt-module-bg-color, transparent);
+ background-image: var(--aksrt-module-bg-image, none);
+ background-size: cover;
+ background-position: center center;
+ background-repeat: no-repeat;
+}
+
+/* ========== 背景遮罩层(提升文字可读性)========== */
+.aksrt-bg-overlay {
+ position: relative;
+}
+
+.aksrt-bg-overlay::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: var(--aksrt-bg-overlay-color, rgba(0, 0, 0, 0.3));
+ pointer-events: none;
+ z-index: 0;
+}
+
+.aksrt-bg-overlay > * {
+ position: relative;
+ z-index: 1;
+}
+
+/* ========== 暗色模式自动切换 ========== */
+@media (prefers-color-scheme: dark) {
+ :root:not(.aksrt-light-mode) .aksrt-bg-body {
+ background-color: var(--aksrt-bg-dark-color, var(--aksrt-bg-color, transparent));
+ background-image: var(--aksrt-bg-dark-image, var(--aksrt-bg-image, none));
+ }
+}
+
+html.aksrt-dark-mode .aksrt-bg-body {
+ background-color: var(--aksrt-bg-dark-color, var(--aksrt-bg-color, transparent));
+ background-image: var(--aksrt-bg-dark-image, var(--aksrt-bg-image, none));
+}
+/**
+ * AKSRT Menu Decorations
+ *
+ * 菜单图标、徽章、多列下拉、图文卡片子菜单样式。
+ * 所有选择器均带 aksrt- 或 .site-nav 命名空间。
+ */
+
+/* ========== 菜单图标 ========== */
+.nav-desktop .menu-item > a .menu-icon,
+.nav-desktop .menu-item > a > i:first-child {
+ display: inline-flex;
+ align-items: center;
+ margin-right: 6px;
+ font-size: 14px;
+ opacity: 0.75;
+ transition: opacity 0.2s ease;
+}
+
+.nav-desktop .menu-item:hover > a .menu-icon,
+.nav-desktop .menu-item:hover > a > i:first-child {
+ opacity: 1;
+}
+
+/* ========== 菜单徽章 ========== */
+.nav-desktop .menu-item > a .menu-badge,
+.nav-desktop .menu-item > a .aksrt-menu-badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ margin-left: 6px;
+ padding: 1px 6px;
+ font-size: 10px;
+ font-weight: 700;
+ line-height: 1.4;
+ letter-spacing: 0.02em;
+ border-radius: 8px;
+ white-space: nowrap;
+ vertical-align: middle;
+ transform: translateY(-1px);
+}
+
+.aksrt-menu-badge--new {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+.aksrt-menu-badge--hot {
+ background: #ff4d4f;
+ color: #fff;
+}
+
+.aksrt-menu-badge--info {
+ background: var(--color-info, #1890ff);
+ color: #fff;
+}
+
+.aksrt-menu-badge--success {
+ background: var(--color-success, #52c41a);
+ color: #fff;
+}
+
+.aksrt-menu-badge--warning {
+ background: var(--color-warning, #faad14);
+ color: #fff;
+}
+
+/* ========== Hover 效果 ========== */
+/* 下划线效果 */
+.aksrt-menu-hover--underline .nav-desktop .menu-item > a {
+ position: relative;
+}
+
+.aksrt-menu-hover--underline .nav-desktop .menu-item > a::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ width: 0;
+ height: 2px;
+ background: var(--color-primary);
+ border-radius: 1px;
+ transform: translateX(-50%);
+ transition: width 0.25s ease;
+}
+
+.aksrt-menu-hover--underline .nav-desktop .menu-item:hover > a::after,
+.aksrt-menu-hover--underline .nav-desktop .menu-item.current-menu-item > a::after,
+.aksrt-menu-hover--underline .nav-desktop .menu-item.current_page_item > a::after {
+ width: 70%;
+}
+
+/* 背景色效果 */
+.aksrt-menu-hover--background .nav-desktop .menu-item > a {
+ border-radius: 6px;
+ transition: background-color 0.2s ease;
+}
+
+.aksrt-menu-hover--background .nav-desktop .menu-item:hover > a {
+ background-color: var(--color-primary-soft, rgba(24, 144, 255, 0.08));
+}
+
+/* 文字变色效果 */
+.aksrt-menu-hover--color .nav-desktop .menu-item > a {
+ transition: color 0.2s ease;
+}
+
+.aksrt-menu-hover--color .nav-desktop .menu-item:hover > a {
+ color: var(--color-primary);
+}
+
+/* ========== 多列 Mega 下拉 ========== */
+.nav-desktop .menu-item .aksrt-mega-submenu {
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ z-index: 999;
+ min-width: var(--aksrt-mega-width, 480px);
+ padding: 16px 20px;
+ background: var(--surface-page, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+ opacity: 0;
+ visibility: hidden;
+ transform: translateX(-50%) translateY(8px);
+ transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
+}
+
+.nav-desktop .menu-item:hover .aksrt-mega-submenu {
+ opacity: 1;
+ visibility: visible;
+ transform: translateX(-50%) translateY(0);
+}
+
+.aksrt-mega-submenu__grid {
+ display: grid;
+ gap: 12px;
+}
+
+.aksrt-mega-submenu__grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
+.aksrt-mega-submenu__grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
+.aksrt-mega-submenu__grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
+.aksrt-mega-submenu__grid--cols-5 { grid-template-columns: repeat(5, 1fr); }
+
+.aksrt-mega-submenu__item {
+ display: flex;
+ align-items: flex-start;
+ gap: 10px;
+ padding: 10px 12px;
+ border-radius: 6px;
+ text-decoration: none;
+ color: var(--color-ink);
+ transition: background-color 0.15s ease;
+}
+
+.aksrt-mega-submenu__item:hover {
+ background-color: var(--color-primary-soft, rgba(24, 144, 255, 0.08));
+}
+
+.aksrt-mega-submenu__item-icon {
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: 6px;
+ background: var(--color-primary-soft, rgba(24, 144, 255, 0.08));
+ color: var(--color-primary);
+ font-size: 14px;
+}
+
+.aksrt-mega-submenu__item-content {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-mega-submenu__item-title {
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 1.4;
+ color: var(--color-ink);
+}
+
+.aksrt-mega-submenu__item-desc {
+ margin-top: 2px;
+ font-size: 12px;
+ line-height: 1.4;
+ color: var(--text-tertiary, #8a909c);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+/* ========== 图文卡片子菜单 ========== */
+.nav-desktop .menu-item .aksrt-card-submenu {
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ z-index: 999;
+ display: flex;
+ gap: 12px;
+ padding: 16px;
+ background: var(--surface-page, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+ opacity: 0;
+ visibility: hidden;
+ transform: translateX(-50%) translateY(8px);
+ transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
+}
+
+.nav-desktop .menu-item:hover .aksrt-card-submenu {
+ opacity: 1;
+ visibility: visible;
+ transform: translateX(-50%) translateY(0);
+}
+
+.aksrt-card-submenu__item {
+ display: flex;
+ flex-direction: column;
+ width: var(--aksrt-card-width, 160px);
+ text-decoration: none;
+ border-radius: 8px;
+ overflow: hidden;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.aksrt-card-submenu__item:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.aksrt-card-submenu__thumb {
+ width: 100%;
+ aspect-ratio: 16 / 10;
+ object-fit: cover;
+ background: var(--color-fill, #f5f5f5);
+}
+
+.aksrt-card-submenu__body {
+ padding: 8px 10px;
+}
+
+.aksrt-card-submenu__title {
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 1.4;
+ color: var(--color-ink);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.aksrt-card-submenu__desc {
+ margin-top: 2px;
+ font-size: 11px;
+ line-height: 1.4;
+ color: var(--text-tertiary, #8a909c);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+/* ========== 暗色模式适配 ========== */
+html.dark .aksrt-mega-submenu,
+html.dark .aksrt-card-submenu,
+html.dark .aksrt-mega-submenu,
+html.dark .aksrt-card-submenu {
+ background: var(--surface-page);
+ border-color: var(--color-line, #2d2d3f);
+}
+
+html.dark .aksrt-mega-submenu__item-title,
+html.dark .aksrt-card-submenu__title,
+html.dark .aksrt-mega-submenu__item-title,
+html.dark .aksrt-card-submenu__title {
+ color: var(--color-ink);
+}
+/**
+ * AKSRT Enhancements — 全局 UI 增强
+ *
+ * 包含:Toast 通知、骨架屏、悬停动效、暗色过渡、滚动感知
+ * 所有选择器使用 aksrt- 前缀避免冲突
+ */
+
+/* ============================================================
+ * 1. Toast 通知系统
+ * ============================================================ */
+.aksrt-toast-container {
+ position: fixed;
+ bottom: 80px;
+ right: 16px;
+ max-width: 360px;
+ z-index: 10000;
+ display: flex;
+ flex-direction: column-reverse;
+ gap: 8px;
+ pointer-events: none;
+}
+
+.aksrt-toast {
+ pointer-events: auto;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 12px 16px;
+ border-radius: var(--main-radius, 8px);
+ color: #fff;
+ font-size: 14px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
+ backdrop-filter: saturate(5) blur(20px);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ transform: translateX(120%);
+ opacity: 0;
+ animation: aksrt-toast-in 0.35s cubic-bezier(0.35, 0.71, 0.46, 1.08) forwards;
+ cursor: pointer;
+ transition: transform 0.3s, opacity 0.3s;
+}
+
+.aksrt-toast.is-dismissing {
+ transform: translateX(120%);
+ opacity: 0;
+ transition: transform 0.3s ease-in, opacity 0.3s ease-in;
+}
+
+.aksrt-toast__icon {
+ font-size: 18px;
+ flex-shrink: 0;
+}
+
+.aksrt-toast__text {
+ flex: 1;
+ min-width: 0;
+ line-height: 1.4;
+}
+
+/* Toast 类型 — 对齐 zibll 纯色 */
+.aksrt-toast--success {
+ background: rgba(16, 185, 129, 0.9);
+}
+
+.aksrt-toast--info {
+ background: rgba(59, 130, 246, 0.9);
+}
+
+.aksrt-toast--warning {
+ background: rgba(245, 158, 11, 0.9);
+}
+
+.aksrt-toast--danger,
+.aksrt-toast--error {
+ background: rgba(239, 68, 68, 0.9);
+}
+
+.aksrt-toast--loading {
+ background: rgba(107, 114, 128, 0.9);
+}
+
+.aksrt-toast--loading .aksrt-toast__icon {
+ animation: aksrt-spin 1s linear infinite;
+}
+
+@keyframes aksrt-toast-in {
+ from {
+ transform: translateX(120%);
+ opacity: 0;
+ }
+ to {
+ transform: translateX(0);
+ opacity: 1;
+ }
+}
+
+@keyframes aksrt-spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+
+/* ============================================================
+ * 2. 骨架屏加载动画
+ * ============================================================ */
+.aksrt-skeleton {
+ background: linear-gradient(
+ 90deg,
+ rgba(121, 121, 121, 0.08) 25%,
+ rgba(121, 121, 121, 0.15) 37%,
+ rgba(121, 121, 121, 0.08) 63%
+ );
+ background-size: 400% 100%;
+ animation: aksrt-skeleton-shimmer 1.5s ease infinite;
+ border-radius: 4px;
+}
+
+.aksrt-skeleton--image {
+ height: 0;
+ padding-bottom: 66.67%; /* 3:2 aspect ratio */
+}
+
+.aksrt-skeleton--avatar {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+}
+
+.aksrt-skeleton--title {
+ height: 22px;
+ width: 80%;
+}
+
+.aksrt-skeleton--text {
+ height: 16px;
+ width: 100%;
+}
+
+.aksrt-skeleton--text-short {
+ height: 16px;
+ width: 60%;
+}
+
+.aksrt-skeleton--button {
+ height: 36px;
+ width: 100px;
+ border-radius: 8px;
+}
+
+@keyframes aksrt-skeleton-shimmer {
+ 0% { background-position: 100% 50%; }
+ 100% { background-position: 0 50%; }
+}
+
+/* 骨架屏组合:文章卡片骨架 */
+.aksrt-skeleton-card {
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ border-radius: 12px;
+ overflow: hidden;
+ padding: 0;
+}
+
+.aksrt-skeleton-card .aksrt-skeleton--image {
+ border-radius: 0;
+}
+
+.aksrt-skeleton-card__body {
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+/* ============================================================
+ * 3. 悬停交互动效
+ * ============================================================ */
+
+/* 卡片放大 */
+.aksrt-hover-zoom {
+ transition: transform 0.3s ease;
+}
+
+.aksrt-hover-zoom:hover {
+ transform: scale(1.02);
+}
+
+/* 卡片轻微放大 */
+.aksrt-hover-zoom-sm {
+ transition: transform 0.3s ease;
+}
+
+.aksrt-hover-zoom-sm:hover {
+ transform: scale(1.02);
+}
+
+/* 悬停显示内容 */
+.aksrt-hover-show {
+ position: relative;
+}
+
+.aksrt-hover-show__content {
+ position: absolute;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(6px);
+ transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
+ z-index: 10;
+}
+
+.aksrt-hover-show:hover .aksrt-hover-show__content {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+/* 关闭按钮旋转 */
+.aksrt-ic-close {
+ transition: transform 0.3s;
+ cursor: pointer;
+}
+
+.aksrt-ic-close:hover {
+ transform: rotate(270deg);
+}
+
+/* 图片悬停缩放(缩略图容器) */
+.aksrt-hover-zoom-img img {
+ transition: transform 0.3s ease;
+}
+
+.aksrt-hover-zoom-img:hover img {
+ transform: scale(1.02);
+}
+
+.aksrt-hover-zoom-img-sm img {
+ transition: transform 0.3s ease;
+}
+
+.aksrt-hover-zoom-img-sm:hover img {
+ transform: scale(1.02);
+}
+
+/* 按钮悬停上浮 */
+.aksrt-hover-lift {
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.aksrt-hover-lift:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+/* ============================================================
+ * 4. 暗色模式过渡 (View Transitions API)
+ * ============================================================ */
+::view-transition-old(root),
+::view-transition-new(root) {
+ animation: none;
+ mix-blend-mode: normal;
+}
+
+.dark::view-transition-old(root) {
+ z-index: 1;
+}
+
+.dark::view-transition-new(root) {
+ z-index: 2147483646;
+}
+
+::view-transition-old(root) {
+ z-index: 2147483646;
+}
+
+::view-transition-new(root) {
+ z-index: 1;
+}
+
+/* backdrop-filter 不支持时的降级 */
+@supports not ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(20px))) {
+ :root {
+ --aksrt-blur-bg: #ffffff;
+ }
+
+ .dark {
+ --aksrt-blur-bg: var(--surface-1);
+ }
+
+ .aksrt-toast {
+ backdrop-filter: none;
+ -webkit-backdrop-filter: none;
+ }
+}
+
+/* ============================================================
+ * 5. 滚动方向感知
+ * ============================================================ */
+
+/* 向下滚动时隐藏导航栏 */
+body.aksrt-scroll-down .site-nav.nav-scroll-hide {
+ transform: translateY(-100%);
+ transition: transform 0.3s ease;
+}
+
+body.aksrt-scroll-up .site-nav.nav-scroll-hide {
+ transform: translateY(0);
+ transition: transform 0.3s ease;
+}
+
+/* 滚动时隐藏浮动按钮 */
+body.aksrt-scrolling .aksrt-floating-right.scrolling-hide {
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.2s;
+}
+
+/* body-scroll 状态类 */
+body.aksrt-body-scroll .aksrt-show-on-scroll {
+ opacity: 1;
+ visibility: visible;
+}
+
+.aksrt-show-on-scroll {
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s, visibility 0.3s;
+}
+
+/* ============================================================
+ * 6. 图片灯箱
+ * ============================================================ */
+.aksrt-lightbox {
+ position: fixed;
+ inset: 0;
+ z-index: 9999;
+ background: rgba(0, 0, 0, 0.85);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s, visibility 0.3s;
+ cursor: zoom-out;
+}
+
+.aksrt-lightbox.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.aksrt-lightbox__img {
+ max-width: 90vw;
+ max-height: 85vh;
+ object-fit: contain;
+ border-radius: 4px;
+ transform: scale(0.9);
+ transition: transform 0.3s;
+ cursor: default;
+}
+
+.aksrt-lightbox.is-open .aksrt-lightbox__img {
+ transform: scale(1);
+}
+
+.aksrt-lightbox__close {
+ position: absolute;
+ top: 16px;
+ right: 16px;
+ width: 36px;
+ height: 36px;
+ border: none;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.15);
+ color: #fff;
+ font-size: 20px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.aksrt-lightbox__close:hover {
+ background: rgba(255, 255, 255, 0.3);
+}
+
+.aksrt-lightbox__caption {
+ position: absolute;
+ bottom: 16px;
+ left: 50%;
+ transform: translateX(-50%);
+ color: rgba(255, 255, 255, 0.8);
+ font-size: 14px;
+ text-align: center;
+ max-width: 80%;
+}
+
+.aksrt-lightbox__nav {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 48px;
+ height: 48px;
+ border: none;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.1);
+ color: #fff;
+ font-size: 24px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.aksrt-lightbox__nav:hover {
+ background: rgba(255, 255, 255, 0.25);
+}
+
+.aksrt-lightbox__nav--prev {
+ left: 16px;
+}
+
+.aksrt-lightbox__nav--next {
+ right: 16px;
+}
+
+.aksrt-lightbox__counter {
+ position: absolute;
+ top: 16px;
+ left: 16px;
+ color: rgba(255, 255, 255, 0.7);
+ font-size: 14px;
+}
+
+.aksrt-lightbox__download {
+ position: absolute;
+ top: 16px;
+ right: 64px;
+ width: 40px;
+ height: 40px;
+ border: none;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.15);
+ color: #fff;
+ font-size: 18px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.aksrt-lightbox__download:hover {
+ background: rgba(255, 255, 255, 0.3);
+}
+
+/* 可缩放图片的光标 */
+.aksrt-cursor-zoom-in {
+ cursor: zoom-in;
+}
+
+/* ============================================================
+ * 7. 文章封面轮播
+ * ============================================================ */
+.single-cover-slider {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+ border-radius: var(--radius-lg, 8px);
+}
+
+.single-cover-slider .swiper-slide {
+ position: relative;
+ overflow: hidden;
+}
+
+.single-cover-slider__img {
+ width: 100%;
+ height: 400px;
+ object-fit: cover;
+ display: block;
+}
+
+.single-cover-slider__overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.6) 100%);
+ pointer-events: none;
+}
+
+.single-cover-slider__content {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: 24px;
+ color: #fff;
+ z-index: 2;
+}
+
+.single-cover-slider__title {
+ margin: 0 0 8px;
+ font-size: 24px;
+ font-weight: 700;
+ text-shadow: 0 1px 3px rgba(0,0,0,0.3);
+}
+
+.single-cover-slider__meta {
+ display: flex;
+ gap: 16px;
+ font-size: 13px;
+ opacity: 0.9;
+}
+
+.single-cover-slider__pagination {
+ position: absolute;
+ bottom: 12px;
+ right: 16px;
+ z-index: 3;
+}
+
+.single-cover-slider__pagination .swiper-pagination-bullet {
+ background: rgba(255,255,255,0.6);
+ opacity: 1;
+}
+
+.single-cover-slider__pagination .swiper-pagination-bullet-active {
+ background: #fff;
+}
+
+.single-cover-slider__prev,
+.single-cover-slider__next {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ z-index: 3;
+ width: 40px;
+ height: 40px;
+ border: none;
+ border-radius: 50%;
+ background: rgba(0,0,0,0.3);
+ color: #fff;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.single-cover-slider__prev:hover,
+.single-cover-slider__next:hover {
+ background: rgba(0,0,0,0.5);
+}
+
+.single-cover-slider__prev { left: 12px; }
+.single-cover-slider__next { right: 12px; }
+
+@media (max-width: 640px) {
+ .single-cover-slider__img {
+ height: 240px;
+ }
+ .single-cover-slider__title {
+ font-size: 18px;
+ }
+}
+
+/* ============================================================
+ * 8. 打赏按钮
+ * ============================================================ */
+.action-btn--reward {
+ position: relative;
+}
+
+.action-btn--reward.is-active {
+ color: var(--color-warning, #F59E0B);
+}
+
+.reward-modal {
+ position: fixed;
+ inset: 0;
+ z-index: 99999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s, visibility 0.3s;
+}
+
+.reward-modal.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.reward-modal__overlay {
+ position: absolute;
+ inset: 0;
+ background: rgba(0,0,0,0.5);
+}
+
+.reward-modal__card {
+ position: relative;
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-lg, 8px);
+ padding: 32px;
+ max-width: 360px;
+ width: 90%;
+ text-align: center;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.15);
+ z-index: 1;
+}
+
+.reward-modal__title {
+ margin: 0 0 8px;
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.reward-modal__desc {
+ margin: 0 0 20px;
+ font-size: 14px;
+ color: var(--color-ink-3);
+}
+
+.reward-modal__qr {
+ width: 200px;
+ height: 200px;
+ margin: 0 auto 16px;
+ border-radius: var(--radius, 10px);
+ overflow: hidden;
+}
+
+.reward-modal__qr img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+.reward-modal__close {
+ position: absolute;
+ top: 12px;
+ right: 12px;
+ width: 32px;
+ height: 32px;
+ border: none;
+ border-radius: 50%;
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-ink-3);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.reward-modal__close:hover {
+ background: var(--surface-3, #ECEEF1);
+}
+
+/* ============================================================
+ * 9. 公告跑马灯 Widget
+ * ============================================================ */
+.aksrt-announcement {
+ position: relative;
+ overflow: hidden;
+ padding: 10px 12px;
+ background: var(--surface-2, #F4F5F7);
+ border-radius: var(--radius, 10px);
+}
+
+.aksrt-announcement__icon {
+ position: absolute;
+ left: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: var(--color-primary, var(--color-primary));
+ font-size: 14px;
+ z-index: 1;
+}
+
+.aksrt-announcement__track {
+ margin-left: 24px;
+ overflow: hidden;
+ height: 20px;
+}
+
+.aksrt-announcement__list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ animation: aksrt-marquee 10s linear infinite;
+}
+
+.aksrt-announcement__item {
+ height: 20px;
+ line-height: 20px;
+ font-size: 13px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.aksrt-announcement__item a {
+ color: var(--color-ink-2);
+ text-decoration: none;
+}
+
+.aksrt-announcement__item a:hover {
+ color: var(--color-primary, var(--color-primary));
+}
+
+@keyframes aksrt-marquee {
+ 0% { transform: translateY(0); }
+ 100% { transform: translateY(-100%); }
+}
+
+.aksrt-announcement:hover .aksrt-announcement__list {
+ animation-play-state: paused;
+}
+
+/* ============================================================
+ * 10. 用户卡片 Widget
+ * ============================================================ */
+.aksrt-user-card {
+ text-align: center;
+ padding: 20px;
+}
+
+.aksrt-user-card__avatar {
+ width: 72px;
+ height: 72px;
+ border-radius: 50%;
+ margin: 0 auto 12px;
+ overflow: hidden;
+ border: 3px solid var(--color-primary-soft, rgba(136,171,218,0.1));
+}
+
+.aksrt-user-card__avatar img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.aksrt-user-card__name {
+ margin: 0 0 4px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-user-card__name a {
+ color: inherit;
+ text-decoration: none;
+}
+
+.aksrt-user-card__name a:hover {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-user-card__bio {
+ margin: 0 0 12px;
+ font-size: 13px;
+ color: var(--color-ink-3);
+ line-height: 1.5;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.aksrt-user-card__stats {
+ display: flex;
+ justify-content: center;
+ gap: 20px;
+ margin-bottom: 16px;
+}
+
+.aksrt-user-card__stat {
+ text-align: center;
+}
+
+.aksrt-user-card__stat-value {
+ display: block;
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-user-card__stat-label {
+ font-size: 12px;
+ color: var(--color-ink-4, #8A8F98);
+}
+
+.aksrt-user-card__actions {
+ display: flex;
+ gap: 8px;
+ justify-content: center;
+}
+
+.aksrt-user-card__btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 16px;
+ border-radius: var(--radius, 10px);
+ font-size: 13px;
+ text-decoration: none;
+ transition: all 0.15s;
+}
+
+.aksrt-user-card__btn--primary {
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+}
+
+.aksrt-user-card__btn--primary:hover {
+ opacity: 0.85;
+ color: #fff;
+}
+
+.aksrt-user-card__btn--ghost {
+ border: 1px solid var(--color-line);
+ color: var(--color-ink-2);
+}
+
+.aksrt-user-card__btn--ghost:hover {
+ border-color: var(--color-primary, var(--color-primary));
+ color: var(--color-primary, var(--color-primary));
+}
+
+/* ============================================================
+ * 11. 滚动触发动画初始状态
+ * ============================================================ */
+[data-aksrt-animate] {
+ will-change: opacity, transform;
+}
+
+/* ============================================================
+ * 12. 粘性侧栏
+ * ============================================================ */
+[data-aksrt-sticky] {
+ will-change: transform;
+}
+
+/* ============================================================
+ * 13. 用户排行榜 Widget
+ * ============================================================ */
+.aksrt-user-ranking {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.aksrt-user-ranking__item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 0;
+ border-bottom: 1px solid var(--color-line-soft, #F0F1F3);
+}
+
+.aksrt-user-ranking__item:last-child {
+ border-bottom: none;
+}
+
+.aksrt-user-ranking__rank {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ border-radius: 6px;
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-ink-3);
+ font-size: 12px;
+ font-weight: 600;
+ flex-shrink: 0;
+}
+
+.aksrt-user-ranking__item--top:nth-child(1) .aksrt-user-ranking__rank {
+ background: #FFD700;
+ color: #fff;
+}
+
+.aksrt-user-ranking__item--top:nth-child(2) .aksrt-user-ranking__rank {
+ background: #C0C0C0;
+ color: #fff;
+}
+
+.aksrt-user-ranking__item--top:nth-child(3) .aksrt-user-ranking__rank {
+ background: #CD7F32;
+ color: #fff;
+}
+
+.aksrt-user-ranking__avatar {
+ flex-shrink: 0;
+}
+
+.aksrt-user-ranking__avatar img {
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.aksrt-user-ranking__name {
+ flex: 1;
+ min-width: 0;
+ font-size: 14px;
+ color: var(--color-ink);
+ text-decoration: none;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.aksrt-user-ranking__name:hover {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-user-ranking__value {
+ font-size: 12px;
+ color: var(--color-ink-4, #8A8F98);
+ white-space: nowrap;
+}
+
+/* ============================================================
+ * 14. 图文封面卡片 Widget
+ * ============================================================ */
+.aksrt-cover-cards {
+ display: grid;
+ grid-template-columns: repeat(var(--cols, 2), 1fr);
+ gap: 12px;
+}
+
+.aksrt-cover-card {
+ position: relative;
+ border-radius: var(--radius-lg, 8px);
+ overflow: hidden;
+ min-height: 160px;
+ display: flex;
+ align-items: flex-end;
+ transition: transform 0.3s, box-shadow 0.3s;
+}
+
+.aksrt-cover-card:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
+}
+
+.aksrt-cover-card__bg {
+ position: absolute;
+ inset: 0;
+}
+
+.aksrt-cover-card__bg img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.5s;
+}
+
+.aksrt-cover-card:hover .aksrt-cover-card__bg img {
+ transform: scale(1.02);
+}
+
+.aksrt-cover-card__overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, rgba(0,0,0,0) 30%, rgba(0,0,0,0.6) 100%);
+}
+
+.aksrt-cover-card__content {
+ position: relative;
+ z-index: 1;
+ padding: 16px;
+ width: 100%;
+}
+
+.aksrt-cover-card__link {
+ text-decoration: none;
+ color: inherit;
+ display: block;
+}
+
+.aksrt-cover-card__title {
+ margin: 0 0 4px;
+ font-size: 16px;
+ font-weight: 600;
+ color: #fff;
+ text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
+}
+
+.aksrt-cover-card__desc {
+ margin: 0;
+ font-size: 13px;
+ color: rgba(255, 255, 255, 0.85);
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+/* ============================================================
+ * 15. 视频播放器 Widget
+ * ============================================================ */
+.aksrt-video-widget {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+ border-radius: var(--radius, 10px);
+ background: #000;
+}
+
+.aksrt-video-widget iframe,
+.aksrt-video-widget video {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: none;
+}
+
+/* ============================================================
+ * 16. 表单输入浮动标签
+ * ============================================================ */
+.aksrt-float-label {
+ position: relative;
+}
+
+.aksrt-float-label__input {
+ width: 100%;
+ padding: 14px 12px 6px;
+ font-size: 14px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink);
+ transition: border-color 0.2s;
+}
+
+.aksrt-float-label__input:focus {
+ outline: none;
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-float-label__label {
+ position: absolute;
+ left: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ font-size: 14px;
+ color: var(--color-ink-4, #8A8F98);
+ pointer-events: none;
+ transition: all 0.2s ease;
+}
+
+.aksrt-float-label__input:focus + .aksrt-float-label__label,
+.aksrt-float-label__input:not(:placeholder-shown) + .aksrt-float-label__label {
+ top: 8px;
+ transform: translateY(0);
+ font-size: 11px;
+ color: var(--color-primary, var(--color-primary));
+}
+
+/* ============================================================
+ * 17. 视差滚动层
+ * ============================================================ */
+[data-aksrt-parallax] {
+ will-change: transform;
+ transition: transform 0.1s linear;
+}
+
+/* ============================================================
+ * 18. 签到日历可视化
+ * ============================================================ */
+.aksrt-signin-calendar__grid {
+ display: grid;
+ grid-template-columns: repeat(7, 1fr);
+ gap: 4px;
+}
+
+.aksrt-signin-calendar__day {
+ aspect-ratio: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 6px;
+ background: var(--surface-2, #F4F5F7);
+ font-size: 12px;
+ color: var(--color-ink-3);
+ transition: all 0.2s;
+}
+
+.aksrt-signin-calendar__day.is-signed {
+ background: var(--color-success, #10B981);
+ color: #fff;
+}
+
+.aksrt-signin-calendar__day.is-today {
+ border: 2px solid var(--color-primary, var(--color-primary));
+}
+
+.aksrt-signin-calendar__day.is-signed.is-today {
+ background: var(--color-primary, var(--color-primary));
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.uc-signin-calendar__title {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ margin: 0 0 10px;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink-2);
+}
+
+.uc-signin-calendar__title i {
+ color: var(--color-primary, var(--color-primary));
+}
+
+/* ============================================================
+ * 19. VIP 等级标识
+ * ============================================================ */
+.aksrt-vip-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 2px 8px;
+ border-radius: var(--radius-pill, 999px);
+ font-size: 11px;
+ font-weight: 600;
+}
+
+.aksrt-vip-badge--gold {
+ background: linear-gradient(135deg, #FFD700, #FFA500);
+ color: #fff;
+}
+
+.aksrt-vip-badge--silver {
+ background: linear-gradient(135deg, #C0C0C0, #A8A8A8);
+ color: #fff;
+}
+
+.aksrt-vip-badge--bronze {
+ background: linear-gradient(135deg, #CD7F32, #A0522D);
+ color: #fff;
+}
+
+/* ============================================================
+ * 20. 用户等级进度条
+ * ============================================================ */
+.aksrt-level-bar {
+ position: relative;
+ height: 8px;
+ background: var(--surface-2, #F4F5F7);
+ border-radius: 4px;
+ overflow: hidden;
+}
+
+.aksrt-level-bar__fill {
+ height: 100%;
+ background: linear-gradient(90deg, var(--color-primary, var(--color-primary)), var(--color-primary-active, #5A85BD));
+ border-radius: 4px;
+ transition: width 0.5s ease;
+}
+
+.aksrt-level-bar__label {
+ position: absolute;
+ right: 0;
+ top: -18px;
+ font-size: 11px;
+ color: var(--color-ink-4, #8A8F98);
+}
+
+/* ============================================================
+ * 21. 弹窗登录/注册
+ * ============================================================ */
+.aksrt-modal-auth {
+ position: fixed;
+ inset: 0;
+ z-index: 99999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s, visibility 0.3s;
+}
+
+.aksrt-modal-auth.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.aksrt-modal-auth__overlay {
+ position: absolute;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.5);
+ backdrop-filter: blur(4px);
+ -webkit-backdrop-filter: blur(4px);
+}
+
+.aksrt-modal-auth__card {
+ position: relative;
+ background: var(--main-bg-color, #fff);
+ border-radius: var(--main-radius, 8px);
+ padding: 32px;
+ max-width: 400px;
+ width: 90%;
+ max-height: 90vh;
+ overflow-y: auto;
+ box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
+ z-index: 1;
+ transform: scale(0.9);
+ transition: transform 0.5s cubic-bezier(0.32, 0.85, 0.45, 1.18);
+}
+
+.aksrt-modal-auth.is-open .aksrt-modal-auth__card {
+ transform: scale(1);
+}
+
+.aksrt-modal-auth__close {
+ position: absolute;
+ top: 12px;
+ right: 12px;
+ width: 36px;
+ height: 36px;
+ border: none;
+ border-radius: 50%;
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-ink-3);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+ font-size: 16px;
+}
+
+.aksrt-modal-auth__close:hover {
+ background: var(--surface-3, #ECEEF1);
+}
+
+.aksrt-modal-auth__header {
+ text-align: center;
+ margin-bottom: 24px;
+}
+
+.aksrt-modal-auth__logo {
+ width: 56px;
+ height: 56px;
+ border-radius: var(--radius);
+ background: linear-gradient(135deg, var(--color-primary, var(--color-primary)), var(--color-primary-active, #5A85BD));
+ color: #fff;
+ font-size: 22px;
+ font-weight: 700;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin: 0 auto 12px;
+}
+
+.aksrt-modal-auth__title {
+ margin: 0;
+ font-size: 20px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+/* Tabs */
+.aksrt-modal-auth__tabs {
+ display: flex;
+ border-bottom: 1px solid var(--color-line);
+ margin-bottom: 20px;
+}
+
+.aksrt-modal-auth__tab {
+ flex: 1;
+ padding: 10px;
+ border: none;
+ background: none;
+ font-size: 15px;
+ font-weight: 500;
+ color: var(--color-ink-3);
+ cursor: pointer;
+ position: relative;
+ transition: color 0.2s;
+}
+
+.aksrt-modal-auth__tab.is-active {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-modal-auth__tab.is-active::after {
+ content: '';
+ position: absolute;
+ bottom: -1px;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: var(--color-primary, var(--color-primary));
+}
+
+/* Panels */
+.aksrt-modal-auth__panel {
+ display: none;
+}
+
+.aksrt-modal-auth__panel.is-active {
+ display: block;
+}
+
+/* Form */
+.aksrt-modal-auth__form {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.aksrt-modal-auth__error {
+ padding: 10px 14px;
+ border-radius: 8px;
+ background: rgba(239, 68, 68, 0.08);
+ color: var(--color-error, #EF4444);
+ font-size: 13px;
+ line-height: 1.5;
+}
+
+.aksrt-modal-auth__error a {
+ color: var(--color-primary, var(--color-primary));
+ text-decoration: underline;
+}
+
+.aksrt-modal-auth__field label {
+ display: block;
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--color-ink-2);
+ margin-bottom: 6px;
+}
+
+.aksrt-modal-auth__field input {
+ width: 100%;
+ padding: 10px 14px;
+ border: 1px solid var(--color-line);
+ border-radius: 10px;
+ font-size: 14px;
+ color: var(--color-ink);
+ background: var(--surface-1, #fff);
+ transition: border-color 0.2s;
+ box-sizing: border-box;
+}
+
+.aksrt-modal-auth__field input:focus {
+ outline: none;
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-modal-auth__field input::placeholder {
+ color: var(--color-ink-4, #8A8F98);
+}
+
+.aksrt-modal-auth__pass-wrap {
+ position: relative;
+}
+
+.aksrt-modal-auth__pass-wrap input {
+ padding-right: 44px;
+}
+
+.aksrt-modal-auth__pass-toggle {
+ position: absolute;
+ right: 8px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 32px;
+ height: 32px;
+ border: none;
+ background: none;
+ color: var(--color-ink-4, #8A8F98);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 6px;
+}
+
+.aksrt-modal-auth__pass-toggle:hover {
+ background: var(--surface-2, #F4F5F7);
+}
+
+.aksrt-modal-auth__actions {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.aksrt-modal-auth__link {
+ font-size: 13px;
+ color: var(--color-primary, var(--color-primary));
+ text-decoration: none;
+}
+
+.aksrt-modal-auth__link:hover {
+ text-decoration: underline;
+}
+
+.aksrt-modal-auth__submit {
+ width: 100%;
+ padding: 12px;
+ border: none;
+ border-radius: 10px;
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+ font-size: 15px;
+ font-weight: 600;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ transition: opacity 0.2s;
+}
+
+.aksrt-modal-auth__submit:hover {
+ opacity: 0.85;
+}
+
+.aksrt-modal-auth__submit:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
+/* Divider */
+.aksrt-modal-auth__divider {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin: 20px 0;
+ color: var(--color-ink-4, #8A8F98);
+ font-size: 12px;
+}
+
+.aksrt-modal-auth__divider::before,
+.aksrt-modal-auth__divider::after {
+ content: '';
+ flex: 1;
+ height: 1px;
+ background: var(--color-line);
+}
+
+/* OAuth */
+.aksrt-modal-auth__oauth {
+ display: flex;
+ justify-content: center;
+ gap: 12px;
+}
+
+.aksrt-modal-auth__oauth-btn {
+ width: 44px;
+ height: 44px;
+ border: 1px solid var(--color-line);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--color-ink-2);
+ font-size: 18px;
+ text-decoration: none;
+ transition: all 0.2s;
+}
+
+.aksrt-modal-auth__oauth-btn:hover {
+ border-color: var(--color-primary, var(--color-primary));
+ color: var(--color-primary, var(--color-primary));
+ background: var(--color-primary-soft, rgba(136, 171, 218, 0.1));
+}
+
+/* Footer */
+.aksrt-modal-auth__footer {
+ text-align: center;
+ margin-top: 20px;
+ font-size: 13px;
+ color: var(--color-ink-3);
+}
+
+.aksrt-modal-auth__switch {
+ border: none;
+ background: none;
+ color: var(--color-primary, var(--color-primary));
+ cursor: pointer;
+ font-size: 13px;
+ font-weight: 500;
+ padding: 0;
+}
+
+.aksrt-modal-auth__switch:hover {
+ text-decoration: underline;
+}
+
+/* Dark mode */
+.theme-dark .aksrt-modal-auth__card,
+html.dark .aksrt-modal-auth__card {
+ background: #1e1e2e;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.theme-dark .aksrt-modal-auth__field input,
+html.dark .aksrt-modal-auth__field input {
+ background: #2a2a3a;
+ border-color: rgba(255, 255, 255, 0.15);
+ color: #e0e0e0;
+}
+
+.theme-dark .aksrt-modal-auth__close,
+html.dark .aksrt-modal-auth__close {
+ background: #2a2a3a;
+}
+
+/* Responsive */
+@media (max-width: 480px) {
+ .aksrt-modal-auth__card {
+ padding: 24px 20px;
+ border-radius: 12px;
+ }
+
+ .aksrt-modal-auth__logo {
+ width: 48px;
+ height: 48px;
+ font-size: 18px;
+ }
+
+ .aksrt-modal-auth__title {
+ font-size: 18px;
+ }
+}
+
+/* ============================================================
+ * 22. 语言切换器
+ * ============================================================ */
+.aksrt-lang-switch {
+ position: relative;
+}
+
+.aksrt-lang-switch__toggle {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 12px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-2);
+ font-size: 13px;
+ cursor: pointer;
+ transition: border-color 0.2s;
+ width: 100%;
+}
+
+.aksrt-lang-switch__toggle:hover {
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-lang-switch__toggle img {
+ border-radius: 2px;
+}
+
+.aksrt-lang-switch__dropdown {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ margin: 4px 0 0;
+ padding: 4px;
+ list-style: none;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+ z-index: 100;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(4px);
+ transition: all 0.2s;
+}
+
+.aksrt-lang-switch:hover .aksrt-lang-switch__dropdown,
+.aksrt-lang-switch__toggle:focus + .aksrt-lang-switch__dropdown {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.aksrt-lang-switch__item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 10px;
+ border-radius: 6px;
+ font-size: 13px;
+ color: var(--color-ink-2);
+ text-decoration: none;
+ transition: background 0.15s;
+}
+
+.aksrt-lang-switch__item:hover {
+ background: var(--surface-2, #F4F5F7);
+}
+
+.aksrt-lang-switch__item.is-active {
+ color: var(--color-primary, var(--color-primary));
+ font-weight: 600;
+}
+
+.aksrt-lang-switch__item img {
+ border-radius: 2px;
+}
+
+/* 国旗模式 */
+.aksrt-lang-switch--flags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.aksrt-lang-switch__flag {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 24px;
+ border: 2px solid transparent;
+ border-radius: 4px;
+ overflow: hidden;
+ transition: border-color 0.2s;
+ text-decoration: none;
+}
+
+.aksrt-lang-switch__flag:hover {
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-lang-switch__flag.is-active {
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-lang-switch__flag img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.aksrt-lang-switch__flag span {
+ font-size: 10px;
+ font-weight: 600;
+ color: var(--color-ink-3);
+}
+
+/* Dark mode */
+.theme-dark .aksrt-lang-switch__toggle,
+html.dark .aksrt-lang-switch__toggle {
+ background: #2a2a3a;
+ border-color: rgba(255, 255, 255, 0.15);
+}
+
+.theme-dark .aksrt-lang-switch__dropdown,
+html.dark .aksrt-lang-switch__dropdown {
+ background: #2a2a3a;
+ border-color: rgba(255, 255, 255, 0.15);
+}
+
+/* ============================================================
+ * 响应式
+ * ============================================================ */
+@media (max-width: 640px) {
+ .aksrt-toast-container {
+ right: 8px;
+ left: 8px;
+ max-width: none;
+ }
+
+ .aksrt-lightbox__nav {
+ width: 36px;
+ height: 36px;
+ font-size: 18px;
+ }
+
+ .single-cover-slider__img {
+ height: 240px;
+ }
+
+ .single-cover-slider__title {
+ font-size: 18px;
+ }
+
+ .reward-modal__card {
+ padding: 24px;
+ }
+
+ .reward-modal__qr {
+ width: 160px;
+ height: 160px;
+ }
+
+ .aksrt-cover-cards {
+ grid-template-columns: 1fr;
+ }
+
+ .aksrt-cover-card {
+ min-height: 140px;
+ }
+}
+
+/* ============================================================
+ * 13. 无障碍:prefers-reduced-motion
+ * 用户系统设置"减少动画"时,禁用所有非必要动效
+ * ============================================================ */
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+
+ .aksrt-skeleton {
+ animation: none !important;
+ }
+
+ .aksrt-toast {
+ animation: none !important;
+ }
+
+ [data-aksrt-animate] {
+ opacity: 1 !important;
+ transform: none !important;
+ }
+}
+
+/* ============================================================
+ * 14. 图片懒加载 blur-to-sharp 过渡
+ * 模仿 zibll 的 lazy_blur 效果
+ * ============================================================ */
+img.lazyload,
+img.lazyloaded,
+img[data-src] {
+ transition: filter 0.6s var(--ease), opacity 0.4s var(--ease);
+}
+
+img.lazyload,
+img[data-src] {
+ filter: blur(5px);
+ opacity: 0.7;
+}
+
+img.lazyloaded {
+ filter: blur(0);
+ opacity: 1;
+}
+
+/* ============================================================
+ * 15. 错误反馈 shake 动画
+ * 表单验证失败时的水平抖动效果
+ * ============================================================ */
+@keyframes aksrtShake {
+ 0%, 100% { transform: translateX(0); }
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
+ 20%, 40%, 60%, 80% { transform: translateX(4px); }
+}
+
+.aksrt-shake {
+ animation: aksrtShake 0.4s ease-in-out;
+}
+
+/* 应用于 Naive UI 表单验证 */
+.n-form-item--error .n-input,
+.n-form-item--error .n-select,
+.n-form-item--error .n-input-number {
+ animation: aksrtShake 0.3s ease-in-out;
+}
+
+/* ============================================================
+ * 16. FPS 加速模式:低端设备禁用 backdrop-filter
+ * 模仿 zibll 的 body.fps-accelerat 模式
+ * ============================================================ */
+body.fps-accelerat .site-nav,
+body.fps-accelerat .footer-tabbar,
+body.fps-accelerat .float-right .float-btn,
+body.fps-accelerat .aksrt-blur-bg {
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
+}
+
+/* 模态框内禁用 backdrop-filter 避免渲染冲突 */
+body.modal-open .site-nav,
+body.dialog-open .site-nav {
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
+}
+
+/* ============================================================
+ * 17. .blur-bg 通用工具类
+ * 模仿 zibll 的 .blur-bg,可在任意元素上应用毛玻璃效果
+ * ============================================================ */
+.aksrt-blur-bg {
+ background: var(--blur-bg);
+ backdrop-filter: saturate(5) blur(20px);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+}
+
+/* ============================================================
+ * 18. 滚动触发动画延迟支持
+ * data-aksrt-delay 属性控制入场延迟
+ * ============================================================ */
+[data-aksrt-animate][data-aksrt-delay="1"] { transition-delay: 0.1s; }
+[data-aksrt-animate][data-aksrt-delay="2"] { transition-delay: 0.2s; }
+[data-aksrt-animate][data-aksrt-delay="3"] { transition-delay: 0.3s; }
+[data-aksrt-animate][data-aksrt-delay="4"] { transition-delay: 0.4s; }
+[data-aksrt-animate][data-aksrt-delay="5"] { transition-delay: 0.5s; }
+
+/* ============================================================
+ * 19. 全站动效节奏统一
+ * 模仿 zibll 的统一 hover / slide / blur / drawer 语言
+ * ============================================================ */
+
+/* --- 全局过渡基线 --- */
+a, button, input, select, textarea {
+ transition: border-color var(--dur-fast) var(--ease),
+ box-shadow var(--dur-fast) var(--ease),
+ background-color var(--dur-fast) var(--ease),
+ color var(--dur-fast) var(--ease);
+}
+
+/* --- 卡片 hover 统一 --- */
+.post-card, .widget, .aksrt-theme-box, .theme-box,
+.comment-body, .friend-card, .special-card,
+.resource-download-box, .resource-meta-box {
+ transition: box-shadow var(--dur) var(--ease),
+ border-color var(--dur) var(--ease),
+ transform var(--dur) var(--ease);
+}
+
+.post-card:hover, .widget:hover, .friend-card:hover, .special-card:hover {
+ box-shadow: var(--shadow);
+ transform: translateY(-2px);
+}
+
+/* --- 按钮 hover 统一 --- */
+.btn-primary, .btn-outline, .btn-lg, .btn-sm,
+.n-button, .aksrt-button {
+ transition: all var(--dur-fast) var(--ease);
+}
+
+.btn-primary:hover, .n-button--primary-type:hover {
+ opacity: 0.85;
+}
+
+.btn-primary:active, .n-button--primary-type:active {
+ opacity: 1;
+}
+
+/* --- 输入框 focus 统一 --- */
+input:focus, textarea:focus, select:focus,
+.n-input--focus, .n-select--focus {
+ box-shadow: var(--focus-ring);
+ transition: box-shadow var(--dur-fast) var(--ease);
+}
+
+/* --- 抽屉/模态框动效统一 --- */
+.n-drawer, .n-modal, .n-dialog {
+ transition: all var(--dur) var(--ease-out);
+}
+
+.n-drawer-mask, .n-modal-mask, .n-dialog-mask {
+ transition: opacity var(--dur) var(--ease);
+}
+
+/* --- Tab 切换动效 --- */
+.n-tabs-tab, .nav-tab, .aksrt-tab {
+ transition: color var(--dur-fast) var(--ease),
+ border-color var(--dur-fast) var(--ease),
+ background-color var(--dur-fast) var(--ease);
+}
+
+/* --- 下拉菜单动效 --- */
+.n-dropdown-menu, .aksrt-dropdown {
+ transition: opacity var(--dur-fast) var(--ease),
+ transform var(--dur-fast) var(--ease-out);
+ transform-origin: top;
+}
+
+/* --- Toast 通知动效 --- */
+.aksrt-toast {
+ animation: aksrtToastIn 0.35s var(--ease-out) forwards;
+}
+
+.aksrt-toast--out {
+ animation: aksrtToastOut 0.3s var(--ease) forwards;
+}
+
+/* --- 骨架屏动效 --- */
+.aksrt-skeleton {
+ animation: aksrtSkeletonShimmer 1.5s infinite linear;
+ background: linear-gradient(90deg, var(--skeleton-base) 25%, var(--skeleton-shine) 50%, var(--skeleton-base) 75%);
+ background-size: 200% 100%;
+}
+
+/* --- 页面切换动效 --- */
+.fade-slide-enter-active,
+.fade-slide-leave-active {
+ transition: opacity var(--dur) var(--ease),
+ transform var(--dur) var(--ease);
+}
+
+.fade-slide-enter-from {
+ opacity: 0;
+ transform: translateY(8px);
+}
+
+.fade-slide-leave-to {
+ opacity: 0;
+ transform: translateY(-8px);
+}
+
+/* --- 导航栏滚动动效 --- */
+.site-nav {
+ transition: transform var(--dur) var(--ease),
+ background-color var(--dur) var(--ease),
+ box-shadow var(--dur) var(--ease);
+}
+
+.site-nav.aksrt-nav--hidden {
+ transform: translateY(-100%);
+}
+
+/* --- 浮层弹出动效 --- */
+@keyframes aksrtPopIn {
+ 0% { opacity: 0; transform: scale(0.95) translateY(-4px); }
+ 100% { opacity: 1; transform: scale(1) translateY(0); }
+}
+
+@keyframes aksrtPopOut {
+ 0% { opacity: 1; transform: scale(1) translateY(0); }
+ 100% { opacity: 0; transform: scale(0.95) translateY(-4px); }
+}
+
+.aksrt-popover, .aksrt-tooltip, .aksrt-dropdown-panel {
+ animation: aksrtPopIn var(--dur-fast) var(--ease-out) forwards;
+}
+
+/* --- 图片懒加载过渡 --- */
+img.lazyload, img.lazyloaded, img[data-src] {
+ transition: filter 0.6s var(--ease), opacity 0.4s var(--ease);
+}
+
+img.lazyload, img[data-src] {
+ filter: blur(5px);
+ opacity: 0.7;
+}
+
+img.lazyloaded {
+ filter: blur(0);
+ opacity: 1;
+}
+
+/* --- 滚动进度条动效 --- */
+.reading-progress-bar {
+ transition: width 0.1s linear;
+}
+
+/* --- 移动端抽屉动效 --- */
+@media (max-width: 767px) {
+ .n-drawer {
+ transition: transform var(--dur) var(--ease-out);
+ }
+
+ .site-nav .n-drawer-body {
+ transition: transform var(--dur) var(--ease-out);
+ }
+}
+
+/* --- 暗色模式切换动效 --- */
+html.dark {
+ transition: background-color 0.3s var(--ease),
+ color 0.3s var(--ease);
+}
+
+html.dark * {
+ transition: background-color 0.3s var(--ease),
+ border-color 0.3s var(--ease),
+ color 0.3s var(--ease),
+ box-shadow 0.3s var(--ease);
+}
+
+/* ============================================================
+ * 18. 合作伙伴无缝滚动 (marquee)
+ * ============================================================ */
+.aksrt-marquee {
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+}
+
+.aksrt-marquee__inner {
+ display: flex;
+ gap: 24px;
+ white-space: nowrap;
+ will-change: transform;
+}
+
+.aksrt-marquee__inner > * {
+ flex-shrink: 0;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .aksrt-marquee__inner {
+ animation: none !important;
+ transform: none !important;
+ }
+}
+
+/* ============================================================
+ * 19. 视频剧集切换按钮
+ * ============================================================ */
+.switch-video,
+.switch-iframe {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 14px;
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.1));
+ border-radius: var(--radius, 8px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-2, #4e5358);
+ font-size: 13px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.15s ease;
+ text-decoration: none;
+}
+
+.switch-video:hover,
+.switch-iframe:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.switch-video.is-active,
+.switch-iframe.is-active {
+ background: var(--color-primary);
+ border-color: var(--color-primary);
+ color: #fff;
+}
+
+/* ============================================================
+ * 20. 一言轮播组件
+ * ============================================================ */
+.aksrt-yiyan {
+ padding: 16px;
+ text-align: center;
+}
+
+.aksrt-yiyan__content {
+ min-height: 60px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+}
+
+.aksrt-yiyan__icon {
+ font-size: 20px;
+ color: var(--color-primary);
+ opacity: 0.6;
+}
+
+.aksrt-yiyan__text {
+ font-size: 14px;
+ line-height: 1.8;
+ color: var(--color-ink-2, #4e5358);
+ margin: 0;
+ transition: opacity 0.2s ease;
+ font-style: italic;
+}
+
+.aksrt-yiyan__from {
+ font-size: 12px;
+ color: var(--color-ink-4, #999);
+ margin: 0;
+}
+
+.aksrt-yiyan__dots {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ margin-top: 12px;
+}
+
+.aksrt-yiyan__dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: var(--color-line, rgba(50, 50, 50, 0.1));
+ transition: background 0.2s;
+}
+
+.aksrt-yiyan__dot.is-active {
+ background: var(--color-primary);
+ width: 16px;
+ border-radius: 3px;
+}
+
+/* ============================================================
+ * 底部弹出 Sheet — 对齐 zibll .modal.bottom
+ * ============================================================ */
+.aksrt-modal--bottom .aksrt-modal-auth__card,
+.modal.bottom .modal-dialog {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ max-width: 100%;
+ width: 100%;
+ border-radius: var(--main-radius, 8px) var(--main-radius, 8px) 0 0;
+ transform: translateY(110%);
+ transition: transform 0.4s;
+ margin-bottom: 0;
+ padding-bottom: env(safe-area-inset-bottom);
+}
+
+.aksrt-modal--bottom.is-open .aksrt-modal-auth__card,
+.modal.bottom.in .modal-dialog {
+ transform: translateY(0);
+}
+
+.aksrt-modal--bottom .aksrt-modal-auth__card,
+.modal.bottom .modal-dialog .modal-content {
+ box-shadow: 0 -10px 50px rgba(0, 0, 0, 0.15);
+}
diff --git a/assets/css/common/floating.css b/assets/css/common/floating.css
new file mode 100644
index 00000000..561ca3a8
--- /dev/null
+++ b/assets/css/common/floating.css
@@ -0,0 +1,452 @@
+/* ============================================================
+ AKSRT – Floating UI & Site Footer
+ ============================================================
+ Covers:
+ • .floating-toolbar – fixed action buttons (scroll-top,
+ font-size, sidebar toggle)
+ • .mobile-nav-overlay – full-screen drawer nav (mobile)
+ • .site-footer – footer grid + bottom bar
+ ============================================================ */
+
+
+/* ═══════════════════════════════════════════════════════════
+ FLOATING TOOLBAR
+ ═══════════════════════════════════════════════════════════ */
+
+.floating-toolbar {
+ position: fixed;
+ right: var(--space-5);
+ bottom: var(--space-8);
+ z-index: var(--z-floating);
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2);
+}
+
+/* ── Individual button ────────────────────────────────────── */
+.floating-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ background: var(--color-surface);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-full);
+ box-shadow: var(--shadow-md);
+ cursor: pointer;
+ color: var(--color-ink-4);
+ transition:
+ background var(--transition-fast),
+ color var(--transition-fast),
+ box-shadow var(--transition-fast),
+ transform var(--transition-fast);
+ padding: 0;
+}
+
+.floating-btn svg {
+ width: 18px;
+ height: 18px;
+ flex-shrink: 0;
+}
+
+.floating-btn:hover,
+.floating-btn:focus-visible {
+ background: var(--color-primary);
+ color: #fff;
+ border-color: var(--color-primary);
+ box-shadow: var(--shadow-lg);
+ transform: translateY(-2px);
+}
+
+.floating-btn:active {
+ transform: translateY(0);
+ box-shadow: var(--shadow-sm);
+}
+
+.floating-btn:focus-visible {
+ outline: 2px solid var(--color-primary);
+ outline-offset: 2px;
+}
+
+/* ── Scroll-to-top: hide until page is scrolled ───────────── */
+.floating-btn--top {
+ opacity: 0;
+ pointer-events: none;
+ transition:
+ opacity var(--transition-base),
+ background var(--transition-fast),
+ color var(--transition-fast),
+ box-shadow var(--transition-fast),
+ transform var(--transition-fast);
+}
+
+.floating-btn--top.is-visible {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+/* ── Mobile: smaller toolbar, stacked horizontally ───────── */
+@media (max-width: 767px) {
+ .floating-toolbar {
+ right: var(--space-4);
+ bottom: var(--space-6);
+ flex-direction: row; /* horizontal row on mobile */
+ }
+
+ .floating-btn {
+ width: 36px;
+ height: 36px;
+ }
+
+ .floating-btn svg {
+ width: 16px;
+ height: 16px;
+ }
+}
+
+
+/* ═══════════════════════════════════════════════════════════
+ MOBILE NAV OVERLAY
+ ═══════════════════════════════════════════════════════════ */
+
+.mobile-nav-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: var(--z-overlay);
+ background: rgba(0, 0, 0, 0.45);
+ opacity: 0;
+ visibility: hidden;
+ transition:
+ opacity var(--transition-base),
+ visibility var(--transition-base);
+ /* backdrop blur on supporting browsers */
+ backdrop-filter: blur(2px);
+ -webkit-backdrop-filter: blur(2px);
+}
+
+.mobile-nav-overlay.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+/* ── Drawer panel ─────────────────────────────────────────── */
+.mobile-nav-drawer {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: min(320px, 85vw);
+ height: 100%;
+ background: var(--color-surface);
+ box-shadow: var(--shadow-xl);
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+ padding: var(--space-6);
+ overflow-y: auto;
+ overscroll-behavior: contain;
+ transform: translateX(-100%);
+ transition: transform var(--transition-base);
+}
+
+.mobile-nav-overlay.is-open .mobile-nav-drawer {
+ transform: translateX(0);
+}
+
+/* ── Close button ─────────────────────────────────────────── */
+.mobile-nav-close {
+ align-self: flex-end;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ height: 36px;
+ background: var(--surface-page);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-full);
+ cursor: pointer;
+ color: var(--color-ink-4);
+ transition: background var(--transition-fast), color var(--transition-fast);
+ flex-shrink: 0;
+}
+
+.mobile-nav-close:hover {
+ background: var(--color-danger);
+ color: #fff;
+ border-color: var(--color-danger);
+}
+
+.mobile-nav-close svg {
+ width: 18px;
+ height: 18px;
+}
+
+/* ── Brand ────────────────────────────────────────────────── */
+.mobile-nav-brand {
+ padding-bottom: var(--space-4);
+ border-bottom: 1px solid var(--color-line);
+}
+
+.mobile-nav-brand a {
+ font-size: 1.125rem;
+ font-weight: 700;
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.mobile-nav-brand a:hover {
+ color: var(--color-primary);
+}
+
+/* ── Nav menu (WordPress-generated ul) ────────────────────── */
+.mobile-nav-menu {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-1);
+}
+
+.mobile-nav-menu li {
+ list-style: none;
+}
+
+.mobile-nav-menu a {
+ display: block;
+ padding: var(--space-2) var(--space-3);
+ font-size: 0.9375rem;
+ font-weight: 500;
+ color: var(--color-ink-4);
+ border-radius: var(--radius-md);
+ text-decoration: none;
+ transition: background var(--transition-fast), color var(--transition-fast);
+}
+
+.mobile-nav-menu a:hover,
+.mobile-nav-menu .current-menu-item > a,
+.mobile-nav-menu .current-page-item > a {
+ background: var(--color-primary-light);
+ color: var(--color-primary);
+}
+
+/* sub-menu indented */
+.mobile-nav-menu .sub-menu {
+ padding-left: var(--space-4);
+ margin-top: var(--space-1);
+}
+
+/* ── Search form ──────────────────────────────────────────── */
+.mobile-nav-search {
+ margin-top: auto;
+ padding-top: var(--space-4);
+ border-top: 1px solid var(--color-line);
+}
+
+.mobile-nav-search form {
+ display: flex;
+ gap: var(--space-2);
+}
+
+.mobile-nav-search input[type="search"] {
+ flex: 1;
+ padding: var(--space-2) var(--space-3);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-md);
+ font-size: 0.875rem;
+ background: var(--surface-page);
+ color: var(--color-ink);
+}
+
+.mobile-nav-search input[type="search"]:focus {
+ outline: none;
+ border-color: var(--color-primary);
+}
+
+.mobile-nav-search button[type="submit"] {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: var(--space-2) var(--space-3);
+ background: var(--color-primary);
+ color: #fff;
+ border: none;
+ border-radius: var(--radius-md);
+ cursor: pointer;
+ font-size: 0.875rem;
+ transition: background var(--transition-fast);
+}
+
+.mobile-nav-search button[type="submit"]:hover {
+ background: var(--color-primary-dark);
+}
+
+/* ── Only mount overlay on mobile ─────────────────────────── */
+@media (min-width: 769px) {
+ .mobile-nav-overlay {
+ display: none !important;
+ }
+}
+
+
+/* ═══════════════════════════════════════════════════════════
+ SITE FOOTER
+ ═══════════════════════════════════════════════════════════ */
+
+.site-footer {
+ margin-top: var(--space-16);
+ background: var(--color-surface);
+ border-top: 1px solid var(--color-line);
+}
+
+.site-footer__inner {
+ padding-top: var(--space-12);
+ padding-bottom: var(--space-10);
+}
+
+/* ── Grid of columns ──────────────────────────────────────── */
+.site-footer__grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
+ gap: var(--space-8);
+ align-items: start;
+}
+
+/* Give the about column a bit more real estate when there's room */
+.site-footer__about {
+ grid-column: span 2;
+}
+
+@media (max-width: 900px) {
+ .site-footer__about {
+ grid-column: span 1;
+ }
+}
+
+@media (max-width: 600px) {
+ .site-footer__grid {
+ grid-template-columns: 1fr 1fr;
+ }
+
+ .site-footer__about {
+ grid-column: 1 / -1;
+ }
+}
+
+/* ── Column headings ──────────────────────────────────────── */
+.site-footer__heading {
+ font-size: 0.8125rem;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ color: var(--color-ink-4);
+ margin-bottom: var(--space-4);
+}
+
+/* ── About description ────────────────────────────────────── */
+.site-footer__desc {
+ font-size: 0.875rem;
+ color: var(--color-ink-4);
+ line-height: 1.65;
+ margin-bottom: var(--space-4);
+}
+
+/* ── Contact icon row ─────────────────────────────────────── */
+.site-footer__contacts {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-2);
+}
+
+.site-footer__contacts a {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: var(--radius-full);
+ border: 1px solid var(--color-line);
+ color: var(--color-ink-4);
+ transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
+}
+
+.site-footer__contacts a:hover {
+ background: var(--color-primary);
+ color: #fff;
+ border-color: var(--color-primary);
+}
+
+.site-footer__contacts .dashicons {
+ font-size: 16px;
+ width: 16px;
+ height: 16px;
+}
+
+/* ── Link lists ───────────────────────────────────────────── */
+.site-footer__links {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2);
+}
+
+.site-footer__links li {
+ list-style: none;
+}
+
+.site-footer__links a {
+ font-size: 0.875rem;
+ color: var(--color-ink-4);
+ text-decoration: none;
+ transition: color var(--transition-fast);
+}
+
+.site-footer__links a:hover {
+ color: var(--color-primary);
+}
+
+/* ── Friend links: wrap horizontally ─────────────────────── */
+.site-footer__links--friends {
+ flex-direction: row;
+ flex-wrap: wrap;
+ gap: var(--space-2) var(--space-4);
+}
+
+/* ── Bottom copyright bar ─────────────────────────────────── */
+.site-footer__bottom {
+ border-top: 1px solid var(--color-border-light);
+ background: var(--surface-page);
+ padding: var(--space-4) 0;
+}
+
+.site-footer__bottom .container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: var(--space-2);
+}
+
+.site-footer__copy,
+.site-footer__icp {
+ font-size: 0.8125rem;
+ color: var(--color-ink-4);
+}
+
+.site-footer__icp {
+ display: flex;
+ align-items: center;
+ gap: var(--space-3);
+}
+
+.site-footer__icp a {
+ color: var(--color-ink-4);
+ transition: color var(--transition-fast);
+}
+
+.site-footer__icp a:hover {
+ color: var(--color-primary);
+}
+
+@media (max-width: 600px) {
+ .site-footer__bottom .container {
+ flex-direction: column;
+ text-align: center;
+ }
+}
diff --git a/assets/css/core/alerts.css b/assets/css/core/alerts.css
new file mode 100644
index 00000000..b0c9b2c4
--- /dev/null
+++ b/assets/css/core/alerts.css
@@ -0,0 +1,53 @@
+/**
+ * AKSRT Alerts
+ * 统一提示组件:error / warning / info / success
+ * 用于替代各页面 inline 的 .login-error / .bind-error 等
+ */
+
+.alert {
+ display: flex;
+ align-items: flex-start;
+ gap: 10px;
+ padding: 12px 14px;
+ margin-bottom: var(--space-4);
+ font-size: var(--text-sm);
+ line-height: var(--leading-snug);
+ border-radius: var(--radius);
+ border: 1px solid transparent;
+}
+
+.alert > svg {
+ flex-shrink: 0;
+ width: 18px;
+ height: 18px;
+ margin-top: 1px;
+}
+
+.alert--error {
+ color: #B91C1C;
+ background: rgba(239, 68, 68, 0.08);
+ border-color: rgba(239, 68, 68, 0.3);
+}
+
+.alert--warning {
+ color: #B45309;
+ background: rgba(245, 158, 11, 0.08);
+ border-color: rgba(245, 158, 11, 0.3);
+}
+
+.alert--success {
+ color: #047857;
+ background: rgba(16, 185, 129, 0.08);
+ border-color: rgba(16, 185, 129, 0.3);
+}
+
+.alert--info {
+ color: #1D4ED8;
+ background: rgba(59, 130, 246, 0.08);
+ border-color: rgba(59, 130, 246, 0.3);
+}
+
+html.dark .alert--error { color: #FCA5A5; }
+html.dark .alert--warning { color: #FCD34D; }
+html.dark .alert--success { color: #6EE7B7; }
+html.dark .alert--info { color: #93C5FD; }
diff --git a/assets/css/core/animations.css b/assets/css/core/animations.css
new file mode 100644
index 00000000..cba303f3
--- /dev/null
+++ b/assets/css/core/animations.css
@@ -0,0 +1,323 @@
+/**
+ * AKSRT Animations — animate.css 等价(独立重写)
+ * ------------------------------------------------------------
+ * 关键帧 + 工具类 + IntersectionObserver 触发配合
+ * 触发 JS 已在 enhancements2.js([data-aksrt-animate] 属性)
+ * 本文件仅定义 @keyframes 和 .aksrt-anim-* 工具类
+ */
+
+/* ============================================================
+ * Keyframes
+ * ============================================================ */
+
+/* Fade 系列 */
+@keyframes aksrtFadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+@keyframes aksrtFadeInUp {
+ from { opacity: 0; transform: translateY(20px); }
+ to { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtFadeInDown {
+ from { opacity: 0; transform: translateY(-20px); }
+ to { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtFadeInLeft {
+ from { opacity: 0; transform: translateX(-20px); }
+ to { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtFadeInRight {
+ from { opacity: 0; transform: translateX(20px); }
+ to { opacity: 1; transform: none; }
+}
+
+/* Zoom 系列 */
+@keyframes aksrtZoomIn {
+ from { opacity: 0; transform: scale(.85); }
+ to { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtZoomInUp {
+ from { opacity: 0; transform: scale(.85) translateY(20px); }
+ to { opacity: 1; transform: none; }
+}
+
+/* Bounce 系列 */
+@keyframes aksrtBounceIn {
+ 0% { opacity: 0; transform: scale(.3); }
+ 50% { opacity: 1; transform: scale(1.08); }
+ 70% { transform: scale(.95); }
+ 100% { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtBounce {
+ 0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
+ 40% { transform: translateY(-12px); }
+ 60% { transform: translateY(-6px); }
+}
+
+/* Pulse */
+@keyframes aksrtPulse {
+ 0% { transform: scale(1); }
+ 50% { transform: scale(1.06); }
+ 100% { transform: scale(1); }
+}
+
+/* Flash */
+@keyframes aksrtFlash {
+ 0%, 50%, 100% { opacity: 1; }
+ 25%, 75% { opacity: 0; }
+}
+
+/* RubberBand */
+@keyframes aksrtRubberBand {
+ 0% { transform: scale(1); }
+ 30% { transform: scaleX(1.25) scaleY(0.75); }
+ 40% { transform: scaleX(0.75) scaleY(1.25); }
+ 50% { transform: scaleX(1.15) scaleY(0.85); }
+ 65% { transform: scaleX(0.95) scaleY(1.05); }
+ 75% { transform: scaleX(1.05) scaleY(0.95); }
+ 100% { transform: scale(1); }
+}
+
+/* Shake */
+@keyframes aksrtShake {
+ 0%, 100% { transform: translateX(0); }
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
+ 20%, 40%, 60%, 80% { transform: translateX(4px); }
+}
+
+/* Swing */
+@keyframes aksrtSwing {
+ 20% { transform: rotate(15deg); }
+ 40% { transform: rotate(-10deg); }
+ 60% { transform: rotate(5deg); }
+ 80% { transform: rotate(-5deg); }
+ 100% { transform: none; }
+}
+
+/* Tada */
+@keyframes aksrtTada {
+ 0% { transform: scale(1); }
+ 10%, 20% { transform: scale(0.9) rotate(-3deg); }
+ 30%, 50%, 70%, 90% { transform: scale(1.1) rotate(3deg); }
+ 40%, 60%, 80% { transform: scale(1.1) rotate(-3deg); }
+ 100% { transform: scale(1) rotate(0); }
+}
+
+/* Wobble */
+@keyframes aksrtWobble {
+ 0% { transform: none; }
+ 15% { transform: translateX(-25%) rotate(-5deg); }
+ 30% { transform: translateX(20%) rotate(3deg); }
+ 45% { transform: translateX(-15%) rotate(-3deg); }
+ 60% { transform: translateX(10%) rotate(2deg); }
+ 75% { transform: translateX(-5%) rotate(-1deg); }
+ 100% { transform: none; }
+}
+
+/* Slide 系列 */
+@keyframes aksrtSlideInUp {
+ from { opacity: 0; transform: translateY(100%); }
+ to { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtSlideInDown {
+ from { opacity: 0; transform: translateY(-100%); }
+ to { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtSlideInLeft {
+ from { opacity: 0; transform: translateX(-100%); }
+ to { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtSlideInRight {
+ from { opacity: 0; transform: translateX(100%); }
+ to { opacity: 1; transform: none; }
+}
+
+/* HeartBeat */
+@keyframes aksrtHeartBeat {
+ 0% { transform: scale(1); }
+ 14% { transform: scale(1.3); }
+ 28% { transform: scale(1); }
+ 42% { transform: scale(1.3); }
+ 70% { transform: scale(1); }
+ 100% { transform: scale(1); }
+}
+
+/* Jello */
+@keyframes aksrtJello {
+ 0%, 100% { transform: none; }
+ 11% { transform: skewX(-12.5deg) skewY(-12.5deg); }
+ 22% { transform: skewX(6.25deg) skewY(6.25deg); }
+ 33% { transform: skewX(-6.25deg) skewY(-6.25deg); }
+ 44% { transform: skewX(3.125deg) skewY(3.125deg); }
+ 55% { transform: skewX(-3.125deg) skewY(-3.125deg); }
+ 66% { transform: skewX(1.5625deg) skewY(1.5625deg); }
+ 77% { transform: skewX(-1.5625deg) skewY(-1.5625deg); }
+ 88% { transform: skewX(0.78125deg) skewY(0.78125deg); }
+}
+
+/* HeadShake */
+@keyframes aksrtHeadShake {
+ 0% { transform: translateX(0); }
+ 6.5% { transform: translateX(-6px) rotateY(-9deg); }
+ 18.5% { transform: translateX(5px) rotateY(7deg); }
+ 31.5% { transform: translateX(-3px) rotateY(-5deg); }
+ 43.5% { transform: translateX(2px) rotateY(3deg); }
+ 50% { transform: translateX(0); }
+ 100% { transform: translateX(0); }
+}
+
+/* BounceOut — 退出动画 */
+@keyframes aksrtBounceOut {
+ 0% { transform: scale(1); }
+ 25% { transform: scale(0.95); }
+ 50% { transform: scale(1.1); }
+ 75% { transform: scale(0.97); }
+ 100% { transform: scale(1); opacity: 0; }
+}
+
+/* ZoomOut — 退出动画 */
+@keyframes aksrtZoomOut {
+ 0% { opacity: 1; transform: none; }
+ 100% { opacity: 0; transform: scale(0.85); }
+}
+
+/* BackIn/BackOut */
+@keyframes aksrtBackInUp {
+ 0% { opacity: 0; transform: translateY(30px) scale(0.7); }
+ 80% { opacity: 0.8; transform: translateY(-5px) scale(1.02); }
+ 100% { opacity: 1; transform: none; }
+}
+
+@keyframes aksrtBackInDown {
+ 0% { opacity: 0; transform: translateY(-30px) scale(0.7); }
+ 80% { opacity: 0.8; transform: translateY(5px) scale(1.02); }
+ 100% { opacity: 1; transform: none; }
+}
+
+/* Flip */
+@keyframes aksrtFlip {
+ 0% { transform: perspective(400px) rotateY(90deg); opacity: 0; }
+ 40% { transform: perspective(400px) rotateY(-10deg); }
+ 70% { transform: perspective(400px) rotateY(10deg); }
+ 100% { transform: perspective(400px) rotateY(0deg); opacity: 1; }
+}
+
+@keyframes aksrtFlipInX {
+ 0% { transform: perspective(400px) rotateX(90deg); opacity: 0; }
+ 40% { transform: perspective(400px) rotateX(-10deg); }
+ 70% { transform: perspective(400px) rotateX(10deg); }
+ 100% { transform: perspective(400px) rotateX(0deg); opacity: 1; }
+}
+
+/* ============================================================
+ * Animation utility classes
+ * ============================================================ */
+.aksrt-anim-fade-in { animation: aksrtFadeIn var(--dur-base, .4s) var(--ease-out, ease) both; }
+.aksrt-anim-fade-up { animation: aksrtFadeInUp var(--dur-base, .4s) var(--ease-out, ease) both; }
+.aksrt-anim-fade-down { animation: aksrtFadeInDown var(--dur-base, .4s) var(--ease-out, ease) both; }
+.aksrt-anim-fade-left { animation: aksrtFadeInLeft var(--dur-base, .4s) var(--ease-out, ease) both; }
+.aksrt-anim-fade-right { animation: aksrtFadeInRight var(--dur-base, .4s) var(--ease-out, ease) both; }
+
+.aksrt-anim-zoom-in { animation: aksrtZoomIn var(--dur-base, .4s) var(--ease-out, ease) both; }
+.aksrt-anim-zoom-in-up { animation: aksrtZoomInUp var(--dur-base, .4s) var(--ease-out, ease) both; }
+
+.aksrt-anim-bounce-in { animation: aksrtBounceIn .6s var(--ease-out, ease) both; }
+.aksrt-anim-bounce { animation: aksrtBounce 1s ease both; }
+
+.aksrt-anim-pulse { animation: aksrtPulse 1s ease infinite; }
+.aksrt-anim-flash { animation: aksrtFlash 1s ease both; }
+.aksrt-anim-rubber-band { animation: aksrtRubberBand .8s ease both; }
+.aksrt-anim-shake { animation: aksrtShake .5s ease both; }
+.aksrt-anim-swing { animation: aksrtSwing .6s var(--ease-out, ease) both; }
+.aksrt-anim-tada { animation: aksrtTada 1s ease both; }
+.aksrt-anim-wobble { animation: aksrtWobble .8s ease both; }
+.aksrt-anim-heart-beat { animation: aksrtHeartBeat 1.3s ease both; }
+.aksrt-anim-jello { animation: aksrtJello .8s ease both; }
+.aksrt-anim-head-shake { animation: aksrtHeadShake .8s ease both; }
+
+/* 退出动画 */
+.aksrt-anim-bounce-out { animation: aksrtBounceOut .5s ease both; }
+.aksrt-anim-zoom-out { animation: aksrtZoomOut .3s ease both; }
+
+/* BackIn 动画 */
+.aksrt-anim-back-in-up { animation: aksrtBackInUp .5s var(--ease-out, ease) both; }
+.aksrt-anim-back-in-down { animation: aksrtBackInDown .5s var(--ease-out, ease) both; }
+
+.aksrt-anim-slide-up { animation: aksrtSlideInUp .5s var(--ease-out, ease) both; }
+.aksrt-anim-slide-down { animation: aksrtSlideInDown .5s var(--ease-out, ease) both; }
+.aksrt-anim-slide-left { animation: aksrtSlideInLeft .5s var(--ease-out, ease) both; }
+.aksrt-anim-slide-right { animation: aksrtSlideInRight .5s var(--ease-out, ease) both; }
+
+.aksrt-anim-flip { animation: aksrtFlip .6s var(--ease-out, ease) both; }
+.aksrt-anim-flip-x { animation: aksrtFlipInX .6s var(--ease-out, ease) both; }
+
+/* ============================================================
+ * Duration modifiers
+ * ============================================================ */
+.aksrt-anim-fast { --dur-base: .2s; }
+.aksrt-anim-slow { --dur-base: .6s; }
+
+/* ============================================================
+ * Delay modifiers (配合 data-aksrt-delay 使用时为 inline,
+ * 也可用 class 方式独立设置)
+ * ============================================================ */
+.aksrt-anim-delay-1 { animation-delay: .1s; }
+.aksrt-anim-delay-2 { animation-delay: .2s; }
+.aksrt-anim-delay-3 { animation-delay: .3s; }
+.aksrt-anim-delay-4 { animation-delay: .4s; }
+.aksrt-anim-delay-5 { animation-delay: .5s; }
+.aksrt-anim-delay-6 { animation-delay: .6s; }
+.aksrt-anim-delay-7 { animation-delay: .7s; }
+.aksrt-anim-delay-8 { animation-delay: .8s; }
+
+/* ============================================================
+ * Infinite modifier
+ * ============================================================ */
+.aksrt-anim-infinite { animation-iteration-count: infinite; }
+
+/* ============================================================
+ * Reduced-motion — 尊重用户偏好
+ * ============================================================ */
+@media (prefers-reduced-motion: reduce) {
+ .aksrt-anim-fade-in,
+ .aksrt-anim-fade-up,
+ .aksrt-anim-fade-down,
+ .aksrt-anim-fade-left,
+ .aksrt-anim-fade-right,
+ .aksrt-anim-zoom-in,
+ .aksrt-anim-zoom-in-up,
+ .aksrt-anim-bounce-in,
+ .aksrt-anim-bounce,
+ .aksrt-anim-pulse,
+ .aksrt-anim-flash,
+ .aksrt-anim-rubber-band,
+ .aksrt-anim-shake,
+ .aksrt-anim-swing,
+ .aksrt-anim-tada,
+ .aksrt-anim-wobble,
+ .aksrt-anim-heart-beat,
+ .aksrt-anim-jello,
+ .aksrt-anim-head-shake,
+ .aksrt-anim-bounce-out,
+ .aksrt-anim-zoom-out,
+ .aksrt-anim-back-in-up,
+ .aksrt-anim-back-in-down,
+ .aksrt-anim-slide-up,
+ .aksrt-anim-slide-down,
+ .aksrt-anim-slide-left,
+ .aksrt-anim-slide-right,
+ .aksrt-anim-flip,
+ .aksrt-anim-flip-x {
+ animation: none !important;
+ }
+}
diff --git a/assets/css/core/buttons.css b/assets/css/core/buttons.css
new file mode 100644
index 00000000..4a3182f0
--- /dev/null
+++ b/assets/css/core/buttons.css
@@ -0,0 +1,304 @@
+/**
+ * AKSRT Buttons — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll .but 系统:
+ * - 正常字重 (normal)
+ * - 4px 圆角
+ * - 灰色默认背景
+ * - opacity hover
+ */
+
+.btn,
+.btn-primary,
+.btn-outline,
+.btn-ghost,
+.btn-danger {
+ --btn-h: 34px;
+ --btn-px: 12px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ height: var(--btn-h);
+ padding: 0 var(--btn-px);
+ font-size: var(--text-sm);
+ font-weight: normal;
+ line-height: 1.44;
+ border: 1px solid transparent;
+ border-radius: var(--radius-btn);
+ cursor: pointer;
+ white-space: nowrap;
+ user-select: none;
+ text-decoration: none;
+ transition: opacity var(--dur-fast) var(--ease),
+ background var(--dur-fast) var(--ease),
+ border-color var(--dur-fast) var(--ease),
+ color var(--dur-fast) var(--ease);
+}
+
+/* 尺寸变体 */
+.btn-sm { --btn-h: 28px; --btn-px: 8px; font-size: var(--text-xs); }
+.btn-lg { --btn-h: 44px; --btn-px: 18px; font-size: var(--text-base); }
+
+/* === Default (gray background, like zibll .but default) === */
+.btn {
+ background: rgba(136, 136, 136, 0.1);
+ color: #888;
+}
+
+.btn:hover {
+ opacity: 0.8;
+}
+
+/* === Primary === */
+.btn-primary {
+ background: var(--color-primary);
+ color: var(--color-on-primary);
+ border-color: var(--color-primary);
+}
+
+.btn-primary:hover {
+ opacity: 0.8;
+ color: var(--color-on-primary);
+}
+
+.btn-primary:active {
+ opacity: 1;
+ box-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.08);
+}
+
+/* === Outline === */
+.btn-outline {
+ background: transparent;
+ color: var(--color-ink-2);
+ border-color: var(--color-line);
+}
+
+.btn-outline:hover {
+ background: var(--color-primary-soft);
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+ opacity: 1;
+}
+
+/* === Ghost === */
+.btn-ghost {
+ background: transparent;
+ color: var(--color-ink-2);
+ border-color: transparent;
+}
+
+.btn-ghost:hover {
+ background: rgba(136, 136, 136, 0.1);
+ opacity: 1;
+}
+
+/* === Danger === */
+.btn-danger {
+ background: var(--color-error);
+ color: #fff;
+ border-color: var(--color-error);
+}
+
+.btn-danger:hover {
+ opacity: 0.8;
+ color: #fff;
+}
+
+/* === Disabled === */
+.btn:disabled,
+.btn-primary:disabled,
+.btn-outline:disabled,
+.btn-ghost:disabled,
+.btn-danger:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+ pointer-events: none;
+}
+
+/* === Icon button === */
+.btn-icon {
+ width: var(--btn-h);
+ padding: 0;
+ justify-content: center;
+}
+
+.btn-icon.btn-sm { width: 28px; }
+.btn-icon.btn-lg { width: 44px; }
+
+/* === Full width === */
+.btn-block {
+ width: 100%;
+}
+
+/* ============================================================
+ * Zibll .but / .badg compat layer — 1:1 zibll main.css (.but system)
+ * ------------------------------------------------------------
+ * Additive: does NOT alter the AKSRT .btn system above. Lets reused
+ * zibll-style markup (.but / .badg / .b-* / .jb-* / .c-* / .but-group /
+ * .but-average / .toggle-radius) render via the --this-* context-coloring vars.
+ * The --this-* DEFAULTS are set on the base rule here (BEFORE the .b-*/.jb-*
+ * modifiers) so the cascade resolves colored variants correctly; scoped to
+ * .but/.badg (never :root) so .float-btn's own var(--this-*, fallback) stays intact.
+ * Consumes --focus-color-opacity* from zibll-compat-vars.css.
+ * ============================================================ */
+
+/* Base (zibll .but / .badg) */
+.but,
+.badg {
+ display: inline-block;
+ vertical-align: middle;
+ padding: 0.3em 0.6em;
+ text-align: center;
+ font-weight: normal;
+ line-height: 1.44;
+ border-radius: 4px;
+ border: 1px solid var(--this-border);
+ box-shadow: var(--this-shadow);
+ background: var(--this-bg);
+ color: var(--this-color);
+ --main-color: var(--this-color);
+ --this-bg: rgba(136, 136, 136, 0.1);
+ --this-border: transparent;
+ --this-shadow: none;
+ --this-color: #888;
+ text-shadow: 0 0 0;
+ transition: 0.15s;
+ cursor: pointer;
+}
+
+.but a { color: inherit; }
+
+.but .icon,
+.but > .fa:not(.fa-angle-right) { margin-right: 0.25em; }
+
+/* hover / active */
+.but:focus,
+.but:hover { opacity: 0.8; color: var(--this-color); }
+.but:active { --this-shadow: inset 0 2px 3px rgba(0, 0, 0, 0.08); }
+
+/* radius variants */
+.but.radius,
+.badg.radius,
+.radius > .but { border-radius: 50px; padding: 0.3em 1em; }
+.but.main-radius,
+.badg.main-radius { border-radius: var(--main-radius); }
+.but.mini-radius,
+.badg.mini-radius { border-radius: var(--mini-radius); }
+
+/* hollow (outline) */
+.but.hollow,
+.badg.hollow { background: transparent; --this-border: var(--this-color); }
+.but.hollow:hover { background: var(--this-bg); }
+.badg.hollow[class*='b-'],
+.but.hollow[class*='b-'] { background: 0 0; --this-border: var(--this-bg); --this-color: var(--this-bg); }
+.but.hollow[class*='b-']:hover { color: #fff; }
+.but.hollow.c-white:hover { background: 0 0; --this-color: var(--focus-color); color: var(--focus-color); }
+
+/* circular icon button */
+.circular,
+.badg.cir,
+.but.cir {
+ padding: 0;
+ border-radius: 5em;
+ --this-size: 1.8em;
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ height: var(--this-size);
+ min-width: var(--this-size);
+}
+.circular.radius4,
+.badg.cir.radius4,
+.but.cir.radius4 { border-radius: 4px; }
+.but.cir svg.icon,
+.but.cir > .fa { margin: 0; }
+
+/* button group (joined) */
+.but-group { display: inline-flex; }
+.but-group > .but { border-radius: 0; margin: 0; }
+.but-group > .but:first-of-type { border-radius: 4px 0 0 4px; }
+.but-group > .but:last-of-type { border-radius: 0 4px 4px 0; }
+
+/* segmented control (equal-width) */
+.but-average { display: flex; border-radius: 4px; overflow: hidden; }
+.but-average.inline { display: inline-flex; }
+.but-average.radius { border-radius: 100px; }
+.but-average.main-radius { border-radius: var(--main-radius); }
+.but-average.mini-radius { border-radius: var(--mini-radius); }
+.but-average > .but { margin: 0 !important; border-radius: 0; flex: auto; }
+.but-average > .but.active { --this-bg: var(--focus-color-opacity1); --this-color: var(--focus-color); }
+
+/* size variants */
+.but.but-sm { font-size: 0.9em; padding: 0.1em 0.4em; vertical-align: 0.05em; }
+.but.badg-sm,
+.badg.badg-sm { font-size: 0.8em; padding: 0 0.2em; vertical-align: 0.1em; min-width: 1.6em; }
+.badg.badg-sm.cir { --this-size: 1.6em; }
+.padding-lg,
+.badg.badg-lg,
+.but.padding-lg { padding: 0.5em 2em; }
+
+/* active badge state */
+.active.badg,
+.active > .badg:not(.vip-tag) { --this-bg: var(--focus-color); --this-color: #fff; }
+.active.badg.hollow,
+.active > .hollow:not(.vip-tag) { --this-color: var(--focus-color); }
+
+/* toggle-radius (round 29px toggle) */
+.toggle-radius {
+ background: var(--this-bg);
+ width: 29px;
+ height: 29px;
+ display: inline-block;
+ text-align: center;
+ border-radius: 100%;
+ position: relative;
+ vertical-align: text-top;
+ --this-bg: var(--main-border-color);
+}
+.toggle-radius .fa,
+.toggle-radius .icon { right: 0 !important; left: 0 !important; margin: auto; }
+
+/* solid color modifiers — set --this-bg; default --this-color white */
+.b-gray, .b-theme, .b-red, .b-yellow, .b-blue, .b-blue-2, .b-black,
+.b-cyan, .b-green, .b-purple,
+.jb-red, .jb-pink, .jb-yellow, .jb-blue, .jb-green, .jb-purple,
+.jb-vip1, .jb-vip2 {
+ color: var(--this-color);
+ background: var(--this-bg);
+ --this-color: #fff;
+}
+.jb-red, .jb-pink, .jb-yellow, .jb-blue, .jb-green, .jb-purple,
+.jb-vip1, .jb-vip2 { border: none; }
+
+.b-theme { --this-bg: var(--focus-color); }
+.b-gray { --this-bg: #818b95; }
+.b-red { --this-bg: #ff5473; }
+.b-yellow { --this-bg: #ff6f06; }
+.b-cyan { --this-bg: #08c4c1; }
+.b-blue { --this-bg: #2997f7; }
+.b-blue-2 { --this-bg: #5c7cff; }
+.b-green { --this-bg: #12b928; }
+.b-purple { --this-bg: #d448f5; }
+.b-black { --this-bg: #121517; }
+
+/* gradient modifiers (zibll .jb-*) */
+.jb-red { --this-bg: linear-gradient(135deg, #fd7a64 10%, #fb2d2d 100%); }
+.jb-yellow { --this-bg: linear-gradient(135deg, #f99d4d 10%, #f7631d 100%); }
+.jb-blue { --this-bg: linear-gradient(135deg, #59c3fb 10%, #268df7 100%); }
+.jb-green { --this-bg: linear-gradient(135deg, #60e464 10%, #5cb85b 100%); }
+.jb-purple { --this-bg: linear-gradient(135deg, #f98dfb 10%, #ea00f9 100%); }
+.jb-pink { --this-bg: linear-gradient(135deg, #ff5e7f 30%, #ff967e 100%); }
+.jb-vip1 { --this-bg: linear-gradient(25deg, #eabe7b 10%, #f5e3c7 70%, #edc788 100%); --this-color: #866127; }
+.jb-vip2 { --this-bg: linear-gradient(317deg, #4d4c4c 30%, #7b7b7b 70%, #5f5c5c 100%); --this-color: #ddd; }
+
+/* text-color modifiers (zibll .c-*) — set --this-color + light --this-bg */
+.c-theme, .c-gray, .c-white, .c-red, .c-red-2, .c-yellow, .c-blue, .c-blue-2,
+.c-green, .c-cyan, .c-purple { color: var(--this-color); }
+.c-theme { --this-color: var(--focus-color); --this-bg: var(--focus-color-opacity1); }
+.c-gray { --this-color: #888; --this-bg: rgba(136, 136, 136, 0.1); }
+.c-white { --this-color: #fff; --this-bg: rgba(255, 255, 255, 0.1); }
+.c-red { --this-color: #ff5473; --this-bg: rgba(255, 84, 115, 0.1); }
+.c-red-2 { --this-color: #d6064c; --this-bg: rgba(194, 41, 46, 0.1); }
+.c-yellow { --this-color: #ff6f06; --this-bg: rgba(255, 111, 6, 0.1); }
+.c-blue { --this-color: #2997f7; --this-bg: rgba(41, 151, 247, 0.1); }
diff --git a/assets/css/core/color-utilities.css b/assets/css/core/color-utilities.css
new file mode 100644
index 00000000..091522c0
--- /dev/null
+++ b/assets/css/core/color-utilities.css
@@ -0,0 +1,272 @@
+/**
+ * AKSRT Color Utilities — 多色按钮 / 渐变按钮 / 文字渐变 / Badge
+ * ------------------------------------------------------------
+ * 所有颜色走 CSS 变量(定义在 tokens.css),不硬编码十六进制。
+ */
+
+/* ============================================================
+ * 1. 多色按钮 — .aksrt-btn--{color}
+ * ============================================================ */
+.aksrt-btn--rose { background: var(--aksrt-rose); color: #fff; }
+.aksrt-btn--rose:hover,
+.aksrt-btn--rose:focus-visible { background: #e11d48; }
+
+.aksrt-btn--blue { background: var(--aksrt-blue); color: #fff; }
+.aksrt-btn--blue:hover,
+.aksrt-btn--blue:focus-visible { background: #2563eb; }
+
+.aksrt-btn--green { background: var(--aksrt-green); color: #fff; }
+.aksrt-btn--green:hover,
+.aksrt-btn--green:focus-visible { background: #059669; }
+
+.aksrt-btn--orange { background: var(--aksrt-orange); color: #fff; }
+.aksrt-btn--orange:hover,
+.aksrt-btn--orange:focus-visible { background: #ea580c; }
+
+.aksrt-btn--purple { background: var(--aksrt-purple); color: #fff; }
+.aksrt-btn--purple:hover,
+.aksrt-btn--purple:focus-visible { background: #7c3aed; }
+
+.aksrt-btn--cyan { background: var(--aksrt-cyan); color: #fff; }
+.aksrt-btn--cyan:hover,
+.aksrt-btn--cyan:focus-visible { background: #0891b2; }
+
+.aksrt-btn--yellow { background: var(--aksrt-yellow); color: #422006; }
+.aksrt-btn--yellow:hover,
+.aksrt-btn--yellow:focus-visible { background: #ca8a04; color: #fff; }
+
+.aksrt-btn--red { background: var(--aksrt-red); color: #fff; }
+.aksrt-btn--red:hover,
+.aksrt-btn--red:focus-visible { background: #dc2626; }
+
+.aksrt-btn--teal { background: var(--aksrt-teal); color: #fff; }
+.aksrt-btn--teal:hover,
+.aksrt-btn--teal:focus-visible { background: #0d9488; }
+
+.aksrt-btn--indigo { background: var(--aksrt-indigo); color: #fff; }
+.aksrt-btn--indigo:hover,
+.aksrt-btn--indigo:focus-visible { background: #4f46e5; }
+
+.aksrt-btn--pink { background: var(--aksrt-pink); color: #fff; }
+.aksrt-btn--pink:hover,
+.aksrt-btn--pink:focus-visible { background: #db2777; }
+
+/* Soft variant — 浅色背景 + 深色文字 */
+.aksrt-btn--rose-soft { background: var(--aksrt-rose-soft); color: var(--aksrt-rose); }
+.aksrt-btn--blue-soft { background: var(--aksrt-blue-soft); color: var(--aksrt-blue); }
+.aksrt-btn--green-soft { background: var(--aksrt-green-soft); color: var(--aksrt-green); }
+.aksrt-btn--orange-soft { background: var(--aksrt-orange-soft); color: var(--aksrt-orange); }
+.aksrt-btn--purple-soft { background: var(--aksrt-purple-soft); color: var(--aksrt-purple); }
+.aksrt-btn--cyan-soft { background: var(--aksrt-cyan-soft); color: var(--aksrt-cyan); }
+.aksrt-btn--yellow-soft { background: var(--aksrt-yellow-soft); color: #92400e; }
+.aksrt-btn--red-soft { background: var(--aksrt-red-soft); color: var(--aksrt-red); }
+.aksrt-btn--teal-soft { background: var(--aksrt-teal-soft); color: var(--aksrt-teal); }
+.aksrt-btn--indigo-soft { background: var(--aksrt-indigo-soft); color: var(--aksrt-indigo); }
+.aksrt-btn--pink-soft { background: var(--aksrt-pink-soft); color: var(--aksrt-pink); }
+
+/* ============================================================
+ * 2. 渐变按钮 — .aksrt-btn--grad-{name}
+ * ============================================================ */
+.aksrt-btn--grad-vip {
+ background: linear-gradient(135deg, var(--aksrt-vip-gold-1), var(--aksrt-vip-gold-2));
+ color: #5a3d00;
+ border: none;
+}
+
+.aksrt-btn--grad-sunset {
+ background: linear-gradient(135deg, var(--aksrt-grad-sunset-1), var(--aksrt-grad-sunset-2));
+ color: #fff;
+ border: none;
+}
+
+.aksrt-btn--grad-ocean {
+ background: linear-gradient(135deg, var(--aksrt-grad-ocean-1), var(--aksrt-grad-ocean-2));
+ color: #fff;
+ border: none;
+}
+
+.aksrt-btn--grad-forest {
+ background: linear-gradient(135deg, var(--aksrt-grad-forest-1), var(--aksrt-grad-forest-2));
+ color: #064e3b;
+ border: none;
+}
+
+.aksrt-btn--grad-night {
+ background: linear-gradient(135deg, var(--aksrt-grad-night-1), var(--aksrt-grad-night-2));
+ color: #4c1d95;
+ border: none;
+}
+
+.aksrt-btn--grad-fire {
+ background: linear-gradient(135deg, var(--aksrt-grad-fire-1), var(--aksrt-grad-fire-2));
+ color: #fff;
+ border: none;
+}
+
+.aksrt-btn--grad-primary {
+ background: linear-gradient(135deg, var(--color-primary), var(--color-primary-active));
+ color: var(--color-on-primary);
+ border: none;
+}
+
+/* 渐变按钮 hover — 亮度微调 */
+.aksrt-btn--grad-vip:hover,
+.aksrt-btn--grad-sunset:hover,
+.aksrt-btn--grad-ocean:hover,
+.aksrt-btn--grad-forest:hover,
+.aksrt-btn--grad-night:hover,
+.aksrt-btn--grad-fire:hover,
+.aksrt-btn--grad-primary:hover {
+ filter: brightness(1.08);
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
+}
+
+/* ============================================================
+ * 3. 文字渐变 — .aksrt-text-grad-{name}
+ * ============================================================ */
+.aksrt-text-grad-primary {
+ background: linear-gradient(135deg, var(--color-primary), var(--color-primary-active));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.aksrt-text-grad-vip {
+ background: linear-gradient(135deg, var(--aksrt-vip-gold-1), var(--aksrt-vip-gold-2));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.aksrt-text-grad-sunset {
+ background: linear-gradient(135deg, var(--aksrt-grad-sunset-1), var(--aksrt-grad-sunset-2));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.aksrt-text-grad-ocean {
+ background: linear-gradient(135deg, var(--aksrt-grad-ocean-1), var(--aksrt-grad-ocean-2));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.aksrt-text-grad-forest {
+ background: linear-gradient(135deg, var(--aksrt-grad-forest-1), var(--aksrt-grad-forest-2));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.aksrt-text-grad-night {
+ background: linear-gradient(135deg, var(--aksrt-grad-night-1), var(--aksrt-grad-night-2));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.aksrt-text-grad-fire {
+ background: linear-gradient(135deg, var(--aksrt-grad-fire-1), var(--aksrt-grad-fire-2));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+/* ============================================================
+ * 4. Badge 系统 — .aksrt-badge / .aksrt-badge--{color}
+ * ============================================================ */
+.aksrt-badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ height: var(--aksrt-badge-h, 22px);
+ padding: 0 8px;
+ border-radius: var(--radius-pill, 100px);
+ font-size: 12px;
+ font-weight: 600;
+ line-height: 1;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+.aksrt-badge--primary { background: var(--color-primary-soft); color: var(--color-primary); }
+.aksrt-badge--success { background: rgba(16, 185, 129, 0.12); color: var(--color-success); }
+.aksrt-badge--warning { background: rgba(245, 158, 11, 0.12); color: var(--color-warning); }
+.aksrt-badge--error { background: rgba(239, 68, 68, 0.12); color: var(--color-error); }
+.aksrt-badge--info { background: rgba(59, 130, 246, 0.12); color: var(--color-info); }
+
+.aksrt-badge--rose { background: var(--aksrt-rose-soft); color: var(--aksrt-rose); }
+.aksrt-badge--blue { background: var(--aksrt-blue-soft); color: var(--aksrt-blue); }
+.aksrt-badge--green { background: var(--aksrt-green-soft); color: var(--aksrt-green); }
+.aksrt-badge--orange { background: var(--aksrt-orange-soft); color: var(--aksrt-orange); }
+.aksrt-badge--purple { background: var(--aksrt-purple-soft); color: var(--aksrt-purple); }
+.aksrt-badge--cyan { background: var(--aksrt-cyan-soft); color: var(--aksrt-cyan); }
+.aksrt-badge--yellow { background: var(--aksrt-yellow-soft); color: #92400e; }
+.aksrt-badge--red { background: var(--aksrt-red-soft); color: var(--aksrt-red); }
+.aksrt-badge--teal { background: var(--aksrt-teal-soft); color: var(--aksrt-teal); }
+.aksrt-badge--indigo { background: var(--aksrt-indigo-soft); color: var(--aksrt-indigo); }
+.aksrt-badge--pink { background: var(--aksrt-pink-soft); color: var(--aksrt-pink); }
+
+/* 渐变 Badge */
+.aksrt-badge--grad-vip {
+ background: linear-gradient(135deg, var(--aksrt-vip-gold-1), var(--aksrt-vip-gold-2));
+ color: #5a3d00;
+}
+
+.aksrt-badge--grad-primary {
+ background: linear-gradient(135deg, var(--color-primary), var(--color-primary-active));
+ color: var(--color-on-primary);
+}
+
+/* Solid badge variant — 纯色背景 + 白色文字 */
+.aksrt-badge--solid-primary { background: var(--color-primary); color: #fff; }
+.aksrt-badge--solid-success { background: var(--color-success); color: #fff; }
+.aksrt-badge--solid-warning { background: var(--color-warning); color: #fff; }
+.aksrt-badge--solid-error { background: var(--color-error); color: #fff; }
+.aksrt-badge--solid-info { background: var(--color-info); color: #fff; }
+.aksrt-badge--solid-rose { background: var(--aksrt-rose); color: #fff; }
+.aksrt-badge--solid-blue { background: var(--aksrt-blue); color: #fff; }
+.aksrt-badge--solid-green { background: var(--aksrt-green); color: #fff; }
+.aksrt-badge--solid-orange { background: var(--aksrt-orange); color: #fff; }
+.aksrt-badge--solid-purple { background: var(--aksrt-purple); color: #fff; }
+.aksrt-badge--solid-cyan { background: var(--aksrt-cyan); color: #fff; }
+.aksrt-badge--solid-yellow { background: var(--aksrt-yellow); color: #422006; }
+.aksrt-badge--solid-red { background: var(--aksrt-red); color: #fff; }
+.aksrt-badge--solid-teal { background: var(--aksrt-teal); color: #fff; }
+.aksrt-badge--solid-indigo { background: var(--aksrt-indigo); color: #fff; }
+.aksrt-badge--solid-pink { background: var(--aksrt-pink); color: #fff; }
+
+/* Badge sizes */
+.aksrt-badge--sm { height: 18px; padding: 0 6px; font-size: 11px; }
+.aksrt-badge--lg { height: 28px; padding: 0 12px; font-size: 13px; }
+
+/* ============================================================
+ * 5. 背景色工具类 — .aksrt-bg-{color}
+ * ============================================================ */
+.aksrt-bg-rose { background-color: var(--aksrt-rose-soft); }
+.aksrt-bg-blue { background-color: var(--aksrt-blue-soft); }
+.aksrt-bg-green { background-color: var(--aksrt-green-soft); }
+.aksrt-bg-orange { background-color: var(--aksrt-orange-soft); }
+.aksrt-bg-purple { background-color: var(--aksrt-purple-soft); }
+.aksrt-bg-cyan { background-color: var(--aksrt-cyan-soft); }
+.aksrt-bg-yellow { background-color: var(--aksrt-yellow-soft); }
+.aksrt-bg-red { background-color: var(--aksrt-red-soft); }
+.aksrt-bg-teal { background-color: var(--aksrt-teal-soft); }
+.aksrt-bg-indigo { background-color: var(--aksrt-indigo-soft); }
+.aksrt-bg-pink { background-color: var(--aksrt-pink-soft); }
+
+/* ============================================================
+ * 6. 文字色工具类 — .aksrt-text-{color}
+ * ============================================================ */
+.aksrt-text-rose { color: var(--aksrt-rose); }
+.aksrt-text-blue { color: var(--aksrt-blue); }
+.aksrt-text-green { color: var(--aksrt-green); }
+.aksrt-text-orange { color: var(--aksrt-orange); }
+.aksrt-text-purple { color: var(--aksrt-purple); }
+.aksrt-text-cyan { color: var(--aksrt-cyan); }
+.aksrt-text-yellow { color: var(--aksrt-yellow); }
+.aksrt-text-red { color: var(--aksrt-red); }
+.aksrt-text-teal { color: var(--aksrt-teal); }
+.aksrt-text-indigo { color: var(--aksrt-indigo); }
+.aksrt-text-pink { color: var(--aksrt-pink); }
diff --git a/assets/css/core/components-ext.css b/assets/css/core/components-ext.css
new file mode 100644
index 00000000..5e72e3fd
--- /dev/null
+++ b/assets/css/core/components-ext.css
@@ -0,0 +1,555 @@
+/**
+ * AKSRT Extended Components — 时间轴 / 步骤向导 / 九宫格 / 定价卡片 /
+ * Toggle 开关 / 自定义复选框 / 数字步进器
+ * ------------------------------------------------------------
+ * 全部使用 aksrt- 前缀,保持原生语义可访问性。
+ */
+
+/* ============================================================
+ * 1. 时间轴 — .aksrt-timeline
+ * ============================================================ */
+.aksrt-timeline {
+ position: relative;
+ padding-left: 28px;
+ margin: 0;
+ list-style: none;
+}
+
+/* 竖线 */
+.aksrt-timeline::before {
+ content: '';
+ position: absolute;
+ left: 8px;
+ top: 4px;
+ bottom: 4px;
+ width: 2px;
+ background: var(--color-line, rgba(50, 50, 50, 0.1));
+ border-radius: 1px;
+}
+
+.aksrt-timeline__item {
+ position: relative;
+ padding-bottom: 24px;
+}
+
+.aksrt-timeline__item:last-child {
+ padding-bottom: 0;
+}
+
+/* 圆点 */
+.aksrt-timeline__dot {
+ position: absolute;
+ left: -24px;
+ top: 4px;
+ width: 12px;
+ height: 12px;
+ border-radius: 50%;
+ background: var(--color-primary);
+ border: 2px solid var(--surface-1, #fff);
+ box-shadow: 0 0 0 2px var(--color-primary-soft, rgba(240, 68, 148, 0.12));
+ z-index: 1;
+}
+
+/* 空心圆点变体 */
+.aksrt-timeline__dot--outline {
+ background: var(--surface-1, #fff);
+ border: 2px solid var(--color-primary);
+ box-shadow: none;
+}
+
+/* 灰色圆点 — 已完成/已过去 */
+.aksrt-timeline__dot--muted {
+ background: var(--color-ink-4, #999);
+ box-shadow: 0 0 0 2px var(--surface-2, #eee);
+}
+
+.aksrt-timeline__time {
+ display: block;
+ font-size: 12px;
+ color: var(--color-ink-4, #999);
+ margin-bottom: 4px;
+}
+
+.aksrt-timeline__title {
+ font-weight: 600;
+ color: var(--color-ink, #333);
+ margin-bottom: 4px;
+}
+
+.aksrt-timeline__content {
+ font-size: 14px;
+ color: var(--color-ink-3, #777);
+ line-height: 1.6;
+}
+
+/* ============================================================
+ * 2. 步骤向导 — .aksrt-steps
+ * ============================================================ */
+.aksrt-steps {
+ display: flex;
+ align-items: flex-start;
+ gap: 0;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ counter-reset: aksrt-step;
+}
+
+.aksrt-steps__item {
+ flex: 1;
+ position: relative;
+ text-align: center;
+ counter-increment: aksrt-step;
+}
+
+/* 连接线 */
+.aksrt-steps__item:not(:last-child)::after {
+ content: '';
+ position: absolute;
+ top: 16px;
+ left: calc(50% + 20px);
+ right: calc(-50% + 20px);
+ height: 2px;
+ background: var(--color-line, rgba(50, 50, 50, 0.1));
+}
+
+.aksrt-steps__icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 34px;
+ height: 34px;
+ border-radius: 50%;
+ background: var(--surface-2, #eee);
+ color: var(--color-ink-3, #777);
+ font-size: 14px;
+ font-weight: 700;
+ margin: 0 auto 8px;
+ position: relative;
+ z-index: 1;
+}
+
+.aksrt-steps__item--active .aksrt-steps__icon {
+ background: var(--color-primary);
+ color: var(--color-on-primary, #fff);
+}
+
+.aksrt-steps__item--done .aksrt-steps__icon {
+ background: var(--color-success);
+ color: #fff;
+}
+
+.aksrt-steps__item--done:not(:last-child)::after {
+ background: var(--color-success);
+}
+
+.aksrt-steps__label {
+ font-size: 13px;
+ font-weight: 600;
+ color: var(--color-ink-3, #777);
+}
+
+.aksrt-steps__item--active .aksrt-steps__label {
+ color: var(--color-primary);
+}
+
+.aksrt-steps__item--done .aksrt-steps__label {
+ color: var(--color-success);
+}
+
+/* 垂直模式 */
+.aksrt-steps--vertical {
+ flex-direction: column;
+ gap: 0;
+ padding-left: 20px;
+}
+
+.aksrt-steps--vertical .aksrt-steps__item {
+ text-align: left;
+ padding-left: 28px;
+ padding-bottom: 20px;
+}
+
+.aksrt-steps--vertical .aksrt-steps__item:not(:last-child)::after {
+ top: 34px;
+ left: 36px;
+ right: auto;
+ width: 2px;
+ height: calc(100% - 34px);
+}
+
+.aksrt-steps--vertical .aksrt-steps__icon {
+ position: absolute;
+ left: 0;
+ margin: 0;
+}
+
+/* ============================================================
+ * 3. 九宫格 — .aksrt-img-grid
+ * ============================================================ */
+.aksrt-img-grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 4px;
+ border-radius: var(--radius, 8px);
+ overflow: hidden;
+}
+
+.aksrt-img-grid img {
+ width: 100%;
+ aspect-ratio: 1;
+ object-fit: cover;
+ display: block;
+ cursor: pointer;
+ transition: transform .2s ease;
+}
+
+.aksrt-img-grid img:hover {
+ transform: scale(1.03);
+}
+
+/* 自适应列数 */
+.aksrt-img-grid--2 { grid-template-columns: repeat(2, 1fr); }
+.aksrt-img-grid--4 { grid-template-columns: repeat(4, 1fr); }
+
+@media (max-width: 480px) {
+ .aksrt-img-grid--4 { grid-template-columns: repeat(3, 1fr); }
+}
+
+/* ============================================================
+ * 4. 定价卡片 — .aksrt-pricing-card
+ * ============================================================ */
+.aksrt-pricing-card {
+ position: relative;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
+ border-radius: var(--radius-lg, 8px);
+ padding: 28px 24px;
+ text-align: center;
+ transition: box-shadow .25s ease, transform .25s ease;
+}
+
+.aksrt-pricing-card:hover {
+ box-shadow: var(--shadow-lg, 0 0 10px rgba(116, 116, 116, 0.12));
+ transform: translateY(-2px);
+}
+
+/* 推荐/高亮卡片 */
+.aksrt-pricing-card--featured {
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 1px var(--color-primary), var(--shadow-lg);
+}
+
+.aksrt-pricing-card__badge {
+ position: absolute;
+ top: -1px;
+ left: 50%;
+ transform: translateX(-50%);
+ background: var(--color-primary);
+ color: #fff;
+ padding: 2px 16px;
+ border-radius: 0 0 var(--radius, 8px) var(--radius, 8px);
+ font-size: 12px;
+ font-weight: 700;
+}
+
+.aksrt-pricing-card__title {
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--color-ink, #333);
+ margin-bottom: 8px;
+}
+
+.aksrt-pricing-card__price {
+ font-size: 36px;
+ font-weight: 800;
+ color: var(--color-primary);
+ line-height: 1.2;
+ margin: 12px 0 4px;
+}
+
+.aksrt-pricing-card__price small {
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--color-ink-3, #777);
+}
+
+.aksrt-pricing-card__desc {
+ font-size: 14px;
+ color: var(--color-ink-3, #777);
+ margin-bottom: 20px;
+}
+
+.aksrt-pricing-card__features {
+ list-style: none;
+ padding: 0;
+ margin: 0 0 24px;
+ text-align: left;
+}
+
+.aksrt-pricing-card__features li {
+ padding: 6px 0;
+ font-size: 14px;
+ color: var(--color-ink-2, #4e5358);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.aksrt-pricing-card__features li::before {
+ content: '✓';
+ color: var(--color-success);
+ font-weight: 700;
+ font-size: 13px;
+}
+
+.aksrt-pricing-card__cta {
+ display: block;
+ width: 100%;
+}
+
+/* ============================================================
+ * 5. Toggle 开关 — .aksrt-toggle (纯 CSS + :checked)
+ * 保持原生 可访问性
+ * ============================================================ */
+.aksrt-toggle {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ cursor: pointer;
+ user-select: none;
+ gap: 8px;
+}
+
+.aksrt-toggle__input {
+ position: absolute;
+ opacity: 0;
+ width: 0;
+ height: 0;
+ pointer-events: none;
+}
+
+.aksrt-toggle__track {
+ position: relative;
+ width: var(--aksrt-toggle-w, 44px);
+ height: var(--aksrt-toggle-h, 24px);
+ background: var(--surface-3, #e8e8e8);
+ border-radius: var(--aksrt-toggle-h, 24px);
+ transition: background .2s ease;
+ flex-shrink: 0;
+}
+
+.aksrt-toggle__track::after {
+ content: '';
+ position: absolute;
+ top: 2px;
+ left: 2px;
+ width: calc(var(--aksrt-toggle-h, 24px) - 4px);
+ height: calc(var(--aksrt-toggle-h, 24px) - 4px);
+ background: #fff;
+ border-radius: 50%;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
+ transition: transform .2s ease;
+}
+
+/* Checked */
+.aksrt-toggle__input:checked + .aksrt-toggle__track {
+ background: var(--color-primary);
+}
+
+.aksrt-toggle__input:checked + .aksrt-toggle__track::after {
+ transform: translateX(calc(var(--aksrt-toggle-w, 44px) - var(--aksrt-toggle-h, 24px)));
+}
+
+/* Focus-visible */
+.aksrt-toggle__input:focus-visible + .aksrt-toggle__track {
+ box-shadow: var(--focus-ring, 0 0 2px 3px rgba(253, 83, 161, 0.4));
+}
+
+/* Disabled */
+.aksrt-toggle__input:disabled + .aksrt-toggle__track {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.aksrt-toggle__label {
+ font-size: 14px;
+ color: var(--color-ink-2, #4e5358);
+}
+
+/* ============================================================
+ * 6. 自定义复选框 — .aksrt-checkbox (纯 CSS + :checked)
+ * 保持原生 可访问性
+ * ============================================================ */
+.aksrt-checkbox {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ cursor: pointer;
+ user-select: none;
+}
+
+.aksrt-checkbox__input {
+ position: absolute;
+ opacity: 0;
+ width: 0;
+ height: 0;
+ pointer-events: none;
+}
+
+.aksrt-checkbox__box {
+ position: relative;
+ width: 18px;
+ height: 18px;
+ border: 2px solid var(--color-line, rgba(50, 50, 50, 0.15));
+ border-radius: 4px;
+ background: var(--surface-1, #fff);
+ transition: background .15s ease, border-color .15s ease;
+ flex-shrink: 0;
+}
+
+/* 打勾 SVG */
+.aksrt-checkbox__box::after {
+ content: '';
+ position: absolute;
+ top: 2px;
+ left: 5px;
+ width: 5px;
+ height: 9px;
+ border: 2px solid #fff;
+ border-top: none;
+ border-left: none;
+ transform: rotate(45deg) scale(0);
+ transition: transform .15s ease;
+}
+
+.aksrt-checkbox__input:checked + .aksrt-checkbox__box {
+ background: var(--color-primary);
+ border-color: var(--color-primary);
+}
+
+.aksrt-checkbox__input:checked + .aksrt-checkbox__box::after {
+ transform: rotate(45deg) scale(1);
+}
+
+.aksrt-checkbox__input:focus-visible + .aksrt-checkbox__box {
+ box-shadow: var(--focus-ring, 0 0 2px 3px rgba(253, 83, 161, 0.4));
+}
+
+.aksrt-checkbox__input:disabled + .aksrt-checkbox__box {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.aksrt-checkbox__label {
+ font-size: 14px;
+ color: var(--color-ink-2, #4e5358);
+}
+
+/* ============================================================
+ * 7. 数字步进器 — .aksrt-stepper
+ * ============================================================ */
+.aksrt-stepper {
+ display: inline-flex;
+ align-items: center;
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.1));
+ border-radius: var(--radius, 8px);
+ overflow: hidden;
+ height: var(--aksrt-stepper-h, 36px);
+}
+
+.aksrt-stepper__btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: var(--aksrt-stepper-h, 36px);
+ height: 100%;
+ background: var(--surface-2, #eee);
+ color: var(--color-ink-2, #4e5358);
+ border: none;
+ cursor: pointer;
+ font-size: 16px;
+ font-weight: 600;
+ transition: background .15s ease, color .15s ease;
+ user-select: none;
+}
+
+.aksrt-stepper__btn:hover {
+ background: var(--surface-3, #e8e8e8);
+ color: var(--color-ink, #333);
+}
+
+.aksrt-stepper__btn:disabled {
+ opacity: 0.4;
+ cursor: not-allowed;
+}
+
+.aksrt-stepper__input {
+ width: 48px;
+ height: 100%;
+ border: none;
+ text-align: center;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink, #333);
+ background: var(--surface-1, #fff);
+ -moz-appearance: textfield;
+}
+
+.aksrt-stepper__input::-webkit-outer-spin-button,
+.aksrt-stepper__input::-webkit-inner-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+.aksrt-stepper__input:focus {
+ outline: none;
+ background: var(--color-primary-softer, rgba(240, 68, 148, 0.05));
+}
+
+/* ============================================================
+ * 8. 头像尺寸变量系统 — .aksrt-avatar--{size}
+ * ============================================================ */
+.aksrt-avatar--xs { width: var(--aksrt-avatar-size-xs); height: var(--aksrt-avatar-size-xs); }
+.aksrt-avatar--sm { width: var(--aksrt-avatar-size-sm); height: var(--aksrt-avatar-size-sm); }
+.aksrt-avatar { width: var(--aksrt-avatar-size); height: var(--aksrt-avatar-size); }
+.aksrt-avatar--lg { width: var(--aksrt-avatar-size-lg); height: var(--aksrt-avatar-size-lg); }
+.aksrt-avatar--xl { width: var(--aksrt-avatar-size-xl); height: var(--aksrt-avatar-size-xl); }
+
+/* ============================================================
+ * 9. 涟漪点击效果 — .aksrt-ripple
+ * 容器加此类,点击时 JS 注入 span.aksrt-ripple__wave
+ * ============================================================ */
+.aksrt-ripple {
+ position: relative;
+ overflow: hidden;
+}
+
+.aksrt-ripple__wave {
+ position: absolute;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.35);
+ transform: scale(0);
+ animation: aksrtRippleWave .6s ease-out forwards;
+ pointer-events: none;
+}
+
+@keyframes aksrtRippleWave {
+ to {
+ transform: scale(4);
+ opacity: 0;
+ }
+}
+
+/* ============================================================
+ * 10. 模态框堆叠动画 — 父模态缩小
+ * ============================================================ */
+.modal-stacked .modal-dialog {
+ transition: transform .25s var(--ease, ease), filter .25s ease;
+}
+
+.modal-stacked .modal-dialog.modal-behind {
+ transform: scale(0.92);
+ filter: brightness(0.85);
+ pointer-events: none;
+}
diff --git a/assets/css/core/forms.css b/assets/css/core/forms.css
new file mode 100644
index 00000000..eef12925
--- /dev/null
+++ b/assets/css/core/forms.css
@@ -0,0 +1,142 @@
+/**
+ * AKSRT Forms — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll .form-control:
+ * - 灰色背景 (#f5f6f7)
+ * - 透明边框
+ * - 34px 高度
+ * - 8px 圆角
+ * - focus 时粉色边框 + 光晕
+ */
+
+/* ===== Field Wrapper ===== */
+.field {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ margin-bottom: var(--space-4);
+}
+
+.field-label {
+ font-size: var(--text-sm);
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.field-help {
+ font-size: var(--text-xs);
+ color: var(--color-ink-3);
+}
+
+.field-error {
+ font-size: var(--text-xs);
+ color: var(--color-error);
+}
+
+/* ===== Input / Textarea / Select — 对齐 zibll .form-control ===== */
+.input,
+.textarea,
+.select,
+input[type="text"].form-input,
+input[type="email"].form-input,
+input[type="password"].form-input,
+input[type="search"].form-input,
+input[type="url"].form-input,
+input[type="tel"].form-input,
+textarea.form-textarea,
+select.form-select {
+ width: 100%;
+ height: 34px;
+ padding: 6px 12px;
+ font-size: 14px;
+ color: var(--color-ink);
+ background: var(--surface-page);
+ border: 1px solid transparent;
+ border-radius: var(--radius);
+ transition: border-color var(--dur-fast) var(--ease),
+ box-shadow var(--dur-fast) var(--ease);
+}
+
+.textarea,
+textarea.form-textarea {
+ height: auto;
+ min-height: 120px;
+ padding: 12px;
+ line-height: var(--leading-snug);
+ resize: vertical;
+}
+
+.input:hover,
+.textarea:hover,
+.select:hover {
+ border-color: var(--color-primary);
+}
+
+.input:focus,
+.textarea:focus,
+.select:focus {
+ outline: none;
+ border-color: var(--color-primary);
+ box-shadow: 0 0 2px 3px rgba(253, 83, 161, 0.4);
+}
+
+.input::placeholder,
+.textarea::placeholder {
+ color: var(--color-ink-4);
+}
+
+/* ===== Select ===== */
+.select,
+select.form-select {
+ appearance: none;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23777' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
+ background-repeat: no-repeat;
+ background-position: right 12px center;
+ padding-right: 32px;
+}
+
+/* ===== Checkbox / Radio ===== */
+.checkbox,
+.radio {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ cursor: pointer;
+ font-size: var(--text-sm);
+ color: var(--color-ink-2);
+}
+
+.checkbox input,
+.radio input {
+ width: 16px;
+ height: 16px;
+ accent-color: var(--color-primary);
+ cursor: pointer;
+}
+
+/* ===== Input Group ===== */
+.input-group {
+ display: flex;
+ align-items: stretch;
+}
+
+.input-group .input {
+ border-radius: var(--radius) 0 0 var(--radius);
+}
+
+.input-group .btn {
+ border-radius: 0 var(--radius) var(--radius) 0;
+}
+
+/* ===== Form Layout ===== */
+.form-row {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: var(--space-4);
+}
+
+.form-actions {
+ display: flex;
+ gap: var(--space-3);
+ margin-top: var(--space-5);
+}
diff --git a/assets/css/core/reset.css b/assets/css/core/reset.css
new file mode 100644
index 00000000..0a381dab
--- /dev/null
+++ b/assets/css/core/reset.css
@@ -0,0 +1,128 @@
+/**
+ * AKSRT Reset
+ * 现代精简 reset,结合 box-sizing 与 a11y 友好的默认值。
+ */
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+}
+
+html {
+ font-size: 16px;
+ scroll-behavior: smooth;
+ -webkit-text-size-adjust: 100%;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ overflow-x: hidden;
+ text-rendering: optimizeLegibility;
+}
+
+body {
+ margin: 0;
+ font-family: var(--font-body);
+ font-size: var(--text-base);
+ line-height: var(--leading-normal);
+ background-color: var(--surface-page);
+ color: var(--color-ink-2);
+ transition: background-color 0.25s ease, color 0.25s ease;
+ overflow-x: hidden;
+}
+
+/* 媒体元素 */
+img,
+picture,
+video,
+canvas,
+svg {
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+
+/* 表单元素继承字体 */
+input,
+button,
+textarea,
+select {
+ font: inherit;
+ color: inherit;
+}
+
+button {
+ background: none;
+ border: 0;
+ padding: 0;
+ cursor: pointer;
+}
+
+/* 链接 */
+a {
+ color: inherit;
+ text-decoration: none;
+ transition: color var(--dur-fast) var(--ease);
+}
+
+a:hover {
+ color: var(--color-primary);
+}
+
+/* 焦点环:a11y 关键 */
+:focus {
+ outline: none;
+}
+
+:focus-visible {
+ outline: none;
+ box-shadow: var(--focus-ring);
+ border-radius: 4px;
+}
+
+/* 选区色 */
+::selection {
+ background: var(--color-primary-soft);
+ color: var(--color-ink);
+}
+
+/* 屏幕阅读器隐藏 */
+.screen-reader-text,
+.sr-only {
+ position: absolute !important;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border: 0;
+}
+
+.screen-reader-text:focus,
+.sr-only:focus {
+ position: fixed !important;
+ top: 16px;
+ left: 16px;
+ width: auto;
+ height: auto;
+ padding: 8px 16px;
+ background: var(--surface-1);
+ color: var(--color-ink);
+ z-index: 100000;
+ clip: auto;
+ box-shadow: var(--shadow-lg);
+ border-radius: var(--radius);
+}
+
+/* 减少动效偏好 */
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+}
diff --git a/assets/css/core/tokens.css b/assets/css/core/tokens.css
new file mode 100644
index 00000000..065f8b86
--- /dev/null
+++ b/assets/css/core/tokens.css
@@ -0,0 +1,429 @@
+/**
+ * AKSRT Design Tokens v7 — 1:1 Zibll Alignment
+ * ------------------------------------------------------------
+ * 单一真理源(Single Source of Truth)
+ * 所有颜色、字体、间距、动效都从此处读取,禁止在组件内硬编码。
+ * 严格对齐 zibll main.css 的视觉值。
+ */
+
+:root {
+ /* ===== Primary — Zibll theme-color (#f04494 pink) ===== */
+ --color-primary: #f04494;
+ --color-primary-hover: #e0307e;
+ --color-primary-active: #c9206d;
+ --color-primary-soft: rgba(240, 68, 148, 0.10);
+ --color-primary-softer: rgba(240, 68, 148, 0.05);
+ --color-on-primary: #FFFFFF;
+
+ /* ===== Ink (text) — 对齐 zibll --key-color / --main-color / --muted-color ===== */
+ --color-ink: #333333; /* zibll --key-color */
+ --color-ink-2: #4e5358; /* zibll --main-color */
+ --color-ink-3: #777777; /* zibll --muted-color */
+ --color-ink-4: #999999; /* zibll --muted-2-color */
+
+ /* ===== Surface — 对齐 zibll --body-bg-color / --main-bg-color / --muted-bg-color ===== */
+ --surface-page: #f5f6f7; /* zibll --body-bg-color */
+ --surface-1: #FFFFFF; /* zibll --main-bg-color */
+ --surface-2: #eeeeee; /* zibll --muted-bg-color */
+ --surface-3: #e8e8e8; /* 输入框 / code */
+
+ /* ===== Borders — 对齐 zibll --main-border-color ===== */
+ --color-line: rgba(50, 50, 50, 0.06);
+ --color-line-soft: rgba(0, 0, 0, 0.03);
+
+ /* ===== State colors ===== */
+ --color-success: #10B981;
+ --color-warning: #F59E0B;
+ --color-error: #EF4444;
+ --color-info: #3B82F6;
+
+ /* ===== Accent (action green — zibll tabbar/CTA) ===== */
+ --color-accent: #18a058;
+ --color-accent-soft: rgba(24, 160, 88, 0.12);
+ --color-accent-shadow: rgba(24, 160, 88, 0.28);
+
+ /* ===== Fonts — 对齐 zibll(系统默认字体栈)===== */
+ --font-display: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
+ --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
+ --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
+ --font-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+
+ /* ===== Type scale ===== */
+ --text-xs: 0.75rem; /* 12 */
+ --text-sm: 0.875rem; /* 14 */
+ --text-base: 1rem; /* 16 */
+ --text-md: 1.125rem; /* 18 */
+ --text-lg: 1.25rem; /* 20 */
+ --text-xl: 1.5rem; /* 24 */
+ --text-2xl: 1.875rem; /* 30 */
+ --text-3xl: 2.25rem; /* 36 */
+ --text-4xl: 3rem; /* 48 */
+ --text-5xl: 3.75rem; /* 60 */
+ --leading-tight: 1.2;
+ --leading-snug: 1.4;
+ --leading-normal: 1.6; /* zibll body line-height */
+ --leading-relaxed: 1.6;
+
+ /* ===== Spacing (4px base) ===== */
+ --space-1: 4px;
+ --space-2: 8px;
+ --space-3: 12px;
+ --space-4: 16px;
+ --space-5: 20px;
+ --space-6: 24px;
+ --space-7: 32px;
+ --space-8: 40px;
+ --space-9: 48px;
+ --space-10: 64px;
+ --space-11: 80px;
+ --space-12: 96px;
+
+ /* ===== Radius — 对齐 zibll --main-radius: 8px ===== */
+ --radius-sm: 4px;
+ --radius: 8px;
+ --radius-lg: 8px;
+ --radius-xl: 12px;
+ --radius-pill: 100px;
+ --radius-avatar: 50%;
+
+ /* ===== Shadows — 对齐 zibll --main-shadow: rgba(116,116,116,0.08) ===== */
+ --shadow-sm: 0 0 10px rgba(116, 116, 116, 0.08);
+ --shadow: 0 0 10px rgba(116, 116, 116, 0.08);
+ --shadow-lg: 0 0 10px rgba(116, 116, 116, 0.12);
+ --shadow-drawer: 0 8px 40px rgba(0, 0, 0, 0.20);
+
+ /* ===== Layout — 对齐 zibll --mian-max-width: 1200px ===== */
+ --nav-height: 60px;
+ --container: 1200px;
+ --container-wide: 1440px;
+ --container-read: 720px;
+ --container-page: 860px;
+ --sidebar-width: 311px;
+ --content-gap: 48px;
+ --sidebar-bp: 992px;
+
+ /* ===== Motion ===== */
+ --ease: cubic-bezier(.4, 0, .2, 1);
+ --ease-out: cubic-bezier(.16, 1, .3, 1);
+ --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
+ --dur-fast: 0.15s;
+ --dur: 0.25s;
+ --dur-slow: 0.4s;
+
+ /* ===== Focus Ring — 对齐 zibll focus-shadow-color ===== */
+ --focus-ring: 0 0 2px 3px rgba(253, 83, 161, 0.4);
+
+ /* ===== Z-index layers ===== */
+ --z-dropdown: 100;
+ --z-sticky: 200;
+ --z-fixed: 300;
+ --z-overlay: 400;
+ --z-modal: 500;
+ --z-popover: 600;
+ --z-toast: 700;
+ --z-tooltip: 800;
+
+ /* ===== Button sizes — 对齐 zibll ===== */
+ --radius-btn: 4px;
+ --btn-sm-h: 28px;
+ --btn-md-h: 34px;
+ --btn-lg-h: 44px;
+
+ /* ===== Card density — 对齐 zibll .box-body { padding: 15px } ===== */
+ --card-padding: 15px;
+ --card-padding-sm: 10px;
+ --card-gap: 16px;
+
+ /* ===== Skeleton loader ===== */
+ --skeleton-base: var(--surface-2);
+ --skeleton-shine: var(--surface-1);
+
+ /* ===== Extended tokens (used by components) ===== */
+ --color-primary-light: var(--color-primary-soft);
+ --color-surface: var(--surface-1);
+ --color-line-strong: var(--color-line);
+ --color-bg-hover: var(--surface-2);
+ --color-border-light: var(--color-line-soft);
+ --color-fill: var(--surface-2);
+ --color-warning-bg: #fffbe6;
+ --color-warning-text: #ad6800;
+
+ --text-secondary: var(--color-ink-3);
+ --text-tertiary: var(--color-ink-4);
+
+ --surface-active: var(--surface-2);
+ --surface-card: var(--surface-1);
+ --surface-hover: var(--surface-2);
+ --surface-secondary: var(--surface-2);
+
+ --radius-code: var(--radius);
+ --radius-full: 100px;
+ --shadow-xl: 0 0 10px rgba(116, 116, 116, 0.12);
+ --space-16: 64px;
+ --z-floating: 900;
+
+ --transition-fast: 0.15s ease;
+ --transition-base: 0.25s ease;
+
+ /* ===== Composite / Context tokens — 对齐 zibll ===== */
+ --header-bg: var(--blur-bg);
+ --header-color: var(--color-ink-2);
+ --footer-bg: var(--surface-1);
+ --footer-color: var(--color-ink-4);
+ --blur-bg: rgba(255, 255, 255, 0.80);
+ --float-btn-bg: rgba(200, 200, 200, 0.40);
+
+ /* ===== AKSRT-to-AKSRT canonical aliases ===== */
+ --content-max: var(--container);
+ --font-heading: var(--font-ui);
+ --radius-card: var(--radius);
+ --radius-md: var(--radius);
+ --color-primary-50: var(--color-primary-soft);
+ --color-primary-dark: var(--color-primary-active);
+ --shadow-md: var(--shadow);
+ --mini-radius: calc(var(--radius) / 1.4);
+ --single-cover-scale: 35%;
+
+ /* ===== Avatar size system — Zibll --this-size 等价 ===== */
+ --aksrt-avatar-size-xs: 24px;
+ --aksrt-avatar-size-sm: 32px;
+ --aksrt-avatar-size: 40px;
+ --aksrt-avatar-size-lg: 56px;
+ --aksrt-avatar-size-xl: 80px;
+
+ /* ===== Post card thumbnail scale ===== */
+ --aksrt-card-thumb-scale: 56.25%; /* 16:9 */
+
+ /* ===== Multi-color palette (for buttons / badges / gradients) ===== */
+ --aksrt-rose: #f43f5e;
+ --aksrt-rose-soft: rgba(244, 63, 94, 0.12);
+ --aksrt-blue: #3b82f6;
+ --aksrt-blue-soft: rgba(59, 130, 246, 0.12);
+ --aksrt-green: #10b981;
+ --aksrt-green-soft: rgba(16, 185, 129, 0.12);
+ --aksrt-orange: #f97316;
+ --aksrt-orange-soft:rgba(249, 115, 22, 0.12);
+ --aksrt-purple: #8b5cf6;
+ --aksrt-purple-soft:rgba(139, 92, 246, 0.12);
+ --aksrt-cyan: #06b6d4;
+ --aksrt-cyan-soft: rgba(6, 182, 212, 0.12);
+ --aksrt-yellow: #eab308;
+ --aksrt-yellow-soft:rgba(234, 179, 8, 0.12);
+ --aksrt-red: #ef4444;
+ --aksrt-red-soft: rgba(239, 68, 68, 0.12);
+ --aksrt-teal: #14b8a6;
+ --aksrt-teal-soft: rgba(20, 184, 166, 0.12);
+ --aksrt-indigo: #6366f1;
+ --aksrt-indigo-soft:rgba(99, 102, 241, 0.12);
+ --aksrt-pink: #ec4899;
+ --aksrt-pink-soft: rgba(236, 72, 153, 0.12);
+
+ /* ===== VIP / special gradients ===== */
+ --aksrt-vip-gold-1: #f6d365;
+ --aksrt-vip-gold-2: #fda085;
+ --aksrt-grad-sunset-1: #f093fb;
+ --aksrt-grad-sunset-2: #f5576c;
+ --aksrt-grad-ocean-1: #4facfe;
+ --aksrt-grad-ocean-2: #00f2fe;
+ --aksrt-grad-forest-1: #43e97b;
+ --aksrt-grad-forest-2: #38f9d7;
+ --aksrt-grad-night-1: #a18cd1;
+ --aksrt-grad-night-2: #fbc2eb;
+ --aksrt-grad-fire-1: #f83600;
+ --aksrt-grad-fire-2: #f9d423;
+
+ /* ===== Component sizing ===== */
+ --aksrt-toggle-w: 44px;
+ --aksrt-toggle-h: 24px;
+ --aksrt-stepper-h: 36px;
+ --aksrt-badge-h: 22px;
+
+ /* ===== Legacy name bridge ===== */
+ --text-1: var(--color-ink);
+ --text-2: var(--color-ink-2);
+ --text-3: var(--color-ink-3);
+ --border: var(--color-line);
+ --color-text-1: var(--color-ink);
+ --color-text-2: var(--color-ink-2);
+ --color-text-3: var(--color-ink-3);
+ --color-primary-bg: var(--color-primary-softer);
+ --color-danger: var(--color-error);
+}
+
+/* ============================================================
+ * Blur-bg fallback cascade (mirrors zibll behaviour)
+ * ============================================================ */
+@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
+ :root {
+ --blur-bg: var(--surface-1);
+ --header-bg: var(--surface-1);
+ }
+}
+
+@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
+ html.dark,
+ body.dark-theme {
+ --blur-bg: #37383a;
+ --header-bg: #37383a;
+ }
+}
+
+body.modal-open,
+body.dialog-open {
+ --blur-bg: var(--surface-1);
+ --header-bg: var(--surface-1);
+}
+
+body.modal-open .site-nav,
+body.modal-open .footer-tabbar,
+body.modal-open .float-right .float-btn,
+body.dialog-open .site-nav,
+body.dialog-open .footer-tabbar,
+body.dialog-open .float-right .float-btn {
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
+}
+
+html.dark body.modal-open,
+html.dark body.dialog-open,
+body.dark-theme body.modal-open,
+body.dark-theme body.dialog-open {
+ --blur-bg: #37383a;
+ --header-bg: #37383a;
+}
+
+/* ============================================================
+ * Multi-level container responsive — 对齐 zibll --mian-max-width
+ * 不同视口宽度下容器自动调整
+ * ============================================================ */
+@media (min-width: 992px) {
+ :root {
+ --container: 960px;
+ }
+}
+
+@media (min-width: 1200px) {
+ :root {
+ --container: 1140px;
+ }
+}
+
+@media (min-width: 1400px) {
+ :root {
+ --container: 1200px;
+ }
+}
+
+/* ============================================================
+ * Dark Theme — 对齐 zibll .dark-theme (#292a2d 范围)
+ * ============================================================ */
+html.dark {
+ --color-ink: #f8fafc;
+ --color-ink-2: #e5eef7;
+ --color-ink-3: #b4b6bb;
+ --color-ink-4: #888a8f;
+
+ --surface-page: #292a2d;
+ --surface-1: #323335;
+ --surface-2: #2d2e31;
+ --surface-3: #3a3b3e;
+
+ --color-line: rgba(114, 114, 114, 0.1);
+ --color-line-soft: rgba(184, 184, 184, 0.02);
+
+ --color-primary-soft: rgba(240, 68, 148, 0.16);
+ --color-primary-softer: rgba(240, 68, 148, 0.08);
+
+ --color-primary-light: var(--color-primary-soft);
+ --color-surface: var(--surface-1);
+ --color-line-strong: var(--color-line);
+ --color-bg-hover: var(--surface-2);
+ --color-border-light: var(--color-line-soft);
+ --color-fill: var(--surface-2);
+
+ --text-secondary: var(--color-ink-3);
+ --text-tertiary: var(--color-ink-4);
+
+ --surface-active: var(--surface-2);
+ --surface-card: var(--surface-1);
+ --surface-hover: var(--surface-2);
+ --surface-secondary: var(--surface-2);
+
+ --shadow-xl: 0 0 10px rgba(24, 24, 24, 0.15);
+
+ --shadow-sm: 0 0 10px rgba(24, 24, 24, 0.1);
+ --shadow: 0 0 10px rgba(24, 24, 24, 0.1);
+ --shadow-lg: 0 0 10px rgba(24, 24, 24, 0.15);
+ --shadow-drawer: 0 8px 40px rgba(0, 0, 0, 0.55);
+
+ --blur-bg: rgba(50, 51, 53, 0.80);
+ --float-btn-bg: rgba(70, 70, 70, 0.40);
+ --header-bg: var(--blur-bg);
+ --footer-bg: var(--surface-1);
+ --footer-color: var(--color-ink-4);
+ --shadow-md: var(--shadow);
+
+ --skeleton-base: #3a3b3e;
+ --skeleton-shine: #444548;
+
+ /* Multi-color palette — dark mode: same hue, softer tint backgrounds */
+ --aksrt-rose-soft: rgba(244, 63, 94, 0.18);
+ --aksrt-blue-soft: rgba(59, 130, 246, 0.18);
+ --aksrt-green-soft: rgba(16, 185, 129, 0.18);
+ --aksrt-orange-soft:rgba(249, 115, 22, 0.18);
+ --aksrt-purple-soft:rgba(139, 92, 246, 0.18);
+ --aksrt-cyan-soft: rgba(6, 182, 212, 0.18);
+ --aksrt-yellow-soft:rgba(234, 179, 8, 0.18);
+ --aksrt-red-soft: rgba(239, 68, 68, 0.18);
+ --aksrt-teal-soft: rgba(20, 184, 166, 0.18);
+ --aksrt-indigo-soft:rgba(99, 102, 241, 0.18);
+ --aksrt-pink-soft: rgba(236, 72, 153, 0.18);
+}
+
+/* Dark mode component refinements */
+html.dark .site-nav {
+ border-bottom-color: var(--color-line);
+ box-shadow: none;
+}
+
+html.dark .footer-tabbar {
+ background: rgba(50, 51, 53, 0.80);
+ box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.20);
+}
+
+html.dark .n-drawer,
+html.dark .n-modal,
+html.dark .n-dialog {
+ background: var(--surface-1);
+}
+
+html.dark .post-card,
+html.dark .widget,
+html.dark .aksrt-theme-box,
+html.dark .theme-box {
+ border-color: var(--color-line);
+}
+
+/* body.dark-theme — zibll compatibility alias for html.dark */
+body.dark-theme .site-nav {
+ border-bottom-color: var(--color-line);
+ box-shadow: none;
+}
+
+body.dark-theme .footer-tabbar {
+ background: rgba(50, 51, 53, 0.80);
+ box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.20);
+}
+
+body.dark-theme .n-drawer,
+body.dark-theme .n-modal,
+body.dark-theme .n-dialog {
+ background: var(--surface-1);
+}
+
+body.dark-theme .post-card,
+body.dark-theme .widget,
+body.dark-theme .aksrt-theme-box,
+body.dark-theme .theme-box {
+ border-color: var(--color-line);
+}
diff --git a/assets/css/core/typography.css b/assets/css/core/typography.css
new file mode 100644
index 00000000..44425457
--- /dev/null
+++ b/assets/css/core/typography.css
@@ -0,0 +1,211 @@
+/**
+ * AKSRT Typography — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll main.css 的排版系统
+ */
+
+/* ===== 全局标题 — 对齐 zibll line 8947 ===== */
+h1, h2, h3, h4, h5, h6 {
+ font-weight: 700;
+ margin: 20px 0 10px;
+ color: var(--key-color, #333);
+}
+
+h1 { font-size: 22px; }
+h2 { font-size: 20px; }
+h3 { font-size: 18px; }
+h4 { font-size: 16px; }
+h5 { font-size: 15px; }
+h6 { font-size: 14px; }
+
+/* ===== 文章正文 — 对齐 zibll line 8740 ===== */
+.wp-posts-content,
+.entry-content,
+.prose {
+ font-size: 16px;
+ line-height: 2;
+ color: var(--main-color, #4e5358);
+ min-height: 90px;
+}
+
+/* ===== 文章内标题 — 对齐 zibll line 8947 ===== */
+.wp-posts-content h1,
+.wp-posts-content h2,
+.wp-posts-content h3,
+.wp-posts-content h4,
+.wp-posts-content h5,
+.entry-content h1,
+.entry-content h2,
+.entry-content h3,
+.entry-content h4,
+.entry-content h5,
+.prose h1,
+.prose h2,
+.prose h3,
+.prose h4,
+.prose h5 {
+ font-weight: 700;
+ margin: 20px 0 10px;
+ color: var(--key-color, #333);
+}
+
+.wp-posts-content h1,
+.entry-content h1,
+.prose h1 { font-size: 22px; }
+
+.wp-posts-content h2,
+.entry-content h2,
+.prose h2 { font-size: 20px; }
+
+.wp-posts-content h3,
+.entry-content h3,
+.prose h3 { font-size: 18px; }
+
+.wp-posts-content h4,
+.entry-content h4,
+.prose h4 { font-size: 16px; }
+
+/* ===== 段落 — 对齐 zibll line 8999 ===== */
+.wp-posts-content p,
+.entry-content p,
+.prose p {
+ margin: 0 0 20px;
+ word-wrap: break-word;
+}
+
+/* ===== 链接 — 对齐 zibll line 8836 ===== */
+.wp-posts-content a,
+.entry-content a,
+.prose a {
+ color: var(--focus-color, #f04494);
+ text-decoration: none;
+}
+
+.wp-posts-content a:hover,
+.entry-content a:hover,
+.prose a:hover {
+ color: var(--focus-color, #f04494);
+}
+
+/* ===== 图片 — 对齐 zibll line 8850 ===== */
+.wp-posts-content img,
+.entry-content img,
+.prose img {
+ max-width: 100%;
+ height: auto;
+ display: block;
+ margin: auto;
+}
+
+/* ===== 内联代码 — 对齐 zibll line 8844 ===== */
+.wp-posts-content code:not(pre code),
+.entry-content code:not(pre code),
+.prose code:not(pre code) {
+ color: #ff3c98;
+ background: rgba(253, 153, 153, 0.2);
+ font-family: var(--font-mono, monospace);
+ font-size: 0.9em;
+}
+
+/* ===== 代码块 — 对齐 zibll ===== */
+.wp-posts-content pre,
+.entry-content pre,
+.prose pre {
+ position: relative;
+ background: #282c34;
+ color: #abb2bf;
+ padding: 15px;
+ border-radius: var(--main-radius, 8px);
+ overflow-x: auto;
+ font-size: 14px;
+ line-height: 1.5;
+ margin: 0 0 20px;
+}
+
+.wp-posts-content pre code,
+.entry-content pre code,
+.prose pre code {
+ color: inherit;
+ background: none;
+ padding: 0;
+ font-size: inherit;
+}
+
+/* ===== 表格 — 对齐 zibll line 8897 ===== */
+.wp-posts-content table,
+.entry-content table,
+.prose table {
+ font-size: 14px;
+ width: 100%;
+ border-collapse: collapse;
+ margin: 0 0 20px;
+}
+
+.wp-posts-content th,
+.wp-posts-content td,
+.entry-content th,
+.entry-content td,
+.prose th,
+.prose td {
+ border: 1px solid var(--main-border-color, rgba(50, 50, 50, 0.06));
+ padding: 8px;
+}
+
+.wp-posts-content th,
+.entry-content th,
+.prose th {
+ background: var(--muted-border-color, rgba(0, 0, 0, 0.03));
+ font-weight: 700;
+}
+
+.wp-posts-content tr:hover,
+.entry-content tr:hover,
+.prose tr:hover {
+ background-color: rgba(240, 68, 148, 0.05);
+}
+
+/* ===== 列表 — 对齐 zibll line 8977 ===== */
+.wp-posts-content ul,
+.wp-posts-content ol,
+.entry-content ul,
+.entry-content ol,
+.prose ul,
+.prose ol {
+ margin: 10px 0 20px 15px;
+ padding-left: 15px;
+}
+
+.wp-posts-content li,
+.entry-content li,
+.prose li {
+ margin-bottom: 10px;
+}
+
+/* ===== 引用 — 对齐 zibll line 680 ===== */
+.wp-posts-content blockquote,
+.entry-content blockquote,
+.prose blockquote {
+ padding: 15px 20px;
+ margin: 0 0 20px;
+ border-left: 4px solid var(--main-border-color, rgba(50, 50, 50, 0.06));
+ background: var(--muted-border-color, rgba(0, 0, 0, 0.03));
+ font-size: 16px;
+ color: var(--muted-color, #777);
+ border-radius: 0;
+}
+
+.wp-posts-content blockquote p:last-child,
+.entry-content blockquote p:last-child,
+.prose blockquote p:last-child {
+ margin-bottom: 0;
+}
+
+/* ===== 水平分割线 — 对齐 zibll line 676 ===== */
+hr {
+ border-color: var(--main-border-color, rgba(50, 50, 50, 0.06));
+}
+
+/* ===== Strong / Bold ===== */
+strong, b {
+ font-weight: 700;
+}
diff --git a/assets/css/frontend/ajax-spinner.css b/assets/css/frontend/ajax-spinner.css
new file mode 100644
index 00000000..0b72a476
--- /dev/null
+++ b/assets/css/frontend/ajax-spinner.css
@@ -0,0 +1,114 @@
+/* ========== AJAX 加载指示器 — 对齐 zibll loading spinner ========== */
+.aksrt-loading {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 40px 20px;
+ color: var(--color-ink-4, #999);
+ font-size: 13px;
+ gap: 8px;
+}
+
+.aksrt-loading__spinner {
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ border: 2px solid var(--surface-3, #e8e8e8);
+ border-top-color: var(--color-primary, #f04494);
+ border-radius: 50%;
+ animation: aksrt-spin 0.6s linear infinite;
+}
+
+@keyframes aksrt-spin {
+ to { transform: rotate(360deg); }
+}
+
+/* 全屏加载遮罩 */
+.aksrt-loading-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(255, 255, 255, 0.8);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 9999;
+ backdrop-filter: blur(2px);
+}
+
+.aksrt-loading-overlay__content {
+ text-align: center;
+}
+
+.aksrt-loading-overlay__spinner {
+ width: 36px;
+ height: 36px;
+ border: 3px solid var(--surface-3, #e8e8e8);
+ border-top-color: var(--color-primary, #f04494);
+ border-radius: 50%;
+ animation: aksrt-spin 0.6s linear infinite;
+ margin: 0 auto 12px;
+}
+
+.aksrt-loading-overlay__text {
+ font-size: 13px;
+ color: var(--color-ink-3, #777);
+}
+
+/* 行内加载(替换内容时) */
+.aksrt-loading-inline {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+ color: var(--color-ink-4, #999);
+ font-size: 12px;
+ gap: 6px;
+}
+
+.aksrt-loading-inline__dot {
+ width: 6px;
+ height: 6px;
+ background: var(--color-primary, #f04494);
+ border-radius: 50%;
+ animation: aksrt-dot-pulse 1.2s ease-in-out infinite;
+}
+
+.aksrt-loading-inline__dot:nth-child(2) {
+ animation-delay: 0.2s;
+}
+
+.aksrt-loading-inline__dot:nth-child(3) {
+ animation-delay: 0.4s;
+}
+
+@keyframes aksrt-dot-pulse {
+ 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); }
+ 40% { opacity: 1; transform: scale(1); }
+}
+
+/* 页面加载进度条 */
+.aksrt-progress-bar {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 2px;
+ background: var(--color-primary, #f04494);
+ z-index: 10000;
+ transition: width 0.3s ease;
+}
+
+/* 减弱动画偏好 */
+@media (prefers-reduced-motion: reduce) {
+ .aksrt-loading__spinner,
+ .aksrt-loading-overlay__spinner {
+ animation-duration: 1.5s;
+ }
+
+ .aksrt-loading-inline__dot {
+ animation: none;
+ opacity: 0.6;
+ }
+}
diff --git a/assets/css/frontend/base.css b/assets/css/frontend/base.css
new file mode 100644
index 00000000..ebc1807f
--- /dev/null
+++ b/assets/css/frontend/base.css
@@ -0,0 +1,99 @@
+/**
+ * AKSRT Main v5 — 博客/个人站完整前端
+ */
+
+/* 防止 hero 等使用 100vw / full-bleed 时产生横向滚动条 */
+html,
+body {
+ overflow-x: clip;
+}
+
+@supports not (overflow-x: clip) {
+ html,
+ body {
+ overflow-x: hidden;
+ }
+}
+
+/* ========== 阅读进度条(单篇文章顶 fixed)========== */
+.reading-progress-bar {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 3px;
+ width: 0%;
+ z-index: 9999;
+ pointer-events: none;
+ background: linear-gradient(90deg, var(--color-primary), var(--color-primary-light));
+ transition: width 0.1s ease-out;
+}
+
+/* 折叠 body 内注入的 BOM / 空白文本节点,防止产生多余行高间距 */
+body {
+ font-family: var(--font-body);
+ font-size: var(--text-base);
+ line-height: var(--leading-normal);
+ color: var(--color-ink-2);
+ background-color: var(--surface-page);
+}
+
+/* zibll compat: global link composite transition */
+a[href] {
+ transition: color 0.2s, background 0.3s, opacity 0.3s, box-shadow 0.3s, transform 0.3s;
+}
+
+.skip-link {
+ position: absolute;
+ left: 16px;
+ top: 12px;
+ z-index: 1100;
+ padding: 10px 14px;
+ border-radius: 999px;
+ background: var(--color-primary);
+ color: #fff;
+ transform: translateY(-140%);
+ transition: transform 0.2s ease;
+}
+
+.skip-link:focus {
+ transform: translateY(0);
+}
+
+/* ========== 站点外壳 ========== */
+.site-wrapper {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ font-size: var(--text-base);
+ line-height: var(--leading-normal);
+}
+
+.site-main {
+ flex: 1;
+}
+
+.container {
+ width: 100%;
+ max-width: var(--container);
+ margin: 0 auto;
+ padding: 0 16px;
+}
+
+@media (min-width: 768px) {
+ .container {
+ padding: 0 24px;
+ }
+}
+
+@media (min-width: 1200px) {
+ .container {
+ padding: 0 32px;
+ }
+}
+
+/* ========== 通用空状态 ========== */
+.no-results {
+ padding: 48px 20px;
+ text-align: center;
+ color: var(--color-ink-3);
+}
diff --git a/assets/css/frontend/breadcrumb.css b/assets/css/frontend/breadcrumb.css
new file mode 100644
index 00000000..a5603001
--- /dev/null
+++ b/assets/css/frontend/breadcrumb.css
@@ -0,0 +1,76 @@
+/* ========== 面包屑导航 — 对齐 zibll breadcrumb ========== */
+.breadcrumb-nav {
+ font-size: 13px;
+ padding: 0 8px;
+ margin-bottom: 12px;
+ opacity: 0.6;
+ line-height: 1.8;
+}
+
+.breadcrumb-nav ol,
+.breadcrumb-nav ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 0;
+}
+
+.breadcrumb-nav li {
+ display: inline-flex;
+ align-items: center;
+}
+
+.breadcrumb-nav li + li::before {
+ content: '/';
+ padding: 0 0 0 6px;
+ opacity: 0.6;
+}
+
+.breadcrumb-nav a {
+ color: var(--color-ink-4, #999);
+ text-decoration: none;
+ transition: color 0.2s;
+}
+
+.breadcrumb-nav a:hover {
+ color: var(--color-primary, #f04494);
+}
+
+.breadcrumb-nav .current {
+ color: var(--color-ink-2, #4e5358);
+ font-weight: 500;
+}
+
+.single-cover-con .breadcrumb-nav,
+.single-cover-con .breadcrumb {
+ font-size: 13px;
+ margin: 5px 0 0 -6px;
+ opacity: unset;
+}
+
+/* 封面内面包屑 */
+.single-cover-con .breadcrumb-nav {
+ color: rgba(255, 255, 255, 0.7);
+}
+
+.single-cover-con .breadcrumb-nav a {
+ color: rgba(255, 255, 255, 0.7);
+}
+
+.single-cover-con .breadcrumb-nav a:hover {
+ color: #fff;
+}
+
+.single-cover-con .breadcrumb-nav .current {
+ color: #fff;
+}
+
+/* 移动端 */
+@media (max-width: 767px) {
+ .breadcrumb-nav {
+ font-size: 12px;
+ }
+}
diff --git a/assets/css/frontend/card-primitives.css b/assets/css/frontend/card-primitives.css
new file mode 100644
index 00000000..92cb32c1
--- /dev/null
+++ b/assets/css/frontend/card-primitives.css
@@ -0,0 +1,163 @@
+/**
+ * AKSRT Card Primitives — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll 的 .theme-box / .box-bg / .box-body / .box-header:
+ * 阴影优先,无边框,8px 圆角,15px 内边距。
+ *
+ * @package AKSRT
+ */
+
+/* ============================================================
+ * .aksrt-theme-box — 完整卡片原语(阴影 + 圆角 + 表面)
+ * 对齐 zibll .theme-box + .box-bg
+ * ============================================================ */
+.aksrt-theme-box {
+ border: none;
+ border-radius: var(--radius);
+ background: var(--surface-1);
+ box-shadow: var(--shadow-sm);
+ transition: box-shadow var(--dur) var(--ease);
+}
+
+.aksrt-theme-box:hover {
+ box-shadow: var(--shadow);
+}
+
+/* ============================================================
+ * .aksrt-box-bg — 表面原语(仅背景 + 阴影)
+ * ============================================================ */
+.aksrt-box-bg {
+ background-color: var(--surface-1);
+ box-shadow: var(--shadow-sm);
+}
+
+/* ============================================================
+ * .aksrt-box-body / .aksrt-box-header — 内边距区段
+ * 对齐 zibll .box-body / .box-header { padding: 15px }
+ * ============================================================ */
+.aksrt-box-body,
+.aksrt-box-header {
+ padding: var(--card-padding);
+}
+
+.aksrt-box-header {
+ border-bottom: 1px solid var(--color-line-soft);
+}
+
+.aksrt-box-header + .aksrt-box-body {
+ padding-top: 0;
+}
+
+.aksrt-box-body.notop,
+.aksrt-box-header.notop { padding-top: 0; }
+.aksrt-box-body.nobottom,
+.aksrt-box-header.nobottom { padding-bottom: 0; }
+
+/* ============================================================
+ * .aksrt-muted-box — 柔和背景嵌套
+ * 对齐 zibll .muted-box
+ * ============================================================ */
+.aksrt-muted-box {
+ background-color: var(--surface-2);
+ border-radius: var(--radius);
+ padding: var(--card-padding);
+}
+
+/* ============================================================
+ * .aksrt-noshadow — 去除阴影
+ * ============================================================ */
+.aksrt-noshadow {
+ box-shadow: none !important;
+}
+
+/* ============================================================
+ * Zibll 兼容别名
+ * ============================================================ */
+.theme-box {
+ background: var(--surface-1);
+ border: none;
+ border-radius: var(--radius);
+ box-shadow: var(--shadow-sm);
+ margin-bottom: 20px;
+ transition: box-shadow var(--dur) var(--ease);
+}
+
+.theme-box:hover {
+ box-shadow: var(--shadow);
+}
+
+.box-bg {
+ background-color: var(--surface-1);
+ box-shadow: var(--shadow-sm);
+}
+
+.box-body {
+ padding: var(--card-padding);
+}
+
+.box-header {
+ padding: var(--card-padding);
+ border-bottom: 1px solid var(--color-line-soft);
+}
+
+.box-header + .box-body {
+ padding-top: 0;
+}
+
+.radius8 {
+ border-radius: var(--radius);
+}
+
+.main-shadow {
+ box-shadow: var(--shadow);
+}
+
+.muted-box {
+ background-color: var(--surface-2);
+ border-radius: var(--radius);
+ padding: var(--card-padding);
+}
+
+/* ============================================================
+ * 暗色模式
+ * ============================================================ */
+html.dark .aksrt-theme-box,
+body.dark-theme .aksrt-theme-box,
+html.dark .theme-box,
+body.dark-theme .theme-box,
+html.dark .box-bg,
+body.dark-theme .box-bg {
+ box-shadow: var(--shadow-sm);
+}
+
+html.dark .aksrt-theme-box:hover,
+body.dark-theme .aksrt-theme-box:hover,
+html.dark .theme-box:hover,
+body.dark-theme .theme-box:hover {
+ box-shadow: var(--shadow);
+}
+
+/* ============================================================
+ * 卡片 hover 动效
+ * ============================================================ */
+.aksrt-theme-box,
+.theme-box {
+ transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
+}
+
+.aksrt-card-hover:hover,
+.aksrt-card-hover:focus-within {
+ box-shadow: none;
+ transform: none;
+}
+
+.aksrt-card-hover-lg:hover,
+.aksrt-card-hover-lg:focus-within {
+ box-shadow: var(--shadow-lg);
+ transform: translateY(-4px);
+}
+
+.aksrt-noshadow:hover {
+ box-shadow: none !important;
+ transform: none !important;
+}
diff --git a/assets/css/frontend/comment-tools.css b/assets/css/frontend/comment-tools.css
new file mode 100644
index 00000000..e46ff0b3
--- /dev/null
+++ b/assets/css/frontend/comment-tools.css
@@ -0,0 +1,281 @@
+/**
+ * AKSRT Comment Tools
+ *
+ * 评论工具栏样式:表情、代码、图片上传、快捷回复。
+ * 所有选择器均带 .comment- 或 .aksrt-comment- 命名空间。
+ */
+
+/* ========== 评论工具栏 ========== */
+.comment-toolbar {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 8px;
+ margin-bottom: 8px;
+ background: var(--surface-secondary, #f8f9fa);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+}
+
+.comment-toolbar__btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border: none;
+ border-radius: 6px;
+ background: transparent;
+ color: var(--text-secondary, #666);
+ font-size: 14px;
+ cursor: pointer;
+ transition: background-color 0.15s ease, color 0.15s ease;
+}
+
+.comment-toolbar__btn:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+ color: var(--color-primary);
+}
+
+.comment-toolbar__btn:disabled {
+ opacity: 0.4;
+ cursor: not-allowed;
+}
+
+.comment-toolbar__separator {
+ width: 1px;
+ height: 20px;
+ margin: 0 4px;
+ background: var(--color-line, #e8e8e8);
+}
+
+/* Server-side toolbar gating (comment_smilie / comment_code / comment_img):
+ the .comment-toolbar__btn display rule outranks the UA [hidden] rule, so an
+ attribute-qualified selector is needed to honor the rendered hidden state. */
+.comment-toolbar__btn[hidden],
+.comment-toolbar__separator[hidden] {
+ display: none;
+}
+
+/* ========== 表情选择器 ========== */
+.comment-emoji-picker {
+ position: absolute;
+ bottom: 100%;
+ left: 0;
+ z-index: 100;
+ width: 320px;
+ max-height: 240px;
+ padding: 12px;
+ background: var(--surface-page, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+ overflow-y: auto;
+}
+
+.comment-emoji-picker__grid {
+ display: grid;
+ grid-template-columns: repeat(8, 1fr);
+ gap: 4px;
+}
+
+.comment-emoji-picker__item {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border: none;
+ border-radius: 4px;
+ background: transparent;
+ font-size: 18px;
+ cursor: pointer;
+ transition: background-color 0.1s ease;
+}
+
+.comment-emoji-picker__item:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+}
+
+/* ========== 快捷回复 ========== */
+.comment-quick-reply {
+ padding: 8px 12px;
+ margin-top: 8px;
+ background: var(--surface-secondary, #f8f9fa);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+}
+
+.comment-quick-reply__title {
+ font-size: 12px;
+ font-weight: 600;
+ color: var(--text-secondary, #666);
+}
+
+.comment-quick-reply__templates {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+ margin-top: 6px;
+}
+
+.comment-quick-reply__template {
+ padding: 4px 10px;
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 16px;
+ background: var(--surface-page, #fff);
+ font-size: 12px;
+ color: var(--text-secondary, #666);
+ cursor: pointer;
+ transition: border-color 0.15s ease, color 0.15s ease;
+}
+
+.comment-quick-reply__template:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+/* ========== 评论代码块 ========== */
+.comment-form textarea code,
+.comment-content code {
+ padding: 2px 6px;
+ background: var(--surface-secondary, #f5f5f5);
+ border-radius: 4px;
+ font-family: var(--font-mono, 'Fira Code', monospace);
+ font-size: 0.875em;
+}
+
+.comment-form textarea pre,
+.comment-content pre {
+ padding: 12px;
+ background: var(--surface-secondary, #f5f5f5);
+ border-radius: 8px;
+ overflow-x: auto;
+ font-family: var(--font-mono, 'Fira Code', monospace);
+ font-size: 0.875em;
+ line-height: 1.6;
+}
+
+/* ========== 投稿页面增强 ========== */
+.aksrt-submit-form__cover-preview {
+ width: 100%;
+ max-width: 400px;
+ aspect-ratio: 16 / 9;
+ margin-top: 8px;
+ border-radius: 8px;
+ overflow: hidden;
+ background: var(--surface-secondary, #f5f5f5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.aksrt-submit-form__cover-preview img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.aksrt-submit-form__cover-placeholder {
+ color: var(--text-tertiary, #8a909c);
+ font-size: 13px;
+}
+
+.aksrt-submit-form__field-toggle {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 0;
+ font-size: 13px;
+ color: var(--text-secondary, #666);
+}
+
+.aksrt-submit-form__word-count {
+ margin-top: 4px;
+ font-size: 12px;
+ color: var(--text-tertiary, #8a909c);
+ text-align: right;
+}
+
+.aksrt-submit-form__leave-warning {
+ position: fixed;
+ bottom: 20px;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 9999;
+ padding: 12px 20px;
+ background: var(--color-warning-bg, #fffbe6);
+ border: 1px solid var(--color-warning, #faad14);
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ font-size: 13px;
+ color: var(--color-warning-text, #ad6800);
+}
+
+/* ========== Post Share Buttons ========== */
+.aksrt-share-bar {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+
+.aksrt-share-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 14px;
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 20px;
+ background: var(--surface-page, #fff);
+ color: var(--text-secondary, #666);
+ font-size: 13px;
+ text-decoration: none;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.aksrt-share-btn:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.06));
+}
+
+.aksrt-share-btn.is-copied {
+ border-color: #52c41a;
+ color: #52c41a;
+ background: #f6ffed;
+}
+
+.aksrt-share-btn--weibo:hover { border-color: #e6162d; color: #e6162d; }
+.aksrt-share-btn--qq:hover { border-color: #12b7f5; color: #12b7f5; }
+.aksrt-share-btn--wechat:hover { border-color: #07c160; color: #07c160; }
+.aksrt-share-btn--telegram:hover { border-color: #26a5e4; color: #26a5e4; }
+.aksrt-share-btn--twitter:hover { border-color: #1da1f2; color: #1da1f2; }
+
+/* Quick quote button */
+.aksrt-quick-quote {
+ position: fixed;
+ padding: 4px 12px;
+ background: var(--color-primary);
+ color: #fff;
+ border: none;
+ border-radius: 4px;
+ font-size: 12px;
+ cursor: pointer;
+ z-index: 9999;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ transition: background 0.2s;
+}
+
+.aksrt-quick-quote:hover {
+ background: var(--color-primary-hover, #40a9ff);
+}
+
+/* TOC active state */
+.aksrt-doc-toc__item.is-active > a,
+.aksrt-doc-toc__item a.is-active {
+ color: var(--color-primary);
+ font-weight: 600;
+ border-left-color: var(--color-primary);
+}
diff --git a/assets/css/frontend/comments.css b/assets/css/frontend/comments.css
new file mode 100644
index 00000000..a99081e4
--- /dev/null
+++ b/assets/css/frontend/comments.css
@@ -0,0 +1,614 @@
+/* ============================================================
+ * AKSRT Comments — v4.0 Zibll-Inspired
+ *
+ * 功能:
+ * - 评论表单(头像 + 输入框 + 操作栏)
+ * - 评论列表(嵌套回复 + 头像 + 时间)
+ * - 排序/过滤栏
+ * - 空状态
+ * - 移动端固定底部输入框(可选)
+ * ============================================================ */
+
+/* ============================================================
+ * 评论区容器
+ * ============================================================ */
+.comments-area {
+ margin: 0;
+ padding: 0;
+ /* 对齐 zibll: 45px */
+ --aksrt-comment-avatar: 45px;
+ --aksrt-comment-avatar-form: 45px;
+ --aksrt-comment-indent: 48px;
+}
+
+/* 评论标题 */
+.comments-header {
+ margin-bottom: 16px;
+}
+
+.comments-title {
+ font-size: 1rem;
+ font-weight: 700;
+ margin: 0;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--color-ink);
+}
+
+.comments-title i {
+ color: var(--color-primary);
+ font-size: 16px;
+}
+
+.comments-count {
+ font-size: 0.8125rem;
+ font-weight: 400;
+ color: var(--color-ink-4);
+}
+
+/* ============================================================
+ * 登录提示
+ * ============================================================ */
+.comment-login-prompt {
+ margin-bottom: 20px;
+}
+
+.comment-login-prompt__inner {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 16px;
+ border-radius: 8px;
+ background: var(--surface-3);
+ font-size: 14px;
+ color: var(--color-ink-4);
+}
+
+.comment-login-prompt__inner i {
+ font-size: 16px;
+ color: var(--color-ink-4);
+}
+
+.comment-login-prompt__btns {
+ margin-left: auto;
+ display: flex;
+ gap: 8px;
+}
+
+/* ============================================================
+ * 评论表单
+ * ============================================================ */
+.comment-respond {
+ margin-bottom: 20px;
+}
+
+.comment-form__inner {
+ display: flex;
+ gap: 12px;
+ align-items: flex-start;
+}
+
+.comment-form__avatar {
+ flex-shrink: 0;
+}
+
+.comment-form__avatar img {
+ width: var(--aksrt-comment-avatar-form);
+ height: var(--aksrt-comment-avatar-form);
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.comment-form__avatar-placeholder {
+ width: var(--aksrt-comment-avatar-form);
+ height: var(--aksrt-comment-avatar-form);
+ border-radius: 50%;
+ background: var(--surface-3);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--color-ink-4);
+}
+
+.comment-form__body {
+ flex: 1;
+ min-width: 0;
+}
+
+.comment-form__reply-info {
+ font-size: 0.8125rem;
+ color: var(--color-ink-4);
+ margin-bottom: 8px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.comment-form__cancel-reply {
+ color: var(--color-error, #ef4444);
+ font-size: 12px;
+}
+
+.comment-form__textarea {
+ width: 100%;
+ min-height: 80px;
+ resize: vertical;
+ border-radius: 8px;
+ border: 1px solid var(--color-line);
+ padding: 5px 5px 4px 5px;
+ font-size: 14px;
+ background: var(--main-bg-color, var(--surface-1));
+ color: var(--color-ink);
+ transition: border-color 0.2s ease, box-shadow 0.2s ease;
+}
+
+.comment-form__textarea:focus {
+ outline: none;
+ border-color: var(--color-primary);
+ box-shadow: none;
+}
+
+.comment-form__actions {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-top: 10px;
+ gap: 8px;
+}
+
+.comment-form__tools {
+ display: flex;
+ gap: 8px;
+}
+
+.comment-form__submit-area {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-left: auto;
+}
+
+.comment-form__guest-field {
+ width: 120px;
+ height: 32px;
+ font-size: 13px;
+}
+
+.comment-form__submit {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+}
+
+/* ============================================================
+ * 排序/过滤栏
+ * ============================================================ */
+.comment-filter {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px 0;
+ margin-bottom: 12px;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.comment-filter__tabs {
+ display: flex;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ gap: 4px;
+}
+
+.comment-filter__tabs li a {
+ display: inline-block;
+ padding: 4px 12px;
+ border-radius: 4px;
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--color-ink-4);
+ text-decoration: none;
+ transition: background 0.15s ease, color 0.15s ease;
+}
+
+.comment-filter__tabs li a:hover {
+ background: var(--surface-3);
+ color: var(--color-ink);
+}
+
+.comment-filter__tabs li.active a {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.12));
+ color: var(--color-primary);
+ font-weight: 600;
+}
+
+/* ============================================================
+ * 评论列表
+ * ============================================================ */
+.comment-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.comment-list .comment {
+ padding: 16px 0;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.comment-list .comment:last-child {
+ border-bottom: none;
+}
+
+/* 嵌套回复 — 对齐 zibll: 86px 缩进 + 灰色背景 */
+.comment-list .children {
+ list-style: none;
+ margin: 0;
+ margin-left: 86px;
+}
+
+.comment-list .children .comment {
+ padding: 10px;
+ background: var(--main-shadow, rgba(0, 0, 0, 0.03));
+ border-radius: var(--radius);
+}
+
+/* 深层嵌套缩进递减 */
+.comment-list .children .children {
+ margin-left: 13px;
+}
+
+/* 评论项内部结构(由 aksrt_comment_callback 渲染) */
+.aksrt-comment__body {
+ display: flex;
+ gap: 12px;
+}
+
+.aksrt-comment__avatar {
+ flex-shrink: 0;
+}
+
+.aksrt-comment__avatar img {
+ width: var(--aksrt-comment-avatar);
+ height: var(--aksrt-comment-avatar);
+ border-radius: 50%;
+ object-fit: cover;
+ margin-right: 20px;
+}
+
+.aksrt-comment__content {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-comment__header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 6px;
+ flex-wrap: wrap;
+}
+
+.aksrt-comment__author {
+ font-weight: 600;
+ font-size: 14px;
+ color: var(--color-ink);
+}
+
+.aksrt-comment__author a {
+ color: inherit;
+}
+
+.aksrt-comment__author a:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-comment__badge {
+ font-size: 10px;
+ padding: 1px 6px;
+ border-radius: 3px;
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.12));
+ color: var(--color-primary);
+ font-weight: 500;
+}
+
+.aksrt-comment__time {
+ font-size: 12px;
+ color: var(--color-ink-4);
+}
+
+.aksrt-comment__text {
+ font-size: 14px;
+ line-height: 1.6;
+ color: var(--color-ink);
+ margin: 0 0 8px;
+ word-wrap: break-word;
+ white-space: pre-wrap;
+}
+
+/* 对齐 zibll: 评论内图片限制 */
+.aksrt-comment__text img:not(.smilie-icon) {
+ max-width: 260px;
+ max-height: 350px;
+}
+
+.aksrt-comment__text p {
+ margin: 0 0 8px;
+}
+
+.aksrt-comment__text p:last-child {
+ margin-bottom: 0;
+}
+
+.aksrt-comment__actions {
+ display: flex;
+ gap: 12px;
+ font-size: 12px;
+}
+
+.aksrt-comment__actions a,
+.aksrt-comment__actions button {
+ color: var(--color-ink-4);
+ background: none;
+ border: none;
+ padding: 0;
+ cursor: pointer;
+ font-size: 12px;
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ transition: color 0.15s ease;
+}
+
+.aksrt-comment__actions a:hover,
+.aksrt-comment__actions button:hover {
+ color: var(--color-primary);
+}
+
+/* 嵌套回复中的头像更小 */
+/* 对齐 zibll: 嵌套头像 26px */
+.children .aksrt-comment__avatar img {
+ width: 26px;
+ height: 26px;
+ margin-right: 6px;
+ vertical-align: 2px;
+}
+
+/* ============================================================
+ * 空状态
+ * ============================================================ */
+.comments-empty {
+ text-align: center;
+ padding: 40px 20px;
+}
+
+.comments-empty__icon {
+ font-size: 48px;
+ color: var(--color-ink-4);
+ opacity: 0.4;
+ margin-bottom: 12px;
+}
+
+.comments-empty__text {
+ font-size: 1rem;
+ font-weight: 600;
+ color: var(--color-ink-4);
+ margin: 0 0 4px;
+}
+
+.comments-empty__hint {
+ font-size: 0.8125rem;
+ color: var(--color-ink-4);
+ margin: 0;
+}
+
+.comments-closed {
+ text-align: center;
+ font-size: 14px;
+ color: var(--color-ink-4);
+ padding: 20px;
+}
+
+/* ============================================================
+ * 评论分页
+ * ============================================================ */
+.comment-pagination {
+ text-align: center;
+ padding: 16px 0;
+}
+
+/* ============================================================
+ * 移动端适配
+ * ============================================================ */
+@media (max-width: 767px) {
+ .comment-form__inner {
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ .comment-form__avatar {
+ display: none;
+ }
+
+ .comment-form__submit-area {
+ flex-wrap: wrap;
+ }
+
+ .comment-form__guest-field {
+ width: 100%;
+ }
+
+ .comment-list .children {
+ margin-left: 0;
+ }
+
+ .children .aksrt-comment__avatar img {
+ width: 36px;
+ height: 36px;
+ }
+
+ /* 移动端评论输入吸底 — 模仿 zibll mobile-fixed */
+ .comment-respond.comment-form--mobile-fixed {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: var(--z-sticky, 200);
+ background: var(--surface-1);
+ border-top: 1px solid var(--color-line);
+ box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.08);
+ padding: 12px 16px;
+ padding-bottom: max(12px, env(safe-area-inset-bottom));
+ }
+
+ .comment-respond.comment-form--mobile-fixed .comment-form__textarea {
+ min-height: 44px;
+ max-height: 120px;
+ }
+
+ .comment-respond.comment-form--mobile-fixed .comment-form__submit-area {
+ margin-top: 8px;
+ }
+
+ /* 当评论区可见时隐藏吸底输入框 */
+ .comment-respond.comment-form--mobile-fixed.is-visible {
+ display: none;
+ }
+}
+
+/* ============================================================
+ * 暗色模式
+ * ============================================================ */
+html.dark .comment-form__textarea,
+body.dark-theme .comment-form__textarea {
+ background: var(--surface-2);
+ border-color: var(--color-line);
+}
+
+.theme-dark .comment-login-prompt__inner,
+html.dark .comment-login-prompt__inner,
+body.dark-theme .comment-login-prompt__inner {
+ background: var(--surface-1);
+}
+
+/* ============================================================
+ * 评论操作按钮(编辑/删除/审核)
+ * ============================================================ */
+.aksrt-comment-actions {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-top: 8px;
+}
+
+.aksrt-comment-action-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 3px 10px;
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.1));
+ border-radius: var(--radius, 8px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-3, #777);
+ font-size: 12px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.15s ease;
+}
+
+.aksrt-comment-action-btn:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+}
+
+.aksrt-comment-action-btn--danger:hover {
+ border-color: var(--color-error);
+ color: var(--color-error);
+ background: rgba(239, 68, 68, 0.08);
+}
+
+.aksrt-comment-action-btn--success:hover {
+ border-color: var(--color-success);
+ color: var(--color-success);
+ background: rgba(16, 185, 129, 0.08);
+}
+
+.aksrt-comment-edit-form {
+ margin: 8px 0;
+}
+
+.aksrt-comment-edit-textarea {
+ width: 100%;
+ min-height: 80px;
+ padding: 8px 12px;
+ border: 1px solid var(--color-line, #ddd);
+ border-radius: var(--radius, 8px);
+ font-size: 14px;
+ font-family: var(--font-body);
+ color: var(--color-ink);
+ background: var(--surface-1, #fff);
+ resize: vertical;
+ transition: border-color 0.15s;
+}
+
+.aksrt-comment-edit-textarea:focus {
+ outline: none;
+ border-color: var(--color-primary);
+}
+
+/* ============================================================
+ * 评论互动:点赞 / 置顶 / 内联管理动作(统一合同)
+ * 这些动作均渲染在 .aksrt-comment__actions 内,复用其文字链按钮样式,
+ * 仅补充点赞激活态、置顶徽章与危险/成功色提示。
+ * ============================================================ */
+.aksrt-comment__like.is-active,
+.aksrt-comment__like.is-active i {
+ color: var(--color-primary);
+}
+
+.aksrt-comment__like-count {
+ font-variant-numeric: tabular-nums;
+}
+
+.aksrt-comment__action--danger:hover {
+ color: var(--color-error, #ef4444);
+}
+
+.aksrt-comment__action--success:hover {
+ color: var(--color-success, #10b981);
+}
+
+/* 置顶徽章 */
+.aksrt-comment__badge--pinned {
+ background: var(--color-warning-soft, rgba(245, 158, 11, 0.14));
+ color: var(--color-warning, #d97706);
+ display: inline-flex;
+ align-items: center;
+ gap: 3px;
+}
+
+/* 置顶评论容器高亮 */
+.aksrt-comment--pinned > .aksrt-comment__body {
+ position: relative;
+}
+
+.comment-list .comment.aksrt-comment--pinned {
+ background: var(--color-warning-soft, rgba(245, 158, 11, 0.06));
+ border-radius: var(--radius, 8px);
+ padding-left: 12px;
+ padding-right: 12px;
+}
+
+/* zibll compat: emoji icon forced 30px */
+.comment-content .smilie-icon,
+.comment-form .smilie-icon {
+ width: 30px !important;
+}
+
+/* zibll compat: code block in comments */
+.comment-content .enlighter-default {
+ margin-bottom: 0;
+ opacity: 0.9;
+}
diff --git a/assets/css/frontend/credits.css b/assets/css/frontend/credits.css
new file mode 100644
index 00000000..68c8ae29
--- /dev/null
+++ b/assets/css/frontend/credits.css
@@ -0,0 +1,384 @@
+/**
+ * Credits · 顶部余额徽章 / 积分明细 / 签到 / 邀请共用样式
+ *
+ * 仅在已登录 + cms_features.download_credit 启用时加载。
+ */
+
+/* ============ 用户下拉中的余额块 ============ */
+.user-dropdown__credits {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 10px 16px;
+ color: var(--color-ink);
+ font: 500 13px/1 var(--font-ui);
+ background: linear-gradient(135deg, rgba(240, 68, 148, 0.08) 0%, rgba(240, 68, 148, 0.02) 100%);
+}
+
+.user-dropdown__credits i {
+ color: #f59e0b;
+ font-size: 14px;
+}
+
+.user-dropdown__credits-label {
+ color: var(--color-ink-2);
+}
+
+.user-dropdown__credits-value {
+ margin-left: auto;
+ font-weight: 700;
+ color: var(--color-primary);
+}
+
+/* ============ 积分明细列表(profile 用) ============ */
+.credits-log {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.credits-log__row {
+ display: grid;
+ grid-template-columns: auto 1fr auto auto;
+ gap: var(--space-3, 12px);
+ align-items: center;
+ padding: 12px 16px;
+ background: var(--surface-1);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+ font-size: 13px;
+}
+
+.credits-log__icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ background: var(--surface-2);
+ color: var(--color-ink-2);
+}
+
+.credits-log__icon.is-positive {
+ background: rgba(22, 163, 74, .1);
+ color: #16a34a;
+}
+
+.credits-log__icon.is-negative {
+ background: rgba(239, 68, 68, .1);
+ color: #ef4444;
+}
+
+.credits-log__reason {
+ color: var(--color-ink);
+ font-weight: 500;
+}
+
+.credits-log__remark {
+ font-weight: 400;
+ color: var(--color-ink-2);
+ font-size: 12px;
+}
+
+.credits-log__date {
+ color: var(--color-ink-3);
+ font-size: 12px;
+}
+
+.credits-log__delta {
+ font-weight: 700;
+ font-variant-numeric: tabular-nums;
+}
+
+.credits-log__delta.is-positive {
+ color: #16a34a;
+}
+
+.credits-log__delta.is-negative {
+ color: #ef4444;
+}
+
+/* ============ 余额卡片(profile 头部) ============ */
+.credits-card {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: space-between;
+ gap: 16px;
+ padding: 20px 24px;
+ border-radius: var(--radius-lg);
+ background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-active) 100%);
+ color: var(--color-on-primary);
+ margin-bottom: 20px;
+}
+
+.credits-card__info {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.credits-card__label {
+ font: 500 13px/1 var(--font-ui);
+ opacity: .85;
+}
+
+.credits-card__value {
+ font: 700 32px/1 var(--font-ui);
+ display: flex;
+ align-items: baseline;
+ gap: 6px;
+}
+
+.credits-card__unit {
+ font: 500 14px/1 var(--font-ui);
+ opacity: .85;
+}
+
+.credits-card__sign {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ flex-shrink: 0;
+}
+
+.credits-card__sign-status {
+ font: 500 13px/1.4 var(--font-ui);
+ opacity: .9;
+ max-width: 160px;
+ text-align: right;
+}
+
+.credits-card__sign .btn-primary {
+ background: rgba(255, 255, 255, .2);
+ border: 1px solid rgba(255, 255, 255, .3);
+ backdrop-filter: blur(4px);
+}
+
+.credits-card__sign .btn-primary:hover:not(:disabled) {
+ background: rgba(255, 255, 255, .35);
+}
+
+.credits-card__sign .btn-primary:disabled {
+ opacity: .5;
+ cursor: default;
+}
+
+/* ============ 签到 panel ============ */
+.aksrt-signin-status {
+ margin: 0 0 16px;
+ color: var(--color-ink-2);
+ font-size: 14px;
+ line-height: 1.6;
+}
+
+.aksrt-signin-status strong {
+ color: var(--color-primary);
+ font-weight: 700;
+}
+
+.aksrt-signin-tip {
+ margin: 0;
+ width: 100%;
+ color: var(--color-on-primary);
+ opacity: .85;
+ font-size: 13px;
+}
+
+/* ============ 邀请 panel ============ */
+.aksrt-invite-desc {
+ margin: 0 0 16px;
+ color: var(--color-ink-2);
+ font-size: 14px;
+}
+
+.aksrt-invite-link-row {
+ display: flex;
+ gap: 8px;
+ margin-bottom: 16px;
+}
+
+.aksrt-invite-link {
+ flex: 1 1 auto;
+ height: 36px;
+ padding: 0 12px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+ background: var(--surface-2);
+ color: var(--color-ink);
+ font: 500 13px/1 var(--font-mono, monospace);
+}
+
+.aksrt-invite-stats {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 12px;
+}
+
+.aksrt-invite-stats > div {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ padding: 12px;
+ background: var(--surface-2);
+ border-radius: var(--radius);
+ text-align: center;
+}
+
+.aksrt-invite-stats span {
+ color: var(--color-ink-3);
+ font: 500 12px/1 var(--font-ui);
+}
+
+.aksrt-invite-stats strong {
+ color: var(--color-primary);
+ font: 700 22px/1 var(--font-ui);
+ font-variant-numeric: tabular-nums;
+}
+
+/* ============ VIP 会员卡片 ============ */
+.uc-vip-card {
+ position: relative;
+ border-radius: var(--radius-lg, 12px);
+ overflow: hidden;
+ margin-bottom: 16px;
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
+ color: #fff;
+}
+
+.uc-vip-card--active {
+ background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
+}
+
+.uc-vip-card__bg {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 120px;
+ height: 120px;
+ background: radial-gradient(circle, rgba(255, 255, 255, .1) 0%, transparent 70%);
+ pointer-events: none;
+}
+
+.uc-vip-card__content {
+ position: relative;
+ padding: 20px;
+}
+
+.uc-vip-card__header {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin-bottom: 12px;
+}
+
+.uc-vip-card__icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, .15);
+ font-size: 18px;
+}
+
+.uc-vip-card--active .uc-vip-card__icon {
+ background: rgba(255, 255, 255, .25);
+}
+
+.uc-vip-card__info {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.uc-vip-card__label {
+ font: 700 16px/1 var(--font-ui);
+}
+
+.uc-vip-card__status {
+ font: 500 12px/1 var(--font-ui);
+ opacity: .8;
+}
+
+.uc-vip-card__status--active {
+ color: #4ade80;
+ opacity: 1;
+}
+
+.uc-vip-card__benefits {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 16px;
+}
+
+.uc-vip-card__benefit {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 10px;
+ border-radius: var(--radius, 8px);
+ background: rgba(255, 255, 255, .1);
+ font: 500 12px/1 var(--font-ui);
+}
+
+.uc-vip-card__benefit i {
+ font-size: 12px;
+}
+
+.uc-vip-card__btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 10px 24px;
+ border-radius: var(--radius, 8px);
+ background: rgba(255, 255, 255, .2);
+ border: 1px solid rgba(255, 255, 255, .3);
+ color: #fff;
+ font: 600 14px/1 var(--font-ui);
+ text-decoration: none;
+ transition: all .2s ease;
+}
+
+.uc-vip-card__btn:hover {
+ background: rgba(255, 255, 255, .3);
+ color: #fff;
+}
+
+/* ============ VIP 徽标 ============ */
+.aksrt-vip-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 2px 8px;
+ border-radius: 4px;
+ font: 600 11px/1 var(--font-ui);
+ background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
+ color: #fff;
+ vertical-align: middle;
+}
+
+.aksrt-vip-badge i {
+ font-size: 10px;
+}
+
+.aksrt-vip-badge--sm {
+ padding: 2px 6px;
+ font-size: 10px;
+}
+
+.aksrt-vip-badge--sm i {
+ font-size: 9px;
+}
+
+.aksrt-vip-badge--lg {
+ padding: 4px 12px;
+ font-size: 13px;
+}
+
+.aksrt-vip-badge--lg i {
+ font-size: 12px;
+}
diff --git a/assets/css/frontend/empty-state.css b/assets/css/frontend/empty-state.css
new file mode 100644
index 00000000..09622f5a
--- /dev/null
+++ b/assets/css/frontend/empty-state.css
@@ -0,0 +1,124 @@
+/* ========== 空状态 — 对齐 zibll empty state ========== */
+.empty-state {
+ text-align: center;
+ padding: 60px 20px;
+ color: var(--color-ink-3, #777);
+}
+
+.empty-state__icon {
+ font-size: 56px;
+ color: var(--surface-3, #e8e8e8);
+ margin-bottom: 16px;
+ line-height: 1;
+}
+
+.empty-state__icon i {
+ display: inline-block;
+}
+
+.empty-state__title {
+ font-size: 16px;
+ font-weight: 500;
+ color: var(--color-ink-2, #4e5358);
+ margin-bottom: 8px;
+}
+
+.empty-state__desc {
+ font-size: 13px;
+ color: var(--color-ink-4, #999);
+ margin-bottom: 20px;
+ max-width: 320px;
+ margin-left: auto;
+ margin-right: auto;
+ line-height: 1.6;
+}
+
+.empty-state__action {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+}
+
+/* 空状态变体 */
+.empty-state--sm {
+ padding: 30px 16px;
+}
+
+.empty-state--sm .empty-state__icon {
+ font-size: 40px;
+}
+
+.empty-state--sm .empty-state__title {
+ font-size: 14px;
+}
+
+.empty-state--sm .empty-state__desc {
+ font-size: 12px;
+}
+
+/* 评论空状态 */
+.comments-empty {
+ text-align: center;
+ padding: 40px 20px;
+}
+
+.comments-empty__icon {
+ font-size: 48px;
+ color: var(--surface-3, #e8e8e8);
+ margin-bottom: 12px;
+}
+
+.comments-empty__text {
+ font-size: 14px;
+ color: var(--color-ink-3, #777);
+ margin-bottom: 4px;
+}
+
+.comments-empty__hint {
+ font-size: 12px;
+ color: var(--color-ink-4, #999);
+}
+
+/* 搜索空状态 */
+.search-empty {
+ text-align: center;
+ padding: 80px 20px;
+}
+
+.search-empty__icon {
+ font-size: 64px;
+ color: var(--surface-3, #e8e8e8);
+ margin-bottom: 16px;
+}
+
+.search-empty__title {
+ font-size: 18px;
+ font-weight: 500;
+ color: var(--color-ink-2, #4e5358);
+ margin-bottom: 8px;
+}
+
+.search-empty__suggestions {
+ font-size: 13px;
+ color: var(--color-ink-4, #999);
+}
+
+.search-empty__suggestions a {
+ color: var(--color-primary, #f04494);
+ text-decoration: none;
+}
+
+.search-empty__suggestions a:hover {
+ text-decoration: underline;
+}
+
+/* 移动端 */
+@media (max-width: 767px) {
+ .empty-state {
+ padding: 40px 16px;
+ }
+
+ .empty-state__icon {
+ font-size: 44px;
+ }
+}
diff --git a/assets/css/frontend/enhancements.css b/assets/css/frontend/enhancements.css
new file mode 100644
index 00000000..2d06f0ec
--- /dev/null
+++ b/assets/css/frontend/enhancements.css
@@ -0,0 +1,3 @@
+@import url("enhancements/core-ui.css");
+@import url("enhancements/components.css");
+@import url("enhancements/modal-motion.css");
diff --git a/assets/css/frontend/enhancements/components.css b/assets/css/frontend/enhancements/components.css
new file mode 100644
index 00000000..5be1dd16
--- /dev/null
+++ b/assets/css/frontend/enhancements/components.css
@@ -0,0 +1,3 @@
+@import url("components/base.css");
+@import url("components/reward-amounts.css");
+@import url("components/custom-amount.css");
diff --git a/assets/css/frontend/enhancements/components/base.css b/assets/css/frontend/enhancements/components/base.css
new file mode 100644
index 00000000..9206b0cc
--- /dev/null
+++ b/assets/css/frontend/enhancements/components/base.css
@@ -0,0 +1,199 @@
+/* ============================================================
+ * 7. 文章封面轮播
+ * ============================================================ */
+.single-cover-slider {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+ border-radius: var(--radius-lg, 8px);
+}
+
+.single-cover-slider .swiper-slide {
+ position: relative;
+ overflow: hidden;
+}
+
+.single-cover-slider__img {
+ width: 100%;
+ height: 400px;
+ object-fit: cover;
+ display: block;
+}
+
+.single-cover-slider__overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, rgba(0,0,0,0) 40%, rgba(0,0,0,0.6) 100%);
+ pointer-events: none;
+}
+
+.single-cover-slider__content {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: 24px;
+ color: #fff;
+ z-index: 2;
+}
+
+.single-cover-slider__title {
+ margin: 0 0 8px;
+ font-size: 24px;
+ font-weight: 700;
+ text-shadow: 0 1px 3px rgba(0,0,0,0.3);
+}
+
+.single-cover-slider__meta {
+ display: flex;
+ gap: 16px;
+ font-size: 13px;
+ opacity: 0.9;
+}
+
+.single-cover-slider__pagination {
+ position: absolute;
+ bottom: 12px;
+ right: 16px;
+ z-index: 3;
+}
+
+.single-cover-slider__pagination .swiper-pagination-bullet {
+ background: rgba(255,255,255,0.6);
+ opacity: 1;
+}
+
+.single-cover-slider__pagination .swiper-pagination-bullet-active {
+ background: #fff;
+}
+
+.single-cover-slider__prev,
+.single-cover-slider__next {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ z-index: 3;
+ width: 40px;
+ height: 40px;
+ border: none;
+ border-radius: 50%;
+ background: rgba(0,0,0,0.3);
+ color: #fff;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.single-cover-slider__prev:hover,
+.single-cover-slider__next:hover {
+ background: rgba(0,0,0,0.5);
+}
+
+.single-cover-slider__prev { left: 12px; }
+.single-cover-slider__next { right: 12px; }
+
+@media (max-width: 640px) {
+ .single-cover-slider__img {
+ height: 240px;
+ }
+ .single-cover-slider__title {
+ font-size: 18px;
+ }
+}
+
+/* ============================================================
+ * 8. 打赏按钮
+ * ============================================================ */
+.action-btn--reward {
+ position: relative;
+}
+
+.action-btn--reward.is-active {
+ color: var(--color-warning, #F59E0B);
+}
+
+.reward-modal {
+ position: fixed;
+ inset: 0;
+ z-index: 99999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s, visibility 0.3s;
+}
+
+.reward-modal.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.reward-modal__overlay {
+ position: absolute;
+ inset: 0;
+ background: rgba(0,0,0,0.5);
+}
+
+.reward-modal__card {
+ position: relative;
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-lg, 8px);
+ padding: 32px;
+ max-width: 360px;
+ width: 90%;
+ text-align: center;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.15);
+ z-index: 1;
+}
+
+.reward-modal__title {
+ margin: 0 0 8px;
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.reward-modal__desc {
+ margin: 0 0 20px;
+ font-size: 14px;
+ color: var(--color-ink-3);
+}
+
+.reward-modal__qr {
+ width: 200px;
+ height: 200px;
+ margin: 0 auto 16px;
+ border-radius: var(--radius, 10px);
+ overflow: hidden;
+}
+
+.reward-modal__qr img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+}
+
+.reward-modal__close {
+ position: absolute;
+ top: 12px;
+ right: 12px;
+ width: 32px;
+ height: 32px;
+ border: none;
+ border-radius: 50%;
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-ink-3);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.reward-modal__close:hover {
+ background: var(--surface-3, #ECEEF1);
+}
+
diff --git a/assets/css/frontend/enhancements/components/custom-amount.css b/assets/css/frontend/enhancements/components/custom-amount.css
new file mode 100644
index 00000000..478687e2
--- /dev/null
+++ b/assets/css/frontend/enhancements/components/custom-amount.css
@@ -0,0 +1,571 @@
+/* ---- custom amount ---- */
+.reward-custom {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 16px;
+}
+
+.reward-custom__input {
+ flex: 1;
+ height: 40px;
+ padding: 0 12px;
+ border: 1px solid var(--color-line, #e5e7eb);
+ border-radius: var(--radius, 10px);
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-ink);
+ font-size: 14px;
+ text-align: center;
+ outline: none;
+ transition: border-color 0.2s;
+ -moz-appearance: textfield;
+}
+
+.reward-custom__input::-webkit-inner-spin-button,
+.reward-custom__input::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+
+.reward-custom__input:focus {
+ border-color: var(--color-primary, #f04494);
+}
+
+.reward-custom__confirm {
+ flex-shrink: 0;
+ height: 40px;
+ padding: 0 20px;
+ border: none;
+ border-radius: var(--radius, 10px);
+ background: var(--color-primary, #f04494);
+ color: #fff;
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: opacity 0.2s;
+}
+
+.reward-custom__confirm:hover {
+ opacity: 0.85;
+}
+
+/* ============================================================
+ * 9. 公告跑马灯 Widget
+ * ============================================================ */
+.aksrt-announcement {
+ position: relative;
+ overflow: hidden;
+ padding: 10px 12px;
+ background: var(--surface-2, #F4F5F7);
+ border-radius: var(--radius, 10px);
+}
+
+.aksrt-announcement__icon {
+ position: absolute;
+ left: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ color: var(--color-primary, var(--color-primary));
+ font-size: 14px;
+ z-index: 1;
+}
+
+.aksrt-announcement__track {
+ margin-left: 24px;
+ overflow: hidden;
+ height: 20px;
+}
+
+.aksrt-announcement__list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ animation: aksrt-marquee 10s linear infinite;
+}
+
+.aksrt-announcement__item {
+ height: 20px;
+ line-height: 20px;
+ font-size: 13px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.aksrt-announcement__item a {
+ color: var(--color-ink-2);
+ text-decoration: none;
+}
+
+.aksrt-announcement__item a:hover {
+ color: var(--color-primary, var(--color-primary));
+}
+
+@keyframes aksrt-marquee {
+ 0% { transform: translateY(0); }
+ 100% { transform: translateY(-100%); }
+}
+
+.aksrt-announcement:hover .aksrt-announcement__list {
+ animation-play-state: paused;
+}
+
+/* ============================================================
+ * 10. 用户卡片 Widget
+ * ============================================================ */
+.aksrt-user-card {
+ text-align: center;
+ padding: 20px;
+}
+
+.aksrt-user-card__avatar {
+ width: 72px;
+ height: 72px;
+ border-radius: 50%;
+ margin: 0 auto 12px;
+ overflow: hidden;
+ border: 3px solid var(--color-primary-soft, rgba(136,171,218,0.1));
+}
+
+.aksrt-user-card__avatar img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.aksrt-user-card__name {
+ margin: 0 0 4px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-user-card__name a {
+ color: inherit;
+ text-decoration: none;
+}
+
+.aksrt-user-card__name a:hover {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-user-card__bio {
+ margin: 0 0 12px;
+ font-size: 13px;
+ color: var(--color-ink-3);
+ line-height: 1.5;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.aksrt-user-card__stats {
+ display: flex;
+ justify-content: center;
+ gap: 20px;
+ margin-bottom: 16px;
+}
+
+.aksrt-user-card__stat {
+ text-align: center;
+}
+
+.aksrt-user-card__stat-value {
+ display: block;
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-user-card__stat-label {
+ font-size: 12px;
+ color: var(--color-ink-4, #8A8F98);
+}
+
+.aksrt-user-card__actions {
+ display: flex;
+ gap: 8px;
+ justify-content: center;
+}
+
+.aksrt-user-card__btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 16px;
+ border-radius: var(--radius, 10px);
+ font-size: 13px;
+ text-decoration: none;
+ transition: all 0.15s;
+}
+
+.aksrt-user-card__btn--primary {
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+}
+
+.aksrt-user-card__btn--primary:hover {
+ opacity: 0.85;
+ color: #fff;
+}
+
+.aksrt-user-card__btn--ghost {
+ border: 1px solid var(--color-line);
+ color: var(--color-ink-2);
+}
+
+.aksrt-user-card__btn--ghost:hover {
+ border-color: var(--color-primary, var(--color-primary));
+ color: var(--color-primary, var(--color-primary));
+}
+
+/* ============================================================
+ * 11. 滚动触发动画初始状态
+ * ============================================================ */
+[data-aksrt-animate] {
+ will-change: opacity, transform;
+}
+
+/* ============================================================
+ * 12. 粘性侧栏
+ * ============================================================ */
+[data-aksrt-sticky] {
+ will-change: transform;
+}
+
+/* ============================================================
+ * 13. 用户排行榜 Widget
+ * ============================================================ */
+.aksrt-user-ranking {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.aksrt-user-ranking__item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 0;
+ border-bottom: 1px solid var(--color-line-soft, #F0F1F3);
+}
+
+.aksrt-user-ranking__item:last-child {
+ border-bottom: none;
+}
+
+.aksrt-user-ranking__rank {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ border-radius: 6px;
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-ink-3);
+ font-size: 12px;
+ font-weight: 600;
+ flex-shrink: 0;
+}
+
+.aksrt-user-ranking__item--top:nth-child(1) .aksrt-user-ranking__rank {
+ background: #FFD700;
+ color: #fff;
+}
+
+.aksrt-user-ranking__item--top:nth-child(2) .aksrt-user-ranking__rank {
+ background: #C0C0C0;
+ color: #fff;
+}
+
+.aksrt-user-ranking__item--top:nth-child(3) .aksrt-user-ranking__rank {
+ background: #CD7F32;
+ color: #fff;
+}
+
+.aksrt-user-ranking__avatar {
+ flex-shrink: 0;
+}
+
+.aksrt-user-ranking__avatar img {
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.aksrt-user-ranking__name {
+ flex: 1;
+ min-width: 0;
+ font-size: 14px;
+ color: var(--color-ink);
+ text-decoration: none;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.aksrt-user-ranking__name:hover {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-user-ranking__value {
+ font-size: 12px;
+ color: var(--color-ink-4, #8A8F98);
+ white-space: nowrap;
+}
+
+/* ============================================================
+ * 14. 图文封面卡片 Widget
+ * ============================================================ */
+.aksrt-cover-cards {
+ display: grid;
+ grid-template-columns: repeat(var(--cols, 2), 1fr);
+ gap: 12px;
+}
+
+.aksrt-cover-card {
+ position: relative;
+ border-radius: var(--radius-lg, 8px);
+ overflow: hidden;
+ min-height: 160px;
+ display: flex;
+ align-items: flex-end;
+ transition: transform 0.3s, box-shadow 0.3s;
+}
+
+.aksrt-cover-card:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
+}
+
+.aksrt-cover-card__bg {
+ position: absolute;
+ inset: 0;
+}
+
+.aksrt-cover-card__bg img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.5s;
+}
+
+.aksrt-cover-card:hover .aksrt-cover-card__bg img {
+ transform: scale(1.02);
+}
+
+.aksrt-cover-card__overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(180deg, rgba(0,0,0,0) 30%, rgba(0,0,0,0.6) 100%);
+}
+
+.aksrt-cover-card__content {
+ position: relative;
+ z-index: 1;
+ padding: 16px;
+ width: 100%;
+}
+
+.aksrt-cover-card__link {
+ text-decoration: none;
+ color: inherit;
+ display: block;
+}
+
+.aksrt-cover-card__title {
+ margin: 0 0 4px;
+ font-size: 16px;
+ font-weight: 600;
+ color: #fff;
+ text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
+}
+
+.aksrt-cover-card__desc {
+ margin: 0;
+ font-size: 13px;
+ color: rgba(255, 255, 255, 0.85);
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+/* ============================================================
+ * 15. 视频播放器 Widget
+ * ============================================================ */
+.aksrt-video-widget {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+ border-radius: var(--radius, 10px);
+ background: #000;
+}
+
+.aksrt-video-widget iframe,
+.aksrt-video-widget video {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: none;
+}
+
+/* ============================================================
+ * 16. 表单输入浮动标签
+ * ============================================================ */
+.aksrt-float-label {
+ position: relative;
+}
+
+.aksrt-float-label__input {
+ width: 100%;
+ padding: 14px 12px 6px;
+ font-size: 14px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink);
+ transition: border-color 0.2s;
+}
+
+.aksrt-float-label__input:focus {
+ outline: none;
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-float-label__label {
+ position: absolute;
+ left: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ font-size: 14px;
+ color: var(--color-ink-4, #8A8F98);
+ pointer-events: none;
+ transition: all 0.2s ease;
+}
+
+.aksrt-float-label__input:focus + .aksrt-float-label__label,
+.aksrt-float-label__input:not(:placeholder-shown) + .aksrt-float-label__label {
+ top: 8px;
+ transform: translateY(0);
+ font-size: 11px;
+ color: var(--color-primary, var(--color-primary));
+}
+
+/* ============================================================
+ * 17. 视差滚动层
+ * ============================================================ */
+[data-aksrt-parallax] {
+ will-change: transform;
+ transition: transform 0.1s linear;
+}
+
+/* ============================================================
+ * 18. 签到日历可视化
+ * ============================================================ */
+.aksrt-signin-calendar__grid {
+ display: grid;
+ grid-template-columns: repeat(7, 1fr);
+ gap: 4px;
+}
+
+.aksrt-signin-calendar__day {
+ aspect-ratio: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 6px;
+ background: var(--surface-2, #F4F5F7);
+ font-size: 12px;
+ color: var(--color-ink-3);
+ transition: all 0.2s;
+}
+
+.aksrt-signin-calendar__day.is-signed {
+ background: var(--color-success, #10B981);
+ color: #fff;
+}
+
+.aksrt-signin-calendar__day.is-today {
+ border: 2px solid var(--color-primary, var(--color-primary));
+}
+
+.aksrt-signin-calendar__day.is-signed.is-today {
+ background: var(--color-primary, var(--color-primary));
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.uc-signin-calendar__title {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ margin: 0 0 10px;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink-2);
+}
+
+.uc-signin-calendar__title i {
+ color: var(--color-primary, var(--color-primary));
+}
+
+/* ============================================================
+ * 19. VIP 等级标识
+ * ============================================================ */
+.aksrt-vip-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 2px 8px;
+ border-radius: var(--radius-pill, 999px);
+ font-size: 11px;
+ font-weight: 600;
+}
+
+.aksrt-vip-badge--gold {
+ background: linear-gradient(135deg, #FFD700, #FFA500);
+ color: #fff;
+}
+
+.aksrt-vip-badge--silver {
+ background: linear-gradient(135deg, #C0C0C0, #A8A8A8);
+ color: #fff;
+}
+
+.aksrt-vip-badge--bronze {
+ background: linear-gradient(135deg, #CD7F32, #A0522D);
+ color: #fff;
+}
+
+/* ============================================================
+ * 20. 用户等级进度条
+ * ============================================================ */
+.aksrt-level-bar {
+ position: relative;
+ height: 8px;
+ background: var(--surface-2, #F4F5F7);
+ border-radius: 4px;
+ overflow: hidden;
+}
+
+.aksrt-level-bar__fill {
+ height: 100%;
+ background: linear-gradient(90deg, var(--color-primary, var(--color-primary)), var(--color-primary-active, #5A85BD));
+ border-radius: 4px;
+ transition: width 0.5s ease;
+}
+
+.aksrt-level-bar__label {
+ position: absolute;
+ right: 0;
+ top: -18px;
+ font-size: 11px;
+ color: var(--color-ink-4, #8A8F98);
+}
+
+
diff --git a/assets/css/frontend/enhancements/components/reward-amounts.css b/assets/css/frontend/enhancements/components/reward-amounts.css
new file mode 100644
index 00000000..e974ae27
--- /dev/null
+++ b/assets/css/frontend/enhancements/components/reward-amounts.css
@@ -0,0 +1,45 @@
+/* ---- reward amounts ---- */
+.reward-amounts {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ justify-content: center;
+ margin-bottom: 16px;
+}
+
+.reward-amounts__btn {
+ display: inline-flex;
+ align-items: baseline;
+ gap: 2px;
+ padding: 8px 16px;
+ border: 1px solid var(--color-line, #e5e7eb);
+ border-radius: var(--radius, 10px);
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-ink);
+ font-size: 15px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.2s ease;
+ user-select: none;
+}
+
+.reward-amounts__btn:hover {
+ border-color: var(--color-primary, #f04494);
+ background: rgba(240, 68, 148, 0.06);
+}
+
+.reward-amounts__btn.is-active {
+ border-color: var(--color-primary, #f04494);
+ background: var(--color-primary, #f04494);
+ color: #fff;
+}
+
+.reward-amounts__currency {
+ font-size: 13px;
+ font-weight: 400;
+}
+
+.reward-amounts__value {
+ font-size: 15px;
+}
+
diff --git a/assets/css/frontend/enhancements/core-ui.css b/assets/css/frontend/enhancements/core-ui.css
new file mode 100644
index 00000000..e5e5691c
--- /dev/null
+++ b/assets/css/frontend/enhancements/core-ui.css
@@ -0,0 +1,483 @@
+/**
+ * AKSRT Enhancements — 全局 UI 增强
+ *
+ * 包含:Toast 通知、骨架屏、悬停动效、暗色过渡、滚动感知
+ * 所有选择器使用 aksrt- 前缀避免冲突
+ */
+
+/* ============================================================
+ * 1. Toast 通知系统
+ * ============================================================ */
+.aksrt-toast-container {
+ position: fixed;
+ bottom: 80px;
+ right: 16px;
+ max-width: 360px;
+ z-index: 10000;
+ display: flex;
+ flex-direction: column-reverse;
+ gap: 8px;
+ pointer-events: none;
+}
+
+.aksrt-toast {
+ pointer-events: auto;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 12px 16px;
+ border-radius: var(--main-radius, 8px);
+ color: #fff;
+ font-size: 14px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
+ backdrop-filter: saturate(5) blur(20px);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ transform: translateX(120%);
+ opacity: 0;
+ animation: aksrt-toast-in 0.35s cubic-bezier(0.35, 0.71, 0.46, 1.08) forwards;
+ cursor: pointer;
+ transition: transform 0.3s, opacity 0.3s;
+}
+
+.aksrt-toast.is-dismissing {
+ transform: translateX(120%);
+ opacity: 0;
+ transition: transform 0.3s ease-in, opacity 0.3s ease-in;
+}
+
+.aksrt-toast__icon {
+ font-size: 18px;
+ flex-shrink: 0;
+}
+
+.aksrt-toast__text {
+ flex: 1;
+ min-width: 0;
+ line-height: 1.4;
+}
+
+/* Toast 类型 — 对齐 zibll 纯色 */
+.aksrt-toast--success {
+ background: rgba(16, 185, 129, 0.9);
+}
+
+.aksrt-toast--info {
+ background: rgba(59, 130, 246, 0.9);
+}
+
+.aksrt-toast--warning {
+ background: rgba(245, 158, 11, 0.9);
+}
+
+.aksrt-toast--danger,
+.aksrt-toast--error {
+ background: rgba(239, 68, 68, 0.9);
+}
+
+.aksrt-toast--loading {
+ background: rgba(107, 114, 128, 0.9);
+}
+
+.aksrt-toast--loading .aksrt-toast__icon {
+ animation: aksrt-spin 1s linear infinite;
+}
+
+.aksrt-modal-auth__error.is-success {
+ background: rgba(16, 185, 129, 0.08);
+ border-color: rgba(16, 185, 129, 0.22);
+ color: #047857;
+}
+
+.aksrt-modal-auth__checkbox {
+ display: flex;
+ align-items: flex-start;
+ gap: 8px;
+ font-size: 13px;
+ color: var(--muted-color, #777);
+}
+
+.aksrt-modal-auth__hint {
+ margin: -4px 0 0;
+ font-size: 13px;
+ color: var(--muted-color, #777);
+ line-height: 1.6;
+}
+
+@keyframes aksrt-toast-in {
+ from {
+ transform: translateX(120%);
+ opacity: 0;
+ }
+ to {
+ transform: translateX(0);
+ opacity: 1;
+ }
+}
+
+@keyframes aksrt-spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+
+/* ============================================================
+ * 2. 骨架屏加载动画
+ * ============================================================ */
+.aksrt-skeleton {
+ background: linear-gradient(
+ 90deg,
+ rgba(121, 121, 121, 0.08) 25%,
+ rgba(121, 121, 121, 0.15) 37%,
+ rgba(121, 121, 121, 0.08) 63%
+ );
+ background-size: 400% 100%;
+ animation: aksrt-skeleton-shimmer 1.5s ease infinite;
+ border-radius: 4px;
+}
+
+.aksrt-skeleton--image {
+ height: 0;
+ padding-bottom: 66.67%; /* 3:2 aspect ratio */
+}
+
+.aksrt-skeleton--avatar {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+}
+
+.aksrt-skeleton--title {
+ height: 22px;
+ width: 80%;
+}
+
+.aksrt-skeleton--text {
+ height: 16px;
+ width: 100%;
+}
+
+.aksrt-skeleton--text-short {
+ height: 16px;
+ width: 60%;
+}
+
+.aksrt-skeleton--button {
+ height: 36px;
+ width: 100px;
+ border-radius: 8px;
+}
+
+@keyframes aksrt-skeleton-shimmer {
+ 0% { background-position: 100% 50%; }
+ 100% { background-position: 0 50%; }
+}
+
+/* 骨架屏组合:文章卡片骨架 */
+.aksrt-skeleton-card {
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ border-radius: 12px;
+ overflow: hidden;
+ padding: 0;
+}
+
+.aksrt-skeleton-card .aksrt-skeleton--image {
+ border-radius: 0;
+}
+
+.aksrt-skeleton-card__body {
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+/* ============================================================
+ * 3. 悬停交互动效
+ * ============================================================ */
+
+/* 卡片放大 */
+.aksrt-hover-zoom {
+ transition: transform 0.3s ease;
+}
+
+.aksrt-hover-zoom:hover {
+ transform: scale(1.02);
+}
+
+/* 卡片轻微放大 */
+.aksrt-hover-zoom-sm {
+ transition: transform 0.3s ease;
+}
+
+.aksrt-hover-zoom-sm:hover {
+ transform: scale(1.02);
+}
+
+/* 悬停显示内容 */
+.aksrt-hover-show {
+ position: relative;
+}
+
+.aksrt-hover-show__content {
+ position: absolute;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(6px);
+ transition: opacity 0.3s, transform 0.3s, visibility 0.3s;
+ z-index: 10;
+}
+
+.aksrt-hover-show:hover .aksrt-hover-show__content {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+/* 关闭按钮旋转 */
+.aksrt-ic-close {
+ transition: transform 0.3s;
+ cursor: pointer;
+}
+
+.aksrt-ic-close:hover {
+ transform: rotate(270deg);
+}
+
+/* 图片悬停缩放(缩略图容器) */
+.aksrt-hover-zoom-img img {
+ transition: transform 0.3s ease;
+}
+
+.aksrt-hover-zoom-img:hover img {
+ transform: scale(1.02);
+}
+
+.aksrt-hover-zoom-img-sm img {
+ transition: transform 0.3s ease;
+}
+
+.aksrt-hover-zoom-img-sm:hover img {
+ transform: scale(1.02);
+}
+
+/* 按钮悬停上浮 */
+.aksrt-hover-lift {
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.aksrt-hover-lift:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+/* ============================================================
+ * 4. 暗色模式过渡 (View Transitions API)
+ * ============================================================ */
+::view-transition-old(root),
+::view-transition-new(root) {
+ animation: none;
+ mix-blend-mode: normal;
+}
+
+.dark::view-transition-old(root),
+body.dark-theme::view-transition-old(root) {
+ z-index: 1;
+}
+
+.dark::view-transition-new(root),
+body.dark-theme::view-transition-new(root) {
+ z-index: 2147483646;
+}
+
+::view-transition-old(root) {
+ z-index: 2147483646;
+}
+
+::view-transition-new(root) {
+ z-index: 1;
+}
+
+/* backdrop-filter 不支持时的降级 */
+@supports not ((-webkit-backdrop-filter: blur(20px)) or (backdrop-filter: blur(20px))) {
+ :root {
+ --aksrt-blur-bg: #ffffff;
+ }
+
+ .dark {
+ --aksrt-blur-bg: var(--surface-1);
+ }
+
+ .aksrt-toast {
+ backdrop-filter: none;
+ -webkit-backdrop-filter: none;
+ }
+}
+
+/* ============================================================
+ * 5. 滚动方向感知
+ * ============================================================ */
+
+/* 向下滚动时隐藏导航栏 */
+body.aksrt-scroll-down .site-nav.nav-scroll-hide {
+ transform: translateY(-100%);
+ transition: transform 0.3s ease;
+}
+
+body.aksrt-scroll-up .site-nav.nav-scroll-hide {
+ transform: translateY(0);
+ transition: transform 0.3s ease;
+}
+
+/* 滚动时隐藏浮动按钮 */
+body.aksrt-scrolling .aksrt-floating-right.scrolling-hide {
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.2s;
+}
+
+/* body-scroll 状态类 */
+body.aksrt-body-scroll .aksrt-show-on-scroll {
+ opacity: 1;
+ visibility: visible;
+}
+
+.aksrt-show-on-scroll {
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s, visibility 0.3s;
+}
+
+/* ============================================================
+ * 6. 图片灯箱
+ * ============================================================ */
+.aksrt-lightbox {
+ position: fixed;
+ inset: 0;
+ z-index: 9999;
+ background: rgba(0, 0, 0, 0.85);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s, visibility 0.3s;
+ cursor: zoom-out;
+}
+
+.aksrt-lightbox.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.aksrt-lightbox__img {
+ max-width: 90vw;
+ max-height: 85vh;
+ object-fit: contain;
+ border-radius: 4px;
+ transform: scale(0.9);
+ transition: transform 0.3s;
+ cursor: default;
+}
+
+.aksrt-lightbox.is-open .aksrt-lightbox__img {
+ transform: scale(1);
+}
+
+.aksrt-lightbox__close {
+ position: absolute;
+ top: 16px;
+ right: 16px;
+ width: 36px;
+ height: 36px;
+ border: none;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.15);
+ color: #fff;
+ font-size: 20px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.aksrt-lightbox__close:hover {
+ background: rgba(255, 255, 255, 0.3);
+}
+
+.aksrt-lightbox__caption {
+ position: absolute;
+ bottom: 16px;
+ left: 50%;
+ transform: translateX(-50%);
+ color: rgba(255, 255, 255, 0.8);
+ font-size: 14px;
+ text-align: center;
+ max-width: 80%;
+}
+
+.aksrt-lightbox__nav {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 48px;
+ height: 48px;
+ border: none;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.1);
+ color: #fff;
+ font-size: 24px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.aksrt-lightbox__nav:hover {
+ background: rgba(255, 255, 255, 0.25);
+}
+
+.aksrt-lightbox__nav--prev {
+ left: 16px;
+}
+
+.aksrt-lightbox__nav--next {
+ right: 16px;
+}
+
+.aksrt-lightbox__counter {
+ position: absolute;
+ top: 16px;
+ left: 16px;
+ color: rgba(255, 255, 255, 0.7);
+ font-size: 14px;
+}
+
+.aksrt-lightbox__download {
+ position: absolute;
+ top: 16px;
+ right: 64px;
+ width: 40px;
+ height: 40px;
+ border: none;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.15);
+ color: #fff;
+ font-size: 18px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+}
+
+.aksrt-lightbox__download:hover {
+ background: rgba(255, 255, 255, 0.3);
+}
+
+/* 可缩放图片的光标 */
+.aksrt-cursor-zoom-in {
+ cursor: zoom-in;
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion.css b/assets/css/frontend/enhancements/modal-motion.css
new file mode 100644
index 00000000..05ee997a
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion.css
@@ -0,0 +1,10 @@
+@import url("modal-motion/base.css");
+@import url("modal-motion/tabs.css");
+@import url("modal-motion/panels.css");
+@import url("modal-motion/form.css");
+@import url("modal-motion/divider.css");
+@import url("modal-motion/oauth.css");
+@import url("modal-motion/footer.css");
+@import url("modal-motion/dark-mode.css");
+@import url("modal-motion/responsive.css");
+@import url("modal-motion/dark-mode-2.css");
diff --git a/assets/css/frontend/enhancements/modal-motion/base.css b/assets/css/frontend/enhancements/modal-motion/base.css
new file mode 100644
index 00000000..ab685916
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/base.css
@@ -0,0 +1,95 @@
+/* ============================================================
+ * 21. 弹窗登录/注册
+ * ============================================================ */
+.aksrt-modal-auth {
+ position: fixed;
+ inset: 0;
+ z-index: 99999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s, visibility 0.3s;
+}
+
+.aksrt-modal-auth.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.aksrt-modal-auth__overlay {
+ position: absolute;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.5);
+ backdrop-filter: blur(4px);
+ -webkit-backdrop-filter: blur(4px);
+}
+
+.aksrt-modal-auth__card {
+ position: relative;
+ background: var(--main-bg-color, #fff);
+ border-radius: var(--main-radius, 8px);
+ padding: 32px;
+ max-width: 400px;
+ width: 90%;
+ max-height: 90vh;
+ overflow-y: auto;
+ box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
+ z-index: 1;
+ transform: scale(0.9);
+ transition: transform 0.5s cubic-bezier(0.32, 0.85, 0.45, 1.18);
+}
+
+.aksrt-modal-auth.is-open .aksrt-modal-auth__card {
+ transform: scale(1);
+}
+
+.aksrt-modal-auth__close {
+ position: absolute;
+ top: 12px;
+ right: 12px;
+ width: 36px;
+ height: 36px;
+ border: none;
+ border-radius: 50%;
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-ink-3);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s;
+ font-size: 16px;
+}
+
+.aksrt-modal-auth__close:hover {
+ background: var(--surface-3, #ECEEF1);
+}
+
+.aksrt-modal-auth__header {
+ text-align: center;
+ margin-bottom: 24px;
+}
+
+.aksrt-modal-auth__logo {
+ width: 56px;
+ height: 56px;
+ border-radius: var(--radius);
+ background: linear-gradient(135deg, var(--color-primary, var(--color-primary)), var(--color-primary-active, #5A85BD));
+ color: #fff;
+ font-size: 22px;
+ font-weight: 700;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin: 0 auto 12px;
+}
+
+.aksrt-modal-auth__title {
+ margin: 0;
+ font-size: 20px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/dark-mode-2.css b/assets/css/frontend/enhancements/modal-motion/dark-mode-2.css
new file mode 100644
index 00000000..340d589e
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/dark-mode-2.css
@@ -0,0 +1,514 @@
+/* Dark mode */
+.theme-dark .aksrt-lang-switch__toggle,
+html.dark .aksrt-lang-switch__toggle {
+ background: #2a2a3a;
+ border-color: rgba(255, 255, 255, 0.15);
+}
+
+.theme-dark .aksrt-lang-switch__dropdown,
+html.dark .aksrt-lang-switch__dropdown {
+ background: #2a2a3a;
+ border-color: rgba(255, 255, 255, 0.15);
+}
+
+/* ============================================================
+ * 响应式
+ * ============================================================ */
+@media (max-width: 640px) {
+ .aksrt-toast-container {
+ right: 8px;
+ left: 8px;
+ max-width: none;
+ }
+
+ .aksrt-lightbox__nav {
+ width: 36px;
+ height: 36px;
+ font-size: 18px;
+ }
+
+ .single-cover-slider__img {
+ height: 240px;
+ }
+
+ .single-cover-slider__title {
+ font-size: 18px;
+ }
+
+ .reward-modal__card {
+ padding: 24px;
+ }
+
+ .reward-modal__qr {
+ width: 160px;
+ height: 160px;
+ }
+
+ .aksrt-cover-cards {
+ grid-template-columns: 1fr;
+ }
+
+ .aksrt-cover-card {
+ min-height: 140px;
+ }
+}
+
+/* ============================================================
+ * 13. 无障碍:prefers-reduced-motion
+ * 用户系统设置"减少动画"时,禁用所有非必要动效
+ * ============================================================ */
+@media (prefers-reduced-motion: reduce) {
+ *,
+ *::before,
+ *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+
+ .aksrt-skeleton {
+ animation: none !important;
+ }
+
+ .aksrt-toast {
+ animation: none !important;
+ }
+
+ [data-aksrt-animate] {
+ opacity: 1 !important;
+ transform: none !important;
+ }
+}
+
+/* ============================================================
+ * 14. 图片懒加载 blur-to-sharp 过渡
+ * 模仿 zibll 的 lazy_blur 效果
+ * ============================================================ */
+img.lazyload,
+img.lazyloaded,
+img[data-src] {
+ transition: filter 0.6s var(--ease), opacity 0.4s var(--ease);
+}
+
+img.lazyload,
+img[data-src] {
+ filter: blur(5px);
+ opacity: 0.7;
+}
+
+img.lazyloaded {
+ filter: blur(0);
+ opacity: 1;
+}
+
+/* 14b. aksrt-lazy 动画变体(按 lazyload_animation 配置切换) */
+@keyframes aksrt-lazy-blur {
+ from { filter: blur(8px); opacity: 0.6; }
+ to { filter: blur(0); opacity: 1; }
+}
+@keyframes aksrt-lazy-fade {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+@keyframes aksrt-lazy-scale {
+ from { transform: scale(1.08); opacity: 0.8; }
+ to { transform: scale(1); opacity: 1; }
+}
+
+img.aksrt-lazy {
+ transition: filter 0.5s var(--ease), opacity 0.5s var(--ease), transform 0.5s var(--ease);
+}
+
+img.aksrt-loaded[data-lazy-animation="blur"] {
+ animation: aksrt-lazy-blur 0.6s ease both;
+}
+img.aksrt-loaded[data-lazy-animation="fade"] {
+ animation: aksrt-lazy-fade 0.6s ease both;
+}
+img.aksrt-loaded[data-lazy-animation="scale"] {
+ animation: aksrt-lazy-scale 0.5s ease both;
+}
+
+/* ============================================================
+ * 15. 错误反馈 shake 动画
+ * 表单验证失败时的水平抖动效果
+ * ============================================================ */
+@keyframes aksrtShake {
+ 0%, 100% { transform: translateX(0); }
+ 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
+ 20%, 40%, 60%, 80% { transform: translateX(4px); }
+}
+
+.aksrt-shake {
+ animation: aksrtShake 0.4s ease-in-out;
+}
+
+/* 应用于 Naive UI 表单验证 */
+.n-form-item--error .n-input,
+.n-form-item--error .n-select,
+.n-form-item--error .n-input-number {
+ animation: aksrtShake 0.3s ease-in-out;
+}
+
+/* ============================================================
+ * 16. FPS 加速模式:低端设备禁用 backdrop-filter
+ * 模仿 zibll 的 body.fps-accelerat 模式
+ * ============================================================ */
+body.fps-accelerat .site-nav,
+body.fps-accelerat .footer-tabbar,
+body.fps-accelerat .float-right .float-btn,
+body.fps-accelerat .aksrt-blur-bg {
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
+}
+
+/* 模态框内禁用 backdrop-filter 避免渲染冲突 */
+body.modal-open .site-nav,
+body.dialog-open .site-nav {
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
+}
+
+/* ============================================================
+ * 17. .blur-bg 通用工具类
+ * 模仿 zibll 的 .blur-bg,可在任意元素上应用毛玻璃效果
+ * ============================================================ */
+.aksrt-blur-bg {
+ background: var(--blur-bg);
+ backdrop-filter: saturate(5) blur(20px);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+}
+
+/* ============================================================
+ * 18. 滚动触发动画延迟支持
+ * data-aksrt-delay 属性控制入场延迟
+ * ============================================================ */
+[data-aksrt-animate][data-aksrt-delay="1"] { transition-delay: 0.1s; }
+[data-aksrt-animate][data-aksrt-delay="2"] { transition-delay: 0.2s; }
+[data-aksrt-animate][data-aksrt-delay="3"] { transition-delay: 0.3s; }
+[data-aksrt-animate][data-aksrt-delay="4"] { transition-delay: 0.4s; }
+[data-aksrt-animate][data-aksrt-delay="5"] { transition-delay: 0.5s; }
+
+/* ============================================================
+ * 19. 全站动效节奏统一
+ * 模仿 zibll 的统一 hover / slide / blur / drawer 语言
+ * ============================================================ */
+
+/* --- 全局过渡基线 --- */
+a, button, input, select, textarea {
+ transition: border-color var(--dur-fast) var(--ease),
+ box-shadow var(--dur-fast) var(--ease),
+ background-color var(--dur-fast) var(--ease),
+ color var(--dur-fast) var(--ease);
+}
+
+/* --- 卡片 hover 统一 --- */
+.post-card, .widget, .aksrt-theme-box, .theme-box,
+.comment-body, .friend-card, .special-card,
+.resource-download-box, .resource-meta-box {
+ transition: box-shadow var(--dur) var(--ease),
+ border-color var(--dur) var(--ease),
+ transform var(--dur) var(--ease);
+}
+
+.post-card:hover, .widget:hover, .friend-card:hover, .special-card:hover {
+ box-shadow: none;
+ transform: none;
+}
+
+/* --- 按钮 hover 统一 --- */
+.btn-primary, .btn-outline, .btn-lg, .btn-sm,
+.n-button, .aksrt-button {
+ transition: all var(--dur-fast) var(--ease);
+}
+
+.btn-primary:hover, .n-button--primary-type:hover {
+ opacity: 0.85;
+}
+
+.btn-primary:active, .n-button--primary-type:active {
+ opacity: 1;
+}
+
+/* --- 输入框 focus 统一 --- */
+input:focus, textarea:focus, select:focus,
+.n-input--focus, .n-select--focus {
+ box-shadow: var(--focus-ring);
+ transition: box-shadow var(--dur-fast) var(--ease);
+}
+
+/* --- 抽屉/模态框动效统一 --- */
+.n-drawer, .n-modal, .n-dialog {
+ transition: all var(--dur) var(--ease-out);
+}
+
+.n-drawer-mask, .n-modal-mask, .n-dialog-mask {
+ transition: opacity var(--dur) var(--ease);
+}
+
+/* --- Tab 切换动效 --- */
+.n-tabs-tab, .nav-tab, .aksrt-tab {
+ transition: color var(--dur-fast) var(--ease),
+ border-color var(--dur-fast) var(--ease),
+ background-color var(--dur-fast) var(--ease);
+}
+
+/* --- 下拉菜单动效 --- */
+.n-dropdown-menu, .aksrt-dropdown {
+ transition: opacity var(--dur-fast) var(--ease),
+ transform var(--dur-fast) var(--ease-out);
+ transform-origin: top;
+}
+
+/* --- Toast 通知动效 --- */
+.aksrt-toast {
+ animation: aksrtToastIn 0.35s var(--ease-out) forwards;
+}
+
+.aksrt-toast--out {
+ animation: aksrtToastOut 0.3s var(--ease) forwards;
+}
+
+/* --- 骨架屏动效 --- */
+.aksrt-skeleton {
+ animation: aksrtSkeletonShimmer 1.5s infinite linear;
+ background: linear-gradient(90deg, var(--skeleton-base) 25%, var(--skeleton-shine) 50%, var(--skeleton-base) 75%);
+ background-size: 200% 100%;
+}
+
+/* --- 页面切换动效 --- */
+.fade-slide-enter-active,
+.fade-slide-leave-active {
+ transition: opacity var(--dur) var(--ease),
+ transform var(--dur) var(--ease);
+}
+
+.fade-slide-enter-from {
+ opacity: 0;
+ transform: translateY(8px);
+}
+
+.fade-slide-leave-to {
+ opacity: 0;
+ transform: translateY(-8px);
+}
+
+/* --- 导航栏滚动动效 --- */
+.site-nav {
+ transition: transform var(--dur) var(--ease),
+ background-color var(--dur) var(--ease),
+ box-shadow var(--dur) var(--ease);
+}
+
+.site-nav.aksrt-nav--hidden {
+ transform: translateY(-100%);
+}
+
+/* --- 浮层弹出动效 --- */
+@keyframes aksrtPopIn {
+ 0% { opacity: 0; transform: scale(0.95) translateY(-4px); }
+ 100% { opacity: 1; transform: scale(1) translateY(0); }
+}
+
+@keyframes aksrtPopOut {
+ 0% { opacity: 1; transform: scale(1) translateY(0); }
+ 100% { opacity: 0; transform: scale(0.95) translateY(-4px); }
+}
+
+.aksrt-popover, .aksrt-tooltip, .aksrt-dropdown-panel {
+ animation: aksrtPopIn var(--dur-fast) var(--ease-out) forwards;
+}
+
+/* --- 图片懒加载过渡 --- */
+img.lazyload, img.lazyloaded, img[data-src] {
+ transition: filter 0.6s var(--ease), opacity 0.4s var(--ease);
+}
+
+img.lazyload, img[data-src] {
+ filter: blur(5px);
+ opacity: 0.7;
+}
+
+img.lazyloaded {
+ filter: blur(0);
+ opacity: 1;
+}
+
+/* --- 滚动进度条动效 --- */
+.reading-progress-bar {
+ transition: width 0.1s linear;
+}
+
+/* --- 移动端抽屉动效 --- */
+@media (max-width: 767px) {
+ .n-drawer {
+ transition: transform var(--dur) var(--ease-out);
+ }
+
+ .site-nav .n-drawer-body {
+ transition: transform var(--dur) var(--ease-out);
+ }
+}
+
+/* --- 暗色模式切换动效 --- */
+html.dark {
+ transition: background-color 0.3s var(--ease),
+ color 0.3s var(--ease);
+}
+
+html.dark * {
+ transition: background-color 0.3s var(--ease),
+ border-color 0.3s var(--ease),
+ color 0.3s var(--ease),
+ box-shadow 0.3s var(--ease);
+}
+
+/* ============================================================
+ * 18. 合作伙伴无缝滚动 (marquee)
+ * ============================================================ */
+.aksrt-marquee {
+ position: relative;
+ overflow: hidden;
+ width: 100%;
+}
+
+.aksrt-marquee__inner {
+ display: flex;
+ gap: 24px;
+ white-space: nowrap;
+ will-change: transform;
+}
+
+.aksrt-marquee__inner > * {
+ flex-shrink: 0;
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .aksrt-marquee__inner {
+ animation: none !important;
+ transform: none !important;
+ }
+}
+
+/* ============================================================
+ * 19. 视频剧集切换按钮
+ * ============================================================ */
+.switch-video,
+.switch-iframe {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 14px;
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.1));
+ border-radius: var(--radius, 8px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-2, #4e5358);
+ font-size: 13px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: all 0.15s ease;
+ text-decoration: none;
+}
+
+.switch-video:hover,
+.switch-iframe:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.switch-video.is-active,
+.switch-iframe.is-active {
+ background: var(--color-primary);
+ border-color: var(--color-primary);
+ color: #fff;
+}
+
+/* ============================================================
+ * 20. 一言轮播组件
+ * ============================================================ */
+.aksrt-yiyan {
+ padding: 16px;
+ text-align: center;
+}
+
+.aksrt-yiyan__content {
+ min-height: 60px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+}
+
+.aksrt-yiyan__icon {
+ font-size: 20px;
+ color: var(--color-primary);
+ opacity: 0.6;
+}
+
+.aksrt-yiyan__text {
+ font-size: 14px;
+ line-height: 1.8;
+ color: var(--color-ink-2, #4e5358);
+ margin: 0;
+ transition: opacity 0.2s ease;
+ font-style: italic;
+}
+
+.aksrt-yiyan__from {
+ font-size: 12px;
+ color: var(--color-ink-4, #999);
+ margin: 0;
+}
+
+.aksrt-yiyan__dots {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ margin-top: 12px;
+}
+
+.aksrt-yiyan__dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: var(--color-line, rgba(50, 50, 50, 0.1));
+ transition: background 0.2s;
+}
+
+.aksrt-yiyan__dot.is-active {
+ background: var(--color-primary);
+ width: 16px;
+ border-radius: 3px;
+}
+
+/* ============================================================
+ * 底部弹出 Sheet — 对齐 zibll .modal.bottom
+ * ============================================================ */
+.aksrt-modal--bottom .aksrt-modal-auth__card,
+.modal.bottom .modal-dialog {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ max-width: 100%;
+ width: 100%;
+ border-radius: var(--main-radius, 8px) var(--main-radius, 8px) 0 0;
+ transform: translateY(110%);
+ transition: transform 0.4s;
+ margin-bottom: 0;
+ padding-bottom: env(safe-area-inset-bottom);
+}
+
+.aksrt-modal--bottom.is-open .aksrt-modal-auth__card,
+.modal.bottom.in .modal-dialog {
+ transform: translateY(0);
+}
+
+.aksrt-modal--bottom .aksrt-modal-auth__card,
+.modal.bottom .modal-dialog .modal-content {
+ box-shadow: 0 -10px 50px rgba(0, 0, 0, 0.15);
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/dark-mode.css b/assets/css/frontend/enhancements/modal-motion/dark-mode.css
new file mode 100644
index 00000000..8c2bcbf1
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/dark-mode.css
@@ -0,0 +1,19 @@
+/* Dark mode */
+.theme-dark .aksrt-modal-auth__card,
+html.dark .aksrt-modal-auth__card {
+ background: #1e1e2e;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.theme-dark .aksrt-modal-auth__field input,
+html.dark .aksrt-modal-auth__field input {
+ background: #2a2a3a;
+ border-color: rgba(255, 255, 255, 0.15);
+ color: #e0e0e0;
+}
+
+.theme-dark .aksrt-modal-auth__close,
+html.dark .aksrt-modal-auth__close {
+ background: #2a2a3a;
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/divider.css b/assets/css/frontend/enhancements/modal-motion/divider.css
new file mode 100644
index 00000000..447d1139
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/divider.css
@@ -0,0 +1,18 @@
+/* Divider */
+.aksrt-modal-auth__divider {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin: 20px 0;
+ color: var(--color-ink-4, #8A8F98);
+ font-size: 12px;
+}
+
+.aksrt-modal-auth__divider::before,
+.aksrt-modal-auth__divider::after {
+ content: '';
+ flex: 1;
+ height: 1px;
+ background: var(--color-line);
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/footer.css b/assets/css/frontend/enhancements/modal-motion/footer.css
new file mode 100644
index 00000000..e9611509
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/footer.css
@@ -0,0 +1,22 @@
+/* Footer */
+.aksrt-modal-auth__footer {
+ text-align: center;
+ margin-top: 20px;
+ font-size: 13px;
+ color: var(--color-ink-3);
+}
+
+.aksrt-modal-auth__switch {
+ border: none;
+ background: none;
+ color: var(--color-primary, var(--color-primary));
+ cursor: pointer;
+ font-size: 13px;
+ font-weight: 500;
+ padding: 0;
+}
+
+.aksrt-modal-auth__switch:hover {
+ text-decoration: underline;
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/form.css b/assets/css/frontend/enhancements/modal-motion/form.css
new file mode 100644
index 00000000..6205a298
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/form.css
@@ -0,0 +1,120 @@
+/* Form */
+.aksrt-modal-auth__form {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.aksrt-modal-auth__error {
+ padding: 10px 14px;
+ border-radius: 8px;
+ background: rgba(239, 68, 68, 0.08);
+ color: var(--color-error, #EF4444);
+ font-size: 13px;
+ line-height: 1.5;
+}
+
+.aksrt-modal-auth__error a {
+ color: var(--color-primary, var(--color-primary));
+ text-decoration: underline;
+}
+
+.aksrt-modal-auth__field label {
+ display: block;
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--color-ink-2);
+ margin-bottom: 6px;
+}
+
+.aksrt-modal-auth__field input {
+ width: 100%;
+ padding: 10px 14px;
+ border: 1px solid var(--color-line);
+ border-radius: 10px;
+ font-size: 14px;
+ color: var(--color-ink);
+ background: var(--surface-1, #fff);
+ transition: border-color 0.2s;
+ box-sizing: border-box;
+}
+
+.aksrt-modal-auth__field input:focus {
+ outline: none;
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-modal-auth__field input::placeholder {
+ color: var(--color-ink-4, #8A8F98);
+}
+
+.aksrt-modal-auth__pass-wrap {
+ position: relative;
+}
+
+.aksrt-modal-auth__pass-wrap input {
+ padding-right: 44px;
+}
+
+.aksrt-modal-auth__pass-toggle {
+ position: absolute;
+ right: 8px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 32px;
+ height: 32px;
+ border: none;
+ background: none;
+ color: var(--color-ink-4, #8A8F98);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 6px;
+}
+
+.aksrt-modal-auth__pass-toggle:hover {
+ background: var(--surface-2, #F4F5F7);
+}
+
+.aksrt-modal-auth__actions {
+ display: flex;
+ justify-content: flex-end;
+}
+
+.aksrt-modal-auth__link {
+ font-size: 13px;
+ color: var(--color-primary, var(--color-primary));
+ text-decoration: none;
+}
+
+.aksrt-modal-auth__link:hover {
+ text-decoration: underline;
+}
+
+.aksrt-modal-auth__submit {
+ width: 100%;
+ padding: 12px;
+ border: none;
+ border-radius: 10px;
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+ font-size: 15px;
+ font-weight: 600;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ transition: opacity 0.2s;
+}
+
+.aksrt-modal-auth__submit:hover {
+ opacity: 0.85;
+}
+
+.aksrt-modal-auth__submit:disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/oauth.css b/assets/css/frontend/enhancements/modal-motion/oauth.css
new file mode 100644
index 00000000..6234e3d7
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/oauth.css
@@ -0,0 +1,27 @@
+/* OAuth */
+.aksrt-modal-auth__oauth {
+ display: flex;
+ justify-content: center;
+ gap: 12px;
+}
+
+.aksrt-modal-auth__oauth-btn {
+ width: 44px;
+ height: 44px;
+ border: 1px solid var(--color-line);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--color-ink-2);
+ font-size: 18px;
+ text-decoration: none;
+ transition: all 0.2s;
+}
+
+.aksrt-modal-auth__oauth-btn:hover {
+ border-color: var(--color-primary, var(--color-primary));
+ color: var(--color-primary, var(--color-primary));
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.1));
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/panels.css b/assets/css/frontend/enhancements/modal-motion/panels.css
new file mode 100644
index 00000000..1abd604b
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/panels.css
@@ -0,0 +1,9 @@
+/* Panels */
+.aksrt-modal-auth__panel {
+ display: none;
+}
+
+.aksrt-modal-auth__panel.is-active {
+ display: block;
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/responsive.css b/assets/css/frontend/enhancements/modal-motion/responsive.css
new file mode 100644
index 00000000..86cb6a46
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/responsive.css
@@ -0,0 +1,139 @@
+/* Responsive */
+@media (max-width: 480px) {
+ .aksrt-modal-auth__card {
+ padding: 24px 20px;
+ border-radius: 12px;
+ }
+
+ .aksrt-modal-auth__logo {
+ width: 48px;
+ height: 48px;
+ font-size: 18px;
+ }
+
+ .aksrt-modal-auth__title {
+ font-size: 18px;
+ }
+}
+
+/* ============================================================
+ * 22. 语言切换器
+ * ============================================================ */
+.aksrt-lang-switch {
+ position: relative;
+}
+
+.aksrt-lang-switch__toggle {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 12px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-2);
+ font-size: 13px;
+ cursor: pointer;
+ transition: border-color 0.2s;
+ width: 100%;
+}
+
+.aksrt-lang-switch__toggle:hover {
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-lang-switch__toggle img {
+ border-radius: 2px;
+}
+
+.aksrt-lang-switch__dropdown {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ margin: 4px 0 0;
+ padding: 4px;
+ list-style: none;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+ z-index: 100;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(4px);
+ transition: all 0.2s;
+}
+
+.aksrt-lang-switch:hover .aksrt-lang-switch__dropdown,
+.aksrt-lang-switch__toggle:focus + .aksrt-lang-switch__dropdown {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.aksrt-lang-switch__item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 10px;
+ border-radius: 6px;
+ font-size: 13px;
+ color: var(--color-ink-2);
+ text-decoration: none;
+ transition: background 0.15s;
+}
+
+.aksrt-lang-switch__item:hover {
+ background: var(--surface-2, #F4F5F7);
+}
+
+.aksrt-lang-switch__item.is-active {
+ color: var(--color-primary, var(--color-primary));
+ font-weight: 600;
+}
+
+.aksrt-lang-switch__item img {
+ border-radius: 2px;
+}
+
+/* 国旗模式 */
+.aksrt-lang-switch--flags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.aksrt-lang-switch__flag {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 24px;
+ border: 2px solid transparent;
+ border-radius: 4px;
+ overflow: hidden;
+ transition: border-color 0.2s;
+ text-decoration: none;
+}
+
+.aksrt-lang-switch__flag:hover {
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-lang-switch__flag.is-active {
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-lang-switch__flag img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.aksrt-lang-switch__flag span {
+ font-size: 10px;
+ font-weight: 600;
+ color: var(--color-ink-3);
+}
+
diff --git a/assets/css/frontend/enhancements/modal-motion/tabs.css b/assets/css/frontend/enhancements/modal-motion/tabs.css
new file mode 100644
index 00000000..079a0b7a
--- /dev/null
+++ b/assets/css/frontend/enhancements/modal-motion/tabs.css
@@ -0,0 +1,34 @@
+/* Tabs */
+.aksrt-modal-auth__tabs {
+ display: flex;
+ border-bottom: 1px solid var(--color-line);
+ margin-bottom: 20px;
+}
+
+.aksrt-modal-auth__tab {
+ flex: 1;
+ padding: 10px;
+ border: none;
+ background: none;
+ font-size: 15px;
+ font-weight: 500;
+ color: var(--color-ink-3);
+ cursor: pointer;
+ position: relative;
+ transition: color 0.2s;
+}
+
+.aksrt-modal-auth__tab.is-active {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-modal-auth__tab.is-active::after {
+ content: '';
+ position: absolute;
+ bottom: -1px;
+ left: 0;
+ right: 0;
+ height: 2px;
+ background: var(--color-primary, var(--color-primary));
+}
+
diff --git a/assets/css/frontend/floating-buttons.css b/assets/css/frontend/floating-buttons.css
new file mode 100644
index 00000000..7ddad783
--- /dev/null
+++ b/assets/css/frontend/floating-buttons.css
@@ -0,0 +1,350 @@
+/* ============================================================
+ * Floating Buttons
+ * ============================================================ */
+
+.float-right {
+ --float-btn-size: 42px;
+ --float-btn-spacing: 8px;
+ --float-btn-opacity: 1;
+ --float-btn-color: var(--color-ink-3);
+ --float-btn-bg: transparent;
+ --float-btn-active-color: var(--color-primary);
+ position: fixed;
+ right: 20px;
+ bottom: 96px;
+ z-index: 900;
+ display: flex;
+ flex-direction: column;
+ gap: var(--float-btn-spacing, 8px);
+ opacity: var(--float-btn-opacity, 1);
+ transition: transform var(--dur, 0.25s) var(--ease, ease), opacity var(--dur, 0.25s) var(--ease, ease);
+ padding-bottom: env(safe-area-inset-bottom, 0px);
+}
+
+.float-right.no-shadow .float-btn {
+ box-shadow: none;
+}
+
+.float-right.no-animation .float-btn {
+ transition: none;
+}
+
+.float-right.no-animation .float-btn:hover {
+ transform: none;
+}
+
+.float-right.position-center {
+ top: 50%;
+ bottom: auto;
+ transform: translateY(-50%);
+}
+
+.float-right.square {
+ gap: 0;
+ overflow: hidden;
+ border-radius: var(--radius-lg, 8px);
+ box-shadow: var(--shadow-md, 0 10px 30px rgba(17, 24, 39, 0.12));
+}
+
+.float-right .float-btn {
+ width: var(--float-btn-size);
+ min-height: var(--float-btn-size);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ color: var(--this-color, var(--float-btn-color));
+ background: var(--this-bg, var(--float-btn-bg));
+ border: 1px solid var(--color-line-soft, #f0f1f3);
+ text-decoration: none;
+ box-shadow: var(--shadow, 0 8px 24px rgba(17, 24, 39, 0.08));
+ transition: transform var(--dur-fast, 0.15s) var(--ease, ease), box-shadow var(--dur-fast, 0.15s) var(--ease, ease), color var(--dur-fast, 0.15s) var(--ease, ease), background var(--dur-fast, 0.15s) var(--ease, ease);
+ cursor: pointer;
+ outline: none;
+ overflow: visible;
+}
+
+.float-right.round .float-btn {
+ border-radius: 12px;
+}
+
+.float-right.square .float-btn {
+ border-radius: 0;
+ box-shadow: none;
+ border-top-width: 0;
+}
+
+.float-right.square .float-btn:first-child {
+ border-top-width: 1px;
+}
+
+.float-right .float-btn:hover {
+ transform: translateY(-2px);
+ color: var(--float-btn-active-color, var(--color-primary));
+ text-decoration: none;
+ box-shadow: var(--shadow-md, 0 10px 30px rgba(17, 24, 39, 0.12));
+ z-index: 2;
+}
+
+.float-right .float-btn:active {
+ transform: scale(0.96);
+}
+
+.float-right .float-btn::after {
+ content: "";
+ position: absolute;
+ inset: auto;
+ width: 6px;
+ height: 6px;
+ border-radius: 999px;
+ background: currentColor;
+ opacity: 0;
+ transform: scale(1);
+ pointer-events: none;
+}
+
+.float-right .float-btn.is-rippling::after {
+ animation: float-btn-ripple 0.55s ease-out;
+}
+
+.float-right .float-btn i {
+ font-size: 16px;
+ line-height: 1;
+}
+
+.float-right .float-btn.ontop {
+ opacity: 0;
+ visibility: hidden;
+ pointer-events: none;
+}
+
+.float-right .float-btn.ontop.is-visible {
+ opacity: 1;
+ visibility: visible;
+ pointer-events: auto;
+}
+
+.float-right.has-blur-pc .float-btn {
+ backdrop-filter: saturate(1.5) blur(10px);
+ -webkit-backdrop-filter: saturate(1.5) blur(10px);
+}
+
+.float-right .hover-show-con {
+ position: absolute;
+ display: block;
+ right: calc(100% + 12px);
+ top: 50%;
+ transform: translateY(-50%);
+ min-width: 180px;
+ max-width: 280px;
+ padding: 12px;
+ border-radius: var(--radius-lg, 8px);
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ box-shadow: var(--shadow-lg, 0 18px 40px rgba(17, 24, 39, 0.18));
+ color: var(--color-ink-2);
+ opacity: 0;
+ visibility: hidden;
+ pointer-events: none;
+ transition: opacity var(--dur-fast, 0.15s) var(--ease, ease), transform var(--dur-fast, 0.15s) var(--ease, ease), visibility var(--dur-fast, 0.15s) var(--ease, ease);
+}
+
+.float-right .hover-show-con::before {
+ content: "";
+ position: absolute;
+ top: 50%;
+ right: -8px;
+ width: 16px;
+ height: 16px;
+ background: inherit;
+ border-top: 1px solid var(--color-line);
+ border-right: 1px solid var(--color-line);
+ transform: translateY(-50%) rotate(45deg);
+}
+
+.float-right .hover-show-con img {
+ display: block;
+ width: 100%;
+ max-width: 160px;
+ height: auto;
+ margin: 0 auto 10px;
+ border-radius: var(--radius, 10px);
+}
+
+.float-right .hover-show-con p {
+ margin: 0;
+ font-size: 13px;
+ line-height: 1.6;
+ color: var(--color-ink-3);
+}
+
+.float-btn-qrcode {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ min-height: 120px;
+ margin: 0 auto 10px;
+ background: #fff;
+ border-radius: var(--radius, 10px);
+}
+
+.float-right .service-wechat .hover-show-con,
+.float-right .service-qq .hover-show-con,
+.float-right .qrcode-btn .hover-show-con {
+ padding: 14px;
+}
+
+.float-right .service-wechat .hover-show-con img,
+.float-right .service-qq .hover-show-con img {
+ margin: 0 auto;
+ box-shadow: 0 10px 24px rgba(17, 24, 39, 0.12);
+}
+
+.float-right .service-wechat .hover-show-con p,
+.float-right .service-qq .hover-show-con p {
+ display: none;
+}
+
+.float-right .newadd-btns .hover-show-con {
+ min-width: 196px;
+ padding: 10px;
+}
+
+.float-add-menu {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.float-add-menu__item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 12px;
+ border-radius: 10px;
+ color: var(--color-ink-2);
+ text-decoration: none;
+ transition: background var(--dur-fast, 0.15s) var(--ease, ease), color var(--dur-fast, 0.15s) var(--ease, ease), transform var(--dur-fast, 0.15s) var(--ease, ease);
+}
+
+.float-add-menu__item i {
+ width: 18px;
+ text-align: center;
+ color: var(--color-primary, var(--color-primary));
+}
+
+.float-add-menu__item:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.1));
+ color: var(--color-primary, var(--color-primary));
+ transform: translateX(-2px);
+}
+
+.float-btn-qrcode :deep(canvas),
+.float-btn-qrcode :deep(img),
+.float-btn-qrcode svg {
+ display: block;
+ margin: 0 auto;
+}
+
+.float-right .float-btn:hover .hover-show-con,
+.float-right .float-btn:focus-visible .hover-show-con {
+ opacity: 1;
+ visibility: visible;
+ pointer-events: auto;
+ transform: translateY(-50%) translateX(-4px);
+}
+
+.float-right.scrolling-hide.is-hidden,
+.float-right.scroll-down-hide.is-hidden {
+ transform: translateX(calc(100% + 24px));
+}
+
+.float-right.position-center.scrolling-hide.is-hidden,
+.float-right.position-center.scroll-down-hide.is-hidden {
+ transform: translateX(calc(100% + 24px)) translateY(-50%);
+}
+
+.float-right__html {
+ font-size: 13px;
+ line-height: 1.6;
+}
+
+.float-right__html a {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.float-right__html a:hover {
+ color: var(--color-primary-hover, #7099CC);
+}
+
+@keyframes float-btn-ripple {
+ 0% {
+ opacity: 0.22;
+ transform: scale(1);
+ }
+ 100% {
+ opacity: 0;
+ transform: scale(14);
+ }
+}
+
+.float-btn__icon-moon {
+ display: none;
+}
+
+.float-btn__icon-sun {
+ display: inline-block;
+}
+
+.theme-dark .float-btn__icon-moon,
+html.dark .float-btn__icon-moon,
+body.dark-theme .float-btn__icon-moon {
+ display: inline-block;
+}
+
+.theme-dark .float-btn__icon-sun,
+html.dark .float-btn__icon-sun,
+body.dark-theme .float-btn__icon-sun {
+ display: none;
+}
+
+.theme-dark .float-right,
+html.dark .float-right,
+body.dark-theme .float-right {
+ --float-btn-color: var(--color-ink-4);
+}
+
+.theme-dark .float-right .hover-show-con,
+html.dark .float-right .hover-show-con,
+body.dark-theme .float-right .hover-show-con {
+ background: var(--surface-2, #1f2430);
+ border-color: rgba(255, 255, 255, 0.08);
+}
+
+@media (max-width: 767px) {
+ .float-right {
+ right: 12px;
+ bottom: 84px;
+ --float-btn-size: 40px;
+ }
+
+ .float-right.has-blur-mobile .float-btn {
+ backdrop-filter: saturate(1.5) blur(10px);
+ -webkit-backdrop-filter: saturate(1.5) blur(10px);
+ }
+
+ .float-right .hover-show-con {
+ max-width: min(240px, calc(100vw - 84px));
+ }
+
+ .float-right .float-btn.hide-on-mobile {
+ display: none;
+ }
+}
+
+@media (min-width: 768px) {
+ .float-right .float-btn.hide-on-pc {
+ display: none;
+ }
+}
diff --git a/assets/css/frontend/footer.css b/assets/css/frontend/footer.css
new file mode 100644
index 00000000..f62048cd
--- /dev/null
+++ b/assets/css/frontend/footer.css
@@ -0,0 +1,4 @@
+@import url("footer/part-1.css");
+@import url("footer/part-2.css");
+@import url("footer/part-3.css");
+@import url("footer/part-4.css");
diff --git a/assets/css/frontend/footer/part-1.css b/assets/css/frontend/footer/part-1.css
new file mode 100644
index 00000000..0ebc8088
--- /dev/null
+++ b/assets/css/frontend/footer/part-1.css
@@ -0,0 +1,300 @@
+/* ============================================================
+ * AKSRT Footer — v4.0 Zibll-Inspired
+ *
+ * 包含:
+ * - 页脚主体(Bootstrap Grid)
+ * - 浮动右侧按钮组
+ * - 移动端底部 Tab 栏
+ * ============================================================ */
+
+/* ============================================================
+ * 页脚主体
+ * ============================================================ */
+:root {
+ --aksrt-footer-tabbar-height: 49px;
+}
+
+.site-footer {
+ margin-top: auto;
+ background: var(--footer-bg, var(--surface-1));
+ padding: 30px;
+}
+
+.site-footer__inner {
+ max-width: var(--container);
+ margin: 0 auto;
+ padding: 0 16px;
+}
+
+@media (min-width: 768px) {
+ .site-footer__inner {
+ padding: 0 24px;
+ }
+}
+
+.site-footer__grid {
+ padding-bottom: 32px;
+}
+
+.site-footer__brand {
+ margin-bottom: 24px;
+}
+
+.site-footer__title {
+ font-size: 1rem;
+ font-weight: 700;
+ margin: 0 0 12px;
+ color: var(--color-ink);
+}
+
+.site-footer__desc {
+ font-size: 14px;
+ color: var(--color-ink-4);
+ line-height: 1.6;
+ margin: 0 0 16px;
+ max-width: 360px;
+}
+
+.site-footer__col {
+ margin-bottom: 24px;
+}
+
+.site-footer__col ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.site-footer__col li {
+ margin-bottom: 8px;
+}
+
+.site-footer__col a {
+ font-size: 14px;
+ color: var(--footer-color, var(--color-ink-3));
+ transition: color 0.15s ease;
+}
+
+.site-footer__col a:hover {
+ color: var(--focus-color, var(--color-primary));
+}
+
+/* 社交链接行 */
+.social-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 16px;
+}
+
+.social-row a {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ background: var(--surface-3);
+ color: var(--color-ink-3);
+ transition: background 0.2s, color 0.2s, transform 0.2s;
+}
+
+.social-row a:hover {
+ background: var(--color-primary);
+ color: #fff;
+ transform: translateY(-2px);
+}
+
+.social-row .social-icon-link {
+ background: var(--surface-3);
+ color: var(--color-ink-3);
+}
+
+.social-row .social-icon-link:hover {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+/* 友情链接 */
+.site-footer__friends {
+ margin-top: 16px;
+}
+
+.site-footer__friends-title {
+ font-size: 0.8125rem;
+ font-weight: 600;
+ color: var(--color-ink-4);
+ margin: 0 0 8px;
+}
+
+.site-footer__friends-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px 12px;
+}
+
+.site-footer__friends-list a {
+ font-size: 0.8125rem;
+ color: var(--color-ink-4);
+}
+
+.site-footer__friends-list a:hover {
+ color: var(--color-primary);
+}
+
+/* 底部栏 */
+.site-footer__bottom {
+ border-top: 1px solid var(--color-line);
+ padding: 20px 0;
+ text-align: center;
+}
+
+.site-footer__filings {
+ display: flex;
+ justify-content: center;
+ gap: 16px;
+ margin-bottom: 8px;
+ flex-wrap: wrap;
+}
+
+.site-footer__filings a {
+ font-size: 0.75rem;
+ color: var(--color-ink-4);
+}
+
+.site-footer__filings a:hover {
+ color: var(--color-primary);
+}
+
+.site-footer__copyright {
+ font-size: 12px;
+ color: var(--color-ink-4);
+ margin: 0;
+}
+
+/* §2.3 三列结构化字段 */
+
+/* 品牌 Logo */
+.site-footer__logo {
+ margin-bottom: 16px;
+}
+.site-footer__logo-img {
+ max-height: 48px;
+ width: auto;
+}
+.site-footer__logo-img--dark {
+ display: none;
+}
+[data-theme="dark"] .site-footer__logo-img--light {
+ display: none;
+}
+[data-theme="dark"] .site-footer__logo-img--dark {
+ display: inline-block;
+}
+
+/* 标准联系项 */
+.site-footer__contact-std {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 10px;
+ margin: 12px 0;
+}
+.site-footer__contact-item {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ background: var(--surface-2, rgba(0,0,0,.05));
+ color: var(--color-ink-3, #888);
+ font-size: 16px;
+ position: relative;
+ cursor: pointer;
+ text-decoration: none;
+ transition: background .2s, color .2s;
+}
+.site-footer__contact-item:hover,
+.site-footer__contact-item:focus {
+ background: var(--color-primary);
+ color: #fff;
+}
+.site-footer__contact-hover {
+ display: none;
+ position: absolute;
+ bottom: calc(100% + 10px);
+ left: 50%;
+ transform: translateX(-50%);
+ padding: 8px;
+ background: var(--surface-1, #fff);
+ border-radius: 8px;
+ box-shadow: 0 4px 16px rgba(0,0,0,.15);
+ z-index: 10;
+ white-space: nowrap;
+}
+.site-footer__contact-hover img {
+ width: 120px;
+ height: 120px;
+ object-fit: contain;
+ border-radius: 4px;
+}
+.site-footer__contact-item:hover .site-footer__contact-hover,
+.site-footer__contact-item:focus .site-footer__contact-hover {
+ display: block;
+}
+
+/* 自定义代码区域 */
+.site-footer__custom-code,
+.site-footer__customize-code {
+ margin-top: 8px;
+ font-size: 0.85rem;
+ color: var(--color-ink-4, #999);
+}
+
+/* 二维码图片组 */
+.site-footer__mini-qr {
+ display: flex;
+ justify-content: center;
+ gap: 24px;
+ padding: 20px 0;
+ border-top: 1px solid var(--color-line, #eee);
+}
+.site-footer__mini-qr-item {
+ text-align: center;
+}
+.site-footer__mini-qr-item img {
+ width: 80px;
+ height: 80px;
+ object-fit: contain;
+ border-radius: 6px;
+ border: 1px solid var(--color-line, #eee);
+}
+.site-footer__mini-qr-item span {
+ display: block;
+ margin-top: 6px;
+ font-size: 12px;
+ color: var(--color-ink-4, #999);
+}
+
+/* 设备可见性工具类 */
+@media (max-width: 767px) {
+ .hide-on-mobile { display: none !important; }
+}
+@media (min-width: 768px) {
+ .hide-on-desktop { display: none !important; }
+}
+
+/* ============================================================
+ * 浮动右侧按钮组(模仿 zibll float-right)
+ * ============================================================ */
+/* 对齐 zibll: bottom 60px, z-index 1030 */
+.float-right-btns {
+ position: fixed;
+ right: 20px;
+ bottom: 60px;
+ z-index: 1030;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ transition: opacity 0.3s ease;
diff --git a/assets/css/frontend/footer/part-2.css b/assets/css/frontend/footer/part-2.css
new file mode 100644
index 00000000..97523579
--- /dev/null
+++ b/assets/css/frontend/footer/part-2.css
@@ -0,0 +1,300 @@
+}
+
+/* 对齐 zibll: 40px, 1.4em icon */
+.float-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ min-height: 40px;
+ border-radius: 50%;
+ border: none;
+ background: var(--float-btn-bg);
+ color: var(--color-ink-3);
+ box-shadow: var(--shadow-sm);
+ cursor: pointer;
+ transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
+ font-size: 1.4em;
+ text-decoration: none;
+}
+
+.float-btn:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow);
+ color: var(--color-primary);
+ background: var(--surface-page);
+ text-decoration: none;
+}
+
+.float-btn:active {
+ transform: scale(0.95);
+}
+
+/* 回到顶部按钮 — 滚动后显示 */
+.float-btn--top {
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.2s ease;
+}
+
+.float-btn--top.is-visible {
+ opacity: 1;
+ visibility: visible;
+ display: flex;
+}
+
+/* 主题切换按钮 */
+#float-theme-toggle .float-btn__icon-moon {
+ display: none !important;
+}
+
+#float-theme-toggle .float-btn__icon-sun {
+ display: inline-block !important;
+}
+
+#float-theme-toggle[aria-pressed="true"] .float-btn__icon-moon,
+.theme-dark #float-theme-toggle .float-btn__icon-moon,
+html.dark #float-theme-toggle .float-btn__icon-moon,
+body.dark-theme #float-theme-toggle .float-btn__icon-moon {
+ display: inline-block !important;
+}
+
+#float-theme-toggle[aria-pressed="true"] .float-btn__icon-sun,
+.theme-dark #float-theme-toggle .float-btn__icon-sun,
+html.dark #float-theme-toggle .float-btn__icon-sun,
+body.dark-theme #float-theme-toggle .float-btn__icon-sun {
+ display: none !important;
+}
+
+/* 移动端隐藏浮动按钮(用 tabbar 代替) */
+@media (max-width: 767px) {
+ .float-right-btns {
+ right: 12px;
+ bottom: 80px;
+ }
+
+ .float-btn {
+ width: 38px;
+ height: 38px;
+ font-size: 14px;
+ }
+}
+
+/* ============================================================
+ * 移动端底部 Tab 栏(模仿 zibll footer-tabbar)
+ * ============================================================ */
+.footer-tabbar {
+ display: none;
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 1035;
+ min-height: var(--aksrt-footer-tabbar-height);
+ background: var(--blur-bg);
+ border-top: 1px solid var(--color-line-soft);
+ padding: 0 0 env(safe-area-inset-bottom, 0px);
+ justify-content: space-around;
+ align-items: center;
+ box-shadow: 0 -4px 5px var(--main-shadow, rgba(0, 0, 0, 0.06));
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+ --tabbar-active-color: #f04494;
+ --tabbar-icon-size: 24px;
+ --tabbar-text-size: 10px;
+}
+
+.footer-tabbar.no-border {
+ border-top: none;
+}
+
+.footer-tabbar.no-shadow {
+ box-shadow: none;
+}
+
+.footer-tabbar.hide-text .tabbar-item span {
+ display: none;
+}
+
+.footer-tabbar.has-animation .tabbar-item {
+ transition: color 0.15s ease, transform 0.15s ease;
+}
+
+.footer-tabbar.has-animation .tabbar-item:active {
+ transform: scale(0.9);
+}
+
+.footer-tabbar-placeholder {
+ display: none;
+ height: calc(var(--aksrt-footer-tabbar-height) + env(safe-area-inset-bottom, 0px));
+}
+
+@media (max-width: 767px) {
+ .footer-tabbar {
+ display: flex;
+ }
+
+ .footer-tabbar-placeholder {
+ display: block;
+ }
+
+ /* 有 tabbar 时页脚需要额外底部间距 */
+ .site-footer {
+ padding-bottom: calc(var(--aksrt-footer-tabbar-height) + env(safe-area-inset-bottom, 0px));
+ }
+}
+
+.tabbar-item {
+ display: flex;
+ flex: 1 1 0;
+ min-width: 0;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 1px;
+ min-height: 49px;
+ padding: 4px 0 3px;
+ color: var(--muted-color, var(--color-ink-3));
+ font-size: 13px;
+ text-decoration: none;
+ border: none;
+ background: none;
+ cursor: pointer;
+ transition: color 0.15s ease;
+ -webkit-tap-highlight-color: transparent;
+ position: relative;
+}
+
+/* 对齐 zibll: 24px 图标 */
+.tabbar-item i {
+ font-size: var(--tabbar-icon-size, 24px);
+ line-height: 1;
+}
+
+.tabbar-item span {
+ display: block;
+ font-size: var(--tabbar-text-size, 10px);
+ font-weight: 500;
+ line-height: 1;
+ transform: scale(0.8);
+ transform-origin: center top;
+}
+
+.tabbar-item:hover,
+.tabbar-item.active {
+ color: var(--tabbar-active-color, var(--color-primary));
+ text-decoration: none;
+}
+
+.tabbar-item.active i {
+ font-weight: 900;
+}
+
+.tabbar-badge {
+ position: absolute;
+ top: 2px;
+ right: 8px;
+ min-width: 16px;
+ height: 16px;
+ padding: 0 4px;
+ border-radius: 999px;
+ background: var(--color-error);
+ color: #fff;
+ font-size: 10px;
+ line-height: 16px;
+ font-style: normal;
+ font-weight: 700;
+ text-align: center;
+ box-shadow: 0 2px 8px rgba(239, 68, 68, 0.20);
+}
+
+.tabbar-badge--dot {
+ min-width: 0;
+ width: 8px;
+ height: 8px;
+ padding: 0;
+ top: 4px;
+ right: 10px;
+ font-size: 0;
+ line-height: 1;
+ box-shadow: 0 0 0 2px var(--blur-bg);
+}
+
+.tabbar-item--add {
+ margin-top: -22px;
+ width: 62px;
+ height: 62px;
+ min-height: 62px;
+ border-radius: 50%;
+ background: var(--color-accent);
+ color: #fff;
+ box-shadow: 0 12px 24px var(--color-accent-shadow);
+ flex: 0 0 62px;
+ z-index: 1;
+}
+
+.tabbar-item--add i {
+ font-size: 22px;
+}
+
+.tabbar-item--add span {
+ font-size: 11px;
+}
+
+.tabbar-item--add:hover,
+.tabbar-item--add.active {
+ color: #fff;
+}
+
+.tabbar-add-backdrop {
+ position: fixed;
+ inset: 0;
+ z-index: 951;
+ background: rgba(15, 23, 42, 0.38);
+}
+
+.tabbar-add-panel {
+ position: fixed;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 952;
+ padding: 0 12px calc(84px + env(safe-area-inset-bottom, 0px));
+}
+
+.tabbar-add-panel__sheet {
+ border-radius: 20px;
+ background: var(--surface-page);
+ box-shadow: 0 18px 50px rgba(15, 23, 42, 0.18);
+ overflow: hidden;
+}
+
+.tabbar-add-panel__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 16px 18px 12px;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.tabbar-add-panel__close {
+ width: 32px;
+ height: 32px;
+ border: 0;
+ border-radius: 50%;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+}
+
+.tabbar-add-panel__list {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 12px;
+ padding: 18px;
+}
+
+.tabbar-add-panel__item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
diff --git a/assets/css/frontend/footer/part-3.css b/assets/css/frontend/footer/part-3.css
new file mode 100644
index 00000000..d8d0ed4a
--- /dev/null
+++ b/assets/css/frontend/footer/part-3.css
@@ -0,0 +1,300 @@
+ gap: 8px;
+ min-height: 88px;
+ border-radius: 18px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ text-decoration: none;
+}
+
+.tabbar-add-panel__item i {
+ font-size: 22px;
+ color: var(--color-accent);
+}
+
+.tabbar-add-panel__item span {
+ font-size: 13px;
+ font-weight: 600;
+}
+
+.tabbar-search-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 953;
+ background: rgba(15, 23, 42, 0.58);
+ display: flex;
+ align-items: stretch;
+ justify-content: center;
+}
+
+.tabbar-search-overlay__dialog {
+ width: 100%;
+ min-height: 100%;
+ background: var(--surface-page);
+ padding: 18px 16px calc(24px + env(safe-area-inset-bottom, 0px));
+}
+
+.tabbar-search-overlay__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 16px;
+}
+
+.tabbar-search-overlay__close {
+ width: 36px;
+ height: 36px;
+ border: 0;
+ border-radius: 50%;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+}
+
+.tabbar-search-overlay__form {
+ display: grid;
+ grid-template-columns: 20px 1fr auto;
+ gap: 10px;
+ align-items: center;
+ padding: 14px 14px 14px 12px;
+ border-radius: 18px;
+ background: var(--surface-2);
+}
+
+.tabbar-search-overlay__icon {
+ color: var(--color-ink-4);
+}
+
+.tabbar-search-overlay__form input {
+ min-width: 0;
+ border: 0;
+ background: transparent;
+ color: var(--color-ink);
+ font-size: 15px;
+ outline: none;
+}
+
+.tabbar-search-overlay__submit {
+ border: 0;
+ border-radius: 12px;
+ padding: 10px 14px;
+ background: var(--color-accent);
+ color: #fff;
+ font-weight: 700;
+}
+
+.tabbar-search-overlay__types {
+ display: flex;
+ gap: 8px;
+ margin-top: 14px;
+}
+
+.tabbar-search-overlay__type {
+ border: 0;
+ border-radius: 999px;
+ padding: 9px 14px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ font-size: 13px;
+ font-weight: 600;
+}
+
+.tabbar-search-overlay__type.is-active {
+ background: var(--color-accent-soft);
+ color: var(--color-accent);
+}
+
+.tabbar-search-overlay__section {
+ margin-top: 20px;
+}
+
+.tabbar-search-overlay__section-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 12px;
+}
+
+.tabbar-search-overlay__label {
+ color: var(--color-ink-3);
+ font-size: 13px;
+ font-weight: 700;
+}
+
+.tabbar-search-overlay__clear {
+ border: 0;
+ background: transparent;
+ color: var(--color-accent);
+ font-size: 12px;
+ font-weight: 700;
+}
+
+.tabbar-search-overlay__history,
+.tabbar-search-overlay__suggestions {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.tabbar-search-overlay__history-item,
+.tabbar-search-overlay__suggestion-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ width: 100%;
+ border: 0;
+ border-radius: 16px;
+ padding: 12px 14px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ text-decoration: none;
+ text-align: left;
+}
+
+.tabbar-search-overlay__history-item i {
+ color: var(--color-accent);
+}
+
+.tabbar-search-overlay__history-item span,
+.tabbar-search-overlay__suggestion-item span {
+ flex: 1;
+ min-width: 0;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.tabbar-search-overlay__suggestion-item small {
+ color: var(--color-ink-4);
+ font-size: 12px;
+}
+
+.tabbar-search-overlay__empty {
+ padding: 14px;
+ border-radius: 16px;
+ background: var(--surface-2);
+ color: var(--color-ink-4);
+ font-size: 13px;
+ text-align: center;
+}
+
+.tabbar-search-overlay__tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.tabbar-search-overlay__tag {
+ padding: 10px 14px;
+ border-radius: 999px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ text-decoration: none;
+ font-size: 13px;
+}
+
+body.tabbar-search-open,
+body.tabbar-add-open {
+ overflow: hidden;
+}
+
+/* 滚动时隐藏 tabbar(可选,通过 JS 添加 class) */
+.footer-tabbar.scrolling-hide {
+ transform: translateY(100%);
+ transition: transform 0.3s ease;
+}
+
+/* 向下滚动隐藏,向上滚动显示 */
+.footer-tabbar.scroll-down-hide {
+ transition: transform 0.3s ease;
+}
+
+.footer-tabbar.scroll-down-hide.is-hidden {
+ transform: translateY(120%);
+}
+
+/* 返回顶部包裹项(首页按钮 + 返回顶部切换) */
+.tabbar-ontop-wrap {
+ position: relative;
+}
+
+.tabbar-ontop-wrap .tabbar-ontop-btn {
+ display: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 2px;
+ padding: 4px 12px;
+ color: var(--color-primary);
+ font-size: 13px;
+ text-decoration: none;
+ cursor: pointer;
+ -webkit-tap-highlight-color: transparent;
+}
+
+.tabbar-ontop-wrap .tabbar-ontop-btn i {
+ font-size: 18px;
+ line-height: 1;
+}
+
+.tabbar-ontop-wrap .tabbar-ontop-btn span {
+ font-weight: 500;
+ line-height: 1;
+ transform: scale(0.8);
+ transform-origin: center top;
+}
+
+.tabbar-ontop-wrap.is-scrolled .tabbar-ontop-btn {
+ display: flex;
+}
+
+.tabbar-ontop-wrap.is-scrolled > .tabbar-item:not(.tabbar-ontop-btn) {
+ opacity: 0;
+ pointer-events: none;
+}
+
+/* ============================================================
+ * 暗色模式适配
+ * ============================================================ */
+.theme-dark .site-footer,
+html.dark .site-footer {
+ background: var(--surface-1);
+}
+
+.theme-dark .float-btn,
+html.dark .float-btn {
+ background: var(--float-btn-bg);
+ box-shadow: var(--shadow-sm);
+}
+
+.theme-dark .footer-tabbar,
+html.dark .footer-tabbar {
+ background: var(--blur-bg);
+ box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.20);
+}
+
+/* ============================================================
+ * 旧版 back-to-top 按钮兼容(隐藏,用浮动按钮代替)
+ * ============================================================ */
+.back-to-top {
+ display: none !important;
+}
+
+/* ============================================================
+ * 页脚布局模板变体
+ * ============================================================ */
+
+/* 紧凑模板:单行版权 + 链接 */
+.site-footer--compact .site-footer__grid {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 16px;
+}
+
+.site-footer--compact .site-footer__brand {
+ flex: 1 1 100%;
+}
diff --git a/assets/css/frontend/footer/part-4.css b/assets/css/frontend/footer/part-4.css
new file mode 100644
index 00000000..a540d1c9
--- /dev/null
+++ b/assets/css/frontend/footer/part-4.css
@@ -0,0 +1,52 @@
+
+.site-footer--compact .site-footer__brand .site-footer__desc,
+.site-footer--compact .site-footer__brand .social-row,
+.site-footer--compact .site-footer__brand .site-footer__friends {
+ display: none;
+}
+
+.site-footer--compact .site-footer__col {
+ flex: 0 0 auto;
+}
+
+.site-footer--compact .site-footer__col ul {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.site-footer--compact .site-footer__bottom {
+ border-top: 1px solid var(--color-line);
+ padding-top: 12px;
+ margin-top: 12px;
+}
+
+/* 中央模板:居中品牌 + 链接 */
+.site-footer--centered .site-footer__grid {
+ text-align: center;
+}
+
+.site-footer--centered .site-footer__brand {
+ flex: 1 1 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.site-footer--centered .site-footer__col {
+ flex: 1 1 auto;
+}
+
+.site-footer--centered .site-footer__col ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 16px;
+}
+
diff --git a/assets/css/frontend/forum.css b/assets/css/frontend/forum.css
new file mode 100644
index 00000000..7f126d62
--- /dev/null
+++ b/assets/css/frontend/forum.css
@@ -0,0 +1,4 @@
+@import url("forum/board.css");
+@import url("forum/topic.css");
+@import url("forum/compose.css");
+@import url("forum/extras.css");
diff --git a/assets/css/frontend/forum/board.css b/assets/css/frontend/forum/board.css
new file mode 100644
index 00000000..122ac577
--- /dev/null
+++ b/assets/css/frontend/forum/board.css
@@ -0,0 +1,402 @@
+/* ============================================================
+ * Forum — 板块页、主题页、发帖页
+ * ============================================================ */
+
+/* Board page */
+.aksrt-forum-board {
+ padding-top: 24px;
+ padding-bottom: 48px;
+}
+
+.aksrt-forum-board__header {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 16px;
+ margin-bottom: 24px;
+ padding: 20px;
+ background: var(--surface-1, #fff);
+ border-radius: 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-forum-board__title {
+ margin: 0 0 4px;
+ font-size: 22px;
+ font-weight: 700;
+ color: var(--color-ink);
+}
+
+.aksrt-forum-board__desc {
+ margin: 0 0 8px;
+ font-size: 14px;
+ color: var(--color-ink-3, #8a909c);
+}
+
+.aksrt-forum-board__meta {
+ display: flex;
+ gap: 16px;
+ font-size: 13px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-board__meta i {
+ margin-right: 4px;
+}
+
+.aksrt-forum-board__compose-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 18px;
+ border-radius: 8px;
+ background: var(--color-primary);
+ color: #fff;
+ text-decoration: none;
+ font-size: 14px;
+ font-weight: 500;
+ white-space: nowrap;
+ transition: opacity 0.15s;
+}
+
+.aksrt-forum-board__compose-btn:hover {
+ opacity: 0.85;
+}
+
+.aksrt-forum-board__actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ justify-content: flex-end;
+}
+
+.aksrt-forum-board__manage-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 16px;
+ border-radius: 8px;
+ border: 1px solid var(--color-line, #d9d9d9);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink);
+ text-decoration: none;
+ cursor: pointer;
+ font-size: 13px;
+}
+
+.aksrt-forum-board__manage-btn--danger {
+ border-color: var(--color-error, #f5222d);
+ color: var(--color-error, #f5222d);
+}
+
+.aksrt-forum-board__manage-btn--danger:hover {
+ background: var(--color-error, #f5222d);
+ color: #fff;
+}
+
+.aksrt-forum-board__governance {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 16px;
+ margin-bottom: 20px;
+}
+
+.aksrt-forum-board__governance-card {
+ padding: 18px;
+ background: var(--surface-1, #fff);
+ border-radius: 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-forum-board__section-title {
+ margin: 0 0 10px;
+ font-size: 15px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-forum-board__moderators {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.aksrt-forum-board__moderator {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ padding: 6px 10px;
+ border-radius: 999px;
+ background: var(--surface-1, #f8f9fa);
+}
+
+.aksrt-forum-board__moderator img {
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+}
+
+.aksrt-forum-board__application-form textarea {
+ width: 100%;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ padding: 10px 12px;
+ resize: vertical;
+ font-family: inherit;
+}
+
+.aksrt-forum-board__application-actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ margin-top: 10px;
+}
+
+.aksrt-forum-board__apply-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 8px 14px;
+ border: none;
+ border-radius: 8px;
+ background: var(--color-primary);
+ color: #fff;
+ cursor: pointer;
+}
+
+.aksrt-forum-board__application-note {
+ color: var(--color-ink-3, #8a909c);
+}
+
+.aksrt-forum-board__application-reason {
+ margin: 10px 0;
+ padding: 10px 12px;
+ border-left: 3px solid var(--color-primary, #1890ff);
+ background: var(--surface-2, #f8fafc);
+ color: var(--color-ink-3, #64748b);
+ font-size: 13px;
+}
+
+.aksrt-forum-board__governance-card .aksrt-forum-board__apply-btn {
+ text-decoration: none;
+}
+
+/* Sticky section */
+.aksrt-forum-board__sticky {
+ margin-bottom: 16px;
+ padding: 12px 16px;
+ background: var(--surface-1, #fff);
+ border-radius: 8px;
+ border-left: 3px solid var(--color-primary);
+}
+
+.aksrt-forum-board__sticky h3 {
+ margin: 0 0 8px;
+ font-size: 13px;
+ color: var(--color-ink-3, #8a909c);
+}
+
+.aksrt-forum-board__sticky-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 6px 0;
+ text-decoration: none;
+ color: var(--color-ink);
+ font-size: 14px;
+}
+
+.aksrt-forum-board__sticky-item:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-board__sticky-meta {
+ font-size: 12px;
+ color: var(--color-ink-4, #c0c4cc);
+}
+
+.aksrt-forum-board__sticky-badge {
+ display: inline-block;
+ padding: 1px 6px;
+ border-radius: 3px;
+ font-size: 11px;
+ font-weight: 500;
+ background: var(--color-primary);
+ color: #fff;
+ margin-right: 6px;
+ flex-shrink: 0;
+}
+
+/* Topic list items */
+.aksrt-forum-board__topics {
+ display: flex;
+ flex-direction: column;
+ gap: 1px;
+}
+
+.aksrt-forum-topic-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 14px 16px;
+ background: var(--surface-1, #fff);
+ transition: background 0.15s;
+}
+
+.aksrt-forum-topic-item:first-child {
+ border-radius: 8px 8px 0 0;
+}
+
+.aksrt-forum-topic-item:last-child {
+ border-radius: 0 0 8px 8px;
+}
+
+.aksrt-forum-topic-item:hover {
+ background: var(--surface-1, #f8f9fa);
+}
+
+.aksrt-forum-topic-item.is-sticky {
+ background: var(--surface-2, #f0f5ff);
+}
+
+.aksrt-forum-topic-item.is-featured {
+ border-left: 3px solid var(--color-success, #52c41a);
+}
+
+.aksrt-forum-topic-item__avatar img {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+}
+
+.aksrt-forum-topic-item__body {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-forum-topic-item__title {
+ font-size: 15px;
+ font-weight: 500;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.aksrt-forum-topic-item__title a {
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.aksrt-forum-topic-item__title a:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-topic-item__badge {
+ display: inline-block;
+ padding: 1px 6px;
+ border-radius: 3px;
+ font-size: 11px;
+ font-weight: 500;
+}
+
+.aksrt-forum-topic-item__badge--sticky {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+/* 置顶分级视觉区分(§7.3):超级置顶加深色,全局置顶用红色凸显。 */
+.aksrt-forum-topic-item__badge--sticky-super {
+ background: var(--focus-color, #fd53a1);
+ color: #fff;
+}
+
+.aksrt-forum-topic-item__badge--sticky-global {
+ background: #e53e3e;
+ color: #fff;
+}
+
+.aksrt-forum-topic-item__badge--featured {
+ background: var(--color-success, #52c41a);
+ color: #fff;
+}
+
+.aksrt-forum-topic-item__badge--muted {
+ background: var(--surface-2, #f5f7fa);
+ color: var(--color-ink-3, #8a909c);
+}
+
+.aksrt-forum-topic-item__lock {
+ color: var(--color-warning, #fa8c16);
+ font-size: 12px;
+}
+
+.aksrt-forum-topic-item__meta {
+ display: flex;
+ gap: 12px;
+ margin-top: 3px;
+ font-size: 12px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-topic-item__stats {
+ display: flex;
+ gap: 12px;
+ font-size: 12px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-topic-item__stats i {
+ margin-right: 3px;
+}
+
+.aksrt-forum-topic-item__actions {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.aksrt-forum-topic-item__action {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 6px 10px;
+ border-radius: 999px;
+ border: 1px solid var(--color-line, #d9d9d9);
+ background: #fff;
+ color: var(--color-ink);
+ text-decoration: none;
+ cursor: pointer;
+ font-size: 12px;
+ white-space: nowrap;
+}
+
+.aksrt-forum-topic-item__action--link {
+ background: var(--surface-1, #f8f9fa);
+}
+
+/* Pagination */
+.aksrt-forum-board__pagination {
+ display: flex;
+ justify-content: center;
+ padding: 20px 0;
+}
+
+/* Empty state */
+.aksrt-forum-board__empty {
+ text-align: center;
+ padding: 48px 24px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-board__empty i {
+ font-size: 40px;
+ margin-bottom: 12px;
+ display: block;
+}
+
+.aksrt-forum-board__empty a {
+ display: inline-block;
+ margin-top: 12px;
+ color: var(--color-primary);
+}
+
diff --git a/assets/css/frontend/forum/compose.css b/assets/css/frontend/forum/compose.css
new file mode 100644
index 00000000..e72686ab
--- /dev/null
+++ b/assets/css/frontend/forum/compose.css
@@ -0,0 +1,709 @@
+/* ============================================================
+ * Compose page
+ * ============================================================ */
+
+.aksrt-forum-compose {
+ padding-top: 24px;
+ padding-bottom: 48px;
+ max-width: 1100px;
+ margin: 0 auto;
+}
+
+.aksrt-forum-compose__header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 20px;
+}
+
+.aksrt-forum-compose__header h1 {
+ margin: 0;
+ font-size: 22px;
+}
+
+.aksrt-forum-compose__notice {
+ margin: 8px 0 0;
+ color: var(--color-ink-3, #8a909c);
+}
+
+.aksrt-forum-compose__back {
+ color: var(--color-ink-3, #8a909c);
+ text-decoration: none;
+ font-size: 14px;
+}
+
+.aksrt-forum-compose__back:hover {
+ color: var(--color-primary);
+}
+
+/* §7.4 — Two-column layout: main + sidebar */
+.aksrt-forum-compose__layout {
+ display: grid;
+ grid-template-columns: 1fr 311px;
+ gap: 24px;
+ align-items: start;
+}
+
+.aksrt-forum-compose__main {
+ min-width: 0;
+}
+
+.aksrt-forum-compose__sidebar {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+/* §7.4 — Sidebar panels */
+.aksrt-forum-compose__panel {
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #eceff4);
+ border-radius: 10px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
+}
+
+.aksrt-forum-compose__panel-title {
+ margin: 0;
+ padding: 12px 16px;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink);
+ border-bottom: 1px solid var(--color-line, #eceff4);
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.aksrt-forum-compose__panel-title i {
+ color: var(--color-ink-3, #8a909c);
+ font-size: 13px;
+}
+
+.aksrt-forum-compose__panel-body {
+ padding: 14px 16px;
+}
+
+.aksrt-forum-compose__readonly {
+ margin: 0;
+ color: var(--color-ink-2, #555);
+ font-size: 14px;
+}
+
+.aksrt-forum-compose__status-line {
+ margin: 0 0 12px;
+ font-size: 13px;
+ color: var(--color-ink-3, #8a909c);
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.aksrt-forum-compose__form {
+ padding: 0;
+ background: transparent;
+ border-radius: 0;
+ box-shadow: none;
+}
+
+.aksrt-forum-compose__main {
+ padding: 24px;
+ background: var(--surface-1, #fff);
+ border-radius: 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-forum-compose__field {
+ margin-bottom: 16px;
+}
+
+.aksrt-forum-compose__field:last-child {
+ margin-bottom: 0;
+}
+
+.aksrt-forum-compose__field label {
+ display: block;
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--color-ink);
+ margin-bottom: 6px;
+}
+
+.aksrt-forum-compose__field .required {
+ color: var(--color-error, #f5222d);
+}
+
+.aksrt-forum-compose__field select,
+.aksrt-forum-compose__field input[type="text"],
+.aksrt-forum-compose__field input[type="number"],
+.aksrt-forum-compose__field input[type="url"] {
+ width: 100%;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ padding: 8px 12px;
+ font-size: 14px;
+ font-family: inherit;
+ box-sizing: border-box;
+}
+
+.aksrt-forum-compose__field textarea {
+ width: 100%;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ padding: 10px 12px;
+ font-size: 14px;
+ resize: vertical;
+ font-family: inherit;
+ box-sizing: border-box;
+}
+
+.aksrt-forum-compose__checkbox {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ cursor: pointer;
+}
+
+/* §7.4 — wp_editor wrapper */
+.aksrt-forum-compose__editor-wrap {
+ margin-bottom: 0;
+}
+
+.aksrt-forum-compose__editor-wrap .wp-editor-wrap {
+ border-radius: 8px;
+ overflow: hidden;
+}
+
+.aksrt-forum-compose__editor-wrap .wp-editor-container {
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+}
+
+/* §7.4 — Character counter */
+.aksrt-forum-compose__char-counter {
+ display: block;
+ text-align: right;
+ font-size: 12px;
+ color: var(--color-ink-3, #8a909c);
+ margin-top: 4px;
+}
+
+.aksrt-forum-compose__char-counter.is-near {
+ color: var(--color-warning, #d48806);
+}
+
+.aksrt-forum-compose__char-counter.is-over {
+ color: var(--color-error, #cf1322);
+ font-weight: 600;
+}
+
+/* §7.4 — Draft notice */
+.aksrt-forum-compose__draft-notice {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 20px;
+ padding: 12px 16px;
+ background: var(--color-info-bg, #e6f7ff);
+ border: 1px solid var(--color-info-border, #91d5ff);
+ border-radius: 8px;
+ font-size: 14px;
+ color: var(--color-info, #0050b3);
+}
+
+.aksrt-forum-compose__draft-toggle {
+ border: none;
+ background: none;
+ color: var(--color-primary);
+ cursor: pointer;
+ font-size: 13px;
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 0;
+}
+
+.aksrt-forum-compose__draft-list {
+ width: 100%;
+ margin-top: 8px;
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.aksrt-forum-compose__draft-item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 12px;
+ background: var(--surface-1, #fff);
+ border-radius: 6px;
+ font-size: 13px;
+}
+
+.aksrt-forum-compose__draft-title {
+ flex: 1;
+ color: var(--color-ink);
+ text-decoration: none;
+ font-weight: 500;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.aksrt-forum-compose__draft-title:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-compose__draft-meta {
+ color: var(--color-ink-3, #8a909c);
+ font-size: 12px;
+ flex-shrink: 0;
+}
+
+.aksrt-forum-compose__draft-delete {
+ border: none;
+ background: none;
+ color: var(--color-ink-3, #8a909c);
+ cursor: pointer;
+ padding: 2px;
+ font-size: 12px;
+}
+
+.aksrt-forum-compose__draft-delete:hover {
+ color: var(--color-error, #cf1322);
+}
+
+/* §7.4 — Remote search select */
+.aksrt-remote-select {
+ position: relative;
+}
+
+.aksrt-remote-select__input {
+ width: 100%;
+}
+
+.aksrt-remote-select__dropdown {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ z-index: 100;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-top: none;
+ border-radius: 0 0 8px 8px;
+ max-height: 200px;
+ overflow-y: auto;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.aksrt-remote-select__option {
+ padding: 8px 12px;
+ cursor: pointer;
+ font-size: 14px;
+}
+
+.aksrt-remote-select__option:hover {
+ background: var(--color-primary-bg, #e6f7ff);
+}
+
+/* §7.4 — Tag tokenizer */
+.aksrt-tag-input {
+ position: relative;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 8px;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ background: var(--surface-1, #fff);
+ min-height: 38px;
+}
+
+.aksrt-tag-input__tokens {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 4px;
+}
+
+.aksrt-tag-input__token {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 2px 8px;
+ background: var(--color-primary-bg, #e6f7ff);
+ color: var(--color-primary, #1890ff);
+ border-radius: 4px;
+ font-size: 13px;
+}
+
+.aksrt-tag-input__token-remove {
+ border: none;
+ background: none;
+ color: var(--color-primary, #1890ff);
+ cursor: pointer;
+ padding: 0;
+ font-size: 14px;
+ line-height: 1;
+ opacity: 0.7;
+}
+
+.aksrt-tag-input__token-remove:hover {
+ opacity: 1;
+}
+
+.aksrt-tag-input__input {
+ flex: 1;
+ min-width: 80px;
+ border: none !important;
+ padding: 2px 4px !important;
+ font-size: 13px;
+ outline: none;
+ box-shadow: none !important;
+}
+
+.aksrt-tag-input__dropdown {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ z-index: 100;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-top: none;
+ border-radius: 0 0 8px 8px;
+ max-height: 160px;
+ overflow-y: auto;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.aksrt-tag-input__suggestion {
+ padding: 6px 12px;
+ cursor: pointer;
+ font-size: 13px;
+}
+
+.aksrt-tag-input__suggestion:hover {
+ background: var(--color-primary-bg, #e6f7ff);
+}
+
+.aksrt-forum-compose__vote-fields[hidden] {
+ display: none;
+}
+
+.aksrt-forum-compose__vote {
+ margin-bottom: 20px;
+ padding: 18px;
+ border: 1px solid var(--color-line, #eceff4);
+ border-radius: 12px;
+ background: var(--surface-1, #f8f9fa);
+}
+
+.aksrt-forum-compose__vote-head {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ margin-bottom: 12px;
+}
+
+.aksrt-forum-compose__vote-head p {
+ margin: 0;
+ color: var(--color-ink-3, #8a909c);
+ font-size: 13px;
+}
+
+.aksrt-forum-compose__feedback,
+.aksrt-forum-board__application-feedback,
+.aksrt-forum-topic__vote-feedback,
+.aksrt-forum-topic__moderation-feedback {
+ font-size: 13px;
+ color: var(--color-ink-3, #8a909c);
+}
+
+.aksrt-forum-compose__feedback.is-success,
+.aksrt-forum-board__application-feedback.is-success,
+.aksrt-forum-topic__vote-feedback.is-success,
+.aksrt-forum-topic__moderation-feedback.is-success {
+ color: var(--color-success, #389e0d);
+}
+
+.aksrt-forum-compose__feedback.is-error,
+.aksrt-forum-board__application-feedback.is-error,
+.aksrt-forum-topic__vote-feedback.is-error,
+.aksrt-forum-topic__moderation-feedback.is-error {
+ color: var(--color-error, #cf1322);
+}
+
+.aksrt-forum-compose__feedback.is-loading,
+.aksrt-forum-board__application-feedback.is-loading,
+.aksrt-forum-topic__vote-feedback.is-loading,
+.aksrt-forum-topic__moderation-feedback.is-loading {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-compose__actions {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 12px;
+}
+
+.aksrt-forum-compose__submit {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 10px 24px;
+ border: none;
+ border-radius: 8px;
+ background: var(--color-primary);
+ color: #fff;
+ cursor: pointer;
+ font-size: 15px;
+ font-weight: 500;
+}
+
+.aksrt-forum-compose__submit:hover {
+ opacity: 0.85;
+}
+
+.aksrt-forum-compose__submit:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.aksrt-forum-compose__draft {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 10px 24px;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-3, #8a909c);
+ cursor: pointer;
+ font-size: 15px;
+}
+
+.aksrt-forum-compose__draft:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+/* ── topic cover (§7.3) ── */
+
+.aksrt-forum-topic__cover {
+ margin-bottom: 20px;
+ border-radius: 12px;
+ overflow: hidden;
+ background: var(--surface-2, #f5f7fa);
+}
+
+.aksrt-forum-topic__cover-img {
+ width: 100%;
+ display: block;
+ object-fit: cover;
+}
+
+.aksrt-forum-topic__cover-slides {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 4px;
+}
+
+.aksrt-forum-topic__cover-slides img {
+ width: 100%;
+ aspect-ratio: 1;
+ object-fit: cover;
+}
+
+.aksrt-forum-topic__cover-player {
+ position: relative;
+ cursor: pointer;
+}
+
+.aksrt-forum-topic__cover-poster {
+ width: 100%;
+ display: block;
+ object-fit: cover;
+}
+
+.aksrt-forum-topic__cover-play-btn {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ border: none;
+ background: rgba(0, 0, 0, 0.5);
+ color: #fff;
+ font-size: 48px;
+ border-radius: 50%;
+ width: 72px;
+ height: 72px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: background 0.15s;
+}
+
+.aksrt-forum-topic__cover-play-btn:hover {
+ background: rgba(0, 0, 0, 0.7);
+}
+
+/* ── topic list cover thumbnails (§7.3) ── */
+
+.aksrt-forum-topic-item__cover {
+ flex-shrink: 0;
+ width: 120px;
+ height: 80px;
+ border-radius: 8px;
+ overflow: hidden;
+ background: var(--surface-2, #f5f7fa);
+}
+
+.aksrt-forum-topic-item__cover img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+}
+
+.aksrt-forum-topic-item__cover-video,
+.aksrt-forum-topic-item__cover-slide {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.aksrt-forum-topic-item__cover-video img,
+.aksrt-forum-topic-item__cover-slide img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+}
+
+.aksrt-forum-topic-item__cover-video i {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 24px;
+ color: #fff;
+ text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
+}
+
+.aksrt-forum-topic-item__cover-count {
+ position: absolute;
+ bottom: 4px;
+ right: 4px;
+ padding: 1px 6px;
+ border-radius: 3px;
+ background: rgba(0, 0, 0, 0.55);
+ color: #fff;
+ font-size: 11px;
+}
+
+/* ── compose cover upload (§7.3) ── */
+
+.aksrt-forum-compose__cover-upload {
+ margin-bottom: 20px;
+}
+
+.aksrt-forum-compose__cover-preview {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 10px;
+ min-height: 60px;
+}
+
+.aksrt-forum-compose__cover-preview img {
+ width: 120px;
+ height: 80px;
+ object-fit: cover;
+ border-radius: 8px;
+ border: 1px solid var(--color-line, #d9d9d9);
+}
+
+.aksrt-forum-compose__cover-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 16px;
+ border: 1px dashed var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-3, #8a909c);
+ cursor: pointer;
+ font-size: 14px;
+ transition: border-color 0.15s, color 0.15s;
+}
+
+.aksrt-forum-compose__cover-btn:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.aksrt-forum-compose__field input[type="url"] {
+ width: 100%;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ padding: 10px 12px;
+ font-size: 14px;
+ font-family: inherit;
+}
+
+@media (max-width: 767px) {
+ .aksrt-forum-board__header,
+ .aksrt-forum-board__actions,
+ .aksrt-forum-topic__vote-head,
+ .aksrt-forum-topic__moderation-head,
+ .aksrt-forum-topic__vote-actions,
+ .aksrt-forum-topic__moderation-actions,
+ .aksrt-forum-compose__header,
+ .aksrt-forum-compose__actions {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .aksrt-forum-topic-item {
+ flex-wrap: wrap;
+ }
+
+ .aksrt-forum-topic-item__actions {
+ width: 100%;
+ flex-direction: row;
+ flex-wrap: wrap;
+ }
+
+ .aksrt-forum-topic-item__cover {
+ width: 80px;
+ height: 56px;
+ }
+
+ .aksrt-forum-topic__cover-slides {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ .aksrt-forum-topic__moderation-grid,
+ .aksrt-forum-compose__grid {
+ grid-template-columns: 1fr;
+ }
+
+ /* §7.4 — Stack sidebar below main on mobile */
+ .aksrt-forum-compose__layout {
+ grid-template-columns: 1fr;
+ }
+
+ .aksrt-forum-compose__sidebar {
+ order: 2;
+ }
+
+ .aksrt-forum-compose {
+ max-width: 100%;
+ }
+}
+
diff --git a/assets/css/frontend/forum/extras.css b/assets/css/frontend/forum/extras.css
new file mode 100644
index 00000000..527be719
--- /dev/null
+++ b/assets/css/frontend/forum/extras.css
@@ -0,0 +1,7 @@
+@import url("extras/base.css");
+@import url("extras/reply-header-tabs-filters.css");
+@import url("extras/load-more.css");
+@import url("extras/additional-role-badges.css");
+@import url("extras/like-button.css");
+@import url("extras/reply-action-buttons.css");
+@import url("extras/quick-post-bar.css");
diff --git a/assets/css/frontend/forum/extras/additional-role-badges.css b/assets/css/frontend/forum/extras/additional-role-badges.css
new file mode 100644
index 00000000..f732d747
--- /dev/null
+++ b/assets/css/frontend/forum/extras/additional-role-badges.css
@@ -0,0 +1,52 @@
+/* --- additional role badges --- */
+
+.aksrt-forum-reply__role-badge--author {
+ background: #fff7e6;
+ color: #d46b08;
+}
+
+.aksrt-forum-reply__role-badge--super {
+ background: #f6ffed;
+ color: #389e0d;
+}
+
+.aksrt-forum-reply__role-badge--catmod {
+ background: #fff0f6;
+ color: #c41d7f;
+}
+
+/* --- hot comment (神评) badge --- */
+
+.aksrt-forum-reply__badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 3px;
+ padding: 1px 6px;
+ border-radius: var(--radius-pill, 999px);
+ font-size: 11px;
+ font-weight: 600;
+ line-height: 1.5;
+}
+
+.aksrt-forum-reply__badge--hot {
+ background: #fff2e8;
+ color: #d4380d;
+}
+
+.aksrt-forum-reply__badge--pinned {
+ background: #e6f7ff;
+ color: #096dd9;
+}
+
+.aksrt-forum-reply.is-hot {
+ border-left: 3px solid #fa541c;
+}
+
+.aksrt-forum-reply.is-pinned {
+ border-left: 3px solid #1890ff;
+}
+
+.aksrt-forum-reply.is-pinned.is-hot {
+ border-left: 3px solid #fa541c;
+}
+
diff --git a/assets/css/frontend/forum/extras/base.css b/assets/css/frontend/forum/extras/base.css
new file mode 100644
index 00000000..5432556c
--- /dev/null
+++ b/assets/css/frontend/forum/extras/base.css
@@ -0,0 +1,621 @@
+/* ============================================================
+ * Forum tag archive page
+ * ============================================================ */
+
+.aksrt-forum-tag {
+ padding-top: 24px;
+ padding-bottom: 48px;
+}
+
+.aksrt-forum-tag__header {
+ margin-bottom: 24px;
+ padding: 20px;
+ background: var(--surface-1, #fff);
+ border-radius: 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-forum-tag__title {
+ margin: 0 0 4px;
+ font-size: 22px;
+ font-weight: 700;
+ color: var(--color-ink);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.aksrt-forum-tag__title i {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-tag__desc {
+ margin: 0 0 8px;
+ font-size: 14px;
+ color: var(--color-ink-3, #8a909c);
+}
+
+.aksrt-forum-tag__count {
+ margin: 0;
+ font-size: 13px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-tag__list {
+ display: flex;
+ flex-direction: column;
+ gap: 1px;
+}
+
+.aksrt-forum-topic-card {
+ display: flex;
+ padding: 16px;
+ background: var(--surface-1, #fff);
+ transition: background 0.15s;
+}
+
+.aksrt-forum-topic-card:first-child {
+ border-radius: 8px 8px 0 0;
+}
+
+.aksrt-forum-topic-card:last-child {
+ border-radius: 0 0 8px 8px;
+}
+
+.aksrt-forum-topic-card:hover {
+ background: var(--surface-1, #f8f9fa);
+}
+
+.aksrt-forum-topic-card__body {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-forum-topic-card__title {
+ margin: 0 0 6px;
+ font-size: 16px;
+ font-weight: 500;
+}
+
+.aksrt-forum-topic-card__title a {
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.aksrt-forum-topic-card__title a:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-topic-card__excerpt {
+ margin: 0 0 8px;
+ font-size: 13px;
+ color: var(--color-ink-3, #8a909c);
+ line-height: 1.5;
+}
+
+.aksrt-forum-topic-card__meta {
+ display: flex;
+ gap: 16px;
+ font-size: 12px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-topic-card__meta i {
+ margin-right: 3px;
+}
+
+.aksrt-forum-tag__pagination {
+ display: flex;
+ justify-content: center;
+ padding: 20px 0;
+}
+
+.aksrt-forum-tag__empty {
+ text-align: center;
+ padding: 48px 24px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-tag__empty i {
+ font-size: 40px;
+ margin-bottom: 12px;
+ display: block;
+}
+
+/* ============================================================
+ * Forum widgets
+ * ============================================================ */
+
+.aksrt-forum-widget__list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.aksrt-forum-widget__item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 0;
+ border-bottom: 1px solid var(--color-line-soft, #f0f1f3);
+}
+
+.aksrt-forum-widget__item:last-child {
+ border-bottom: none;
+}
+
+.aksrt-forum-widget__rank {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ border-radius: 6px;
+ background: var(--surface-2, #f4f5f7);
+ color: var(--color-ink-3, #8a909c);
+ font-size: 12px;
+ font-weight: 600;
+ flex-shrink: 0;
+}
+
+.aksrt-forum-widget__item:nth-child(1) .aksrt-forum-widget__rank {
+ background: var(--color-error, #ef4444);
+ color: #fff;
+}
+
+.aksrt-forum-widget__item:nth-child(2) .aksrt-forum-widget__rank {
+ background: var(--color-warning, #f59e0b);
+ color: #fff;
+}
+
+.aksrt-forum-widget__item:nth-child(3) .aksrt-forum-widget__rank {
+ background: var(--color-info, #3b82f6);
+ color: #fff;
+}
+
+.aksrt-forum-widget__link {
+ flex: 1;
+ min-width: 0;
+ color: var(--color-ink);
+ text-decoration: none;
+ font-size: 14px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.aksrt-forum-widget__link:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-widget__views,
+.aksrt-forum-widget__author {
+ font-size: 12px;
+ color: var(--color-ink-4, #8a909c);
+ white-space: nowrap;
+}
+
+.aksrt-forum-widget__boards {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.aksrt-forum-widget__board {
+ padding: 8px 0;
+ border-bottom: 1px solid var(--color-line-soft, #f0f1f3);
+}
+
+.aksrt-forum-widget__board:last-child {
+ border-bottom: none;
+}
+
+.aksrt-forum-widget__board a {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ color: var(--color-ink);
+ text-decoration: none;
+ font-size: 14px;
+}
+
+.aksrt-forum-widget__board a:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-widget__board a i {
+ margin-right: 6px;
+ color: var(--color-primary);
+}
+
+.aksrt-forum-widget__count {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 24px;
+ height: 20px;
+ padding: 0 6px;
+ background: var(--surface-2, #f4f5f7);
+ border-radius: var(--radius-pill, 999px);
+ color: var(--color-ink-3, #8a909c);
+ font-size: 11px;
+ font-weight: 600;
+}
+
+.aksrt-forum-widget__empty {
+ text-align: center;
+ padding: 16px;
+ color: var(--color-ink-4, #8a909c);
+ font-size: 13px;
+}
+
+/* ── bbs_type / question badges (§7.3) ── */
+
+.aksrt-forum-topic__badge--question {
+ background: #e6f7ff;
+ color: #1890ff;
+}
+
+.aksrt-forum-topic__badge--solved {
+ background: #f6ffed;
+ color: #52c41a;
+}
+
+.aksrt-forum-topic-item__badge--question {
+ background: #e6f7ff;
+ color: #1890ff;
+}
+
+.aksrt-forum-topic-item__badge--solved {
+ background: #f6ffed;
+ color: #52c41a;
+}
+
+/* ── favorite button (§7.3) ── */
+
+.js-aksrt-topic-favorite {
+ background: none;
+ border: none;
+ cursor: pointer;
+ transition: color .15s;
+}
+
+.js-aksrt-topic-favorite[data-favorited="1"] {
+ color: var(--color-warning, #faad14);
+}
+
+.js-aksrt-topic-favorite:disabled {
+ opacity: .5;
+ cursor: not-allowed;
+}
+
+/* ── score actions (§7.3) ── */
+
+.aksrt-forum-topic__score-actions {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ margin: 16px 0;
+ padding: 12px 16px;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--border-2, #e8e8e8);
+ border-radius: var(--radius-m, 8px);
+}
+
+.aksrt-forum-topic__score-total {
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink, #333);
+}
+
+.aksrt-forum-topic__score-total i {
+ color: var(--color-warning, #faad14);
+ margin-right: 4px;
+}
+
+.aksrt-forum-topic__score-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 28px;
+ height: 28px;
+ border: 1px solid var(--border-2, #e0e0e0);
+ border-radius: var(--radius-s, 4px);
+ background: var(--surface-1, #fff);
+ cursor: pointer;
+ font-size: 12px;
+ transition: all .15s;
+}
+
+.aksrt-forum-topic__score-btn:hover:not(:disabled) {
+ border-color: var(--color-primary, #1890ff);
+ color: var(--color-primary, #1890ff);
+}
+
+.aksrt-forum-topic__score-btn--up:hover:not(:disabled) {
+ color: var(--color-success, #52c41a);
+ border-color: var(--color-success, #52c41a);
+}
+
+.aksrt-forum-topic__score-btn--down:hover:not(:disabled) {
+ color: var(--color-error, #f5222d);
+ border-color: var(--color-error, #f5222d);
+}
+
+.aksrt-forum-topic__score-btn:disabled {
+ opacity: .4;
+ cursor: not-allowed;
+}
+
+.aksrt-forum-topic__score-badge {
+ color: var(--color-warning, #faad14);
+ font-weight: 600;
+}
+
+.aksrt-forum-topic__score-feedback {
+ font-size: 13px;
+ color: var(--color-ink-4, #999);
+}
+
+/* ── vote enhancements (§7.3) ── */
+
+.aksrt-forum-topic__vote--pk .aksrt-forum-topic__vote-options {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+}
+
+.aksrt-forum-topic__vote--expired {
+ opacity: .7;
+}
+
+.aksrt-forum-topic__vote-type-badge {
+ display: inline-block;
+ padding: 1px 6px;
+ background: var(--color-primary, #1890ff);
+ color: #fff;
+ border-radius: var(--radius-pill, 999px);
+ font-size: 11px;
+ font-weight: 700;
+ margin-left: 6px;
+}
+
+.aksrt-forum-topic__vote-expired-badge {
+ display: inline-block;
+ padding: 1px 6px;
+ background: var(--color-error, #f5222d);
+ color: #fff;
+ border-radius: var(--radius-pill, 999px);
+ font-size: 11px;
+ font-weight: 600;
+ margin-left: 6px;
+}
+
+.aksrt-forum-topic__vote-expiry-info {
+ color: var(--color-ink-4, #999);
+ font-size: 12px;
+ margin-left: 6px;
+}
+
+/* ── topic_cat chip (§7.3) ── */
+
+.aksrt-forum-topic__chip--topic-cat {
+ background: var(--color-primary-bg, #e6f7ff);
+ color: var(--color-primary, #1890ff);
+ font-weight: 600;
+}
+
+/* ── report modal (§7.5) ── */
+
+.aksrt-forum-topic__header-top {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.aksrt-forum-report-modal {
+ position: fixed;
+ inset: 0;
+ z-index: 9999;
+}
+
+.aksrt-forum-report-modal__backdrop {
+ position: absolute;
+ inset: 0;
+ background: rgba(15, 23, 42, 0.55);
+}
+
+.aksrt-forum-report-modal__dialog {
+ position: relative;
+ max-width: 520px;
+ margin: 8vh auto 0;
+ padding: 20px;
+ border-radius: 14px;
+ background: var(--surface-1, #fff);
+ box-shadow: 0 18px 60px rgba(15, 23, 42, 0.2);
+ z-index: 1;
+}
+
+.aksrt-forum-report-modal__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ margin-bottom: 12px;
+}
+
+.aksrt-forum-report-modal__head h2 {
+ margin: 0;
+ font-size: 18px;
+}
+
+.aksrt-forum-report-modal__close {
+ border: none;
+ background: transparent;
+ font-size: 24px;
+ line-height: 1;
+ cursor: pointer;
+ color: var(--color-ink-3, #64748b);
+}
+
+.aksrt-forum-report-modal__target {
+ margin: 0 0 14px;
+ color: var(--color-ink-3, #64748b);
+ font-size: 13px;
+}
+
+.aksrt-forum-report-modal__actions {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.aksrt-forum-report-modal__feedback {
+ font-size: 13px;
+}
+
+.is-report-modal-open {
+ overflow: hidden;
+}
+
+.aksrt-forum-reply__report-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ border: none;
+ background: transparent;
+ color: var(--color-ink-4, #94a3b8);
+ cursor: pointer;
+ padding: 0;
+ font-size: 12px;
+}
+
+.aksrt-forum-reply__report-btn:hover {
+ color: var(--color-error, #ef4444);
+}
+
+/* ── moderation enhancements (§7.5) ── */
+
+.aksrt-forum-topic__moderation-note {
+ margin-bottom: 16px;
+ padding: 12px 14px;
+ border-radius: 10px;
+ background: var(--surface-2, #f8fafc);
+ color: var(--color-ink-3, #64748b);
+ font-size: 13px;
+}
+
+.aksrt-forum-topic__moderation-note strong {
+ color: var(--color-ink, #334155);
+ margin-right: 6px;
+}
+
+.aksrt-forum-topic__field small {
+ display: block;
+ margin-top: 6px;
+ color: var(--color-ink-4, #94a3b8);
+ font-size: 12px;
+}
+
+/* ── paywall / credits unlock (§7.3) ── */
+
+.aksrt-forum-topic__pay-price {
+ display: inline-block;
+ margin-top: 12px;
+ padding: 6px 16px;
+ background: #fff7e6;
+ color: #d46b08;
+ border-radius: 8px;
+ font-size: 15px;
+ font-weight: 600;
+}
+
+.aksrt-forum-topic__unlock-feedback {
+ display: block;
+ margin-top: 10px;
+ font-size: 13px;
+}
+
+.aksrt-forum-compose__visibility-extra select[multiple] {
+ min-height: 90px;
+}
+
+.aksrt-forum-compose__visibility-extra input[type="number"] {
+ width: 100%;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ padding: 10px 12px;
+ font-size: 14px;
+ font-family: inherit;
+}
+
+/* ── adopted answer (§7.3) ── */
+
+.aksrt-forum-reply.is-adopted {
+ border: 2px solid var(--color-success, #52c41a);
+ border-radius: var(--radius-m, 8px);
+ padding: 12px;
+ background: #f6ffed;
+}
+
+.aksrt-forum-reply__adopted-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 2px 8px;
+ background: var(--color-success, #52c41a);
+ color: #fff;
+ border-radius: var(--radius-pill, 999px);
+ font-size: 11px;
+ font-weight: 600;
+}
+
+.aksrt-forum-reply__adopt-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 4px 10px;
+ border: 1px solid var(--color-success, #52c41a);
+ border-radius: var(--radius-s, 4px);
+ background: transparent;
+ color: var(--color-success, #52c41a);
+ font-size: 12px;
+ cursor: pointer;
+ transition: all .15s;
+}
+
+.aksrt-forum-reply__adopt-btn:hover:not(:disabled) {
+ background: var(--color-success, #52c41a);
+ color: #fff;
+}
+
+.aksrt-forum-reply__adopt-btn:disabled,
+.aksrt-forum-reply__adopt-btn.is-adopted {
+ opacity: .6;
+ cursor: not-allowed;
+}
+
+/* ── moderator role badge (§7.5) ── */
+
+.aksrt-forum-reply__role-badge {
+ display: inline-flex;
+ align-items: center;
+ padding: 1px 6px;
+ border-radius: var(--radius-pill, 999px);
+ font-size: 11px;
+ font-weight: 600;
+ line-height: 1.5;
+}
+
+.aksrt-forum-reply__role-badge--admin {
+ background: #fff1f0;
+ color: #cf1322;
+}
+
+.aksrt-forum-reply__role-badge--mod {
+ background: #e6f7ff;
+ color: #096dd9;
+}
+
+/* ── §7.6 forum comment engine ── */
+
diff --git a/assets/css/frontend/forum/extras/like-button.css b/assets/css/frontend/forum/extras/like-button.css
new file mode 100644
index 00000000..7fd51987
--- /dev/null
+++ b/assets/css/frontend/forum/extras/like-button.css
@@ -0,0 +1,62 @@
+/* --- like button --- */
+
+.aksrt-forum-reply__like-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 2px 8px;
+ border: none;
+ background: none;
+ color: var(--c-text-3, #999);
+ font-size: 13px;
+ cursor: pointer;
+ transition: color .2s;
+}
+
+.aksrt-forum-reply__like-btn:hover {
+ color: var(--c-primary, #1890ff);
+}
+
+.aksrt-forum-reply__like-btn.is-active {
+ color: var(--c-primary, #1890ff);
+}
+
+.aksrt-forum-reply__like-count {
+ font-size: 12px;
+ min-width: 10px;
+}
+
+/* --- nested reply (楼中楼) --- */
+
+.aksrt-forum-reply--nested {
+ padding-left: 0;
+ margin-left: 0;
+}
+
+.aksrt-forum-reply__children {
+ margin-top: 8px;
+ padding: 8px 0 0 12px;
+ border-left: 2px solid var(--c-border, #f0f0f0);
+}
+
+.aksrt-forum-reply__children .aksrt-forum-reply {
+ padding: 8px 0;
+ margin-bottom: 0;
+ border-bottom: 1px solid var(--c-border-light, #f5f5f5);
+}
+
+.aksrt-forum-reply__children .aksrt-forum-reply:last-child {
+ border-bottom: none;
+}
+
+.aksrt-forum-reply__avatar--sm img {
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+}
+
+.aksrt-forum-reply__reply-to {
+ font-size: 12px;
+ color: var(--c-text-3, #999);
+}
+
diff --git a/assets/css/frontend/forum/extras/load-more.css b/assets/css/frontend/forum/extras/load-more.css
new file mode 100644
index 00000000..dd19e8e7
--- /dev/null
+++ b/assets/css/frontend/forum/extras/load-more.css
@@ -0,0 +1,23 @@
+/* --- load more --- */
+
+.aksrt-forum-replies__load-more {
+ text-align: center;
+ padding: 16px 0;
+}
+
+.aksrt-forum-replies__more-btn {
+ padding: 8px 24px;
+ border: 1px solid var(--c-border, #d9d9d9);
+ border-radius: var(--radius, 6px);
+ background: none;
+ color: var(--c-text-2, #666);
+ font-size: 14px;
+ cursor: pointer;
+ transition: all .2s;
+}
+
+.aksrt-forum-replies__more-btn:hover {
+ border-color: var(--c-primary, #1890ff);
+ color: var(--c-primary, #1890ff);
+}
+
diff --git a/assets/css/frontend/forum/extras/quick-post-bar.css b/assets/css/frontend/forum/extras/quick-post-bar.css
new file mode 100644
index 00000000..5fddff0c
--- /dev/null
+++ b/assets/css/frontend/forum/extras/quick-post-bar.css
@@ -0,0 +1,31 @@
+/* Quick post bar */
+
+.aksrt-forum-quick-post {
+ margin-bottom: 16px;
+}
+
+.aksrt-forum-quick-post__input {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 16px;
+ border: 1px solid var(--c-border, #e8e8e8);
+ border-radius: var(--radius, 6px);
+ background: var(--c-fill-1, #fafafa);
+ color: var(--c-text-3, #999);
+ font-size: 14px;
+ text-decoration: none;
+ transition: border-color .2s, box-shadow .2s;
+}
+
+.aksrt-forum-quick-post__input:hover {
+ border-color: var(--c-primary, #1890ff);
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, .1);
+}
+
+.aksrt-forum-quick-post__input img {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+}
+
diff --git a/assets/css/frontend/forum/extras/reply-action-buttons.css b/assets/css/frontend/forum/extras/reply-action-buttons.css
new file mode 100644
index 00000000..67678f9d
--- /dev/null
+++ b/assets/css/frontend/forum/extras/reply-action-buttons.css
@@ -0,0 +1,239 @@
+/* --- reply action buttons --- */
+
+.aksrt-forum-reply__reply-btn,
+.aksrt-forum-reply__top-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 2px 8px;
+ border: none;
+ background: none;
+ color: var(--c-text-3, #999);
+ font-size: 13px;
+ cursor: pointer;
+ transition: color .2s;
+}
+
+.aksrt-forum-reply__reply-btn:hover,
+.aksrt-forum-reply__top-btn:hover {
+ color: var(--c-primary, #1890ff);
+}
+
+/* ── §7.9 Forum user page tabs ── */
+
+.uh-forum__subtabs {
+ display: flex;
+ gap: 4px;
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid var(--c-border, #e8e8e8);
+}
+
+.uh-forum__subtab {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 14px;
+ border-radius: var(--radius-pill, 999px);
+ font-size: 13px;
+ color: var(--c-text-3, #999);
+ text-decoration: none;
+ transition: all .2s;
+}
+
+.uh-forum__subtab:hover {
+ color: var(--c-text-1, #333);
+ background: var(--c-fill-1, #f5f5f5);
+}
+
+.uh-forum__subtab.is-active {
+ background: var(--c-primary, #1890ff);
+ color: #fff;
+}
+
+.uh-forum__subtab-count {
+ font-size: 11px;
+ opacity: .7;
+}
+
+.uh-forum__list {
+ display: flex;
+ flex-direction: column;
+}
+
+.uh-forum__item {
+ padding: 12px 0;
+ border-bottom: 1px solid var(--c-border-light, #f5f5f5);
+}
+
+.uh-forum__item:last-child {
+ border-bottom: none;
+}
+
+.uh-forum__item-title {
+ display: block;
+ font-size: 15px;
+ font-weight: 500;
+ color: var(--c-text-1, #333);
+ text-decoration: none;
+ margin-bottom: 4px;
+}
+
+.uh-forum__item-title:hover {
+ color: var(--c-primary, #1890ff);
+}
+
+.uh-forum__item-meta {
+ display: flex;
+ gap: 12px;
+ font-size: 12px;
+ color: var(--c-text-3, #999);
+}
+
+.uh-forum__item-meta i {
+ margin-right: 3px;
+}
+
+.uh-forum__section-title {
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--c-text-2, #666);
+ margin: 16px 0 10px;
+ padding-bottom: 6px;
+ border-bottom: 1px solid var(--c-border-light, #f5f5f5);
+}
+
+.uh-forum__section-title i {
+ margin-right: 4px;
+ font-size: 13px;
+}
+
+.uh-forum__plate-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+ gap: 10px;
+ margin-bottom: 16px;
+}
+
+.uh-forum__plate-card {
+ display: block;
+ padding: 12px;
+ border: 1px solid var(--c-border, #e8e8e8);
+ border-radius: var(--radius, 6px);
+ text-decoration: none;
+ transition: border-color .2s, box-shadow .2s;
+}
+
+.uh-forum__plate-card:hover {
+ border-color: var(--c-primary, #1890ff);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, .06);
+}
+
+.uh-forum__plate-name {
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--c-text-1, #333);
+ margin-bottom: 6px;
+}
+
+.uh-forum__plate-stats {
+ display: flex;
+ gap: 10px;
+ font-size: 12px;
+ color: var(--c-text-3, #999);
+}
+
+.uh-forum__pagination {
+ margin-top: 16px;
+ text-align: center;
+}
+
+/* ── §7.3 Hidden content block [aksrt_hide] ── */
+
+.aksrt-forum-hide {
+ margin: 16px 0;
+}
+
+.aksrt-forum-hide--locked {
+ padding: 16px;
+ border: 1px dashed var(--c-border, #d9d9d9);
+ border-radius: var(--radius, 6px);
+ background: var(--c-fill-1, #fafafa);
+ text-align: center;
+}
+
+.aksrt-forum-hide__message {
+ font-size: 13px;
+ color: var(--c-text-3, #999);
+}
+
+.aksrt-forum-hide__message i {
+ margin-right: 4px;
+ color: var(--c-warning, #faad14);
+}
+
+.aksrt-forum-hide--revealed {
+ padding: 12px 16px;
+ border-left: 3px solid var(--c-success, #52c41a);
+ background: var(--c-fill-1, #f6ffed);
+ border-radius: 0 var(--radius, 6px) var(--radius, 6px) 0;
+}
+
+/* ── §7.10 Forum home tab engine ── */
+
+.aksrt-forum-home-tabs {
+ display: flex;
+ gap: 4px;
+ padding: 0 0 12px;
+ margin-bottom: 16px;
+ border-bottom: 1px solid var(--c-border, #e8e8e8);
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+.aksrt-forum-home-tabs__btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 16px;
+ border: 1px solid var(--c-border, #d9d9d9);
+ border-radius: var(--radius-pill, 999px);
+ background: none;
+ color: var(--c-text-3, #999);
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ white-space: nowrap;
+ transition: all .2s;
+}
+
+.aksrt-forum-home-tabs__btn:hover {
+ color: var(--c-text-1, #333);
+ border-color: var(--c-primary, #1890ff);
+}
+
+.aksrt-forum-home-tabs__btn.is-active {
+ background: var(--c-primary, #1890ff);
+ color: #fff;
+ border-color: var(--c-primary, #1890ff);
+}
+
+.aksrt-forum-home-tabs__badge {
+ display: inline-block;
+ min-width: 18px;
+ height: 18px;
+ padding: 0 5px;
+ border-radius: 9px;
+ background: #ff4d4f;
+ color: #fff;
+ font-size: 11px;
+ font-weight: 700;
+ line-height: 18px;
+ text-align: center;
+}
+
+.aksrt-forum-home__load-more {
+ text-align: center;
+ padding: 16px 0;
+}
+
diff --git a/assets/css/frontend/forum/extras/reply-header-tabs-filters.css b/assets/css/frontend/forum/extras/reply-header-tabs-filters.css
new file mode 100644
index 00000000..60655ed8
--- /dev/null
+++ b/assets/css/frontend/forum/extras/reply-header-tabs-filters.css
@@ -0,0 +1,69 @@
+/* --- reply header tabs & filters --- */
+
+.aksrt-forum-replies__header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid var(--c-border, #e8e8e8);
+}
+
+.aksrt-forum-replies__tabs {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.aksrt-forum-replies__tab {
+ padding: 4px 12px;
+ border: 1px solid var(--c-border, #d9d9d9);
+ border-radius: var(--radius-pill, 999px);
+ background: none;
+ color: var(--c-text-3, #999);
+ font-size: 13px;
+ cursor: pointer;
+ transition: all .2s;
+}
+
+.aksrt-forum-replies__tab:hover {
+ color: var(--c-text-1, #333);
+ border-color: var(--c-primary, #1890ff);
+}
+
+.aksrt-forum-replies__tab.is-active {
+ background: var(--c-primary, #1890ff);
+ color: #fff;
+ border-color: var(--c-primary, #1890ff);
+}
+
+.aksrt-forum-replies__filter {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 13px;
+ color: var(--c-text-3, #999);
+ cursor: pointer;
+ margin-left: 8px;
+}
+
+.aksrt-forum-replies__filter input[type="checkbox"] {
+ width: 14px;
+ height: 14px;
+}
+
+.aksrt-forum-replies__empty {
+ padding: 40px 0;
+ text-align: center;
+ color: var(--c-text-3, #bbb);
+ font-size: 14px;
+}
+
+.aksrt-forum-replies__empty i {
+ font-size: 24px;
+ display: block;
+ margin-bottom: 8px;
+}
+
diff --git a/assets/css/frontend/forum/topic.css b/assets/css/frontend/forum/topic.css
new file mode 100644
index 00000000..e4ded01f
--- /dev/null
+++ b/assets/css/frontend/forum/topic.css
@@ -0,0 +1,331 @@
+/* ============================================================
+ * Topic detail page
+ * ============================================================ */
+
+.aksrt-forum-topic {
+ padding-top: 24px;
+ padding-bottom: 48px;
+ max-width: 800px;
+ margin: 0 auto;
+}
+
+.aksrt-forum-topic__breadcrumb {
+ font-size: 13px;
+ color: var(--color-ink-4, #8a909c);
+ margin-bottom: 16px;
+}
+
+.aksrt-forum-topic__breadcrumb a {
+ color: var(--color-primary);
+ text-decoration: none;
+}
+
+.aksrt-forum-topic__sep {
+ margin: 0 6px;
+}
+
+.aksrt-forum-topic__header {
+ margin-bottom: 20px;
+}
+
+.aksrt-forum-topic__title {
+ margin: 0 0 8px;
+ font-size: 22px;
+ font-weight: 700;
+ color: var(--color-ink);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+}
+
+.aksrt-forum-topic__badge {
+ display: inline-block;
+ padding: 2px 8px;
+ border-radius: 4px;
+ font-size: 12px;
+ font-weight: 500;
+}
+
+.aksrt-forum-topic__badge--sticky {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+.aksrt-forum-topic__badge--sticky-super {
+ background: var(--focus-color, #fd53a1);
+ color: #fff;
+}
+
+.aksrt-forum-topic__badge--sticky-global {
+ background: #e53e3e;
+ color: #fff;
+}
+
+.aksrt-forum-topic__badge--featured {
+ background: var(--color-success, #52c41a);
+ color: #fff;
+}
+
+.aksrt-forum-topic__badge--locked {
+ background: #fff7e6;
+ color: #d46b08;
+}
+
+.aksrt-forum-topic__badge--visibility {
+ background: var(--surface-2, #f5f7fa);
+ color: var(--color-ink-3, #8a909c);
+}
+
+.aksrt-forum-topic__meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 16px;
+ font-size: 13px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-topic__author {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.aksrt-forum-topic__author img {
+ border-radius: 50%;
+}
+
+.aksrt-forum-topic__quick-actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ margin-top: 14px;
+}
+
+.aksrt-forum-topic__quick-action,
+.aksrt-forum-topic__primary-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ padding: 9px 16px;
+ border: none;
+ border-radius: 999px;
+ background: var(--surface-1, #fff);
+ color: var(--color-ink);
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.aksrt-forum-topic__primary-btn {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+.aksrt-forum-topic__taxonomy {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 20px;
+}
+
+.aksrt-forum-topic__chip {
+ display: inline-flex;
+ align-items: center;
+ padding: 6px 10px;
+ border-radius: 999px;
+ background: var(--surface-2, #f5f7fa);
+ color: var(--color-ink-3, #8a909c);
+ text-decoration: none;
+ font-size: 13px;
+}
+
+.aksrt-forum-topic__chip--special {
+ background: #fff1f0;
+ color: #cf1322;
+}
+
+.aksrt-forum-topic__content {
+ padding: 20px;
+ background: var(--surface-1, #fff);
+ border-radius: 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+ margin-bottom: 24px;
+ line-height: 1.8;
+ font-size: 15px;
+}
+
+.aksrt-forum-topic__content img {
+ max-width: 100%;
+ border-radius: 8px;
+}
+
+.aksrt-forum-topic__vote,
+.aksrt-forum-topic__moderation {
+ margin-bottom: 24px;
+ padding: 20px;
+ background: var(--surface-1, #fff);
+ border-radius: 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-forum-topic__vote-head,
+.aksrt-forum-topic__moderation-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ margin-bottom: 16px;
+}
+
+.aksrt-forum-topic__vote-head h2,
+.aksrt-forum-topic__moderation-head h2 {
+ margin: 0;
+ font-size: 18px;
+}
+
+.aksrt-forum-topic__vote-head span,
+.aksrt-forum-topic__moderation-head p {
+ color: var(--color-ink-3, #8a909c);
+ font-size: 13px;
+}
+
+.aksrt-forum-topic__vote-options {
+ display: grid;
+ gap: 10px;
+}
+
+.aksrt-forum-topic__vote-option {
+ display: grid;
+ grid-template-columns: auto 1fr auto;
+ align-items: center;
+ gap: 10px;
+ padding: 12px 14px;
+ border-radius: 10px;
+ background: var(--surface-1, #f8f9fa);
+}
+
+.aksrt-forum-topic__vote-option.is-selected {
+ outline: 1px solid var(--color-primary);
+}
+
+.aksrt-forum-topic__vote-count {
+ font-size: 12px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-topic__vote-actions,
+.aksrt-forum-topic__moderation-actions {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin-top: 16px;
+}
+
+.aksrt-forum-topic__moderation-grid,
+.aksrt-forum-compose__grid {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 16px;
+}
+
+.aksrt-forum-topic__field select,
+.aksrt-forum-topic__field textarea,
+.aksrt-forum-compose__field input[type="text"],
+.aksrt-forum-compose__field textarea,
+.aksrt-forum-compose__field select {
+ width: 100%;
+}
+
+.aksrt-forum-topic__field label {
+ display: block;
+ margin-bottom: 6px;
+ font-size: 14px;
+ font-weight: 500;
+}
+
+.aksrt-forum-topic__field select,
+.aksrt-forum-topic__field textarea {
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ padding: 10px 12px;
+ font-family: inherit;
+ font-size: 14px;
+}
+
+.aksrt-forum-topic__denied {
+ padding: 56px 24px;
+ text-align: center;
+ background: var(--surface-1, #fff);
+ border-radius: 12px;
+}
+
+.aksrt-forum-topic__denied i {
+ font-size: 42px;
+ margin-bottom: 14px;
+ color: var(--color-ink-4, #8a909c);
+}
+
+.aksrt-forum-topic__replies {
+ margin-bottom: 24px;
+}
+
+.aksrt-forum-topic__replies-title {
+ font-size: 16px;
+ font-weight: 600;
+ margin-bottom: 16px;
+ color: var(--color-ink);
+}
+
+.aksrt-forum-topic__reply-form {
+ padding: 20px;
+ background: var(--surface-1, #fff);
+ border-radius: 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-forum-topic__reply-form h2,
+.aksrt-forum-topic__reply-form h3 {
+ margin: 0 0 12px;
+ font-size: 15px;
+ color: var(--color-ink);
+}
+
+.aksrt-forum-topic__reply-field textarea {
+ width: 100%;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ padding: 12px;
+ font-size: 14px;
+ resize: vertical;
+ font-family: inherit;
+}
+
+.aksrt-forum-topic__reply-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 20px;
+ border: none;
+ border-radius: 8px;
+ background: var(--color-primary);
+ color: #fff;
+ cursor: pointer;
+ font-size: 14px;
+}
+
+.aksrt-forum-topic__reply-btn:hover {
+ opacity: 0.85;
+}
+
+.aksrt-forum-topic__locked-notice,
+.aksrt-forum-topic__login-notice {
+ text-align: center;
+ padding: 20px;
+ color: var(--color-ink-3, #8a909c);
+ font-size: 14px;
+}
+
+.aksrt-forum-topic__login-notice a {
+ color: var(--color-primary);
+}
+
diff --git a/assets/css/frontend/header-components.css b/assets/css/frontend/header-components.css
new file mode 100644
index 00000000..ad48dad3
--- /dev/null
+++ b/assets/css/frontend/header-components.css
@@ -0,0 +1,6 @@
+@import url("header-components/base.css");
+@import url("header-components/widget-device-visibility.css");
+@import url("header-components/admin-hint.css");
+@import url("header-components/dark-theme.css");
+@import url("header-components/card-device-visibility.css");
+@import url("header-components/search-keywords-row.css");
diff --git a/assets/css/frontend/header-components/admin-hint.css b/assets/css/frontend/header-components/admin-hint.css
new file mode 100644
index 00000000..dc520795
--- /dev/null
+++ b/assets/css/frontend/header-components/admin-hint.css
@@ -0,0 +1,90 @@
+/* Admin hint */
+.header-components__admin-hint {
+ margin: 16px auto 0;
+ padding: 8px 14px;
+ border-radius: var(--radius-pill, 999px);
+ background: rgba(0, 0, 0, 0.32);
+ color: rgba(255, 255, 255, 0.95);
+ font: 500 13px/1.4 var(--font-ui);
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+.header-components__admin-link {
+ color: #fff;
+ text-decoration: underline;
+ text-decoration-thickness: 1px;
+ text-underline-offset: 2px;
+ font-weight: 600;
+}
+
+.header-components__admin-link:hover {
+ color: #ffe082;
+}
+
+/* ============================================================
+ * Layer 2: 搜索覆盖模块(在轮播内部 absolute 定位)
+ * ============================================================ */
+.header-components-search {
+ position: absolute;
+ bottom: 25%;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 10;
+ width: 100%;
+ max-width: 600px;
+ padding: 0 16px;
+}
+
+.header-components-search__form {
+ display: flex;
+ align-items: center;
+ background: rgba(255, 255, 255, 0.95);
+ border-radius: 50px;
+ padding: 4px 4px 4px 20px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+ backdrop-filter: blur(10px);
+ transition: box-shadow 0.3s ease, transform 0.2s ease;
+}
+
+.header-components-search__form:focus-within {
+ box-shadow: 0 6px 30px rgba(0, 0, 0, 0.2);
+ transform: translateY(-1px);
+}
+
+.header-components-search__icon {
+ color: var(--color-ink-3, #999);
+ font-size: 16px;
+ margin-right: 12px;
+ flex-shrink: 0;
+}
+
+.header-components-search__input {
+ flex: 1;
+ border: none !important;
+ background: transparent !important;
+ box-shadow: none !important;
+ font-size: 15px;
+ padding: 10px 0;
+ color: var(--color-ink);
+}
+
+.header-components-search__input:focus {
+ outline: none;
+}
+
+.header-components-search__input::placeholder {
+ color: var(--color-ink-4, #aaa);
+}
+
+.header-components-search__btn {
+ border-radius: 50px;
+ padding: 10px 24px;
+ font-size: 14px;
+ font-weight: 500;
+ flex-shrink: 0;
+}
+
diff --git a/assets/css/frontend/header-components/base.css b/assets/css/frontend/header-components/base.css
new file mode 100644
index 00000000..36d09f1d
--- /dev/null
+++ b/assets/css/frontend/header-components/base.css
@@ -0,0 +1,176 @@
+/* ============================================================
+ * AKSRT Header Slider — v5.0 Zibll-Aligned
+ *
+ * 三层架构:
+ * - Layer 1: Swiper 全宽轮播背景
+ * - Layer 2: 搜索覆盖模块
+ * - Layer 3: 图标卡片网格覆盖
+ *
+ * 对标 zibll 的 new-swiper 体系:
+ * - CSS 变量高度控制 (--pc-height / --m-height)
+ * - data-* 属性驱动配置
+ * - 缩略图分页器、视差、懒加载
+ * ============================================================ */
+
+/* ============================================================
+ * .new-swiper 基础样式(对标 zibll)
+ * ============================================================ */
+.aksrt-slider-wrapper {
+ position: relative;
+ margin-bottom: 20px;
+}
+
+.new-swiper {
+ position: relative;
+ overflow: hidden;
+ --pc-height: auto;
+ --m-height: auto;
+}
+
+.new-swiper .swiper-wrapper {
+ height: var(--pc-height);
+}
+
+.new-swiper .swiper-slide {
+ position: relative;
+ overflow: hidden;
+}
+
+.new-swiper .swiper-slide img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+/* 懒加载预加载器 */
+.new-swiper .swiper-lazy-preloader {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 42px;
+ height: 42px;
+ margin: -21px 0 0 -21px;
+ border: 3px solid rgba(255,255,255,0.3);
+ border-top-color: #fff;
+ border-radius: 50%;
+ animation: aksrt-swiper-spin 0.8s linear infinite;
+}
+
+@keyframes aksrt-swiper-spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+
+/* 懒加载图片 */
+.new-swiper .swiper-lazy {
+ opacity: 0;
+ transition: opacity 0.3s;
+}
+
+.new-swiper .swiper-lazy.lazyloaded,
+.new-swiper .swiper-slide-visible .swiper-lazy {
+ opacity: 1;
+}
+
+/* 缩略图分页器 */
+.new-swiper .pagination-thumbnail-item {
+ width: 60px;
+ height: 40px;
+ border-radius: 4px;
+ overflow: hidden;
+ opacity: 0.5;
+ transition: opacity 0.3s, border-color 0.3s;
+ border: 2px solid transparent;
+ cursor: pointer;
+ display: inline-block;
+}
+
+.new-swiper .pagination-thumbnail-item img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.new-swiper .pagination-thumbnail-item-active {
+ opacity: 1;
+ border-color: #fff;
+}
+
+/* 视差层 */
+.new-swiper [data-swiper-parallax] {
+ transition: none;
+}
+
+/* 比例高度模式 */
+.new-swiper.scale-height .swiper-wrapper {
+ height: 0;
+ padding-bottom: var(--scale-ratio, 45%);
+}
+
+/* 幻灯片文字覆盖层 */
+.aksrt-slide-text {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 2;
+ width: calc(100% - 32px);
+ max-width: 920px;
+ text-align: center;
+ color: #fff;
+}
+
+.aksrt-slide-text__title {
+ font-family: var(--font-display, var(--font-ui));
+ font-size: clamp(1.75rem, 4vw, 3rem);
+ font-weight: 700;
+ margin: 0 0 12px;
+ line-height: 1.2;
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
+}
+
+.aksrt-slide-text__desc {
+ font-size: clamp(0.9rem, 1.4vw, 1.125rem);
+ margin: 0;
+ line-height: 1.6;
+ color: rgba(255, 255, 255, 0.9);
+ text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+}
+
+/* 移动端高度 */
+@media (max-width: 767px) {
+ .new-swiper .swiper-wrapper {
+ height: var(--m-height);
+ }
+}
+
+/* ============================================================
+ * Container — 三层叠加的父容器
+ * ============================================================ */
+.header-components-container {
+ position: relative;
+ isolation: isolate; /* 创建独立堆叠上下文,内部 z-index 不外泄 */
+ width: 100%;
+ margin-bottom: 20px;
+}
+
+/* ============================================================
+ * Device Visibility for Hero/Banner slides
+ * ============================================================ */
+
+/* PC-only slides: hidden on mobile */
+@media (max-width: 767.98px) {
+ .hero-slide--pc-only,
+ .banner-slide--pc-only {
+ display: none !important;
+ }
+}
+
+/* Mobile-only slides: hidden on PC */
+@media (min-width: 768px) {
+ .hero-slide--mobile-only,
+ .banner-slide--mobile-only {
+ display: none !important;
+ }
+}
+
diff --git a/assets/css/frontend/header-components/card-device-visibility.css b/assets/css/frontend/header-components/card-device-visibility.css
new file mode 100644
index 00000000..57955416
--- /dev/null
+++ b/assets/css/frontend/header-components/card-device-visibility.css
@@ -0,0 +1,169 @@
+/* ===== Card device visibility ===== */
+@media (min-width: 768px) {
+ .hide-cards-pc .header-components-card { display: none; }
+}
+@media (max-width: 767px) {
+ .hide-cards-mobile .header-components-card { display: none; }
+}
+
+.theme-dark .header-components-search .line-form,
+html.dark .header-components-search .line-form {
+ background: rgba(30, 30, 30, 0.86);
+ color: #ddd;
+}
+
+.header-components-search .search-input-text {
+ position: relative;
+ padding: 3px 42px 3px 8px;
+}
+
+.header-components-search .line-form-input {
+ width: 100%;
+ padding: 0.65em 0 0.2em 0;
+ font-size: 16px;
+ border: none !important;
+ outline: 0 !important;
+ background: transparent !important;
+ box-shadow: none !important;
+ opacity: 0.92;
+ color: var(--color-ink);
+}
+
+.theme-dark .header-components-search .line-form-input,
+html.dark .header-components-search .line-form-input {
+ color: #f2f2f2;
+}
+
+.header-components-search .line-form-input::placeholder {
+ color: transparent;
+}
+
+.header-components-search .line-form-line,
+.header-components-search .line-form-line::before {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ height: 1px;
+ transition: 0.4s;
+ background: rgba(255, 255, 255, 0.34);
+}
+
+.header-components-search .line-form-line::before {
+ content: "";
+ width: 0;
+ background: rgba(255, 255, 255, 0.92);
+}
+
+.header-components-search .line-form-input:focus ~ .line-form-line::before,
+.header-components-search .line-form-input:not(:placeholder-shown) ~ .line-form-line::before {
+ width: 100%;
+}
+
+.header-components-search .scale-placeholder {
+ position: absolute;
+ left: 0;
+ bottom: 0.72em;
+ opacity: 0.68;
+ transition: transform 0.2s, font-size 0.2s, color 0.2s, opacity 0.2s;
+ pointer-events: none;
+ transform-origin: left top;
+}
+
+.header-components-search .scale-placeholder.is-focus,
+.header-components-search .line-form-input:focus ~ .scale-placeholder,
+.header-components-search .line-form-input:not(:placeholder-shown) ~ .scale-placeholder {
+ transform: translateY(-1.45em);
+ font-size: 12px;
+ color: #fff;
+ opacity: 0.92;
+}
+
+.header-components-search .line-form .abs-right {
+ position: absolute;
+ right: -6px;
+ top: 50%;
+ transform: translateY(-50%);
+ margin: 0;
+}
+
+.header-components-search__submit {
+ width: 34px;
+ height: 34px;
+ border: none;
+ border-radius: 999px;
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+}
+
+.header-components-search__submit svg {
+ width: 15px;
+ height: 15px;
+}
+
+/* Search add-ons: category dropdown */
+.header-components-search__cat {
+ appearance: none;
+ -webkit-appearance: none;
+ background: transparent;
+ border: none;
+ border-right: 1px solid rgba(255, 255, 255, 0.25);
+ color: inherit;
+ font-size: 13px;
+ padding: 0 12px;
+ min-width: 90px;
+ max-width: 140px;
+ cursor: pointer;
+ outline: none;
+ height: 40px;
+}
+
+.header-components-search__cat option {
+ color: #333;
+ background: #fff;
+}
+
+/* Search add-ons: type switcher */
+.header-components-search__types {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ padding: 0 8px;
+ border-right: 1px solid rgba(255, 255, 255, 0.25);
+}
+
+.header-components-search__type-label {
+ display: inline-flex;
+ align-items: center;
+ cursor: pointer;
+ font-size: 12px;
+ padding: 3px 8px;
+ border-radius: 100px;
+ transition: background 0.2s, color 0.2s;
+ white-space: nowrap;
+}
+
+.header-components-search__type-radio {
+ display: none;
+}
+
+.header-components-search__type-radio:checked + .header-components-search__type-text {
+ color: var(--color-primary, #4a90d9);
+ font-weight: 600;
+}
+
+/* has-addons: pill adjustments */
+.line-form.has-addons {
+ display: flex;
+ align-items: center;
+}
+
+.line-form.has-addons .search-input-text {
+ flex: 1;
+ min-width: 0;
+}
+
diff --git a/assets/css/frontend/header-components/dark-theme.css b/assets/css/frontend/header-components/dark-theme.css
new file mode 100644
index 00000000..73a762a9
--- /dev/null
+++ b/assets/css/frontend/header-components/dark-theme.css
@@ -0,0 +1,377 @@
+/* Dark theme */
+.theme-dark .header-components-search__form,
+html.dark .header-components-search__form,
+body.dark-theme .header-components-search__form {
+ background: rgba(30, 30, 30, 0.9);
+}
+
+.theme-dark .header-components-search__input,
+html.dark .header-components-search__input,
+body.dark-theme .header-components-search__input {
+ color: #eee;
+}
+
+/* ============================================================
+ * Layer 3: 图标卡片(模仿 zibll — 骑在 hero 底部边界线上)
+ *
+ * 关键技术:卡片在 DOM 中位于轮播之后,
+ * 使用 margin-top: -40px 向上拉,使其骑在 hero 底部边界线上
+ * ============================================================ */
+.header-components-card {
+ position: relative;
+ z-index: 10;
+ margin-top: -40px;
+}
+
+.header-components-card__container {
+ max-width: var(--container, 1280px);
+ margin: 0 auto;
+ padding: 0 16px;
+}
+
+/* 卡片行:flex 水平排列 */
+.header-components-card__row {
+ display: flex;
+ gap: 10px;
+ padding-top: 4px; /* 为 hover 上浮留出空间 */
+}
+
+/* 每个卡片项等宽 */
+.header-components-card__item {
+ flex: 1;
+ min-width: 0;
+}
+
+/* 共享背景模式:一个大卡片包裹 */
+.header-components-card__wrap--shared {
+ background: var(--surface-page);
+ border-radius: 8px;
+ padding: 10px;
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+ border: 1px solid var(--color-line);
+}
+
+/* 独立背景模式:每个卡片有自己的背景 */
+.header-components-card__item-bg {
+ background: var(--surface-page);
+ border-radius: 8px;
+ padding: 12px 14px;
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+ border: 1px solid var(--color-line);
+ height: 100%;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.header-components-card__item-bg:hover {
+ transform: none;
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+}
+
+/* 毛玻璃效果 */
+.filter-blur .header-components-card__wrap--shared,
+.filter-blur .header-components-card__item-bg {
+ background: rgba(255, 255, 255, 0.75);
+ backdrop-filter: saturate(3) blur(20px);
+ -webkit-backdrop-filter: saturate(3) blur(20px);
+ border-color: rgba(255, 255, 255, 0.3);
+}
+
+.theme-dark .filter-blur .header-components-card__wrap--shared,
+html.dark .filter-blur .header-components-card__wrap--shared,
+body.dark-theme .filter-blur .header-components-card__wrap--shared,
+.theme-dark .filter-blur .header-components-card__item-bg,
+html.dark .filter-blur .header-components-card__item-bg,
+body.dark-theme .filter-blur .header-components-card__item-bg {
+ background: rgba(30, 30, 30, 0.75);
+ border-color: rgba(255, 255, 255, 0.1);
+}
+
+/* ============================================================
+ * 单个图标卡片样式(模仿 zibll icon-cover-card)
+ * 结构:左侧圆形图标 + 右侧标题/描述
+ * ============================================================ */
+.icon-cover-card {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 8px;
+ border-radius: 6px;
+ text-decoration: none;
+ color: var(--color-ink);
+ transition: background 0.15s ease;
+}
+
+a.icon-cover-card:hover {
+ background: var(--surface-3);
+ text-decoration: none;
+ color: var(--color-ink);
+}
+
+/* 图标容器 — 圆形 */
+.icon-cover-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ min-width: 40px;
+ border-radius: 50%;
+ font-size: 18px;
+ flex-shrink: 0;
+}
+
+/* 方形图标 */
+.icon-cover-icon.radius4 {
+ border-radius: 6px;
+}
+
+/* 图标颜色类(模仿 zibll 的调色板) */
+.icon-cover-icon.c-blue {
+ background: rgba(66, 133, 244, 0.12);
+ color: #4285f4;
+}
+.icon-cover-icon.c-yellow {
+ background: rgba(251, 188, 4, 0.12);
+ color: #fbbc04;
+}
+.icon-cover-icon.c-green {
+ background: rgba(52, 168, 83, 0.12);
+ color: #34a853;
+}
+.icon-cover-icon.c-red {
+ background: rgba(234, 67, 53, 0.12);
+ color: #ea4335;
+}
+.icon-cover-icon.c-orange {
+ background: rgba(255, 152, 0, 0.12);
+ color: #ff9800;
+}
+.icon-cover-icon.c-cyan {
+ background: rgba(0, 188, 212, 0.12);
+ color: #00bcd4;
+}
+.icon-cover-icon.c-pink {
+ background: rgba(233, 30, 99, 0.12);
+ color: #e91e63;
+}
+
+/* 渐变图标背景 */
+.icon-cover-icon.jb-cyan {
+ background: linear-gradient(135deg, #4facfe, #00f2fe);
+ color: #fff;
+}
+.icon-cover-icon.jb-green {
+ background: linear-gradient(135deg, #43e97b, #38f9d7);
+ color: #fff;
+}
+.icon-cover-icon.jb-orange {
+ background: linear-gradient(135deg, #fa709a, #fee140);
+ color: #fff;
+}
+
+/* 文字区 */
+.icon-cover-desc {
+ flex: 1;
+ min-width: 0;
+ overflow: hidden;
+}
+
+.icon-cover-title {
+ font-size: 13px;
+ font-weight: 600;
+ line-height: 1.3;
+ color: var(--color-ink);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.icon-cover-subtitle {
+ font-size: 11px;
+ color: var(--color-ink-4);
+ margin-top: 2px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ line-height: 1.3;
+}
+
+/* ============================================================
+ * 响应式
+ * ============================================================ */
+@media (max-width: 767px) {
+ .header-components-card {
+ margin-top: -35px;
+ }
+
+ .header-components-card__row {
+ flex-wrap: wrap;
+ gap: 6px;
+ }
+
+ /* 移动端 2 列 */
+ .header-components-card__item {
+ flex: 0 0 calc(50% - 3px);
+ }
+
+ .header-components-card__item-bg {
+ padding: 10px;
+ }
+
+ .header-components-card__wrap--shared {
+ padding: 6px;
+ }
+
+ .icon-cover-card {
+ gap: 6px;
+ padding: 6px;
+ }
+
+ .icon-cover-icon {
+ width: 32px;
+ height: 32px;
+ min-width: 32px;
+ font-size: 14px;
+ }
+
+ .icon-cover-title {
+ font-size: 12px;
+ }
+
+ .icon-cover-subtitle {
+ display: none;
+ }
+}
+
+@media (max-width: 480px) {
+ .icon-cover-card {
+ gap: 4px;
+ padding: 2px;
+ }
+
+ .icon-cover-icon {
+ width: 28px;
+ height: 28px;
+ min-width: 28px;
+ font-size: 12px;
+ }
+}
+
+/* ============================================================
+ * Nav 透明模式(轮播可见时 nav 变透明)
+ * ============================================================ */
+
+/* ============================================================
+ * Zibll-aligned text/search structure overrides
+ * ============================================================ */
+.header-components__content.slide-text {
+ width: calc(100% - 32px);
+ max-width: 920px;
+ top: 42%;
+ z-index: 12;
+ padding-top: 0;
+}
+
+.header-components__content.slide-text .slide-title {
+ font-size: clamp(1.75rem, 4vw, 3rem);
+ line-height: 1.2;
+ margin: 0 0 12px;
+}
+
+.header-components__content.slide-text .slide-desc {
+ max-width: 680px;
+ margin: 0 auto;
+ font-size: clamp(0.9rem, 1.4vw, 1.125rem);
+ line-height: 1.6;
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.header-components-search {
+ top: calc(50% + 56px);
+ bottom: auto;
+ max-width: 680px;
+ padding: 0 20px;
+ font-size: 16px;
+}
+
+.card-0 .header-components-search {
+ top: calc(50% + 76px);
+}
+
+.header-components-search .search-input {
+ max-width: 620px;
+ margin: 0 auto;
+}
+
+.header-components-search .search-form {
+ margin: 0;
+ display: block;
+ background: transparent;
+ border-radius: 0;
+ padding: 0;
+ box-shadow: none;
+ -webkit-backdrop-filter: none;
+ backdrop-filter: none;
+ transform: none;
+}
+
+.header-components-search .search-form:focus-within {
+ box-shadow: none;
+ transform: none;
+}
+
+.header-components-search .line-form {
+ position: relative;
+ border-radius: 100px;
+ padding: 0.35em 1em;
+ background: rgba(255, 255, 255, 0.82);
+ color: #555;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+}
+
+.filter-blur .header-components-search .line-form {
+ background: rgba(255, 255, 255, 0.75);
+}
+
+/* ===== Container-level blur: PC/Mobile split ===== */
+@media (min-width: 768px) {
+ .has-blur-pc .header-components-card__wrap--shared,
+ .has-blur-pc .header-components-card__item-bg {
+ background: rgba(255, 255, 255, 0.75);
+ backdrop-filter: saturate(3) blur(20px);
+ -webkit-backdrop-filter: saturate(3) blur(20px);
+ border-color: rgba(255, 255, 255, 0.3);
+ }
+ .has-blur-pc .header-components-search .line-form {
+ background: rgba(255, 255, 255, 0.75);
+ }
+ .theme-dark .has-blur-pc .header-components-card__wrap--shared,
+ html.dark .has-blur-pc .header-components-card__wrap--shared,
+ .theme-dark .has-blur-pc .header-components-card__item-bg,
+ html.dark .has-blur-pc .header-components-card__item-bg {
+ background: rgba(30, 30, 30, 0.75);
+ border-color: rgba(255, 255, 255, 0.1);
+ }
+}
+@media (max-width: 767px) {
+ .has-blur-mobile .header-components-card__wrap--shared,
+ .has-blur-mobile .header-components-card__item-bg {
+ background: rgba(255, 255, 255, 0.75);
+ backdrop-filter: saturate(3) blur(20px);
+ -webkit-backdrop-filter: saturate(3) blur(20px);
+ border-color: rgba(255, 255, 255, 0.3);
+ }
+ .has-blur-mobile .header-components-search .line-form {
+ background: rgba(255, 255, 255, 0.75);
+ }
+ .theme-dark .has-blur-mobile .header-components-card__wrap--shared,
+ html.dark .has-blur-mobile .header-components-card__wrap--shared,
+ .theme-dark .has-blur-mobile .header-components-card__item-bg,
+ html.dark .has-blur-mobile .header-components-card__item-bg {
+ background: rgba(30, 30, 30, 0.75);
+ border-color: rgba(255, 255, 255, 0.1);
+ }
+}
+
diff --git a/assets/css/frontend/header-components/search-keywords-row.css b/assets/css/frontend/header-components/search-keywords-row.css
new file mode 100644
index 00000000..b3097e68
--- /dev/null
+++ b/assets/css/frontend/header-components/search-keywords-row.css
@@ -0,0 +1,455 @@
+/* Search keywords row */
+.header-components-search__keywords {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+ margin-top: 10px;
+ justify-content: center;
+}
+
+.header-components-search__kw-tag {
+ display: inline-block;
+ padding: 3px 10px;
+ font-size: 12px;
+ line-height: 1.4;
+ border-radius: 100px;
+ background: rgba(255, 255, 255, 0.2);
+ backdrop-filter: blur(6px);
+ color: inherit;
+ text-decoration: none;
+ transition: background 0.2s;
+}
+
+.header-components-search__kw-tag:hover {
+ background: rgba(255, 255, 255, 0.4);
+}
+
+@media (max-width: 991px) {
+ .header-components {
+ height: var(--pc-height);
+ }
+
+ .header-components-search {
+ top: calc(50% + 44px);
+ max-width: 560px;
+ }
+}
+
+@media (max-width: 767px) {
+ .header-components {
+ height: var(--m-height);
+ }
+
+ .header-components__content.slide-text {
+ width: calc(100% - 28px);
+ max-width: 480px;
+ top: 40%;
+ padding-top: 0;
+ }
+
+ .header-components__content.slide-text .slide-title {
+ font-size: clamp(1.25rem, 5vw, 1.75rem);
+ margin-bottom: 10px;
+ }
+
+ .header-components__content[style*="--hero-text-size-m"] .slide-title {
+ font-size: var(--hero-text-size-m);
+ }
+
+ .header-components__content.slide-text .slide-desc {
+ font-size: 0.875rem;
+ line-height: 1.5;
+ }
+
+ .header-components-search {
+ top: calc(50% + 20px);
+ width: calc(100% - 24px);
+ max-width: 420px;
+ padding: 0 12px;
+ font-size: 12px;
+ }
+
+ .card-1 .header-components-search,
+ .card-2 .header-components-search {
+ top: calc(50% + 46px);
+ }
+
+ .card-5 .header-components-search,
+ .card-6 .header-components-search {
+ top: calc(50% - 22px);
+ }
+
+ .card-7 .header-components-search,
+ .card-8 .header-components-search {
+ top: calc(50% - 52px);
+ }
+
+ .header-components-search .line-form {
+ font-size: 14px;
+ padding: 4px 12px;
+ }
+
+ .header-components-search .scale-placeholder.is-focus,
+ .header-components-search .line-form-input:focus ~ .scale-placeholder {
+ transform: translateY(-32px);
+ font-size: 12px;
+ color: #fff;
+ }
+
+ .header-components-card {
+ margin-top: -35px;
+ }
+
+ .header-components-card__container {
+ padding: 0 10px;
+ }
+
+ .header-components-card__row {
+ flex-wrap: wrap;
+ gap: 6px;
+ }
+
+ .header-components-card__item {
+ flex: 0 0 calc(50% - 3px);
+ }
+
+ .header-components-card__item-bg {
+ padding: 8px 10px;
+ }
+
+ .header-components-card__wrap--shared {
+ padding: 6px;
+ }
+
+ .icon-cover-card {
+ gap: 6px;
+ padding: 4px;
+ min-height: 52px;
+ border-radius: 6px;
+ }
+
+ .icon-cover-icon {
+ width: 30px;
+ height: 30px;
+ min-width: 30px;
+ font-size: 14px;
+ }
+
+ .icon-cover-title {
+ font-size: 12px;
+ }
+
+ .icon-cover-subtitle {
+ display: none;
+ }
+}
+
+@media (max-width: 480px) {
+ .header-components {
+ height: var(--m-height);
+ }
+
+ .header-components__content.slide-text .slide-title {
+ font-size: clamp(1.1rem, 5.4vw, 1.4rem);
+ margin-bottom: 8px;
+ }
+
+ .header-components__content.slide-text .slide-desc {
+ font-size: 0.8125rem;
+ }
+
+ .header-components-search {
+ top: calc(50% + 26px);
+ width: calc(100% - 20px);
+ padding: 0 10px;
+ }
+
+ .card-5 .header-components-search,
+ .card-6 .header-components-search {
+ top: calc(50% - 12px);
+ }
+
+ .card-7 .header-components-search,
+ .card-8 .header-components-search {
+ top: calc(50% - 40px);
+ }
+
+ .header-components-search .search-input-text {
+ padding-right: 40px;
+ }
+
+ .header-components-search__submit {
+ width: 34px;
+ height: 34px;
+ }
+}
+
+.site-nav.nav-transparent {
+ background-color: transparent;
+ border-bottom-color: transparent;
+ color: #fff;
+}
+
+.site-nav.nav-transparent .site-brand,
+.site-nav.nav-transparent .site-brand__name {
+ color: #fff;
+}
+
+.site-nav.nav-transparent .icon-btn {
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.site-nav.nav-transparent .icon-btn:hover {
+ background: rgba(255, 255, 255, 0.15);
+ color: #fff;
+}
+
+.site-nav.nav-transparent ul.nav-desktop a {
+ color: rgba(255, 255, 255, 0.85);
+}
+
+.site-nav.nav-transparent ul.nav-desktop a:hover {
+ color: #fff;
+ background: rgba(255, 255, 255, 0.15);
+}
+
+.site-nav.nav-transparent ul.nav-desktop .current-menu-item > a,
+.site-nav.nav-transparent ul.nav-desktop .current_page_item > a {
+ background: rgba(255, 255, 255, 0.2);
+ color: #fff;
+}
+
+.site-nav.nav-transparent .nav-auth .btn-outline {
+ border-color: rgba(255, 255, 255, 0.6);
+ color: #fff;
+}
+
+.site-nav.nav-transparent .nav-auth .btn-outline:hover {
+ background: rgba(255, 255, 255, 0.15);
+ border-color: #fff;
+}
+
+.site-nav.nav-transparent .nav-user__toggle {
+ border-color: rgba(255, 255, 255, 0.5);
+}
+
+/* 滚动后恢复实心 */
+.site-nav.nav-transparent.is-scrolled {
+ background-color: var(--surface-page);
+ border-bottom-color: var(--color-line);
+ color: var(--color-ink);
+}
+
+.site-nav.nav-transparent.is-scrolled .site-brand,
+.site-nav.nav-transparent.is-scrolled .site-brand__name {
+ color: var(--color-ink);
+}
+
+.site-nav.nav-transparent.is-scrolled .icon-btn {
+ color: var(--color-ink-3);
+}
+
+.site-nav.nav-transparent.is-scrolled ul.nav-desktop a {
+ color: var(--color-ink-3);
+}
+
+.site-nav.nav-transparent.is-scrolled .nav-auth .btn-outline {
+ border-color: var(--color-line);
+ color: var(--color-ink);
+}
+
+.site-nav.nav-transparent.is-scrolled .nav-user__toggle {
+ border-color: var(--color-line);
+}
+
+/* ============================================================
+ * Header Slider — Swiper Navigation & Pagination (Zibll-style)
+ * ============================================================ */
+.header-components .swiper-button-prev,
+.header-components .swiper-button-next {
+ width: 30px;
+ height: 40px;
+ color: #fff;
+ text-shadow: 0 0 6px #444;
+ opacity: 0;
+ transition: opacity 0.3s, background-color 0.3s;
+ z-index: 10;
+}
+
+.header-components .swiper-button-prev::after,
+.header-components .swiper-button-next::after {
+ font-size: 16px;
+ font-weight: 700;
+}
+
+.header-slider:hover .swiper-button-prev,
+.header-slider:hover .swiper-button-next {
+ opacity: 0.8;
+}
+
+.header-components .swiper-button-prev:hover,
+.header-components .swiper-button-next:hover {
+ opacity: 1;
+ background-color: rgba(0, 0, 0, 0.3);
+}
+
+.header-components .swiper-pagination-bullet {
+ width: 10px;
+ height: 10px;
+ background: transparent;
+ border: 2px solid rgba(255, 255, 255, 0.6);
+ opacity: 0.7;
+ border-radius: 20px;
+ transition: 0.4s;
+}
+
+.header-components .swiper-pagination-bullet-active {
+ background: #fff;
+ border-color: #fff;
+ opacity: 1;
+}
+
+@media (max-width: 640px) {
+ .header-components .swiper-button-prev,
+ .header-components .swiper-button-next {
+ display: none;
+ }
+}
+
+/* ============================================================
+ * Banner Module — 内联轮播条(模仿 zibll)
+ * ============================================================ */
+.banner-module {
+ position: relative;
+ width: 100%;
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
+}
+
+.banner-module__swiper {
+ position: relative;
+ width: 100%;
+ height: clamp(180px, 22vw, 300px);
+}
+
+.banner-module__swiper .swiper-slide {
+ position: relative;
+ overflow: hidden;
+ cursor: pointer;
+ height: 100%;
+}
+
+.banner-module__slide-bg {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.banner-module__slide-bg img,
+.banner-module__slide-bg .fit-cover {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.banner-module__slide-fallback {
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark, #5a8bc4));
+}
+
+.banner-module__slide-overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(
+ to bottom,
+ rgba(0, 0, 0, 0) 0%,
+ rgba(0, 0, 0, 0.15) 50%,
+ rgba(0, 0, 0, 0.5) 100%
+ );
+ pointer-events: none;
+}
+
+.banner-module__content {
+ position: absolute;
+ bottom: 24px;
+ left: 24px;
+ right: 24px;
+ z-index: 2;
+ color: #fff;
+ max-width: 680px;
+}
+
+.banner-module__title {
+ font-family: var(--font-display, var(--font-ui));
+ font-size: clamp(1.125rem, 2vw, 1.5rem);
+ font-weight: 700;
+ margin: 0 0 4px;
+ line-height: 1.3;
+ text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+}
+
+.banner-module__subtitle {
+ font-size: clamp(0.8125rem, 1.2vw, 0.9375rem);
+ margin: 0;
+ opacity: 0.9;
+ line-height: 1.5;
+ text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+}
+
+/* Swiper 导航箭头 */
+.banner-module .swiper-button-prev,
+.banner-module .swiper-button-next {
+ width: 36px;
+ height: 36px;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.85);
+ color: var(--color-ink);
+ opacity: 0;
+ pointer-events: none;
+ z-index: 10;
+ transition: opacity 0.3s ease, transform 0.2s ease;
+}
+
+.banner-module .swiper-button-prev::after,
+.banner-module .swiper-button-next::after {
+ font-size: 14px;
+ font-weight: 700;
+}
+
+.banner-module:hover .swiper-button-prev,
+.banner-module:hover .swiper-button-next {
+ opacity: 1;
+ pointer-events: auto;
+}
+
+.banner-module .swiper-button-prev:hover,
+.banner-module .swiper-button-next:hover {
+ transform: scale(1.1);
+ background: #fff;
+}
+
+/* Banner 响应式 */
+@media (max-width: 767px) {
+ .banner-module {
+ border-radius: 8px;
+ }
+
+ .banner-module__swiper {
+ height: clamp(120px, 30vw, 180px);
+ }
+
+ .banner-module__content {
+ bottom: 12px;
+ left: 12px;
+ right: 12px;
+ }
+
+ .banner-module .swiper-button-prev,
+ .banner-module .swiper-button-next {
+ display: none;
+ }
+}
+
diff --git a/assets/css/frontend/header-components/widget-device-visibility.css b/assets/css/frontend/header-components/widget-device-visibility.css
new file mode 100644
index 00000000..fb92aca8
--- /dev/null
+++ b/assets/css/frontend/header-components/widget-device-visibility.css
@@ -0,0 +1,198 @@
+/* Widget device visibility */
+@media (max-width: 767.98px) {
+ .aksrt-widget--mobile-only {
+ display: none !important;
+ }
+}
+
+@media (min-width: 768px) {
+ .aksrt-widget--pc-only {
+ display: none !important;
+ }
+}
+
+/* 首页首屏模块:向上抵消导航占位,保证 Hero 与导航重叠显示 */
+.home-modules > .header-components-container:first-child,
+.home-modules--fullbleed > .header-components-container:first-child {
+ margin-top: calc(var(--nav-height, 60px) * -1);
+}
+
+/* WordPress Admin Bar 已全局禁用,无需偏移规则 */
+
+/* ============================================================
+ * Layer 1: Swiper 轮播
+ * ============================================================ */
+.header-components {
+ position: relative;
+ width: 100%;
+ --pc-height: 550px;
+ --m-height: 280px;
+ height: var(--pc-height);
+ max-height: none;
+ overflow: hidden;
+ background: #111;
+}
+
+/* slide-header 模式:背景保持满铺,仅将文本层下移避开导航 */
+.header-components.slide-header {
+ padding-top: 0;
+}
+
+.header-components.slide-header .header-components__content.slide-text {
+ padding-top: var(--nav-height, 60px);
+}
+
+/* WordPress Admin Bar 已全局禁用,无需偏移规则 */
+
+/* 渐变兜底 */
+.header-components--gradient {
+ background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-active, var(--color-primary-dark)) 100%);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.header-components--gradient::before {
+ content: "";
+ position: absolute;
+ inset: 0;
+ background: radial-gradient(ellipse 80% 60% at 20% 20%, rgba(255, 255, 255, 0.15), transparent),
+ radial-gradient(ellipse 50% 50% at 80% 80%, rgba(0, 0, 0, 0.2), transparent);
+ pointer-events: none;
+}
+
+/* Swiper 内部 */
+.header-components .swiper-wrapper {
+ position: absolute;
+ inset: 0;
+ height: 100%;
+ width: 100%;
+}
+
+.header-components .swiper-slide {
+ position: relative;
+ height: 100%;
+ overflow: hidden;
+ cursor: pointer;
+}
+
+/* 幻灯片背景图 */
+.header-components__slide-bg {
+ position: absolute;
+ inset: 0;
+ overflow: hidden;
+}
+
+.header-components__slide-bg img,
+.header-components__slide-bg .fit-cover {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.header-components__slide-fallback {
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
+}
+
+/* 视频背景 */
+.header-components__video {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ z-index: 0;
+}
+
+/* 图片图层(视差叠加) */
+.header-components__layer {
+ position: absolute;
+ inset: 0;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-position: center;
+ pointer-events: none;
+}
+
+.header-components__layer--free-size {
+ background-size: auto;
+}
+
+.header-components__layer--parallax {
+ will-change: transform, opacity;
+ opacity: var(--layer-parallax-opacity, 0.6);
+ transform: translateY(calc(var(--scroll-y, 0) * var(--layer-parallax-scale, 0.3) * 1px));
+}
+
+/* 文字视差 */
+.has-text-parallax {
+ will-change: transform;
+ transform: translate(-50%, calc(-50% + var(--scroll-y, 0) * var(--hero-text-parallax, 0) * 0.15px));
+}
+
+/* 文字尺寸覆盖 */
+.header-components__content[style*="--hero-text-size-pc"] .slide-title {
+ font-size: var(--hero-text-size-pc);
+}
+
+/* 幻灯片遮罩 */
+.header-components__slide-overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(
+ to bottom,
+ rgba(0, 0, 0, 0.1) 0%,
+ rgba(0, 0, 0, 0.25) 40%,
+ rgba(0, 0, 0, 0.55) 100%
+ );
+ z-index: 1;
+ pointer-events: none;
+}
+
+/* 幻灯片文字内容 */
+.header-components__content {
+ position: absolute;
+ bottom: auto;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ z-index: 2;
+ width: calc(100% - 32px);
+ max-width: 920px;
+ text-align: center;
+ color: #fff;
+}
+
+.header-components__title {
+ font-family: var(--font-display, var(--font-ui));
+ font-size: clamp(1.75rem, 4vw, 3rem);
+ font-weight: 700;
+ margin: 0 0 12px;
+ line-height: 1.2;
+ letter-spacing: -0.02em;
+ color: #fff;
+ text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5), 0 1px 3px rgba(0, 0, 0, 0.4);
+}
+
+.header-components__subtitle {
+ font-size: clamp(0.9rem, 1.4vw, 1.125rem);
+ margin: 0;
+ max-width: 680px;
+ margin-left: auto;
+ margin-right: auto;
+ line-height: 1.6;
+ color: rgba(255, 255, 255, 0.9);
+ text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+}
+
+.header-components__description {
+ font-size: clamp(0.8rem, 1.2vw, 0.95rem);
+ margin: 8px auto 0;
+ max-width: 600px;
+ line-height: 1.5;
+ color: rgba(255, 255, 255, 0.8);
+ text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
+}
+
diff --git a/assets/css/frontend/home-modules.css b/assets/css/frontend/home-modules.css
new file mode 100644
index 00000000..94cbed32
--- /dev/null
+++ b/assets/css/frontend/home-modules.css
@@ -0,0 +1,16 @@
+@import url("home-modules/base.css");
+@import url("home-modules/tabs.css");
+@import url("home-modules/tag-cloud.css");
+@import url("home-modules/ranking.css");
+@import url("home-modules/friend-links.css");
+@import url("home-modules/html-module.css");
+@import url("home-modules/responsive.css");
+@import url("home-modules/text-title.css");
+@import url("home-modules/button-group.css");
+@import url("home-modules/spacing.css");
+@import url("home-modules/faq.css");
+@import url("home-modules/data-grid.css");
+@import url("home-modules/highlight-cards.css");
+@import url("home-modules/partner-marquee.css");
+@import url("home-modules/product-showcase.css");
+@import url("home-modules/user-cards.css");
diff --git a/assets/css/frontend/home-modules/base.css b/assets/css/frontend/home-modules/base.css
new file mode 100644
index 00000000..1a3a6882
--- /dev/null
+++ b/assets/css/frontend/home-modules/base.css
@@ -0,0 +1,89 @@
+/**
+ * Home Modules · CMS 形态首页模块系统样式
+ *
+ * 仅在 site_profile=cms 时(首页)加载。
+ *
+ * 宽度模型:
+ * - .home-modules > .home-module 锁定到 --container(默认 1280)
+ * - .home-modules > .hero 走 full-bleed(不在此处约束)
+ * - banner 模块的精细微调见 hero.css `.banner-slider.home-modules__banner`
+ */
+
+.home-modules {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-9, 48px);
+ padding-bottom: var(--space-9, 48px);
+}
+
+.home-modules--fullbleed {
+ width: 100%;
+}
+
+.home-modules--fullbleed > .home-module {
+ max-width: 100%;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+/* 容器宽度统一:所有非 hero 的 home-module 都对齐到 --container */
+.home-modules > .home-module {
+ width: 100%;
+ max-width: var(--container);
+ margin-left: auto;
+ margin-right: auto;
+ padding-left: 16px;
+ padding-right: 16px;
+ box-sizing: border-box;
+}
+
+@media (min-width: 768px) {
+ .home-modules > .home-module {
+ padding-left: 24px;
+ padding-right: 24px;
+ }
+}
+
+/* ============ 公共 header ============ */
+.home-module__header {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ gap: var(--space-3, 12px);
+ margin-bottom: var(--space-5, 20px);
+ padding-bottom: var(--space-3, 12px);
+ border-bottom: 1px solid var(--color-line);
+}
+
+.home-module__title {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font: 700 22px/1.2 var(--font-display);
+ margin: 0;
+ color: var(--color-ink);
+}
+
+.home-module__title i {
+ color: var(--color-primary);
+}
+
+.home-module__more {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font: 500 13px/1 var(--font-ui);
+ color: var(--color-primary);
+ text-decoration: none;
+}
+
+.home-module__more:hover {
+ color: var(--color-primary-active);
+}
+
+.home-module__admin-tools {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 14px;
+}
+
diff --git a/assets/css/frontend/home-modules/button-group.css b/assets/css/frontend/home-modules/button-group.css
new file mode 100644
index 00000000..2a704e77
--- /dev/null
+++ b/assets/css/frontend/home-modules/button-group.css
@@ -0,0 +1,46 @@
+/* Button Group */
+.home-module--button-group {
+ padding: 32px 0;
+}
+
+.home-module__buttons {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 12px;
+ margin-top: 16px;
+}
+
+.aksrt-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 10px 24px;
+ border-radius: var(--radius-md, 8px);
+ font-size: 14px;
+ font-weight: 500;
+ text-decoration: none;
+ transition: opacity 0.2s, transform 0.2s;
+}
+
+.aksrt-btn:hover {
+ opacity: 0.85;
+ transform: translateY(-1px);
+}
+
+.aksrt-btn--primary {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+.aksrt-btn--outline {
+ background: transparent;
+ color: var(--color-primary);
+ border: 1px solid var(--color-primary);
+}
+
+.aksrt-btn--ghost {
+ background: transparent;
+ color: var(--color-ink);
+}
+
diff --git a/assets/css/frontend/home-modules/data-grid.css b/assets/css/frontend/home-modules/data-grid.css
new file mode 100644
index 00000000..4f77deee
--- /dev/null
+++ b/assets/css/frontend/home-modules/data-grid.css
@@ -0,0 +1,38 @@
+/* Data Grid */
+.home-module--data-grid {
+ padding: 32px 0;
+}
+
+.home-module__data-grid {
+ display: grid;
+ gap: 16px;
+ text-align: center;
+}
+
+.aksrt-data-cell {
+ padding: 24px 16px;
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-md, 8px);
+ border: 1px solid var(--color-line, #e8e8e8);
+}
+
+.aksrt-data-cell i {
+ font-size: 24px;
+ color: var(--color-primary);
+ margin-bottom: 8px;
+ display: block;
+}
+
+.aksrt-data-cell__value {
+ font-size: 28px;
+ font-weight: 700;
+ color: var(--color-ink);
+ display: block;
+ margin-bottom: 4px;
+}
+
+.aksrt-data-cell__label {
+ font-size: 13px;
+ color: var(--color-ink-3);
+}
+
diff --git a/assets/css/frontend/home-modules/faq.css b/assets/css/frontend/home-modules/faq.css
new file mode 100644
index 00000000..b41693b9
--- /dev/null
+++ b/assets/css/frontend/home-modules/faq.css
@@ -0,0 +1,48 @@
+/* FAQ */
+.home-module--faq {
+ padding: 32px 0;
+}
+
+.home-module__faq-grid {
+ column-gap: 24px;
+}
+
+.aksrt-faq-item {
+ break-inside: avoid;
+ margin-bottom: 12px;
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: var(--radius-md, 8px);
+ overflow: hidden;
+}
+
+.aksrt-faq-item__question {
+ padding: 14px 16px;
+ font-size: 15px;
+ font-weight: 600;
+ cursor: pointer;
+ background: var(--surface-1, #fff);
+ list-style: none;
+}
+
+.aksrt-faq-item__question::-webkit-details-marker {
+ display: none;
+}
+
+.aksrt-faq-item__question::after {
+ content: '+';
+ float: right;
+ font-weight: 400;
+ transition: transform 0.2s;
+}
+
+.aksrt-faq-item[open] .aksrt-faq-item__question::after {
+ content: '−';
+}
+
+.aksrt-faq-item__answer {
+ padding: 0 16px 14px;
+ font-size: 14px;
+ color: var(--color-ink-3);
+ line-height: 1.7;
+}
+
diff --git a/assets/css/frontend/home-modules/friend-links.css b/assets/css/frontend/home-modules/friend-links.css
new file mode 100644
index 00000000..6e57bf90
--- /dev/null
+++ b/assets/css/frontend/home-modules/friend-links.css
@@ -0,0 +1,55 @@
+/* ============ Friend Links ============ */
+.home-module__friends-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+ gap: var(--space-3, 12px);
+}
+
+.home-module__friend-card {
+ display: flex;
+ align-items: center;
+ gap: var(--space-3, 12px);
+ padding: 12px;
+ border-radius: var(--radius);
+ border: 1px solid var(--color-line);
+ background: var(--surface-1);
+ color: var(--color-ink);
+ text-decoration: none;
+ transition: border-color .18s ease, transform .18s ease;
+}
+
+.home-module__friend-card:hover {
+ border-color: var(--color-primary);
+ transform: translateY(-1px);
+}
+
+.home-module__friend-avatar {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ object-fit: cover;
+ flex: 0 0 40px;
+}
+
+.home-module__friend-meta {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ min-width: 0;
+}
+
+.home-module__friend-meta strong {
+ font: 600 14px/1.2 var(--font-ui);
+}
+
+.home-module__friend-meta span {
+ font-size: 12px;
+ color: var(--color-ink-3);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
diff --git a/assets/css/frontend/home-modules/highlight-cards.css b/assets/css/frontend/home-modules/highlight-cards.css
new file mode 100644
index 00000000..21818ffc
--- /dev/null
+++ b/assets/css/frontend/home-modules/highlight-cards.css
@@ -0,0 +1,57 @@
+/* Highlight Cards */
+.home-module--highlight-cards {
+ padding: 32px 0;
+}
+
+.home-module__highlight-grid {
+ display: grid;
+ gap: 16px;
+}
+
+.aksrt-highlight-card {
+ padding: 24px;
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-md, 8px);
+ border: 1px solid var(--color-line, #e8e8e8);
+ text-decoration: none;
+ color: inherit;
+ transition: box-shadow 0.2s, transform 0.2s;
+}
+
+.aksrt-highlight-card:hover {
+ box-shadow: none;
+ transform: none;
+}
+
+.aksrt-highlight-card__image {
+ width: 100%;
+ border-radius: var(--radius-sm, 4px);
+ margin-bottom: 12px;
+}
+
+.aksrt-highlight-card__icon {
+ width: 48px;
+ height: 48px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--radius-md, 8px);
+ background: var(--color-primary-softer);
+ color: var(--color-primary);
+ font-size: 20px;
+ margin-bottom: 12px;
+}
+
+.aksrt-highlight-card__title {
+ font-size: 16px;
+ font-weight: 600;
+ margin: 0 0 8px;
+}
+
+.aksrt-highlight-card__desc {
+ font-size: 13px;
+ color: var(--color-ink-3);
+ margin: 0;
+ line-height: 1.6;
+}
+
diff --git a/assets/css/frontend/home-modules/html-module.css b/assets/css/frontend/home-modules/html-module.css
new file mode 100644
index 00000000..fcf5a000
--- /dev/null
+++ b/assets/css/frontend/home-modules/html-module.css
@@ -0,0 +1,7 @@
+/* ============ HTML Module ============ */
+.home-module--html .home-module__html-body {
+ color: var(--color-ink);
+ font-size: 15px;
+ line-height: 1.7;
+}
+
diff --git a/assets/css/frontend/home-modules/partner-marquee.css b/assets/css/frontend/home-modules/partner-marquee.css
new file mode 100644
index 00000000..f18cf509
--- /dev/null
+++ b/assets/css/frontend/home-modules/partner-marquee.css
@@ -0,0 +1,42 @@
+/* Partner Marquee */
+.home-module--partner-marquee {
+ padding: 32px 0;
+ overflow: hidden;
+}
+
+.aksrt-marquee {
+ overflow: hidden;
+ width: 100%;
+}
+
+.aksrt-marquee__track {
+ display: flex;
+ gap: 32px;
+ width: max-content;
+ animation: aksrt-marquee-scroll var(--marquee-duration, 30s) linear infinite;
+}
+
+.aksrt-marquee__item {
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 8px 16px;
+}
+
+.aksrt-marquee__item img {
+ height: 40px;
+ width: auto;
+ opacity: 0.7;
+ transition: opacity 0.2s;
+}
+
+.aksrt-marquee__item:hover img {
+ opacity: 1;
+}
+
+@keyframes aksrt-marquee-scroll {
+ 0% { transform: translateX(0); }
+ 100% { transform: translateX(-50%); }
+}
+
diff --git a/assets/css/frontend/home-modules/product-showcase.css b/assets/css/frontend/home-modules/product-showcase.css
new file mode 100644
index 00000000..60c974eb
--- /dev/null
+++ b/assets/css/frontend/home-modules/product-showcase.css
@@ -0,0 +1,58 @@
+/* Product Showcase */
+.home-module--product-showcase {
+ padding: 32px 0;
+}
+
+.home-module__product-grid {
+ display: grid;
+ gap: 16px;
+}
+
+.aksrt-product-card {
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-md, 8px);
+ border: 1px solid var(--color-line, #e8e8e8);
+ overflow: hidden;
+ text-decoration: none;
+ color: inherit;
+ transition: box-shadow 0.2s, transform 0.2s;
+}
+
+.aksrt-product-card:hover {
+ box-shadow: none;
+ transform: none;
+}
+
+.aksrt-product-card__image img {
+ width: 100%;
+ aspect-ratio: 4/3;
+ object-fit: cover;
+}
+
+.aksrt-product-card__body {
+ padding: 16px;
+}
+
+.aksrt-product-card__title {
+ font-size: 15px;
+ font-weight: 600;
+ margin: 0 0 6px;
+}
+
+.aksrt-product-card__desc {
+ font-size: 13px;
+ color: var(--color-ink-3);
+ margin: 0 0 8px;
+ line-height: 1.5;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.aksrt-product-card__price {
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--color-error);
+}
+
diff --git a/assets/css/frontend/home-modules/ranking.css b/assets/css/frontend/home-modules/ranking.css
new file mode 100644
index 00000000..a33019a1
--- /dev/null
+++ b/assets/css/frontend/home-modules/ranking.css
@@ -0,0 +1,60 @@
+/* ============ Ranking ============ */
+.home-module__ranking-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: var(--space-3, 12px);
+}
+
+.home-module__ranking-item {
+ display: flex;
+ align-items: center;
+ gap: var(--space-3, 12px);
+ padding: 12px 14px;
+ background: var(--surface-1);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+}
+
+.home-module__ranking-num {
+ flex: 0 0 32px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+ font: 700 13px/1 var(--font-ui);
+}
+
+.home-module__ranking-item--top .home-module__ranking-num {
+ background: linear-gradient(135deg, #f59e0b 0%, #f97316 100%);
+ color: #fff;
+ box-shadow: 0 4px 8px rgba(245, 158, 11, .25);
+}
+
+.home-module__ranking-link {
+ flex: 1 1 auto;
+ color: var(--color-ink);
+ text-decoration: none;
+ font: 500 14px/1.4 var(--font-ui);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.home-module__ranking-link:hover {
+ color: var(--color-primary);
+}
+
+.home-module__ranking-value {
+ flex: 0 0 auto;
+ color: var(--color-ink-3);
+ font-variant-numeric: tabular-nums;
+ font: 500 12px/1 var(--font-ui);
+}
+
diff --git a/assets/css/frontend/home-modules/responsive.css b/assets/css/frontend/home-modules/responsive.css
new file mode 100644
index 00000000..73b80ce2
--- /dev/null
+++ b/assets/css/frontend/home-modules/responsive.css
@@ -0,0 +1,294 @@
+/* ============ Responsive ============ */
+@media (max-width: 640px) {
+ .home-modules {
+ gap: var(--space-7, 32px);
+ }
+ .home-module__header {
+ flex-wrap: wrap;
+ }
+ .home-module__title {
+ font-size: 18px;
+ }
+}
+
+/* ============ Hotspot 热点推荐 ============ */
+
+/* 手机端隐藏 */
+.hotspot--desktop-only {
+ display: none;
+}
+
+@media (min-width: 768px) {
+ .hotspot--desktop-only {
+ display: block;
+ }
+}
+
+.hotspot__list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.hotspot__item {
+ display: flex;
+ align-items: flex-start;
+ gap: var(--space-4, 16px);
+ padding: var(--space-4, 16px) 0;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.hotspot__item:last-child {
+ border-bottom: none;
+}
+
+.hotspot__num {
+ flex: 0 0 32px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: var(--radius-avatar, 50%);
+ font: 700 13px/1 var(--font-ui);
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+}
+
+.hotspot__num--top {
+ background: var(--color-primary);
+ color: var(--color-on-primary, #fff);
+}
+
+.hotspot__body {
+ flex: 1;
+ min-width: 0;
+}
+
+.hotspot__title {
+ display: block;
+ font: 600 15px/1.4 var(--font-ui);
+ color: var(--color-ink);
+ text-decoration: none;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ transition: color 0.18s ease;
+}
+
+.hotspot__title:hover {
+ color: var(--color-primary);
+}
+
+.hotspot__meta {
+ display: flex;
+ align-items: center;
+ gap: var(--space-3, 12px);
+ margin-top: var(--space-2, 8px);
+ font: 400 12px/1 var(--font-ui);
+ color: var(--color-ink-3);
+}
+
+.hotspot__cat {
+ display: inline-block;
+ padding: 2px 8px;
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-2);
+ font-size: 11px;
+ font-weight: 500;
+}
+
+/* ============ 分类推荐卡片 ============ */
+
+.cat-cards-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 20px;
+}
+
+.cat-card {
+ background: var(--surface-2, #fff);
+ border-radius: 10px;
+ padding: 22px;
+ box-shadow: 0 1px 6px rgba(0, 0, 0, 0.08);
+ transition: box-shadow 0.2s ease, border-color 0.2s ease;
+}
+
+.cat-card:hover {
+ box-shadow: var(--shadow-md);
+}
+
+/* 上部:封面 + 信息 */
+.cat-card__top {
+ display: flex;
+ align-items: flex-start;
+ gap: 18px;
+ margin-bottom: 18px;
+}
+
+.cat-card__banner {
+ width: 145px;
+ height: 95px;
+ border-radius: 8px;
+ overflow: hidden;
+ position: relative;
+ flex-shrink: 0;
+ background: var(--surface-3, #f5f5f5);
+}
+
+.cat-card__cover {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+ transition: transform 0.3s ease;
+}
+
+.cat-card:hover .cat-card__cover {
+ transform: scale(1.02);
+}
+
+/* 浏览量胶囊:红底白字 */
+.cat-card__views {
+ position: absolute;
+ top: 8px;
+ right: 8px;
+ background: #f54343;
+ color: #fff;
+ font-size: 12px;
+ font-weight: 600;
+ padding: 2px 7px;
+ border-radius: 15px;
+ pointer-events: none;
+ z-index: 1;
+}
+
+.cat-card__info {
+ flex: 1;
+ height: 95px;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.cat-card__name {
+ font-size: 19px;
+ font-weight: 600;
+ color: var(--color-ink);
+ line-height: 1.3;
+}
+
+.cat-card__desc {
+ font-size: 13px;
+ color: var(--color-ink-3);
+ margin-top: 4px;
+ line-height: 1.5;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.cat-card__foot {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 13px;
+ color: var(--color-ink-4);
+}
+
+.cat-card__more {
+ color: var(--color-primary);
+ text-decoration: none;
+ font-weight: 500;
+}
+
+.cat-card__more:hover {
+ text-decoration: underline;
+}
+
+/* 下部:文章列表 */
+.cat-card__list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.cat-card__list li {
+ display: flex;
+ align-items: flex-start;
+ font-size: 13.5px;
+ color: var(--color-ink);
+ line-height: 1.6;
+ padding: 5px 0;
+}
+
+.cat-card__list li::before {
+ content: "\25CF";
+ color: var(--color-primary);
+ font-size: 10px;
+ margin-right: 8px;
+ margin-top: 3px;
+ flex-shrink: 0;
+}
+
+.cat-card__list li a {
+ color: inherit;
+ text-decoration: none;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex: 1;
+ min-width: 0;
+ transition: color 0.15s ease;
+}
+
+.cat-card__list li a:hover {
+ color: var(--color-primary);
+}
+
+.cat-card__time {
+ color: var(--color-ink-4);
+ font-size: 12px;
+ margin-left: auto;
+ padding-left: 12px;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+/* 懒加载骨架 */
+.cat-card__banner .aksrt-skeleton {
+ position: absolute;
+ inset: 0;
+}
+
+.cat-card__banner img.aksrt-lazy {
+ opacity: 0;
+ transition: opacity 0.3s ease;
+}
+
+.cat-card__banner img.aksrt-loaded {
+ opacity: 1;
+}
+
+/* 响应式 */
+@media (max-width: 767px) {
+ .cat-cards-grid {
+ grid-template-columns: 1fr;
+ gap: 16px;
+ }
+
+ .cat-card__name {
+ font-size: 16px;
+ }
+
+ .cat-card__info {
+ height: auto;
+ min-height: 95px;
+ }
+}
+
+/* ============================================================
+ * Phase 5: 运营型模块样式
+ * ============================================================ */
+
diff --git a/assets/css/frontend/home-modules/spacing.css b/assets/css/frontend/home-modules/spacing.css
new file mode 100644
index 00000000..c03325ac
--- /dev/null
+++ b/assets/css/frontend/home-modules/spacing.css
@@ -0,0 +1,5 @@
+/* Spacing */
+.home-module--spacing {
+ pointer-events: none;
+}
+
diff --git a/assets/css/frontend/home-modules/tabs.css b/assets/css/frontend/home-modules/tabs.css
new file mode 100644
index 00000000..4af252d7
--- /dev/null
+++ b/assets/css/frontend/home-modules/tabs.css
@@ -0,0 +1,56 @@
+/* ============ Tabs ============ */
+.home-module__header--tabs {
+ flex-wrap: wrap;
+ border-bottom: 0;
+ padding-bottom: 0;
+}
+
+.home-module__tabs {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-1, 4px);
+ border-bottom: 1px solid var(--color-line);
+ margin-top: var(--space-3, 12px);
+ width: 100%;
+}
+
+.home-module__tab {
+ background: transparent;
+ border: 0;
+ padding: 8px 16px;
+ font: 500 14px/1 var(--font-ui);
+ color: var(--color-ink-2);
+ cursor: pointer;
+ border-radius: 8px 8px 0 0;
+ border-bottom: 2px solid transparent;
+ transition: color .18s ease, border-color .18s ease;
+}
+
+.home-module__tab:hover {
+ color: var(--color-ink);
+}
+
+.home-module__tab.is-active {
+ color: var(--color-primary);
+ border-bottom-color: var(--color-primary);
+}
+
+.home-module__tab-panel {
+ margin-top: var(--space-5, 20px);
+}
+
+.index-tab-main .home-module__tab-panel.tab-pane[hidden],
+.home-tab-content .home-module__tab-panel.tab-pane[hidden] {
+ display: none;
+}
+
+.home-module__tab-panel[hidden] {
+ display: none;
+}
+
+.home-module__empty {
+ color: var(--color-ink-3);
+ text-align: center;
+ padding: var(--space-7, 32px) 0;
+}
+
diff --git a/assets/css/frontend/home-modules/tag-cloud.css b/assets/css/frontend/home-modules/tag-cloud.css
new file mode 100644
index 00000000..8f204418
--- /dev/null
+++ b/assets/css/frontend/home-modules/tag-cloud.css
@@ -0,0 +1,33 @@
+/* ============ Tag Cloud ============ */
+.home-module__tag-cloud {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-2, 8px);
+}
+
+.home-module__tag {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 12px;
+ border-radius: var(--radius-pill);
+ background: var(--surface-2);
+ color: var(--color-ink-2);
+ font: 500 13px/1 var(--font-ui);
+ text-decoration: none;
+ transition: background .18s ease, color .18s ease;
+}
+
+.home-module__tag:hover {
+ background: var(--color-primary);
+ color: var(--color-on-primary);
+}
+
+.home-module__tag-count {
+ font-variant-numeric: tabular-nums;
+ opacity: .7;
+}
+
diff --git a/assets/css/frontend/home-modules/text-title.css b/assets/css/frontend/home-modules/text-title.css
new file mode 100644
index 00000000..3a6782e9
--- /dev/null
+++ b/assets/css/frontend/home-modules/text-title.css
@@ -0,0 +1,17 @@
+/* Text Title */
+.home-module--text-title {
+ padding: 24px 0;
+}
+
+.home-module--text-title .home-module__title {
+ font-size: 28px;
+ font-weight: 700;
+ margin: 0 0 8px;
+}
+
+.home-module--text-title .home-module__subtitle {
+ font-size: 15px;
+ color: var(--color-ink-3);
+ margin: 0;
+}
+
diff --git a/assets/css/frontend/home-modules/user-cards.css b/assets/css/frontend/home-modules/user-cards.css
new file mode 100644
index 00000000..35ac1504
--- /dev/null
+++ b/assets/css/frontend/home-modules/user-cards.css
@@ -0,0 +1,180 @@
+/* ============ User Cards ============ */
+.home-module__users-grid {
+ display: grid;
+ grid-template-columns: repeat(var(--cols, 4), 1fr);
+ gap: var(--space-4, 16px);
+}
+
+.home-module__user-card {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ padding: 20px 16px;
+ border-radius: var(--radius);
+ border: 1px solid var(--color-line);
+ background: var(--surface-1);
+ transition: border-color .18s ease, transform .18s ease;
+}
+
+.home-module__user-card:hover {
+ border-color: var(--color-line);
+ transform: none;
+}
+
+.home-module__user-link {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+ text-decoration: none;
+ color: var(--color-ink);
+}
+
+.home-module__user-avatar {
+ width: 64px;
+ height: 64px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.home-module__user-name {
+ font: 600 14px/1.2 var(--font-ui);
+}
+
+.home-module__user-bio {
+ font-size: 12px;
+ color: var(--color-ink-3);
+ margin: 4px 0 0;
+ line-height: 1.4;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.home-module__user-stats {
+ display: flex;
+ gap: 12px;
+ margin-top: 8px;
+ font-size: 12px;
+ color: var(--color-ink-2);
+}
+
+.home-module__user-stat {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.home-module__user-stat i {
+ font-size: 11px;
+ color: var(--color-ink-3);
+}
+
+/* ============ More (Discover Categories) ============ */
+.home-module__more-grid {
+ display: grid;
+ grid-template-columns: repeat(var(--cols, 3), 1fr);
+ gap: var(--space-4, 16px);
+}
+
+.home-module__more-card {
+ border-radius: var(--radius);
+ border: 1px solid var(--color-line);
+ background: var(--surface-1);
+ overflow: hidden;
+ transition: border-color .18s ease, transform .18s ease;
+}
+
+.home-module__more-card:hover {
+ border-color: var(--color-line);
+ transform: none;
+}
+
+.home-module__more-link {
+ display: block;
+ text-decoration: none;
+ color: inherit;
+}
+
+.home-module__more-cover {
+ aspect-ratio: 16 / 9;
+ overflow: hidden;
+ background: var(--color-fill-2);
+}
+
+.home-module__more-cover img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.home-module__more-cover--placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 28px;
+ color: var(--color-ink-3);
+}
+
+.home-module__more-body {
+ padding: 12px;
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+}
+
+.home-module__more-name {
+ font: 600 14px/1.3 var(--font-ui);
+}
+
+.home-module__more-count {
+ font-size: 12px;
+ color: var(--color-ink-3);
+}
+
+.home-module__more-posts {
+ list-style: none;
+ margin: 0;
+ padding: 0 12px 12px;
+}
+
+.home-module__more-posts li {
+ border-top: 1px solid var(--color-line-light, rgba(0,0,0,.06));
+}
+
+.home-module__more-posts a {
+ display: block;
+ padding: 6px 0;
+ font-size: 13px;
+ color: var(--color-ink-2);
+ text-decoration: none;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ transition: color .15s ease;
+}
+
+.home-module__more-posts a:hover {
+ color: var(--color-primary);
+}
+
+/* 响应式 */
+@media (max-width: 767px) {
+ .home-module__data-grid,
+ .home-module__highlight-grid,
+ .home-module__product-grid {
+ grid-template-columns: 1fr !important;
+ }
+
+ .home-module__faq-grid {
+ column-count: 1 !important;
+ }
+
+ .home-module__users-grid,
+ .home-module__more-grid {
+ grid-template-columns: 1fr 1fr !important;
+ }
+}
+
diff --git a/assets/css/frontend/homepage-fixed.css b/assets/css/frontend/homepage-fixed.css
new file mode 100644
index 00000000..3f61bf97
--- /dev/null
+++ b/assets/css/frontend/homepage-fixed.css
@@ -0,0 +1,3 @@
+@import url("homepage-fixed/base.css");
+@import url("homepage-fixed/ajax-tab-skeleton-placeholder.css");
+@import url("homepage-fixed/ajax-tab-error-state.css");
diff --git a/assets/css/frontend/homepage-fixed/ajax-tab-error-state.css b/assets/css/frontend/homepage-fixed/ajax-tab-error-state.css
new file mode 100644
index 00000000..f867ad90
--- /dev/null
+++ b/assets/css/frontend/homepage-fixed/ajax-tab-error-state.css
@@ -0,0 +1,197 @@
+/* AJAX tab error state */
+.aksrt-homepage__tab-error {
+ padding: 32px 16px;
+ text-align: center;
+ color: var(--color-ink-4, #999);
+ font-size: 14px;
+}
+
+.aksrt-homepage__tab-retry {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin-top: 12px;
+ padding: 6px 14px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 8px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-3, #777);
+ font-size: 13px;
+ cursor: pointer;
+ transition: color 0.2s, border-color 0.2s;
+}
+
+.aksrt-homepage__tab-retry:hover {
+ color: var(--color-primary, var(--color-primary));
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+/* ================================================================
+ 14. RESPONSIVE — TABLET (max-width: 991px)
+ ================================================================ */
+
+@media (max-width: 991.98px) {
+ .aksrt-homepage__shell.content-shell,
+ .aksrt-homepage__fluid-zone.content-shell {
+ padding-top: 16px;
+ }
+
+ .aksrt-homepage__posts > .posts-item.list {
+ padding: 15px;
+ gap: 14px;
+ }
+
+ .aksrt-homepage__posts > .posts-item.list .item-thumbnail {
+ width: 160px;
+ min-width: 160px;
+ padding-bottom: calc(160px * 0.7);
+ }
+
+ .aksrt-homepage__posts > .posts-item.list.mult-thumb .thumb-items > span {
+ width: calc(33.333% - 6px);
+ padding-bottom: calc(var(--posts-list-scale, 70%) / 3);
+ }
+
+ .aksrt-homepage__posts > .posts-item.list.mult-thumb .thumb-items > span:nth-child(4) {
+ display: none;
+ }
+
+ /* Card mode: 2 columns */
+ .aksrt-homepage__posts[data-view="card"] > .posts-item {
+ width: calc(50% - 16px);
+ }
+}
+
+/* ================================================================
+ 15. RESPONSIVE — MOBILE (max-width: 767px)
+ ================================================================ */
+
+@media (max-width: 767px) {
+ .aksrt-homepage__shell.content-shell {
+ padding-left: 10px;
+ padding-right: 10px;
+ }
+
+ .aksrt-homepage__posts > .posts-item.list {
+ padding: 12px;
+ gap: 12px;
+ margin-bottom: 10px;
+ }
+
+ .aksrt-homepage__posts > .posts-item.list .item-thumbnail {
+ width: 120px;
+ min-width: 120px;
+ padding-bottom: calc(120px * 0.7);
+ }
+
+ .aksrt-homepage__posts .item-heading {
+ font-size: 15px;
+ line-height: 1.4;
+ }
+
+ .aksrt-homepage__posts .item-excerpt {
+ display: none;
+ }
+
+ .aksrt-homepage__posts .meta-right {
+ display: none;
+ }
+
+ /* Card mode: 2 columns (match Zibll) */
+ .aksrt-homepage__posts[data-view="card"] > .posts-item {
+ width: calc(50% - 10px);
+ margin: 5px;
+ }
+
+ /* Tab skeleton: smaller thumb */
+ .aksrt-homepage__tab-skeleton-thumb {
+ width: 120px;
+ min-width: 120px;
+ height: 84px;
+ }
+}
+
+/* ================================================================
+ 16. RESPONSIVE — SMALL MOBILE (max-width: 640px)
+ ================================================================ */
+
+@media (max-width: 640px) {
+ .aksrt-homepage__tabs,
+ .aksrt-homepage__titlebox {
+ margin-bottom: 8px;
+ }
+
+ .aksrt-homepage__admin-link {
+ margin-left: 0;
+ margin-top: 12px;
+ }
+
+ .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-stuck,
+ .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed {
+ padding: 8px 10px;
+ border-radius: 10px;
+ }
+
+ .aksrt-homepage__sortbar {
+ gap: 10px;
+ margin-bottom: 12px;
+ padding-bottom: 12px;
+ font-size: 13px;
+ }
+
+ .aksrt-homepage__posts > .posts-item.list {
+ padding: 10px;
+ gap: 10px;
+ border-radius: var(--radius, 8px);
+ }
+
+ .aksrt-homepage__posts > .posts-item.list .item-thumbnail {
+ width: 96px;
+ min-width: 96px;
+ padding-bottom: calc(96px * 0.7);
+ border-radius: 6px;
+ }
+
+ .aksrt-homepage__posts .item-heading {
+ font-size: 15px;
+ -webkit-line-clamp: 2;
+ }
+
+ .aksrt-homepage__posts .item-tags .badge {
+ font-size: 11px;
+ padding: 2px 5px;
+ }
+
+ .aksrt-homepage__posts .item-meta {
+ flex-wrap: wrap;
+ gap: 8px;
+ font-size: 12px;
+ }
+
+ .aksrt-homepage__posts .meta-avatar {
+ width: 20px;
+ height: 20px;
+ }
+
+ .aksrt-homepage__posts .meta-item {
+ font-size: 12px;
+ }
+
+ /* Card mode: single column */
+ .aksrt-homepage__posts[data-view="card"] {
+ margin: 0;
+ }
+
+ .aksrt-homepage__posts[data-view="card"] > .posts-item {
+ width: 100%;
+ margin: 0 0 10px;
+ }
+
+ /* Tab skeleton: adapt */
+ .aksrt-homepage__tab-skeleton-thumb {
+ width: 96px;
+ min-width: 96px;
+ height: 67px;
+ }
+}
+
diff --git a/assets/css/frontend/homepage-fixed/ajax-tab-skeleton-placeholder.css b/assets/css/frontend/homepage-fixed/ajax-tab-skeleton-placeholder.css
new file mode 100644
index 00000000..7a6e577d
--- /dev/null
+++ b/assets/css/frontend/homepage-fixed/ajax-tab-skeleton-placeholder.css
@@ -0,0 +1,51 @@
+/* AJAX tab skeleton placeholder */
+.aksrt-homepage__tab-skeleton {
+ display: flex;
+ flex-direction: column;
+ gap: 15px;
+ padding: 10px 0;
+}
+
+.aksrt-homepage__tab-skeleton-item {
+ display: flex;
+ gap: 16px;
+ padding: 20px;
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius, 8px);
+ animation: aksrt-skeleton-pulse 1.5s ease-in-out infinite;
+}
+
+.aksrt-homepage__tab-skeleton-thumb {
+ width: 190px;
+ min-width: 190px;
+ height: 133px;
+ background: var(--surface-2, #eee);
+ border-radius: var(--radius, 8px);
+}
+
+.aksrt-homepage__tab-skeleton-body {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.aksrt-homepage__tab-skeleton-line {
+ height: 14px;
+ background: var(--surface-2, #eee);
+ border-radius: 4px;
+}
+
+.aksrt-homepage__tab-skeleton-line:first-child {
+ width: 70%;
+ height: 18px;
+}
+
+.aksrt-homepage__tab-skeleton-line:nth-child(2) {
+ width: 100%;
+}
+
+.aksrt-homepage__tab-skeleton-line:nth-child(3) {
+ width: 40%;
+}
+
diff --git a/assets/css/frontend/homepage-fixed/base-1.css b/assets/css/frontend/homepage-fixed/base-1.css
new file mode 100644
index 00000000..3ca9aa28
--- /dev/null
+++ b/assets/css/frontend/homepage-fixed/base-1.css
@@ -0,0 +1,401 @@
+/**
+ * Homepage Fixed Layout — Zibll Visual Parity
+ *
+ * Implements Zibll's homepage visual language:
+ * - System font stack with Chinese fallbacks
+ * - 1200px container, 311px sidebar
+ * - Post cards: list mode (190px thumb) + card mode (3-col grid)
+ * - Zibll shadow/radius/spacing values
+ * - scale(1.02) thumbnail hover
+ * - Lazy-load animations (blur/fade/scale)
+ * - Full responsive: 1200/991/767/640px breakpoints
+ */
+
+/* ================================================================
+ 0. ANIMATIONS
+ ================================================================ */
+
+@keyframes aksrt-lazy-blur {
+ from { filter: blur(5px); opacity: 0.6; }
+ to { filter: blur(0); opacity: 1; }
+}
+
+@keyframes aksrt-lazy-fade {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+@keyframes aksrt-lazy-scale {
+ from { transform: scale(1.1); opacity: 0.8; }
+ to { transform: scale(1); opacity: 1; }
+}
+
+@keyframes aksrt-skeleton-pulse {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.4; }
+}
+
+/* ================================================================
+ 1. HOMEPAGE CONTAINER & TYPOGRAPHY
+ ================================================================ */
+
+.aksrt-homepage {
+ font-family: "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
+ font-size: 16px;
+ line-height: 1.42857143;
+ color: var(--main-color, #4e5358);
+ background: transparent;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.aksrt-homepage a[href] {
+ transition: color 0.2s, background 0.3s, opacity 0.3s, box-shadow 0.3s, transform 0.3s;
+}
+
+.aksrt-homepage img.aksrt-loaded {
+ animation: aksrt-lazy-blur 0.6s ease;
+}
+
+.aksrt-homepage img.aksrt-loaded.img-icon {
+ animation: aksrt-lazy-fade 0.6s ease;
+}
+
+.aksrt-homepage .aksrt-skeleton {
+ animation: aksrt-skeleton-pulse 1.5s ease-in-out infinite;
+}
+
+/* ================================================================
+ 2. LAYOUT SHELL
+ ================================================================ */
+
+.aksrt-homepage__fluid-zone.content-shell,
+.aksrt-homepage__shell.content-shell {
+ max-width: min(100%, var(--container, 1200px));
+}
+
+.aksrt-homepage__fluid-zone.content-shell {
+ padding-top: 18px;
+ padding-bottom: 0;
+}
+
+.aksrt-homepage__hero {
+ width: 100vw;
+ max-width: 100vw;
+ margin: 0 calc(-50vw + 50%) 24px;
+}
+
+.aksrt-homepage__hero .header-components-container {
+ margin-bottom: 0;
+}
+
+.aksrt-homepage__shell.content-shell {
+ padding-top: 0;
+ padding-bottom: 36px;
+}
+
+.aksrt-homepage__content-layout {
+ gap: 20px;
+}
+
+@media (min-width: 992px) {
+ .aksrt-homepage__content-layout {
+ grid-template-columns: minmax(0, 1fr) var(--sidebar-width, 311px);
+ }
+}
+
+@media (max-width: 1200px) {
+ .aksrt-homepage__fluid-zone.content-shell,
+ .aksrt-homepage__shell.content-shell {
+ max-width: 95%;
+ }
+}
+
+.aksrt-homepage__content-zone,
+.aksrt-homepage__fluid-zone,
+.aksrt-homepage__aside {
+ display: block;
+}
+
+.aksrt-homepage__system-modules {
+ gap: 0;
+ padding-bottom: 0;
+}
+
+.aksrt-homepage__content-zone.aksrt-homepage__system-modules {
+ margin-bottom: 20px;
+}
+
+.aksrt-homepage__content-zone--featured {
+ margin-bottom: 20px;
+}
+
+.aksrt-homepage__content-zone--featured.home-modules {
+ gap: 24px;
+ padding-bottom: 0;
+}
+
+.aksrt-homepage__content-zone .widget-card:last-child,
+.aksrt-homepage__aside .widget:last-child,
+.aksrt-homepage__fluid-zone .widget-fluid:last-child {
+ margin-bottom: 0;
+}
+
+/* ================================================================
+ 3. FLUID WIDGETS
+ ================================================================ */
+
+.aksrt-homepage__fluid-zone .widget-fluid {
+ margin-bottom: 20px;
+ background: transparent;
+ padding: 0;
+ border: 0;
+ box-shadow: none;
+}
+
+.aksrt-homepage .widget-fluid.widget_aksrt_tab_posts,
+.aksrt-homepage .widget-fluid.widget_aksrt_category_block,
+.aksrt-homepage .widget-fluid.widget_aksrt_category_tabs,
+.aksrt-homepage .widget-fluid.widget_aksrt_category_recommend {
+ padding: 15px;
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius, 8px);
+ box-shadow: 0 0 10px var(--shadow, rgba(116, 116, 116, 0.08));
+}
+
+.aksrt-homepage__content-zone .widget-card,
+.aksrt-homepage__aside .widget {
+ background: var(--surface-1, #fff);
+ padding: 15px;
+ border: none;
+ border-radius: var(--radius, 8px);
+ box-shadow: 0 0 10px var(--shadow, rgba(116, 116, 116, 0.08));
+}
+
+/* ================================================================
+ 4. STREAM CONTAINER
+ ================================================================ */
+
+.aksrt-homepage__stream,
+.aksrt-homepage__stream.widget-card {
+ overflow: visible;
+ padding: 0;
+ background: transparent;
+ border: 0;
+ border-radius: 0;
+ box-shadow: none;
+ margin-bottom: 0;
+}
+
+/* ================================================================
+ 5. TABS
+ ================================================================ */
+
+.aksrt-homepage__tabs,
+.aksrt-homepage__titlebox {
+ margin-bottom: 10px;
+ padding-bottom: 0;
+ border-bottom: 0;
+}
+
+.aksrt-homepage__tabs.box-body,
+.aksrt-homepage__titlebox.box-body {
+ padding: 0;
+}
+
+.aksrt-homepage__tabs-sentinel {
+ width: 100%;
+ height: 1px;
+ margin: 0;
+ pointer-events: none;
+}
+
+.aksrt-homepage__tabs.home-tab-nav-box {
+ position: static;
+ z-index: auto;
+ background: transparent;
+}
+
+.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"] {
+ position: sticky;
+ top: var(--nav-height, 60px);
+ z-index: 995;
+ background: transparent;
+ transition: background-color 0.2s ease,
+ box-shadow 0.2s ease,
+ border-radius 0.2s ease,
+ padding 0.2s ease,
+ margin 0.2s ease,
+ backdrop-filter 0.2s ease,
+ -webkit-backdrop-filter 0.2s ease;
+}
+
+.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-stuck,
+.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed {
+ margin-bottom: 14px;
+ padding: 10px 16px;
+ background: rgba(255, 255, 255, 0.92);
+ border-radius: 12px;
+ box-shadow: 0 10px 28px rgba(24, 24, 24, 0.08);
+ backdrop-filter: saturate(1.6) blur(20px);
+ -webkit-backdrop-filter: saturate(1.6) blur(20px);
+}
+
+.aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed {
+ position: fixed;
+}
+
+html.dark .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-stuck,
+html.dark .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed,
+html.dark .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-stuck,
+html.dark .aksrt-homepage__tabs.home-tab-nav-box[data-sticky-tabs="true"].is-affixed {
+ background: rgba(24, 24, 24, 0.82);
+ box-shadow: 0 12px 30px rgba(0, 0, 0, 0.24);
+}
+
+.aksrt-homepage__tab-list {
+ list-style: none;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ margin: 0;
+ padding: 0;
+}
+
+.aksrt-homepage__admin-link {
+ margin-left: auto;
+}
+
+.scroll-x {
+ overflow-x: auto;
+ overflow-y: hidden;
+}
+
+.no-scrollbar {
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+}
+
+.no-scrollbar::-webkit-scrollbar {
+ display: none;
+}
+
+.aksrt-homepage__tab-item {
+ display: inline-flex;
+ flex: 0 0 auto;
+ padding: 0;
+ margin: 0;
+ border-radius: 20px;
+ font-weight: 500;
+ transition: background 0.2s ease, color 0.2s ease;
+}
+
+.aksrt-homepage__tab-button {
+ padding: 6px 14px;
+ border: 0;
+ background: transparent;
+ color: var(--color-ink);
+ font-family: inherit;
+ font-size: 14px;
+ font-weight: inherit;
+ line-height: 1.2;
+ white-space: nowrap;
+ border-radius: inherit;
+ cursor: pointer;
+}
+
+.aksrt-homepage__tab-button:hover {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-homepage__tab-item.is-active {
+ background: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-homepage__tab-item.is-active .aksrt-homepage__tab-button,
+.aksrt-homepage__tab-button[aria-selected="true"] {
+ color: #fff !important;
+}
+
+/* ================================================================
+ 6. SORTBAR + VIEW TOGGLE
+ ================================================================ */
+
+.aksrt-homepage__sortbar {
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ margin-bottom: 16px;
+ padding: 2px 0 14px;
+ border-bottom: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
+ color: var(--color-ink-3, #777);
+ font-size: 14px;
+}
+
+.aksrt-homepage__sortbar-label {
+ flex: 0 0 auto;
+ color: var(--color-ink);
+ font-weight: 700;
+}
+
+.aksrt-homepage__sortbar-links {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 0;
+ flex: 1 1 auto;
+}
+
+.aksrt-homepage__sortbar-link {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ padding: 0 12px;
+ color: var(--color-ink-3, #777);
+ text-decoration: none;
+ line-height: 1.4;
+}
+
+.aksrt-homepage__sortbar-link:first-child {
+ padding-left: 0;
+}
+
+.aksrt-homepage__sortbar-link + .aksrt-homepage__sortbar-link::before {
+ content: "\00b7";
+ position: absolute;
+ left: -2px;
+ color: var(--color-ink-4, #b1b1b1);
+}
+
+.aksrt-homepage__sortbar-link:hover,
+.aksrt-homepage__sortbar-link.is-active {
+ color: var(--color-ink);
+}
+
+.aksrt-homepage__view-toggle {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin-left: auto;
+ flex: 0 0 auto;
+}
+
+.aksrt-homepage__view-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 28px;
+ height: 28px;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: var(--color-ink-4, #999);
+ border-radius: 4px;
+ cursor: pointer;
+ transition: color 0.2s, background 0.2s;
+}
+
+.aksrt-homepage__view-btn:hover {
+ color: var(--color-ink);
+ background: var(--surface-2, #eee);
+}
diff --git a/assets/css/frontend/homepage-fixed/base-2.css b/assets/css/frontend/homepage-fixed/base-2.css
new file mode 100644
index 00000000..3f33502b
--- /dev/null
+++ b/assets/css/frontend/homepage-fixed/base-2.css
@@ -0,0 +1,400 @@
+
+.aksrt-homepage__view-btn.is-active {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-homepage__view-btn svg {
+ width: 16px;
+ height: 16px;
+ fill: currentColor;
+}
+
+/* ================================================================
+ 7. TITLE THEME (sidebar section headers)
+ ================================================================ */
+
+.title-theme {
+ position: relative;
+ padding-left: 1.2em;
+ font-size: 15px;
+ font-weight: 700;
+ line-height: 1.4;
+}
+
+.title-theme::before {
+ position: absolute;
+ content: "";
+ width: 4px;
+ background: var(--color-primary, var(--color-primary));
+ top: 10%;
+ left: 2px;
+ bottom: 10%;
+ border-radius: 5px;
+ box-shadow: 1px 1px 3px -1px var(--color-primary, var(--color-primary));
+}
+
+.aksrt-homepage__page-indicator {
+ margin-left: 10px;
+ font-size: 80%;
+ font-weight: 400;
+ opacity: 0.7;
+}
+
+/* ================================================================
+ 8. PANELS
+ ================================================================ */
+
+.aksrt-homepage__panel[hidden] {
+ display: none !important;
+}
+
+.aksrt-homepage__panels {
+ display: block;
+}
+
+.home-tab-content {
+ display: block;
+}
+
+.index-tab-main .tab-pane[hidden],
+.home-tab-content .tab-pane[hidden] {
+ display: none !important;
+}
+
+.aksrt-homepage__panel {
+ opacity: 0;
+ transition: opacity 0.3s ease;
+}
+
+.aksrt-homepage__panel.is-active,
+.aksrt-homepage__panel:not([hidden]) {
+ opacity: 1;
+}
+
+/* ================================================================
+ 9. POST LIST — LIST MODE
+ ================================================================ */
+
+.aksrt-homepage__posts {
+ display: block;
+ margin: 0;
+}
+
+.aksrt-homepage__posts > .posts-item.list {
+ width: 100%;
+ margin: 15px 0;
+ padding: 20px;
+ display: flex;
+ flex-direction: row;
+ gap: 16px;
+ min-width: 0;
+ background: var(--surface-1, #fff);
+ border: none;
+ border-radius: var(--radius, 8px);
+ box-shadow: 0 0 10px var(--shadow, rgba(116, 116, 116, 0.08));
+ overflow: hidden;
+ transition: box-shadow 0.2s, transform 0.2s;
+}
+
+.aksrt-homepage__posts > .posts-item.list:last-child {
+ margin-bottom: 0;
+}
+
+.aksrt-homepage__posts > .posts-item.list:hover {
+ box-shadow: 0 4px 16px rgba(116, 116, 116, 0.16);
+ transform: translateY(-1px);
+}
+
+html.dark .aksrt-homepage__posts > .posts-item.list:hover,
+html.dark .aksrt-homepage__posts > .posts-item.list:hover {
+ box-shadow: 0 4px 16px rgba(24, 24, 24, 0.22);
+}
+
+.aksrt-homepage__posts > .posts-item.list .item-thumbnail {
+ position: relative;
+ width: 190px;
+ min-width: 190px;
+ height: 0;
+ padding-top: 0;
+ padding-bottom: calc(190px * 0.7);
+ border-radius: var(--radius, 8px);
+ overflow: hidden;
+ flex-shrink: 0;
+}
+
+.aksrt-homepage__posts > .posts-item.list .item-thumbnail > a {
+ position: absolute;
+ inset: 0;
+ display: block;
+}
+
+.aksrt-homepage__posts > .posts-item.list .item-thumbnail img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.3s;
+}
+
+.aksrt-homepage__posts > .posts-item.list:hover .item-thumbnail img {
+ transform: scale(1.02);
+}
+
+.aksrt-homepage__posts > .posts-item.list .item-thumbnail .aksrt-skeleton {
+ position: absolute;
+ inset: 0;
+ background: var(--surface-2, #eee);
+ border-radius: inherit;
+}
+
+.aksrt-homepage__posts > .posts-item.list .item-thumbnail .img-badge {
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ padding: 2px 6px;
+ border-radius: 4px;
+ font-size: 11px;
+ font-weight: 500;
+ line-height: 1.4;
+ background: rgba(0, 0, 0, 0.6);
+ color: #fff;
+ z-index: 1;
+}
+
+.aksrt-homepage__posts > .posts-item.list .thumb-items {
+ display: none;
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb {
+ display: block;
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb .item-thumbnail {
+ display: none;
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb .thumb-items {
+ display: block;
+ margin: 0 -3px 6px;
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb .thumb-items > span {
+ position: relative;
+ display: inline-block;
+ width: calc(25% - 6px);
+ height: 0;
+ margin: 0 3px;
+ padding-bottom: calc(var(--posts-list-scale, 70%) / 4);
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb .thumb-items.contain > span {
+ overflow: hidden;
+ background: var(--color-line, rgba(50, 50, 50, 0.06));
+ border-radius: var(--radius, 8px);
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb .thumb-items > span .aksrt-skeleton,
+.aksrt-homepage__posts > .posts-item.list.mult-thumb .thumb-items > span > img {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb .thumb-items > span > img {
+ object-fit: cover;
+ transition: transform 0.3s;
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb:hover .thumb-items > span > img {
+ transform: scale(1.02);
+}
+
+.aksrt-homepage__posts > .posts-item.list.mult-thumb .item-body {
+ width: 100%;
+ padding: 2px 0 0;
+}
+
+.aksrt-homepage__posts > .posts-item.list .item-body {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ gap: 8px;
+ margin: 0;
+ padding: 2px 0;
+ min-width: 0;
+ flex: 1 1 auto;
+}
+
+.aksrt-homepage__posts .item-heading {
+ margin: 0 0 2px;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 1.4;
+ min-height: 0;
+ max-height: 2.8em;
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ color: var(--color-ink);
+}
+
+.aksrt-homepage__posts .item-heading a {
+ color: inherit;
+ text-decoration: none;
+}
+
+.aksrt-homepage__posts .item-heading a:hover {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-homepage__posts .item-excerpt {
+ margin: 0;
+ color: var(--main-color, #4e5358);
+ font-size: 14px;
+ line-height: 1.6;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.aksrt-homepage__posts .item-tags {
+ display: flex;
+ align-items: center;
+ min-height: 0;
+ margin-bottom: 0;
+ gap: 5px;
+ flex-wrap: wrap;
+ overflow: visible;
+}
+
+.aksrt-homepage__posts .item-tags .badge {
+ min-height: auto;
+ margin-right: 0;
+ padding: 2px 5px;
+ border-radius: 4px;
+ font-size: 11px;
+ line-height: 1.4;
+ font-weight: 400;
+}
+
+.aksrt-homepage__posts .item-meta {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin: 0;
+ padding-top: 0;
+ border-top: 0;
+ font-size: 13px;
+ color: var(--color-ink-3, #777);
+}
+
+.aksrt-homepage__posts .meta-author,
+.aksrt-homepage__posts .meta-right {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.aksrt-homepage__posts .meta-avatar {
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+}
+
+.aksrt-homepage__posts .meta-name {
+ color: var(--color-ink);
+ font-weight: 500;
+}
+
+.aksrt-homepage__posts .meta-dot {
+ width: 4px;
+ height: 4px;
+ border-radius: 999px;
+ background: var(--color-ink-4, #b1b1b1);
+}
+
+.aksrt-homepage__posts .meta-item {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 13px;
+ white-space: nowrap;
+ color: var(--color-ink-3, #777);
+}
+
+.aksrt-homepage__posts .meta-item i {
+ font-size: 12px;
+}
+
+/* ================================================================
+ 10. POST CARDS — CARD MODE (3-column grid)
+ ================================================================ */
+
+.aksrt-homepage__posts[data-view="card"] {
+ display: flex;
+ flex-wrap: wrap;
+ margin: -8px;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item {
+ width: calc(33.333% - 16px);
+ margin: 8px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ background: var(--surface-1, #fff);
+ border: none;
+ border-radius: var(--radius, 8px);
+ box-shadow: none;
+ overflow: hidden;
+ transition: box-shadow 0.3s, transform 0.2s;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item:hover {
+ box-shadow: 0 0 10px var(--shadow, rgba(116, 116, 116, 0.08));
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item.style2 {
+ background: transparent;
+ box-shadow: none;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item.style2:hover {
+ background: var(--surface-1, #fff);
+ box-shadow: 0 0 10px var(--shadow, rgba(116, 116, 116, 0.08));
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item.style3 {
+ padding: 0;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item .item-thumbnail {
+ position: relative;
+ display: block;
+ width: 100%;
+ height: 0;
+ padding-top: 0;
+ padding-bottom: var(--posts-card-scale, 70%);
+ min-width: unset;
+ border-radius: var(--radius, 8px);
+ overflow: hidden;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item .item-thumbnail > a {
+ position: absolute;
+ inset: 0;
+ display: block;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item .item-thumbnail img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
diff --git a/assets/css/frontend/homepage-fixed/base-3.css b/assets/css/frontend/homepage-fixed/base-3.css
new file mode 100644
index 00000000..5e2fb9d7
--- /dev/null
+++ b/assets/css/frontend/homepage-fixed/base-3.css
@@ -0,0 +1,245 @@
+ transition: transform 0.3s;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item.mult-thumb .thumb-items {
+ display: none;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item.mult-thumb .item-thumbnail {
+ display: block;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item.style3 .item-thumbnail,
+.aksrt-homepage__posts[data-view="card"] > .posts-item.style3 .item-thumbnail img {
+ border-radius: var(--radius, 8px) var(--radius, 8px) 0 0;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item:hover .item-thumbnail img {
+ transform: scale(1.02);
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item .item-body {
+ width: 100%;
+ margin: 10px 0 0;
+ padding: 0;
+ gap: 6px;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item.style3 .item-body {
+ margin: 0;
+ padding: 10px;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item .item-heading {
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1.4;
+ min-height: 2.8em;
+ -webkit-line-clamp: 2;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item .item-excerpt {
+ display: none;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item .item-meta {
+ font-size: 12px;
+}
+
+.aksrt-homepage__posts[data-view="card"] > .posts-item .meta-right {
+ display: none;
+}
+
+/* ================================================================
+ 11. PAGINATION
+ ================================================================ */
+
+.aksrt-homepage__panel-footer {
+ display: flex;
+ justify-content: center;
+ margin-top: 18px;
+}
+
+.aksrt-homepage__more,
+.aksrt-homepage .aksrt-load-more-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 34px;
+ padding: 0 14px;
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
+ border-radius: var(--radius, 8px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-3, #777);
+ font-size: 13px;
+ font-weight: 500;
+ transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
+}
+
+.aksrt-homepage__more:hover,
+.aksrt-homepage .aksrt-load-more-btn:hover {
+ color: var(--color-primary, var(--color-primary));
+ border-color: var(--color-primary, var(--color-primary));
+ box-shadow: none;
+ transform: none;
+}
+
+.aksrt-homepage .ajax-pagination {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 10px;
+ margin-top: 20px;
+}
+
+.aksrt-homepage .navigation.pagination .nav-links,
+.aksrt-homepage .pagination {
+ gap: 0;
+ margin: 20px 0 10px;
+}
+
+.aksrt-homepage .navigation.pagination .page-numbers,
+.aksrt-homepage .pagination .page-numbers {
+ min-width: 31px;
+ height: auto;
+ padding: 6px 9px 5px;
+ margin: 3px;
+ border: 0;
+ border-radius: 3px;
+ background: var(--surface-2, #eee);
+ color: var(--color-ink-3, #777);
+ font-size: 13px;
+ line-height: 1.4;
+}
+
+.aksrt-homepage .navigation.pagination .page-numbers:hover,
+.aksrt-homepage .pagination .page-numbers:hover {
+ opacity: 0.7;
+}
+
+.aksrt-homepage .navigation.pagination .current,
+.aksrt-homepage .pagination .current {
+ background: var(--color-primary, var(--color-primary)) !important;
+ color: #fff !important;
+}
+
+/* ================================================================
+ 12. SIDEBAR
+ ================================================================ */
+
+.aksrt-homepage__aside .widget-list li,
+.aksrt-homepage__aside .widget_recent_entries li,
+.aksrt-homepage__aside .recent-posts-row {
+ padding-top: 8px;
+ padding-bottom: 8px;
+}
+
+.aksrt-homepage__aside .widget-title,
+.aksrt-homepage__content-zone .widget-title {
+ margin-bottom: 12px;
+}
+
+.aksrt-homepage__aside .widget-title {
+ position: relative;
+ margin: 0 0 10px;
+ padding-left: 1.2em;
+ padding-bottom: 8px;
+ font-size: 15px;
+ font-weight: 700;
+ line-height: 1.4;
+}
+
+.aksrt-homepage__aside .widget-title::before {
+ content: "";
+ position: absolute;
+ top: 10%;
+ bottom: 10%;
+ left: 2px;
+ width: 4px;
+ height: auto;
+ background: var(--color-primary, var(--color-primary));
+ border-radius: 5px;
+ box-shadow: 1px 1px 3px -1px var(--color-primary, var(--color-primary));
+ transition: transform 0.4s ease;
+ transform-origin: left;
+}
+
+.aksrt-homepage__aside .widget_recent_entries li a,
+.aksrt-homepage__aside .widget-list li a {
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 1.5;
+}
+
+.aksrt-homepage__aside .widget_recent_entries li {
+ display: block;
+}
+
+.aksrt-homepage__aside .widget_search .search-field {
+ height: 40px;
+ border-radius: 30px;
+ background: var(--surface-2, #eee);
+}
+
+.aksrt-homepage__aside .widget_search .search-submit {
+ top: 4px;
+ right: 4px;
+ height: 32px;
+ padding: 0 12px;
+ border-radius: 30px;
+ font-size: 12px;
+}
+
+.aksrt-homepage__aside .tag-cloud {
+ gap: 6px;
+}
+
+.aksrt-homepage__aside .tag-cloud a {
+ padding: 4px 10px;
+ border-radius: 20px;
+ font-size: 12px;
+ border: 0;
+ background: var(--surface-2, #eee);
+ transition: background 0.2s, color 0.2s;
+}
+
+.aksrt-homepage__aside .tag-cloud a:hover {
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+}
+
+.aksrt-homepage .widget.notop,
+.aksrt-homepage .box-body.notop {
+ padding-top: 0;
+}
+
+.aksrt-homepage .widget.nobottom,
+.aksrt-homepage .box-body.nobottom {
+ padding-bottom: 0;
+}
+
+.aksrt-homepage .widget.widget_custom_html {
+ padding: 0;
+ background: transparent;
+ box-shadow: none;
+ border-radius: 0;
+}
+
+/* ================================================================
+ 13. LOADING & EMPTY STATES
+ ================================================================ */
+
+.aksrt-homepage .aksrt-loading-indicator {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--color-ink-3, #777);
+ font-size: 13px;
+}
+
+.aksrt-homepage__stream .no-results {
+ padding: 32px 16px;
+ text-align: center;
+ color: var(--color-ink-4, #999);
+}
+
diff --git a/assets/css/frontend/homepage-fixed/base.css b/assets/css/frontend/homepage-fixed/base.css
new file mode 100644
index 00000000..4e615659
--- /dev/null
+++ b/assets/css/frontend/homepage-fixed/base.css
@@ -0,0 +1,3 @@
+@import url("base-1.css");
+@import url("base-2.css");
+@import url("base-3.css");
diff --git a/assets/css/frontend/layout.css b/assets/css/frontend/layout.css
new file mode 100644
index 00000000..8b0530e9
--- /dev/null
+++ b/assets/css/frontend/layout.css
@@ -0,0 +1,516 @@
+/* ========== 面包屑 — 对齐 zibll .breadcrumb ========== */
+.breadcrumbs {
+ font-size: 13px;
+ color: var(--muted-2-color, #999);
+ margin-bottom: 12px;
+ opacity: 0.8;
+}
+
+.breadcrumbs a {
+ color: var(--muted-2-color, #999);
+}
+
+.breadcrumbs a:hover {
+ color: var(--focus-color, #f04494);
+}
+
+.breadcrumbs__sep {
+ margin: 0 0 0 6px;
+ opacity: 0.6;
+}
+
+@media (max-width: 767px) {
+ .breadcrumbs {
+ font-size: 12px;
+ }
+}
+
+/* 封面内面包屑 */
+.single-cover-con .breadcrumbs {
+ font-size: 13px;
+ margin: 5px 0 0 -6px;
+ opacity: unset;
+}
+
+/* ========== 主布局 ========== */
+.content-shell {
+ width: 100%;
+ margin: 0 auto;
+ padding: 32px 16px 48px;
+ max-width: var(--container);
+}
+
+@media (min-width: 768px) {
+ .content-shell {
+ padding: 40px 24px 56px;
+ }
+}
+
+/* page.php 专用:阅读宽度收窄 */
+.content-shell--page {
+ max-width: var(--container-page, 860px);
+}
+
+.content-shell--cms {
+ max-width: 100%;
+ padding: 0;
+}
+
+/* page.php 内的元素 */
+.entry-page .entry-thumb {
+ margin: 0 0 var(--space-6, 24px);
+ border-radius: var(--radius-lg, 12px);
+ overflow: hidden;
+}
+
+.entry-page .page-links {
+ margin-top: var(--space-6, 24px);
+ font-size: var(--text-sm, 0.875rem);
+ color: var(--color-ink-3, var(--color-ink-3));
+}
+
+.entry-page .page-links-title {
+ margin-right: 8px;
+ font-weight: 600;
+}
+
+.content-layout {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 20px;
+ align-items: start;
+}
+
+@media (min-width: 992px) {
+ .content-layout {
+ grid-template-columns: minmax(0, 1fr) var(--sidebar-width, 311px);
+ gap: 20px;
+ }
+}
+
+.content-layout__primary {
+ min-width: 0;
+}
+
+.content-layout__aside {
+ min-width: 0;
+}
+
+@media (min-width: 992px) {
+ .content-layout__aside {
+ position: sticky;
+ top: calc(var(--nav-height, 60px) + 16px);
+ align-self: start;
+ }
+
+ /* WordPress Admin Bar 已全局禁用,无需偏移规则 */
+}
+
+@media (min-width: 992px) {
+ .has-static-nav .content-layout__aside {
+ top: 16px;
+ }
+}
+
+.content-layout--no-sidebar {
+ grid-template-columns: 1fr;
+}
+
+.content-layout--no-sidebar .content-layout__primary {
+ width: 100%;
+ max-width: var(--content-no-sidebar-max, 1080px);
+ margin: 0 auto;
+}
+
+/* 三栏布局变体:侧边栏在左侧 */
+@media (min-width: 992px) {
+ .content-layout--sidebar-left {
+ grid-template-columns: var(--sidebar-width, 311px) minmax(0, 1fr);
+ }
+
+ .content-layout--sidebar-left .content-layout__aside {
+ order: -1;
+ }
+}
+
+/* ========== 页面标题区 ========== */
+.page-header {
+ margin-bottom: 28px;
+}
+
+.page-header .entry-title {
+ margin-bottom: 8px;
+}
+
+.page-header p {
+ color: var(--color-ink-3);
+ margin: 0;
+ max-width: 720px;
+}
+
+.term-page-header {
+ position: relative;
+ overflow: hidden;
+ border: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.08));
+ border-radius: var(--radius-lg);
+ background: var(--surface-1);
+ box-shadow: var(--shadow-sm, 0 1px 6px rgba(15, 23, 42, 0.04));
+}
+
+.term-page-header__body {
+ position: relative;
+ z-index: 1;
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 16px;
+ padding: 24px;
+}
+
+.term-page-header__eyebrow {
+ margin: 0 0 8px;
+ font-size: 0.8125rem;
+ font-weight: 700;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ color: var(--color-primary);
+}
+
+.term-page-header__desc {
+ margin-top: 10px;
+}
+
+.term-page-header__cover {
+ min-height: 140px;
+ background-position: center;
+ background-size: cover;
+ border-top: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.08));
+}
+
+.term-page-header--simple .term-page-header__cover {
+ display: none;
+}
+
+/* Card style: accent top border, slightly more padding */
+.term-page-header--card {
+ border-top: 3px solid var(--color-primary, #f04494);
+}
+
+.term-page-header--card .term-page-header__body {
+ padding: 28px 24px;
+}
+
+/* Cover style: full-width hero with background image */
+.term-page-header--cover {
+ border: none;
+ border-radius: var(--radius-lg);
+ background: transparent;
+ box-shadow: none;
+ min-height: 220px;
+ display: flex;
+ flex-direction: column;
+}
+
+.term-page-header__cover-bg {
+ position: absolute;
+ inset: 0;
+ background-position: center;
+ background-size: cover;
+ border-radius: var(--radius-lg);
+}
+
+.term-page-header__cover-overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(135deg, rgba(0, 0, 0, 0.55) 0%, rgba(0, 0, 0, 0.25) 100%);
+ border-radius: var(--radius-lg);
+}
+
+.term-page-header--cover .term-page-header__body {
+ flex: 1;
+ align-items: flex-end;
+ z-index: 2;
+}
+
+.term-page-header__body--overlay .entry-title,
+.term-page-header__body--overlay .term-page-header__desc,
+.term-page-header__body--overlay .term-page-header__eyebrow {
+ color: #fff;
+}
+
+.term-page-header__body--overlay .term-page-header__eyebrow {
+ color: rgba(255, 255, 255, 0.8);
+}
+
+@media (max-width: 767px) {
+ .term-page-header--cover {
+ min-height: 160px;
+ }
+}
+
+.aksrt-admin-quicklink {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ min-height: 36px;
+ padding: 0 14px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-2);
+ color: var(--color-ink-2);
+ text-decoration: none;
+ white-space: nowrap;
+ font-size: 0.875rem;
+ font-weight: 600;
+}
+
+.aksrt-admin-quicklink:hover {
+ color: var(--color-primary);
+ border-color: var(--color-primary);
+ background: var(--color-primary-soft, rgba(59, 130, 246, 0.08));
+}
+
+.archive-filter-bar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 16px;
+ flex-wrap: wrap;
+ margin: -8px 0 24px;
+ padding: 16px 18px;
+ border-radius: var(--radius-lg);
+ background: var(--surface-2);
+ border: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.06));
+}
+
+.archive-filter-bar__main {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ flex-wrap: wrap;
+}
+
+.archive-filter-bar__label {
+ color: var(--color-ink-4);
+ font-size: 0.8125rem;
+ font-weight: 600;
+}
+
+.archive-filter-bar__chips {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.archive-filter-bar__chip {
+ display: inline-flex;
+ align-items: center;
+ min-height: 34px;
+ padding: 0 12px;
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-1);
+ color: var(--color-ink-2);
+ text-decoration: none;
+ font-size: 0.875rem;
+ font-weight: 500;
+}
+
+.archive-filter-bar__chip.is-active,
+.archive-filter-bar__chip:hover {
+ background: var(--color-primary);
+ color: var(--color-on-primary, #fff);
+}
+
+.archive-filter-bar__meta {
+ color: var(--color-ink-4);
+ font-size: 0.8125rem;
+ font-weight: 600;
+}
+
+.archive-filter-bar__sort {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-left: auto;
+}
+
+.archive-filter-bar__main--tags {
+ border-top: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.06));
+ padding-top: 10px;
+ margin-top: 10px;
+}
+
+/* §3.4 custom_filter dimension rows */
+.archive-filter-bar__main--custom {
+ border-top: 1px solid var(--color-line-soft, rgba(15, 23, 42, 0.06));
+ padding-top: 10px;
+ margin-top: 10px;
+}
+
+/* AJAX 筛选加载状态 */
+.archive__ajax-wrap {
+ position: relative;
+ transition: opacity 0.2s ease;
+}
+
+.archive__ajax-wrap.is-loading {
+ opacity: 0.5;
+ pointer-events: none;
+}
+
+.archive__ajax-loading {
+ display: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ align-items: center;
+ justify-content: center;
+ z-index: 5;
+ background: rgba(255, 255, 255, 0.6);
+ backdrop-filter: blur(1px);
+}
+
+.archive__ajax-loading.is-loading {
+ display: flex;
+}
+
+.archive__ajax-spinner {
+ display: inline-block;
+ width: 28px;
+ height: 28px;
+ border: 3px solid var(--surface-3, #e8e8e8);
+ border-top-color: var(--color-primary, #f04494);
+ border-radius: 50%;
+ animation: aksrt-spin 0.6s linear infinite;
+}
+
+@media (max-width: 767px) {
+ .term-page-header__body {
+ flex-direction: column;
+ align-items: stretch;
+ padding: 20px;
+ }
+
+ .aksrt-admin-quicklink {
+ width: fit-content;
+ }
+}
+
+/* ========== AJAX 分页(加载更多 / 无限滚动) ========== */
+.aksrt-pagination-ajax {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 16px;
+ margin: 40px 0 8px;
+}
+
+.aksrt-load-more-btn {
+ min-width: 180px;
+ height: 44px;
+ padding: 0 32px;
+ border-radius: var(--radius-btn);
+ border: 1px solid var(--color-line);
+ background: var(--surface-page);
+ color: var(--color-ink);
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: border-color 0.2s, color 0.2s, background 0.2s;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+}
+
+.aksrt-load-more-btn:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.aksrt-load-more-btn:disabled {
+ opacity: 0.5;
+ pointer-events: none;
+}
+
+.aksrt-loading-indicator {
+ display: none;
+ align-items: center;
+ gap: 8px;
+ font-size: 14px;
+ color: var(--color-ink-4);
+}
+
+.aksrt-loading-indicator i {
+ font-size: 16px;
+}
+
+.aksrt-scroll-sentinel {
+ width: 100%;
+ height: 1px;
+ pointer-events: none;
+}
+
+/* ========== 移动端/平板隐藏侧栏(与 zibll 一致:991px 以下隐藏) ========== */
+@media (max-width: 991px) {
+ .content-layout__aside {
+ display: none;
+ }
+}
+
+/* CMS 模块在侧栏布局中的适配 */
+.content-layout__primary--cms {
+ min-width: 0;
+}
+
+.content-layout__primary--cms .home-modules {
+ gap: var(--space-7, 32px);
+}
+
+.content-layout__primary--cms .home-modules > .home-module {
+ max-width: 100%;
+ padding-left: 0;
+ padding-right: 0;
+}
+
+/* ============================================================
+ * Phase 2 — 背景遮罩层级修正
+ * body.aksrt-bg-overlay 的 ::before 需要 z-index: -1 让内容在其上方
+ * ============================================================ */
+body.aksrt-bg-overlay {
+ position: relative;
+}
+
+body.aksrt-bg-overlay::before {
+ z-index: -1;
+}
+
+body.aksrt-bg-overlay .site-wrapper {
+ position: relative;
+ z-index: 0;
+}
+
+/* ============================================================
+ * Phase 2 — 侧栏 widget 内链接增强
+ * ============================================================ */
+.content-layout__aside .widget a {
+ transition: color var(--dur-fast, 0.15s) var(--ease);
+}
+
+.content-layout__aside .widget a:hover {
+ color: var(--color-primary);
+}
+
+/* ============================================================
+ * Phase 5 — 文章操作卡片增强
+ * ============================================================ */
+
+/* ============================================================
+ * Phase 6 — 评论卡片容器
+ * ============================================================ */
+.comments-card {
+ overflow: hidden;
+}
diff --git a/assets/css/frontend/menu-decorations.css b/assets/css/frontend/menu-decorations.css
new file mode 100644
index 00000000..82554756
--- /dev/null
+++ b/assets/css/frontend/menu-decorations.css
@@ -0,0 +1,280 @@
+/**
+ * AKSRT Menu Decorations
+ *
+ * 菜单图标、徽章、多列下拉、图文卡片子菜单样式。
+ * 所有选择器均带 aksrt- 或 .site-nav 命名空间。
+ */
+
+/* ========== 菜单图标 ========== */
+.nav-desktop .menu-item > a .menu-icon,
+.nav-desktop .menu-item > a > i:first-child {
+ display: inline-flex;
+ align-items: center;
+ margin-right: 6px;
+ font-size: 14px;
+ opacity: 0.75;
+ transition: opacity 0.2s ease;
+}
+
+.nav-desktop .menu-item:hover > a .menu-icon,
+.nav-desktop .menu-item:hover > a > i:first-child {
+ opacity: 1;
+}
+
+/* ========== 菜单徽章 ========== */
+.nav-desktop .menu-item > a .menu-badge,
+.nav-desktop .menu-item > a .aksrt-menu-badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ margin-left: 6px;
+ padding: 1px 6px;
+ font-size: 10px;
+ font-weight: 700;
+ line-height: 1.4;
+ letter-spacing: 0.02em;
+ border-radius: 8px;
+ white-space: nowrap;
+ vertical-align: middle;
+ transform: translateY(-1px);
+}
+
+.aksrt-menu-badge--new {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+.aksrt-menu-badge--hot {
+ background: #ff4d4f;
+ color: #fff;
+}
+
+.aksrt-menu-badge--info {
+ background: var(--color-info, #1890ff);
+ color: #fff;
+}
+
+.aksrt-menu-badge--success {
+ background: var(--color-success, #52c41a);
+ color: #fff;
+}
+
+.aksrt-menu-badge--warning {
+ background: var(--color-warning, #faad14);
+ color: #fff;
+}
+
+/* ========== Hover 效果 ========== */
+/* 下划线效果 */
+.aksrt-menu-hover--underline .nav-desktop .menu-item > a {
+ position: relative;
+}
+
+.aksrt-menu-hover--underline .nav-desktop .menu-item > a::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ width: 0;
+ height: 2px;
+ background: var(--color-primary);
+ border-radius: 1px;
+ transform: translateX(-50%);
+ transition: width 0.25s ease;
+}
+
+.aksrt-menu-hover--underline .nav-desktop .menu-item:hover > a::after,
+.aksrt-menu-hover--underline .nav-desktop .menu-item.current-menu-item > a::after,
+.aksrt-menu-hover--underline .nav-desktop .menu-item.current_page_item > a::after {
+ width: 70%;
+}
+
+/* 背景色效果 */
+.aksrt-menu-hover--background .nav-desktop .menu-item > a {
+ border-radius: 6px;
+ transition: background-color 0.2s ease;
+}
+
+.aksrt-menu-hover--background .nav-desktop .menu-item:hover > a {
+ background-color: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+}
+
+/* 文字变色效果 */
+.aksrt-menu-hover--color .nav-desktop .menu-item > a {
+ transition: color 0.2s ease;
+}
+
+.aksrt-menu-hover--color .nav-desktop .menu-item:hover > a {
+ color: var(--color-primary);
+}
+
+/* ========== 多列 Mega 下拉 ========== */
+.nav-desktop .menu-item .aksrt-mega-submenu {
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ z-index: 999;
+ min-width: var(--aksrt-mega-width, 480px);
+ padding: 16px 20px;
+ background: var(--surface-page, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+ opacity: 0;
+ visibility: hidden;
+ transform: translateX(-50%) translateY(8px);
+ transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
+}
+
+.nav-desktop .menu-item:hover .aksrt-mega-submenu {
+ opacity: 1;
+ visibility: visible;
+ transform: translateX(-50%) translateY(0);
+}
+
+.aksrt-mega-submenu__grid {
+ display: grid;
+ gap: 12px;
+}
+
+.aksrt-mega-submenu__grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
+.aksrt-mega-submenu__grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
+.aksrt-mega-submenu__grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
+.aksrt-mega-submenu__grid--cols-5 { grid-template-columns: repeat(5, 1fr); }
+
+.aksrt-mega-submenu__item {
+ display: flex;
+ align-items: flex-start;
+ gap: 10px;
+ padding: 10px 12px;
+ border-radius: 6px;
+ text-decoration: none;
+ color: var(--color-ink);
+ transition: background-color 0.15s ease;
+}
+
+.aksrt-mega-submenu__item:hover {
+ background-color: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+}
+
+.aksrt-mega-submenu__item-icon {
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ height: 32px;
+ border-radius: 6px;
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+ color: var(--color-primary);
+ font-size: 14px;
+}
+
+.aksrt-mega-submenu__item-content {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-mega-submenu__item-title {
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 1.4;
+ color: var(--color-ink);
+}
+
+.aksrt-mega-submenu__item-desc {
+ margin-top: 2px;
+ font-size: 12px;
+ line-height: 1.4;
+ color: var(--text-tertiary, #8a909c);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+/* ========== 图文卡片子菜单 ========== */
+.nav-desktop .menu-item .aksrt-card-submenu {
+ position: absolute;
+ top: 100%;
+ left: 50%;
+ z-index: 999;
+ display: flex;
+ gap: 12px;
+ padding: 16px;
+ background: var(--surface-page, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
+ opacity: 0;
+ visibility: hidden;
+ transform: translateX(-50%) translateY(8px);
+ transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
+}
+
+.nav-desktop .menu-item:hover .aksrt-card-submenu {
+ opacity: 1;
+ visibility: visible;
+ transform: translateX(-50%) translateY(0);
+}
+
+.aksrt-card-submenu__item {
+ display: flex;
+ flex-direction: column;
+ width: var(--aksrt-card-width, 160px);
+ text-decoration: none;
+ border-radius: 8px;
+ overflow: hidden;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+}
+
+.aksrt-card-submenu__item:hover {
+ transform: none;
+ box-shadow: none;
+}
+
+.aksrt-card-submenu__thumb {
+ width: 100%;
+ aspect-ratio: 16 / 10;
+ object-fit: cover;
+ background: var(--color-fill, #f5f5f5);
+}
+
+.aksrt-card-submenu__body {
+ padding: 8px 10px;
+}
+
+.aksrt-card-submenu__title {
+ font-size: 13px;
+ font-weight: 500;
+ line-height: 1.4;
+ color: var(--color-ink);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.aksrt-card-submenu__desc {
+ margin-top: 2px;
+ font-size: 11px;
+ line-height: 1.4;
+ color: var(--text-tertiary, #8a909c);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+/* ========== 暗色模式适配 ========== */
+html.dark .aksrt-mega-submenu,
+body.dark-theme .aksrt-mega-submenu,
+html.dark .aksrt-card-submenu,
+body.dark-theme .aksrt-card-submenu {
+ background: var(--surface-page);
+ border-color: var(--color-line, #2d2d3f);
+}
+
+html.dark .aksrt-mega-submenu__item-title,
+body.dark-theme .aksrt-mega-submenu__item-title,
+html.dark .aksrt-card-submenu__title,
+body.dark-theme .aksrt-card-submenu__title {
+ color: var(--color-ink);
+}
diff --git a/assets/css/frontend/messages.css b/assets/css/frontend/messages.css
new file mode 100644
index 00000000..f05eba2b
--- /dev/null
+++ b/assets/css/frontend/messages.css
@@ -0,0 +1,580 @@
+/* ============================================================
+ * Messages Center — 独立消息中心页面
+ * ============================================================ */
+
+.messages-center {
+ display: grid;
+ grid-template-columns: 220px 1fr;
+ gap: 24px;
+ min-height: 60vh;
+ padding-top: 24px;
+ padding-bottom: 48px;
+}
+
+/* ---- 左侧导航 ---- */
+.messages-center__nav {
+ position: sticky;
+ top: calc(var(--nav-height, 60px) + 24px);
+ align-self: start;
+ background: var(--surface-card, #fff);
+ border-radius: 12px;
+ padding: 16px 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.messages-nav__list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.messages-nav__item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px 12px;
+ border-radius: 8px;
+ color: var(--color-ink);
+ text-decoration: none;
+ font-size: 14px;
+ transition: background 0.15s, color 0.15s;
+ cursor: pointer;
+}
+
+.messages-nav__item:hover {
+ background: var(--surface-hover, rgba(0, 0, 0, 0.04));
+}
+
+.messages-nav__item.is-active {
+ background: var(--color-primary-light, rgba(59, 130, 246, 0.08));
+ color: var(--color-primary, #3b82f6);
+ font-weight: 600;
+}
+
+.messages-nav__badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 20px;
+ height: 20px;
+ padding: 0 6px;
+ border-radius: 10px;
+ background: var(--color-primary, #3b82f6);
+ color: #fff;
+ font-size: 11px;
+ font-weight: 600;
+ line-height: 1;
+}
+
+.messages-nav__badge:empty,
+.messages-nav__badge[data-count="0"] {
+ display: none;
+}
+
+.messages-nav__actions {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ margin-top: 16px;
+ padding-top: 12px;
+ border-top: 1px solid var(--color-line);
+}
+
+.messages-nav__action-btn {
+ display: block;
+ width: 100%;
+ padding: 8px 12px;
+ border: none;
+ border-radius: 6px;
+ background: var(--surface-hover, rgba(0, 0, 0, 0.04));
+ color: var(--color-ink-3, #666);
+ font-size: 13px;
+ cursor: pointer;
+ text-align: center;
+ transition: background 0.15s;
+}
+
+.messages-nav__action-btn:hover {
+ background: var(--surface-active, rgba(0, 0, 0, 0.08));
+}
+
+/* ---- 右侧内容 ---- */
+.messages-center__content {
+ min-width: 0;
+}
+
+.messages-list {
+ display: flex;
+ flex-direction: column;
+ gap: 1px;
+ background: var(--surface-card, #fff);
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.message-item {
+ display: flex;
+ align-items: flex-start;
+ gap: 12px;
+ padding: 16px 20px;
+ background: var(--surface-card, #fff);
+ border-bottom: 1px solid var(--color-border-light, #f3f4f6);
+ transition: background 0.15s;
+}
+
+.message-item:last-child {
+ border-bottom: none;
+}
+
+.message-item:hover {
+ background: var(--surface-hover, rgba(0, 0, 0, 0.02));
+}
+
+.message-item.is-unread {
+ border-left: 3px solid var(--color-primary, #3b82f6);
+}
+
+.message-item.is-unread .message-item__title {
+ font-weight: 600;
+}
+
+.message-item__icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ height: 36px;
+ min-width: 36px;
+ border-radius: 50%;
+ background: var(--color-primary-light, rgba(59, 130, 246, 0.1));
+ color: var(--color-primary, #3b82f6);
+ font-size: 14px;
+}
+
+.message-item__body {
+ flex: 1;
+ min-width: 0;
+}
+
+.message-item__title {
+ font-size: 14px;
+ color: var(--color-ink);
+ margin-bottom: 4px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.message-item__new-badge {
+ display: inline-block;
+ padding: 1px 6px;
+ border-radius: 3px;
+ background: var(--color-danger, #ef4444);
+ color: #fff;
+ font-size: 10px;
+ font-weight: 600;
+ line-height: 1.4;
+}
+
+.message-item__desc {
+ font-size: 13px;
+ color: var(--color-ink-3, #666);
+ margin-bottom: 4px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.message-item__time {
+ font-size: 12px;
+ color: var(--color-ink-4, #999);
+}
+
+.message-item__actions {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-shrink: 0;
+}
+
+.message-item__action-btn {
+ padding: 4px 10px;
+ border: none;
+ border-radius: 4px;
+ background: transparent;
+ color: var(--color-ink-3, #666);
+ font-size: 12px;
+ cursor: pointer;
+ transition: background 0.15s, color 0.15s;
+}
+
+.message-item__action-btn:hover {
+ background: var(--surface-hover, rgba(0, 0, 0, 0.06));
+ color: var(--color-primary, #3b82f6);
+}
+
+.message-item__action-btn--danger:hover {
+ color: var(--color-danger, #ef4444);
+}
+
+/* ---- 空状态 ---- */
+.messages-empty {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 64px 24px;
+ background: var(--surface-card, #fff);
+ border-radius: 12px;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.messages-empty__icon {
+ font-size: 48px;
+ color: var(--color-ink-4, #ccc);
+ margin-bottom: 16px;
+}
+
+.messages-empty__text {
+ font-size: 14px;
+ color: var(--color-ink-3, #666);
+}
+
+.messages-empty__hint {
+ margin-top: 4px;
+ font-size: 12px;
+ color: var(--color-ink-4, #999);
+}
+
+/* ---- 分页 ---- */
+.messages-pagination {
+ display: flex;
+ justify-content: center;
+ gap: 8px;
+ margin-top: 24px;
+}
+
+/* ---- 响应式 ---- */
+@media (max-width: 767px) {
+ .messages-center {
+ grid-template-columns: 1fr;
+ gap: 16px;
+ padding-top: 16px;
+ }
+
+ .messages-center__nav {
+ position: static;
+ padding: 12px;
+ border-radius: 8px;
+ }
+
+ .messages-nav__list {
+ display: flex;
+ overflow-x: auto;
+ gap: 4px;
+ scrollbar-width: none;
+ }
+
+ .messages-nav__list::-webkit-scrollbar {
+ display: none;
+ }
+
+ .messages-nav__item {
+ white-space: nowrap;
+ padding: 8px 12px;
+ font-size: 13px;
+ border-radius: 20px;
+ }
+
+ .messages-nav__actions {
+ flex-direction: row;
+ margin-top: 12px;
+ padding-top: 10px;
+ }
+
+ .message-item {
+ padding: 12px 14px;
+ }
+
+ .message-item__actions {
+ flex-direction: column;
+ gap: 4px;
+ }
+}
+
+/* ---- 暗色模式 ---- */
+html.dark .messages-center__nav,
+html.dark .messages-center__nav {
+ background: var(--surface-1);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+}
+
+html.dark .messages-nav__item:hover,
+html.dark .messages-nav__item:hover {
+ background: rgba(255, 255, 255, 0.05);
+}
+
+html.dark .messages-nav__item.is-active,
+html.dark .messages-nav__item.is-active {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.16));
+}
+
+html.dark .messages-nav__action-btn,
+html.dark .messages-nav__action-btn {
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+}
+
+html.dark .messages-nav__action-btn:hover,
+html.dark .messages-nav__action-btn:hover {
+ background: var(--surface-3);
+}
+
+html.dark .messages-list,
+html.dark .messages-list {
+ background: var(--surface-1);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+}
+
+html.dark .message-item,
+html.dark .message-item {
+ background: var(--surface-1);
+ border-bottom-color: var(--color-line);
+}
+
+html.dark .message-item:hover,
+html.dark .message-item:hover {
+ background: var(--surface-2);
+}
+
+html.dark .message-item__icon,
+html.dark .message-item__icon {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.16));
+}
+
+html.dark .message-item__action-btn:hover,
+html.dark .message-item__action-btn:hover {
+ background: var(--surface-3);
+}
+
+html.dark .messages-empty,
+html.dark .messages-empty {
+ background: var(--surface-1);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
+}
+
+html.dark .messages-nav__actions,
+html.dark .messages-nav__actions {
+ border-top-color: var(--color-line);
+}
+
+/* ============================================================
+ * Private Messages / Conversations
+ * ============================================================ */
+
+.aksrt-pm__list {
+ display: flex;
+ flex-direction: column;
+}
+
+.aksrt-pm__item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 14px 16px;
+ cursor: pointer;
+ border-bottom: 1px solid var(--color-line, #f0f0f0);
+ transition: background 0.15s;
+}
+
+.aksrt-pm__item:hover {
+ background: var(--surface-1, #f8f9fa);
+}
+
+.aksrt-pm__item.is-unread {
+ background: var(--surface-2, #f0f5ff);
+}
+
+.aksrt-pm__avatar {
+ width: 44px;
+ height: 44px;
+ border-radius: 50%;
+ object-fit: cover;
+ flex-shrink: 0;
+}
+
+.aksrt-pm__info {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-pm__name {
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--color-ink);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.aksrt-pm__badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 18px;
+ height: 18px;
+ border-radius: 9px;
+ background: var(--color-primary);
+ color: #fff;
+ font-size: 11px;
+ font-weight: 600;
+ padding: 0 5px;
+}
+
+.aksrt-pm__preview {
+ font-size: 12px;
+ color: var(--text-secondary, #8a909c);
+ margin-top: 3px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.aksrt-pm__time {
+ font-size: 11px;
+ color: var(--text-tertiary, #c0c4cc);
+ flex-shrink: 0;
+}
+
+/* Thread view */
+.aksrt-pm__thread {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ min-height: 400px;
+}
+
+.aksrt-pm__thread-header {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 12px 16px;
+ border-bottom: 1px solid var(--color-line, #f0f0f0);
+}
+
+.aksrt-pm__back-btn {
+ background: none;
+ border: none;
+ color: var(--color-primary);
+ cursor: pointer;
+ font-size: 13px;
+ padding: 4px 8px;
+ border-radius: 4px;
+}
+
+.aksrt-pm__back-btn:hover {
+ background: var(--surface-1, #f0f5ff);
+}
+
+.aksrt-pm__thread-name {
+ font-size: 15px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-pm__messages {
+ flex: 1;
+ overflow-y: auto;
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.aksrt-pm__msg {
+ display: flex;
+ max-width: 75%;
+}
+
+.aksrt-pm__msg--mine {
+ align-self: flex-end;
+}
+
+.aksrt-pm__msg--mine .aksrt-pm__msg-bubble {
+ background: var(--color-primary);
+ color: #fff;
+ border-radius: 12px 12px 4px 12px;
+}
+
+.aksrt-pm__msg:not(.aksrt-pm__msg--mine) .aksrt-pm__msg-bubble {
+ background: var(--surface-2, #f0f0f0);
+ color: var(--color-ink);
+ border-radius: 12px 12px 12px 4px;
+}
+
+.aksrt-pm__msg-bubble {
+ padding: 10px 14px;
+ font-size: 14px;
+ line-height: 1.5;
+ word-break: break-word;
+}
+
+.aksrt-pm__msg-time {
+ font-size: 11px;
+ margin-top: 4px;
+ opacity: 0.6;
+}
+
+.aksrt-pm__compose {
+ display: flex;
+ align-items: flex-end;
+ gap: 8px;
+ padding: 12px 16px;
+ border-top: 1px solid var(--color-line, #f0f0f0);
+}
+
+.aksrt-pm__compose textarea {
+ flex: 1;
+ border: 1px solid var(--color-line, #d9d9d9);
+ border-radius: 8px;
+ padding: 8px 12px;
+ font-size: 14px;
+ resize: none;
+ outline: none;
+ font-family: inherit;
+}
+
+.aksrt-pm__compose textarea:focus {
+ border-color: var(--color-primary);
+}
+
+.aksrt-pm__send-btn {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ border: none;
+ background: var(--color-primary);
+ color: #fff;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ transition: opacity 0.15s;
+}
+
+.aksrt-pm__send-btn:hover {
+ opacity: 0.85;
+}
+
+/* Dark mode */
+html.dark .aksrt-pm__item:hover,
+html.dark .aksrt-pm__item:hover {
+ background: var(--surface-2);
+}
+
+html.dark .aksrt-pm__item.is-unread,
+html.dark .aksrt-pm__item.is-unread {
+ background: rgba(240, 68, 148, 0.08);
+}
diff --git a/assets/css/frontend/nav.css b/assets/css/frontend/nav.css
new file mode 100644
index 00000000..01861f5b
--- /dev/null
+++ b/assets/css/frontend/nav.css
@@ -0,0 +1,12 @@
+@import url("nav/base.css");
+@import url("nav/dark-mode-submenu.css");
+@import url("nav/dark-mode-mega-menu.css");
+@import url("nav/responsive-mega-menu.css");
+@import url("nav/mobile-toggle.css");
+@import url("nav/mobile-theme-toggle-in-drawer.css");
+@import url("nav/menu-item-icon.css");
+@import url("nav/menu-item-badge.css");
+@import url("nav/hover-effects.css");
+@import url("nav/mega-submenu.css");
+@import url("nav/cards-submenu.css");
+@import url("nav/nav-fixed-mobile-fallback.css");
diff --git a/assets/css/frontend/nav/base.css b/assets/css/frontend/nav/base.css
new file mode 100644
index 00000000..357f4dd6
--- /dev/null
+++ b/assets/css/frontend/nav/base.css
@@ -0,0 +1,332 @@
+/* ============================================================
+ * AKSRT Navigation — Editorial v3.4
+ *
+ * - 高度 60px (--nav-h)
+ * - 字体使用 --font-ui (Inter / 思源黑体)
+ * - 主色蓝调,hover 改为 primary-soft 浅底
+ * - 永远实心:白底深字 + 1px 分隔线,滚动后追加 box-shadow
+ * - 移动端:≤768 显示汉堡菜单
+ * ============================================================ */
+
+.site-nav {
+ position: sticky;
+ top: 0;
+ z-index: 1000;
+ min-height: var(--nav-height, 60px);
+ background-color: var(--blur-bg);
+ backdrop-filter: saturate(5) blur(20px);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ transition: background-color 0.25s ease,
+ border-color 0.25s ease,
+ color 0.25s ease,
+ box-shadow 0.25s ease,
+ transform 0.3s ease; /* 滚动隐藏过渡 */
+}
+
+/* 滚动隐藏头部 — 对齐 zibll .scroll-down.nav-fixed .header.scroll-down-hide */
+.site-nav.is-hidden {
+ transform: translateY(-105%);
+}
+
+.site-nav--static {
+ position: relative;
+}
+
+.site-nav--transparent {
+ background: transparent; /* 对齐 zibll .header.show-slide: 透明覆盖在 slider 上 */
+ border-bottom-color: transparent;
+}
+
+.site-nav--transparent:not(.is-scrolled) {
+ --header-color: #fff; /* 对齐 zibll --header-color:#fff */
+ color: #fff;
+}
+
+.site-nav--transparent:not(.is-scrolled) a {
+ color: inherit;
+}
+
+.site-nav--transparent.is-scrolled {
+ background: var(--blur-bg); /* 滚动后恢复毛玻璃背景 */
+ border-bottom-color: var(--color-line-soft);
+}
+
+.site-nav--blur {
+ background: var(--blur-bg);
+ backdrop-filter: saturate(5) blur(20px);
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ border-bottom-color: transparent;
+}
+
+html.dark .site-nav--transparent:not(.is-scrolled),
+html.dark .site-nav--blur:not(.is-scrolled),
+body.dark-theme .site-nav--transparent:not(.is-scrolled),
+body.dark-theme .site-nav--blur:not(.is-scrolled) {
+ background: transparent;
+ border-bottom-color: transparent;
+}
+
+html.dark .site-nav--transparent.is-scrolled,
+html.dark .site-nav--blur.is-scrolled,
+body.dark-theme .site-nav--transparent.is-scrolled,
+body.dark-theme .site-nav--blur.is-scrolled {
+ background: var(--blur-bg);
+ border-bottom-color: var(--color-line-soft);
+}
+
+/* 滚动后追加阴影 — 对齐 zibll .body-scroll .header */
+.site-nav.is-scrolled {
+ box-shadow: 0 4px 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
+}
+
+/* WordPress Admin Bar 已全局禁用,无需偏移规则 */
+
+/* ============================================================
+ * Inner / Row layout
+ * ============================================================ */
+.site-nav__inner {
+ max-width: var(--nav-max-width, var(--container));
+ margin: 0 auto;
+ padding: 0 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 0;
+}
+
+.site-nav__row {
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 12px;
+ width: 100%;
+ min-height: var(--nav-height, 60px);
+}
+
+/* ============================================================
+ * Brand
+ * ============================================================ */
+.site-brand {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ min-width: 0;
+ max-width: min(48vw, 360px);
+ padding: 7px 10px;
+ color: var(--color-ink);
+ font-size: 17px;
+ font-weight: 700;
+ letter-spacing: -0.01em;
+ flex-shrink: 0;
+ text-decoration: none;
+}
+
+.site-brand:hover {
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.site-brand--has-logo {
+ gap: 0;
+}
+
+.site-brand__logo {
+ width: 36px;
+ height: 36px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 800;
+ font-size: 13px;
+ color: var(--color-on-primary, #fff);
+ background: linear-gradient(135deg, var(--color-primary), var(--color-primary-active, var(--color-primary-dark)));
+ letter-spacing: 0.02em;
+ overflow: hidden;
+}
+
+.site-brand__media {
+ display: block;
+ flex: 0 1 auto;
+ max-width: 100%;
+ padding: 0 30px;
+ line-height: 0;
+ box-sizing: border-box;
+ background: transparent !important;
+ border: 0;
+ border-radius: 0;
+ box-shadow: none;
+ filter: none !important;
+ opacity: 1;
+}
+
+.site-brand__img {
+ display: block;
+ height: 36px;
+ width: auto;
+ max-width: 100%;
+ object-fit: contain;
+ object-position: left center;
+ background: transparent !important;
+ border-radius: 0;
+ box-shadow: none;
+ filter: none !important;
+ mix-blend-mode: normal !important;
+ opacity: 1;
+ transform: none !important;
+}
+
+.site-brand__name {
+ font-weight: 700;
+ letter-spacing: -0.01em;
+ white-space: nowrap;
+}
+
+/* Light/dark logo toggle */
+.site-brand__logo-img--dark {
+ display: none;
+}
+
+html.dark .site-brand__logo-img--light,
+[data-theme="dark"] .site-brand__logo-img--light,
+body.dark-theme .site-brand__logo-img--light {
+ display: none;
+}
+
+html.dark .site-brand__logo-img--dark,
+[data-theme="dark"] .site-brand__logo-img--dark,
+body.dark-theme .site-brand__logo-img--dark {
+ display: inline-block;
+}
+
+/* ============================================================
+ * Desktop menu
+ * ============================================================ */
+ul.nav-desktop {
+ display: none;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ align-items: center;
+ flex: 1 1 auto;
+ min-width: 0;
+}
+
+.nav-desktop--fallback {
+ display: none;
+ align-items: center;
+ flex: 1 1 auto;
+ min-width: 0;
+}
+
+ul.nav-desktop a,
+.nav-desktop--fallback a {
+ color: var(--color-ink-3);
+ font-weight: 500;
+ padding: 0 10px; /* 对齐 zibll:仅水平 padding,垂直居中靠 flex 行高 */
+ border-radius: 4px;
+ transition: color var(--dur-fast, 0.15s) var(--ease),
+ background var(--dur-fast, 0.15s) var(--ease);
+}
+
+/* Hover — 对齐 zibll: 仅变色,无背景 */
+ul.nav-desktop a:hover,
+.nav-desktop--fallback a:hover {
+ color: var(--color-primary);
+ background: transparent;
+}
+
+/* Active page — 对齐 zibll: 仅变色(指示器走下方胶囊条) */
+ul.nav-desktop .current-menu-item > a,
+ul.nav-desktop .current_page_item > a {
+ color: var(--color-primary);
+ background: transparent;
+}
+
+/* ============================================================
+ * Desktop submenu (dropdown)
+ * ============================================================ */
+ul.nav-desktop .menu-item {
+ position: relative;
+}
+
+/* 顶部 hover/current 胶囊指示器 — 对齐 zibll .navbar-nav>li:before
+ (5px 高、底部 15px 圆角,从 header 顶缘垂下)。
+ stretch 链(row→ul→li)让 li 充满 60px 行高,::before top:0 即锚定 header 顶部;
+ ::before 为 absolute 不进入 flex 流,不挤压链接。 */
+ul.nav-desktop {
+ align-self: stretch;
+}
+
+ul.nav-desktop > .menu-item {
+ align-self: stretch;
+ display: flex;
+ align-items: center;
+}
+
+ul.nav-desktop > .menu-item::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 5px;
+ background: var(--focus-color, var(--color-primary));
+ border-radius: 0 0 15px 15px;
+ opacity: 0;
+ transition: opacity 0.3s;
+ pointer-events: none;
+}
+
+ul.nav-desktop > .menu-item:hover::before,
+ul.nav-desktop > .current-menu-item::before,
+ul.nav-desktop > .current_page_item::before {
+ opacity: 1;
+}
+
+ul.nav-desktop .sub-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 998; /* 保留较高 z-index(zibll 用 99,AKSRT 栈更深,避免被覆盖) */
+ min-width: 120px;
+ list-style: none;
+ margin: 4px 0 0;
+ padding: 10px 5px;
+ background: var(--main-bg-color, #fff);
+ border: 1px solid var(--main-border-color, rgba(50, 50, 50, 0.06));
+ border-radius: var(--main-radius, 8px);
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(6px);
+ transition: opacity 0.4s ease, transform 0.4s ease, visibility 0.4s ease;
+}
+
+ul.nav-desktop .menu-item:hover > .sub-menu {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+ul.nav-desktop .sub-menu .menu-item > a {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 15px;
+ font-size: 14px;
+ border-radius: 4px;
+ white-space: nowrap;
+}
+
+ul.nav-desktop .sub-menu .menu-item > a:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+ color: var(--color-primary);
+}
+
+/* Nested submenus fly out to the right — 对齐 zibll top:-10px,去 margin-left */
+ul.nav-desktop .sub-menu .sub-menu {
+ top: -10px;
+ left: 100%;
+ margin: 0;
+}
+
diff --git a/assets/css/frontend/nav/cards-submenu.css b/assets/css/frontend/nav/cards-submenu.css
new file mode 100644
index 00000000..272b996d
--- /dev/null
+++ b/assets/css/frontend/nav/cards-submenu.css
@@ -0,0 +1,128 @@
+/* Cards submenu */
+.aksrt-nav__cards {
+ display: grid;
+ gap: 12px;
+ padding: 8px;
+}
+
+.aksrt-nav__card {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 10px 12px;
+ border-radius: 6px;
+ text-decoration: none;
+ color: inherit;
+ transition: background 0.15s;
+}
+
+.aksrt-nav__card:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.06));
+}
+
+.aksrt-nav__card-icon {
+ width: 36px;
+ height: 36px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--color-primary-soft, #e6f4ff);
+ color: var(--color-primary);
+ font-size: 16px;
+ flex-shrink: 0;
+}
+
+.aksrt-nav__card-text {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-nav__card-title {
+ font-size: 13px;
+ font-weight: 600;
+ color: var(--color-ink);
+ margin: 0;
+}
+
+.aksrt-nav__card-desc {
+ font-size: 11px;
+ color: var(--color-ink-4);
+ margin: 2px 0 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+/* ============================================================
+ * 导航溢出「更多」下拉
+ * ============================================================ */
+.aksrt-nav-more {
+ position: relative;
+}
+
+.aksrt-nav-more__btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 12px;
+ border: none;
+ background: none;
+ color: var(--color-ink-2);
+ font-size: 14px;
+ font-weight: 500;
+ cursor: pointer;
+ border-radius: var(--radius, 8px);
+ transition: background 0.15s, color 0.15s;
+}
+
+.aksrt-nav-more__btn:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+ color: var(--color-primary);
+}
+
+.aksrt-nav-more__dropdown {
+ display: none;
+ position: absolute;
+ top: 100%;
+ right: 0;
+ min-width: 160px;
+ padding: 6px 0;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
+ border-radius: var(--radius, 8px);
+ box-shadow: var(--shadow-lg, 0 0 10px rgba(116, 116, 116, 0.12));
+ z-index: var(--z-dropdown, 100);
+ list-style: none;
+ margin: 4px 0 0;
+}
+
+.aksrt-nav-more__dropdown.is-open {
+ display: block;
+}
+
+.aksrt-nav-more__dropdown li {
+ display: block;
+}
+
+.aksrt-nav-more__dropdown li a,
+.aksrt-nav-more__dropdown li button {
+ display: block;
+ width: 100%;
+ padding: 8px 16px;
+ border: none;
+ background: none;
+ color: var(--color-ink-2);
+ font-size: 14px;
+ text-align: left;
+ text-decoration: none;
+ cursor: pointer;
+ transition: background 0.15s, color 0.15s;
+}
+
+.aksrt-nav-more__dropdown li a:hover,
+.aksrt-nav-more__dropdown li button:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+ color: var(--color-primary);
+}
+
diff --git a/assets/css/frontend/nav/dark-mode-mega-menu.css b/assets/css/frontend/nav/dark-mode-mega-menu.css
new file mode 100644
index 00000000..28994298
--- /dev/null
+++ b/assets/css/frontend/nav/dark-mode-mega-menu.css
@@ -0,0 +1,12 @@
+/* Dark mode Mega Menu */
+html.dark ul.nav-desktop .mega-menu-item > .mega-menu__panel,
+body.dark-theme ul.nav-desktop .mega-menu-item > .mega-menu__panel {
+ background: var(--surface-page);
+ border-color: var(--color-line, #2d2d3f);
+}
+
+html.dark .mega-menu__panel > .menu-item:hover,
+body.dark-theme .mega-menu__panel > .menu-item:hover {
+ background: var(--surface-2);
+}
+
diff --git a/assets/css/frontend/nav/dark-mode-submenu.css b/assets/css/frontend/nav/dark-mode-submenu.css
new file mode 100644
index 00000000..2e253195
--- /dev/null
+++ b/assets/css/frontend/nav/dark-mode-submenu.css
@@ -0,0 +1,109 @@
+/* Dark mode submenu */
+html.dark ul.nav-desktop .sub-menu,
+body.dark-theme ul.nav-desktop .sub-menu {
+ background: var(--surface-page);
+ border-color: var(--color-line, #2d2d3f);
+}
+
+/* ============================================================
+ * Mega Menu (图文超级菜单)
+ * ============================================================ */
+
+/* Mega Menu 容器:全宽定位 */
+ul.nav-desktop .mega-menu-item {
+ position: static;
+}
+
+ul.nav-desktop .mega-menu-item > .mega-menu__panel {
+ position: fixed; /* 对齐 zibll .senior-submenu: position:fixed 全视口宽 */
+ top: var(--nav-height, 60px);
+ left: 0;
+ right: 0;
+ transform: none;
+ max-width: var(--container);
+ margin: 0 auto; /* 内容区居中 */
+ padding: 20px 16px; /* 对齐 zibll 垂直 20px + 水平内边距 */
+ box-shadow: 0 10px 10px rgba(0, 0, 0, 0.05); /* 对齐 zibll shadow */
+}
+
+/* 列布局 */
+.mega-menu__columns-2 {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 8px;
+}
+
+.mega-menu__columns-3 {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 8px;
+}
+
+.mega-menu__columns-4 {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 8px;
+}
+
+.mega-menu__columns-5 {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 8px;
+}
+
+/* Mega Menu 子项(卡片样式) */
+.mega-menu__panel > .menu-item {
+ border-radius: 8px;
+ transition: background 0.15s;
+}
+
+.mega-menu__panel > .menu-item:hover {
+ background: var(--surface-2, #F4F5F7);
+}
+
+.mega-menu__panel > .menu-item > a {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 12px;
+ font-size: 14px;
+ border-radius: 8px;
+ white-space: normal;
+ line-height: 1.4;
+}
+
+.mega-menu__panel > .menu-item > a i {
+ width: 20px;
+ text-align: center;
+ color: var(--color-primary, var(--color-primary));
+ flex-shrink: 0;
+}
+
+/* 描述文字 */
+.mega-menu__item-desc {
+ display: block;
+ font-size: 12px;
+ color: var(--color-ink-4, #8A8F98);
+ margin-top: 2px;
+ line-height: 1.3;
+}
+
+/* Mega Menu 标题分组 */
+.mega-menu__panel .mega-menu__group-title {
+ grid-column: 1 / -1;
+ padding: 8px 12px 4px;
+ font-size: 12px;
+ font-weight: 600;
+ color: var(--color-ink-3);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+/* Mega Menu 底部区域(可放图片/CTA) */
+.mega-menu__panel .mega-menu__footer {
+ grid-column: 1 / -1;
+ padding: 12px 0 0;
+ margin-top: 8px;
+ border-top: 1px solid var(--color-line);
+}
+
diff --git a/assets/css/frontend/nav/hover-effects.css b/assets/css/frontend/nav/hover-effects.css
new file mode 100644
index 00000000..2e127318
--- /dev/null
+++ b/assets/css/frontend/nav/hover-effects.css
@@ -0,0 +1,35 @@
+/* Hover effects */
+.aksrt-nav__item--hover-underline > a::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ width: 0;
+ height: 2px;
+ background: var(--color-primary);
+ transition: width 0.2s ease, left 0.2s ease;
+ border-radius: 1px;
+}
+
+.aksrt-nav__item--hover-underline:hover > a::after {
+ width: 60%;
+ left: 20%;
+}
+
+.aksrt-nav__item--hover-background > a {
+ transition: background-color 0.2s;
+ border-radius: 4px;
+}
+
+.aksrt-nav__item--hover-background:hover > a {
+ background-color: var(--color-primary-soft, rgba(240, 68, 148, 0.08));
+}
+
+.aksrt-nav__item--hover-color > a {
+ transition: color 0.2s;
+}
+
+.aksrt-nav__item--hover-color:hover > a {
+ color: var(--color-primary);
+}
+
diff --git a/assets/css/frontend/nav/mega-submenu.css b/assets/css/frontend/nav/mega-submenu.css
new file mode 100644
index 00000000..d41a4464
--- /dev/null
+++ b/assets/css/frontend/nav/mega-submenu.css
@@ -0,0 +1,28 @@
+/* Mega submenu */
+.aksrt-nav__mega {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1001;
+ background: var(--surface-1);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow-lg);
+ padding: 16px;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(8px);
+ transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
+}
+
+.aksrt-nav__item:hover > .aksrt-nav__mega {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.aksrt-nav__mega--columns {
+ display: grid;
+ gap: 16px;
+}
+
diff --git a/assets/css/frontend/nav/menu-item-badge.css b/assets/css/frontend/nav/menu-item-badge.css
new file mode 100644
index 00000000..5a6b5379
--- /dev/null
+++ b/assets/css/frontend/nav/menu-item-badge.css
@@ -0,0 +1,41 @@
+/* Menu item badge */
+.aksrt-nav__badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 10px;
+ font-weight: 600;
+ line-height: 1;
+ padding: 2px 5px;
+ border-radius: 3px;
+ margin-left: 4px;
+ white-space: nowrap;
+ vertical-align: middle;
+ transform: translateY(-1px);
+}
+
+.aksrt-nav__badge--new {
+ color: #fff;
+ background: var(--color-error);
+}
+
+.aksrt-nav__badge--hot {
+ color: #fff;
+ background: var(--color-warning);
+}
+
+.aksrt-nav__badge--info {
+ color: #fff;
+ background: var(--color-info);
+}
+
+.aksrt-nav__badge--success {
+ color: #fff;
+ background: var(--color-success);
+}
+
+.aksrt-nav__badge--vip {
+ color: #fff;
+ background: linear-gradient(135deg, var(--color-warning), var(--color-error));
+}
+
diff --git a/assets/css/frontend/nav/menu-item-icon.css b/assets/css/frontend/nav/menu-item-icon.css
new file mode 100644
index 00000000..67ccce61
--- /dev/null
+++ b/assets/css/frontend/nav/menu-item-icon.css
@@ -0,0 +1,20 @@
+/* Menu item icon */
+.aksrt-nav__icon {
+ font-size: 0.85em;
+ width: 1.2em;
+ text-align: center;
+ margin-right: 4px;
+ opacity: 0.7;
+ transition: opacity 0.2s;
+}
+
+.aksrt-nav__item--has-icon > a {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.aksrt-nav__item--has-icon:hover .aksrt-nav__icon {
+ opacity: 1;
+}
+
diff --git a/assets/css/frontend/nav/mobile-theme-toggle-in-drawer.css b/assets/css/frontend/nav/mobile-theme-toggle-in-drawer.css
new file mode 100644
index 00000000..728acaf9
--- /dev/null
+++ b/assets/css/frontend/nav/mobile-theme-toggle-in-drawer.css
@@ -0,0 +1,18 @@
+/* Mobile theme toggle in drawer */
+.nav-drawer__theme-toggle {
+ padding: 0 20px 16px;
+}
+
+.nav-drawer__theme-toggle .theme-toggle-mobile {
+ width: 100%;
+ min-height: 44px;
+ justify-content: center;
+ gap: 8px;
+ display: flex;
+ align-items: center;
+}
+
+/* ============================================================
+ * Menu Decoration — Icons, Badges, Hover Effects
+ * ============================================================ */
+
diff --git a/assets/css/frontend/nav/mobile-toggle.css b/assets/css/frontend/nav/mobile-toggle.css
new file mode 100644
index 00000000..24f200a8
--- /dev/null
+++ b/assets/css/frontend/nav/mobile-toggle.css
@@ -0,0 +1,604 @@
+/* Mobile toggle */
+.nav-toggle {
+ display: flex;
+}
+
+@media (max-width: 991px) {
+ .site-brand {
+ max-width: min(46vw, 311px);
+ }
+
+ .site-brand__media {
+ padding: 0 8px;
+ }
+
+ .nav-publish-btn {
+ display: none;
+ }
+}
+
+/* Desktop search icon: hide on mobile (use drawer search instead) */
+@media (max-width: 767px) {
+ .site-brand {
+ max-width: min(62vw, 260px);
+ padding: 7px 0;
+ }
+
+ .site-brand__media {
+ padding: 0;
+ }
+
+ #search-toggle {
+ display: none;
+ }
+ /* Search panel only makes sense alongside the desktop search icon */
+ .nav-search-panel {
+ display: none !important;
+ }
+}
+
+@media (min-width: 768px) {
+ ul.nav-desktop,
+ .nav-desktop--fallback {
+ display: flex;
+ }
+
+ .nav-auth {
+ display: flex;
+ }
+
+ .nav-auth-dropdown {
+ display: flex;
+ }
+
+ .nav-toggle {
+ display: none;
+ }
+}
+
+/* ============================================================
+ * Header Layout Variants (desktop ≥768px)
+ * Layout 1: Standard — brand left, nav flex-1, actions right
+ * Layout 2: Centered — brand left, nav centered with flex, actions right
+ * Layout 3: Compact — brand left, nav pushed right, actions right
+ * ============================================================ */
+@media (min-width: 768px) {
+ /* Layout 2: center the nav between brand and actions */
+ body.header-layout-2 .nav-desktop {
+ flex: 1;
+ justify-content: center;
+ }
+
+ body.header-layout-2 .nav-actions {
+ flex-shrink: 0;
+ }
+
+ /* Layout 3: push nav to the right side */
+ body.header-layout-3 .site-nav__row {
+ justify-content: flex-start;
+ }
+
+ body.header-layout-3 .nav-desktop {
+ flex: 1;
+ justify-content: flex-end;
+ margin-left: 24px;
+ }
+
+ body.header-layout-3 .nav-actions {
+ margin-left: 8px;
+ }
+}
+
+.nav-mobile-strip {
+ display: none;
+ width: calc(100% + 8px);
+ margin: 0 -4px;
+ padding: 0 0 12px;
+}
+
+.nav-mobile-strip__menu,
+.nav-mobile-strip__menu ul {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ overflow-x: auto;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+}
+
+.nav-mobile-strip__menu::-webkit-scrollbar,
+.nav-mobile-strip__menu ul::-webkit-scrollbar {
+ display: none;
+}
+
+.nav-mobile-strip__menu a {
+ display: inline-flex;
+ align-items: center;
+ min-height: 34px;
+ padding: 0 12px;
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-2);
+ color: var(--color-ink-2);
+ white-space: nowrap;
+ text-decoration: none;
+ font-size: 0.875rem;
+ font-weight: 500;
+}
+
+.nav-mobile-strip__menu .current-menu-item > a,
+.nav-mobile-strip__menu .current_page_item > a {
+ background: var(--color-primary);
+ color: var(--color-on-primary, #fff);
+}
+
+@media (max-width: 767px) {
+ .nav-mobile-strip {
+ display: block;
+ }
+}
+
+/* ============================================================
+ * User avatar + dropdown
+ * ============================================================ */
+.nav-user {
+ position: relative;
+}
+
+.nav-user__toggle {
+ width: 36px;
+ height: 36px;
+ border-radius: var(--radius-avatar);
+ padding: 0;
+ border: none; /* 对齐 zibll:头像无边框 */
+ cursor: pointer;
+ overflow: hidden;
+ background: var(--surface-2);
+ transition: box-shadow var(--dur-fast, 0.15s) var(--ease);
+}
+
+.nav-user__toggle:hover {
+ box-shadow: 0 0 0 2px var(--color-primary-soft);
+}
+
+.nav-user__toggle img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+}
+
+.user-dropdown {
+ position: absolute;
+ top: calc(100% + 8px);
+ right: 0;
+ width: 260px;
+ max-width: calc(100vw - 32px);
+ padding: 12px 0;
+ background: var(--surface-1);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-lg, 8px);
+ box-shadow: var(--shadow-lg);
+ z-index: 1100;
+ opacity: 0;
+ visibility: hidden;
+ transform: translateY(-6px);
+ transition: opacity 0.2s, transform 0.2s, visibility 0.2s;
+}
+
+.user-dropdown.is-open {
+ opacity: 1;
+ visibility: visible;
+ transform: translateY(0);
+}
+
+.user-dropdown__profile {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 16px 14px;
+}
+
+.user-dropdown__profile img {
+ width: 44px;
+ height: 44px;
+ border-radius: var(--radius-avatar);
+ object-fit: cover;
+ flex-shrink: 0;
+}
+
+.user-dropdown__name {
+ font-weight: 700;
+ font-size: 0.9375rem;
+ color: var(--color-ink);
+}
+
+.user-dropdown__email {
+ font-size: 0.75rem;
+ color: var(--color-ink-4);
+ word-break: break-all;
+ margin-top: 2px;
+}
+
+.user-dropdown__sep {
+ height: 1px;
+ background: var(--color-line);
+ margin: 6px 0;
+}
+
+.user-dropdown a,
+.user-dropdown button {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ width: 100%;
+ padding: 0 16px;
+ height: 44px;
+ border: none;
+ background: none;
+ font-size: 0.875rem;
+ color: var(--color-ink);
+ text-align: left;
+ cursor: pointer;
+ transition: background var(--dur-fast, 0.15s) var(--ease),
+ color var(--dur-fast, 0.15s) var(--ease);
+}
+
+.user-dropdown a:hover,
+.user-dropdown button:hover {
+ background: var(--surface-3);
+ color: var(--color-primary-active);
+}
+
+/* dropdown 项内的 SVG 图标 */
+.user-dropdown__item svg {
+ width: 16px;
+ height: 16px;
+ flex-shrink: 0;
+ opacity: 0.85;
+}
+
+.user-dropdown__item span:first-of-type:not(.user-dropdown__pill) {
+ flex: 1;
+ min-width: 0;
+}
+
+/* 未读消息数 badge */
+.user-dropdown__badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 18px;
+ height: 18px;
+ padding: 0 5px;
+ margin-left: auto;
+ font-size: 11px;
+ font-weight: 600;
+ color: #fff;
+ background: var(--color-error, #ef4444);
+ border-radius: 9px;
+ line-height: 1;
+}
+
+.user-dropdown__credits {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 0 16px;
+ height: 44px;
+ font-size: 0.875rem;
+ color: var(--color-ink-2);
+}
+
+.user-dropdown__credits i {
+ color: var(--color-warning);
+ flex-shrink: 0;
+}
+
+.user-dropdown__credits-label {
+ flex: 1;
+}
+
+.user-dropdown__credits-value {
+ font-weight: 600;
+ color: var(--color-primary);
+}
+
+.user-dropdown__logout {
+ color: var(--color-error) !important;
+}
+
+.user-dropdown__logout svg {
+ color: var(--color-error);
+}
+
+.user-dropdown__logout:hover {
+ background: rgba(239, 68, 68, 0.08) !important;
+ color: var(--color-error) !important;
+}
+
+.user-dropdown .badge-dot {
+ margin-left: auto;
+ min-width: 8px;
+ height: 8px;
+ border-radius: var(--radius-pill);
+ background: var(--color-error);
+}
+
+/* ============================================================
+ * Search panel
+ * ============================================================ */
+.nav-search-panel {
+ display: none;
+ padding: 12px 0 16px;
+ border-top: 1px solid var(--color-line);
+}
+
+.nav-search-panel.is-open {
+ display: block;
+}
+
+.nav-searchbox {
+ margin: 0;
+}
+
+.nav-searchbox__field {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ min-height: 42px;
+ padding: 0 6px 0 14px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-pill, 999px);
+ background: var(--surface-3);
+ box-sizing: border-box;
+ transition: border-color var(--dur-fast, 0.15s) var(--ease), box-shadow var(--dur-fast, 0.15s) var(--ease), background var(--dur-fast, 0.15s) var(--ease);
+}
+
+.nav-searchbox__icon {
+ order: 1;
+ flex: 0 0 16px;
+ width: 16px;
+ height: 16px;
+ color: var(--color-ink-4);
+ pointer-events: none;
+}
+
+.nav-searchbox__input {
+ order: 2;
+ flex: 1;
+ min-width: 0;
+ width: auto;
+ height: 40px;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: var(--color-ink);
+ font-size: 0.9rem;
+ line-height: 1.2;
+ box-sizing: border-box;
+}
+
+.nav-searchbox__input:focus {
+ outline: none;
+}
+
+.nav-searchbox__input::placeholder {
+ color: var(--color-ink-4);
+}
+
+.nav-searchbox__submit {
+ order: 3;
+ flex: 0 0 auto;
+ height: 30px;
+ min-width: 64px;
+ padding: 0 14px;
+ border: 0;
+ border-radius: var(--radius-pill, 999px);
+ background: var(--color-primary);
+ color: #fff;
+ font-size: 0.8125rem;
+ font-weight: 600;
+ line-height: 1;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.nav-searchbox__field:focus-within {
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 3px var(--color-primary-soft);
+ background: var(--surface-1);
+}
+
+.nav-searchbox__submit:hover {
+ background: var(--color-primary-active);
+}
+
+/* ============================================================
+ * Mobile drawer / mobile header
+ * ============================================================ */
+.mobile-header.nav-drawer-backdrop {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.45);
+ z-index: 1200;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s ease, visibility 0.3s;
+}
+
+.mobile-header.nav-drawer-backdrop.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.mobile-header.nav-drawer {
+ position: fixed;
+ top: 0;
+ right: 0;
+ width: min(100vw, 360px);
+ height: 100vh;
+ max-height: 100dvh;
+ background: var(--surface-page);
+ z-index: 1210;
+ box-shadow: var(--shadow-drawer);
+ transform: translateX(100%);
+ transition: transform 0.32s var(--ease-out, ease);
+ display: flex;
+ flex-direction: column;
+ overflow: auto;
+ pointer-events: none;
+ visibility: hidden;
+}
+
+.mobile-header.nav-drawer.is-open {
+ transform: translateX(0);
+ pointer-events: auto;
+ visibility: visible;
+}
+
+.mobile-navbar {
+ display: flex;
+ flex-direction: column;
+ min-height: 100%;
+}
+
+.mobile-navbar .navbar-brand {
+ max-width: calc(100% - 52px);
+ padding: 7px 0;
+}
+
+.mobile-navbar .navbar-logo {
+ padding: 0;
+}
+
+.nav-drawer-backdrop {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.45);
+ z-index: 1200;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.3s ease, visibility 0.3s;
+}
+
+.nav-drawer-backdrop.is-open {
+ opacity: 1;
+ visibility: visible;
+}
+
+.nav-drawer {
+ position: fixed;
+ top: 0;
+ right: 0;
+ width: min(100vw, 360px);
+ height: 100vh;
+ max-height: 100dvh;
+ background: var(--surface-page);
+ z-index: 1210;
+ box-shadow: var(--shadow-drawer);
+ transform: translateX(100%);
+ transition: transform 0.32s var(--ease-out, ease);
+ display: flex;
+ flex-direction: column;
+ overflow: auto;
+ pointer-events: none;
+ visibility: hidden;
+}
+
+.nav-drawer.is-open {
+ transform: translateX(0);
+ pointer-events: auto;
+ visibility: visible;
+}
+
+.nav-drawer__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 16px;
+ padding: 16px 20px;
+ border-bottom: 1px solid var(--color-line);
+ font-weight: 700;
+ font-size: 1rem;
+}
+
+.site-brand--drawer {
+ max-width: calc(100% - 52px);
+ padding: 7px 0;
+}
+
+.site-brand--drawer .site-brand__media {
+ padding: 0;
+}
+
+.nav-drawer__search {
+ padding: 16px 20px 0;
+}
+
+.nav-drawer__search .nav-searchbox__field {
+ min-height: 40px;
+}
+
+.nav-drawer__search .nav-searchbox__input {
+ height: 38px;
+}
+
+.nav-drawer__search .nav-searchbox__submit {
+ height: 28px;
+ min-width: 58px;
+ padding: 0 12px;
+ font-size: 0.75rem;
+}
+
+.nav-drawer__menu {
+ flex: 1;
+ padding: 16px 20px 32px;
+}
+
+.nav-drawer__menu a {
+ display: block;
+ padding: 14px 0;
+ font-size: 1rem;
+ font-weight: 500;
+ color: var(--color-ink);
+ border-bottom: 1px solid var(--color-line-soft);
+}
+
+.nav-drawer__menu a:hover {
+ color: var(--color-primary-active);
+}
+
+.nav-drawer__menu ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.nav-drawer__auth {
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ border-top: 1px solid var(--color-line);
+}
+
+.nav-drawer__auth .btn-outline,
+.nav-drawer__auth .btn-primary {
+ width: 100%;
+ height: 44px;
+}
+
+.nav-drawer__publish {
+ padding: 0 20px 20px;
+}
+
+.nav-drawer__publish .btn-primary {
+ width: 100%;
+ min-height: 44px;
+ justify-content: center;
+ gap: 8px;
+}
+
diff --git a/assets/css/frontend/nav/nav-fixed-mobile-fallback.css b/assets/css/frontend/nav/nav-fixed-mobile-fallback.css
new file mode 100644
index 00000000..9490453e
--- /dev/null
+++ b/assets/css/frontend/nav/nav-fixed-mobile-fallback.css
@@ -0,0 +1,10 @@
+/* ===== nav_fixed mobile fallback ===== */
+/* On mobile, static nav should remain sticky so the hamburger toggle stays accessible */
+@media (max-width: 767px) {
+ .has-static-nav .site-nav--static {
+ position: sticky;
+ top: 0;
+ z-index: 1000;
+ }
+}
+
diff --git a/assets/css/frontend/nav/responsive-mega-menu.css b/assets/css/frontend/nav/responsive-mega-menu.css
new file mode 100644
index 00000000..bff4a837
--- /dev/null
+++ b/assets/css/frontend/nav/responsive-mega-menu.css
@@ -0,0 +1,106 @@
+/* Responsive Mega Menu */
+@media (max-width: 767px) {
+ ul.nav-desktop .mega-menu-item > .mega-menu__panel {
+ position: static;
+ transform: none;
+ width: 100%;
+ max-width: none;
+ margin: 0;
+ box-shadow: none;
+ }
+
+ .mega-menu__columns-2,
+ .mega-menu__columns-3,
+ .mega-menu__columns-4,
+ .mega-menu__columns-5 {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* ============================================================
+ * Right actions (icons + auth)
+ * ============================================================ */
+.nav-actions {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ flex-shrink: 0;
+ margin-left: auto;
+}
+
+.nav-settings-link,
+.nav-publish-btn {
+ flex-shrink: 0;
+}
+
+.nav-settings-link svg {
+ width: 18px;
+ height: 18px;
+}
+
+.nav-publish-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ height: 36px;
+ padding: 0 14px;
+ font-size: 0.875rem;
+ font-weight: 600;
+}
+
+.nav-publish-btn i {
+ font-size: 0.8125rem;
+}
+
+.theme-toggle.is-animating svg {
+ transform: rotate(360deg);
+}
+
+/* ============================================================
+ * Auth buttons (in nav, when logged out)
+ * ============================================================ */
+.nav-auth {
+ display: none;
+ align-items: center;
+ gap: 8px;
+}
+
+/* btn-outline / btn-primary 复用 core/buttons.css 的定义,
+ * 这里仅做导航专用调整(高度对齐、字体) */
+.nav-auth .btn-outline,
+.nav-auth .btn-primary {
+ height: 36px;
+ font-size: 0.875rem;
+ padding: 0 16px;
+}
+
+/* Auth dropdown variant (layouts 1/3) — icon trigger + panel */
+.nav-auth-dropdown {
+ position: relative;
+ display: none;
+ align-items: center;
+}
+
+.nav-auth-dropdown__trigger {
+ width: 36px;
+ height: 36px;
+}
+
+.nav-auth-dropdown__trigger svg {
+ width: 20px;
+ height: 20px;
+}
+
+.nav-auth-dropdown__panel {
+ display: none;
+ position: absolute;
+ top: calc(100% + 8px);
+ right: 0;
+ min-width: 180px;
+ z-index: 1100;
+}
+
+.nav-auth-dropdown.is-open .nav-auth-dropdown__panel {
+ display: block;
+}
+
diff --git a/assets/css/frontend/overlay-primitives.css b/assets/css/frontend/overlay-primitives.css
new file mode 100644
index 00000000..6c2c90e7
--- /dev/null
+++ b/assets/css/frontend/overlay-primitives.css
@@ -0,0 +1,78 @@
+/**
+ * AKSRT Overlay / Glass Primitives
+ *
+ * Provides backdrop-filter glass surfaces used by header, footer-tabbar,
+ * floating buttons and search overlays — matching zibll's blur system.
+ *
+ * @package AKSRT
+ */
+
+/* ============================================================
+ * .aksrt-blur-bg — generic glass surface
+ * Use on any element that needs a translucent blurred background.
+ * ============================================================ */
+.aksrt-blur-bg {
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+ background: var(--blur-bg);
+}
+
+/* ============================================================
+ * Glass on site-nav (when using fixed/sticky mode)
+ * Applied via .site-nav--blur already; this adds the zibll-grade
+ * saturate(5) blur(20px) instead of the lighter saturate(1.5) blur(18px).
+ * ============================================================ */
+.site-nav--glass {
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+ background: var(--blur-bg);
+ border-bottom-color: transparent;
+}
+
+.site-nav--glass.is-scrolled {
+ box-shadow: 0 4px 10px rgba(20, 28, 48, 0.06);
+ border-bottom-color: var(--color-line-soft);
+}
+
+html.dark .site-nav--glass.is-scrolled,
+html.dark .site-nav--glass.is-scrolled {
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
+}
+
+/* ============================================================
+ * Glass on footer-tabbar (already uses backdrop-filter in footer.css;
+ * this class can be toggled to match zibll's exact blur spec)
+ * ============================================================ */
+.footer-tabbar--glass {
+ -webkit-backdrop-filter: saturate(5) blur(20px);
+ backdrop-filter: saturate(5) blur(20px);
+ background: var(--blur-bg);
+ box-shadow: 0 -4px 5px rgba(20, 28, 48, 0.06);
+}
+
+html.dark .footer-tabbar--glass,
+html.dark .footer-tabbar--glass {
+ box-shadow: 0 -4px 5px rgba(0, 0, 0, 0.25);
+}
+
+/* ============================================================
+ * Glass on floating buttons (lighter blur: saturate(2) blur(10px))
+ * ============================================================ */
+.float-right--glass .float-btn {
+ -webkit-backdrop-filter: saturate(2) blur(10px);
+ backdrop-filter: saturate(2) blur(10px);
+ background: var(--float-btn-bg);
+ border-color: transparent;
+}
+
+/* ============================================================
+ * Scroll shadow on glass header (zibll: .body-scroll .header)
+ * ============================================================ */
+body.has-scrolled .site-nav--glass {
+ box-shadow: 0 4px 10px rgba(20, 28, 48, 0.06);
+}
+
+html.dark body.has-scrolled .site-nav--glass,
+html.dark body.has-scrolled .site-nav--glass {
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.25);
+}
diff --git a/assets/css/frontend/pages.css b/assets/css/frontend/pages.css
new file mode 100644
index 00000000..c6342ebc
--- /dev/null
+++ b/assets/css/frontend/pages.css
@@ -0,0 +1,5 @@
+@import url("pages/base.css");
+@import url("pages/board-cards.css");
+@import url("pages/topic-rows.css");
+@import url("pages/sidebar.css");
+@import url("pages/empty-state.css");
diff --git a/assets/css/frontend/pages/base-1.css b/assets/css/frontend/pages/base-1.css
new file mode 100644
index 00000000..9017c280
--- /dev/null
+++ b/assets/css/frontend/pages/base-1.css
@@ -0,0 +1,400 @@
+/* ========== 归档时间轴 ========== */
+.archive-timeline__group {
+ margin-bottom: 40px;
+}
+
+.archive-timeline__heading {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin-bottom: 20px;
+ font-size: 1.125rem;
+ font-weight: 700;
+}
+
+.archive-timeline__badge {
+ font-size: 12px;
+ font-weight: 600;
+ padding: 4px 10px;
+ border-radius: var(--radius-pill);
+ background: var(--color-primary-50);
+ color: var(--color-primary-dark);
+}
+
+html.dark .archive-timeline__badge,
+html.dark .archive-timeline__badge {
+ color: var(--color-primary-light);
+}
+
+/* ========== 认证页 / 表单页 ========== */
+.auth-page .site-nav__inner {
+ max-width: 100%;
+}
+
+.auth-shell {
+ min-height: calc(100vh - var(--nav-height));
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 48px 16px 64px;
+}
+
+.auth-card {
+ width: 100%;
+ max-width: 400px;
+ padding: 32px 28px;
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--color-line);
+ background: var(--surface-2);
+ box-shadow: var(--shadow-md);
+}
+
+.auth-card__logo {
+ width: 80px;
+ height: 80px;
+ margin: 0 auto 16px;
+ border-radius: var(--radius-lg);
+ background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #fff;
+ font-weight: 800;
+ font-size: 28px;
+}
+
+.auth-card__title {
+ text-align: center;
+ font-weight: 800;
+ font-size: 1.5rem;
+ margin: 0 0 4px;
+}
+
+.auth-card__subtitle {
+ text-align: center;
+ color: var(--color-ink-3);
+ font-size: 14px;
+ margin: 0 0 24px;
+}
+
+/* 绑定/登录会话过期状态 */
+.auth-card__expired {
+ text-align: center;
+ padding: var(--space-8, 40px) var(--space-5, 20px);
+}
+
+.auth-card__expired p {
+ color: var(--color-ink-3);
+ margin-bottom: var(--space-5, 20px);
+}
+
+.auth-card__expired-action {
+ display: inline-flex;
+ text-decoration: none;
+ padding: 10px 32px;
+}
+
+.form-field {
+ margin-bottom: 16px;
+ position: relative;
+}
+
+.form-field label {
+ display: block;
+ font-size: 13px;
+ font-weight: 600;
+ margin-bottom: 6px;
+ color: var(--color-ink-3);
+}
+
+.input-wrap {
+ position: relative;
+}
+
+.input-wrap .input-icon {
+ position: absolute;
+ left: 14px;
+ top: 50%;
+ transform: translateY(-50%);
+ font-size: 14px;
+ opacity: 0.6;
+ pointer-events: none;
+}
+
+.form-field input:not([type="checkbox"]) {
+ width: 100%;
+ height: 44px;
+ padding: 0 16px 0 40px;
+ border-radius: var(--radius-btn);
+ border: 1px solid var(--color-line);
+ background: var(--surface-page);
+ color: var(--color-ink);
+ font-size: 14px;
+ box-sizing: border-box;
+}
+
+.form-field input:focus {
+ outline: none;
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 3px var(--color-primary-50);
+}
+
+.form-field--pwd input {
+ padding-right: 44px;
+}
+
+.input-wrap .toggle-pwd {
+ position: absolute;
+ right: 4px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 40px;
+ height: 40px;
+ border: none;
+ background: none;
+ cursor: pointer;
+ color: var(--color-ink-4);
+}
+
+.form-row-between {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 20px;
+ font-size: 13px;
+}
+
+/* 社交登录分隔线 */
+.social-login-divider {
+ display: flex;
+ align-items: center;
+ margin: 24px 0 16px;
+ color: var(--color-ink-3, #94a3b8);
+ font-size: 13px;
+}
+.social-login-divider::before,
+.social-login-divider::after {
+ content: '';
+ flex: 1;
+ height: 1px;
+ background: var(--color-line, #e2e8f0);
+}
+.social-login-divider span {
+ padding: 0 16px;
+ white-space: nowrap;
+}
+
+.oauth-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ justify-content: center;
+ margin-top: 16px;
+}
+
+.oauth-btn {
+ width: 44px;
+ height: 44px;
+ border-radius: var(--radius-btn);
+ border: 1px solid var(--color-line);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--color-ink-3);
+ transition: border-color 0.2s, color 0.2s;
+}
+.oauth-btn svg {
+ width: 22px;
+ height: 22px;
+ display: block;
+ fill: currentColor;
+}
+
+.oauth-btn:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.auth-footer-link {
+ text-align: center;
+ margin-top: 20px;
+ font-size: 14px;
+ color: var(--color-ink-3);
+}
+
+.auth-footer-link a {
+ color: var(--color-primary);
+ font-weight: 600;
+}
+
+/* ========== 用户中心 Dashboard ========== */
+.dashboard {
+ max-width: 960px;
+ margin: 0 auto;
+}
+
+.dashboard-tabs {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 4px;
+ border-bottom: 1px solid var(--color-line);
+ margin-bottom: 24px;
+ position: sticky;
+ top: var(--nav-height);
+ z-index: 50;
+ background: var(--surface-page);
+ padding-top: 8px;
+}
+
+/* WordPress Admin Bar 已全局禁用,无需偏移规则 */
+
+.dashboard-tabs button {
+ padding: 12px 16px;
+ border: none;
+ background: none;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink-3);
+ cursor: pointer;
+ border-bottom: 2px solid transparent;
+ margin-bottom: -1px;
+ transition: color 0.2s, border-color 0.2s;
+}
+
+.dashboard-tabs__link {
+ padding: 12px 16px;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink-3);
+ text-decoration: none;
+ border-bottom: 2px solid transparent;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin-bottom: -1px;
+ transition: color 0.15s;
+}
+
+.dashboard-tabs__link:hover {
+ color: var(--color-primary);
+}
+
+.dashboard-tabs button:hover {
+ color: var(--color-ink);
+}
+
+.dashboard-tabs button.is-active {
+ color: var(--color-primary);
+ border-bottom-color: var(--color-primary);
+}
+
+@media (max-width: 767px) {
+ .dashboard-tabs button {
+ padding: 10px 12px;
+ font-size: 13px;
+ }
+ .tab-hide-mobile { display: none !important; }
+}
+
+@media (min-width: 768px) {
+ .tab-hide-pc { display: none !important; }
+}
+
+.dashboard-panel {
+ display: none;
+}
+
+.dashboard-panel.is-active {
+ display: block;
+}
+
+.data-table-wrap {
+ overflow-x: auto;
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--color-line);
+}
+
+.data-table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 14px;
+}
+
+.data-table th,
+.data-table td {
+ padding: 12px 16px;
+ text-align: left;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.data-table th {
+ background: var(--surface-3);
+ font-weight: 600;
+}
+
+.data-table tr:nth-child(even) {
+ background: var(--surface-2);
+}
+
+html.dark .data-table tr:nth-child(even),
+html.dark .data-table tr:nth-child(even) {
+ background: rgba(255, 255, 255, 0.02);
+}
+
+.notif-list {
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-lg);
+ overflow: hidden;
+}
+
+.notif-item {
+ display: flex;
+ gap: 12px;
+ padding: 16px 18px;
+ border-bottom: 1px solid var(--color-line);
+ background: var(--surface-2);
+}
+
+.notif-item:last-child {
+ border-bottom: none;
+}
+
+.notif-item--unread {
+ border-left: 3px solid var(--color-info);
+ padding-left: 15px;
+}
+
+.notif-item--unread .notif-title {
+ font-weight: 700;
+}
+
+.notif-title {
+ font-size: 14px;
+ margin: 0 0 4px;
+}
+
+.notif-meta {
+ font-size: 12px;
+ color: var(--color-ink-4);
+}
+/* ========== About / 友链 / 404 ========== */
+.about-hero {
+ max-width: 640px;
+ margin: 0 auto;
+ text-align: center;
+ padding: 24px 20px 40px;
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--color-line);
+ background: var(--surface-2);
+}
+
+.about-avatar {
+ width: 150px;
+ height: 150px;
+ border-radius: var(--radius-avatar);
+ object-fit: cover;
+ margin-bottom: 16px;
+ border: 4px solid var(--color-line);
+}
diff --git a/assets/css/frontend/pages/base-2.css b/assets/css/frontend/pages/base-2.css
new file mode 100644
index 00000000..61dda31f
--- /dev/null
+++ b/assets/css/frontend/pages/base-2.css
@@ -0,0 +1,400 @@
+
+.skill-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ justify-content: center;
+ margin-top: 16px;
+}
+
+.skill-tags span {
+ padding: 6px 12px;
+ border-radius: var(--radius-pill);
+ border: 1px solid var(--color-line);
+ font-size: 13px;
+ color: var(--color-ink-3);
+}
+
+.timeline {
+ max-width: 560px;
+ margin: 40px auto 0;
+ padding-left: 20px;
+ border-left: 2px solid var(--color-line);
+}
+
+.timeline__item {
+ position: relative;
+ padding: 0 0 24px 20px;
+}
+
+.timeline__item::before {
+ content: "";
+ position: absolute;
+ left: -27px;
+ top: 4px;
+ width: 12px;
+ height: 12px;
+ border-radius: var(--radius-avatar);
+ background: var(--color-primary);
+ border: 2px solid var(--surface-page);
+}
+
+.friends-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 20px;
+}
+
+@media (min-width: 768px) {
+ .friends-grid {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
+
+.friend-card {
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--color-line);
+ padding: 20px;
+ text-align: center;
+ background: var(--surface-2);
+ transition: transform 0.25s, box-shadow 0.25s;
+ color: inherit;
+ text-decoration: none;
+ display: block;
+}
+
+.friend-card:hover {
+ transform: translateY(-4px);
+ box-shadow: var(--shadow-md);
+ color: inherit;
+}
+
+.friend-card img {
+ width: 80px;
+ height: 80px;
+ object-fit: contain;
+ border-radius: var(--radius-btn);
+ margin-bottom: 12px;
+}
+
+.friend-card h3 {
+ font-size: 1rem;
+ margin: 0 0 8px;
+}
+
+.friend-card p {
+ font-size: 12px;
+ color: var(--color-ink-3);
+ margin: 0;
+ line-height: 1.5;
+}
+
+.error-hero {
+ text-align: center;
+ padding: 80px 20px 60px;
+ max-width: 720px;
+ margin: 0 auto;
+}
+
+.error-hero__icon {
+ font-size: 4rem;
+ margin: 0 0 8px;
+ color: var(--color-primary);
+}
+
+.error-hero__code {
+ font-size: clamp(4rem, 12vw, 7rem);
+ font-weight: 800;
+ color: var(--color-ink-4, var(--color-ink-3));
+ line-height: 1;
+ margin-bottom: 8px;
+}
+
+.error-hero__title {
+ font: 700 clamp(20px, 3vw, 28px)/1.3 var(--font-display);
+ margin: 0 0 12px;
+ color: var(--color-ink);
+}
+
+.error-hero__desc {
+ color: var(--color-ink-2);
+ max-width: 480px;
+ margin: 0 auto 28px;
+ line-height: 1.65;
+}
+
+.error-hero__search {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ max-width: 480px;
+ margin: 0 auto 24px;
+ padding: 6px 6px 6px 14px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-pill);
+ background: var(--surface-1);
+ transition: border-color .18s ease, box-shadow .18s ease;
+}
+
+.error-hero__search:focus-within {
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 3px rgba(240, 68, 148, 0.15);
+}
+
+.error-hero__search-icon {
+ color: var(--color-ink-3);
+ display: inline-flex;
+}
+
+.error-hero__search input[type="search"] {
+ flex: 1 1 auto;
+ border: 0;
+ background: transparent;
+ outline: none;
+ font: 500 14px/1 var(--font-ui);
+ color: var(--color-ink);
+ padding: 8px 0;
+}
+
+.error-hero__actions {
+ display: flex;
+ gap: 12px;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+.error-section {
+ max-width: 720px;
+ margin: 40px auto;
+ padding: 24px;
+ background: var(--surface-1);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-lg);
+}
+
+.error-section__title {
+ font: 600 16px/1.2 var(--font-ui);
+ margin: 0 0 16px;
+ color: var(--color-ink);
+}
+
+.error-section__chips {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.error-section__chip {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 12px;
+ border-radius: var(--radius-pill);
+ background: var(--surface-2);
+ color: var(--color-ink-2);
+ text-decoration: none;
+ font: 500 13px/1 var(--font-ui);
+ transition: background .18s ease, color .18s ease;
+}
+
+.error-section__chip:hover {
+ background: var(--color-primary);
+ color: var(--color-on-primary);
+}
+
+.error-section__chip span {
+ opacity: .7;
+ font-variant-numeric: tabular-nums;
+}
+
+.error-section__list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.error-section__list li + li {
+ border-top: 1px dashed var(--color-line);
+}
+
+.error-section__list a {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ padding: 12px 0;
+ color: var(--color-ink);
+ text-decoration: none;
+ transition: color .18s ease;
+}
+
+.error-section__list a:hover .error-section__list-title {
+ color: var(--color-primary);
+}
+
+.error-section__list-title {
+ flex: 1 1 auto;
+ font: 500 14px/1.4 var(--font-ui);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.error-section__list-meta {
+ flex: 0 0 auto;
+ color: var(--color-ink-3);
+ font: 500 12px/1 var(--font-ui);
+ font-variant-numeric: tabular-nums;
+}
+
+/* ============================================================
+ * 首页分类推荐模块
+ * ============================================================ */
+.category-recommend {
+ max-width: var(--container);
+ margin: 40px auto;
+ padding: 0 20px;
+}
+
+.category-recommend__header {
+ margin-bottom: 24px;
+}
+
+.category-recommend__title {
+ font-size: 24px;
+ font-weight: 700;
+ color: var(--color-ink);
+ position: relative;
+ padding-left: 16px;
+ margin: 0;
+}
+
+.category-recommend__title::before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 4px;
+ bottom: 4px;
+ width: 4px;
+ border-radius: 2px;
+ background: var(--color-primary);
+}
+
+.category-recommend__grid {
+ display: grid;
+ grid-template-columns: repeat(var(--cr-columns, 2), 1fr);
+ gap: 20px;
+}
+
+.category-recommend-card {
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-lg);
+ background: var(--surface-2);
+ overflow: hidden;
+ transition: box-shadow 0.2s ease, border-color 0.2s ease;
+}
+
+.category-recommend-card:hover {
+ box-shadow: var(--shadow-md);
+ border-color: var(--color-primary);
+}
+
+.category-recommend-card__hero {
+ position: relative;
+ aspect-ratio: 16 / 9;
+ overflow: hidden;
+ background: var(--surface-3);
+}
+
+.category-recommend-card__hero a {
+ display: block;
+ width: 100%;
+ height: 100%;
+}
+
+.category-recommend-card__cover {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+ transition: transform 0.3s ease;
+}
+
+.category-recommend-card:hover .category-recommend-card__cover {
+ transform: scale(1.02);
+}
+
+.category-recommend-card__badge {
+ position: absolute;
+ top: 12px;
+ right: 12px;
+ background: rgba(0, 0, 0, 0.6);
+ color: #fff;
+ font-size: 12px;
+ font-weight: 600;
+ padding: 4px 10px;
+ border-radius: var(--radius-pill);
+ backdrop-filter: blur(4px);
+ pointer-events: none;
+}
+
+.category-recommend-card__meta {
+ padding: 16px 16px 12px;
+}
+
+.category-recommend-card__name {
+ margin: 0 0 8px;
+ font-size: 18px;
+ font-weight: 700;
+ line-height: 1.3;
+}
+
+.category-recommend-card__name a {
+ color: var(--color-ink);
+}
+
+.category-recommend-card__name a:hover {
+ color: var(--color-primary);
+}
+
+.category-recommend-card__desc {
+ margin: 0;
+ font-size: 14px;
+ color: var(--color-ink-3);
+ line-height: 1.5;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.category-recommend-card__posts {
+ list-style: none;
+ margin: 0;
+ padding: 0 16px;
+ border-top: 1px solid var(--color-line);
+}
+
+.category-recommend-card__post-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ padding: 10px 0;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.category-recommend-card__post-item:last-child {
+ border-bottom: none;
+}
+
+.category-recommend-card__post-title {
+ flex: 1;
+ font-size: 14px;
+ color: var(--color-ink);
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ min-width: 0;
+}
+
diff --git a/assets/css/frontend/pages/base-3.css b/assets/css/frontend/pages/base-3.css
new file mode 100644
index 00000000..fc690cf4
--- /dev/null
+++ b/assets/css/frontend/pages/base-3.css
@@ -0,0 +1,193 @@
+.category-recommend-card__post-title:hover {
+ color: var(--color-primary);
+}
+
+.category-recommend-card__post-date {
+ flex-shrink: 0;
+ font-size: 12px;
+ color: var(--color-ink-4);
+}
+
+.category-recommend-card__more {
+ padding: 12px 16px;
+ text-align: center;
+ border-top: 1px solid var(--color-line);
+}
+
+.category-recommend-card__more a {
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-primary);
+ transition: color 0.15s ease;
+}
+
+.category-recommend-card__more a:hover {
+ color: var(--color-primary-dark);
+ text-decoration: underline;
+}
+
+/* 分类推荐懒加载骨架 */
+.category-recommend-card__hero .aksrt-skeleton {
+ position: absolute;
+ inset: 0;
+}
+
+.category-recommend-card__hero img.aksrt-lazy {
+ opacity: 0;
+ transition: opacity 0.3s ease;
+}
+
+.category-recommend-card__hero img.aksrt-loaded {
+ opacity: 1;
+}
+
+/* 分类推荐响应式 */
+@media (max-width: 767px) {
+ .category-recommend {
+ margin: 24px auto;
+ padding: 0 16px;
+ }
+
+ .category-recommend__title {
+ font-size: 20px;
+ }
+
+ .category-recommend__grid {
+ grid-template-columns: 1fr;
+ gap: 16px;
+ }
+
+ .category-recommend-card__name {
+ font-size: 16px;
+ }
+
+ .category-recommend-card__meta {
+ padding: 12px 14px 10px;
+ }
+
+ .category-recommend-card__posts {
+ padding: 0 14px;
+ }
+}
+
+/* ============================================================
+ * 通知"敬请期待"占位(profile dashboard)
+ * ============================================================ */
+.notif-coming-soon {
+ text-align: center;
+ padding: var(--space-9, 48px) var(--space-5, 20px) !important;
+}
+
+.notif-coming-soon__icon {
+ width: 64px;
+ height: 64px;
+ margin: 0 auto var(--space-4, 16px);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--radius-pill);
+ background: var(--color-primary-soft, var(--color-primary-50));
+ color: var(--color-primary);
+}
+
+.notif-coming-soon__icon svg {
+ width: 32px;
+ height: 32px;
+}
+
+.notif-coming-soon__title {
+ font-size: var(--text-lg, 1.25rem);
+ font-weight: 700;
+ margin: 0 0 var(--space-2, 8px);
+ color: var(--color-ink);
+}
+
+.notif-coming-soon__pill {
+ display: inline-block;
+ padding: 4px 12px;
+ margin: 0 0 var(--space-3, 12px);
+ font-size: 0.75rem;
+ font-weight: 600;
+ letter-spacing: 0.04em;
+ background: var(--color-primary-soft, var(--color-primary-50));
+ color: var(--color-primary-active, var(--color-primary-dark));
+ border-radius: var(--radius-pill);
+}
+
+.notif-coming-soon__desc {
+ max-width: 420px;
+ margin: 0 auto;
+ font-size: var(--text-sm, 0.875rem);
+ line-height: var(--leading-relaxed, 1.7);
+ color: var(--color-ink-3);
+}
+
+/* ============================================================
+ * Forum Page
+ * ============================================================ */
+
+.aksrt-forum-header {
+ padding: clamp(32px, 5vw, 64px) 0 clamp(16px, 3vw, 32px);
+ background: linear-gradient(135deg, var(--color-primary-soft, #e6f4ff) 0%, var(--surface-2, #f5f7fa) 100%);
+ margin-bottom: 32px;
+ text-align: center;
+}
+
+.aksrt-forum-header__title {
+ font: 700 clamp(28px, 4vw, 40px)/1.15 var(--font-display, inherit);
+ margin: 0 0 8px;
+ color: var(--color-ink);
+}
+
+.aksrt-forum-header__desc {
+ margin: 0 0 24px;
+ color: var(--color-ink-2, #666);
+ font-size: 15px;
+}
+
+.aksrt-forum-header__stats {
+ display: flex;
+ justify-content: center;
+ gap: 32px;
+}
+
+.aksrt-forum-header__stat-num {
+ display: block;
+ font-size: 28px;
+ font-weight: 700;
+ color: var(--color-primary);
+}
+
+.aksrt-forum-header__stat-label {
+ font-size: 13px;
+ color: var(--color-ink-3, #999);
+}
+
+.aksrt-forum__layout {
+ display: grid;
+ grid-template-columns: 1fr 280px;
+ gap: 24px;
+}
+
+@media (max-width: 1023px) {
+ .aksrt-forum__layout {
+ grid-template-columns: 1fr;
+ }
+}
+
+.aksrt-forum-section__title {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--color-ink);
+ margin: 0 0 16px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid var(--color-line, #e8e8e8);
+}
+
+.aksrt-forum-section__title i {
+ color: var(--color-primary);
+}
+
diff --git a/assets/css/frontend/pages/base.css b/assets/css/frontend/pages/base.css
new file mode 100644
index 00000000..4e615659
--- /dev/null
+++ b/assets/css/frontend/pages/base.css
@@ -0,0 +1,3 @@
+@import url("base-1.css");
+@import url("base-2.css");
+@import url("base-3.css");
diff --git a/assets/css/frontend/pages/board-cards.css b/assets/css/frontend/pages/board-cards.css
new file mode 100644
index 00000000..93fc53c6
--- /dev/null
+++ b/assets/css/frontend/pages/board-cards.css
@@ -0,0 +1,58 @@
+/* Board cards */
+.aksrt-forum-boards__grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 12px;
+ margin-bottom: 32px;
+}
+
+.aksrt-forum-board-card {
+ display: flex;
+ gap: 12px;
+ padding: 16px;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ transition: box-shadow 0.2s;
+}
+
+.aksrt-forum-board-card:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-forum-board-card__icon {
+ width: 48px;
+ height: 48px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 8px;
+ background: var(--color-primary-soft, #e6f4ff);
+ color: var(--color-primary);
+ font-size: 20px;
+ flex-shrink: 0;
+}
+
+.aksrt-forum-board-card__title {
+ margin: 0 0 4px;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-forum-board-card__desc {
+ margin: 0 0 8px;
+ font-size: 12px;
+ color: var(--color-ink-3, #999);
+ line-height: 1.5;
+}
+
+.aksrt-forum-board-card__meta {
+ font-size: 11px;
+ color: var(--color-ink-3, #999);
+}
+
+.aksrt-forum-board-card__meta i {
+ margin-right: 3px;
+}
+
diff --git a/assets/css/frontend/pages/empty-state.css b/assets/css/frontend/pages/empty-state.css
new file mode 100644
index 00000000..33ef4e63
--- /dev/null
+++ b/assets/css/frontend/pages/empty-state.css
@@ -0,0 +1,292 @@
+/* Empty state */
+.aksrt-forum__empty {
+ text-align: center;
+ padding: 48px 24px;
+ color: var(--color-ink-3, #999);
+}
+
+.aksrt-forum__empty i {
+ font-size: 48px;
+ margin-bottom: 16px;
+ opacity: 0.3;
+}
+
+.aksrt-forum-header {
+ text-align: left;
+}
+
+.aksrt-forum-header__content {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: flex-end;
+ justify-content: space-between;
+ gap: 20px;
+ width: min(1200px, calc(100% - 32px));
+ margin: 0 auto 20px;
+}
+
+.aksrt-forum-header__actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+}
+
+.aksrt-forum-header__action {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ padding: 10px 16px;
+ border-radius: 999px;
+ border: 1px solid var(--color-line, #d9e2f2);
+ background: rgba(255, 255, 255, 0.78);
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.aksrt-forum-header__action--primary {
+ border-color: var(--color-primary);
+ background: var(--color-primary);
+ color: #fff;
+}
+
+.aksrt-forum-header__stats {
+ flex-wrap: wrap;
+}
+
+.aksrt-forum-header__stat {
+ min-width: 92px;
+}
+
+.aksrt-forum-ops {
+ margin-bottom: 24px;
+}
+
+.aksrt-forum-ops__card {
+ padding: 20px;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 12px;
+}
+
+.aksrt-forum-ops__list {
+ margin: 0;
+ padding-left: 18px;
+ color: var(--color-ink-2, #666);
+ line-height: 1.7;
+}
+
+.aksrt-forum-board-card__link {
+ display: flex;
+ gap: 12px;
+ width: 100%;
+ color: inherit;
+ text-decoration: none;
+}
+
+.aksrt-forum-board-card__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+}
+
+.aksrt-forum-board-card__status {
+ display: inline-flex;
+ align-items: center;
+ padding: 2px 8px;
+ border-radius: 999px;
+ background: var(--surface-2, #f0f5ff);
+ color: var(--color-primary);
+ font-size: 11px;
+}
+
+.aksrt-forum-topic-row__title-wrap {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 6px;
+ margin-bottom: 4px;
+}
+
+.aksrt-forum-topic-row__badge {
+ display: inline-flex;
+ align-items: center;
+ padding: 2px 8px;
+ border-radius: 999px;
+ font-size: 11px;
+ font-weight: 600;
+}
+
+.aksrt-forum-topic-row__badge--sticky {
+ background: #e6f4ff;
+ color: #1677ff;
+}
+
+.aksrt-forum-topic-row__badge--featured {
+ background: #f6ffed;
+ color: #389e0d;
+}
+
+.aksrt-forum-topic-row__board {
+ color: var(--color-primary);
+ text-decoration: none;
+}
+
+.aksrt-forum-sidebar-card__empty {
+ margin: 0;
+ color: var(--color-ink-3, #999);
+ font-size: 13px;
+}
+
+.aksrt-forum-sidebar-card__item--stack {
+ display: block;
+}
+
+.aksrt-forum-sidebar-card__item--stack strong,
+.aksrt-forum-sidebar-card__item--stack span {
+ display: block;
+}
+
+@media (max-width: 767px) {
+ .aksrt-forum-header__content {
+ width: calc(100% - 24px);
+ }
+
+ .aksrt-forum-header__actions {
+ width: 100%;
+ }
+
+ .aksrt-forum-header__action {
+ width: 100%;
+ justify-content: center;
+ }
+}
+
+/* ============================================================
+ * 文章归档(page-archives.php + [aksrt_archive] 短代码)
+ * Phase 10 视觉收口:此前 .aksrt-archives 无样式。
+ * ============================================================ */
+.aksrt-archives__year {
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: var(--color-ink);
+ margin: 28px 0 12px;
+ padding-bottom: 8px;
+ border-bottom: 2px solid var(--color-line);
+}
+
+.aksrt-archives__year:first-child {
+ margin-top: 0;
+}
+
+.aksrt-archives__month {
+ font-size: 0.95rem;
+ font-weight: 600;
+ color: var(--color-ink-3, #666);
+ margin: 16px 0 8px;
+}
+
+.aksrt-archives__list {
+ list-style: none;
+ margin: 0 0 8px;
+ padding: 0;
+}
+
+.aksrt-archives__item {
+ display: flex;
+ align-items: baseline;
+ gap: 12px;
+ padding: 6px 0;
+ border-bottom: 1px dashed var(--color-line);
+}
+
+.aksrt-archives__date {
+ flex-shrink: 0;
+ font-variant-numeric: tabular-nums;
+ font-size: 0.8125rem;
+ color: var(--color-ink-4, #999);
+}
+
+.aksrt-archives__link {
+ color: var(--color-ink);
+ text-decoration: none;
+ transition: color 0.15s ease;
+}
+
+.aksrt-archives__link:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-archives--empty {
+ padding: 24px;
+ text-align: center;
+ color: var(--color-ink-4, #999);
+}
+
+/* ============================================================
+ * 个人资料卡短代码([aksrt_profile])
+ * ============================================================ */
+.aksrt-profile-card {
+ display: flex;
+ gap: 14px;
+ align-items: flex-start;
+ padding: 16px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 8px);
+ background: var(--surface-1, #fff);
+}
+
+.aksrt-profile-card--guest {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 10px;
+}
+
+.aksrt-profile-card__avatar img {
+ width: 64px;
+ height: 64px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.aksrt-profile-card__body {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-profile-card__name {
+ font-size: 1rem;
+ font-weight: 600;
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.aksrt-profile-card__name:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-profile-card__bio {
+ margin: 4px 0 8px;
+ font-size: 0.8125rem;
+ color: var(--color-ink-3, #666);
+ line-height: 1.5;
+}
+
+.aksrt-profile-card__stats {
+ display: flex;
+ gap: 18px;
+}
+
+.aksrt-profile-card__stat {
+ display: flex;
+ flex-direction: column;
+ font-size: 0.75rem;
+ color: var(--color-ink-4, #999);
+}
+
+.aksrt-profile-card__stat strong {
+ font-size: 1.05rem;
+ color: var(--color-ink);
+ line-height: 1.2;
+}
+
diff --git a/assets/css/frontend/pages/sidebar.css b/assets/css/frontend/pages/sidebar.css
new file mode 100644
index 00000000..1b7466cf
--- /dev/null
+++ b/assets/css/frontend/pages/sidebar.css
@@ -0,0 +1,98 @@
+/* Sidebar */
+.aksrt-forum-sidebar-card {
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ padding: 16px;
+ margin-bottom: 16px;
+}
+
+.aksrt-forum-sidebar-card__title {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin: 0 0 12px;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-forum-sidebar-card__title i {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-sidebar-card__list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.aksrt-forum-sidebar-card__item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 0;
+ border-bottom: 1px solid var(--color-line, #f0f0f0);
+}
+
+.aksrt-forum-sidebar-card__item:last-child {
+ border-bottom: none;
+}
+
+.aksrt-forum-sidebar-card__rank {
+ width: 20px;
+ height: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 4px;
+ background: var(--surface-2, #f5f7fa);
+ font-size: 11px;
+ font-weight: 600;
+ color: var(--color-ink-3, #999);
+ flex-shrink: 0;
+}
+
+.aksrt-forum-sidebar-card__item:nth-child(1) .aksrt-forum-sidebar-card__rank { background: #fff1f0; color: #f5222d; }
+.aksrt-forum-sidebar-card__item:nth-child(2) .aksrt-forum-sidebar-card__rank { background: #fff7e6; color: #fa8c16; }
+.aksrt-forum-sidebar-card__item:nth-child(3) .aksrt-forum-sidebar-card__rank { background: var(--color-primary-soft); color: var(--color-primary); }
+
+.aksrt-forum-sidebar-card__link {
+ flex: 1;
+ font-size: 13px;
+ color: var(--color-ink-2, #666);
+ text-decoration: none;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.aksrt-forum-sidebar-card__link:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-sidebar-card__views {
+ font-size: 11px;
+ color: var(--color-ink-3, #999);
+ flex-shrink: 0;
+}
+
+.aksrt-forum-sidebar-card__content ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.aksrt-forum-sidebar-card__content li {
+ padding: 4px 0;
+ font-size: 13px;
+ color: var(--color-ink-2, #666);
+ line-height: 1.6;
+}
+
+.aksrt-forum-sidebar-card__content li::before {
+ content: '•';
+ color: var(--color-primary);
+ margin-right: 6px;
+}
+
diff --git a/assets/css/frontend/pages/topic-rows.css b/assets/css/frontend/pages/topic-rows.css
new file mode 100644
index 00000000..fe6336e7
--- /dev/null
+++ b/assets/css/frontend/pages/topic-rows.css
@@ -0,0 +1,55 @@
+/* Topic rows */
+.aksrt-forum-topics__list {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ margin-bottom: 32px;
+}
+
+.aksrt-forum-topic-row {
+ display: flex;
+ gap: 12px;
+ padding: 12px;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ transition: border-color 0.2s;
+}
+
+.aksrt-forum-topic-row:hover {
+ border-color: var(--color-primary);
+}
+
+.aksrt-forum-topic-row__avatar img {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.aksrt-forum-topic-row__title {
+ margin: 0 0 4px;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.aksrt-forum-topic-row__title a {
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.aksrt-forum-topic-row__title a:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-forum-topic-row__meta {
+ display: flex;
+ gap: 12px;
+ font-size: 11px;
+ color: var(--color-ink-3, #999);
+}
+
+.aksrt-forum-topic-row__meta i {
+ margin-right: 3px;
+}
+
diff --git a/assets/css/frontend/pagination.css b/assets/css/frontend/pagination.css
new file mode 100644
index 00000000..e13a1072
--- /dev/null
+++ b/assets/css/frontend/pagination.css
@@ -0,0 +1,230 @@
+/* ========== 分页 — 对齐 zibll pagination ========== */
+.pagination,
+.aksrt-pagination,
+.navigation.pagination .nav-links,
+.pagenav.ajax-pag {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 4px;
+ padding: 20px 0;
+ flex-wrap: wrap;
+}
+
+.pagination a,
+.pagination span,
+.aksrt-pagination a,
+.aksrt-pagination span,
+.navigation.pagination a,
+.navigation.pagination span,
+.pagenav.ajax-pag a,
+.pagenav.ajax-pag span {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 31px;
+ padding: 6px 9px 5px;
+ font-size: 13px;
+ line-height: 1.4;
+ color: var(--muted-color, var(--color-ink-3));
+ background: var(--main-border-color, rgba(50, 50, 50, 0.06));
+ border: none;
+ border-radius: 3px;
+ text-decoration: none;
+ transition: all 0.2s;
+ user-select: none;
+}
+
+.pagination a:hover,
+.aksrt-pagination a:hover,
+.navigation.pagination a:hover,
+.pagenav.ajax-pag a:hover {
+ opacity: 0.7;
+}
+
+.pagination .current,
+.aksrt-pagination .current,
+.navigation.pagination .current,
+.pagenav.ajax-pag .current {
+ color: var(--color-on-primary, #fff);
+ background: var(--color-primary, #f04494);
+ border-color: var(--color-primary, #f04494);
+ font-weight: 500;
+}
+
+.pagination .dots,
+.aksrt-pagination .dots,
+.navigation.pagination .dots,
+.pagenav.ajax-pag .dots {
+ border: none;
+ background: none;
+ color: var(--color-ink-4, #999);
+ cursor: default;
+ min-width: auto;
+ padding-left: 4px;
+ padding-right: 4px;
+}
+
+.pagination .prev,
+.pagination .next,
+.aksrt-pagination .prev,
+.aksrt-pagination .next,
+.navigation.pagination .prev,
+.navigation.pagination .next,
+.pagenav.ajax-pag .prev,
+.pagenav.ajax-pag .next {
+ font-size: 12px;
+}
+
+.pagination .prev i,
+.pagination .next i,
+.aksrt-pagination .prev i,
+.aksrt-pagination .next i,
+.navigation.pagination .prev i,
+.navigation.pagination .next i,
+.pagenav.ajax-pag .prev i,
+.pagenav.ajax-pag .next i {
+ font-size: 11px;
+}
+
+.pagenav.ajax-pag .pag-jump,
+.aksrt-pagination .pag-jump,
+.navigation.pagination .pag-jump {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ margin-left: 6px;
+}
+
+.pagenav.ajax-pag .jump-input,
+.aksrt-pagination .jump-input,
+.navigation.pagination .jump-input {
+ width: 64px;
+ min-width: 64px;
+ padding: 6px 8px 5px;
+ font-size: 13px;
+ line-height: 1.4;
+ color: var(--muted-color, var(--color-ink-3));
+ background: var(--main-bg-color, #fff);
+ border: 1px solid var(--main-border-color, rgba(50, 50, 50, 0.06));
+ border-radius: 3px;
+ box-shadow: none;
+}
+
+.pagenav.ajax-pag .jump-input:focus,
+.aksrt-pagination .jump-input:focus,
+.navigation.pagination .jump-input:focus {
+ outline: none;
+ border-color: var(--focus-color, var(--color-primary, #f04494));
+}
+
+.pagenav.ajax-pag .pag-jump .ajax-next,
+.aksrt-pagination .pag-jump .ajax-next,
+.navigation.pagination .pag-jump .ajax-next {
+ min-width: auto;
+ cursor: pointer;
+}
+
+/* 上一页/下一页 */
+.pagination__nav {
+ display: flex;
+ gap: 8px;
+ justify-content: center;
+ margin-top: 8px;
+}
+
+.pagination__nav a {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 14px;
+ font-size: 13px;
+ color: var(--color-ink-2, #4e5358);
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
+ border-radius: 6px;
+ text-decoration: none;
+ transition: all 0.2s;
+}
+
+.pagination__nav a:hover {
+ color: var(--color-primary, #f04494);
+ border-color: var(--color-primary, #f04494);
+}
+
+/* AJAX 加载更多 */
+.load-more {
+ text-align: center;
+ padding: 20px 0;
+}
+
+.load-more__btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 10px 24px;
+ font-size: 13px;
+ color: var(--color-ink-2, #4e5358);
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, rgba(50, 50, 50, 0.06));
+ border-radius: 20px;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.load-more__btn:hover {
+ color: var(--color-primary, #f04494);
+ border-color: var(--color-primary, #f04494);
+}
+
+.load-more__btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.load-more__spinner {
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ border: 2px solid var(--surface-3, #e8e8e8);
+ border-top-color: var(--color-primary, #f04494);
+ border-radius: 50%;
+ animation: spin 0.6s linear infinite;
+}
+
+@keyframes spin {
+ to { transform: rotate(360deg); }
+}
+
+/* 移动端 */
+@media (max-width: 767px) {
+ .pagination a,
+ .pagination span,
+ .aksrt-pagination a,
+ .aksrt-pagination span,
+ .navigation.pagination a,
+ .navigation.pagination span,
+ .pagenav.ajax-pag a,
+ .pagenav.ajax-pag span {
+ min-width: 28px;
+ font-size: 12px;
+ margin: 2px;
+ }
+
+ .pagenav.ajax-pag .pag-jump,
+ .aksrt-pagination .pag-jump,
+ .navigation.pagination .pag-jump {
+ width: 100%;
+ justify-content: center;
+ margin-left: 0;
+ margin-top: 6px;
+ }
+
+ .pagenav.ajax-pag .jump-input,
+ .aksrt-pagination .jump-input,
+ .navigation.pagination .jump-input {
+ width: 58px;
+ min-width: 58px;
+ font-size: 12px;
+ }
+}
diff --git a/assets/css/frontend/post-card-cms.css b/assets/css/frontend/post-card-cms.css
new file mode 100644
index 00000000..491fb686
--- /dev/null
+++ b/assets/css/frontend/post-card-cms.css
@@ -0,0 +1,60 @@
+/**
+ * Post Card · CMS (grid-cms layout)
+ */
+
+.post-grid--grid-cms {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
+ gap: 20px;
+}
+
+.post-grid--grid-cms .posts-item.card.posts-item--cms {
+ height: 100%;
+ border-radius: 16px;
+}
+
+.post-grid--grid-cms .posts-item--cms .item-body {
+ gap: 10px;
+}
+
+.post-grid--grid-cms .posts-item--cms .item-excerpt {
+ -webkit-line-clamp: 2;
+}
+
+.post-grid--grid-cms .posts-item--cms .item-cms-strip {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.post-grid--grid-cms .posts-item--cms .item-cms-strip li {
+ display: inline-flex;
+ align-items: center;
+ min-height: 24px;
+ padding: 0 10px;
+ border-radius: 999px;
+ background: var(--surface-2);
+ color: var(--color-ink-4);
+ font-size: 12px;
+ font-weight: 500;
+}
+
+.post-grid--grid-cms .posts-item--cms .item-cms-strip li::before {
+ display: none;
+}
+
+@media (max-width: 640px) {
+ .post-grid--grid-cms {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 14px;
+ }
+}
+
+@media (max-width: 380px) {
+ .post-grid--grid-cms {
+ grid-template-columns: 1fr;
+ }
+}
diff --git a/assets/css/frontend/post-card.css b/assets/css/frontend/post-card.css
new file mode 100644
index 00000000..00d9e483
--- /dev/null
+++ b/assets/css/frontend/post-card.css
@@ -0,0 +1,584 @@
+/**
+ * AKSRT Post Card / List — 1:1 Zibll Alignment
+ *
+ * 对齐 zibll main.css 的 .posts-item 系统
+ * - 默认 = 列表模式(无额外类名)
+ * - .card = 卡片模式
+ *
+ * 布局:inline-block(对齐 zibll,不用 Grid)
+ */
+
+/* ============================================================
+ * 列表容器 — 对齐 zibll .posts-row
+ * ============================================================ */
+.post-grid {
+ margin-left: -8px;
+ margin-right: -8px;
+ font-size: 0; /* 消除 inline-block 间隙 */
+}
+
+.post-grid--list {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+/* ============================================================
+ * 通用 posts-item 基础 — 对齐 zibll line 7585
+ * ============================================================ */
+.posts-item {
+ padding: 20px;
+ margin: 15px 0;
+ background: var(--main-bg-color, #fff);
+ overflow: hidden;
+ transition: 0.2s;
+ box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
+ border-radius: var(--main-radius, 8px);
+}
+
+/* ============================================================
+ * 卡片模式 .posts-item.card — 对齐 zibll line 7733
+ * ============================================================ */
+.posts-item.card {
+ width: calc(33.333% - 16px);
+ display: inline-block;
+ margin: 8px;
+ padding: 10px;
+ vertical-align: top;
+ transition: 0.3s;
+ font-size: 1rem; /* 重置容器 font-size: 0 */
+}
+
+@media (max-width: 991px) {
+ .posts-item.card {
+ width: calc(33.333% - 12px);
+ margin: 6px;
+ }
+}
+
+@media (max-width: 767px) {
+ .posts-item.card {
+ width: calc(50% - 10px);
+ margin: 5px;
+ padding: 8px;
+ }
+}
+
+/* ============================================================
+ * 缩略图 — 对齐 zibll line 7604
+ * ============================================================ */
+.item-thumbnail {
+ position: relative;
+ overflow: hidden;
+ border-radius: var(--main-radius, 8px);
+}
+
+/* 列表模式缩略图 */
+.posts-item:not(.card) .item-thumbnail {
+ width: 190px;
+ height: 0;
+ padding-bottom: var(--posts-list-scale, 70%);
+ float: left;
+ margin-right: 20px;
+}
+
+/* 卡片模式缩略图 */
+.posts-item.card .item-thumbnail {
+ width: 100%;
+ height: 0;
+ padding-bottom: var(--posts-card-scale, 70%);
+}
+
+.item-thumbnail a {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ display: block;
+}
+
+.item-thumbnail img,
+.item-thumbnail .fit-cover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.3s ease;
+}
+
+.posts-item:hover .item-thumbnail img {
+ transform: scale(1.05);
+}
+
+/* 图片徽章 */
+.img-badge {
+ position: absolute;
+ top: 8px;
+ padding: 2px 8px;
+ border-radius: 4px;
+ font-size: 11px;
+ font-weight: 600;
+ color: #fff;
+ z-index: 2;
+}
+
+.img-badge.left {
+ left: 8px;
+}
+
+.badge-sticky {
+ background: var(--color-error, #ef4444);
+}
+
+/* ============================================================
+ * 标题 — 对齐 zibll line 7669
+ * ============================================================ */
+.item-heading {
+ margin-top: 0;
+ margin-bottom: 5px;
+ font-size: 18px;
+ line-height: 1.4em;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 2;
+ overflow: hidden;
+ max-height: 2.8em;
+}
+
+.item-heading--bold {
+ font-weight: 700;
+}
+
+.fit-cover {
+ object-fit: cover;
+}
+
+.fit-contain {
+ object-fit: contain;
+}
+
+.posts-item.card .item-heading {
+ font-size: 14px;
+ min-height: 2.8em; /* 对齐 zibll:定高使无摘要卡片底部 meta 对齐;line-height/max-height 继承基类 1.4em/2.8em */
+}
+
+.item-heading a {
+ color: var(--key-color, #333);
+}
+
+.item-heading a:hover {
+ color: var(--focus-color, #f04494);
+}
+
+/* ============================================================
+ * 摘要 — 对齐 zibll 单行 ellipsis
+ * ============================================================ */
+.item-excerpt {
+ font-size: 13px;
+ color: var(--muted-color, #777);
+ line-height: 1.5;
+ margin: 5px 0;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+/* ============================================================
+ * 元信息 — 对齐 zibll line 7701
+ * ============================================================ */
+.item-meta {
+ font-size: 13px;
+ color: var(--muted-2-color, #999);
+ margin-top: 10px;
+}
+
+.item-meta item {
+ margin-right: 8px;
+}
+
+.meta-author {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.meta-avatar {
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.meta-time {
+ font-size: 12px;
+}
+
+.meta-right {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ float: right;
+}
+
+.meta-item {
+ display: inline-flex;
+ align-items: center;
+ gap: 3px;
+}
+
+.meta-item i {
+ font-size: 11px;
+ opacity: 0.7;
+}
+
+.meta-dot {
+ width: 4px;
+ height: 4px;
+ border-radius: 999px;
+ background: currentColor;
+ opacity: 0.3;
+ display: inline-block;
+}
+
+/* ============================================================
+ * 标签 — 对齐 zibll line 7723
+ * ============================================================ */
+.item-tags {
+ margin-top: 8px;
+}
+
+.item-tags .badge {
+ display: inline-block;
+ font-size: 11px;
+ padding: 2px 5px;
+ margin-right: 5px;
+ border-radius: 50px;
+ text-decoration: none;
+ transition: 0.15s;
+}
+
+.badge-price {
+ background: rgba(239, 68, 68, 0.1);
+ color: var(--color-error, #ef4444);
+}
+
+.badge-category {
+ background: var(--focus-shadow-color, rgba(253, 83, 161, 0.12));
+ color: var(--focus-color, #f04494);
+}
+
+.badge-category:hover {
+ background: var(--focus-shadow-color, rgba(253, 83, 161, 0.2));
+ color: var(--focus-color, #f04494);
+ text-decoration: none;
+}
+
+.badge-tag {
+ background: var(--muted-bg-color, #eee);
+ color: var(--muted-2-color, #999);
+}
+
+.badge-tag:hover {
+ background: var(--focus-shadow-color, rgba(253, 83, 161, 0.12));
+ color: var(--focus-color, #f04494);
+ text-decoration: none;
+}
+
+/* ============================================================
+ * 卡片模式 body — 对齐 zibll padding: 10px 整体
+ * ============================================================ */
+.posts-item.card .item-body {
+ width: 100%;
+ margin: 10px 0 0;
+ padding: 0;
+}
+
+/* ============================================================
+ * 列表模式 clearfix — 对齐 zibll float 布局
+ * ============================================================ */
+.posts-item:not(.card)::after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+/* ============================================================
+ * Mini 文章列表 — 对齐 zibll .posts-mini line 7903
+ * ============================================================ */
+.posts-mini {
+ padding: 10px;
+ display: inline-flex;
+ width: 50%;
+ vertical-align: top;
+ font-size: 1rem;
+}
+
+.posts-mini .item-thumbnail {
+ width: 96px;
+ min-width: 96px;
+ height: 0;
+ padding-bottom: 70%;
+ float: none;
+ margin-right: 12px;
+ margin-top: 2px;
+}
+
+.posts-mini .item-heading {
+ font-size: 14px;
+ line-height: 1.5;
+ -webkit-line-clamp: 2;
+ max-height: 3em;
+}
+
+@media (max-width: 767px) {
+ .posts-mini {
+ width: 100%;
+ }
+}
+
+/* ============================================================
+ * AJAX 翻页 — 对齐 zibll
+ * ============================================================ */
+.ajax-pagination {
+ text-align: center;
+ padding: 20px 0;
+}
+
+.ajax-pagination .ajax-next {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ padding: 5px 15px;
+ border-radius: 30px;
+ background: var(--muted-bg-color, #eee);
+ color: var(--muted-color, #777);
+ font-size: 14px;
+ cursor: pointer;
+ transition: 0.15s;
+ border: none;
+ text-decoration: none;
+}
+
+.ajax-pagination .ajax-next:hover {
+ background: var(--focus-shadow-color, rgba(253, 83, 161, 0.12));
+ color: var(--focus-color, #f04494);
+ text-decoration: none;
+}
+
+.ajax-pagination .ajax-next.is-loading {
+ pointer-events: none;
+ opacity: 0.7;
+}
+
+.ajax-pagination .ajax-nomore {
+ color: var(--muted-2-color, #999);
+ font-size: 13px;
+}
+
+/* ============================================================
+ * 骨架屏(AKSRT 保留,Zibll 无此特性)
+ * ============================================================ */
+.skeleton-card {
+ background: var(--main-bg-color, #fff);
+ border-radius: var(--main-radius, 8px);
+ overflow: hidden;
+ box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
+}
+
+.skeleton-card__thumb {
+ width: 100%;
+ padding-top: var(--posts-card-scale, 70%);
+ background: var(--muted-bg-color, #eee);
+ animation: skeleton-pulse 1.5s ease-in-out infinite;
+}
+
+.skeleton-card__body {
+ padding: 10px;
+}
+
+.skeleton-card__line {
+ height: 14px;
+ border-radius: 4px;
+ background: var(--muted-bg-color, #eee);
+ margin-bottom: 8px;
+ animation: skeleton-pulse 1.5s ease-in-out infinite;
+}
+
+.skeleton-card__line--short {
+ width: 60%;
+}
+
+.skeleton-card__line--meta {
+ width: 40%;
+ height: 12px;
+ margin-top: 12px;
+}
+
+@keyframes skeleton-pulse {
+ 0%, 100% { opacity: 1; }
+ 50% { opacity: 0.5; }
+}
+
+/* ============================================================
+ * 卡片样式变体 — 对齐 zibll main.css 7682–7900
+ * ============================================================ */
+
+/* 卡片标签占位高度(无标签卡片不塌陷) */
+.posts-item.card .item-tags {
+ min-height: 23px;
+}
+
+/* style2:透明底,hover 才出卡片底 + 阴影 */
+.posts-item.card.style2 {
+ background: transparent;
+ box-shadow: none;
+}
+
+.posts-item.card.style2:hover {
+ background: var(--main-bg-color, #fff);
+ box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
+}
+
+/* style3:padding 0,缩略图顶部圆角,body 内 padding 10px */
+.posts-item.card.style3 {
+ padding: 0;
+}
+
+.posts-item.card.style3 .item-thumbnail,
+.posts-item.card.style3 .item-thumbnail img {
+ border-radius: var(--main-radius, 8px) var(--main-radius, 8px) 0 0;
+}
+
+.posts-item.card.style3 .item-body {
+ padding: 10px;
+ margin: 0;
+}
+
+/* 窄缩略图列表变体 .list.style2:130px 缩略图 + 单行标题 ellipsis */
+.posts-item.list.style2 .item-thumbnail {
+ width: 130px;
+}
+
+.posts-item.list.style2 .item-heading {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ display: unset;
+ max-height: 1.4em;
+}
+
+/* 多图卡片 .mult-thumb:九宫格缩略图(每行 4 列) */
+.posts-item.mult-thumb .thumb-items {
+ margin: 0 -3px 6px -3px;
+}
+
+.posts-item.mult-thumb .thumb-items > span {
+ width: calc(25% - 6px);
+ display: inline-block;
+ height: 0;
+ padding-bottom: calc(var(--posts-list-scale, 70%) / 4);
+ margin: 0 3px;
+ position: relative;
+}
+
+.posts-item.mult-thumb .thumb-items > span > img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.posts-item.mult-thumb .thumb-items.contain > span {
+ background: var(--main-border-color, rgba(50, 50, 50, 0.06));
+ border-radius: var(--main-radius, 8px);
+ overflow: hidden;
+}
+
+.posts-item.mult-thumb .thumb-items.contain > span > img {
+ object-fit: contain;
+ border-radius: 0;
+}
+
+/* 无间距连排 .no_margin:首尾圆角,中间无圆角无阴影 */
+.posts-item.no_margin {
+ margin: 0;
+ box-shadow: none;
+ border-radius: 0;
+}
+
+.posts-item.no_margin:first-of-type {
+ margin-top: 10px;
+ border-radius: var(--main-radius, 8px) var(--main-radius, 8px) 0 0;
+}
+
+.posts-item.no_margin:last-of-type {
+ margin-bottom: 15px;
+ border-radius: 0 0 var(--main-radius, 8px) var(--main-radius, 8px);
+}
+
+.posts-item + .pagenav,
+.posts-item + .aksrt-pagination,
+.posts-item + .pagination,
+.posts-item + .navigation.pagination {
+ margin-top: -15px;
+}
+
+.posts-item.card + .pagenav,
+.posts-item.card + .aksrt-pagination,
+.posts-item.card + .pagination,
+.posts-item.card + .navigation.pagination {
+ margin-top: -10px;
+}
+
+/* mini 列表缩略图 hover 放大(对齐 zibll .posts-item:hover 缩略图) */
+.posts-mini:hover .item-thumbnail img {
+ transform: scale(1.05);
+}
+
+/* 瀑布流 .waterfall-box:缩略图保持原始比例(配合瀑布流 JS 时启用) */
+.waterfall-box {
+ position: relative;
+}
+
+.waterfall-box .card .item-thumbnail {
+ padding-bottom: 0;
+ height: auto;
+}
+
+.waterfall-box .card .item-thumbnail img {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+/* ============================================================
+ * 暗色模式 — 对齐 zibll
+ * ============================================================ */
+.theme-dark .posts-item,
+html.dark .posts-item {
+ background: var(--main-bg-color, #323335);
+ border-color: var(--main-border-color, rgba(114, 114, 114, 0.1));
+}
+
+/* ============================================================
+ * 无缩略图状态
+ * ============================================================ */
+.posts-item.no-thumb {
+ overflow: visible;
+}
+
+.posts-item.no-thumb .item-body {
+ width: 100%;
+}
+
+.posts-item.has-no-thumb {
+ overflow: visible;
+}
+
+.posts-item.has-no-thumb .item-body {
+ width: 100%;
+}
diff --git a/assets/css/frontend/print.css b/assets/css/frontend/print.css
new file mode 100644
index 00000000..8fae6ba5
--- /dev/null
+++ b/assets/css/frontend/print.css
@@ -0,0 +1,105 @@
+/**
+ * AKSRT Print Stylesheet
+ *
+ * 优化内容打印:隐藏导航、悬浮按钮、侧栏,保留正文和图片。
+ *
+ * @package AKSRT
+ */
+
+@media print {
+ /* 隐藏非内容元素 */
+ .site-nav,
+ .site-footer,
+ .footer-tabbar,
+ .float-right,
+ .float-btn,
+ .aksrt-toast-container,
+ .resource-mobile-fab,
+ .resource-mobile-download-bar,
+ .sidebar,
+ .aksrt-sidebar,
+ .widget-area,
+ .comments-area,
+ .post-navigation,
+ .aksrt-breadcrumbs,
+ .reading-progress-bar,
+ .aksrt-admin-bar,
+ #wpadminbar,
+ .aksrt-blur-bg {
+ display: none !important;
+ }
+
+ /* 正文优化 */
+ body {
+ font-family: Georgia, "Noto Serif SC", serif;
+ font-size: 12pt;
+ line-height: 1.6;
+ color: #000;
+ background: #fff;
+ }
+
+ .site-main,
+ .entry-content,
+ .article-content {
+ max-width: 100%;
+ margin: 0;
+ padding: 0;
+ }
+
+ /* 标题 */
+ h1, h2, h3, h4, h5, h6 {
+ page-break-after: avoid;
+ page-break-inside: avoid;
+ }
+
+ /* 图片 */
+ img {
+ max-width: 100% !important;
+ height: auto !important;
+ page-break-inside: avoid;
+ }
+
+ /* 链接显示 URL */
+ a[href^="http"]::after {
+ content: " (" attr(href) ")";
+ font-size: 0.8em;
+ color: #666;
+ word-break: break-all;
+ }
+
+ /* 代码块 */
+ pre, code {
+ page-break-inside: avoid;
+ border: 1px solid #ccc;
+ padding: 4px;
+ }
+
+ /* 表格 */
+ table {
+ page-break-inside: avoid;
+ border-collapse: collapse;
+ }
+
+ th, td {
+ border: 1px solid #ccc;
+ padding: 6px;
+ }
+
+ /* 资源元信息 */
+ .resource-meta-box,
+ .resource-download-box {
+ border: 1px solid #ccc;
+ padding: 12px;
+ margin: 16px 0;
+ }
+
+ .resource-download-box__btn {
+ display: none;
+ }
+
+ /* 分页避免 */
+ .post-card,
+ .entry-card {
+ page-break-inside: avoid;
+ }
+}
diff --git a/assets/css/frontend/product-archive.css b/assets/css/frontend/product-archive.css
new file mode 100644
index 00000000..04dd094b
--- /dev/null
+++ b/assets/css/frontend/product-archive.css
@@ -0,0 +1,711 @@
+/**
+ * AKSRT Product Archive — 商品归档页样式
+ *
+ * 商品分类页、标签页共用样式。
+ * 卡片网格、价格徽章、空状态。
+ *
+ * Tokens: 颜色 / 间距 / 圆角 / 阴影 全部来自 core/tokens.css
+ */
+
+/* ================================================
+ * 页面头:标题 + 计数
+ * ================================================ */
+.aksrt-product-archive {
+ padding-top: var(--space-6);
+ padding-bottom: var(--space-9);
+}
+
+.aksrt-product-archive__header {
+ margin-bottom: var(--space-6);
+ padding: var(--space-5);
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-lg, 8px);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-product-archive__title {
+ margin: 0 0 4px;
+ font-size: 22px;
+ font-weight: 700;
+ color: var(--color-ink);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.aksrt-product-archive__title i {
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-product-archive__desc {
+ margin: 0 0 8px;
+ font-size: 14px;
+ color: var(--color-ink-3);
+ line-height: 1.6;
+}
+
+.aksrt-product-archive__count {
+ margin: 0;
+ font-size: 13px;
+ color: var(--color-ink-4, #8A8F98);
+}
+
+/* ================================================
+ * 商品网格
+ * ================================================ */
+.aksrt-product-archive__grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
+ gap: var(--space-5);
+ margin-bottom: var(--space-8);
+}
+
+/* ================================================
+ * 商品卡片
+ * ================================================ */
+.aksrt-product-card {
+ display: flex;
+ flex-direction: column;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-lg, 8px);
+ overflow: hidden;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.04);
+ transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
+}
+
+.aksrt-product-card:hover {
+ transform: translateY(-3px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-product-card__link {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ text-decoration: none;
+ color: inherit;
+}
+
+/* 商品图片 */
+.aksrt-product-card__image {
+ position: relative;
+ aspect-ratio: 4 / 3;
+ background-color: var(--surface-2, #F4F5F7);
+ overflow: hidden;
+}
+
+.aksrt-product-card__image img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ transition: transform 0.3s ease;
+}
+
+.aksrt-product-card:hover .aksrt-product-card__image img {
+ transform: scale(1.02);
+}
+
+.aksrt-product-card__image--placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--color-ink-4, #8A8F98);
+ font-size: 32px;
+}
+
+/* 卡片正文 */
+.aksrt-product-card__body {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2);
+ padding: var(--space-4);
+ flex: 1;
+}
+
+.aksrt-product-card__title {
+ margin: 0;
+ font-size: 15px;
+ font-weight: 600;
+ line-height: 1.4;
+ color: var(--color-ink);
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.aksrt-product-card__excerpt {
+ margin: 0;
+ font-size: 13px;
+ color: var(--color-ink-3);
+ line-height: 1.5;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+/* 底部:价格 + 销量 */
+.aksrt-product-card__footer {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
+ margin-top: auto;
+ padding-top: var(--space-3);
+ border-top: 1px solid var(--color-line-soft, #F0F1F3);
+}
+
+.aksrt-product-card__price {
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--color-error, #EF4444);
+}
+
+.aksrt-product-card__sales {
+ font-size: 12px;
+ color: var(--color-ink-4, #8A8F98);
+}
+
+/* ================================================
+ * 分页
+ * ================================================ */
+.aksrt-product-archive__pagination {
+ display: flex;
+ justify-content: center;
+ padding: var(--space-5) 0;
+}
+
+.aksrt-product-archive__pagination .page-numbers {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 36px;
+ height: 36px;
+ padding: 0 8px;
+ margin: 0 4px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-2);
+ font-size: 14px;
+ text-decoration: none;
+ transition: all 0.15s ease;
+}
+
+.aksrt-product-archive__pagination .page-numbers:hover {
+ border-color: var(--color-primary, var(--color-primary));
+ color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-product-archive__pagination .page-numbers.current {
+ background: var(--color-primary, var(--color-primary));
+ border-color: var(--color-primary, var(--color-primary));
+ color: #fff;
+}
+
+/* ================================================
+ * 空状态
+ * ================================================ */
+.aksrt-product-archive__empty {
+ text-align: center;
+ padding: var(--space-9) var(--space-5);
+ color: var(--color-ink-3);
+}
+
+.aksrt-product-archive__empty i {
+ font-size: 48px;
+ color: var(--color-ink-4, #8A8F98);
+ margin-bottom: var(--space-4);
+ display: block;
+}
+
+.aksrt-product-archive__empty p {
+ margin: 0;
+ font-size: 15px;
+}
+
+/* ================================================
+ * 响应式
+ * ================================================ */
+@media (max-width: 640px) {
+ .aksrt-product-archive__grid {
+ grid-template-columns: repeat(2, 1fr);
+ gap: var(--space-3);
+ }
+
+ .aksrt-product-card__body {
+ padding: var(--space-3);
+ }
+
+ .aksrt-product-card__title {
+ font-size: 14px;
+ }
+
+ .aksrt-product-card__price {
+ font-size: 16px;
+ }
+}
+
+@media (max-width: 380px) {
+ .aksrt-product-archive__grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+/* ================================================
+ * 产品详情页样式补充
+ * ================================================ */
+.aksrt-product {
+ padding-top: var(--space-6);
+ padding-bottom: var(--space-9);
+}
+
+.aksrt-product__layout {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--space-7);
+ margin-bottom: var(--space-7);
+}
+
+.aksrt-product__image {
+ border-radius: var(--radius-lg, 8px);
+ overflow: hidden;
+ background: var(--surface-2, #F4F5F7);
+}
+
+.aksrt-product__img {
+ width: 100%;
+ display: block;
+}
+
+.aksrt-product__img-placeholder {
+ aspect-ratio: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--color-ink-4, #8A8F98);
+ font-size: 64px;
+}
+
+.aksrt-product__info {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+}
+
+.aksrt-product__title {
+ margin: 0;
+ font-size: 24px;
+ font-weight: 700;
+ color: var(--color-ink);
+ line-height: 1.3;
+}
+
+.aksrt-product__price-row {
+ display: flex;
+ align-items: baseline;
+ gap: var(--space-3);
+}
+
+.aksrt-product__price {
+ font-size: 28px;
+ font-weight: 700;
+ color: var(--color-error, #EF4444);
+}
+
+.aksrt-product__sales {
+ font-size: 13px;
+ color: var(--color-ink-4, #8A8F98);
+}
+
+.aksrt-product__excerpt {
+ margin: 0;
+ font-size: 14px;
+ color: var(--color-ink-3);
+ line-height: 1.6;
+}
+
+.aksrt-product__meta {
+ font-size: 14px;
+ color: var(--color-ink-2);
+}
+
+.aksrt-product__meta i {
+ margin-right: 4px;
+}
+
+.aksrt-product__actions {
+ margin-top: var(--space-4);
+}
+
+.aksrt-product__buy-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ padding: 12px 32px;
+ border: none;
+ border-radius: var(--radius, 10px);
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+ font-size: 16px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: opacity 0.15s;
+}
+
+.aksrt-product__buy-btn:hover {
+ opacity: 0.85;
+}
+
+.aksrt-product__detail {
+ padding: var(--space-6);
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-lg, 8px);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-product__detail-title {
+ margin: 0 0 var(--space-4);
+ font-size: 18px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-product__detail-content {
+ font-size: 15px;
+ line-height: 1.8;
+ color: var(--color-ink-2);
+}
+
+.aksrt-product__detail-content img {
+ max-width: 100%;
+ border-radius: var(--radius, 10px);
+}
+
+.aksrt-product__empty {
+ text-align: center;
+ padding: var(--space-10) var(--space-5);
+ color: var(--color-ink-3);
+}
+
+.aksrt-product__empty i {
+ display: block;
+ margin-bottom: var(--space-4);
+}
+
+.aksrt-product__empty p {
+ margin: 0;
+ font-size: 16px;
+}
+
+/* 产品详情页响应式 */
+@media (max-width: 767px) {
+ .aksrt-product__layout {
+ grid-template-columns: 1fr;
+ gap: var(--space-5);
+ }
+
+ .aksrt-product__title {
+ font-size: 20px;
+ }
+
+ .aksrt-product__price {
+ font-size: 24px;
+ }
+}
+
+/* ================================================
+ * 购物车页样式
+ * ================================================ */
+.aksrt-cart {
+ padding-top: var(--space-6);
+ padding-bottom: var(--space-9);
+}
+
+.aksrt-cart__title {
+ margin: 0 0 var(--space-6);
+ font-size: 24px;
+ font-weight: 700;
+ color: var(--color-ink);
+}
+
+.aksrt-cart__layout {
+ display: grid;
+ grid-template-columns: 1fr 320px;
+ gap: var(--space-6);
+}
+
+.aksrt-cart__items {
+ min-height: 200px;
+}
+
+.aksrt-cart__item {
+ display: flex;
+ align-items: center;
+ gap: var(--space-4);
+ padding: var(--space-4);
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ margin-bottom: var(--space-3);
+}
+
+.aksrt-cart__item-img {
+ width: 80px;
+ height: 80px;
+ object-fit: cover;
+ border-radius: var(--radius-sm, 6px);
+}
+
+.aksrt-cart__item-info {
+ flex: 1;
+ min-width: 0;
+}
+
+.aksrt-cart__item-info h4 {
+ margin: 0 0 4px;
+ font-size: 15px;
+ font-weight: 500;
+ color: var(--color-ink);
+}
+
+.aksrt-cart__item-price {
+ font-size: 14px;
+ color: var(--color-ink-3);
+}
+
+.aksrt-cart__item-qty {
+ display: flex;
+ align-items: center;
+ gap: var(--space-2);
+}
+
+.aksrt-cart__qty-btn {
+ width: 28px;
+ height: 28px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-sm, 6px);
+ background: var(--surface-1, #fff);
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+}
+
+.aksrt-cart__qty-btn:hover {
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-cart__item-subtotal {
+ font-weight: 600;
+ color: var(--color-error, #EF4444);
+ min-width: 80px;
+ text-align: right;
+}
+
+.aksrt-cart__remove-btn {
+ width: 32px;
+ height: 32px;
+ border: none;
+ background: none;
+ cursor: pointer;
+ color: var(--color-ink-4, #8A8F98);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--radius-sm, 6px);
+}
+
+.aksrt-cart__remove-btn:hover {
+ background: var(--surface-2, #F4F5F7);
+ color: var(--color-error, #EF4444);
+}
+
+.aksrt-cart__sidebar {
+ position: sticky;
+ top: 24px;
+}
+
+.aksrt-cart__summary {
+ padding: var(--space-5);
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius-lg, 8px);
+}
+
+.aksrt-cart__summary-title {
+ margin: 0 0 var(--space-4);
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--color-ink);
+}
+
+.aksrt-cart__summary-row {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: var(--space-3);
+ font-size: 14px;
+ color: var(--color-ink-2);
+}
+
+.aksrt-cart__summary-total {
+ display: flex;
+ justify-content: space-between;
+ padding-top: var(--space-3);
+ border-top: 1px solid var(--color-line);
+ margin-bottom: var(--space-5);
+ font-weight: 600;
+}
+
+.aksrt-cart__total-price {
+ font-size: 20px;
+ color: var(--color-error, #EF4444);
+}
+
+.aksrt-cart__checkout-btn {
+ width: 100%;
+ padding: 12px;
+ border: none;
+ border-radius: var(--radius, 10px);
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+ font-size: 16px;
+ font-weight: 600;
+ cursor: pointer;
+ transition: opacity 0.15s;
+}
+
+.aksrt-cart__checkout-btn:hover {
+ opacity: 0.85;
+}
+
+.aksrt-cart__checkout-btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.aksrt-cart__empty {
+ text-align: center;
+ padding: var(--space-9) var(--space-5);
+ color: var(--color-ink-3);
+}
+
+.aksrt-cart__empty i {
+ display: block;
+ margin-bottom: var(--space-4);
+}
+
+.aksrt-cart__empty p {
+ margin: 0 0 var(--space-4);
+ font-size: 15px;
+}
+
+/* 购物车响应式 */
+@media (max-width: 767px) {
+ .aksrt-cart__layout {
+ grid-template-columns: 1fr;
+ }
+
+ .aksrt-cart__sidebar {
+ position: static;
+ }
+}
+
+/* ================================================
+ * 商品编辑页样式
+ * ================================================ */
+.aksrt-product-edit {
+ padding-top: var(--space-6);
+ padding-bottom: var(--space-9);
+ max-width: 720px;
+ margin: 0 auto;
+}
+
+.aksrt-product-edit__title {
+ margin: 0 0 var(--space-6);
+ font-size: 24px;
+ font-weight: 700;
+ color: var(--color-ink);
+}
+
+.aksrt-product-edit__form {
+ padding: var(--space-6);
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-lg, 8px);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
+}
+
+.aksrt-product-edit__field {
+ margin-bottom: var(--space-5);
+}
+
+.aksrt-product-edit__field label {
+ display: block;
+ font-size: 14px;
+ font-weight: 500;
+ color: var(--color-ink);
+ margin-bottom: var(--space-2);
+}
+
+.aksrt-product-edit__field input,
+.aksrt-product-edit__field textarea {
+ width: 100%;
+ padding: 10px 14px;
+ font-size: 14px;
+ color: var(--color-ink);
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ transition: border-color 0.15s;
+}
+
+.aksrt-product-edit__field input:focus,
+.aksrt-product-edit__field textarea:focus {
+ outline: none;
+ border-color: var(--color-primary, var(--color-primary));
+}
+
+.aksrt-product-edit__field textarea {
+ resize: vertical;
+ min-height: 100px;
+}
+
+.aksrt-product-edit__actions {
+ display: flex;
+ gap: var(--space-3);
+ margin-top: var(--space-6);
+}
+
+.aksrt-product-edit__actions .btn-primary {
+ padding: 10px 24px;
+ border: none;
+ border-radius: var(--radius, 10px);
+ background: var(--color-primary, var(--color-primary));
+ color: #fff;
+ font-size: 15px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: opacity 0.15s;
+}
+
+.aksrt-product-edit__actions .btn-primary:hover {
+ opacity: 0.85;
+}
+
+.aksrt-product-edit__actions .btn-ghost {
+ padding: 10px 24px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius, 10px);
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-2);
+ font-size: 15px;
+ text-decoration: none;
+ transition: border-color 0.15s;
+}
+
+.aksrt-product-edit__actions .btn-ghost:hover {
+ border-color: var(--color-primary, var(--color-primary));
+}
diff --git a/assets/css/frontend/resource-archive.css b/assets/css/frontend/resource-archive.css
new file mode 100644
index 00000000..f14d1771
--- /dev/null
+++ b/assets/css/frontend/resource-archive.css
@@ -0,0 +1,598 @@
+/**
+ * Resource Archive · /resources
+ *
+ * 仅在 is_post_type_archive('aksrt_resource') 时加载。
+ */
+
+.content-shell--cms {
+ max-width: 100%;
+ padding: 0;
+}
+
+/* ============ Header ============ */
+.resource-archive-header {
+ padding: clamp(40px, 6vw, 80px) 0 clamp(24px, 4vw, 48px);
+ background: linear-gradient(135deg, var(--color-primary-soft) 0%, var(--surface-2) 100%);
+}
+
+.resource-archive-header__breadcrumbs {
+ font-size: 13px;
+ color: var(--color-ink-3);
+ margin-bottom: var(--space-3, 12px);
+}
+
+.resource-archive-header__breadcrumbs a {
+ color: var(--color-ink-2);
+ text-decoration: none;
+}
+
+.resource-archive-header__breadcrumbs a:hover {
+ color: var(--color-primary);
+}
+
+.resource-archive-header__title {
+ font: 700 clamp(28px, 4vw, 44px)/1.15 var(--font-display);
+ margin: 0;
+ color: var(--color-ink);
+}
+
+.resource-archive-header__sub {
+ margin: var(--space-2, 8px) 0 0;
+ color: var(--color-ink-3);
+ font-size: 14px;
+}
+
+/* ============ Toolbar ============ */
+.resource-archive {
+ padding-top: var(--space-6, 24px);
+ padding-bottom: var(--space-9, 48px);
+}
+
+.resource-archive__toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: var(--space-4, 16px) var(--space-5, 20px);
+ margin-bottom: var(--space-5, 20px);
+ padding-bottom: var(--space-4, 16px);
+ border-bottom: 1px solid var(--color-line);
+}
+
+.resource-archive__filter-group {
+ display: flex;
+ align-items: center;
+ gap: var(--space-2, 8px);
+}
+
+.resource-archive__filter-label {
+ font: 500 12px/1 var(--font-ui);
+ color: var(--color-ink-3);
+ letter-spacing: .04em;
+ text-transform: uppercase;
+}
+
+.resource-archive__sort {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ gap: var(--space-1, 4px);
+}
+
+.resource-archive__sort-link {
+ display: inline-flex;
+ align-items: center;
+ height: 30px;
+ padding: 0 12px;
+ border-radius: var(--radius-pill);
+ font: 500 13px/1 var(--font-ui);
+ color: var(--color-ink-2);
+ text-decoration: none;
+ transition: background .18s ease, color .18s ease;
+}
+
+.resource-archive__sort-link:hover {
+ background: var(--surface-2);
+ color: var(--color-ink);
+}
+
+.resource-archive__sort-link.is-active {
+ background: var(--color-primary);
+ color: var(--color-on-primary);
+}
+
+.resource-archive__price-range {
+ display: flex;
+ align-items: center;
+ gap: var(--space-2, 8px);
+ margin-left: auto;
+}
+
+.resource-archive__price-input {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ font: 500 11px/1 var(--font-ui);
+ color: var(--color-ink-3);
+}
+
+.resource-archive__price-input input {
+ width: 80px;
+ height: 30px;
+ padding: 0 10px;
+ border: 1px solid var(--color-line);
+ border-radius: var(--radius);
+ background: var(--surface-1);
+ font: 500 13px/1 var(--font-ui);
+ color: var(--color-ink);
+}
+
+.resource-archive__price-input input:focus {
+ outline: 0;
+ border-color: var(--color-primary);
+ box-shadow: 0 0 0 3px rgba(240, 68, 148, 0.15);
+}
+
+.resource-archive__price-sep {
+ color: var(--color-ink-3);
+ font-weight: 500;
+ margin-top: 12px;
+}
+
+.resource-archive__price-range button {
+ margin-top: 12px;
+}
+
+.resource-archive__reset {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ font: 500 13px/1 var(--font-ui);
+ color: var(--color-ink-3);
+ text-decoration: none;
+}
+
+.resource-archive__reset:hover {
+ color: #ef4444;
+}
+
+@media (max-width: 767px) {
+ .resource-archive__price-range {
+ margin-left: 0;
+ flex-basis: 100%;
+ flex-wrap: wrap;
+ }
+}
+
+/* ============================================================
+ * Download Center Page
+ * ============================================================ */
+
+/* Hero section */
+.aksrt-download-hero {
+ position: relative;
+ padding: clamp(40px, 6vw, 80px) 0 clamp(24px, 4vw, 48px);
+ background: linear-gradient(135deg, var(--color-primary-soft, #e6f4ff) 0%, var(--surface-2, #f5f7fa) 100%);
+ margin-bottom: 32px;
+}
+
+.aksrt-download-hero__content {
+ max-width: var(--container, 1280px);
+ margin: 0 auto;
+ padding: 0 24px;
+}
+
+.aksrt-download-hero__title {
+ font: 700 clamp(28px, 4vw, 44px)/1.15 var(--font-display, inherit);
+ margin: 0 0 8px;
+ color: var(--color-ink);
+}
+
+.aksrt-download-hero__desc {
+ margin: 0 0 24px;
+ color: var(--color-ink-2, #666);
+ font-size: 16px;
+ line-height: 1.6;
+}
+
+.aksrt-download-hero__stats {
+ display: flex;
+ gap: 32px;
+ margin-bottom: 24px;
+}
+
+.aksrt-download-hero__stat-num {
+ display: block;
+ font-size: 28px;
+ font-weight: 700;
+ color: var(--color-primary);
+}
+
+.aksrt-download-hero__stat-label {
+ font-size: 13px;
+ color: var(--color-ink-3, #999);
+}
+
+.aksrt-download-hero__filters {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.aksrt-download-hero__filter {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 14px;
+ border-radius: 20px;
+ background: var(--surface-1, #fff);
+ color: var(--color-ink-2, #666);
+ text-decoration: none;
+ font-size: 13px;
+ transition: all 0.2s;
+ border: 1px solid var(--color-line, #e8e8e8);
+}
+
+.aksrt-download-hero__filter:hover {
+ color: var(--color-primary);
+ border-color: var(--color-primary);
+}
+
+.aksrt-download-hero__filter--active {
+ background: var(--color-primary);
+ color: #fff;
+ border-color: var(--color-primary);
+}
+
+.aksrt-download-hero__filter-count {
+ font-size: 11px;
+ opacity: 0.7;
+}
+
+/* Download center layout */
+.aksrt-download-center__layout {
+ display: grid;
+ grid-template-columns: 1fr 311px;
+ gap: 24px;
+}
+
+@media (max-width: 991px) {
+ .aksrt-download-center__layout {
+ grid-template-columns: 1fr;
+ }
+}
+
+.aksrt-download-center__grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 16px;
+ margin-bottom: 24px;
+}
+
+.aksrt-download-card {
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ overflow: hidden;
+ transition: box-shadow 0.2s;
+}
+
+.aksrt-download-card:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
+}
+
+.aksrt-download-card__thumb {
+ aspect-ratio: 16/9;
+ overflow: hidden;
+}
+
+.aksrt-download-card__thumb img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.aksrt-download-card__body {
+ padding: 12px;
+}
+
+.aksrt-download-card__title {
+ margin: 0 0 6px;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.aksrt-download-card__title a {
+ color: var(--color-ink);
+ text-decoration: none;
+}
+
+.aksrt-download-card__title a:hover {
+ color: var(--color-primary);
+}
+
+.aksrt-download-card__excerpt {
+ margin: 0 0 8px;
+ font-size: 12px;
+ color: var(--color-ink-3, #999);
+ line-height: 1.5;
+}
+
+.aksrt-download-card__meta {
+ display: flex;
+ gap: 12px;
+ font-size: 11px;
+ color: var(--color-ink-3, #999);
+}
+
+.aksrt-download-card__meta i {
+ margin-right: 3px;
+}
+
+/* Download sidebar */
+.aksrt-download-center__sidebar {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.aksrt-dl-sidebar-card {
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ padding: 16px;
+}
+
+.aksrt-dl-sidebar-card__title {
+ margin: 0 0 12px;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--color-ink);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.aksrt-dl-sidebar-card__title i {
+ color: var(--color-primary);
+}
+
+.aksrt-dl-sidebar-card__list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.aksrt-dl-sidebar-card__list li {
+ border-bottom: 1px solid var(--color-line, #f0f0f0);
+}
+
+.aksrt-dl-sidebar-card__list li:last-child {
+ border-bottom: none;
+}
+
+.aksrt-dl-sidebar-card__list a {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 8px 4px;
+ color: var(--color-ink-2, #666);
+ text-decoration: none;
+ font-size: 13px;
+ transition: color 0.2s;
+}
+
+.aksrt-dl-sidebar-card__list a:hover,
+.aksrt-dl-sidebar-card__list li.is-active a {
+ color: var(--color-primary);
+}
+
+.aksrt-dl-sidebar-card__list .count {
+ font-size: 11px;
+ color: var(--color-ink-3, #999);
+}
+
+/* Permission card */
+.aksrt-dl-perm-card {
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ padding: 16px;
+}
+
+.aksrt-dl-perm-card__status {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 12px;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.aksrt-dl-perm-card__icon--success { color: #52c41a; }
+.aksrt-dl-perm-card__icon--warning { color: #faad14; }
+
+.aksrt-dl-perm-card__cost {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ margin-bottom: 12px;
+ font-size: 13px;
+ color: var(--color-ink-2, #666);
+}
+
+.aksrt-dl-perm-card__balance {
+ color: var(--color-ink-3, #999);
+ font-size: 12px;
+}
+
+.aksrt-dl-perm-card__actions {
+ display: flex;
+ gap: 8px;
+}
+
+.aksrt-dl-perm-card__btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 8px 16px;
+ border-radius: 6px;
+ font-size: 13px;
+ font-weight: 500;
+ text-decoration: none;
+ transition: all 0.2s;
+}
+
+.aksrt-dl-perm-card__btn--primary {
+ background: var(--color-primary);
+ color: #fff;
+}
+
+.aksrt-dl-perm-card__btn--primary:hover {
+ background: var(--color-primary-hover, #40a9ff);
+}
+
+.aksrt-dl-perm-card__btn--outline {
+ background: transparent;
+ color: var(--color-primary);
+ border: 1px solid var(--color-primary);
+}
+
+.aksrt-dl-perm-card__btn--outline:hover {
+ background: var(--color-primary-soft, #e6f4ff);
+}
+
+/* Empty state */
+.aksrt-download-center__empty {
+ text-align: center;
+ padding: 48px 24px;
+ color: var(--color-ink-3, #999);
+}
+
+.aksrt-download-center__empty i {
+ font-size: 48px;
+ margin-bottom: 16px;
+ opacity: 0.3;
+}
+
+/* ============================================================
+ * Download Status Bar
+ * ============================================================ */
+.aksrt-dl-status-bar {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 16px;
+ padding: 14px 20px;
+ margin-bottom: 24px;
+ background: var(--surface-1, #fff);
+ border: 1px solid var(--color-line, #e8e8e8);
+ border-radius: 8px;
+ font-size: 13px;
+}
+
+.aksrt-dl-status-bar__item {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ color: var(--color-ink-2, #666);
+}
+
+.aksrt-dl-status-bar__item i {
+ color: var(--color-primary);
+ font-size: 14px;
+}
+
+.aksrt-dl-status-bar__label {
+ color: var(--color-ink-3, #999);
+ font-size: 12px;
+}
+
+.aksrt-dl-status-bar__value {
+ font-weight: 700;
+ color: var(--color-ink);
+ font-size: 15px;
+}
+
+.aksrt-dl-status-bar__item--hint {
+ flex: 1;
+}
+
+.aksrt-dl-status-bar__item--hint i {
+ color: var(--color-ink-3, #999);
+}
+
+.aksrt-dl-status-bar__actions {
+ display: flex;
+ gap: 8px;
+ margin-left: auto;
+}
+
+/* Download card footer with price */
+.aksrt-download-card__footer {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding-top: 8px;
+ border-top: 1px solid var(--color-line, #f0f0f0);
+ margin-top: 8px;
+}
+
+.aksrt-download-card__price {
+ font-size: 12px;
+ font-weight: 600;
+ padding: 2px 8px;
+ border-radius: 4px;
+}
+
+.aksrt-download-card__price.is-free {
+ background: #f6ffed;
+ color: #52c41a;
+}
+
+.aksrt-download-card__price.is-paid {
+ background: #fff7e6;
+ color: #fa8c16;
+}
+
+.aksrt-download-card__action {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 12px;
+ color: var(--color-primary);
+ text-decoration: none;
+ font-weight: 500;
+ transition: gap 0.2s;
+}
+
+.aksrt-download-card__action:hover {
+ gap: 6px;
+}
+
+/* Download sidebar tips */
+.aksrt-dl-sidebar-card__tips p {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 12px;
+ color: var(--color-ink-2, #666);
+ margin: 0 0 8px;
+ line-height: 1.5;
+}
+
+.aksrt-dl-sidebar-card__tips p:last-child {
+ margin-bottom: 0;
+}
+
+.aksrt-dl-sidebar-card__tips i {
+ color: var(--color-primary);
+ font-size: 11px;
+ flex-shrink: 0;
+}
+
+/* Permission card disabled state */
+.aksrt-dl-perm-card__btn--disabled {
+ opacity: 0.6;
+ cursor: not-allowed;
+}
diff --git a/assets/css/frontend/resource-meta.css b/assets/css/frontend/resource-meta.css
new file mode 100644
index 00000000..3cf61c98
--- /dev/null
+++ b/assets/css/frontend/resource-meta.css
@@ -0,0 +1,5 @@
+@import url("resource-meta/part-1.css");
+@import url("resource-meta/part-2.css");
+@import url("resource-meta/part-3.css");
+@import url("resource-meta/part-4.css");
+@import url("resource-meta/part-5.css");
diff --git a/assets/css/frontend/resource-meta/part-1.css b/assets/css/frontend/resource-meta/part-1.css
new file mode 100644
index 00000000..0a110a0f
--- /dev/null
+++ b/assets/css/frontend/resource-meta/part-1.css
@@ -0,0 +1,300 @@
+/* ============================================================
+ * 桌面端 .resource-download-box 基础样式
+ * ============================================================ */
+
+.resource-download-box {
+ padding: 20px;
+ background: var(--surface-page, #fff);
+ border: 1px solid var(--color-line, rgba(0,0,0,0.08));
+ border-radius: var(--radius-lg, 10px);
+ box-shadow: 0 2px 12px rgba(0,0,0,0.06), 0 1px 4px rgba(0,0,0,0.04);
+}
+
+/* ============================================================
+ * v2 双栏布局 — 模仿 zibll pay-box
+ * ============================================================ */
+.resource-download-box--v2 {
+ position: relative;
+ overflow: visible;
+}
+
+.resource-download-box--v2::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--color-primary), var(--color-accent));
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
+}
+
+.resource-download-box__body {
+ display: grid;
+ grid-template-columns: 200px 1fr;
+ gap: 20px;
+ align-items: start;
+}
+
+/* 缩略图列 */
+.resource-download-box__thumb-col {
+ position: relative;
+}
+
+.resource-download-box__thumb {
+ width: 100%;
+ aspect-ratio: 4 / 3;
+ object-fit: cover;
+ border-radius: var(--radius);
+ background: var(--surface-2);
+}
+
+.resource-download-box__pay-tag {
+ position: absolute;
+ top: 8px;
+ left: 8px;
+}
+
+/* 内容列 */
+.resource-download-box__content-col {
+ min-width: 0;
+}
+
+/* 价格区 */
+.resource-download-box__pricing {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+ margin: 12px 0;
+}
+
+.resource-download-box__original-price {
+ font-size: 13px;
+ color: var(--color-ink-4);
+ text-decoration: line-through;
+}
+
+/* VIP 价格区 */
+.resource-download-box__vip-pricing {
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+ margin-bottom: 12px;
+}
+
+.resource-download-box__vip-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 12px;
+ font-weight: 600;
+ padding: 4px 10px;
+ border-radius: 6px;
+ cursor: default;
+}
+
+.resource-download-box__vip-badge--1 {
+ background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
+ color: #fff;
+}
+
+.resource-download-box__vip-badge--2 {
+ background: linear-gradient(135deg, #8b5cf6 0%, #7c3aed 100%);
+ color: #fff;
+}
+
+.resource-download-box__vip-badge i {
+ font-size: 11px;
+}
+
+/* 服务保障 */
+.resource-download-box__guarantees {
+ display: flex;
+ gap: 16px;
+ flex-wrap: wrap;
+ margin-top: 12px;
+ padding-top: 12px;
+ border-top: 1px solid var(--color-line-soft);
+}
+
+.resource-download-box__guarantee {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 12px;
+ color: var(--color-success, #10B981);
+}
+
+.resource-download-box__guarantee i {
+ font-size: 12px;
+}
+
+/* 响应式 */
+@media (max-width: 640px) {
+ .resource-download-box__body {
+ grid-template-columns: 1fr;
+ }
+
+ .resource-download-box__thumb-col {
+ display: none;
+ }
+
+ .resource-download-box__guarantees {
+ gap: 12px;
+ }
+}
+
+/* 头部:标题 + 价格 */
+.resource-download-box__header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ margin-bottom: 14px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid var(--color-line, rgba(0,0,0,0.06));
+}
+
+.resource-download-box__title-wrap {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ min-width: 0;
+ flex: 1;
+}
+
+.resource-download-box__title {
+ font-size: 15px;
+ font-weight: 700;
+ margin: 0;
+ color: var(--color-ink);
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ line-height: 1.3;
+}
+
+.resource-download-box__title i {
+ color: var(--color-primary, #3B82F6);
+ font-size: 15px;
+}
+
+.resource-download-box__count {
+ font-size: 11px;
+ color: var(--color-ink-4, #8A8F98);
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+/* 价格标签 */
+.resource-download-box__price {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 13px;
+ font-weight: 700;
+ padding: 4px 10px;
+ border-radius: 20px;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+.resource-download-box__price:not(.is-free) {
+ color: var(--color-error, #EF4444);
+ background: #FEF2F2;
+}
+
+.resource-download-box__price.is-free {
+ color: var(--color-success, #10B981);
+ background: #F0FDF4;
+}
+
+/* 空状态 */
+.resource-download-box__notice--empty {
+ padding: 14px 16px;
+ background: var(--surface-2, #F4F5F7);
+ border-radius: 8px;
+ text-align: center;
+}
+
+.resource-download-box__notice--empty p {
+ margin: 0;
+ font-size: 13px;
+ color: var(--color-ink-3);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+}
+
+/* 下载源列表 */
+.resource-download-box__list {
+ list-style: none;
+ margin: 0 0 14px;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.resource-download-box__item {
+ margin: 0;
+}
+
+/* 下载按钮 */
+.resource-download-box__btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ width: 100%;
+ min-height: 44px;
+ padding: 10px 18px;
+ border: none;
+ border-radius: 10px;
+ background: var(--color-primary, #3B82F6);
+ color: #fff;
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ text-decoration: none;
+ transition: background 0.2s ease, transform 0.15s ease, box-shadow 0.2s ease, opacity 0.2s ease;
+ box-shadow: 0 2px 8px rgba(59,130,246,0.25);
+}
+
+.resource-download-box__btn:hover {
+ background: var(--color-primary-active, #2563EB);
+ box-shadow: 0 4px 14px rgba(59,130,246,0.35);
+ transform: translateY(-1px);
+}
+
+.resource-download-box__btn:active {
+ transform: scale(0.97);
+ transition-duration: 0.1s;
+}
+
+.resource-download-box__btn i {
+ font-size: 15px;
+ flex-shrink: 0;
+}
+
+.resource-download-box__btn span {
+ flex-shrink: 0;
+}
+
+/* 按钮副文案 */
+.resource-download-box__btn-sub {
+ display: block;
+ font-size: 11px;
+ font-weight: 400;
+ opacity: 0.85;
+ margin-top: 2px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+/* 类型标签 */
+.resource-download-box__type-tag {
+ display: inline-flex;
diff --git a/assets/css/frontend/resource-meta/part-2.css b/assets/css/frontend/resource-meta/part-2.css
new file mode 100644
index 00000000..f42eee80
--- /dev/null
+++ b/assets/css/frontend/resource-meta/part-2.css
@@ -0,0 +1,300 @@
+ align-items: center;
+ padding: 2px 8px;
+ margin-left: auto;
+ border-radius: 10px;
+ font-size: 11px;
+ font-weight: 500;
+ background: rgba(255,255,255,0.2);
+ flex-shrink: 0;
+}
+
+/* -- 按钮状态变体 -- */
+.resource-download-box__btn--login {
+ background: var(--color-primary, #3B82F6);
+}
+
+.resource-download-box__btn--credit-low {
+ background: var(--color-ink-4, #8A8F98) !important;
+ box-shadow: none !important;
+ cursor: not-allowed;
+ opacity: 0.7;
+}
+
+.resource-download-box__btn--credit-low:hover {
+ transform: none !important;
+}
+
+.resource-download-box__btn--paid {
+ background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
+}
+
+/* 提示文字区 */
+.resource-download-box__hint {
+ margin: 0 0 14px;
+ padding: 10px 14px;
+ border-radius: 8px;
+ font-size: 12px;
+ line-height: 1.5;
+ display: flex;
+ align-items: flex-start;
+ gap: 8px;
+}
+
+.resource-download-box__hint i {
+ font-size: 13px;
+ flex-shrink: 0;
+ margin-top: 1px;
+}
+
+.resource-download-box__hint--login {
+ color: var(--color-primary, #3B82F6);
+ background: rgba(59,130,246,0.06);
+}
+
+.resource-download-box__hint--login i {
+ color: var(--color-primary, #3B82F6);
+}
+
+.resource-download-box__hint--credit {
+ color: #D97706;
+ background: #FFFBEB;
+}
+
+.resource-download-box__hint--credit i {
+ color: #F59E0B;
+}
+
+/* 验证码表单区 - bind模式隐藏 */
+.resource-download-box__captcha {
+ margin: 0 0 14px;
+ padding: 14px;
+ border: 1px dashed var(--color-line, rgba(0,0,0,0.12));
+ border-radius: 8px;
+ background: var(--surface-2, #FAFAFB);
+}
+
+/* bind 模式:容器保留但视觉隐藏(仍作为挂载点) */
+.resource-download-box__captcha--hidden {
+ padding: 0 !important;
+ border: none !important;
+ background: transparent !important;
+ margin: 0 !important;
+ min-height: 0;
+ overflow: hidden;
+ /* 极验bind按钮也隐藏,通过JS触发 */
+}
+.resource-download-box__captcha--hidden > * {
+ visibility: hidden;
+ height: 0;
+ overflow: hidden;
+ pointer-events: none;
+}
+
+/* 底部免责 */
+.resource-download-box__footer {
+ margin: 0;
+ padding-top: 12px;
+ border-top: 1px solid var(--color-line, rgba(0,0,0,0.06));
+}
+
+.resource-download-box__notice-text {
+ margin: 0;
+ font-size: 11px;
+ line-height: 1.6;
+ color: var(--color-ink-4, #8A8F98);
+ display: flex;
+ align-items: flex-start;
+ gap: 6px;
+}
+
+.resource-download-box__notice-text i {
+ font-size: 12px;
+ flex-shrink: 0;
+ margin-top: 2px;
+ color: var(--color-ink-4, #8A8F98);
+}
+
+/* 被拦截态(登录/积分不足)不透明 */
+.resource-download-box.is-blocked {
+ opacity: 1;
+}
+
+
+/* ============================================================
+ * v4.3 资源侧栏下载卡片(垂直布局,适合 300px 侧栏宽度)
+ * ============================================================ */
+
+.resource-sidebar-sticky {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+/* 下载卡片 */
+.resource-download-card {
+ overflow: hidden;
+}
+
+.resource-download-card__thumb {
+ width: 100%;
+ aspect-ratio: 16 / 10;
+ overflow: hidden;
+ border-radius: 8px 8px 0 0;
+}
+
+.resource-download-card__thumb img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.resource-download-card__body {
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.resource-download-card__title {
+ font-size: 15px;
+ font-weight: 700;
+ margin: 0;
+ line-height: 1.35;
+ color: var(--color-ink);
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.resource-download-card__desc {
+ font-size: 13px;
+ color: var(--color-ink-4);
+ line-height: 1.5;
+ margin: 0;
+}
+
+/* 价格 */
+.resource-download-card__price {
+ padding: 6px 0;
+}
+
+.resource-price {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 14px;
+ font-weight: 700;
+}
+
+.resource-price--paid {
+ color: var(--color-error, #ef4444);
+}
+
+.resource-price--paid i {
+ color: #f59e0b;
+}
+
+.resource-price--paid strong {
+ font-size: 1.25rem;
+}
+
+.resource-price--paid small {
+ font-size: 12px;
+ font-weight: 400;
+ color: var(--color-ink-4);
+}
+
+.resource-price--free {
+ color: var(--color-success, #34a853);
+}
+
+/* 下载按钮区 */
+.resource-download-card__actions {
+ padding: 4px 0;
+}
+
+/* 已下载数 */
+.resource-download-card__sales {
+ font-size: 12px;
+ color: var(--color-ink-4);
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+/* 演示链接 */
+.resource-download-card__demo {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ padding: 8px;
+ border-radius: 6px;
+ background: var(--surface-3);
+ color: var(--color-ink-3);
+ font-size: 13px;
+ text-decoration: none;
+ transition: background 0.2s, color 0.2s;
+}
+
+.resource-download-card__demo:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.12));
+ color: var(--color-primary);
+ text-decoration: none;
+}
+
+/* 资源属性卡片 */
+.resource-meta-card__title {
+ font-size: 13px;
+ font-weight: 700;
+ margin: 0 0 10px;
+ color: var(--color-ink);
+}
+
+.resource-meta-card__list {
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.resource-meta-card__row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 13px;
+}
+
+.resource-meta-card__row dt {
+ color: var(--color-ink-4);
+ margin: 0;
+}
+
+.resource-meta-card__row dd {
+ color: var(--color-ink);
+ font-weight: 500;
+ margin: 0;
+ text-align: right;
+}
+
+/* 服务保障卡片 */
+.resource-guarantee-card__list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ font-size: 12px;
+ color: var(--color-ink-4);
+}
+
+.resource-guarantee-card__list span {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.resource-guarantee-card__list i {
+ color: var(--color-success, #34a853);
+ font-size: 13px;
+}
+
diff --git a/assets/css/frontend/resource-meta/part-3.css b/assets/css/frontend/resource-meta/part-3.css
new file mode 100644
index 00000000..b14b11ea
--- /dev/null
+++ b/assets/css/frontend/resource-meta/part-3.css
@@ -0,0 +1,300 @@
+/* 移动端:侧栏变为正文下方(由 layout.css 统一处理隐藏) */
+
+/* ============================================================
+ * v5.0 移动端下载区域重构(992px 以下生效)
+ *
+ * 设计原则:
+ * - 块级卡片容器,匹配 .theme-box.box-body.radius8 风格
+ * - 下载项纵向堆叠,每项独立卡片,触摸友好(min-height:48px)
+ * - 纯色配色,禁止渐变/紫色,使用 Font Awesome 图标包
+ * ============================================================ */
+
+/* ----- 移动端下载区域容器(块级卡片) ----- */
+.resource-mobile-download-bar {
+ display: none; /* 默认隐藏,媒体查询中启用 */
+ margin: 16px 0;
+ background: var(--surface-page, #fff);
+ border: 1px solid var(--color-line, rgba(0,0,0,0.08));
+ border-radius: var(--radius-lg, 10px);
+ box-shadow: 0 2px 12px rgba(0,0,0,0.06), 0 1px 4px rgba(0,0,0,0.04);
+ overflow: hidden;
+}
+
+/* ===== resource-download-box 组件移动端样式 ===== */
+
+/* 组件根 */
+.resource-mobile-download-bar .resource-download-box {
+ padding: 0;
+ margin: 0;
+}
+
+.resource-mobile-download-bar .resource-download-box.is-blocked {
+ opacity: 1;
+}
+
+/* ---- 头部区:标题 + 价格 + 源数量 ---- */
+.resource-mobile-download-bar .resource-download-box__header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ padding: 16px 16px 12px;
+ border-bottom: 1px solid var(--color-line, rgba(0,0,0,0.06));
+}
+
+.resource-mobile-download-bar .resource-download-box__title-wrap {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ min-width: 0;
+ flex: 1;
+}
+
+.resource-mobile-download-bar .resource-download-box__title {
+ font-size: 15px;
+ font-weight: 700;
+ margin: 0;
+ color: var(--color-ink);
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ line-height: 1.3;
+}
+
+.resource-mobile-download-bar .resource-download-box__title i {
+ color: var(--color-primary, #3B82F6);
+ font-size: 15px;
+}
+
+.resource-mobile-download-bar .resource-download-box__count {
+ font-size: 11px;
+ color: var(--color-ink-4, #8A8F98);
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+/* 头部价格标签 */
+.resource-mobile-download-bar .resource-download-box__price {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 13px;
+ font-weight: 700;
+ padding: 4px 10px;
+ border-radius: 20px;
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+.resource-mobile-download-bar .resource-download-box__price:not(.is-free) {
+ color: var(--color-error, #EF4444);
+ background: #FEF2F2;
+}
+
+.resource-mobile-download-bar .resource-download-box__price.is-free {
+ color: var(--color-success, #10B981);
+ background: #F0FDF4;
+}
+
+/* ---- 空状态提示 ---- */
+.resource-mobile-download-bar .resource-download-box__notice--empty {
+ margin: 16px;
+ padding: 14px 16px;
+ background: var(--surface-2, #F4F5F7);
+ border-radius: 8px;
+ text-align: center;
+}
+
+.resource-mobile-download-bar .resource-download-box__notice--empty p {
+ margin: 0;
+ font-size: 13px;
+ color: var(--color-ink-3);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+}
+
+.resource-mobile-download-bar .resource-download-box__notice--empty i {
+ color: var(--color-primary, #3B82F6);
+}
+
+/* ---- 下载源列表 ---- */
+.resource-mobile-download-bar .resource-download-box__list {
+ list-style: none;
+ margin: 0;
+ padding: 12px 16px 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+/* ---- 下载项(每个一行) ---- */
+.resource-mobile-download-bar .resource-download-box__item {
+ margin: 0;
+}
+
+/* ---- 下载按钮(核心交互元素)---- */
+.resource-mobile-download-bar .resource-download-box__btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ width: 100%;
+ min-height: 50px; /* 触摸友好 */
+ padding: 12px 20px;
+ border: none;
+ border-radius: 10px;
+ background: var(--color-primary, #3B82F6);
+ color: #fff;
+ font-size: 14px;
+ font-weight: 600;
+ cursor: pointer;
+ text-decoration: none;
+ position: relative;
+ overflow: hidden;
+ transition: background 0.2s ease, transform 0.15s ease, box-shadow 0.2s ease, opacity 0.2s ease;
+ box-shadow: 0 2px 8px rgba(59,130,246,0.3);
+ -webkit-tap-highlight-color: transparent;
+}
+
+.resource-mobile-download-bar .resource-download-box__btn i {
+ font-size: 16px;
+ flex-shrink: 0;
+}
+
+.resource-mobile-download-bar .resource-download-box__btn span {
+ flex-shrink: 0;
+}
+
+/* 按钮副文案(来源名称 / 余额信息)*/
+.resource-mobile-download-bar .resource-download-box__btn-sub {
+ display: block;
+ font-size: 11px;
+ font-weight: 400;
+ opacity: 0.85;
+ margin-top: 2px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 100%;
+}
+
+/* 类型标签(网盘/外链)*/
+.resource-mobile-download-bar .resource-download-box__type-tag {
+ display: inline-flex;
+ align-items: center;
+ padding: 2px 8px;
+ margin-left: auto;
+ border-radius: 10px;
+ font-size: 11px;
+ font-weight: 500;
+ background: rgba(255,255,255,0.2);
+ flex-shrink: 0;
+}
+
+/* -- 按钮状态变体 -- */
+
+/* 正常态 hover */
+.resource-mobile-download-bar .resource-download-box__btn:hover {
+ background: var(--color-primary-active, #2563EB);
+ box-shadow: 0 4px 14px rgba(59,130,246,0.4);
+ transform: translateY(-1px);
+}
+
+/* active 按压反馈 */
+.resource-mobile-download-bar .resource-download-box__btn:active {
+ transform: scale(0.97);
+ transition-duration: 0.1s;
+}
+
+/* 登录拦截态 */
+.resource-mobile-download-bar .resource-download-box__btn--login {
+ background: var(--color-primary, #3B82F6);
+}
+
+/* 余额不足态(禁用外观)*/
+.resource-mobile-download-bar .resource-download-box__btn--credit-low {
+ background: var(--color-ink-4, #8A8F98);
+ box-shadow: none;
+ cursor: not-allowed;
+ opacity: 0.7;
+}
+
+.resource-mobile-download-bar .resource-download-box__btn--credit-low:hover {
+ transform: none;
+ box-shadow: none;
+ background: var(--color-ink-4, #8A8F98);
+}
+
+/* 付费下载态 */
+.resource-mobile-download-bar .resource-download-box__btn--paid {
+ background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
+}
+
+/* ---- 提示文字区 ---- */
+.resource-mobile-download-bar .resource-download-box__hint {
+ margin: 0 16px 12px;
+ padding: 10px 14px;
+ border-radius: 8px;
+ font-size: 12px;
+ line-height: 1.5;
+ display: flex;
+ align-items: flex-start;
+ gap: 8px;
+}
+
+.resource-mobile-download-bar .resource-download-box__hint i {
+ font-size: 14px;
+ flex-shrink: 0;
+ margin-top: 1px;
+}
+
+.resource-mobile-download-bar .resource-download-box__hint--login {
+ color: var(--color-primary, #3B82F6);
+ background: rgba(59,130,246,0.06);
+}
+
+.resource-mobile-download-bar .resource-download-box__hint--login i {
+ color: var(--color-primary, #3B82F6);
+}
+
+.resource-mobile-download-bar .resource-download-box__hint--credit {
+ color: #D97706;
+ background: #FFFBEB;
+}
+
+.resource-mobile-download-bar .resource-download-box__hint--credit i {
+ color: #F59E0B;
+}
+
+/* ---- 验证码表单区 ---- */
+.resource-mobile-download-bar .resource-download-box__captcha {
+ margin: 0 16px 16px;
+ padding: 14px;
+ border: 1px dashed var(--color-line, rgba(0,0,0,0.12));
+ border-radius: 8px;
+ background: var(--surface-2, #FAFAFB);
+}
+
+/* ---- 底部免责声明 ---- */
+.resource-mobile-download-bar .resource-download-box__footer {
+ margin: 0;
+ padding: 12px 16px;
+ border-top: 1px solid var(--color-line, rgba(0,0,0,0.06));
+}
+
+.resource-mobile-download-bar .resource-download-box__notice-text {
+ margin: 0;
+ font-size: 11px;
+ line-height: 1.6;
+ color: var(--color-ink-4, #8A8F98);
+ display: flex;
+ align-items: flex-start;
+ gap: 6px;
+}
+
+.resource-mobile-download-bar .resource-download-box__notice-text i {
+ font-size: 12px;
+ flex-shrink: 0;
+ margin-top: 2px;
diff --git a/assets/css/frontend/resource-meta/part-4.css b/assets/css/frontend/resource-meta/part-4.css
new file mode 100644
index 00000000..8aa36b91
--- /dev/null
+++ b/assets/css/frontend/resource-meta/part-4.css
@@ -0,0 +1,300 @@
+ color: var(--color-ink-4, #8A8F98);
+}
+
+
+/* ----- 移动端悬浮下载按钮(FAB) ----- */
+.resource-mobile-fab {
+ display: none; /* 默认隐藏,移动端媒体查询中启用 */
+ position: fixed;
+ bottom: 72px;
+ right: 20px;
+ z-index: 950;
+ width: 56px;
+ height: 56px;
+ border-radius: 50%;
+ background: var(--color-primary, #3B82F6);
+ color: #fff;
+ text-decoration: none;
+ display: flex; /* 覆盖上面的 display:none */
+ align-items: center;
+ justify-content: center;
+ font-size: 22px;
+ box-shadow: 0 4px 16px rgba(59,130,246,0.35), 0 2px 6px rgba(0,0,0,0.1);
+ opacity: 0;
+ transform: scale(0.8) translateY(10px);
+ transition: opacity 0.35s cubic-bezier(0.4, 0, 0.2, 1), transform 0.35s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.3s ease;
+ pointer-events: none;
+ -webkit-tap-highlight-color: transparent;
+ animation: fabFadeIn 0.5s 1.5s forwards;
+}
+
+@keyframes fabFadeIn {
+ to {
+ opacity: 1;
+ transform: scale(1) translateY(0);
+ pointer-events: auto;
+ }
+}
+
+.resource-mobile-fab:hover {
+ transform: scale(1.08) translateY(-2px);
+ box-shadow: 0 6px 24px rgba(59,130,246,0.45), 0 4px 10px rgba(0,0,0,0.15);
+ color: #fff;
+}
+
+.resource-mobile-fab:active {
+ transform: scale(0.95);
+ transition-duration: 0.1s;
+}
+
+/* FAB脉冲效果(吸引注意) */
+.resource-mobile-fab::after {
+ content: '';
+ position: absolute;
+ inset: -4px;
+ border-radius: 50%;
+ background: transparent;
+ border: 2px solid var(--color-primary, #3B82F6);
+ opacity: 0;
+ animation: fabPulse 2s 2.5s infinite;
+}
+
+@keyframes fabPulse {
+ 0% { transform: scale(1); opacity: 0.6; }
+ 100% { transform: scale(1.4); opacity: 0; }
+}
+
+
+/* ============================================================
+ * 响应式媒体查询
+ * ============================================================ */
+
+/* 移动端/平板(< 992px):显示移动端下载栏和FAB */
+@media (max-width: 991px) {
+ .resource-mobile-download-bar {
+ display: block;
+ }
+
+ .resource-mobile-fab {
+ display: flex;
+ bottom: calc(72px + env(safe-area-inset-bottom, 0px));
+ right: calc(20px + env(safe-area-inset-right, 0px));
+ }
+
+ /* 超小屏适配(<= 380px) */
+ @media (max-width: 380px) {
+ .resource-mobile-download-bar .resource-download-box__header {
+ flex-wrap: wrap;
+ gap: 8px;
+ padding: 14px 12px 10px;
+ }
+
+ .resource-mobile-download-bar .resource-download-box__list {
+ padding: 10px 12px 14px;
+ gap: 8px;
+ }
+
+ .resource-mobile-download-bar .resource-download-box__btn {
+ min-height: 46px;
+ padding: 10px 14px;
+ font-size: 13px;
+ }
+
+ .resource-mobile-download-bar .resource-download-box__title {
+ font-size: 14px;
+ }
+
+ .resource-mobile-download-bar .resource-download-box__hint,
+ .resource-mobile-download-bar .resource-download-box__footer,
+ .resource-mobile-download-bar .resource-download-box__captcha {
+ margin-left: 12px;
+ margin-right: 12px;
+ }
+ }
+}
+
+/* 桌面端(>= 992px):隐藏移动端元素,保持原侧栏布局 */
+@media (min-width: 992px) {
+ .resource-mobile-download-bar {
+ display: none !important;
+ }
+
+ .resource-mobile-fab {
+ display: none !important;
+ }
+}
+
+/* ============================================================
+ * 云服务品牌按钮样式
+ * ============================================================ */
+.resource-download-box__btn--service-baidu {
+ background: linear-gradient(135deg, #1578f8 0%, #0d65d9 100%);
+}
+
+.resource-download-box__btn--service-lanzou {
+ background: linear-gradient(135deg, #f37526 0%, #e06318 100%);
+}
+
+.resource-download-box__btn--service-aliyun {
+ background: linear-gradient(135deg, #6666ff 0%, #5050e0 100%);
+}
+
+.resource-download-box__btn--service-weiyun {
+ background: linear-gradient(135deg, #4facfe 0%, #3a8fd4 100%);
+}
+
+.resource-download-box__btn--service-onedrive {
+ background: linear-gradient(135deg, #0078d4 0%, #006abc 100%);
+}
+
+.resource-download-box__btn--service-tianyi {
+ background: linear-gradient(135deg, #0099ff 0%, #0080e0 100%);
+}
+
+.resource-download-box__btn--service-123pan {
+ background: linear-gradient(135deg, #2b7bff 0%, #1a65e0 100%);
+}
+
+.resource-download-box__btn--service-quark {
+ background: linear-gradient(135deg, #6a5acd 0%, #5a4ab5 100%);
+}
+
+.resource-download-box__btn--service-xunlei {
+ background: linear-gradient(135deg, #00a4ff 0%, #0090e0 100%);
+}
+
+.resource-download-box__btn--service-mega {
+ background: linear-gradient(135deg, #d92323 0%, #c01a1a 100%);
+}
+
+.resource-download-box__btn--service-github {
+ background: linear-gradient(135deg, #333333 0%, #1a1a1a 100%);
+}
+
+/* 云服务徽章 */
+.resource-download-box__service-badge {
+ display: inline-block;
+ font-size: 10px;
+ font-weight: 600;
+ padding: 2px 6px;
+ border-radius: 4px;
+ color: #fff;
+ margin-left: 6px;
+ letter-spacing: 0.02em;
+ line-height: 1.3;
+}
+
+/* ============================================================
+ * 元信息卡片图标增强
+ * ============================================================ */
+.resource-meta-box__key {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+.resource-meta-box__key i {
+ width: 16px;
+ text-align: center;
+ color: var(--color-ink-4, #8A8F98);
+ font-size: 13px;
+ flex-shrink: 0;
+}
+
+/* ============================================================
+ * 渐变价格标签(模仿 zibll 渐变 pay-tag)
+ * ============================================================ */
+.resource-download-box__price--gradient {
+ background: linear-gradient(135deg, #EF4444 0%, #F97316 100%);
+ color: #fff;
+ font-weight: 700;
+ padding: 5px 12px;
+ border-radius: 20px;
+ font-size: 13px;
+}
+
+.resource-download-box__price--gradient.is-free {
+ background: linear-gradient(135deg, #10B981 0%, #059669 100%);
+}
+
+/* ============================================================
+ * 销量/下载量徽章
+ * ============================================================ */
+.resource-download-box__sales-badge {
+ position: absolute;
+ top: -8px;
+ right: -8px;
+ background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
+ color: #fff;
+ font-size: 11px;
+ font-weight: 600;
+ padding: 3px 8px;
+ border-radius: 12px;
+ box-shadow: 0 2px 6px rgba(59, 130, 246, 0.3);
+ white-space: nowrap;
+}
+
+/* ============================================================
+ * 下载框整体增强 — 模仿 zibll pay-box 视觉重量
+ * ============================================================ */
+.resource-download-box {
+ position: relative;
+ overflow: visible;
+}
+
+.resource-download-box::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--color-primary), var(--color-accent));
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
+}
+
+/* ============================================================
+ * 付费类型徽章 — 模仿 zibll 渐变 pay-tag
+ * ============================================================ */
+.resource-pay-type-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ font-size: 11px;
+ font-weight: 600;
+ padding: 3px 8px;
+ border-radius: 4px;
+ color: #fff;
+ line-height: 1.3;
+ letter-spacing: 0.02em;
+}
+
+.resource-pay-type-badge i {
+ font-size: 10px;
+}
+
+/* 在归档卡片上的徽章位置 */
+.post-card .resource-pay-type-badge {
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ z-index: 2;
+}
+
+/* 在下载框内的徽章 */
+.resource-download-box__header .resource-pay-type-badge {
+ margin-left: 8px;
+}
+
+/* ============================================================
+ * 原价划线 — 模仿 zibll .original-price
+ * ============================================================ */
+.resource-original-price {
+ font-size: 13px;
+ color: var(--color-ink-4);
+ text-decoration: line-through;
+ margin-left: 6px;
+}
+
+.resource-original-price::before {
+ content: '';
diff --git a/assets/css/frontend/resource-meta/part-5.css b/assets/css/frontend/resource-meta/part-5.css
new file mode 100644
index 00000000..03274875
--- /dev/null
+++ b/assets/css/frontend/resource-meta/part-5.css
@@ -0,0 +1,55 @@
+ position: absolute;
+ left: -2px;
+ right: -2px;
+ top: 50%;
+ height: 1px;
+ background: var(--color-ink-4);
+ transform: rotate(-8deg);
+}
+
+/* ============================================================
+ * 视频播放器容器
+ * ============================================================ */
+.resource-video-container {
+ position: relative;
+ width: 100%;
+ padding-bottom: 56.25%;
+ margin: 16px 0;
+ border-radius: var(--radius-lg);
+ overflow: hidden;
+ background: #000;
+}
+
+.resource-video-container iframe {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ border: none;
+}
+
+/* ============================================================
+ * 付费图库预览
+ * ============================================================ */
+.resource-gallery-locked {
+ position: relative;
+ filter: blur(8px);
+ pointer-events: none;
+ user-select: none;
+}
+
+.resource-gallery-locked::after {
+ content: '\f023';
+ font-family: 'Font Awesome 5 Free';
+ font-weight: 900;
+ position: absolute;
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 32px;
+ color: rgba(255, 255, 255, 0.8);
+ background: rgba(0, 0, 0, 0.3);
+}
+
diff --git a/assets/css/frontend/sidebar.css b/assets/css/frontend/sidebar.css
new file mode 100644
index 00000000..04330043
--- /dev/null
+++ b/assets/css/frontend/sidebar.css
@@ -0,0 +1,167 @@
+/* ========== 侧边栏 — 对齐 zibll sidebar ========== */
+.sidebar {
+ width: var(--sidebar-width, 311px);
+ flex-shrink: 0;
+}
+
+.sidebar-inner {
+ position: sticky;
+ top: calc(var(--nav-height, 60px) + 16px);
+}
+
+/* Widget 通用 */
+.widget {
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius, 8px);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
+ margin-bottom: 16px;
+ overflow: hidden;
+}
+
+.widget-title {
+ font-size: 15px;
+ color: var(--color-ink, #333);
+ padding-bottom: 8px;
+ margin-bottom: 10px;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.widget-title i {
+ color: var(--color-primary, #f04494);
+ font-size: 14px;
+}
+
+.widget-content {
+ padding: 15px;
+}
+
+.widget-content--flush {
+ padding: 0;
+}
+
+/* Widget 链接 */
+.widget a {
+ color: var(--color-ink-2, #4e5358);
+ text-decoration: none;
+ transition: color 0.2s;
+}
+
+.widget a:hover {
+ color: var(--color-primary, #f04494);
+}
+
+/* Widget 标签云 */
+.widget-tag-cloud .tagcloud {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+}
+
+.widget-tag-cloud .tagcloud a {
+ display: inline-block;
+ padding: 3px 10px;
+ font-size: 12px !important;
+ background: var(--surface-2, #eee);
+ border-radius: 4px;
+ color: var(--color-ink-2, #4e5358);
+ transition: all 0.2s;
+}
+
+.widget-tag-cloud .tagcloud a:hover {
+ background: var(--color-primary-soft, rgba(240, 68, 148, 0.1));
+ color: var(--color-primary, #f04494);
+}
+
+/* Widget 列表 */
+.widget ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.widget ul li {
+ padding: 8px 0;
+ font-size: 13px;
+ line-height: 1.6;
+}
+
+.widget ul li:last-child {
+ border-bottom: none;
+}
+
+/* 热门文章 widget */
+.widget-hot-posts .hot-post-item {
+ display: flex;
+ gap: 10px;
+ padding: 8px 0;
+ border-bottom: 1px solid var(--color-line-soft, rgba(0, 0, 0, 0.03));
+}
+
+.widget-hot-posts .hot-post-item:last-child {
+ border-bottom: none;
+}
+
+.widget-hot-posts .hot-post-item__thumb {
+ width: 60px;
+ height: 45px;
+ border-radius: 4px;
+ object-fit: cover;
+ flex-shrink: 0;
+}
+
+.widget-hot-posts .hot-post-item__title {
+ font-size: 13px;
+ color: var(--color-ink, #333);
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+.widget-hot-posts .hot-post-item__meta {
+ font-size: 11px;
+ color: var(--color-ink-4, #999);
+ margin-top: 2px;
+}
+
+/* 用户卡片 widget */
+.widget-user-card {
+ text-align: center;
+ padding: 20px 16px;
+}
+
+.widget-user-card__avatar {
+ width: 64px;
+ height: 64px;
+ border-radius: 50%;
+ object-fit: cover;
+ margin-bottom: 10px;
+}
+
+.widget-user-card__name {
+ font-size: 15px;
+ font-weight: 600;
+ color: var(--color-ink, #333);
+ margin-bottom: 4px;
+}
+
+.widget-user-card__desc {
+ font-size: 12px;
+ color: var(--color-ink-3, #777);
+ margin-bottom: 12px;
+}
+
+/* 侧边栏响应式 */
+@media (max-width: 1200px) {
+ .sidebar {
+ width: 280px;
+ }
+}
+
+@media (max-width: 991px) {
+ .sidebar {
+ display: none;
+ }
+}
diff --git a/assets/css/frontend/single-post.css b/assets/css/frontend/single-post.css
new file mode 100644
index 00000000..fc82184b
--- /dev/null
+++ b/assets/css/frontend/single-post.css
@@ -0,0 +1,7 @@
+@import url("single-post/content.css");
+@import url("single-post/code-blocks.css");
+@import url("single-post/navigation.css");
+@import url("single-post/cover.css");
+@import url("single-post/author-actions.css");
+@import url("single-post/related-toc.css");
+@import url("single-post/hidden-content.css");
diff --git a/assets/css/frontend/single-post/author-actions.css b/assets/css/frontend/single-post/author-actions.css
new file mode 100644
index 00000000..1cf33304
--- /dev/null
+++ b/assets/css/frontend/single-post/author-actions.css
@@ -0,0 +1,441 @@
+/* ===== 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-card,
+.post-actions {
+ position: relative;
+ text-align: center;
+ margin-bottom: 16px;
+}
+
+.post-actions-card__hint {
+ font-size: 13px;
+ color: var(--color-ink-4, var(--color-ink-4));
+ margin-bottom: 12px;
+}
+
+.post-actions-card__buttons,
+.post-actions {
+ display: flex;
+ justify-content: center;
+ gap: 10px;
+ margin-bottom: 12px;
+}
+
+.action-btn,
+.action {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 0.3em 1em;
+ border-radius: 50px;
+ border: none;
+ background: rgba(136, 136, 136, 0.1);
+ color: #888;
+ cursor: pointer;
+ font-size: 14px;
+ transition: all 0.15s ease;
+}
+
+.action-btn:hover,
+.action:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.action-btn.is-active,
+.action.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,
+.action i { font-size: 1.2em; }
+.action-btn__count { font-weight: 600; }
+.action-btn__label { font-size: 13px; }
+
+/* ===== 分享下拉面板 ===== */
+
+/* 确保父容器作为定位参考 */
+.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-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 .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 — 对齐 zibll 卡片容器 ===== */
+.author-box {
+ margin-bottom: 16px;
+ padding: 15px;
+ background: var(--main-bg-color, #fff);
+ border-radius: var(--main-radius, 8px);
+ box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
+}
+
+.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); }
+
diff --git a/assets/css/frontend/single-post/code-blocks.css b/assets/css/frontend/single-post/code-blocks.css
new file mode 100644
index 00000000..22f97a57
--- /dev/null
+++ b/assets/css/frontend/single-post/code-blocks.css
@@ -0,0 +1,128 @@
+/* ========== 浠g爜鍧?GitHub 椋庢牸 ========== */
+.code-block {
+ border-radius: var(--radius-code);
+ border: 1px solid var(--color-line);
+ overflow: hidden;
+ margin: 1.5em 0;
+ background: var(--surface-3);
+}
+
+.code-block__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 36px;
+ padding: 0 12px;
+ background: var(--surface-3);
+ border-bottom: 1px solid var(--color-line);
+ font-size: 12px;
+ color: var(--color-ink-3);
+}
+
+.code-block__copy {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 12px;
+ border-radius: 6px;
+ border: 1px solid var(--color-line);
+ background: var(--surface-page);
+ cursor: pointer;
+ font-size: 12px;
+ color: var(--color-ink-3);
+}
+
+.code-block__copy:hover {
+ border-color: var(--color-primary);
+ color: var(--color-primary);
+}
+
+.code-block__body {
+ overflow-x: auto;
+ padding: 16px 20px;
+ font-family: var(--font-mono);
+ font-size: 13.5px;
+ line-height: 1.6;
+}
+
+@media (max-width: 767px) {
+ .code-block__body {
+ font-size: 12px;
+ padding: 12px 14px;
+ }
+}
+
+.entry-content pre.wp-block-code,
+.entry-content pre:not(.wp-block-preformatted) {
+ border-radius: var(--radius-code);
+ border: 1px solid var(--color-line);
+ background: var(--surface-3);
+ padding: 0;
+ overflow: hidden;
+}
+
+.entry-content pre code {
+ display: block;
+ padding: 16px 20px;
+ overflow-x: auto;
+ background: transparent;
+ font-size: 13.5px;
+ line-height: 1.6;
+}
+
+/* Syntax highlight utilities (plugin or wrapped markup) */
+.gh-keyword {
+ color: #cf222e;
+}
+
+html.dark .gh-keyword,
+html.dark .gh-keyword {
+ color: #ff7b72;
+}
+
+.gh-string {
+ color: #0a3069;
+}
+
+html.dark .gh-string,
+html.dark .gh-string {
+ color: #a5d6ff;
+}
+
+.gh-comment {
+ color: #6e7781;
+ font-style: italic;
+}
+
+html.dark .gh-comment,
+html.dark .gh-comment {
+ color: #8b949e;
+}
+
+.gh-function {
+ color: #8250df;
+}
+
+html.dark .gh-function,
+html.dark .gh-function {
+ color: #d2a8ff;
+}
+
+.gh-var {
+ color: #0550ae;
+}
+
+html.dark .gh-var,
+html.dark .gh-var {
+ color: #79c0ff;
+}
+
+.gh-op {
+ color: #24292f;
+}
+
+html.dark .gh-op,
+html.dark .gh-op {
+ color: #c9d1d9;
+}
+
diff --git a/assets/css/frontend/single-post/content.css b/assets/css/frontend/single-post/content.css
new file mode 100644
index 00000000..780a879d
--- /dev/null
+++ b/assets/css/frontend/single-post/content.css
@@ -0,0 +1,290 @@
+/* ========== Single Post ========== */
+.entry-header,
+.article-header {
+ margin-bottom: 24px;
+}
+
+/* 标题 — 对齐 zibll: 22px, bold, line-height 1.4 */
+.entry-title,
+.article-title {
+ font-size: 22px;
+ font-weight: 700;
+ margin: 0 0 16px;
+ line-height: 1.4;
+}
+
+.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;
+}
+
+/* 内容区 — 对齐 zibll: 16px, line-height 2 */
+.entry-content {
+ font-size: 16px;
+ line-height: 2;
+ color: var(--color-ink);
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ min-height: 90px;
+}
+
+.entry-content > *:first-child {
+ margin-top: 0;
+}
+
+.entry-content p {
+ margin: 0 0 1.5em;
+}
+
+.entry-content h2 {
+ font-size: 20px;
+ font-weight: 700;
+ margin: 20px 0 10px;
+}
+
+.entry-content h3 {
+ font-size: 18px;
+ font-weight: 700;
+ margin: 20px 0 10px;
+}
+
+.entry-content blockquote {
+ margin: 0 0 20px;
+ padding: 15px 20px;
+ border-left: 4px solid var(--main-border-color, rgba(50, 50, 50, 0.06));
+ background: var(--muted-border-color, rgba(0, 0, 0, 0.03));
+ border-radius: 0;
+ color: var(--muted-color, #777);
+}
+
+.entry-content img {
+ margin: 0 auto;
+ display: block;
+ max-width: 100%;
+ height: auto;
+}
+
+/* ===== 图片灯箱 ===== */
+.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;
+}
+
+.entry-content iframe,
+.entry-content .wp-block-embed iframe,
+.entry-content video {
+ max-width: 100%;
+ height: auto;
+}
+
+.entry-content .wp-block-embed {
+ position: relative;
+ width: 100%;
+ max-width: 100%;
+ overflow: hidden;
+ margin: 1.5em 0;
+}
+
+/* 行内代码 — 对齐 zibll: 粉色文字 + 粉色背景 */
+.entry-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;
+}
+
+.entry-content ul,
+.entry-content ol {
+ padding-left: 1.5em;
+ margin: 0 0 1.5em;
+}
+
+.entry-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;
+}
+
+.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;
+}
+
diff --git a/assets/css/frontend/single-post/cover.css b/assets/css/frontend/single-post/cover.css
new file mode 100644
index 00000000..577e0a66
--- /dev/null
+++ b/assets/css/frontend/single-post/cover.css
@@ -0,0 +1,192 @@
+/* ============================================================
+ * v4.3 cover, author bar, actions, author card, nav, and related posts
+ * The cover stays inside the content column with a fixed aspect ratio box.
+ * ============================================================ */
+
+/* ===== Cover (in-column ratio box) ===== */
+.single-cover {
+ position: relative;
+ overflow: hidden;
+ border-radius: 8px;
+ margin-bottom: 16px;
+ padding-bottom: var(--single-cover-scale, 35%);
+}
+
+.single-cover > .fit-cover,
+.single-cover > img {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.single-cover__overlay {
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(
+ to bottom,
+ rgba(0, 0, 0, 0) 30%,
+ rgba(0, 0, 0, 0.6) 100%
+ );
+ pointer-events: none;
+}
+
+.single-cover__content {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: 20px;
+ color: #fff;
+ border-radius: 0 0 8px 8px;
+}
+
+.single-cover__title,
+.single-cover__content .article-title {
+ font-size: clamp(1.125rem, 2.5vw, 1.5rem);
+ font-weight: 700;
+ margin: 0 0 6px;
+ line-height: 1.35;
+ text-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
+ color: #fff;
+}
+
+.single-cover__meta,
+.single-cover__content .cover-meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ font-size: 12px;
+ opacity: 0.85;
+}
+
+.single-cover__meta span,
+.single-cover__content .cover-meta .meta-view {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+}
+
+/* ===== Video Cover ===== */
+.single-cover--video {
+ background: #000;
+}
+
+.single-cover--video .single-cover__video {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+/* ===== Slide Cover ===== */
+.single-cover--slide {
+ background: var(--color-bg-2, #f5f5f5);
+}
+
+.single-cover__slides {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+}
+
+.single-cover__slide {
+ position: absolute;
+ inset: 0;
+ opacity: 0;
+ transition: opacity 0.6s ease;
+}
+
+.single-cover__slide.is-active {
+ opacity: 1;
+}
+
+.single-cover__slide img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.single-cover__dots {
+ position: absolute;
+ bottom: 12px;
+ right: 16px;
+ display: flex;
+ gap: 6px;
+ z-index: 2;
+}
+
+.single-cover__dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.5);
+ transition: background 0.3s ease;
+ cursor: pointer;
+}
+
+.single-cover__dot.is-active {
+ background: #fff;
+}
+
+/* ===== 面包屑 ===== */
+.post-breadcrumbs {
+ margin-bottom: 12px;
+ font-size: 13px;
+ color: var(--color-ink-4, var(--color-ink-4));
+}
+
+.article-title + .img-badge,
+.single-head-cover .img-badge.right,
+.article-header .img-badge.right {
+ position: absolute;
+ top: 14px;
+ right: 14px;
+ z-index: 2;
+}
+
+.article-avatar {
+ position: relative;
+}
+
+.article-avatar .line-form-line,
+.article-avatar .line-form-line::before {
+ position: absolute;
+ top: 50%;
+ left: calc(52px + 16px);
+ right: 120px;
+ height: 1px;
+ transform: translateY(-50%);
+ background: var(--color-line);
+}
+
+.article-avatar .line-form-line::before {
+ content: "";
+ right: auto;
+ width: 42px;
+ background: var(--color-primary, #f04494);
+ opacity: 0.3;
+}
+
+/* ===== Article Card ===== */
+.article-card {
+ margin-bottom: 16px;
+}
+
+.article-card__header {
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid var(--color-line);
+}
+
+.article-card__title {
+ font-size: clamp(1.25rem, 3vw, 1.75rem);
+ font-weight: 800;
+ margin: 0;
+ line-height: 1.35;
+ color: var(--color-ink);
+}
+
diff --git a/assets/css/frontend/single-post/hidden-content.css b/assets/css/frontend/single-post/hidden-content.css
new file mode 100644
index 00000000..fb2c3a17
--- /dev/null
+++ b/assets/css/frontend/single-post/hidden-content.css
@@ -0,0 +1,121 @@
+/* ---- Yiyan inline blocks (single post) ---- */
+.yiyan--header,
+.yiyan--footer {
+ margin: 16px 0;
+ padding: 12px 16px;
+}
+
+.yiyan--box {
+ margin: 24px 0;
+ padding: 20px;
+ border-radius: 8px;
+ background: var(--card-bg, #fff);
+ box-shadow: var(--card-shadow, 0 2px 8px rgba(0, 0, 0, .06));
+}
+
+/* ---- Front / After content insertion ---- */
+.article-front-content,
+.article-after-content {
+ padding: 12px 0;
+ font-size: 14px;
+ line-height: 1.8;
+ color: var(--text-secondary, #666);
+ border-bottom: 1px dashed var(--border-color, #eee);
+ margin-bottom: 12px;
+}
+
+.article-after-content {
+ border-bottom: none;
+ border-top: 1px dashed var(--border-color, #eee);
+ margin-bottom: 0;
+ margin-top: 12px;
+}
+
+/* ---- Hidden Content Shortcodes ---- */
+.aksrt-hidden-content {
+ position: relative;
+ margin: 16px 0;
+ padding: 16px;
+ border-radius: var(--border-radius, 8px);
+ font-size: 14px;
+ line-height: 1.8;
+}
+
+.aksrt-hidden-content--unlocked {
+ background: var(--bg-secondary, #f8f9fa);
+ border: 1px solid var(--border-color, #e5e7eb);
+}
+
+.aksrt-hidden-content--locked {
+ background: linear-gradient(135deg, var(--bg-secondary, #f8f9fa) 0%, var(--bg-tertiary, #f1f3f5) 100%);
+ border: 1px dashed var(--border-color, #d1d5db);
+ text-align: center;
+ padding: 24px 16px;
+}
+
+.aksrt-hidden-content__message {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ font-size: 15px;
+ color: var(--text-secondary, #6b7280);
+ margin-bottom: 12px;
+}
+
+.aksrt-hidden-content__message i {
+ font-size: 18px;
+ color: var(--text-muted, #9ca3af);
+}
+
+.aksrt-hidden-content--vip .aksrt-hidden-content__message i {
+ color: var(--vip-color, #f59e0b);
+}
+
+.aksrt-hidden-content--payshow .aksrt-hidden-content__message i {
+ color: var(--primary-color, #3b82f6);
+}
+
+.aksrt-hidden-content__form {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ margin-top: 8px;
+}
+
+.aksrt-hidden-content__password-input {
+ width: 200px;
+ max-width: 60%;
+ padding: 6px 12px;
+ border: 1px solid var(--border-color, #d1d5db);
+ border-radius: var(--border-radius, 6px);
+ font-size: 14px;
+ background: var(--bg-primary, #fff);
+ color: var(--text-primary, #1f2937);
+ outline: none;
+ transition: border-color .2s;
+}
+
+.aksrt-hidden-content__password-input:focus {
+ border-color: var(--primary-color, #3b82f6);
+}
+
+.aksrt-hidden-content__submit-btn,
+.aksrt-hidden-content__login-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 6px 16px;
+ font-size: 13px;
+ border-radius: var(--border-radius, 6px);
+ cursor: pointer;
+ text-decoration: none;
+ transition: opacity .2s;
+}
+
+.aksrt-hidden-content__submit-btn:hover,
+.aksrt-hidden-content__login-btn:hover {
+ opacity: .85;
+}
+
diff --git a/assets/css/frontend/single-post/navigation.css b/assets/css/frontend/single-post/navigation.css
new file mode 100644
index 00000000..6de42565
--- /dev/null
+++ b/assets/css/frontend/single-post/navigation.css
@@ -0,0 +1,79 @@
+/* ========== Post Navigation ========== */
+.post-nav-links {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+ margin-top: 32px;
+}
+
+@media (min-width: 768px) {
+ .post-nav-links {
+ gap: 16px;
+ margin-top: 40px;
+ }
+}
+
+.post-nav-links a {
+ display: block;
+ padding: 16px;
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--color-line);
+ background: var(--surface-2);
+ transition: border-color 0.2s;
+}
+
+.post-nav-links a:hover {
+ border-color: var(--color-primary);
+}
+
+.post-nav-links .nav-subtitle {
+ display: block;
+ font-size: 12px;
+ color: var(--color-ink-4);
+ margin-bottom: 4px;
+}
+
+.post-nav-links .nav-title {
+ font-weight: 700;
+ color: var(--color-ink);
+}
+
+.post-navigation,
+.navigation.post-navigation {
+ margin-top: 40px;
+}
+
+.post-navigation .nav-links,
+.navigation.post-navigation .nav-links {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+}
+
+@media (min-width: 768px) {
+ .post-navigation .nav-links,
+ .navigation.post-navigation .nav-links {
+ gap: 16px;
+ }
+}
+
+.post-navigation a,
+.navigation.post-navigation a {
+ display: block;
+ padding: 16px;
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--color-line);
+ background: var(--surface-2);
+ transition: border-color 0.2s;
+}
+
+.post-navigation a:hover,
+.navigation.post-navigation a:hover {
+ border-color: var(--color-primary);
+}
+
+
+/* ===== Utility card classes (unified in card-primitives.css) ===== */
+.mt-3 {
+ margin-top: 16px;
+}
diff --git a/assets/css/frontend/single-post/related-toc.css b/assets/css/frontend/single-post/related-toc.css
new file mode 100644
index 00000000..d9485473
--- /dev/null
+++ b/assets/css/frontend/single-post/related-toc.css
@@ -0,0 +1,430 @@
+/* ===== Previous / Next Navigation ===== */
+.post-nav-box {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 12px;
+ margin-bottom: 16px;
+}
+
+.post-nav-box__item {
+ display: block;
+ padding: 15px;
+ text-decoration: none;
+ transition: color 0.15s ease;
+ color: var(--key-color, #333);
+}
+
+.post-nav-box__item:hover {
+ color: var(--focus-color, #f04494);
+ text-decoration: none;
+}
+
+.post-nav-box__item--next { text-align: right; }
+
+.post-nav-box__label {
+ display: block;
+ font-size: 12px;
+ color: var(--color-ink-4, var(--color-ink-4));
+ margin-bottom: 4px;
+}
+
+.post-nav-box__title {
+ display: block;
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--key-color, #333);
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+/* ===== Related Posts — 对齐 zibll 卡片容器 ===== */
+.related-box {
+ margin-bottom: 16px;
+ overflow: hidden;
+ background: var(--main-bg-color, #fff);
+ border-radius: var(--main-radius, 8px);
+ box-shadow: 0 0 10px var(--main-shadow, rgba(116, 116, 116, 0.08));
+}
+
+.related-box__header { padding-bottom: 0; }
+
+.related-box__title {
+ font-size: 14px;
+ font-weight: 700;
+ margin: 0;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+}
+
+.related-box__title i { color: var(--color-primary); font-size: 13px; }
+
+.related-box__list {
+ padding: 12px 16px 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 0;
+}
+
+.related-box__item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 8px 0;
+ border-bottom: 1px solid var(--color-line);
+ text-decoration: none;
+ color: inherit;
+}
+
+.related-box__item:last-child { border-bottom: none; }
+.related-box__item:hover { color: var(--color-primary); }
+
+.related-box__thumb {
+ width: 96px;
+ min-width: 96px;
+ height: 64px;
+ border-radius: var(--main-radius, 8px);
+ overflow: hidden;
+ flex-shrink: 0;
+ background: var(--muted-bg-color, #eee);
+}
+
+.related-box__thumb img { width: 100%; height: 100%; object-fit: cover; }
+
+.related-box__placeholder {
+ width: 100%; height: 100%;
+ display: flex; align-items: center; justify-content: center;
+ color: var(--color-ink-4); font-size: 14px;
+}
+
+.related-box__item-title {
+ font-size: 14px;
+ font-weight: 600;
+ display: -webkit-box;
+ -webkit-line-clamp: 1;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+}
+
+/* ===== Comment Card Spacing ===== */
+.comments-card { margin-bottom: 16px; }
+
+/* ===== Content Height Clamp ===== */
+.wp-posts-content.limit-height {
+ position: relative;
+ overflow: hidden;
+}
+
+.wp-posts-content.limit-height::after {
+ content: '';
+ position: absolute;
+ bottom: 0; left: 0; right: 0;
+ height: 100px;
+ background: linear-gradient(to bottom, transparent, var(--surface-page));
+ pointer-events: none;
+}
+
+.wp-posts-content.limit-height.is-expanded::after { display: none; }
+
+.entry-content.limit-height {
+ position: relative;
+ overflow: hidden;
+}
+
+.entry-content.limit-height::after {
+ content: '';
+ position: absolute;
+ bottom: 0; left: 0; right: 0;
+ height: 100px;
+ background: linear-gradient(to bottom, transparent, var(--surface-page));
+ pointer-events: none;
+}
+
+.entry-content.limit-height.is-expanded::after { display: none; }
+
+.content-expand-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ width: 100%;
+ padding: 10px;
+ margin-top: -30px;
+ position: relative;
+ z-index: 2;
+ border: none;
+ background: var(--surface-page);
+ color: var(--color-primary);
+ font-size: 13px;
+ font-weight: 500;
+ cursor: pointer;
+ border-top: 1px solid var(--color-line);
+}
+
+.content-expand-btn:hover { background: var(--color-primary-soft, rgba(240, 68, 148, 0.06)); }
+.content-expand-btn.is-expanded i { transform: rotate(180deg); }
+
+/* ===== Mobile ===== */
+@media (max-width: 767px) {
+ .single-cover { padding-bottom: 55%; }
+ .single-cover__content { padding: 14px; }
+ .single-cover__title { font-size: 1rem; }
+ .post-nav-box { grid-template-columns: 1fr; }
+ .post-actions-card__buttons { gap: 8px; }
+ .action-btn { padding: 8px 14px; font-size: 13px; }
+}
+
+/* ===== 鏆楄壊妯″紡 ===== */
+.theme-dark .article-end-separator span,
+html.dark .article-end-separator span {
+ background: var(--surface-1);
+}
+
+/* ============================================================
+ * Phase 7 single/article controls
+ * ============================================================ */
+.reading-progress-bar {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 120;
+ width: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--color-primary), color-mix(in srgb, var(--color-primary) 55%, #fff));
+ box-shadow: 0 2px 12px color-mix(in srgb, var(--color-primary) 24%, transparent);
+}
+
+.author-info-bar.article-author-bar {
+ display: flex;
+ align-items: flex-start;
+ gap: 12px;
+ margin-bottom: 18px;
+}
+
+.author-info-bar.article-author-bar .author-info-bar__avatar img,
+.author-info-bar.article-author-bar .author-info-bar__avatar .avatar {
+ width: 44px;
+ height: 44px;
+ border-radius: 50%;
+ object-fit: cover;
+}
+
+.author-info-bar.article-author-bar .author-info-bar__body {
+ min-width: 0;
+ flex: 1;
+}
+
+.author-info-bar.article-author-bar .author-info-bar__name {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ color: var(--color-ink);
+ font-weight: 600;
+ font-size: 15px;
+}
+
+.author-info-bar.article-author-bar .author-info-bar__sub {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px 10px;
+ margin-top: 4px;
+ color: var(--color-ink-4);
+ font-size: 12px;
+}
+
+.author-info-bar.article-author-bar .author-info-bar__bio {
+ margin: 8px 0 0;
+ color: var(--color-ink-3);
+ font-size: 13px;
+ line-height: 1.6;
+}
+
+.action-btn--ghost {
+ background: var(--surface-2);
+}
+
+.toc-widget {
+ position: sticky;
+ top: 88px;
+ padding: 18px 18px 14px;
+ margin-bottom: 16px;
+}
+
+.toc-widget .widget-title {
+ margin-bottom: 10px;
+}
+
+.toc-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: grid;
+ gap: 8px;
+}
+
+.toc-list li {
+ min-width: 0;
+}
+
+.toc-list a {
+ display: block;
+ color: var(--color-ink-3);
+ font-size: 13px;
+ line-height: 1.55;
+ text-decoration: none;
+ transition: color 0.2s ease, transform 0.2s ease;
+}
+
+.toc-list a:hover,
+.toc-list a.is-active {
+ color: var(--color-primary);
+}
+
+.toc-list .toc-h3 a {
+ padding-left: 12px;
+}
+
+.toc-list .toc-h4 a {
+ padding-left: 24px;
+}
+
+.toc-float-btn {
+ position: fixed;
+ right: 18px;
+ bottom: 86px;
+ z-index: 41;
+ width: 48px;
+ height: 48px;
+ border: none;
+ border-radius: 999px;
+ display: none;
+ align-items: center;
+ justify-content: center;
+ background: var(--color-primary);
+ color: #fff;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
+}
+
+.toc-drawer-overlay {
+ position: fixed;
+ inset: 0;
+ z-index: 79;
+ display: none;
+ background: rgba(15, 23, 42, 0.36);
+}
+
+.toc-drawer-overlay.is-open {
+ display: block;
+}
+
+.toc-drawer {
+ position: fixed;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ z-index: 80;
+ width: min(86vw, 340px);
+ padding: 18px 18px 28px;
+ background: var(--surface-page);
+ border-left: 1px solid var(--color-line);
+ transform: translateX(100%);
+ transition: transform 0.25s ease;
+ overflow-y: auto;
+}
+
+.toc-drawer.is-open {
+ transform: translateX(0);
+}
+
+.toc-drawer__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ margin-bottom: 14px;
+}
+
+.toc-drawer__head h3 {
+ margin: 0;
+ font-size: 16px;
+}
+
+.toc-drawer__close {
+ width: 36px;
+ height: 36px;
+ border: none;
+ border-radius: 999px;
+ background: var(--surface-2);
+ color: var(--color-ink-3);
+}
+
+.resource-mobile-fab {
+ position: fixed;
+ right: 18px;
+ bottom: 24px;
+ z-index: 42;
+ width: 52px;
+ height: 52px;
+ display: none;
+ align-items: center;
+ justify-content: center;
+ border-radius: 999px;
+ background: var(--color-primary);
+ color: #fff;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
+}
+
+.resource-mobile-download-bar {
+ display: none;
+ margin-bottom: 16px;
+}
+
+.resource-related {
+ margin-bottom: 16px;
+}
+
+.resource-related__header {
+ margin-bottom: 14px;
+}
+
+.resource-related__title {
+ margin: 0;
+ font-size: 18px;
+ font-weight: 700;
+}
+
+.resource-related__grid {
+ margin-top: 0;
+}
+
+@media (max-width: 991px) {
+ .toc-widget {
+ display: none;
+ }
+
+ .toc-float-btn {
+ display: inline-flex;
+ }
+
+ .resource-mobile-download-bar {
+ display: block;
+ }
+
+ .resource-mobile-fab {
+ display: inline-flex;
+ }
+}
+
+@media (max-width: 767px) {
+ .author-info-bar.article-author-bar {
+ gap: 10px;
+ margin-bottom: 16px;
+ }
+
+ .author-info-bar.article-author-bar .author-info-bar__sub {
+ gap: 6px 8px;
+ }
+}
+
diff --git a/assets/css/frontend/site-notice.css b/assets/css/frontend/site-notice.css
new file mode 100644
index 00000000..57a150e9
--- /dev/null
+++ b/assets/css/frontend/site-notice.css
@@ -0,0 +1,131 @@
+/**
+ * AKSRT Site Notice — Popup notice styles
+ */
+
+.aksrt-site-notice {
+ position: fixed;
+ inset: 0;
+ z-index: 99998;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+}
+
+.aksrt-site-notice__overlay {
+ position: absolute;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.5);
+}
+
+.aksrt-site-notice__dialog {
+ position: relative;
+ background: var(--surface-1, #fff);
+ border-radius: var(--radius-lg, 12px);
+ box-shadow: 0 8px 40px rgba(0, 0, 0, 0.15);
+ width: 100%;
+ max-height: 80vh;
+ overflow-y: auto;
+}
+
+.aksrt-site-notice__head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 20px 24px 0;
+}
+
+.aksrt-site-notice__title {
+ margin: 0;
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--color-ink, #333);
+}
+
+.aksrt-site-notice__close {
+ width: 32px;
+ height: 32px;
+ border: none;
+ border-radius: 50%;
+ background: var(--surface-2, #eee);
+ color: var(--color-ink-3, #777);
+ font-size: 16px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.15s;
+}
+
+.aksrt-site-notice__close:hover {
+ background: var(--surface-3, #ddd);
+}
+
+.aksrt-site-notice__body {
+ padding: 16px 24px;
+ font-size: 14px;
+ line-height: 1.7;
+ color: var(--color-ink-2, #4e5358);
+}
+
+.aksrt-site-notice__body a {
+ color: var(--color-primary);
+}
+
+.aksrt-site-notice__foot {
+ padding: 0 24px 20px;
+ text-align: center;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 10px;
+ justify-content: center;
+}
+
+/* Button base — shared by both