mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-30 06:45:55 +00:00
- Add explicit CJK fonts (PingFang SC, Noto Sans SC, Microsoft YaHei) and programmer fonts (JetBrains Mono, Fira Code, Cascadia Code) to Tailwind config - Bump prose base size from prose-sm (14px) to prose-lg (18px) for sharper CJK rendering - Unify user/assistant message font size at 18px with CJK-aware line-height (1.8) - Replace pure black/white foreground with Apple-style warm grays (#1d1d1f / #f5f5f7) - Override Tailwind Typography colors to use design tokens for consistency - Add negative letter-spacing on headings for tighter, more polished look
187 lines
5.9 KiB
HTML
187 lines
5.9 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="color-scheme" content="light dark" />
|
|
<meta
|
|
name="description"
|
|
content="nanobot web UI — chat with your nanobot workspace."
|
|
data-i18n-meta="description"
|
|
/>
|
|
<meta name="theme-color" content="#fafaf9" media="(prefers-color-scheme: light)" />
|
|
<meta name="theme-color" content="#161618" media="(prefers-color-scheme: dark)" />
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/brand/nanobot_favicon_32.png" />
|
|
<link rel="icon" type="image/png" sizes="73x75" href="/brand/nanobot_icon.png" />
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/brand/nanobot_apple_touch.png" />
|
|
<style>
|
|
html,
|
|
body,
|
|
#root {
|
|
height: 100%;
|
|
}
|
|
|
|
body {
|
|
margin: 0;
|
|
background: #ffffff;
|
|
color: #0a0a0a;
|
|
font-family:
|
|
system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
"Helvetica Neue", Arial, "Noto Sans", "Noto Sans SC",
|
|
"PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
|
|
sans-serif;
|
|
}
|
|
|
|
html.dark body {
|
|
background: #1a1a1a;
|
|
color: #fafafa;
|
|
}
|
|
|
|
.boot-splash {
|
|
display: flex;
|
|
height: 100%;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.boot-splash-inner {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
color: rgba(255, 255, 255, 0.74);
|
|
font-size: 14px;
|
|
}
|
|
|
|
html:not(.dark) .boot-splash-inner {
|
|
color: rgba(10, 10, 10, 0.64);
|
|
}
|
|
|
|
.boot-dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 9999px;
|
|
background: currentColor;
|
|
opacity: 0.75;
|
|
animation: boot-pulse 1s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes boot-pulse {
|
|
0%,
|
|
100% {
|
|
transform: scale(0.9);
|
|
opacity: 0.45;
|
|
}
|
|
50% {
|
|
transform: scale(1);
|
|
opacity: 0.85;
|
|
}
|
|
}
|
|
</style>
|
|
<script>
|
|
(function () {
|
|
try {
|
|
var stored = localStorage.getItem("nanobot-webui.theme");
|
|
var dark =
|
|
stored === "dark" ||
|
|
(!stored &&
|
|
window.matchMedia &&
|
|
window.matchMedia("(prefers-color-scheme: dark)").matches);
|
|
if (dark) document.documentElement.classList.add("dark");
|
|
} catch {}
|
|
})();
|
|
</script>
|
|
<script>
|
|
(function () {
|
|
var localeKey = "nanobot.locale";
|
|
var copy = {
|
|
en: {
|
|
boot: "Loading nanobot…",
|
|
description: "nanobot web UI — chat with your nanobot workspace."
|
|
},
|
|
"zh-CN": {
|
|
boot: "正在加载 nanobot…",
|
|
description: "nanobot Web UI —— 与你的 nanobot 工作区对话。"
|
|
},
|
|
"zh-TW": {
|
|
boot: "正在載入 nanobot…",
|
|
description: "nanobot Web UI —— 與你的 nanobot 工作區對話。"
|
|
},
|
|
fr: {
|
|
boot: "Chargement de nanobot…",
|
|
description: "Interface web nanobot — discutez avec votre espace de travail nanobot."
|
|
},
|
|
ja: {
|
|
boot: "nanobot を読み込み中…",
|
|
description: "nanobot Web UI — nanobot ワークスペースと会話します。"
|
|
},
|
|
ko: {
|
|
boot: "nanobot 불러오는 중…",
|
|
description: "nanobot 웹 UI — nanobot 작업공간과 대화하세요."
|
|
},
|
|
es: {
|
|
boot: "Cargando nanobot…",
|
|
description: "Interfaz web de nanobot: conversa con tu espacio de trabajo de nanobot."
|
|
},
|
|
vi: {
|
|
boot: "Đang tải nanobot…",
|
|
description: "Giao diện web nanobot — trò chuyện với workspace nanobot của bạn."
|
|
},
|
|
id: {
|
|
boot: "Memuat nanobot…",
|
|
description: "UI web nanobot — ngobrol dengan workspace nanobot Anda."
|
|
}
|
|
};
|
|
|
|
function normalizeLocale(input) {
|
|
if (!input) return "en";
|
|
var raw = String(input).trim();
|
|
if (!raw) return "en";
|
|
if (copy[raw]) return raw;
|
|
var lower = raw.toLowerCase();
|
|
if (lower === "zh" || lower.indexOf("zh-cn") === 0 || lower.indexOf("zh-sg") === 0) {
|
|
return "zh-CN";
|
|
}
|
|
if (
|
|
lower.indexOf("zh-tw") === 0 ||
|
|
lower.indexOf("zh-hk") === 0 ||
|
|
lower.indexOf("zh-mo") === 0 ||
|
|
lower.indexOf("zh-hant") === 0
|
|
) {
|
|
return "zh-TW";
|
|
}
|
|
var base = lower.split("-")[0];
|
|
return copy[base] ? base : "en";
|
|
}
|
|
|
|
try {
|
|
var stored = localStorage.getItem(localeKey);
|
|
var detected =
|
|
stored ||
|
|
(navigator.languages && navigator.languages[0]) ||
|
|
navigator.language ||
|
|
"en";
|
|
var locale = normalizeLocale(detected);
|
|
var localized = copy[locale] || copy.en;
|
|
document.documentElement.lang = locale;
|
|
var description = document.querySelector('[data-i18n-meta=\"description\"]');
|
|
if (description) description.setAttribute("content", localized.description);
|
|
var boot = document.querySelector("[data-boot-copy]");
|
|
if (boot) boot.textContent = localized.boot;
|
|
} catch {}
|
|
})();
|
|
</script>
|
|
<title>nanobot</title>
|
|
</head>
|
|
<body class="bg-background text-foreground antialiased">
|
|
<div id="root">
|
|
<div class="boot-splash">
|
|
<div class="boot-splash-inner">
|
|
<span class="boot-dot" aria-hidden="true"></span>
|
|
<span data-boot-copy>Loading nanobot…</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script type="module" src="/src/main.tsx"></script>
|
|
</body>
|
|
</html>
|