feat(static): 优化社区首页 — Hero首屏+特性卡片+悬浮毛玻璃导航,CTA随登录态切换
This commit is contained in:
1 parent
27ab50ae68
commit
66963092a3
3 files changed
+291
-32
No files matched your search
+194
-9
@@ -4,31 +4,177 @@ body {
|
|||||||
align-items: normal;
|
align-items: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== 头部 ===== */
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
html { scroll-behavior: smooth; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== 按钮 ===== */
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0.55rem 1.3rem;
|
||||||
|
font-size: 0.88rem;
|
||||||
|
font-weight: 600;
|
||||||
|
font-family: inherit;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
line-height: 1.4;
|
||||||
|
transition: opacity 0.15s, transform 0.1s, background 0.15s, border-color 0.15s;
|
||||||
|
}
|
||||||
|
.btn:active { transform: scale(0.96); }
|
||||||
|
.btn-primary { background: var(--accent); color: #fff; }
|
||||||
|
.btn-primary:hover { background: var(--accent-dark); opacity: 1; }
|
||||||
|
.btn-ghost { background: var(--accent-soft); color: var(--accent-dark); }
|
||||||
|
.btn-ghost:hover { border-color: var(--accent); opacity: 1; }
|
||||||
|
.btn-lg { padding: 0.7rem 1.9rem; font-size: 1rem; border-radius: var(--radius-md); }
|
||||||
|
|
||||||
|
/* ===== 头部:悬浮毛玻璃导航(镜像 minimap/userpanel 风格) ===== */
|
||||||
.header {
|
.header {
|
||||||
|
position: sticky;
|
||||||
|
top: 0.75rem;
|
||||||
|
z-index: 100;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.5rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: rgba(253, 246, 238, 0.72);
|
||||||
|
border: 1px solid var(--border-light);
|
||||||
|
backdrop-filter: blur(12px);
|
||||||
|
-webkit-backdrop-filter: blur(12px);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
transition: background 0.2s, border-color 0.2s;
|
||||||
}
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.header {
|
||||||
|
background: rgba(30, 23, 18, 0.72);
|
||||||
|
border-color: var(--border);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.header h1 {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
transition: color 0.15s;
|
||||||
|
}
|
||||||
|
.header h1:hover { color: var(--accent); }
|
||||||
|
|
||||||
.right-group {
|
.right-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
flex-wrap: wrap;
|
||||||
|
gap: 0.4rem;
|
||||||
.right-group > img,
|
|
||||||
.right-group > b,
|
|
||||||
.right-group > button {
|
|
||||||
margin-left: 5px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#avatar {
|
#avatar {
|
||||||
|
width: 36px;
|
||||||
|
height: 36px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
border: 1.5px solid var(--border);
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== 网站简介 ===== */
|
#name {
|
||||||
|
font-size: 0.88rem;
|
||||||
|
max-width: 120px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Hero 首屏 ===== */
|
||||||
|
.hero {
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
padding: 4rem 1rem 3rem;
|
||||||
|
}
|
||||||
|
.hero::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: radial-gradient(ellipse 60% 50% at 50% 30%, var(--accent-glow), transparent 70%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.hero > * { position: relative; }
|
||||||
|
.hero-title {
|
||||||
|
font-size: clamp(1.8rem, 5vw, 2.6rem);
|
||||||
|
font-weight: 800;
|
||||||
|
line-height: 1.35;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
.accent-text { color: var(--accent); }
|
||||||
|
.hero-sub {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
color: var(--fg-secondary);
|
||||||
|
}
|
||||||
|
.hero-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin-top: 1.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== 特性卡片 ===== */
|
||||||
|
.section-title {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
|
.features {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
|
||||||
|
gap: 0.9rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.feature-card {
|
||||||
|
background: var(--card);
|
||||||
|
border: 1px solid var(--border-light);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
padding: 1.4rem 1.25rem;
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
transition: transform 0.18s, box-shadow 0.2s, border-color 0.2s;
|
||||||
|
}
|
||||||
|
.feature-card:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
border-color: var(--border);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
.feature-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 38px;
|
||||||
|
height: 38px;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
background: var(--accent-soft);
|
||||||
|
color: var(--accent-dark);
|
||||||
|
}
|
||||||
|
.feature-icon svg { width: 20px; height: 20px; }
|
||||||
|
.feature-card h3 { margin-bottom: 0.35rem; }
|
||||||
|
.feature-card p {
|
||||||
|
font-size: 0.86rem;
|
||||||
|
line-height: 1.65;
|
||||||
|
color: var(--fg-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== 关于本站 ===== */
|
||||||
|
.about {
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: 2rem;
|
||||||
|
}
|
||||||
.site-intro {
|
.site-intro {
|
||||||
max-width: 640px;
|
max-width: 640px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@@ -36,3 +182,42 @@ body {
|
|||||||
line-height: 1.9;
|
line-height: 1.9;
|
||||||
color: var(--fg-secondary);
|
color: var(--fg-secondary);
|
||||||
}
|
}
|
||||||
|
.quick-links {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1.25rem;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
}
|
||||||
|
.quick-links a {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: var(--muted);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.15s;
|
||||||
|
}
|
||||||
|
.quick-links a:hover { color: var(--accent); }
|
||||||
|
|
||||||
|
/* ===== 入场动画 ===== */
|
||||||
|
@keyframes fade-up {
|
||||||
|
from { opacity: 0; transform: translateY(12px); }
|
||||||
|
to { opacity: 1; transform: none; }
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
.hero > *, .feature-card, .about { animation: fade-up 0.5s ease both; }
|
||||||
|
.hero-sub { animation-delay: 0.08s; }
|
||||||
|
.hero-actions { animation-delay: 0.16s; }
|
||||||
|
.feature-card:nth-child(2) { animation-delay: 0.06s; }
|
||||||
|
.feature-card:nth-child(3) { animation-delay: 0.12s; }
|
||||||
|
.feature-card:nth-child(4) { animation-delay: 0.18s; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== 响应式 ===== */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.header { top: 0.5rem; padding: 0.45rem 0.75rem; }
|
||||||
|
.header h1 { font-size: 1rem; }
|
||||||
|
#name { max-width: 72px; }
|
||||||
|
.hero { padding: 2.5rem 0.5rem 2rem; }
|
||||||
|
.hero-sub { font-size: 0.95rem; }
|
||||||
|
.hero-actions { flex-direction: column; align-items: stretch; }
|
||||||
|
.section-title { margin-top: 2rem; }
|
||||||
|
}
|
||||||
+78
-22
@@ -1,35 +1,91 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="description" content="DNFS 树状笔记:以树状结构组织知识的笔记社区,支持 Markdown、链接卡片、图片与文件分享。">
|
||||||
|
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#fdf6ee">
|
||||||
|
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1e1712">
|
||||||
|
<link rel="icon" href="favicon.ico">
|
||||||
<link rel="stylesheet" href="css/theme.css">
|
<link rel="stylesheet" href="css/theme.css">
|
||||||
<link rel="stylesheet" href="css/index.css">
|
<link rel="stylesheet" href="css/index.css">
|
||||||
<title>DNFS 欢迎来到树状笔记</title>
|
<title>DNFS 树状笔记 — 让知识自然成体系</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<h1 onclick="window.location.href='index.html'">DNFS 树状笔记</h1>
|
<h1 id="logo">DNFS 树状笔记</h1>
|
||||||
<div class="right-group">
|
<nav class="right-group" aria-label="用户操作">
|
||||||
<img src="favicon.ico" alt="头像加载失败" id="avatar" width="70px" height="70px">
|
<img src="favicon.ico" alt="用户头像" id="avatar" style="display:none">
|
||||||
<b id="name">DNFS</b>
|
<b id="name" style="display:none"></b>
|
||||||
<button id="enterBtn" onclick="window.location.href='dnfs.html'" style="display:none">进入笔记</button>
|
<button id="enterBtn" class="btn btn-primary" style="display:none">进入笔记</button>
|
||||||
<button id="logoutBtn" style="display:none">退出</button>
|
<button id="logoutBtn" class="btn btn-ghost" style="display:none">退出</button>
|
||||||
<button id="loginBtn" onclick="window.location.href='login.html'">登录</button>
|
<button id="loginBtn" class="btn btn-primary">登录</button>
|
||||||
<button id="registerBtn" onclick="window.location.href='register.html'">注册</button>
|
<button id="registerBtn" class="btn btn-ghost">注册</button>
|
||||||
</div>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<div id="main-page">
|
|
||||||
<h2>关于本站</h2>
|
<main id="main-page">
|
||||||
<p class="site-intro">
|
<section class="hero">
|
||||||
DNFS 树状笔记是一个以树状结构组织内容的笔记社区:每个节点都可以生长出子节点,
|
<h2 class="hero-title">让知识像树一样<br><span class="accent-text">自然生长</span></h2>
|
||||||
像树枝一样层层延展,让知识自然成体系。支持 Markdown 文本、链接卡片、图片与文件分享,
|
<p class="hero-sub">每个节点都可以生长出子节点,像树枝一样层层延展</p>
|
||||||
注册登录后即可创建属于你自己的知识树。
|
<div class="hero-actions">
|
||||||
</p>
|
<button id="ctaBtn" class="btn btn-primary btn-lg">开始记录</button>
|
||||||
</div>
|
<a class="btn btn-ghost btn-lg" href="#features">了解更多</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="features">
|
||||||
|
<h2 class="section-title">为什么选择树状笔记</h2>
|
||||||
|
<div class="features">
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon" aria-hidden="true">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" y1="10.51" x2="15.42" y2="6.51"/><line x1="8.59" y1="13.49" x2="15.42" y2="17.49"/></svg>
|
||||||
|
</div>
|
||||||
|
<h3>树状结构组织</h3>
|
||||||
|
<p>每个节点都能生长出子节点,像树枝般层层延展,让零散的想法自然汇聚成体系。</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon" aria-hidden="true">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
|
||||||
|
</div>
|
||||||
|
<h3>Markdown 写作</h3>
|
||||||
|
<p>原生支持 Markdown 渲染,代码块、引用、列表一应俱全,专注内容本身。</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon" aria-hidden="true">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
|
||||||
|
</div>
|
||||||
|
<h3>多媒体分享</h3>
|
||||||
|
<p>链接卡片、图片直显、文件下载,多种内容形态一站承载,分享更自由。</p>
|
||||||
|
</div>
|
||||||
|
<div class="feature-card">
|
||||||
|
<div class="feature-icon" aria-hidden="true">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
|
||||||
|
</div>
|
||||||
|
<h3>深色模式</h3>
|
||||||
|
<p>跟随系统偏好自动切换明暗主题,日夜皆宜的舒适阅读体验。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="about">
|
||||||
|
<h2 class="section-title">关于本站</h2>
|
||||||
|
<p class="site-intro">
|
||||||
|
DNFS 树状笔记是一个以树状结构组织内容的笔记社区:每个节点都可以生长出子节点,
|
||||||
|
像树枝一样层层延展,让知识自然成体系。支持 Markdown 文本、链接卡片、图片与文件分享,
|
||||||
|
注册登录后即可创建属于你自己的知识树。
|
||||||
|
</p>
|
||||||
|
<div class="quick-links">
|
||||||
|
<a href="allcolor.html">调色板</a>
|
||||||
|
<a href="games/">小游戏</a>
|
||||||
|
<a href="LICENSE.html">用户使用条例</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">蜀ICP备2024107064号-2</a>
|
<a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener">蜀ICP备2024107064号-2</a>
|
||||||
</footer>
|
</footer>
|
||||||
<script src="js/index.js"></script>
|
<script src="js/index.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,16 +1,30 @@
|
|||||||
/* index.js — 社区首页逻辑
|
/* index.js — 社区首页逻辑
|
||||||
*
|
*
|
||||||
* 登录态检测:POST /whoami(HttpOnly q4_token Cookie 自动携带,JS 不经手 Token)
|
* 登录态检测:POST /whoami(HttpOnly q4_token Cookie 自动携带,JS 不经手 Token)
|
||||||
* 已登录:显示用户名与"进入笔记/退出"按钮;未登录:显示"登录/注册"
|
* 已登录:显示头像/用户名与"进入笔记/退出"按钮,首屏 CTA 指向笔记页
|
||||||
|
* 未登录:显示"登录/注册",首屏 CTA 指向登录页
|
||||||
*/
|
*/
|
||||||
(function () {
|
(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const nameEl = document.getElementById('name');
|
const nameEl = document.getElementById('name');
|
||||||
|
const avatarEl = document.getElementById('avatar');
|
||||||
const enterBtn = document.getElementById('enterBtn');
|
const enterBtn = document.getElementById('enterBtn');
|
||||||
const logoutBtn = document.getElementById('logoutBtn');
|
const logoutBtn = document.getElementById('logoutBtn');
|
||||||
const loginBtn = document.getElementById('loginBtn');
|
const loginBtn = document.getElementById('loginBtn');
|
||||||
const registerBtn = document.getElementById('registerBtn');
|
const registerBtn = document.getElementById('registerBtn');
|
||||||
|
const ctaBtn = document.getElementById('ctaBtn');
|
||||||
|
const logoEl = document.getElementById('logo');
|
||||||
|
|
||||||
|
let loggedIn = false;
|
||||||
|
|
||||||
|
function go(url) { window.location.href = url; }
|
||||||
|
|
||||||
|
logoEl.addEventListener('click', () => go('index.html'));
|
||||||
|
enterBtn.addEventListener('click', () => go('dnfs.html'));
|
||||||
|
loginBtn.addEventListener('click', () => go('login.html'));
|
||||||
|
registerBtn.addEventListener('click', () => go('register.html'));
|
||||||
|
ctaBtn.addEventListener('click', () => go(loggedIn ? 'dnfs.html' : 'login.html'));
|
||||||
|
|
||||||
async function checkLogin() {
|
async function checkLogin() {
|
||||||
try {
|
try {
|
||||||
@@ -18,11 +32,15 @@
|
|||||||
if (!res.ok) return;
|
if (!res.ok) return;
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data && data.login && data.user) {
|
if (data && data.login && data.user) {
|
||||||
|
loggedIn = true;
|
||||||
nameEl.textContent = String(data.user);
|
nameEl.textContent = String(data.user);
|
||||||
|
nameEl.style.display = '';
|
||||||
|
avatarEl.style.display = '';
|
||||||
enterBtn.style.display = '';
|
enterBtn.style.display = '';
|
||||||
logoutBtn.style.display = '';
|
logoutBtn.style.display = '';
|
||||||
loginBtn.style.display = 'none';
|
loginBtn.style.display = 'none';
|
||||||
registerBtn.style.display = 'none';
|
registerBtn.style.display = 'none';
|
||||||
|
ctaBtn.textContent = '进入我的知识树';
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn('index: 登录态检测失败', e.message);
|
console.warn('index: 登录态检测失败', e.message);
|
||||||
|
|||||||
Reference in new issue
Block a user