Files
Netcatty/index.html
T
LAPTOP-O016UC3M\Qi Chen cef7441ff9 Improves HTML formatting and code consistency
Refactors indentation and element formatting for better readability.
Enhances maintainability and visual structure without changing logic.
2025-12-18 23:05:13 +08:00

201 lines
5.8 KiB
HTML
Executable File

<!DOCTYPE html>
<html lang="en" class="h-full">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self'; connect-src 'self' data: blob: ws: wss: https:; img-src 'self' data: https:;" />
<title>netcatty SSH</title>
<style>
/* Load extended Unicode ranges for terminal box drawing characters */
@font-face {
font-family: 'JetBrains Mono Extended';
src: local('JetBrains Mono'), local('JetBrainsMono-Regular');
unicode-range: U+2500-257F, U+2580-259F, U+25A0-25FF, U+2700-27BF;
}
:root {
--background: 216 33% 96%;
--foreground: 222 47% 12%;
--card: 0 0% 100%;
--card-foreground: 222 47% 12%;
--popover: 0 0% 100%;
--popover-foreground: 222 47% 12%;
--primary: 208 100% 50%;
--primary-foreground: 0 0% 100%;
--secondary: 220 16% 90%;
--secondary-foreground: 222 47% 12%;
--muted: 220 16% 90%;
--muted-foreground: 220 10% 45%;
--accent: var(--primary);
--accent-foreground: 222 47% 12%;
--destructive: 0 70% 50%;
--destructive-foreground: 0 0% 100%;
--border: 220 16% 82%;
--input: 220 16% 82%;
--ring: 208 100% 50%;
--radius: 0.65rem;
}
.dark {
--background: 220 28% 8%;
--foreground: 210 40% 95%;
--card: 220 22% 12%;
--card-foreground: 210 40% 95%;
--popover: 220 22% 12%;
--popover-foreground: 210 40% 95%;
--primary: 200 100% 61%;
--primary-foreground: 220 40% 96%;
--secondary: 220 16% 16%;
--secondary-foreground: 210 40% 90%;
--muted: 220 16% 16%;
--muted-foreground: 220 10% 70%;
--accent: var(--primary);
--accent-foreground: 220 40% 96%;
--destructive: 0 70% 50%;
--destructive-foreground: 210 40% 96%;
--border: 220 22% 18%;
--input: 220 22% 18%;
--ring: 200 100% 61%;
--radius: 0.65rem;
}
body {
font-family: 'Space Grotesk', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
margin: 0;
background: hsl(var(--background));
color: hsl(var(--foreground));
}
/* Global Modern Scrollbar */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: hsl(var(--muted-foreground) / 0.3);
border-radius: 99px;
border: 3px solid transparent;
background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
background: hsl(var(--muted-foreground) / 0.5);
background-clip: content-box;
}
::-webkit-scrollbar-corner {
background: transparent;
}
/* Utility to hide scrollbar */
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
/* Splash screen styles */
.splash-screen {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: hsl(var(--background));
z-index: 9999;
transition: opacity 0.2s ease-out;
}
.splash-screen.fade-out {
opacity: 0;
pointer-events: none;
}
.splash-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 24px;
}
.splash-logo {
width: 64px;
height: 64px;
color: hsl(var(--primary));
}
.splash-spinner {
width: 24px;
height: 24px;
border: 2px solid hsl(var(--muted));
border-top-color: hsl(var(--primary));
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>
<script>
(function () {
try {
var theme = localStorage.getItem('netcatty_theme_v1');
var color = localStorage.getItem('netcatty_color_v1');
var lang = localStorage.getItem('netcatty_ui_language_v1');
var root = document.documentElement;
if (theme === 'dark' || theme === 'light') {
root.classList.remove('light', 'dark');
root.classList.add(theme);
}
if (color) {
root.style.setProperty('--primary', color);
root.style.setProperty('--accent', color);
root.style.setProperty('--ring', color);
}
if (lang) root.lang = lang;
} catch (e) {
// ignore
}
})();
</script>
<link rel="stylesheet" href="/index.css">
</head>
<body class="bg-background text-foreground overflow-hidden antialiased h-screen w-screen">
<div id="root" class="h-full w-full">
<!-- Splash screen: shown while React loads, hidden after first paint -->
<div id="splash" class="splash-screen">
<div class="splash-content">
<svg class="splash-logo" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="48" height="48" rx="12" fill="currentColor" fill-opacity="0.1" />
<path
d="M14 16C14 14.8954 14.8954 14 16 14H32C33.1046 14 34 14.8954 34 16V32C34 33.1046 33.1046 34 32 34H16C14.8954 34 14 33.1046 14 32V16Z"
stroke="currentColor" stroke-width="2" />
<path d="M18 22L22 26L18 30" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" />
<path d="M26 30H30" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
</svg>
<div class="splash-spinner"></div>
</div>
</div>
</div>
<script type="module" src="/index.tsx"></script>
</body>
</html>