This commit is contained in:
retoor 2025-06-07 07:56:57 +02:00
parent 389d417c1b
commit bdddbf678c
2 changed files with 206 additions and 235 deletions

View File

@ -10,6 +10,7 @@
<meta name="keywords" content="snek, chat, molodetz"> <meta name="keywords" content="snek, chat, molodetz">
<meta name="color-scheme" content="dark"> <meta name="color-scheme" content="dark">
<link rel="stylesheet" href="/sandbox.css" />
<title>{% block title %}Snek chat by Molodetz{% endblock %}</title> <title>{% block title %}Snek chat by Molodetz{% endblock %}</title>
<script src="/polyfills/Promise.withResolvers.js" type="module"></script> <script src="/polyfills/Promise.withResolvers.js" type="module"></script>
@ -34,6 +35,7 @@
<main> <main>
{% block main %} {% block main %}
{% endblock %} {% endblock %}
{% include "sandbox.html" %}
</main> </main>
</body> </body>
</html> </html>

View File

@ -1,133 +1,49 @@
<!DOCTYPE html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
background-color: white; /* Ensure the iframe has a white background */
}
/* Base reset */
* { margin:0; padding:0; box-sizing:border-box; }
body {
font-family: 'Segoe UI',sans-serif;
background: #000;
color: #eee;
line-height:1.5;
}
a { color: #7ef; text-decoration: none; }
a:hover { text-decoration: underline; }
/* Container */
.container { width: 90%; max-width: 960px; margin: auto; padding: 2rem 0; }
/* Hero */
.hero {
text-align: center;
padding: 4rem 0;
}
.hero h1 {
font-size: 3rem;
background: linear-gradient(90deg,#7ef 0%,#0fa 100%);
-webkit-background-clip: text;
color: transparent;
}
.hero p {
font-size: 1.2rem;
margin: 1rem 0 2rem;
}
.btn {
display: inline-block;
padding: .75rem 1.5rem;
margin: .5rem;
background: #0fa;
color: #111;
font-weight: bold;
border-radius: 4px;
transition: background .2s;
}
.btn:hover { background: #7ef; }
/* Features grid */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}
.card {
background: #1a1a1a;
border-radius: 6px;
padding: 1.5rem;
box-shadow: 0 2px 6px rgba(0,0,0,0.6);
}
.card h3 {
margin-bottom: .75rem;
color: #7ef;
}
.card ul {
list-style: disc inside;
margin-top: .5rem;
}
/* Footer */
footer {
text-align: center;
font-size: .9rem;
padding: 2rem 0;
color: #888;
}
footer code {
background: #222;
padding: 2px 4px;
border-radius: 3px;
color: #7ef;
}
/* Mobile tweaks */
@media (max-width: 480px) {
.hero h1 { font-size: 2.4rem; }
.btn { width: 100%; box-sizing: border-box; text-align:center; }
}
</style>
</head>
<body>
<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" /> <meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Snek The Ultimate Web Community</title> <title>Snek The Ultimate Web Community</title>
<link rel="stylesheet" href="/sandbox.css" />
<style> <style>
/* Base reset */
* { margin:0; padding:0; box-sizing:border-box; } * { margin:0; padding:0; box-sizing:border-box; }
html, body { height: 100%; }
.card {
opacity: 0.7;
z-index: 10;
}
.star {
z-index: -10;
}
body { body {
font-family: 'Segoe UI',sans-serif; font-family: 'Segoe UI',sans-serif;
background: #111; background: #111;
color: #eee; color: #eee;
line-height:1.5; line-height:1.5;
min-height: 100vh;
position: relative;
overflow-x: auto;
overflow-y: auto;
} }
a { color: #7ef; text-decoration: none; } a { color: #7ef; text-decoration: none; }
a:hover { text-decoration: underline; } a:hover { text-decoration: underline; }
/* Container */
.container { width: 90%; max-width: 960px; margin: auto; padding: 2rem 0; } .container { width: 90%; max-width: 960px; margin: auto; padding: 2rem 0; }
/* Hero */
.hero { .hero {
text-align: center; text-align: center;
padding: 4rem 0; padding: 4rem 0;
background-image: url('/image/snek_logo_256x256.png');
background-size: contain;
background-position: left center;
background-repeat: no-repeat;
} }
.hero h1 { .hero h1 {
font-size: 3rem; font-size: 3rem;
background: linear-gradient(90deg,#7ef 0%,#0fa 100%); background: linear-gradient(90deg,#7ef 0%,#0fa 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
color: transparent; -webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
margin-bottom: .5rem;
} }
.hero p { .hero p {
font-size: 1.2rem; font-size: 1.2rem;
@ -142,10 +58,9 @@
font-weight: bold; font-weight: bold;
border-radius: 4px; border-radius: 4px;
transition: background .2s; transition: background .2s;
cursor: pointer;
} }
.btn:hover { background: #7ef; } .btn:hover { background: #7ef; }
/* Features grid */
.grid { .grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
@ -161,13 +76,28 @@
.card h3 { .card h3 {
margin-bottom: .75rem; margin-bottom: .75rem;
color: #7ef; color: #7ef;
font-size: 1.25rem;
} }
.card ul { .card ul {
list-style: disc inside; list-style: disc inside;
margin-top: .5rem; margin-top: .5rem;
} }
section#signup,
/* Footer */ section#selfhost {
text-align:center;
margin:4rem 0;
}
section#selfhost pre {
display:inline-block;
background:#222;
padding:1rem;
border-radius:4px;
color:#7ef;
font-size:1rem;
margin: 1rem 0;
text-align: left;
box-sizing: border-box;
}
footer { footer {
text-align: center; text-align: center;
font-size: .9rem; font-size: .9rem;
@ -180,140 +110,179 @@
border-radius: 3px; border-radius: 3px;
color: #7ef; color: #7ef;
} }
.star {
/* Mobile tweaks */ position: fixed;
background: #fff;
border-radius: 50%;
pointer-events: none;
z-index: 0;
opacity: .8;
animation: star-flicker 4s infinite alternate;
}
@keyframes star-flicker {
0%, 100% { opacity: .7; }
50% { opacity: 1; }
}
@media (max-width: 480px) { @media (max-width: 480px) {
.hero h1 { font-size: 2.4rem; } .hero h1 { font-size: 2.4rem; }
.btn { width: 100%; box-sizing: border-box; text-align:center; } .btn { width: 100%; box-sizing: border-box; text-align:center; }
.hero {
background-size: 64px 64px;
padding-left: 0;
}
}
#starfield {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
z-index: -2;
pointer-events: none;
background: transparent;
display: block;
} }
</style> </style>
<link rel="stylesheet" href="/static/sandbox.css" />
</head> </head>
<body> <body>
<header class="container hero">
<header class="container hero"> <h1>Snek</h1>
<h1>Snek</h1> <p>The Ultimate Web Community for Devs, Testers &amp; AI Enthusiasts</p>
<p>The Ultimate Web Community for Devs, Testers &amp; AI Enthusiasts</p> <a href="/login.html" class="btn">Login</a>
<a href="/login.html" class="btn">Login</a> <a href="/register.html" class="btn">Register</a>
<a href="/register.html" class="btn">Register</a> </header>
</header> <main class="container">
<section id="features" class="grid">
<main class="container"> <div class="card">
<h3>File Sharing</h3>
<section id="features" class="grid"> <ul>
<div class="card"> <li>SFTP storage with your Snek credentials</li>
<h3>File Sharing</h3> <li>WebDAV support same login</li>
<ul> </ul>
<li>SFTP storage with your Snek credentials</li> </div>
<li>WebDAV support same login</li> <div class="card">
</ul> <h3>Git Repositories</h3>
</div> <ul>
<li>Configure repos for any official Git client</li>
<div class="card"> <li>Instant setup, push &amp; pull</li>
<h3>Git Repositories</h3> </ul>
<ul> </div>
<li>Configure repos for any official Git client</li> <div class="card">
<li>Instant setup, push &amp; pull</li> <h3>AI Powerhouse</h3>
</ul> <ul>
</div> <li>Chat with free &amp; commercial AIs</li>
<li>Generate AI-powered images</li>
<div class="card"> <li>Build your own AI bots in &lt;5 minutes (copy/paste example)</li>
<h3>AI Powerhouse</h3> </ul>
<ul> </div>
<li>Chat with free &amp; commercial AIs</li> <div class="card">
<li>Generate AI-powered images</li> <h3>Dev &amp; Terminal</h3>
<li>Build your own AI bots in &lt;5 minutes (copy/paste example)</li> <ul>
</ul> <li>Ubuntu web terminal in-browser</li>
</div> <li>Full profile &amp; permissions management</li>
</ul>
<div class="card"> </div>
<h3>Dev &amp; Terminal</h3> <div class="card">
<ul> <h3>Chat &amp; Media</h3>
<li>Ubuntu web terminal in-browser</li> <ul>
<li>Full profile &amp; permissions management</li> <li>Upload any file type in chat</li>
</ul> <li>Rich media support (audio, video, images…)</li>
</div> <li>Direct messaging with other users</li>
</ul>
<div class="card"> </div>
<h3>Chat &amp; Media</h3> <div class="card">
<ul> <h3>Privacy &amp; Community</h3>
<li>Upload any file type in chat</li> <ul>
<li>Rich media support (audio, video, images…)</li> <li>No logging—never even your IP</li>
<li>Direct messaging with other users</li> <li>No email required to sign up</li>
</ul> <li>Multi-national, open community</li>
</div> <li>Hacking encouraged!</li>
</ul>
<div class="card"> </div>
<h3>Privacy &amp; Community</h3> <div class="card">
<ul> <h3>Customization &amp; Deployment</h3>
<li>No logging—never even your IP</li> <ul>
<li>No email required to sign up</li> <li>Full layout &amp; theme customization</li>
<li>Multi-national, open community</li> <li>Install as a PWA on your phone</li>
<li>Hacking encouraged!</li> <li>Optionally self-host: <code>pip install</code>, zero config</li>
</ul> </ul>
</div> </div>
</section>
<div class="card"> <section id="signup">
<h3>Customization &amp; Deployment</h3> <h2>Ready to join?</h2>
<ul> <p>No email. No logs. Just sign up, pick a username, and dive in!</p>
<li>Full layout &amp; theme customization</li> <a href="/register" class="btn">Sign Up Now</a>
<li>Install as a PWA on your phone</li> </section>
<li>Optionally self-host: <code>pip install snek</code>, zero config</li> <section id="selfhost" style="margin-bottom:4rem;">
</ul> <h2>Self-Host in Seconds</h2>
</div> <p>Just run:</p>
</section> <pre>
<section id="signup" style="text-align:center; margin:4rem 0;">
<h2>Ready to join?</h2>
<p>No email. No logs. Just sign up, pick a username, and dive in!</p>
<a href="/register" class="btn">Sign Up Now</a>
</section>
<section id="selfhost" style="text-align:center; margin-bottom:4rem;">
<h2>Self-Host in Seconds</h2>
<p>Just run:</p>
<pre style="display:inline-block; background:#222; padding:1rem; border-radius:4px; color:#7ef;">
pip install git+https://retoor.molodetz.nl/retoor/snek.git pip install git+https://retoor.molodetz.nl/retoor/snek.git
snek serve snek serve
</pre> </pre>
<p>No configuration required—it's that simple.</p> <p>No configuration required—it's that simple.</p>
</section> </section>
{% include "sandbox.html" %}
</main> </main>
<footer>
<footer> <p>&copy; 2025 Snek Join our global community of developers, testers &amp; AI enthusiasts.</p>
<p>&copy; 2025 Snek Join our global community of developers, testers &amp; AI enthusiasts.</p> </footer>
</footer> <script>
(function() {
<script> const canvas = document.getElementById('starfield');
const ctx = canvas.getContext('2d');
// number of stars you want let stars = [];
const STAR_COUNT = 200; let w = window.innerWidth;
const body = document.body; let h = window.innerHeight;
function resize() {
for (let i = 0; i < STAR_COUNT; i++) { w = window.innerWidth;
const star = document.createElement('div'); h = window.innerHeight;
star.classList.add('star'); canvas.width = w;
canvas.height = h;
// random position within the viewport }
star.style.left = Math.random() * 100 + '%'; function randomStar() {
star.style.top = Math.random() * 100 + '%'; return {
x: Math.random() * w,
// random size (optional) y: Math.random() * h,
const size = Math.random() * 2 + 1; // between 1px and 3px r: Math.random() * 0.8 + 0.2,
star.style.width = size + 'px'; o: Math.random() * 0.5 + 0.5,
star.style.height = size + 'px'; tw: Math.random() * 100 + 60,
phase: Math.random() * 2 * Math.PI
// random animation timing for natural flicker };
const duration = Math.random() * 3 + 2; // 2s5s }
const delay = Math.random() * 5; // 0s5s function createStars(count) {
star.style.animationDuration = duration + 's'; stars = [];
star.style.animationDelay = delay + 's'; for (let i=0; i<count; ++i) stars.push(randomStar());
}
body.appendChild(star); function drawStars(time) {
ctx.clearRect(0, 0, w, h);
for (const s of stars) {
const twinkle = 0.5 + 0.5 * Math.sin(time/1000 * (1000/s.tw) + s.phase);
ctx.globalAlpha = s.o * twinkle;
ctx.beginPath();
ctx.arc(s.x, s.y, s.r, 0, 2 * Math.PI);
ctx.fillStyle = '#fff';
ctx.fill();
} }
</script> ctx.globalAlpha = 1;
}
function animate(time) {
drawStars(time || 0);
requestAnimationFrame(animate);
}
function updateStars() {
const count = Math.floor(w * h / 4500);
createStars(count);
}
window.addEventListener('resize', function() {
resize();
updateStars();
});
resize();
updateStars();
animate();
})();
</script>
</body> </body>
</html> </html>