Files
goodbuddy/demoui.html
T

1222 lines
30 KiB
HTML

<!doctype html>
<html lang="zh-CN" data-theme="light">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<title>GoodBuddy 主题配色 Demo</title>
<style>
:root {
color-scheme: light;
--page-bg: #e8f0f5;
--page-glow: rgb(117 204 236 / 25%);
--app-bg: #ffffff;
--sidebar-bg: #edf4f8;
--topbar-bg: #f7fafc;
--surface: #ffffff;
--surface-subtle: #f3f7fa;
--surface-muted: #e7eef4;
--text: #17263a;
--text-secondary: #51657a;
--text-muted: #718498;
--border: #d1dee8;
--border-strong: #b9cad8;
--accent: #0877dc;
--accent-hover: #0668c2;
--accent-soft: #e4f2ff;
--accent-border: #afd3f2;
--teal: #078f7d;
--teal-soft: #e2f7f2;
--danger: #c23b47;
--shadow-app: 0 28px 70px rgb(41 74 101 / 18%);
--shadow-card: 0 8px 24px rgb(54 94 126 / 9%);
--shadow-float: 0 16px 36px rgb(41 74 101 / 16%);
--focus: 0 0 0 3px rgb(8 119 220 / 22%);
}
:root[data-theme="dark"] {
color-scheme: dark;
--page-bg: #030a11;
--page-glow: rgb(25 116 159 / 25%);
--app-bg: #07131f;
--sidebar-bg: #0d2233;
--topbar-bg: #0a1b29;
--surface: #0d1d2c;
--surface-subtle: #12283a;
--surface-muted: #1a3448;
--text: #edf7ff;
--text-secondary: #b5c6d5;
--text-muted: #8fa6b9;
--border: #29445a;
--border-strong: #3b5b73;
--accent: #72c5ff;
--accent-hover: #9bd7ff;
--accent-soft: #123b5b;
--accent-border: #28668f;
--teal: #63ddc7;
--teal-soft: #103c36;
--danger: #ff9ca7;
--shadow-app: 0 34px 90px rgb(0 4 9 / 58%);
--shadow-card: 0 10px 28px rgb(0 4 9 / 24%);
--shadow-float: 0 18px 42px rgb(0 4 9 / 46%);
--focus: 0 0 0 3px rgb(114 197 255 / 24%);
}
* {
box-sizing: border-box;
}
html,
body {
width: 100%;
min-width: 320px;
min-height: 100%;
margin: 0;
}
body {
display: grid;
min-height: 100vh;
padding: clamp(16px, 3vw, 40px);
overflow: hidden;
background:
radial-gradient(
circle at 52% -12%,
var(--page-glow),
transparent 42%
),
var(--page-bg);
color: var(--text);
font-family:
Inter, "Noto Sans SC", "Segoe UI", "PingFang SC",
"Microsoft YaHei UI", sans-serif;
place-items: center;
transition:
background 220ms ease,
color 180ms ease;
}
button,
input {
color: inherit;
font: inherit;
}
button {
border: 0;
}
button:focus-visible,
input:focus-visible {
outline: 0;
box-shadow: var(--focus);
}
.demo-shell {
position: relative;
display: grid;
width: min(1380px, 100%);
height: min(860px, calc(100vh - clamp(32px, 6vw, 80px)));
min-height: 620px;
overflow: hidden;
border: 1px solid var(--border);
border-radius: 24px;
background: var(--app-bg);
box-shadow: var(--shadow-app);
grid-template-columns: 238px minmax(0, 1fr);
transition:
background 180ms ease,
border-color 180ms ease,
box-shadow 180ms ease;
}
.sidebar {
display: flex;
min-width: 0;
padding: 22px 16px 16px;
border-right: 1px solid var(--border);
background: var(--sidebar-bg);
flex-direction: column;
transition:
background 180ms ease,
border-color 180ms ease;
}
.brand {
display: flex;
align-items: center;
padding: 0 8px 22px;
gap: 11px;
}
.brand-mark,
.assistant-avatar {
display: grid;
color: white;
place-items: center;
}
.brand-mark {
width: 36px;
height: 36px;
flex: 0 0 36px;
border-radius: 11px;
background: linear-gradient(145deg, #1788ec, #08a994);
box-shadow: 0 6px 16px rgb(8 119 220 / 20%);
}
.brand-mark svg {
width: 22px;
height: 22px;
}
.brand-copy {
min-width: 0;
}
.brand-copy strong,
.brand-copy span {
display: block;
}
.brand-copy strong {
font-size: 14px;
letter-spacing: -0.01em;
}
.brand-copy span {
margin-top: 2px;
color: var(--text-muted);
font-size: 10px;
}
.project-button,
.sidebar-search {
display: flex;
width: 100%;
align-items: center;
min-height: 38px;
border: 1px solid var(--border);
border-radius: 10px;
background: var(--surface);
color: var(--text-secondary);
gap: 9px;
}
.project-button {
padding: 0 10px;
cursor: pointer;
text-align: left;
}
.project-button span {
flex: 1;
overflow: hidden;
color: var(--text);
font-size: 11px;
font-weight: 650;
text-overflow: ellipsis;
white-space: nowrap;
}
.new-chat {
display: flex;
width: 100%;
min-height: 40px;
align-items: center;
padding: 0 12px;
border-radius: 10px;
margin-top: 10px;
background: var(--accent);
color: white;
cursor: pointer;
font-size: 12px;
font-weight: 700;
gap: 9px;
transition:
background 120ms ease,
transform 120ms ease;
}
:root[data-theme="dark"] .new-chat {
background: #1476c8;
}
.new-chat:hover {
background: var(--accent-hover);
transform: translateY(-1px);
}
.sidebar-search {
margin: 10px 0 16px;
padding: 0 10px;
}
.sidebar-search input {
width: 100%;
min-width: 0;
border: 0;
outline: 0;
background: transparent;
font-size: 11px;
}
.sidebar-search input::placeholder {
color: var(--text-muted);
}
.nav-label {
padding: 0 9px;
margin: 2px 0 7px;
color: var(--text-muted);
font-size: 9px;
font-weight: 750;
letter-spacing: 0.1em;
}
.nav {
display: grid;
gap: 4px;
}
.nav-item {
display: flex;
width: 100%;
min-height: 38px;
align-items: center;
padding: 0 10px;
border: 1px solid transparent;
border-radius: 10px;
background: transparent;
color: var(--text-secondary);
cursor: pointer;
font-size: 12px;
font-weight: 580;
gap: 10px;
text-align: left;
transition:
background 120ms ease,
color 120ms ease,
border-color 120ms ease;
}
.nav-item:hover {
background: color-mix(
in srgb,
var(--accent-soft) 56%,
transparent
);
color: var(--accent);
}
.nav-item.is-active {
border-color: var(--accent-border);
background: var(--accent-soft);
color: var(--accent);
}
.nav-icon,
.tool-icon,
.inline-icon {
display: grid;
place-items: center;
}
.nav-icon {
width: 18px;
height: 18px;
flex: 0 0 18px;
}
svg {
width: 18px;
height: 18px;
fill: none;
stroke: currentColor;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 1.8;
}
.sidebar-footer {
padding-top: 14px;
border-top: 1px solid var(--border);
margin-top: auto;
}
.profile {
display: flex;
width: 100%;
align-items: center;
padding: 8px;
border-radius: 10px;
background: transparent;
color: var(--text-secondary);
cursor: pointer;
gap: 9px;
text-align: left;
}
.profile:hover {
background: var(--surface);
}
.profile-avatar {
display: grid;
width: 30px;
height: 30px;
flex: 0 0 30px;
border-radius: 9px;
background: var(--teal-soft);
color: var(--teal);
font-size: 10px;
font-weight: 800;
place-items: center;
}
.profile-copy {
min-width: 0;
}
.profile-copy strong,
.profile-copy span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.profile-copy strong {
color: var(--text);
font-size: 11px;
}
.profile-copy span {
margin-top: 2px;
color: var(--text-muted);
font-size: 9px;
}
.workspace {
display: grid;
min-width: 0;
min-height: 0;
background: var(--app-bg);
grid-template-rows: 62px minmax(0, 1fr);
transition: background 180ms ease;
}
.topbar {
display: flex;
min-width: 0;
align-items: center;
padding: 0 20px;
border-bottom: 1px solid var(--border);
background: var(--topbar-bg);
gap: 10px;
transition:
background 180ms ease,
border-color 180ms ease;
}
.title-group {
min-width: 0;
}
.title-group strong,
.title-group span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.title-group strong {
font-size: 13px;
}
.title-group span {
margin-top: 3px;
color: var(--text-muted);
font-size: 9px;
}
.scope-chip,
.mode-chip {
display: inline-flex;
min-height: 28px;
align-items: center;
border-radius: 999px;
font-size: 10px;
font-weight: 650;
white-space: nowrap;
}
.scope-chip {
padding: 0 10px;
border: 1px solid var(--accent-border);
background: var(--accent-soft);
color: var(--accent);
gap: 6px;
}
.scope-chip::before {
width: 6px;
height: 6px;
border-radius: 50%;
background: currentColor;
content: "";
}
.topbar-actions {
display: flex;
min-width: 0;
align-items: center;
margin-left: auto;
gap: 8px;
}
.mode-chip {
padding: 0 10px;
border: 1px solid var(--border);
background: var(--surface);
color: var(--text-secondary);
}
.theme-toggle {
display: flex;
min-height: 34px;
align-items: center;
padding: 3px 4px 3px 10px;
border: 1px solid var(--border-strong);
border-radius: 999px;
background: var(--surface);
color: var(--text-secondary);
cursor: pointer;
font-size: 10px;
font-weight: 700;
gap: 8px;
transition:
background 180ms ease,
border-color 180ms ease;
}
.theme-toggle__track {
position: relative;
width: 44px;
height: 26px;
border-radius: 999px;
background: var(--surface-muted);
transition: background 180ms ease;
}
.theme-toggle__thumb {
position: absolute;
top: 3px;
left: 3px;
display: grid;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--surface);
box-shadow: 0 2px 7px rgb(34 62 85 / 22%);
color: var(--accent);
place-items: center;
transition:
left 180ms ease,
background 180ms ease;
}
.theme-toggle__thumb svg {
width: 12px;
height: 12px;
stroke-width: 2;
}
:root[data-theme="dark"] .theme-toggle__track {
background: var(--accent-soft);
}
:root[data-theme="dark"] .theme-toggle__thumb {
left: 21px;
}
.chat-canvas {
display: grid;
min-width: 0;
min-height: 0;
background: var(--app-bg);
grid-template-rows: minmax(0, 1fr) auto;
}
.messages {
min-height: 0;
padding: clamp(24px, 4vw, 48px)
clamp(24px, 7vw, 92px) 24px;
overflow: auto;
}
.message-flow {
width: min(820px, 100%);
margin: 0 auto;
}
.user-message {
display: flex;
justify-content: flex-end;
margin-bottom: 24px;
}
.user-bubble {
max-width: min(660px, 88%);
padding: 13px 16px;
border-radius: 16px 16px 4px 16px;
background: #0b78dc;
box-shadow: 0 7px 18px rgb(8 119 220 / 18%);
color: white;
font-size: 13px;
line-height: 1.65;
}
:root[data-theme="dark"] .user-bubble {
background: #176fb7;
box-shadow: 0 8px 22px rgb(0 7 14 / 28%);
}
.assistant-message {
display: grid;
gap: 12px;
grid-template-columns: 34px minmax(0, 1fr);
}
.assistant-avatar {
width: 34px;
height: 34px;
border-radius: 11px;
background: linear-gradient(145deg, #1285d9, #08a68e);
box-shadow: 0 6px 15px rgb(8 143 125 / 17%);
}
.assistant-avatar svg {
width: 18px;
height: 18px;
}
.assistant-content {
min-width: 0;
}
.assistant-meta {
display: flex;
align-items: center;
margin: 2px 0 9px;
gap: 8px;
}
.assistant-meta strong {
font-size: 12px;
}
.assistant-meta span {
color: var(--text-muted);
font-size: 9px;
}
.assistant-copy {
margin: 0;
color: var(--text-secondary);
font-size: 13px;
line-height: 1.75;
}
.tool-card {
display: grid;
max-width: 620px;
min-height: 68px;
align-items: center;
padding: 12px;
border: 1px solid var(--border);
border-radius: 13px;
margin-top: 15px;
background: var(--surface-subtle);
box-shadow: var(--shadow-card);
gap: 11px;
grid-template-columns: 38px minmax(0, 1fr) auto;
transition:
background 180ms ease,
border-color 180ms ease;
}
.tool-icon {
width: 38px;
height: 38px;
border-radius: 10px;
background: var(--surface);
color: var(--accent);
}
.tool-copy {
min-width: 0;
}
.tool-copy strong,
.tool-copy span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tool-copy strong {
font-size: 11px;
}
.tool-copy span {
margin-top: 4px;
color: var(--text-muted);
font-size: 9px;
}
.tool-status {
display: inline-flex;
align-items: center;
padding: 5px 8px;
border-radius: 999px;
background: var(--teal-soft);
color: var(--teal);
font-size: 9px;
font-weight: 750;
gap: 5px;
}
.tool-status::before {
width: 5px;
height: 5px;
border-radius: 50%;
background: currentColor;
content: "";
}
.result-lines {
display: grid;
max-width: 620px;
margin-top: 14px;
gap: 7px;
}
.result-lines span {
height: 6px;
border-radius: 999px;
background: var(--surface-muted);
}
.result-lines span:nth-child(2) {
width: 88%;
}
.result-lines span:nth-child(3) {
width: 62%;
}
.composer-area {
padding: 16px clamp(24px, 7vw, 92px) 22px;
background: linear-gradient(
to bottom,
color-mix(in srgb, var(--app-bg) 84%, transparent),
var(--app-bg) 24%
);
}
.composer {
width: min(820px, 100%);
min-height: 86px;
padding: 13px 14px 10px;
border: 1px solid var(--border-strong);
border-radius: 16px;
margin: 0 auto;
background: var(--surface);
box-shadow: var(--shadow-float);
transition:
background 180ms ease,
border-color 180ms ease,
box-shadow 180ms ease;
}
.composer textarea {
width: 100%;
min-height: 34px;
padding: 0;
border: 0;
outline: 0;
background: transparent;
color: var(--text);
font: inherit;
font-size: 12px;
line-height: 1.55;
resize: none;
}
.composer textarea::placeholder {
color: var(--text-muted);
}
.composer-footer {
display: flex;
align-items: center;
gap: 8px;
}
.composer-tool,
.send-button {
display: grid;
width: 30px;
height: 30px;
border-radius: 9px;
cursor: pointer;
place-items: center;
}
.composer-tool {
background: transparent;
color: var(--text-muted);
}
.composer-tool:hover {
background: var(--surface-subtle);
color: var(--accent);
}
.composer-tool svg,
.send-button svg {
width: 15px;
height: 15px;
}
.composer-context {
display: flex;
align-items: center;
min-height: 28px;
padding: 0 9px;
border: 1px solid var(--border);
border-radius: 8px;
margin-left: 2px;
background: var(--surface-subtle);
color: var(--text-secondary);
font-size: 9px;
font-weight: 650;
}
.send-button {
margin-left: auto;
background: var(--accent);
color: white;
}
:root[data-theme="dark"] .send-button {
background: #1476c8;
}
.floating-note {
position: absolute;
right: 24px;
bottom: 24px;
display: none;
min-width: 190px;
padding: 12px;
border: 1px solid var(--accent-border);
border-radius: 14px;
background: var(--surface);
box-shadow: var(--shadow-float);
gap: 10px;
grid-template-columns: 34px minmax(0, 1fr);
pointer-events: none;
}
.floating-note-icon {
display: grid;
width: 34px;
height: 34px;
border-radius: 10px;
background: var(--teal-soft);
color: var(--teal);
place-items: center;
}
.floating-note strong,
.floating-note span {
display: block;
}
.floating-note strong {
font-size: 11px;
}
.floating-note span {
margin-top: 3px;
color: var(--text-muted);
font-size: 9px;
}
@media (max-width: 900px) {
.demo-shell {
grid-template-columns: 78px minmax(0, 1fr);
}
.sidebar {
padding-inline: 11px;
}
.brand {
justify-content: center;
padding-inline: 0;
}
.brand-copy,
.project-button span,
.project-button svg:last-child,
.new-chat span,
.sidebar-search input,
.nav-label,
.nav-item > span:last-child,
.profile-copy {
display: none;
}
.project-button,
.new-chat,
.sidebar-search,
.nav-item,
.profile {
justify-content: center;
padding-inline: 0;
}
.scope-chip {
display: none;
}
}
@media (max-width: 620px) {
body {
padding: 0;
}
.demo-shell {
width: 100%;
height: 100vh;
min-height: 560px;
border: 0;
border-radius: 0;
grid-template-columns: 64px minmax(0, 1fr);
}
.sidebar {
padding-inline: 8px;
}
.title-group span,
.mode-chip,
.theme-toggle__label {
display: none;
}
.topbar {
padding-inline: 13px;
}
.messages {
padding: 22px 16px;
}
.composer-area {
padding: 12px 14px 16px;
}
.assistant-message {
grid-template-columns: 30px minmax(0, 1fr);
}
.assistant-avatar {
width: 30px;
height: 30px;
}
.tool-card {
grid-template-columns: 34px minmax(0, 1fr);
}
.tool-icon {
width: 34px;
height: 34px;
}
.tool-status {
display: none;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
scroll-behavior: auto !important;
transition-duration: 0.01ms !important;
}
}
</style>
</head>
<body>
<div class="demo-shell">
<aside class="sidebar" aria-label="主导航">
<div class="brand">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path d="M8.5 7.5a4.5 4.5 0 1 0 0 9h2.25" />
<path d="M15.5 7.5a4.5 4.5 0 1 1 0 9h-2.25" />
<path d="M9.5 9.5 14.5 14.5" />
</svg>
</span>
<span class="brand-copy">
<strong>GoodBuddy</strong>
<span>AI 工作伙伴</span>
</span>
</div>
<button class="project-button" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M3.5 6.5h7l2 2h8v10h-17z" />
</svg>
<span>GoodBuddy 官网</span>
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="m8 10 4 4 4-4" />
</svg>
</button>
<button class="new-chat" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 5v14M5 12h14" />
</svg>
<span>新建对话</span>
</button>
<label class="sidebar-search">
<svg viewBox="0 0 24 24" aria-hidden="true">
<circle cx="10.5" cy="10.5" r="6.5" />
<path d="m15.5 15.5 4 4" />
</svg>
<input type="search" placeholder="搜索对话" />
</label>
<p class="nav-label">工作区</p>
<nav class="nav">
<button class="nav-item is-active" type="button">
<span class="nav-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 5.5h16v11H9l-5 3z" />
</svg>
</span>
<span>对话</span>
</button>
<button class="nav-item" type="button">
<span class="nav-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M5 4.5h11a3 3 0 0 1 3 3v12H8a3 3 0 0 1-3-3z" />
<path d="M8 4.5v12a3 3 0 0 0 3 3" />
</svg>
</span>
<span>知识库</span>
</button>
<button class="nav-item" type="button">
<span class="nav-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M4 13h3l2-7 4 12 2-6h5" />
</svg>
</span>
<span>智能心跳</span>
</button>
<button class="nav-item" type="button">
<span class="nav-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<rect x="4" y="5" width="16" height="15" rx="2" />
<path d="M8 3v4M16 3v4M8 11h8M8 15h5" />
</svg>
</span>
<span>任务与活动</span>
</button>
<button class="nav-item" type="button">
<span class="nav-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M5 5.5h14M5 12h14M5 18.5h9" />
</svg>
</span>
<span>魔法笔记</span>
</button>
</nav>
<div class="sidebar-footer">
<button class="profile" type="button">
<span class="profile-avatar">GB</span>
<span class="profile-copy">
<strong>本地工作区</strong>
<span>安全模式已开启</span>
</span>
</button>
</div>
</aside>
<main class="workspace">
<header class="topbar">
<div class="title-group">
<strong>产品官网维护</strong>
<span>最后更新于今天 16:24</span>
</div>
<span class="scope-chip">项目:GoodBuddy 官网</span>
<div class="topbar-actions">
<span class="mode-chip">计划模式</span>
<button
aria-label="切换深色主题"
aria-pressed="false"
class="theme-toggle"
id="theme-toggle"
type="button"
>
<span class="theme-toggle__label">浅色</span>
<span class="theme-toggle__track" aria-hidden="true">
<span class="theme-toggle__thumb">
<svg viewBox="0 0 24 24">
<circle cx="12" cy="12" r="3.5" />
<path
d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"
/>
</svg>
</span>
</span>
</button>
</div>
</header>
<section class="chat-canvas">
<div class="messages">
<div class="message-flow">
<div class="user-message">
<div class="user-bubble">
检查官网内容与下载入口是否需要更新。
</div>
</div>
<article class="assistant-message">
<div class="assistant-avatar">
<svg viewBox="0 0 24 24" aria-hidden="true">
<rect x="5" y="7" width="14" height="11" rx="3" />
<path d="M9 11h.01M15 11h.01M9 15h6M12 4v3" />
</svg>
</div>
<div class="assistant-content">
<div class="assistant-meta">
<strong>GoodBuddy</strong>
<span>刚刚</span>
</div>
<p class="assistant-copy">
我会先核对发布清单与项目知识,再给出不执行变更的更新计划。
</p>
<div class="tool-card">
<span class="tool-icon">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M7 5h10M7 9h10M7 13h7M5 3h14v18H5z" />
</svg>
</span>
<span class="tool-copy">
<strong>读取项目知识</strong>
<span>范围:GoodBuddy 官网 · 8 个相关条目</span>
</span>
<span class="tool-status">已完成</span>
</div>
<div class="result-lines" aria-hidden="true">
<span></span>
<span></span>
<span></span>
</div>
</div>
</article>
</div>
</div>
<div class="composer-area">
<div class="composer">
<textarea
aria-label="继续输入"
placeholder="继续补充要求…"
></textarea>
<div class="composer-footer">
<button class="composer-tool" aria-label="添加附件">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="m9 12 5-5a3 3 0 1 1 4 4l-7 7a5 5 0 0 1-7-7l7-7" />
</svg>
</button>
<button class="composer-tool" aria-label="语音输入">
<svg viewBox="0 0 24 24" aria-hidden="true">
<rect x="9" y="3" width="6" height="12" rx="3" />
<path d="M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21" />
</svg>
</button>
<span class="composer-context">Ask · 只读</span>
<button class="send-button" aria-label="发送">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M12 19V5M6 11l6-6 6 6" />
</svg>
</button>
</div>
</div>
</div>
</section>
</main>
</div>
<script>
const root = document.documentElement
const toggle = document.querySelector("#theme-toggle")
const label = toggle.querySelector(".theme-toggle__label")
const icon = toggle.querySelector(".theme-toggle__thumb")
const sunIcon = `
<svg viewBox="0 0 24 24">
<circle cx="12" cy="12" r="3.5"></circle>
<path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"></path>
</svg>`
const moonIcon = `
<svg viewBox="0 0 24 24">
<path d="M20 15.6A8.5 8.5 0 0 1 8.4 4 8.5 8.5 0 1 0 20 15.6Z"></path>
</svg>`
function setTheme(theme) {
const isDark = theme === "dark"
root.dataset.theme = theme
toggle.setAttribute("aria-pressed", String(isDark))
toggle.setAttribute(
"aria-label",
isDark ? "切换浅色主题" : "切换深色主题"
)
label.textContent = isDark ? "深色" : "浅色"
icon.innerHTML = isDark ? moonIcon : sunIcon
}
toggle.addEventListener("click", () => {
setTheme(root.dataset.theme === "dark" ? "light" : "dark")
})
document.querySelectorAll(".nav-item").forEach((item) => {
item.addEventListener("click", () => {
document
.querySelectorAll(".nav-item")
.forEach((navItem) => navItem.classList.remove("is-active"))
item.classList.add("is-active")
})
})
</script>
</body>
</html>