agent-Specialization/static/mobile-overlay-demo.html

342 lines
9.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>移动端多面板示例</title>
<style>
:root {
font-family: 'SF Pro Display', 'PingFang SC', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
color: #2f251b;
--bg: #f4efe7;
--card: #fffdf8;
--accent: #e06a3a;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
background: var(--bg);
display: flex;
flex-direction: column;
}
.chat-area {
flex: 1;
display: flex;
flex-direction: column;
padding: 16px;
gap: 12px;
}
.chat-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.chat-header h1 {
font-size: 20px;
margin: 0;
}
.message {
padding: 12px 14px;
border-radius: 14px;
max-width: 90%;
line-height: 1.5;
}
.message.user {
background: #fff;
margin-left: auto;
border: 1px solid rgba(0, 0, 0, 0.05);
}
.message.bot {
background: var(--card);
border: 1px solid rgba(0, 0, 0, 0.08);
}
.mobile-toolbar {
position: sticky;
bottom: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 6px;
padding: 12px 16px clamp(16px, 4vw, 28px);
background: linear-gradient(180deg, rgba(244, 239, 231, 0.9), rgba(244, 239, 231, 1));
border-top: 1px solid rgba(0, 0, 0, 0.05);
}
.toolbar-btn {
border: none;
border-radius: 999px;
padding: 10px;
background: rgba(47, 37, 27, 0.08);
color: #3a2f23;
font-size: 14px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
transition: background 0.2s ease;
}
.toolbar-btn.active {
background: var(--accent);
color: #fffaf3;
}
.toolbar-btn span {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.sheet {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 50;
transition: visibility 0.2s;
visibility: hidden;
}
.sheet.is-visible {
pointer-events: auto;
visibility: visible;
}
.sheet-backdrop {
position: absolute;
inset: 0;
background: rgba(11, 8, 5, 0.35);
opacity: 0;
transition: opacity 0.25s ease;
}
.sheet.is-visible .sheet-backdrop {
opacity: 1;
}
.sheet-panel {
position: absolute;
top: clamp(12px, 3vh, 24px);
bottom: clamp(12px, 3vh, 24px);
width: min(420px, 88vw);
border-radius: 20px;
background: #fffdf8;
box-shadow: 0 24px 60px rgba(20, 12, 4, 0.35);
display: flex;
flex-direction: column;
transform: translateX(-120%);
transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.sheet[data-side='right'] .sheet-panel {
right: clamp(12px, 3vw, 24px);
transform: translateX(120%);
}
.sheet[data-side='left'] .sheet-panel {
left: clamp(12px, 3vw, 24px);
}
.sheet.is-visible .sheet-panel {
transform: translateX(0);
}
.sheet-header {
padding: 18px 22px;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
display: flex;
justify-content: space-between;
align-items: center;
}
.sheet-title {
font-size: 18px;
font-weight: 600;
}
.close-btn {
border: none;
background: rgba(0, 0, 0, 0.05);
border-radius: 999px;
width: 34px;
height: 34px;
font-size: 18px;
cursor: pointer;
}
.sheet-body {
flex: 1;
overflow-y: auto;
padding: 18px 22px 24px;
display: flex;
flex-direction: column;
gap: 16px;
}
.section-card {
background: rgba(47, 37, 27, 0.04);
border-radius: 16px;
padding: 14px 16px;
border: 1px solid rgba(47, 37, 27, 0.08);
}
.status-card {
background: radial-gradient(circle at 10% 20%, rgba(255, 163, 103, 0.35), rgba(255, 244, 234, 0.7));
border: none;
}
</style>
</head>
<body>
<main class="chat-area">
<header class="chat-header">
<h1>对话区域</h1>
<small>仅占满屏幕,其他面板以弹层呈现</small>
</header>
<div class="message bot">你好!我在移动端也可以干活 🙌</div>
<div class="message user">我想看看其它面板在哪里?</div>
<div class="message bot">点击下方按钮就能半覆盖地拉出侧栏。</div>
</main>
<nav class="mobile-toolbar">
<button class="toolbar-btn" data-open="conversation-sheet">
<span>对话记录</span>
</button>
<button class="toolbar-btn" data-open="workspace-sheet">
🧰
<span>工作台</span>
</button>
<button class="toolbar-btn" data-open="focus-sheet">
👁️
<span>聚焦文件</span>
</button>
</nav>
<section class="sheet" data-side="left" id="conversation-sheet">
<div class="sheet-backdrop" data-close></div>
<div class="sheet-panel">
<div class="sheet-header">
<div class="sheet-title">对话记录</div>
<button class="close-btn" data-close>×</button>
</div>
<div class="sheet-body">
<div class="section-card status-card">
<strong>快速操作</strong>
<p>新建对话 · 搜索 · 会话列表</p>
</div>
<div class="section-card">
<p>#1234 需求讨论 · 刚刚</p>
</div>
<div class="section-card">
<p>#1227 UI 迭代 · 1 小时前</p>
</div>
</div>
</div>
</section>
<section class="sheet" data-side="left" id="workspace-sheet">
<div class="sheet-backdrop" data-close></div>
<div class="sheet-panel">
<div class="sheet-header">
<div class="sheet-title">三合一工作台</div>
<button class="close-btn" data-close>×</button>
</div>
<div class="sheet-body">
<div class="section-card status-card">
<strong>AI Agent v2.4</strong>
<p>已连接 · 思考模式</p>
</div>
<div class="section-card">
<h4>项目文件</h4>
<p>/src/App.vue</p>
<p>/stores/ui.ts</p>
</div>
<div class="section-card">
<h4>待办列表</h4>
<p>1. 完成移动端布局</p>
<p>2. 录制演示</p>
</div>
<div class="section-card">
<h4>子智能体</h4>
<p>#05 构建状态 · 运行中</p>
</div>
</div>
</div>
</section>
<section class="sheet" data-side="right" id="focus-sheet">
<div class="sheet-backdrop" data-close></div>
<div class="sheet-panel">
<div class="sheet-header">
<div class="sheet-title">聚焦面板</div>
<button class="close-btn" data-close>×</button>
</div>
<div class="sheet-body">
<div class="section-card">
<h4>App.vue</h4>
<p>...main-container / panel 切换逻辑...</p>
</div>
<div class="section-card">
<h4>ui.ts</h4>
<p>...isMobileViewport · activeMobileSheet...</p>
</div>
<div class="section-card">
<h4>styles/_responsive.scss</h4>
<p>...overlay 动画与遮罩...</p>
</div>
</div>
</div>
</section>
<script>
const buttons = document.querySelectorAll('[data-open]');
const sheets = document.querySelectorAll('.sheet');
const toolbarButtons = document.querySelectorAll('.toolbar-btn');
const closeAllSheets = () => {
sheets.forEach(sheet => sheet.classList.remove('is-visible'));
toolbarButtons.forEach(btn => btn.classList.remove('active'));
};
buttons.forEach(btn => {
btn.addEventListener('click', () => {
const targetId = btn.getAttribute('data-open');
const targetSheet = document.getElementById(targetId);
if (!targetSheet) return;
const isAlreadyOpen = targetSheet.classList.contains('is-visible');
closeAllSheets();
if (!isAlreadyOpen) {
targetSheet.classList.add('is-visible');
btn.classList.add('active');
}
});
});
document.querySelectorAll('[data-close]').forEach(el => {
el.addEventListener('click', () => {
const sheet = el.closest('.sheet');
if (!sheet) return;
sheet.classList.remove('is-visible');
toolbarButtons.forEach(btn => {
if (btn.getAttribute('data-open') === sheet.id) {
btn.classList.remove('active');
}
});
});
});
</script>
</body>
</html>