样式修噶

This commit is contained in:
董宏凯 committed 2026-05-22 14:56:59 +08:00
1 parent e076abe759
commit 19660e49d2
18 files changed
+2791 -453

No files matched your search

-9
View File
@@ -1,9 +0,0 @@
# GEMINI_API_KEY: Required for Gemini AI API calls.
# AI Studio automatically injects this at runtime from user secrets.
# Users configure this via the Secrets panel in the AI Studio UI.
GEMINI_API_KEY="MY_GEMINI_API_KEY"
# APP_URL: The URL where this applet is hosted.
# AI Studio automatically injects this at runtime with the Cloud Run service URL.
# Used for self-referential links, OAuth callbacks, and API endpoints.
APP_URL="MY_APP_URL"
-20
View File
@@ -1,20 +0,0 @@
<div align="center">
<img width="1200" height="475" alt="GHBanner" src="https://ai.google.dev/static/site-assets/images/share-ais-513315318.png" />
</div>
# Run and deploy your AI Studio app
This contains everything you need to run your app locally.
View your app in AI Studio: https://ai.studio/apps/75261c35-a558-4ef8-9501-e8b7f9c98bfb
## Run Locally
**Prerequisites:** Node.js
1. Install dependencies:
`npm install`
2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key
3. Run the app:
`npm run dev`
-13
View File
@@ -1,13 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Google AI Studio App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
-6
View File
@@ -1,6 +0,0 @@
{
"name": "Gemini Style Assistant",
"description": "A clean, modern AI assistant interface inspired by Google Gemini with centered search, suggestion pills, and a minimalist sidebar.",
"requestFramePermissions": [],
"majorCapabilities": ["MAJOR_CAPABILITY_SERVER_SIDE_GEMINI_API"]
}
-35
View File
@@ -1,35 +0,0 @@
{
"name": "react-example",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --port=3000 --host=0.0.0.0",
"build": "vite build",
"preview": "vite preview",
"clean": "rm -rf dist server.js",
"lint": "tsc --noEmit"
},
"dependencies": {
"@google/genai": "^1.29.0",
"@tailwindcss/vite": "^4.1.14",
"@vitejs/plugin-react": "^5.0.4",
"lucide-react": "^0.546.0",
"react": "^19.0.1",
"react-dom": "^19.0.1",
"vite": "^6.2.3",
"express": "^4.21.2",
"dotenv": "^17.2.3",
"motion": "^12.23.24"
},
"devDependencies": {
"@types/node": "^22.14.0",
"autoprefixer": "^10.4.21",
"esbuild": "^0.25.0",
"tailwindcss": "^4.1.14",
"tsx": "^4.21.0",
"typescript": "~5.8.2",
"vite": "^6.2.3",
"@types/express": "^4.17.21"
}
}
-238
View File
@@ -1,238 +0,0 @@
/**
* @license
* SPDX-License-Identifier: Apache-2.0
*/
import { useState } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import {
MessageSquare,
Bot,
Wrench,
Brain,
ListChecks,
Settings,
Menu,
Mic,
Plus,
Sparkles,
ArrowRight,
User,
History,
LayoutGrid,
Languages,
Code2,
Music,
Database,
Search
} from 'lucide-react';
export default function App() {
const [sidebarOpen, setSidebarOpen] = useState(true);
const navItems = [
{ icon: MessageSquare, label: '对话', active: true },
{ icon: Bot, label: '智能体' },
{ icon: Wrench, label: '技能' },
{ icon: Brain, label: '记忆' },
{ icon: ListChecks, label: '任务管理' },
];
const recentChats = [
'CM助手初次问候交谈',
'Untitled',
'Untitled',
'Untitled',
'帮我写一个500字的文案',
'帮我生成一个写论文的实例',
];
const suggestions = [
{ icon: Code2, label: 'Build an Android app', color: 'text-green-600', bg: 'bg-green-50' },
{ icon: Languages, label: 'Convert text to speech', color: 'text-blue-600', bg: 'bg-blue-50' },
{ icon: Music, label: 'Generate music', color: 'text-purple-600', bg: 'bg-purple-50' },
{ icon: Database, label: 'Add database and auth', color: 'text-cyan-600', bg: 'bg-cyan-50' },
];
return (
<div className="flex h-screen w-full bg-white font-sans text-gray-900 overflow-hidden">
{/* Sidebar */}
<motion.aside
initial={false}
animate={{ width: sidebarOpen ? 280 : 0, opacity: sidebarOpen ? 1 : 0 }}
className="relative bg-gray-50 border-r border-gray-100 flex flex-col h-full"
>
<div className="p-4 flex items-center justify-between">
<div className="flex items-center gap-2 px-2 py-1.5 bg-red-50 text-red-700 rounded-lg cursor-pointer">
<Plus size={18} />
<span className="font-medium text-sm">新对话</span>
</div>
</div>
<nav className="flex-1 overflow-y-auto px-2 space-y-1">
<div className="space-y-1 pb-4">
{navItems.map((item) => (
<div
key={item.label}
className={`flex items-center gap-3 px-3 py-2 rounded-xl cursor-pointer transition-colors ${
item.active ? 'bg-white shadow-sm font-medium' : 'hover:bg-gray-100 text-gray-600'
}`}
>
<item.icon size={18} />
<span className="text-sm">{item.label}</span>
</div>
))}
</div>
<div className="pt-4 border-t border-gray-200">
<h3 className="px-3 mb-2 text-xs font-semibold text-gray-400 uppercase tracking-wider">
最近对话
</h3>
{recentChats.map((chat, idx) => (
<div
key={idx}
className="px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100 rounded-lg cursor-pointer truncate"
>
{chat}
</div>
))}
</div>
</nav>
<div className="p-4 border-t border-gray-200">
<div className="flex items-center gap-3 px-3 py-2 text-gray-600 hover:bg-gray-100 rounded-xl cursor-pointer">
<Settings size={18} />
<span className="text-sm">设置和更多</span>
</div>
</div>
</motion.aside>
{/* Main Content */}
<main className="flex-1 flex flex-col relative h-full overflow-y-auto">
{/* Top bar */}
<header className="absolute top-0 w-full p-4 flex items-center justify-between z-10">
<button
onClick={() => setSidebarOpen(!sidebarOpen)}
className="p-2 hover:bg-gray-100 rounded-lg text-gray-500 transition-colors"
>
<Menu size={20} />
</button>
<div className="flex items-center gap-2">
<button className="p-2 hover:bg-gray-100 rounded-lg text-gray-500 transition-colors">
<Settings size={20} />
</button>
<div className="w-8 h-8 rounded-full bg-gradient-to-tr from-blue-400 to-purple-400 flex items-center justify-center text-white shadow-sm ring-2 ring-white cursor-pointer overflow-hidden">
<User size={16} />
</div>
</div>
</header>
{/* Center Canvas */}
<div className="flex-1 flex flex-col items-center justify-center px-4 max-w-4xl mx-auto w-full pt-16">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="text-center mb-12 relative"
>
<div className="absolute -top-16 left-1/2 -translate-x-1/2 opacity-10 blur-2xl pointer-events-none">
<Sparkles size={120} className="text-blue-500 animate-pulse" />
</div>
<h1 className="text-5xl font-display font-medium tracking-tight bg-clip-text text-transparent bg-gradient-to-r from-gray-900 to-gray-500 mb-4 px-4">
Build your ideas with Gemini
</h1>
<Sparkles className="absolute -right-8 top-0 text-blue-200 opacity-50" size={48} />
</motion.div>
{/* Search/Input Area */}
<motion.div
initial={{ opacity: 0, scale: 0.95 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.1 }}
className="w-full max-w-2xl relative group"
>
<div className="gemini-gradient-border gemini-shadow rounded-3xl bg-white p-2">
<div className="flex flex-col p-4 space-y-4">
<textarea
placeholder="Describe an app and let Gemini do the rest"
className="w-full bg-transparent resize-none focus:outline-none text-lg text-gray-700 min-h-[80px]"
/>
<div className="flex items-center justify-between pt-2">
<div className="flex items-center gap-2">
<button className="p-2 hover:bg-gray-100 rounded-full text-gray-400 transition-colors">
<Mic size={20} />
</button>
<button className="p-2 hover:bg-gray-100 rounded-full text-gray-400 transition-colors">
<Plus size={20} />
</button>
</div>
<button className="flex items-center gap-2 px-5 py-2.5 bg-gray-50 hover:bg-gray-100 text-gray-700 rounded-full border border-gray-200 transition-all font-medium text-sm group/btn shadow-sm">
<Sparkles size={16} className="text-blue-500" />
I'm feeling lucky
<ArrowRight size={14} className="opacity-0 -translate-x-2 group-hover/btn:opacity-100 group-hover/btn:translate-x-0 transition-all" />
</button>
</div>
</div>
</div>
</motion.div>
{/* Suggestion Chips */}
<div className="mt-8 flex flex-wrap justify-center gap-3">
{suggestions.map((suggestion, idx) => (
<motion.button
key={suggestion.label}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2 + idx * 0.05 }}
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
className={`flex items-center gap-2 px-4 py-2.5 rounded-2xl border border-gray-100 bg-white hover:bg-gray-50 shadow-sm transition-all text-sm font-medium group hover:border-gray-200 text-gray-700`}
>
<suggestion.icon className={`w-4 h-4 ${suggestion.color}`} />
{suggestion.label}
</motion.button>
))}
<motion.button
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.4 }}
className="flex items-center justify-center p-2 rounded-full border border-gray-100 bg-white hover:bg-gray-50 text-gray-400 shadow-sm transition-all"
>
<ArrowRight size={16} />
</motion.button>
</div>
</div>
{/* Footer info/links */}
<footer className="w-full max-w-4xl mx-auto px-4 py-12 mt-auto">
<div className="rounded-3xl border border-gray-100 bg-gray-50/50 p-8 flex items-center justify-between group hover:bg-gray-50 transition-colors">
<div>
<h2 className="text-2xl font-display font-medium text-gray-800 mb-1">
Discover and remix app ideas
</h2>
<p className="text-gray-500 text-sm italic">
(Gallery view pending implementation)
</p>
</div>
<button className="flex items-center gap-2 px-6 py-2.5 bg-white border border-gray-200 rounded-xl hover:shadow-md transition-all font-medium text-gray-700">
Browse the app gallery
<ArrowRight size={18} />
</button>
</div>
</footer>
{/* Floating Right Bar (from target image) */}
<div className="absolute right-6 top-1/2 -translate-y-1/2 flex flex-col gap-4">
<button className="p-2.5 bg-white shadow-lg border border-gray-100 rounded-xl hover:scale-110 transition-all text-gray-400">
<LayoutGrid size={22} />
</button>
<button className="p-2.5 bg-white shadow-lg border border-gray-100 rounded-xl hover:scale-110 transition-all text-gray-400">
<Languages size={22} />
</button>
</div>
</main>
</div>
);
}
-71
View File
@@ -1,71 +0,0 @@
@import "tailwindcss";
@theme {
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
--font-display: "Outfit", "Inter", sans-serif;
}
@layer base {
body {
@apply bg-white text-gray-900 antialiased;
}
}
@layer utilities {
.gemini-shadow {
box-shadow: 0 0 20px rgba(66, 133, 244, 0.08),
0 0 40px rgba(219, 68, 55, 0.04),
0 0 60px rgba(244, 180, 0, 0.04),
0 0 80px rgba(15, 157, 88, 0.04);
}
.gemini-gradient-border {
position: relative;
background: white;
border-radius: 1.5rem; /* rounded-3xl */
z-index: 0;
overflow: hidden;
}
.gemini-gradient-border::before {
content: '';
position: absolute;
width: 150%;
height: 150%;
top: -25%;
left: -25%;
background: conic-gradient(
from 0deg,
transparent 0deg,
transparent 90deg,
#4285F4 120deg,
#DB4437 150deg,
#F4B400 180deg,
#0F9D58 210deg,
transparent 240deg
);
z-index: -2;
animation: rotate 3s linear infinite;
filter: blur(15px);
}
.gemini-gradient-border::after {
content: '';
position: absolute;
inset: 1.5px; /* The "thickness" of the glow border */
background: white;
border-radius: calc(1.5rem - 1px);
z-index: -1;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
}
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Outfit:wght@400;500;600&display=swap');
-10
View File
@@ -1,10 +0,0 @@
import {StrictMode} from 'react';
import {createRoot} from 'react-dom/client';
import App from './App.tsx';
import './index.css';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
);
-26
View File
@@ -1,26 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"experimentalDecorators": true,
"useDefineForClassFields": false,
"module": "ESNext",
"lib": [
"ES2022",
"DOM",
"DOM.Iterable"
],
"skipLibCheck": true,
"moduleResolution": "bundler",
"isolatedModules": true,
"moduleDetection": "force",
"allowJs": true,
"jsx": "react-jsx",
"paths": {
"@/*": [
"./*"
]
},
"allowImportingTsExtensions": true,
"noEmit": true
}
}
-22
View File
@@ -1,22 +0,0 @@
import tailwindcss from '@tailwindcss/vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import {defineConfig} from 'vite';
export default defineConfig(() => {
return {
plugins: [react(), tailwindcss()],
resolve: {
alias: {
'@': path.resolve(__dirname, '.'),
},
},
server: {
// HMR is disabled in AI Studio via DISABLE_HMR env var.
// Do not modify—file watching is disabled to prevent flickering during agent edits.
hmr: process.env.DISABLE_HMR !== 'true',
// Disable file watching when DISABLE_HMR is true to save CPU during agent edits.
watch: process.env.DISABLE_HMR === 'true' ? null : {},
},
};
});
@@ -72,6 +72,12 @@ const menuItems: MenuItem[] = [
icon: HelpCircle,
children: [
{ id: "general-qa", label: "通用问答", icon: CircleHelp, path: "/page/workspace/chats/new" },
{
id: "qa-roundtable",
label: "圆桌规划",
icon: Bot,
path: "/page/roundtable/planning",
},
{ id: "qa-zzjc", label: "zzjc支持", icon: Bot },
{ id: "qa-zzxd", label: "zzXD应用", icon: Layout },
{ id: "qa-research", label: "课题研究", icon: FileText, path: "/page/canvas/ai-writing" },
+5 -3
View File
@@ -1,4 +1,5 @@
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { useTheme as useNextTheme } from 'next-themes';
// 主题类型
export type ThemeType = 'dark' | 'light';
@@ -91,6 +92,7 @@ interface ThemeProviderProps {
}
export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
const { setTheme: setNextTheme } = useNextTheme();
const [theme, setThemeState] = useState<ThemeType>(() => {
// 从 localStorage 读取保存的主题
const saved = localStorage.getItem('strategy-theme');
@@ -107,13 +109,13 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
setThemeState(newTheme);
};
// 保存到 localStorage
// 保存到 localStorage,并同步 html class 与 next-themes
useEffect(() => {
localStorage.setItem('strategy-theme', theme);
// 更新文档类名
document.documentElement.classList.remove('dark', 'light');
document.documentElement.classList.add(theme);
}, [theme]);
setNextTheme(theme);
}, [theme, setNextTheme]);
const themeConfig = themes[theme];
+2
View File
@@ -8,6 +8,7 @@ import WorkspaceRoutes from "./WorkspaceRoutes";
import StrategyRoutes from "./StrategyRoutes";
import Header from "@/strategy-components/Header";
import OpenCanvasRoutes from "@/open-canvas/routes/OpenCanvasRoutes";
import RoundtableRoutes from "./RoundtableRoutes";
function PageLayout() {
const [collapsed, setCollapsed] = useState(false);
@@ -43,6 +44,7 @@ function PageLayout() {
/>
<Route path="strategy/*" element={<StrategyRoutes />} />
<Route path="canvas/*" element={<OpenCanvasRoutes />} />
<Route path="roundtable/*" element={<RoundtableRoutes />} />
</Routes>
</main>
</div>
@@ -0,0 +1,16 @@
import { Navigate, Route, Routes } from "react-router-dom";
import RoundtablePlanningPage from "@/roundtable-planning/pages/RoundtablePlanningPage";
import "@/roundtable-planning/styles/roundtable-planning.css";
export default function RoundtableRoutes() {
return (
<div className="h-full w-full overflow-hidden">
<Routes>
<Route index element={<Navigate to="planning" replace />} />
<Route path="planning" element={<RoundtablePlanningPage />} />
<Route path="*" element={<Navigate to="planning" replace />} />
</Routes>
</div>
);
}
@@ -0,0 +1,498 @@
import React from "react";
import {
ShieldCheck,
Layers,
Clipboard,
Star,
CheckCircle,
Download,
Share2,
Sparkles
} from "lucide-react";
interface HighFidelityReportProps {
budgetLimit: number;
consensusPercentage: number;
setCurrentStep: (step: number) => void;
setStep1MessageHistory: (history: any) => void;
setStep2RoundtableDialogues: (dialogues: any) => void;
triggerToast: (msg: string) => void;
}
export const HighFidelityReport: React.FC<HighFidelityReportProps> = ({
budgetLimit,
consensusPercentage,
setCurrentStep,
setStep1MessageHistory,
setStep2RoundtableDialogues,
triggerToast
}) => {
return (
<div className="flex-1 flex flex-col min-h-0 overflow-y-auto text-slate-800">
{/* Output title block */}
<div className="shrink-0 px-6 py-4.5 border-b border-slate-100 flex items-center justify-between bg-gradient-to-r from-slate-50 to-white flex-wrap gap-3">
<div className="flex flex-wrap items-center gap-2.5">
<div className="flex items-center gap-2">
<CheckCircle className="w-5 h-5 text-emerald-500" />
<h3 className="text-sm font-black text-slate-900 tracking-tight">
最终架构规划方案 (成果展示大屏)
</h3>
</div>
<div className="flex items-center gap-1.5 shrink-0">
<span className="text-[10px] font-black text-emerald-700 bg-emerald-50 border border-emerald-200 px-2 py-0.5 rounded-full shadow-sm">
● 已达成共识
</span>
<span className="text-[10px] font-mono text-slate-400 font-semibold bg-slate-100/80 px-2 py-0.5 rounded-lg">
生成时间:2026-05-21 11:01:12
</span>
</div>
</div>
<div className="flex items-center gap-2">
<button
id="report-download-pdf-btn"
onClick={() => triggerToast("📥 架构方案白皮书 PDF 已开始准备传输...")}
className="bg-white border border-slate-200 text-slate-700 hover:bg-slate-50 text-[10.5px] font-bold px-3 py-1.5 rounded-xl flex items-center gap-1 transition cursor-pointer"
>
<Download className="w-3.5 h-3.5 text-slate-500" />
导出方案 PDF
</button>
<button
id="report-share-btn"
onClick={() => triggerToast("🔗 方案安全访问及沙盒校验链接已复制到剪贴板!")}
className="bg-white border border-slate-200 text-slate-700 hover:bg-slate-50 text-[10.5px] font-bold px-3 py-1.5 rounded-xl flex items-center gap-1 transition cursor-pointer"
>
<Share2 className="w-3.5 h-3.5 text-slate-500" />
安全分享
</button>
</div>
</div>
{/* Comprehensive high fidelity report details */}
<div className="p-6 space-y-6">
{/* Dashboard Metric Overview Rows */}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
{/* Metric 1 */}
<div className="bg-gradient-to-br from-white to-slate-50/20 border border-slate-150 rounded-2xl p-4 shadow-[0_2px_8px_rgba(0,0,0,0.015)] text-xs text-slate-500 font-medium hover:scale-[1.01] transition-all">
<span className="text-[10px] font-extrabold uppercase tracking-wider text-slate-400 block mb-1">设计全要素通过率</span>
<div className="flex items-baseline gap-1 mt-1">
<span className="text-2xl font-black text-slate-900 font-mono">
{budgetLimit >= 500 ? "99.4%" : budgetLimit > 400 ? "98.2%" : "96.5%"}
</span>
<span className="text-[9px] font-black text-emerald-600 bg-emerald-50 px-1.5 py-0.2 rounded-full">合规通过</span>
</div>
<p className="text-[9.5px] text-slate-400 mt-2 leading-tight">安全拦截红线保障 0 出圈、0 超限</p>
</div>
{/* Metric 2 */}
<div className="bg-gradient-to-br from-white to-slate-50/20 border border-slate-150 rounded-2xl p-4 shadow-[0_2px_8px_rgba(0,0,0,0.015)] text-xs text-slate-500 font-medium hover:scale-[1.01] transition-all">
<span className="text-[10px] font-extrabold uppercase tracking-wider text-primary block mb-1">安全冗余评估能级</span>
<div className="flex items-baseline gap-1 mt-1">
<span className="text-2xl font-black text-primary font-mono">
{budgetLimit >= 540 ? "Tier III+" : budgetLimit > 410 ? "Tier II" : "Tier I"}
</span>
<span className="text-[9px] font-black text-[var(--brand-900)] bg-[var(--brand-200)] px-1.5 py-0.2 rounded-full">异地容灾</span>
</div>
<p className="text-[9.5px] text-slate-400 mt-2 leading-tight">多路容错算力热备与热切换防线</p>
</div>
{/* Metric 3 */}
<div className="bg-gradient-to-br from-white to-slate-50/20 border border-slate-150 rounded-2xl p-4 shadow-[0_2px_8px_rgba(0,0,0,0.015)] text-xs text-slate-500 font-medium hover:scale-[1.01] transition-all">
<span className="text-[10px] font-extrabold uppercase tracking-wider text-slate-400 block mb-1">研讨总核销资金预算</span>
<div className="flex items-baseline gap-1 mt-1">
<span className="text-2xl font-black text-slate-800 font-mono">
{Math.round(budgetLimit * 0.925 * 10) / 10}万
</span>
<span className="text-[9px] font-black text-emerald-600 bg-emerald-50 px-1.5 py-0.2 rounded-full font-sans">
省 {Math.round(budgetLimit * 0.075 * 10) / 10}w
</span>
</div>
<p className="text-[9.5px] text-slate-400 mt-2 leading-tight">包含逻辑容器、极端微物理灾灾备购置</p>
</div>
{/* Metric 4 */}
<div className="bg-gradient-to-br from-white to-slate-50/20 border border-slate-150 rounded-2xl p-4 shadow-[0_2px_8px_rgba(0,0,0,0.015)] text-xs text-slate-500 font-medium hover:scale-[1.01] transition-all">
<span className="text-[10px] font-extrabold uppercase tracking-wider text-slate-400 block mb-1">终审共识度评分</span>
<div className="flex items-baseline gap-1 mt-1">
<span className="text-2xl font-black text-slate-900 font-mono">42 轮研商</span>
<span className="text-[9px] font-black text-amber-600 bg-amber-50 px-1.5 py-0.2 rounded-full">
共识率 {consensusPercentage}%
</span>
</div>
<p className="text-[9.5px] text-slate-400 mt-2 leading-tight">多智能体委员会滚动合议完美收敛</p>
</div>
</div>
{/* Section I: 执行摘要 (Executive Summary) */}
<div className="bg-gradient-to-br from-[var(--brand-200)]/30 to-[var(--brand-200)]/10 border border-red-100 rounded-2xl p-5 hover:shadow-md transition">
<div className="flex items-center gap-2 mb-3">
<ShieldCheck className="w-4.5 h-4.5 text-[var(--brand-900)]" />
<h4 className="text-xs font-black text-slate-900 uppercase tracking-widest">
执行摘要 / Executive Summary
</h4>
</div>
<div className="text-xs text-slate-755 leading-relaxed space-y-2 font-medium">
<p className="flex items-start gap-1.5">
<span className="text-primary text-md leading-none">•</span>
<span>本路线规划方案在总核销支出预算限制 ≤ <b className="text-slate-900 font-bold">{budgetLimit}万(主备案并轨共耗约 {Math.round(budgetLimit * 0.925 * 10) / 10}万元)</b>、核心编制队伍限制 ≤ <b className="text-slate-900 font-bold">30人</b>、绝对周转上线规定 <b className="text-slate-900 font-bold">72小时</b> 内交付的目标约束下制定。最终裁决收敛并采纳包含【信息补全】、【主干推进】与【风险收敛】三阶段非对称推进的稳健路径。</span>
</p>
<p className="flex items-start gap-1.5">
<span className="text-primary text-md leading-none">•</span>
<span>经多角色 AI 官群及人类指挥官深度澄清和在沙盒拓扑中演算测试,采用本规划方案,在安全拦截(合规绿码)、运行负载及高灾备级余度三大维度上均符合最苛刻的可落地标准。</span>
</p>
<p className="flex items-start gap-1.5">
<span className="text-primary text-md leading-none">•</span>
<span>项目具有明确的关键里程碑控制链、主备熔断备份计划,可执行确凿性最优,推荐自批复时点起立即启动第一阶段工作。</span>
</p>
</div>
</div>
{/* Section II: 方案详细大纲 (Detailed Core Outline) */}
<div className="bg-white border border-slate-150 rounded-2xl p-5 hover:shadow-md transition space-y-6">
<div className="flex items-center gap-2 border-b border-slate-100 pb-3 mb-1">
<Layers className="w-4.5 h-4.5 text-primary" strokeWidth={2.5} />
<h4 className="text-xs font-black text-slate-900 uppercase tracking-widest">
一、最终规划方案内容大纲
</h4>
</div>
<div className="space-y-6 text-xs text-slate-750 font-medium leading-relaxed">
{/* Item 1 */}
<div className="space-y-1.5">
<h5 className="font-extrabold text-slate-900 flex items-center gap-1.5 text-[12px]">
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-[var(--brand-200)] text-primary font-bold font-mono text-[10.5px]">1</span>
任务背景与目标 / Target Scope
</h5>
<p className="pl-6.5 text-slate-500 leading-normal">
围绕给定预算上限(限额:{budgetLimit}万)与资源约束(人数:≤30人,时限:72小时),建立一套主备、高容错、防崩溃的多模态适应性部署方案。通过多智能体委员会多轮博弈对抗演炼,彻底击碎不确定性风险,平滑过渡并投产运行。
</p>
</div>
{/* Item 2 */}
<div className="space-y-1.5">
<h5 className="font-extrabold text-slate-900 flex items-center gap-1.5 text-[12px]">
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-[var(--brand-200)] text-[var(--brand-900)] font-bold font-mono text-[10.5px]">2</span>
约束条件与关键假设 / Ground Hypotheses
</h5>
<div className="pl-6.5 grid grid-cols-1 md:grid-cols-2 gap-3 mt-1.5 text-slate-500">
<div className="p-3 bg-slate-50 border border-slate-150 rounded-xl space-y-1">
<span className="font-black text-slate-800 text-[10.5px] block">📌 指向性硬约束:</span>
<ul className="list-disc pl-4 space-y-1 text-[10px]">
<li>预算开销指示极限: <b className="text-slate-850">≤ {budgetLimit}万</b></li>
<li>人力池最大可用总额: <b className="text-slate-850">≤ 30人</b></li>
<li>全投产周转交付极限: <b className="text-slate-850">≤ 72小时</b></li>
</ul>
</div>
<div className="p-3 bg-slate-50 border border-slate-150 rounded-xl space-y-1">
<span className="font-black text-slate-800 text-[10.5px] block">🔮 关键假设依据:</span>
<ul className="list-disc pl-4 space-y-1 text-[10px]">
<li>阶段一能够在24h内快捷、高配合度、无阻碍补全关键参数</li>
<li>灾灾备系统对逻辑双微高可用(云原生 K3s)具有高度适配性</li>
<li>极端环境历史数据具有一定参照性,各微服务配合维持稳定</li>
</ul>
</div>
</div>
</div>
{/* Item 3 (Interactive roadmap timeline pipeline mockup) */}
<div className="space-y-3">
<h5 className="font-extrabold text-slate-900 flex items-center gap-1.5 text-[12px]">
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-purple-50 text-purple-600 font-bold font-mono text-[10.5px]">3</span>
三阶段推进方案路线图 / Three-Phase Integration Roadmap
</h5>
<p className="pl-6.5 text-slate-500 pb-1">
项目设计采用分段非对称递进开发,首尾相扣,利用熔断和回滚阀门最大化减少交付风险:
</p>
<div className="pl-6.5 grid grid-cols-1 md:grid-cols-3 gap-4">
{/* Phase 1 card */}
<div className="bg-slate-50 border border-slate-150 rounded-2xl p-4 flex flex-col justify-between hover:border-red-200 transition relative">
<div className="absolute top-2.5 right-3 px-2 py-0.5 rounded-full bg-[var(--brand-200)] text-primary border border-red-100 font-mono font-bold text-[9px]">
0 - 24h
</div>
<div>
<span className="font-black text-[11.5px] tracking-tight block mb-2 text-primary">
阶段一:系统信息补全
</span>
<ul className="text-[10px] text-slate-500 space-y-1.5 leading-snug">
<li className="flex items-start gap-1">
<span className="text-primary">•</span>
<span>补缺所有缺失现状对齐指标</span>
</li>
<li className="flex items-start gap-1">
<span className="text-primary">•</span>
<span>拉网厘清核心需求物理缺失</span>
</li>
<li className="flex items-start gap-1">
<span className="text-primary">•</span>
<span>与一线用户对齐约束边界</span>
</li>
</ul>
</div>
<div className="border-t border-slate-150 pt-3 mt-4 flex items-center justify-between text-[9px]">
<span className="text-slate-400 font-bold">交付物件:</span>
<span className="text-slate-700 bg-slate-200/50 px-1.5 py-0.5 rounded font-bold font-sans">《范围基准对齐白皮书》</span>
</div>
</div>
{/* Phase 2 card */}
<div className="bg-slate-50 border border-slate-150 rounded-2xl p-4 flex flex-col justify-between hover:border-purple-200 transition relative">
<div className="absolute top-2.5 right-3 px-2 py-0.5 rounded-full bg-purple-50 text-purple-600 border border-purple-100 font-mono font-bold text-[9px]">
24 - 60h
</div>
<div>
<span className="font-black text-[11.5px] tracking-tight block mb-2 text-purple-650">
阶段二:主任务核心递进
</span>
<ul className="text-[10px] text-slate-500 space-y-1.5 leading-snug">
<li className="flex items-start gap-1">
<span className="text-purple-500">•</span>
<span>5个核心子模块并行极速构建</span>
</li>
<li className="flex items-start gap-1">
<span className="text-purple-500">•</span>
<span>多智能体拓扑动态推演和收敛</span>
</li>
<li className="flex items-start gap-1">
<span className="text-purple-500">•</span>
<span>自习惯里程碑路径重排与分配</span>
</li>
</ul>
</div>
<div className="border-t border-slate-150 pt-3 mt-4 flex items-center justify-between text-[9px]">
<span className="text-slate-400 font-bold">交付物件:</span>
<span className="text-slate-700 bg-slate-200/50 px-1.5 py-0.5 rounded font-bold font-sans">《容器级物理架构拓扑》</span>
</div>
</div>
{/* Phase 3 card */}
<div className="bg-slate-50 border border-slate-150 rounded-2xl p-4 flex flex-col justify-between hover:border-emerald-200 transition relative">
<div className="absolute top-2.5 right-3 px-2 py-0.5 rounded-full bg-emerald-50 text-emerald-600 border border-emerald-100 font-mono font-bold text-[9px]">
60 - 72h
</div>
<div>
<span className="font-black text-[11.5px] tracking-tight block mb-2 text-emerald-650">
阶段三:极端风险安全收敛
</span>
<ul className="text-[10px] text-slate-500 space-y-1.5 leading-snug">
<li className="flex items-start gap-1">
<span className="text-emerald-500">•</span>
<span>一键拉闸灾灾备崩溃性沙盒论证</span>
</li>
<li className="flex items-start gap-1">
<span className="text-emerald-500">•</span>
<span>安全审核拦截与物理封签加签</span>
</li>
<li className="flex items-start gap-1">
<span className="text-emerald-500">•</span>
<span>打包大案报告完美交付投产运行</span>
</li>
</ul>
</div>
<div className="border-t border-slate-150 pt-3 mt-4 flex items-center justify-between text-[9px]">
<span className="text-slate-400 font-bold">交付物件:</span>
<span className="text-slate-700 bg-slate-200/50 px-1.5 py-0.5 rounded font-bold font-sans">《投产交付大白皮书》</span>
</div>
</div>
</div>
</div>
{/* Item 4 */}
<div className="space-y-1.5">
<h5 className="font-extrabold text-slate-900 flex items-center gap-1.5 text-[12px]">
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-amber-50 text-amber-600 font-bold font-mono text-[10.5px]">4</span>
资源配置计划 / Budget & Resource Allocation
</h5>
<div className="pl-6.5 text-slate-500 space-y-2 leading-relaxed">
<p>
主备案并轨总体支出已精精控制在限额内(耗资约 <b className="text-slate-900 font-black">{Math.round(budgetLimit * 0.925 * 10) / 10}万元</b>,含容器、中继微灾备硬件耗销:42%,情报库与政策规则授权:23%,防崩溃校验与极端测试:17%,极客安全风控硬预留:10.5%,剩余资金安全冗余)。
</p>
<div className="flex flex-wrap gap-2 pt-1 font-bold text-[10px]">
<span className="bg-slate-100 px-2.5 py-1 rounded-lg border border-slate-150 text-slate-700">
总限额极限: <b>{budgetLimit}万元</b>
</span>
<span className="bg-[var(--brand-200)] text-[var(--brand-900)] px-2.5 py-1 rounded-lg border border-red-200">
军官与执行队伍编制: <b>28人(合规限度)</b>
</span>
<button
onClick={() => triggerToast("📅 正在基于实时72小时主过程进行甘特图渲染...")}
className="text-primary hover:underline flex items-center gap-1 cursor-pointer font-black"
>
[在线查看项目开发实施甘特图 timeline]
</button>
</div>
</div>
</div>
{/* Item 5 */}
<div className="space-y-1.5">
<h5 className="font-extrabold text-slate-900 flex items-center gap-1.5 text-[12px]">
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-red-50 text-red-650 font-bold font-mono text-[10.5px]">5</span>
风险识别与安全应对 / Secondary Risk Management
</h5>
<p className="pl-6.5 text-slate-500 leading-normal">
通过多智能体委员会滚动博弈对抗和风险拦截验证,提前判定并锁定「需求过载细节波动」、「物理接机到货故障」、「通信源不完整滞缓」等 3 项主要隐忧。全部预案、补偿基金及冗余措施已完成,详见右侧面板。
</p>
</div>
{/* Item 6 */}
<div className="space-y-1.5">
<h5 className="font-extrabold text-slate-900 flex items-center gap-1.5 text-[12px]">
<span className="flex h-5 w-5 items-center justify-center rounded-full bg-emerald-50 text-emerald-650 font-bold font-mono text-[10.5px]">6</span>
关键里程碑控制链与下一步工作 / Execution Advice
</h5>
<div className="pl-6.5 text-slate-500 space-y-2 mt-2 leading-relaxed">
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2 text-[9.5px] font-medium">
<div className="p-2 bg-slate-50 border border-slate-150 rounded-xl flex items-start gap-2">
<span className="h-4.5 w-4.5 rounded bg-[var(--brand-200)]0 text-white flex items-center justify-center shrink-0 font-bold font-mono text-[9px]">M1</span>
<div>
<b className="text-slate-800 block text-[10.5px]">【T+12h 状态核验】</b>
<span>拉网对齐所有缺失要素,未达标熔断顺延</span>
</div>
</div>
<div className="p-2 bg-slate-50 border border-slate-150 rounded-xl flex items-start gap-2">
<span className="h-4.5 w-4.5 rounded bg-purple-500 text-white flex items-center justify-center shrink-0 font-bold font-mono text-[9px]">M2</span>
<div>
<b className="text-slate-800 block text-[10.5px]">【T+24h 双活就绪】</b>
<span>物理容器拉通,注入最极限崩溃测试演习</span>
</div>
</div>
<div className="p-2 bg-slate-50 border border-slate-150 rounded-xl flex items-start gap-2">
<span className="h-4.5 w-4.5 rounded bg-emerald-500 text-white flex items-center justify-center shrink-0 font-bold font-mono text-[9px]">M3</span>
<div>
<b className="text-slate-800 block text-[10.5px]">【T+60h 安全审计】</b>
<span>突发拔网接管成功,获得整装绿码授权</span>
</div>
</div>
</div>
<p className="text-[10.5px] text-slate-700 bg-amber-50/60 p-2.5 rounded-lg border border-amber-100 leading-normal font-medium mt-1.5">
💡 <b>行动意见:</b> 指挥官裁可此成果后,项目立即固化加锁。每日安排每12小时高维配合对齐站会,强力扣死这 3 颗 M-Class 螺丝钉。
</p>
</div>
</div>
</div>
</div>
{/* Section III: 论证依据支撑库 (Supporting Evidence Pieces) */}
<div className="bg-white border border-slate-150 rounded-2xl p-5 hover:shadow-md transition space-y-4">
<div className="flex items-center gap-2 border-b border-slate-100 pb-3 mb-1">
<Clipboard className="w-4.5 h-4.5 text-primary" strokeWidth={2.5} />
<h4 className="text-xs font-black text-slate-900 uppercase tracking-widest">
二、论证依据要件归档情况
</h4>
</div>
<p className="text-xs text-slate-400 font-medium">
本报告方案具有无可挑剔的底层输入支撑。点击各要件名称,可通过云控制台查看对应沙盒隔离归档详情:
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-3 pt-1 text-xs">
{[
{ num: "01", name: "用户需求研商访谈纪要.txt", size: "14.2 KB", color: "border-red-100 bg-[var(--brand-200)]/20 text-[var(--brand-900)]" },
{ num: "02", name: "指标现状及运行分析报告.docx", size: "2.4 MB", color: "border-teal-100 bg-teal-50/20 text-teal-750" },
{ num: "03", name: "典型物理拓扑经验 (2份).pdf", size: "4.8 MB", color: "border-purple-100 bg-purple-50/20 text-purple-750" },
{ num: "04", name: "安全极端防范策略库.json", size: "128 KB", color: "border-amber-100 bg-amber-50/20 text-amber-700" },
{ num: "05", name: "全行业合规防灾法规准则.pdf", size: "1.9 MB", color: "border-red-100 bg-red-50/20 text-red-750" }
].map((doc, index) => (
<div
key={index}
onClick={() => triggerToast(`正在预览论证原始要件: 《${doc.name}》...`)}
className={`p-3 border rounded-xl flex flex-col justify-between hover:scale-[1.02] active:scale-95 transition cursor-pointer select-none ${doc.color}`}
>
<div>
<b className="font-mono text-[9px] block mb-1 opacity-70">FILE-{doc.num}</b>
<span className="font-bold tracking-tight text-[11px] leading-snug block line-clamp-2 min-h-[32px]">
{doc.name}
</span>
</div>
<div className="flex items-center justify-between text-[9px] opacity-75 mt-3 border-t border-slate-200/50 pt-1.5 font-mono">
<span>附件档案</span>
<span>{doc.size}</span>
</div>
</div>
))}
</div>
</div>
{/* Section IV: 采纳采定理由陈述 (Final Ruling Statement / Stamp Board) */}
<div className="bg-gradient-to-r from-amber-50/40 via-yellow-50/30 to-amber-50/20 border border-amber-200/70 rounded-2xl p-5 hover:shadow-md transition">
<div className="flex items-center gap-2 mb-2.5">
<Star className="w-4.5 h-4.5 text-amber-500 fill-amber-400" />
<h4 className="text-xs font-black text-slate-900 uppercase tracking-widest">
三、采纳理由与最终裁定判词
</h4>
</div>
<div className="text-xs text-slate-800 leading-relaxed font-semibold">
<p>
经由专家委员会团队大模型多视角滚动共计 <b className="text-slate-900 font-extrabold">12 轮</b> 极限对抗研商、冲突演炼得出:在「工期匹配度」(92%)、「预算开支控制度」(90%)、「极端容灾抗体余温」(88%) 与「总价值安全收益率」(91%) 四维雷达对决合围精算测定中,本主案 A 指标总合分最高(<b>90.3分</b>)。相比其他预算爆限、对外部相关配合条件依赖极重的僵硬路线,本规划方案在限时给定的 {budgetLimit}万元 条件内,取得了最高确凿的可执行概率。特此裁决:<b>给予最高优先级采纳,盖印发布!</b>
</p>
</div>
</div>
{/* Footer Bottom Actions Box */}
<div className="pt-2 border-t border-slate-100 flex items-center justify-between flex-wrap gap-4">
<div className="flex items-center gap-1 text-slate-400 text-xs font-medium">
<svg className="w-4 h-4 text-slate-400 animate-pulse shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2.5">
<circle cx="12" cy="12" r="10" />
<path d="M12 6v6l4 2" />
</svg>
<span className="line-clamp-1">全案终审已经盖印下发。若再次起草新路线会商,可点左侧清归。</span>
</div>
<div className="flex items-center gap-2 w-full md:w-auto">
<button
id="step3-reset-btn"
onClick={() => {
setCurrentStep(1);
setStep1MessageHistory([
{
id: 1,
sender: "理解专家 (Gemini)",
avatarType: "blue",
content: "您好!我是多智能体理解与转化专家。请问我们本次需要进行什么业务路线图的顶层研商?(您可以选择下方预设模板一键录入任务环境)",
time: "10:00:00"
}
]);
setStep2RoundtableDialogues([
{
id: 1,
sender: "总结陈述智能体 (Gemini 2.5 Pro)",
avatarType: "blue",
content: "各位专家好,本论证轮主要针对“任务目标72小时极速打通投产”及“总预算在500万内开销”做可行度分析与冗余设计研商。请各抒己见。",
time: "10:01:05",
confidence: "主席初始化"
}
]);
triggerToast("✨ 指导系统成功完成归档,重新开始新一轮规划会商");
}}
className="flex-1 md:flex-none border border-slate-700 text-slate-700 hover:text-slate-900 hover:bg-slate-50 text-[10.5px] font-bold px-4 py-3 rounded-2xl transition cursor-pointer select-none font-sans"
>
重新起草新规划
</button>
<button
id="step3-sign-btn"
onClick={() => {
triggerToast("🚀 [最高指令授权签批]:协同全案已加签封存下发!核心路由组和灾灾备机制已就绪保障投产!");
}}
className="flex-1 md:flex-none bg-primary hover:bg-[var(--brand-900)] text-white text-[10.5px] font-black px-5 py-3 rounded-2xl shadow-lg shadow-primary/20 active:scale-95 transition cursor-pointer select-none flex items-center gap-1.5 justify-center"
>
<Sparkles className="w-3.5 h-3.5 text-red-200" />
签发起草成果并投产运行
</button>
</div>
</div>
</div>
</div>
);
};
@@ -0,0 +1,2 @@
export { default as RoundtablePlanningPage } from "./pages/RoundtablePlanningPage";
export { HighFidelityReport } from "./components/HighFidelityReport";
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,217 @@
@import "tailwindcss";
/* 圆桌规划 — 浅色红色主题(对齐 docs/浅红色ui修改.md) */
.roundtable-planning {
--rt-primary: var(--workspace-brand, #f5222d);
--rt-primary-hover: var(--brand-900, #cf1322);
--rt-primary-active: var(--brand-950, #a8071a);
--rt-primary-soft: var(--brand-200, #feeded);
--rt-page-bg: #fef6f6;
}
.roundtable-planning ::-webkit-scrollbar-thumb {
background: #fcb5b9;
}
.roundtable-planning ::-webkit-scrollbar-thumb:hover {
background: #fa9196;
}
.roundtable-planning .custom-scrollbar-inner::-webkit-scrollbar-thumb {
background: #fddadc;
}
/* 深色模式:跟随全局 ThemeContext(html.dark)或组件 .roundtable-planning--dark */
.dark .roundtable-planning,
.roundtable-planning--dark {
--rt-page-bg: var(--background);
--rt-primary: var(--primary);
--rt-primary-hover: var(--primary);
--rt-primary-soft: var(--accent);
color: var(--foreground);
background-color: var(--background);
}
.dark .roundtable-planning ::-webkit-scrollbar-thumb,
.roundtable-planning--dark ::-webkit-scrollbar-thumb {
background: color-mix(in oklch, var(--primary) 45%, var(--border));
}
.dark .roundtable-planning ::-webkit-scrollbar-thumb:hover,
.roundtable-planning--dark ::-webkit-scrollbar-thumb:hover {
background: color-mix(in oklch, var(--primary) 65%, var(--border));
}
.dark .roundtable-planning .custom-scrollbar-inner::-webkit-scrollbar-thumb,
.roundtable-planning--dark .custom-scrollbar-inner::-webkit-scrollbar-thumb {
background: color-mix(in oklch, var(--primary) 35%, transparent);
}
/* 页面底与浅色专用背景 */
.dark .roundtable-planning.bg-\[\#fef6f6\],
.roundtable-planning--dark.bg-\[\#fef6f6\] {
background-color: var(--background) !important;
}
/* 表面:白底卡片 → card */
.dark .roundtable-planning .bg-white,
.roundtable-planning--dark .bg-white {
background-color: var(--card) !important;
}
.dark .roundtable-planning .bg-slate-50,
.dark .roundtable-planning .bg-slate-50\/20,
.dark .roundtable-planning .bg-slate-50\/30,
.roundtable-planning--dark .bg-slate-50,
.roundtable-planning--dark .bg-slate-50\/20,
.roundtable-planning--dark .bg-slate-50\/30 {
background-color: color-mix(in oklch, var(--muted) 80%, transparent) !important;
}
.dark .roundtable-planning .from-slate-50,
.roundtable-planning--dark .from-slate-50 {
--tw-gradient-from: var(--muted) !important;
}
.dark .roundtable-planning .to-white,
.roundtable-planning--dark .to-white {
--tw-gradient-to: var(--card) !important;
}
/* 品牌浅红底 → accent */
.dark .roundtable-planning [class*="brand-200"],
.roundtable-planning--dark [class*="brand-200"] {
background-color: color-mix(in oklch, var(--accent) 55%, transparent) !important;
}
.dark .roundtable-planning .border-red-100,
.dark .roundtable-planning .border-red-100\/50,
.dark .roundtable-planning .border-red-200,
.dark .roundtable-planning .border-red-200\/50,
.dark .roundtable-planning .border-red-200\/85,
.roundtable-planning--dark .border-red-100,
.roundtable-planning--dark .border-red-100\/50,
.roundtable-planning--dark .border-red-200,
.roundtable-planning--dark .border-red-200\/50,
.roundtable-planning--dark .border-red-200\/85 {
border-color: var(--border) !important;
}
.dark .roundtable-planning .border-slate-100,
.dark .roundtable-planning .border-slate-200,
.dark .roundtable-planning .border-slate-200\/50,
.dark .roundtable-planning .border-\[\#e2e8f0\],
.roundtable-planning--dark .border-slate-100,
.roundtable-planning--dark .border-slate-200,
.roundtable-planning--dark .border-slate-200\/50,
.roundtable-planning--dark .border-\[\#e2e8f0\] {
border-color: var(--border) !important;
}
/* 文字 */
.dark .roundtable-planning .text-slate-900,
.dark .roundtable-planning .text-slate-800,
.dark .roundtable-planning .text-slate-700,
.dark .roundtable-planning .text-\[\#334155\],
.roundtable-planning--dark .text-slate-900,
.roundtable-planning--dark .text-slate-800,
.roundtable-planning--dark .text-slate-700,
.roundtable-planning--dark .text-\[\#334155\] {
color: var(--foreground) !important;
}
.dark .roundtable-planning .text-slate-600,
.dark .roundtable-planning .text-slate-500,
.dark .roundtable-planning .text-slate-400,
.roundtable-planning--dark .text-slate-600,
.roundtable-planning--dark .text-slate-500,
.roundtable-planning--dark .text-slate-400 {
color: var(--muted-foreground) !important;
}
.dark .roundtable-planning .hover\:text-slate-800:hover,
.roundtable-planning--dark .hover\:text-slate-800:hover {
color: var(--foreground) !important;
}
.dark .roundtable-planning .hover\:bg-slate-50:hover,
.roundtable-planning--dark .hover\:bg-slate-50:hover {
background-color: var(--accent) !important;
}
/* 顶栏 */
.dark .roundtable-planning > header,
.roundtable-planning--dark > header {
background-color: var(--card) !important;
border-color: var(--border) !important;
box-shadow: none !important;
}
/* 步骤条容器 */
.dark .roundtable-planning header .rounded-2xl.border,
.roundtable-planning--dark header .rounded-2xl.border {
background-color: var(--muted) !important;
border-color: var(--border) !important;
}
/* 次要按钮(白底) */
.dark .roundtable-planning header button.bg-white,
.roundtable-planning--dark header button.bg-white {
background-color: var(--secondary) !important;
color: var(--foreground) !important;
}
/* 输入区 focus ring */
.dark .roundtable-planning .focus-within\:ring-\[var\(--brand-200\)\]\/50:focus-within,
.roundtable-planning--dark .focus-within\:ring-\[var\(--brand-200\)\]\/50:focus-within {
--tw-ring-color: color-mix(in oklch, var(--primary) 25%, transparent) !important;
}
/* 渐变横幅 */
.dark .roundtable-planning .from-\[var\(--brand-200\)\],
.roundtable-planning--dark .from-\[var\(--brand-200\)\] {
--tw-gradient-from: color-mix(in oklch, var(--accent) 40%, transparent) !important;
}
.dark .roundtable-planning .border-primary,
.roundtable-planning--dark .border-2.border-primary {
border-color: color-mix(in oklch, var(--primary) 50%, var(--border)) !important;
}
/* 分隔线 */
.dark .roundtable-planning .bg-slate-200,
.roundtable-planning--dark .bg-slate-200 {
background-color: var(--border) !important;
}
/* Custom elegant scrollbar styling */
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #e2e8f0;
}
.custom-scrollbar-inner::-webkit-scrollbar-thumb {
background: #fddadc;
}
.dark .custom-scrollbar-inner::-webkit-scrollbar-thumb,
.roundtable-planning--dark .custom-scrollbar-inner::-webkit-scrollbar-thumb {
background: color-mix(in oklch, var(--primary) 35%, var(--border));
}