chess-trainer-mcp
Version:
Chess Trainer MCP Server with Stockfish NNUE engine - Interactive chess training with AI coaching capabilities
135 lines (120 loc) • 4.53 kB
HTML
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/chess-icon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Chess Trainer MCP</title>
<meta name="description" content="Advanced chess training with AI-powered analysis and coaching">
<!-- PWA Meta Tags -->
<meta name="theme-color" content="#1a1a1a" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Chess Trainer" />
<!-- PWA Icons -->
<link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/icons/favicon-16x16.png" />
<link rel="manifest" href="/manifest.json" />
<!-- Chessground CSS -->
<link rel="stylesheet" href="/chessground.base.css" />
<link rel="stylesheet" href="/chessground.brown.css" />
<link rel="stylesheet" href="/chessground.cburnett.css" />
<style>
/* Critical CSS for loading */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif;
background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
color: #ffffff;
overflow-x: hidden;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
#root {
min-height: 100vh;
min-height: 100dvh; /* Dynamic viewport height for mobile */
}
.loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
min-height: 100dvh;
gap: 1rem;
font-size: 18px;
color: #888;
background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
}
.loading-spinner {
width: 40px;
height: 40px;
border: 3px solid #333;
border-top: 3px solid #4f9eff;
border-radius: 50%;
animation: spin 1s linear infinite;
}
.loading-text {
font-weight: 500;
letter-spacing: 0.5px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Prevent zoom on iOS */
input, select, textarea {
font-size: 16px;
}
</style>
<script type="module" crossorigin src="/assets/index-Ad0-R2PL.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vendor-B0SF1ZWq.js">
<link rel="modulepreload" crossorigin href="/assets/chess-BxNetR-S.js">
<link rel="stylesheet" crossorigin href="/assets/index-Cy2xWLvC.css">
</head>
<body>
<div id="loading" class="loading">
<div class="loading-spinner"></div>
<div class="loading-text">Loading Chess Trainer</div>
</div>
<div id="root"></div>
<script>
// PWA Service Worker Registration
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(registration => {
// SW registered
})
.catch(registrationError => {
console.error('SW registration failed: ', registrationError);
});
});
}
// Hide loading when app loads
window.addEventListener('load', () => {
setTimeout(() => {
const loading = document.getElementById('loading');
if (loading) loading.style.display = 'none';
}, 1000);
});
// Prevent pinch zoom on mobile
document.addEventListener('gesturestart', function (e) {
e.preventDefault();
});
// Handle viewport height changes on mobile
function setViewportHeight() {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
}
setViewportHeight();
window.addEventListener('resize', setViewportHeight);
window.addEventListener('orientationchange', setViewportHeight);
</script>
</body>
</html>