diff --git a/public/css/layouts/empty.css b/public/css/layouts/empty.css
new file mode 100644
index 0000000..5776eb5
--- /dev/null
+++ b/public/css/layouts/empty.css
@@ -0,0 +1,432 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ font-family: Arial, sans-serif;
+ color: #333;
+}
+
+body {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background-color: #fcfcfc;
+}
+
+.page-layout {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.page {
+ width: 100%;
+ /* display: flex; */
+ /* flex-direction: column; */
+ flex: 1;
+ position: relative;
+
+}
+
+.container {
+ max-width: 1226px;
+ margin-right: auto;
+ margin-left: auto;
+ padding-left: 20px;
+ padding-right: 20px;
+}
+
+@media (max-width: 640px) {
+ .container {
+ padding-left: 10px;
+ padding-right: 10px;
+ }
+}
+
+.clearfix::after {
+ content: '';
+ display: table;
+ clear: both;
+}
+
+.navbar-brand {
+ float: left;
+ height: 100%;
+ display: flex;
+ align-items: center;
+}
+
+/* ===== 顶部导航 响应式 ===== */
+.navbar {
+ position: relative;
+}
+
+.navbar .menu-toggle {
+ display: none;
+ position: absolute;
+ right: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 40px;
+ height: 40px;
+ border: none;
+ background: transparent;
+ padding: 0;
+ cursor: pointer;
+}
+
+.navbar .menu-toggle .bar {
+ display: block;
+ width: 22px;
+ height: 2px;
+ background: #333;
+ margin: 5px auto;
+ transition: transform .2s ease, opacity .2s ease;
+}
+
+.navbar .mobile-menu {
+ display: none;
+ position: relative;
+ overflow: hidden;
+ max-height: 0;
+ transition: max-height .25s ease;
+ background: rgba(255, 255, 255, 0.95);
+ border-radius: 0 0 12px 12px;
+ box-shadow: 0 4px 16px rgba(0, 0, 0, .06);
+}
+
+.navbar.open .mobile-menu {
+ display: none;
+ max-height: 400px;
+}
+
+.navbar .mobile-menu .menu-item {
+ display: block;
+ padding: 12px 0;
+}
+
+/* 桌面端可见区域 */
+.desktop-only {
+ display: block;
+}
+
+/* <= 1024 宽度:显示切换按钮,隐藏桌面菜单 */
+@media (max-width: 1024px) {
+ .desktop-only {
+ display: none;
+ }
+
+ .navbar .menu-toggle {
+ display: inline-block;
+ }
+
+ .navbar .mobile-menu {
+ padding: 8px 20px 12px;
+ }
+
+ .navbar.open .mobile-menu {
+ display: block;
+ }
+}
+
+.menu {
+ height: 100%;
+ margin-left: 20px;
+
+ .menu-item {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ padding: 0 10px;
+ cursor: pointer;
+
+ &:hover {
+ background: rgba(175, 175, 175, 0.1);
+ }
+ }
+}
+
+.menu.left {
+ float: left;
+
+ .menu-item {
+ float: left;
+
+ &+.menu-item {
+ margin-left: 5px;
+ }
+ }
+}
+
+.right.menu {
+ float: right;
+
+ .menu-item {
+ float: right;
+
+ &+.menu-item {
+ margin-right: 5px;
+ }
+ }
+}
+
+
+.footer-panel {
+ padding: 0;
+ font-size: 14px;
+ margin-top: auto;
+ background-color: #ffffff;
+}
+
+.footer-content {
+ max-width: 1226px;
+ margin: 0 auto;
+ padding: 0 20px;
+}
+
+.footer-main {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ margin-bottom: 2rem;
+}
+
+.footer-section {
+ text-align: center;
+}
+
+.footer-title {
+ margin-bottom: 1rem;
+ color: #111827;
+ font-weight: 600;
+}
+
+.footer-desc {
+ color: #6b7280;
+ line-height: 1.6;
+ margin-bottom: 0;
+}
+
+.footer-links {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.footer-links li {
+ margin-bottom: 0.75rem;
+}
+
+.footer-links a {
+ text-decoration: none;
+ color: #6b7280;
+ transition: color 0.2s ease;
+}
+
+.footer-links a:hover {
+ color: #2563eb;
+}
+
+.social-links {
+ display: flex;
+ justify-content: center;
+ gap: 1rem;
+}
+
+.social-link {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ text-decoration: none;
+ transition: all 0.2s ease;
+}
+
+.social-link:hover {
+ transform: translateY(-2px);
+}
+
+.social-link span {
+ font-size: 18px;
+ line-height: 1;
+}
+
+.footer-bottom {
+ border-top: 1px solid #e5e7eb;
+ padding-top: 1.5rem;
+}
+
+.footer-bottom-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1rem;
+}
+
+.copyright {
+ color: #6b7280;
+ text-align: center;
+}
+
+.footer-actions {
+ display: flex;
+ gap: 1.5rem;
+}
+
+.footer-actions a {
+ text-decoration: none;
+ color: #6b7280;
+ transition: color 0.2s ease;
+}
+
+.footer-actions a:hover {
+ color: #2563eb;
+}
+
+/* 响应式设计 */
+@media (min-width: 768px) {
+ .footer-main {
+ grid-template-columns: repeat(4, 1fr);
+ text-align: left;
+ }
+
+ .footer-section {
+ text-align: left;
+ }
+
+ .social-links {
+ justify-content: flex-start;
+ }
+
+ .footer-bottom-content {
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ .copyright {
+ text-align: left;
+ margin-bottom: 0;
+ }
+}
+
+/* 移动端优化(<=767px) */
+@media (max-width: 767px) {
+ .footer-content {
+ padding: 0 16px;
+ }
+
+ .footer-main {
+ gap: 1.25rem;
+ /* 20px */
+ margin-bottom: 1rem;
+ /* 16px */
+ }
+
+ .footer-title {
+ font-size: 16px;
+ }
+
+ .footer-desc {
+ font-size: 13px;
+ }
+
+ .footer-links li {
+ margin-bottom: 0.5rem;
+ /* 8px */
+ }
+
+ .footer-actions {
+ flex-wrap: wrap;
+ gap: 1rem;
+ /* 16px */
+ justify-content: center;
+ }
+
+ .footer-actions a {
+ font-size: 13px;
+ }
+
+ .social-links {
+ flex-wrap: wrap;
+ gap: 0.75rem;
+ /* 12px */
+ justify-content: center;
+ }
+
+ .social-link {
+ width: 40px;
+ height: 40px;
+ }
+
+ .footer-bottom-content {
+ gap: 0.75rem;
+ /* 12px */
+ }
+}
+
+/* iconify图标 */
+.streamline-ultimate-color--wechat-logo {
+ display: inline-block;
+ width: 32px;
+ height: 32px;
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none'%3E%3Cpath fill='%2378eb7b' d='M12.385 3.757a8.45 8.45 0 0 0-6.93-.541a7.06 7.06 0 0 0-3.633 2.862a5.36 5.36 0 0 0-.669 4.11a6.3 6.3 0 0 0 2.73 3.691q-.372 1.065-.714 2.138c.821-.428 1.634-.872 2.451-1.308a9.1 9.1 0 0 0 3.06.436a5.3 5.3 0 0 1-.211-2.47c.212-1.15.8-2.195 1.673-2.973a7.24 7.24 0 0 1 5.433-1.785a6.34 6.34 0 0 0-3.19-4.162z'/%3E%3Cpath fill='%23c9f7ca' d='M1.176 10.269c.14-.533.356-1.042.644-1.511a7.05 7.05 0 0 1 3.632-2.863a8.45 8.45 0 0 1 6.93.542c.7.389 1.326.9 1.848 1.507a8 8 0 0 1 1.343-.023a6.34 6.34 0 0 0-3.19-4.162a8.45 8.45 0 0 0-6.931-.541A7.05 7.05 0 0 0 1.82 6.08a5.36 5.36 0 0 0-.67 4.11q.016.038.026.079'/%3E%3Cpath stroke='%23191919' stroke-linecap='round' stroke-linejoin='round' d='M12.385 3.757a8.45 8.45 0 0 0-6.93-.541a7.06 7.06 0 0 0-3.633 2.862a5.36 5.36 0 0 0-.669 4.11a6.3 6.3 0 0 0 2.73 3.691q-.372 1.065-.714 2.138c.821-.428 1.634-.872 2.451-1.308a9.1 9.1 0 0 0 3.06.436a5.3 5.3 0 0 1-.211-2.47c.212-1.15.8-2.195 1.673-2.973a7.24 7.24 0 0 1 5.433-1.785a6.34 6.34 0 0 0-3.19-4.162z' stroke-width='1'/%3E%3Cpath fill='%2378eb7b' stroke='%23191919' stroke-linecap='round' stroke-linejoin='round' d='M5.643 6.299a.478.478 0 1 1 .321.9a.478.478 0 0 1-.321-.9m5.029.005a.478.478 0 1 1 .338.894a.478.478 0 0 1-.338-.894' stroke-width='1'/%3E%3Cpath fill='%2378eb7b' d='M22.6 13.584a5.54 5.54 0 0 0-2.58-2.633a7.11 7.11 0 0 0-6.38.024a5.3 5.3 0 0 0-2.828 3.482a4.48 4.48 0 0 0 .574 3.314a6.1 6.1 0 0 0 4.157 2.712a7.6 7.6 0 0 0 3.633-.24c.702.274 1.333.716 2.015 1.042a41 41 0 0 0-.564-1.756a5.7 5.7 0 0 0 1.876-2.073a4.5 4.5 0 0 0 .112-3.872z'/%3E%3Cpath fill='%23c9f7ca' d='M13.633 13.288a7.11 7.11 0 0 1 6.38-.024a5.54 5.54 0 0 1 2.58 2.632q.143.325.231.67a4.5 4.5 0 0 0-.23-2.986a5.54 5.54 0 0 0-2.581-2.633a7.11 7.11 0 0 0-6.38.024a5.3 5.3 0 0 0-2.828 3.482c-.151.69-.13 1.406.064 2.085a5.35 5.35 0 0 1 2.764-3.25'/%3E%3Cpath stroke='%23191919' stroke-linecap='round' stroke-linejoin='round' d='M22.6 13.584a5.54 5.54 0 0 0-2.58-2.633a7.11 7.11 0 0 0-6.38.024a5.3 5.3 0 0 0-2.828 3.482a4.48 4.48 0 0 0 .574 3.314a6.1 6.1 0 0 0 4.157 2.712a7.6 7.6 0 0 0 3.633-.24c.702.274 1.333.716 2.015 1.042a41 41 0 0 0-.564-1.756a5.7 5.7 0 0 0 1.876-2.073a4.5 4.5 0 0 0 .112-3.872z' stroke-width='1'/%3E%3Cpath fill='%2378eb7b' d='M14.813 13.282a.485.485 0 0 1 .613.617a.478.478 0 1 1-.613-.617'/%3E%3Cpath stroke='%23191919' stroke-linecap='round' stroke-linejoin='round' d='M14.813 13.282a.485.485 0 0 1 .613.617a.478.478 0 1 1-.613-.617' stroke-width='1'/%3E%3Cpath fill='%2378eb7b' d='M18.968 13.27c.36-.03.616.342.462.668l-.001.001a.468.468 0 0 1-.74.128a.74.74 0 0 1-.164-.346a.525.525 0 0 1 .443-.45'/%3E%3Cpath stroke='%23191919' stroke-linecap='round' stroke-linejoin='round' d='M18.968 13.27c.36-.03.616.342.462.668l-.001.001a.468.468 0 0 1-.74.128a.74.74 0 0 1-.164-.346a.525.525 0 0 1 .443-.45' stroke-width='1'/%3E%3C/g%3E%3C/svg%3E");
+}
+
+.fa7-brands--weibo {
+ display: inline-block;
+ width: 32px;
+ height: 32px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23000' d='M407 177.6c7.6-24-13.4-46.8-37.4-41.7c-22 4.8-28.8-28.1-7.1-32.8c50.1-10.9 92.3 37.1 76.5 84.8c-6.8 21.2-38.8 10.8-32-10.3M214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6c79.5-33.6 140.5-16.8 114 51.4c-3.7 9.4 1.1 10.9 8.3 13.1c135.7 42.3 34.8 215.2-169.7 215.2m143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7c-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116M347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3c72.3-15.2 134.8 52.8 111.7 124c-7.4 24.2 29.1 37 37.4 12c31.9-99.8-55.1-195.9-157.4-174.3m-78.5 311c-17.1 38.8-66.8 60-109.1 46.3c-40.8-13.1-58-53.4-40.3-89.7c17.7-35.4 63.1-55.4 103.4-45.1c42 10.8 63.1 50.2 46 88.5m-86.3-30c-12.9-5.4-30 .3-38 12.9c-8.3 12.9-4.3 28 8.6 34c13.1 6 30.8.3 39.1-12.9c8-13.1 3.7-28.3-9.7-34m32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4c-2.9 5.1-1.4 10.6 3.7 12.9c5.1 2 11.7-.3 14.6-5.4c2.8-5.2 1.1-10.9-4-12.9'/%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.cib--tencent-qq {
+ display: inline-block;
+ width: 32px;
+ height: 32px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cpath fill='%23000' d='M28.527 20.047a57 57 0 0 0-1.068-3.02l-1.443-3.595c.005-.041.02-.744.02-1.115C26.036 6.177 23.136 0 16 0S5.964 6.177 5.964 12.323c0 .365.02 1.073.02 1.115l-1.443 3.593q-.576 1.493-1.068 3.016c-1.359 4.38-.921 6.193-.583 6.235c.719.083 2.803-3.297 2.803-3.297c0 1.959 1.009 4.516 3.192 6.36c-.812.249-1.817.64-2.459 1.115c-.577.427-.505.859-.4 1.036c.457.771 7.843.489 9.973.251c2.136.239 9.521.52 9.979-.251c.104-.177.177-.609-.4-1.036c-.647-.475-1.647-.865-2.464-1.115c2.183-1.849 3.192-4.407 3.192-6.365c0 0 2.084 3.385 2.803 3.297c.339-.036.776-1.855-.583-6.229zM16.88 6.464c.052-1.407.88-2.505 1.849-2.464c.968.041 1.708 1.213 1.656 2.62c-.052 1.401-.88 2.505-1.849 2.459c-.963-.043-1.708-1.215-1.656-2.615M13.271 4c.969-.041 1.797 1.057 1.849 2.464c.052 1.4-.693 2.572-1.656 2.615c-.969.047-1.797-1.057-1.849-2.459c-.052-1.407.688-2.579 1.656-2.62m-3.375 7.057c.255-.573 2.859-1.208 6.088-1.208h.032c3.224 0 5.833.635 6.088 1.208a.15.15 0 0 1 .021.083a.2.2 0 0 1-.037.111c-.219.317-3.109 1.889-6.067 1.889h-.037c-2.963 0-5.853-1.572-6.072-1.889a.18.18 0 0 1-.016-.193zm13.896 11.495c-.297 4.907-3.204 7.984-7.699 8.032h-.181c-4.496-.048-7.407-3.125-7.699-8.032c-.109-1.797 0-3.323.193-4.573q.64.133 1.281.235v4.677s2.208.448 4.421.136V18.73c.651.036 1.281.052 1.875.041h.032c2.239.032 4.953-.271 7.577-.792c.199 1.251.303 2.776.199 4.573zM13.973 7.74c.417-.057.724-.547.677-1.1c-.047-.557-.416-.963-.839-.905c-.416.052-.724.547-.676 1.099s.416.959.837.907zm5.334-.865c.105.047.292.057.387-.192c.047-.131.031-.224-.016-.287c-.032-.047-.177-.156-.495-.235c-1.204-.297-1.787.511-1.871.661c-.057.099-.015.24.073.308c.088.067.188.047.24-.011c.771-.839 1.615-.276 1.681-.245z'/%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.ri--github-fill {
+ display: inline-block;
+ width: 32px;
+ height: 32px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M12.001 2c-5.525 0-10 4.475-10 10a9.99 9.99 0 0 0 6.837 9.488c.5.087.688-.213.688-.476c0-.237-.013-1.024-.013-1.862c-2.512.463-3.162-.612-3.362-1.175c-.113-.288-.6-1.175-1.025-1.413c-.35-.187-.85-.65-.013-.662c.788-.013 1.35.725 1.538 1.025c.9 1.512 2.337 1.087 2.912.825c.088-.65.35-1.087.638-1.337c-2.225-.25-4.55-1.113-4.55-4.938c0-1.088.387-1.987 1.025-2.687c-.1-.25-.45-1.275.1-2.65c0 0 .837-.263 2.75 1.024a9.3 9.3 0 0 1 2.5-.337c.85 0 1.7.112 2.5.337c1.913-1.3 2.75-1.024 2.75-1.024c.55 1.375.2 2.4.1 2.65c.637.7 1.025 1.587 1.025 2.687c0 3.838-2.337 4.688-4.562 4.938c.362.312.675.912.675 1.85c0 1.337-.013 2.412-.013 2.75c0 .262.188.574.688.474A10.02 10.02 0 0 0 22 12c0-5.525-4.475-10-10-10'/%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
+
+.icomoon-free--blog {
+ display: inline-block;
+ width: 32px;
+ height: 32px;
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='%23000' d='M6 0v1.5a8.46 8.46 0 0 1 6.01 2.489a8.47 8.47 0 0 1 2.489 6.01h1.5c0-5.523-4.477-10-10-10z'/%3E%3Cpath fill='%23000' d='M6 3v1.5c1.469 0 2.85.572 3.889 1.611S11.5 8.531 11.5 10H13a7 7 0 0 0-7-7m1.5 3l-1 1L3 8l-3 6.5l.396.396l3.638-3.638a1 1 0 1 1 .707.707l-3.638 3.638l.396.396l6.5-3l1-3.5l1-1l-2.5-2.5z'/%3E%3C/svg%3E");
+ background-color: currentColor;
+ -webkit-mask-image: var(--svg);
+ mask-image: var(--svg);
+ -webkit-mask-repeat: no-repeat;
+ mask-repeat: no-repeat;
+ -webkit-mask-size: 100% 100%;
+ mask-size: 100% 100%;
+}
\ No newline at end of file
diff --git a/public/css/page/index copy.css b/public/css/page/index copy.css
new file mode 100644
index 0000000..2c8f30b
--- /dev/null
+++ b/public/css/page/index copy.css
@@ -0,0 +1,53 @@
+.home-hero {
+ margin: 40px 20px 40px;
+ /* background: rgba(255, 255, 255, 0.1);
+ backdrop-filter: blur(12px); */
+ text-align: center;
+}
+.avatar-container {
+ width: 120px;
+ height: 120px;
+ margin: 0 auto;
+ position: relative;
+}
+.avatar-container .author {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ color: white;
+ font-size: 20px;
+ font-weight: bold;
+}
+.avatar-container:hover .avatar {
+ transform: rotate(360deg);
+ left: 100%;
+}
+.avatar {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ cursor: pointer;
+ left: 0;
+ transform-origin: center center;
+ transition: 0.5s transform ease-in-out, 0.5s left ease-in-out;
+}
+/*
+.card {
+ background: rgba(255, 255, 255, 0.1);
+ backdrop-filter: blur(12px);
+ border-radius: 8px;
+ padding: 20px;
+ width: 300px;
+ margin: 0 auto;
+ margin-bottom: 40px;
+ text-align: center;
+} */
+
+@media screen and (max-width: 768px) {
+ .home-hero {
+ margin: 0;
+ margin-top: 20px;
+ }
+}
diff --git a/public/css/page/index.css b/public/css/page/index.css
index 2c8f30b..b42d0d4 100644
--- a/public/css/page/index.css
+++ b/public/css/page/index.css
@@ -1,53 +1,55 @@
-.home-hero {
- margin: 40px 20px 40px;
- /* background: rgba(255, 255, 255, 0.1);
- backdrop-filter: blur(12px); */
- text-align: center;
-}
-.avatar-container {
- width: 120px;
- height: 120px;
- margin: 0 auto;
- position: relative;
-}
-.avatar-container .author {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- color: white;
- font-size: 20px;
- font-weight: bold;
-}
-.avatar-container:hover .avatar {
- transform: rotate(360deg);
- left: 100%;
-}
-.avatar {
- position: relative;
- width: 100%;
- height: 100%;
- border-radius: 50%;
- cursor: pointer;
- left: 0;
- transform-origin: center center;
- transition: 0.5s transform ease-in-out, 0.5s left ease-in-out;
-}
-/*
-.card {
- background: rgba(255, 255, 255, 0.1);
- backdrop-filter: blur(12px);
- border-radius: 8px;
- padding: 20px;
- width: 300px;
- margin: 0 auto;
- margin-bottom: 40px;
- text-align: center;
-} */
-
-@media screen and (max-width: 768px) {
- .home-hero {
- margin: 0;
- margin-top: 20px;
+.list {
+ display: flex;
+ gap: 15px;
+ flex-wrap: wrap;
+
+ &.blog {
+
+ >* {
+ width: calc(25% - 15px * 3 / 4);
+ }
+
+ /* ≥1024px 默认4列;介于768px-1023px 显示3列 */
+ @media (max-width: 1023px) {
+ >* {
+ width: calc(33.3333% - 15px * 2 / 3);
+ }
+ }
+
+ /* 介于640px-767px 显示2列 */
+ @media (max-width: 767px) {
+ >* {
+ width: calc(50% - 15px * 1 / 2);
+ }
+ }
+
+ /* <640px 显示1列,并优化间距与字号 */
+ @media (max-width: 639px) {
+ gap: 12px;
+
+ >* {
+ width: 100%;
+ }
+
+ .article-card {
+ padding: 14px;
+ }
+
+ .article-title {
+ font-size: 16px;
+ }
+
+ .article-meta {
+ font-size: 12px;
+ }
+
+ .article-desc {
+ font-size: 14px;
+ }
+ }
}
}
+
+.list a:hover {
+ text-decoration: underline;
+}
\ No newline at end of file
diff --git a/public/lib/simplebar-shim.css b/public/lib/simplebar-shim.css
index b245ea6..3093e18 100644
--- a/public/lib/simplebar-shim.css
+++ b/public/lib/simplebar-shim.css
@@ -1,6 +1,11 @@
.simplebar-content {
- height: 100%;
+ min-height: 100%;
+ display: flex;
+ flex-direction: column;
+ > :nth-child(1) {
+ flex: 1;
+ }
}
.simplebar-scrollbar::before {
diff --git a/src/controllers/Page/PageController.js b/src/controllers/Page/PageController.js
index e1841db..c361c50 100644
--- a/src/controllers/Page/PageController.js
+++ b/src/controllers/Page/PageController.js
@@ -12,7 +12,37 @@ class PageController {
// 首页
async indexGet(ctx) {
- return await ctx.render("page/index/index", {}, { includeSite: true, includeUser: true })
+ return await ctx.render(
+ "page/index/index",
+ {
+ apiList: [
+ {
+ name: "随机图片",
+ desc: "随机图片,点击查看。
右键可复制链接",
+ url: "https://pic.xieyaxin.top/random.php",
+ },
+ ],
+ blogs: [
+ {
+ title: "以梦为马,不负韶华",
+ content: "生活如诗,岁月如歌。让我们在时光的长河中,保持热爱,奔赴山海,书写属于自己的精彩篇章。",
+ },
+ {
+ title: "风雨过后是彩虹",
+ content: "以前,我以为自己很坚强,直到有一天,我发现自己连哭都哭不出来。",
+ },
+ {
+ title: "岁月如歌",
+ content: "未来,我希望能有更多的时间陪伴家人,有更多的时间去旅行,有更多的时间去实现自己的梦想。",
+ },
+ {
+ title: "明月如水",
+ content: "啊啊"
+ }
+ ].slice(0, 4),
+ },
+ { includeSite: true, includeUser: true }
+ )
}
// 未授权报错页
@@ -141,6 +171,10 @@ class PageController {
router.get("/articles", controller.pageGet("page/articles/index"), { auth: false })
router.get("/about", controller.pageGet("page/about/index"), { auth: false })
+ router.get("/terms", controller.pageGet("page/index/terms"), { auth: false })
+ router.get("/privacy", controller.pageGet("page/index/privacy"), { auth: false })
+ router.get("/faq", controller.pageGet("page/index/faq"), { auth: false })
+ // router.get("/feedback", controller.pageGet("page/index/feedback"), { auth: false })
router.get("/login", controller.loginGet.bind(controller), { auth: "try" })
router.post("/login", controller.loginPost.bind(controller), { auth: false })
router.get("/captcha", controller.captchaGet.bind(controller), { auth: false })
diff --git a/src/views/layouts/base.pug b/src/views/layouts/base.pug
index 01b5696..c8f6c3b 100644
--- a/src/views/layouts/base.pug
+++ b/src/views/layouts/base.pug
@@ -52,7 +52,7 @@ html(lang="zh-CN")
height: initial;
}
div(data-simplebar style="height: 100%")
- div(style="height: 100%; display: flex; flex-direction: column" id="aaaa")
+ div(style="height: 100%; display: flex; flex-direction: column")
block content
block scripts
+js('lib/bg-change.js')
diff --git a/src/views/layouts/empty.pug b/src/views/layouts/empty.pug
new file mode 100644
index 0000000..43cf7ae
--- /dev/null
+++ b/src/views/layouts/empty.pug
@@ -0,0 +1,115 @@
+extends /layouts/root.pug
+//- 采用纯背景页面的布局,背景图片随机切换,卡片采用高斯滤镜类玻璃化效果
+
+block $$head
+ +css('css/layouts/empty.css')
+ block pageHead
+
+block $$content
+ nav.navbar(class="relative")
+ .placeholder(class="h-[45px] w-full opacity-0")
+ .fixed-container(class="shadow fixed bg-white h-[45px] top-0 left-0 right-0 z-10")
+ .container.clearfix(class="h-full")
+ .navbar-brand
+ a(href="/" class="text-[20px]")
+ #{$site.site_title}
+ // 桌面端菜单
+ .left.menu.desktop-only
+ a.menu-item(href="/about") 明月照佳人
+ a.menu-item(href="/about") 岁月催人老
+ if !isLogin
+ .right.menu.desktop-only
+ a.menu-item(href="/login") 登录
+ a.menu-item(href="/register") 注册
+ else
+ .right.menu.desktop-only
+ a.menu-item(hx-post="/logout") 退出
+ a.menu-item() 欢迎您 , #{$user.username}
+ // 移动端:汉堡按钮
+ button.menu-toggle(type="button" aria-label="打开菜单")
+ span.bar
+ span.bar
+ span.bar
+ // 移动端菜单内容(与桌面端一致)
+ .mobile-menu.container
+ .left.menu
+ a.menu-item(href="/about") 明月照佳人
+ a.menu-item(href="/about") 岁月催人老
+ if !isLogin
+ .right.menu
+ a.menu-item(href="/login") 登录
+ a.menu-item(href="/register") 注册
+ else
+ .right.menu
+ a.menu-item(hx-post="/logout") 退出
+ a.menu-item() 欢迎您 , #{$user.username}
+ .page-layout
+ .page.container
+ block pageContent
+
+ footer.footer.shadow.mt-10
+ .footer-panel(class="bg-white border-t border-gray-200")
+ .footer-content.container(class="pt-12 pb-6")
+ .footer-main(class="grid grid-cols-1 md:grid-cols-4 gap-8 mb-8")
+ .footer-section
+ h3.footer-title(class="text-lg font-semibold text-gray-900 mb-4") #{$site.site_title}
+ p.footer-desc(class="text-gray-600 text-sm leading-relaxed") 明月照佳人,用真心对待世界。
岁月催人老,用真情对待自己。
+
+ .footer-section
+ h3.footer-title(class="text-lg font-semibold text-gray-900 mb-4") 快速链接
+ ul.footer-links(class="space-y-3")
+ li
+ a(href="/" class="text-gray-600 hover:text-blue-600 transition-colors duration-200 text-sm") 首页
+ li
+ a(href="/about" class="text-gray-600 hover:text-blue-600 transition-colors duration-200 text-sm") 关于我们
+ li
+ a(href="/contact" class="text-gray-600 hover:text-blue-600 transition-colors duration-200 text-sm") 联系我们
+ li
+ a(href="/help" class="text-gray-600 hover:text-blue-600 transition-colors duration-200 text-sm") 帮助中心
+
+ .footer-section
+ h3.footer-title(class="text-lg font-semibold text-gray-900 mb-4") 服务支持
+ ul.footer-links(class="space-y-3")
+ li
+ a(href="/terms" class="text-gray-600 hover:text-blue-600 transition-colors duration-200 text-sm") 服务条款
+ li
+ a(href="/privacy" class="text-gray-600 hover:text-blue-600 transition-colors duration-200 text-sm") 隐私政策
+ li
+ a(href="/faq" class="text-gray-600 hover:text-blue-600 transition-colors duration-200 text-sm") 常见问题
+ li
+ a(href="/feedback" class="text-gray-600 hover:text-blue-600 transition-colors duration-200 text-sm") 意见反馈
+
+ .footer-section
+ h3.footer-title(class="text-lg font-semibold text-gray-900 mb-4") 关注我
+ .social-links(class="flex space-x-4 flex-wrap")
+ a(href="#" class="social-link p-2 rounded-full bg-gray-100 hover:bg-blue-100 transition-colors duration-200" title="微信")
+ span.streamline-ultimate-color--wechat-logo
+ // a(href="#" class="social-link p-2 rounded-full bg-gray-100 hover:bg-red-100 transition-colors duration-200" title="微博")
+ span.fa7-brands--weibo
+ a(href="#" class="social-link p-2 rounded-full bg-gray-100 hover:bg-blue-100 transition-colors duration-200" title="QQ")
+ span.cib--tencent-qq
+ a(href="#" class="social-link p-2 rounded-full bg-gray-100 hover:bg-gray-200 transition-colors duration-200" title="GitHub")
+ span.ri--github-fill
+ a(href="https://blog.xieyaxin.top" target="_blank" class="social-link p-2 rounded-full bg-gray-100 hover:bg-gray-200 transition-colors duration-200" title="GitHub")
+ span.icomoon-free--blog
+
+ .footer-bottom(class="border-t border-gray-200 pt-6")
+ .footer-bottom-content(class="flex flex-col md:flex-row justify-between items-center")
+ .copyright(class="text-gray-500 text-sm mb-4 md:mb-0")
+ | © 2023-#{new Date().getFullYear()} #{$site.site_author}. 保留所有权利。
+ .footer-actions(class="flex items-center space-x-6")
+ a(href="/sitemap" class="text-gray-500 hover:text-blue-600 transition-colors duration-200 text-sm") 网站地图
+ a(href="/rss" class="text-gray-500 hover:text-blue-600 transition-colors duration-200 text-sm") RSS订阅
+
+block $$scripts
+ block pageScripts
+ script.
+ (function(){
+ var navbar = document.querySelector('.navbar');
+ var toggle = navbar && navbar.querySelector('.menu-toggle');
+ if(toggle){
+ toggle.addEventListener('click', function(){
+ navbar.classList.toggle('open');
+ });
+ }
+ })();
diff --git a/src/views/layouts/root.pug b/src/views/layouts/root.pug
index 60733ff..371d4e6 100644
--- a/src/views/layouts/root.pug
+++ b/src/views/layouts/root.pug
@@ -38,12 +38,14 @@ html(lang="zh-CN")
block $$scripts
script.
//- 处理滚动条位置
- const el = document.querySelector('.simplebar-content-wrapper')
- const scrollTop = sessionStorage.getItem('scrollTop-'+location.pathname)
- el.scrollTop = scrollTop
- el.addEventListener("scroll", function(e) {
- sessionStorage.setItem('scrollTop-'+location.pathname, e.target.scrollTop)
- })
+ window.onload = function() {
+ const el = document.querySelector('.simplebar-content-wrapper')
+ const scrollTop = sessionStorage.getItem('scrollTop-'+location.pathname)
+ el.scrollTop = scrollTop
+ el.addEventListener("scroll", function(e) {
+ sessionStorage.setItem('scrollTop-'+location.pathname, e.target.scrollTop)
+ })
+ }
//- 处理点击慢慢回到顶部
const backToTopBtn = document.querySelector('.back-to-top');
if (backToTopBtn) {
diff --git a/src/views/page/index/faq.pug b/src/views/page/index/faq.pug
new file mode 100644
index 0000000..f9cf08a
--- /dev/null
+++ b/src/views/page/index/faq.pug
@@ -0,0 +1,56 @@
+extends /layouts/empty.pug
+
+block pageHead
+ +css('css/page/index.css')
+
+block pageContent
+ .faq.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100")
+ h1(class="text-2xl font-bold mb-4") 常见问题(FAQ)
+ p(class="text-gray-600 mb-6") 为帮助您快速了解与使用本站,这里汇总了常见问答。
+
+ // 基础使用
+ h2(class="text-xl font-semibold mt-6 mb-3") 一、基础使用
+ dl.divide-y.divide-gray-100
+ div.py-4
+ dt.font-medium 我如何注册与登录?
+ dd.text-gray-700.mt-1 访问“注册/登录”页面,按提示完成信息填写即可。如遇验证码问题,请刷新或稍后重试。
+ div.py-4
+ dt.font-medium 忘记密码怎么办?
+ dd.text-gray-700.mt-1 目前暂未开放自助找回功能,请通过页脚联系方式与我们取得联系协助处理。
+
+ // 账号与安全
+ h2(class="text-xl font-semibold mt-6 mb-3") 二、账号与安全
+ dl.divide-y.divide-gray-100
+ div.py-4
+ dt.font-medium 如何提升账户安全?
+ dd.text-gray-700.mt-1 使用强密码、定期更换、不在公共设备保存登录信息,退出时及时登出。
+ div.py-4
+ dt.font-medium 我的数据会被如何使用?
+ dd.text-gray-700.mt-1 我们严格遵循最小必要与合规原则处理数据,详见
+ a(href="/privacy" class="text-blue-600 hover:underline") 隐私政策
+ | 。
+
+ // 功能与服务
+ h2(class="text-xl font-semibold mt-6 mb-3") 三、功能与服务
+ dl.divide-y.divide-gray-100
+ div.py-4
+ dt.font-medium 你们提供哪些公开 API?
+ dd.text-gray-700.mt-1 可在首页“API 列表”中查看示例与说明,或关注文档更新。
+ div.py-4
+ dt.font-medium 页面打不开/出现错误怎么办?
+ dd.text-gray-700.mt-1 刷新页面、清理缓存或更换网络环境;如仍有问题,请将报错信息与时间反馈给我们。
+
+ // 合规与条款
+ h2(class="text-xl font-semibold mt-6 mb-3") 四、合规与条款
+ dl.divide-y.divide-gray-100
+ div.py-4
+ dt.font-medium 需要遵守哪些条款?
+ dd.text-gray-700.mt-1 使用前请阅读并同意
+ a(href="/terms" class="text-blue-600 hover:underline") 服务条款
+ | 与
+ a(href="/privacy" class="text-blue-600 hover:underline") 隐私政策
+ | 。
+
+ p(class="text-gray-500 text-sm mt-8") 最近更新:#{new Date().getFullYear()} 年 #{new Date().getMonth()+1} 月 #{new Date().getDate()} 日
+
+
diff --git a/src/views/page/index/feedback.pug b/src/views/page/index/feedback.pug
new file mode 100644
index 0000000..8a141ee
--- /dev/null
+++ b/src/views/page/index/feedback.pug
@@ -0,0 +1,29 @@
+extends /layouts/empty.pug
+
+block pageHead
+ +css('css/page/index.css')
+
+block pageContent
+ .feedback.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100")
+ h1(class="text-2xl font-bold mb-2") 意见反馈
+ p(class="text-gray-600 mb-6") 欢迎提出您的建议或问题,我们会尽快处理。
+
+ form(class="space-y-4" method="post" action="#" onsubmit="alert('感谢反馈!'); return false;")
+ .grid.grid-cols-1.md\:grid-cols-2.gap-4
+ .form-item
+ label.block.text-sm.text-gray-600.mb-1(for="name") 您的称呼
+ input#name(type="text" name="name" placeholder="例如:张三" class="w-full border border-gray-200 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-200")
+ .form-item
+ label.block.text-sm.text-gray-600.mb-1(for="email") 邮箱(可选)
+ input#email(type="email" name="email" placeholder="用于回复您" class="w-full border border-gray-200 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-200")
+ .form-item
+ label.block.text-sm.text-gray-600.mb-1(for="subject") 主题
+ input#subject(type="text" name="subject" placeholder="简要概括问题/建议" class="w-full border border-gray-200 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-200")
+ .form-item
+ label.block.text-sm.text-gray-600.mb-1(for="content") 详细描述
+ textarea#content(name="content" rows="6" placeholder="请尽量描述清楚场景、复现步骤、预期与实际结果等" class="w-full border border-gray-200 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-200")
+ .flex.items-center.justify-between
+ button(type="submit" class="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors") 提交反馈
+ a(href="mailto:me@xieyaxin.top" class="text-sm text-gray-500 hover:text-blue-600") 或发送邮件联系
+
+
diff --git a/src/views/page/index/index copy 2.pug b/src/views/page/index/index copy 2.pug
new file mode 100644
index 0000000..c7ce24a
--- /dev/null
+++ b/src/views/page/index/index copy 2.pug
@@ -0,0 +1,11 @@
+extends /layouts/bg-page.pug
+
+block pageHead
+ +css("css/page/index.css")
+
+block pageContent
+ div(class="mt-[20px]")
+ +include()
+ include /htmx/navbar.pug
+ .card(class="mt-[20px]")
+ img(src="/static/bg2.webp" alt="bg")
\ No newline at end of file
diff --git a/src/views/page/index/index.pug b/src/views/page/index/index.pug
index c7ce24a..1438c2c 100644
--- a/src/views/page/index/index.pug
+++ b/src/views/page/index/index.pug
@@ -1,11 +1,58 @@
-extends /layouts/bg-page.pug
+extends /layouts/empty.pug
block pageHead
- +css("css/page/index.css")
+ +css('css/page/index.css')
+ +css('https://unpkg.com/tippy.js@5/dist/backdrop.css')
+ +js("https://unpkg.com/popper.js@1")
+ +js("https://unpkg.com/tippy.js@5")
+
+mixin item(url, desc)
+ a(href=url data-tippy-content=desc target="_blank" class="inline-block text-[16px] p-[10px] rounded-[10px] shadow")
+ block
+
+mixin card(blog)
+ .article-card(class="bg-white rounded-[12px] shadow p-6 transition hover:shadow-lg border border-gray-100")
+ h3.article-title(class="text-lg font-semibold text-gray-900 mb-2")
+ a(href="/article/1" class="hover:text-blue-600 transition-colors duration-200") #{blog.title}
+ p.article-meta(class="text-sm text-gray-400 mb-3")
+ | 作者:明月 | 2024-06-01 | 分类:生活感悟
+ p.article-desc(
+ class="text-gray-600 text-base mb-4 line-clamp-2"
+ style="height: 2.8em; overflow: hidden;"
+ )
+ | #{blog.content}
+ a(href="/article/1" class="inline-block text-sm text-blue-600 hover:underline transition-colors duration-200") 阅读全文 →
+
+mixin empty()
+ .div-placeholder(class="h-[100px] w-full bg-gray-100 text-center flex items-center justify-center text-[16px]")
+ block
block pageContent
- div(class="mt-[20px]")
- +include()
- include /htmx/navbar.pug
- .card(class="mt-[20px]")
- img(src="/static/bg2.webp" alt="bg")
\ No newline at end of file
+ div(class="mt-[20px]")
+ h2(class="text-[20px] font-bold mb-[10px]") 接口列表
+ if apiList && apiList.length > 0
+ .api.list
+ each api in apiList
+ +item(api.url, api.desc) #{api.name}
+ else
+ +empty() 空
+ div(class="mt-[20px]")
+ h2(class="text-[20px] font-bold mb-[10px]") 文章列表
+ if blogs && blogs.length > 0
+ .blog.list
+ each blog in blogs
+ +card(blog)
+ else
+ +empty() 空
+ div(class="mt-[20px]")
+ h2(class="text-[20px] font-bold mb-[10px]") 收藏列表
+ if collections && collections.length > 0
+ .blog.list
+ each collection in collections
+ +card(collection)
+ else
+ +empty() 收藏列表数据为空
+
+block pageScripts
+ script.
+ tippy('[data-tippy-content]');
\ No newline at end of file
diff --git a/src/views/page/index/privacy.pug b/src/views/page/index/privacy.pug
new file mode 100644
index 0000000..be9b0b1
--- /dev/null
+++ b/src/views/page/index/privacy.pug
@@ -0,0 +1,78 @@
+extends /layouts/empty.pug
+
+block pageHead
+ +css('css/page/index.css')
+
+block pageContent
+ .privacy.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100")
+ h1(class="text-2xl font-bold mb-4") 隐私政策
+ p(class="text-gray-600 mb-6") 我们重视您的个人信息与隐私保护。本隐私政策旨在向您说明我们如何收集、使用、共享与保护您的信息,以及您对个人信息享有的权利。请您在使用本站服务前仔细阅读并充分理解本政策的全部内容。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 一、适用范围
+ ul.list-disc.pl-6.text-gray-700
+ li 当您访问、浏览、注册、登录、使用本站提供的各项产品/服务时,本政策适用。
+ li 如与《服务条款》存在不一致,以本政策就个人信息处理相关内容为准。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 二、我们收集的信息
+ p 为向您提供服务与优化体验,我们可能收集以下信息:
+ ul.list-disc.pl-6.text-gray-700
+ li 账户信息:昵称、头像、联系方式(如邮箱、手机)、密码或凭证等。
+ li 使用信息:访问记录、点击行为、浏览历史、设备信息(设备型号、操作系统、浏览器类型、分辨率)、网络信息(IP、运营商)。
+ li 日志信息:错误日志、性能日志、系统事件,以便排查问题和提升稳定性。
+ li 交互信息:您与我们沟通时提交的反馈、工单、评论与表单信息。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 三、信息的来源与收集方式
+ ul.list-disc.pl-6.text-gray-700
+ li 您主动提供:注册、填写表单、提交反馈时提供的相关信息。
+ li 自动收集:通过 Cookie/本地存储、日志与统计分析工具自动采集的使用数据与设备信息。
+ li 第三方来源:在您授权的前提下,我们可能从依法合规的第三方获取必要信息以完善服务。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 四、我们如何使用信息
+ ul.list-disc.pl-6.text-gray-700
+ li 提供、维护与优化产品/服务的功能与性能。
+ li 账号管理、身份验证、安全防护与风险控制。
+ li 向您发送与服务相关的通知(如更新、变更、异常提示)。
+ li 数据统计与分析,用于改善产品体验与用户支持。
+ li 依法需配合的监管合规、争议处理与维权。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 五、Cookie 与本地存储
+ p 为确保基础功能和提升体验,我们会使用 Cookie 或浏览器本地存储:
+ ul.list-disc.pl-6.text-gray-700
+ li 目的:会话保持、偏好设置、性能与功能分析。
+ li 管理:您可在浏览器设置中清除或禁止 Cookie;但部分功能可能因此受限或不可用。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 六、信息共享、转让与公开披露
+ ul.list-disc.pl-6.text-gray-700
+ li 我们不会向无关第三方出售您的个人信息。
+ li 仅在以下情形共享或转让:获得您明确同意;基于法律法规、司法或行政机关要求;为实现功能所必需的可信合作伙伴(最小必要原则并签署保密与数据保护协议)。
+ li 公开披露仅在法律要求或为保护重大公共利益、他人生命财产安全等必要情形下进行。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 七、第三方服务与 SDK
+ p 本站可能集成第三方服务(如统计分析、支付、登录、地图等)。第三方可能独立收集、处理您的信息,其行为受其自身隐私政策约束。我们将审慎评估接入必要性并尽可能要求其遵循最小必要、去标识化与安全合规。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 八、信息的存储与安全
+ ul.list-disc.pl-6.text-gray-700
+ li 存储地点与期限:信息通常存储在依法设立的服务器中,保存期限以实现目的所需的最短时间为准,法律法规另有要求的从其规定。
+ li 安全措施:采用访问控制、加密传输/存储、最小权限、定期审计与备份等措施,降低信息泄露、损毁、丢失风险。
+ li 事件响应:一旦发生安全事件,我们将按照法律法规履行告知与处置义务。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 九、您的权利
+ ul.list-disc.pl-6.text-gray-700
+ li 访问、更正与删除:在不影响其他自然人合法权益及法律留存要求的前提下,您可按照指引访问、更正或删除相关信息。
+ li 撤回同意与注销账户:您可撤回非必要信息处理的授权,或申请注销账户(法律法规另有规定或为履行合同所必需的除外)。
+ li 获取副本与可携权(如适用):在符合法律条件时,您可请求导出个人信息副本。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 十、未成年人保护
+ p 未成年人应在监护人监护、指导下使用本站服务。若您是监护人并对未成年人信息有疑问,请与我们联系,我们将在核实后尽快处理。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 十一、跨境传输(如适用)
+ p 如涉及将您的个人信息传输至境外,我们会依据适用法律履行必要评估、备案与合同保障义务,并确保接收方具备足够的数据保护能力。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 十二、本政策的更新
+ p 为适应业务、技术或法律法规变化,我们可能对本政策进行更新。重大变更将以显著方式提示。您继续使用服务即视为接受更新后的政策。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 十三、联系我们
+ p 如您对本政策或个人信息保护有任何疑问、意见或请求,请通过页脚中的联系方式与我们取得联系,我们将尽快予以回复。
+
+ p(class="text-gray-500 text-sm mt-8") 最近更新:#{new Date().getFullYear()} 年 #{new Date().getMonth()+1} 月 #{new Date().getDate()} 日
+
diff --git a/src/views/page/index/terms.pug b/src/views/page/index/terms.pug
new file mode 100644
index 0000000..c271f07
--- /dev/null
+++ b/src/views/page/index/terms.pug
@@ -0,0 +1,67 @@
+extends /layouts/empty.pug
+
+block pageHead
+ +css('css/page/index.css')
+
+block pageContent
+ .terms.container(class="mt-[20px] bg-white rounded-[12px] shadow p-6 border border-gray-100")
+ h1(class="text-2xl font-bold mb-4") 服务条款
+ p(class="text-gray-600 mb-6") 欢迎使用本网站与相关服务。为保障您的合法权益,请在使用前仔细阅读并充分理解本服务条款。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 一、协议的接受与变更
+ p 本条款构成您与本站之间就使用本站服务所达成的协议。一旦您访问或使用本站,即视为您已阅读并同意受本条款约束。本站有权根据业务需要对条款进行修订,修订后的条款将通过页面公示或其他适当方式通知,若您继续使用服务,即视为接受修订内容。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 二、账户注册与使用
+ ul.list-disc.pl-6.text-gray-700
+ li 您应当具备完全民事行为能力;如不具备,请确保在监护人指导下使用。
+ li 注册信息应真实、准确、完整,并在变更时及时更新。
+ li 您应妥善保管账户与密码,因保管不善导致的损失由您自行承担。
+ li 发现任何未经授权的使用行为,请立即与我们联系。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 三、用户行为规范
+ ul.list-disc.pl-6.text-gray-700
+ li 遵守法律法规,不得利用本站制作、复制、发布、传播违法违规内容。
+ li 不得干扰、破坏本站正常运营,不得进行未经授权的访问、抓取或数据采集。
+ li 不得对本站进行逆向工程、反编译或尝试获取源代码。
+ li 尊重他人合法权益,不得侵犯他人知识产权、隐私权、名誉权等。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 四、内容与知识产权
+ ul.list-disc.pl-6.text-gray-700
+ li 除非另有说明,本站及其内容(包括但不限于文字、图片、界面、版式、程序、数据等)受相关法律保护。
+ li 未经授权,任何人不得以任何方式使用、复制、修改、传播或用于商业目的。
+ li 用户在本站发布或上传的内容,用户应保证拥有相应权利且不侵犯任何第三方权益。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 五、隐私与数据保护
+ p 我们将依法收集、使用、存储与保护您的个人信息。更多细则请参见
+ a(href="/privacy" class="text-blue-600 hover:underline") 隐私政策
+ | 。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 六、第三方服务
+ p 本站可能集成或链接第三方服务。您对第三方服务的使用应遵循其各自的条款与政策,由此产生的纠纷与责任由您与第三方自行解决。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 七、服务变更、中断与终止
+ ul.list-disc.pl-6.text-gray-700
+ li 因系统维护、升级或不可抗力等原因,本站有权对服务进行变更、中断或终止。
+ li 对于免费服务,本站不对中断或终止承担任何赔偿责任;对付费服务,将依据法律法规与约定处理。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 八、免责声明
+ ul.list-disc.pl-6.text-gray-700
+ li 本站以“现状”与“可得”基础提供服务,不对服务的准确性、完整性、持续性做出明示或暗示保证。
+ li 因网络故障、设备故障、黑客攻击、不可抗力等造成的服务中断或数据丢失,本站不承担由此产生的损失责任。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 九、违约处理
+ p 如您违反本条款或相关法律法规,本站有权采取包括但不限于限制功能、冻结或注销账号、删除内容、追究法律责任等措施。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 十、适用法律与争议解决
+ p 本条款的订立、执行与解释及争议的解决,适用中华人民共和国法律。因本条款产生的任何争议,双方应友好协商解决;协商不成的,提交本站所在地有管辖权的人民法院诉讼解决。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 十一、未成年人保护
+ p 未成年人应在监护人监护、指导下使用本站服务。监护人应承担监护责任,合理监督未成年人上网行为。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 十二、条款的可分割性
+ p 如本条款任何条款被认定为无效或不可执行,其余条款仍然有效并对双方具有约束力。
+
+ h2(class="text-xl font-semibold mt-6 mb-3") 十三、联系与通知
+ p 如您对本条款有任何疑问或需要联系本站,请通过页脚中的联系方式与我们取得联系。
+
+ p(class="text-gray-500 text-sm mt-8") 最近更新:#{new Date().getFullYear()} 年 #{new Date().getMonth()+1} 月 #{new Date().getDate()} 日