Files
onepager/sites/commanderkin.de/index.html
m 84b28d64f5 feat: AI/KI disclosure footer — shared/ai-disclosure.js + all 54 sites
Self-injecting script following impressum.js pattern:
- data-tone attribute: playful | serious | minimal | none
- Reads document.documentElement.lang for KI (de) vs AI (en)
- MutationObserver on lang attr for i18n toggle compat
- All tones link to msbls.de/ki
- Injected into all 54 custom sites with data-tone="playful"
- Template infra: base.html includes script, render.sh reads disclosure.tone
- disclosure.tone added to 3 example site.yaml files

Implements m/onepager#2
2026-04-01 13:26:04 +02:00

521 lines
16 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CommanderKIn — Commander Keen + KI</title>
<meta name="description" content="Old-School Vibes, New-School AI. 90er Retro-Gaming meets künstliche Intelligenz.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
:root{
--black:#000;
--green:#33ff33;
--blue:#0055aa;
--red:#ff3333;
--green-dim:#1a8c1a;
--green-glow:0 0 10px rgba(51,255,51,.4),0 0 40px rgba(51,255,51,.15);
--red-glow:0 0 10px rgba(255,51,51,.4),0 0 40px rgba(255,51,51,.15);
--blue-glow:0 0 10px rgba(0,85,170,.4),0 0 40px rgba(0,85,170,.15);
}
html{scroll-behavior:smooth}
body{
background:var(--black);
color:var(--green);
font-family:'VT323',monospace;
font-size:20px;
line-height:1.6;
overflow-x:hidden;
-webkit-font-smoothing:none;
-moz-osx-font-smoothing:unset;
}
/* CRT Scanlines Overlay */
body::before{
content:'';
position:fixed;
inset:0;
background:repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0,0,0,.15) 2px,
rgba(0,0,0,.15) 4px
);
pointer-events:none;
z-index:9999;
}
/* CRT Screen Curve + Vignette */
body::after{
content:'';
position:fixed;
inset:0;
background:radial-gradient(ellipse at center,transparent 60%,rgba(0,0,0,.7) 100%);
pointer-events:none;
z-index:9998;
}
/* Pixel grid noise */
.noise{
position:fixed;inset:0;z-index:9997;pointer-events:none;opacity:.03;
background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.container{
max-width:900px;
margin:0 auto;
padding:0 24px;
position:relative;
z-index:1;
}
/* ========== HERO ========== */
.hero{
min-height:100vh;
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
text-align:center;
padding:40px 20px;
}
.hero-title{
font-family:'Press Start 2P',monospace;
font-size:clamp(28px,6vw,56px);
color:var(--green);
text-shadow:var(--green-glow);
letter-spacing:2px;
line-height:1.4;
margin-bottom:8px;
}
.hero-title .ki{
color:var(--red);
text-shadow:var(--red-glow);
}
.cursor-blink{
display:inline-block;
width:0.6em;
height:1em;
background:var(--green);
vertical-align:middle;
margin-left:4px;
animation:blink 1s step-end infinite;
}
@keyframes blink{0%,100%{opacity:1}50%{opacity:0}}
.hero-sub{
font-family:'Press Start 2P',monospace;
font-size:clamp(10px,2vw,16px);
color:var(--blue);
text-shadow:var(--blue-glow);
margin-top:16px;
letter-spacing:1px;
}
.hero-sub .loading-dots::after{
content:'';
animation:dots 2s step-end infinite;
}
@keyframes dots{
0%{content:''}25%{content:'.'}50%{content:'..'}75%{content:'...'}
}
.boot-text{
margin-top:40px;
font-size:14px;
color:var(--green-dim);
text-align:left;
max-width:500px;
line-height:1.8;
}
.boot-text span{animation:fadeIn .3s ease forwards;opacity:0}
@keyframes fadeIn{to{opacity:1}}
/* ========== CONCEPT ========== */
.concept{
padding:80px 0;
text-align:center;
}
.concept-text{
font-size:clamp(22px,3vw,32px);
max-width:700px;
margin:0 auto;
line-height:1.6;
color:var(--green);
}
.concept-text em{
color:var(--red);
font-style:normal;
text-shadow:var(--red-glow);
}
.section-divider{
text-align:center;
padding:20px 0;
font-family:'Press Start 2P',monospace;
font-size:12px;
color:var(--green-dim);
letter-spacing:8px;
}
/* ========== LEVELS ========== */
.levels{
padding:60px 0;
}
.levels-title{
font-family:'Press Start 2P',monospace;
font-size:clamp(14px,2.5vw,22px);
color:var(--blue);
text-shadow:var(--blue-glow);
text-align:center;
margin-bottom:48px;
}
.level{
display:flex;
align-items:flex-start;
gap:20px;
padding:24px;
margin-bottom:16px;
border:1px solid #1a1a2e;
border-radius:4px;
background:rgba(51,255,51,.02);
transition:all .3s ease;
}
.level:hover{
border-color:var(--green);
background:rgba(51,255,51,.06);
box-shadow:var(--green-glow);
}
.level-badge{
font-family:'Press Start 2P',monospace;
font-size:11px;
color:var(--black);
background:var(--green);
padding:6px 10px;
white-space:nowrap;
flex-shrink:0;
border-radius:2px;
}
.level.boss .level-badge{
background:var(--red);
animation:pulse-red 2s ease infinite;
}
@keyframes pulse-red{
0%,100%{box-shadow:none}50%{box-shadow:var(--red-glow)}
}
.level-name{
font-family:'Press Start 2P',monospace;
font-size:clamp(12px,2vw,16px);
color:var(--green);
margin-bottom:6px;
}
.level.boss .level-name{color:var(--red);text-shadow:var(--red-glow)}
.level-desc{
font-size:18px;
color:var(--green-dim);
line-height:1.5;
}
/* ========== PIXEL ART DIVIDER ========== */
.pixel-art{
text-align:center;
padding:40px 0;
font-family:'Press Start 2P',monospace;
font-size:10px;
color:var(--green-dim);
line-height:1.2;
white-space:pre;
overflow:hidden;
}
/* ========== CTA ========== */
.cta{
padding:80px 0;
text-align:center;
}
.cta-label{
font-family:'Press Start 2P',monospace;
font-size:clamp(10px,1.5vw,14px);
color:var(--blue);
text-shadow:var(--blue-glow);
margin-bottom:32px;
animation:blink 1.5s step-end infinite;
}
.btn-start{
display:inline-block;
font-family:'Press Start 2P',monospace;
font-size:clamp(16px,3vw,24px);
color:var(--black);
background:var(--green);
padding:18px 48px;
border:none;
cursor:pointer;
text-decoration:none;
border-radius:4px;
transition:all .2s ease;
box-shadow:var(--green-glow);
position:relative;
}
.btn-start:hover{
background:var(--red);
box-shadow:var(--red-glow);
transform:scale(1.05);
}
.btn-start:active{transform:scale(.97)}
/* ========== FOOTER ========== */
.footer{
padding:60px 0 40px;
text-align:center;
border-top:1px solid #1a1a2e;
}
.insert-coin{
font-family:'Press Start 2P',monospace;
font-size:clamp(10px,2vw,14px);
color:var(--green);
text-shadow:var(--green-glow);
animation:blink 1.2s step-end infinite;
}
.footer-sub{
margin-top:20px;
font-size:14px;
color:#333;
letter-spacing:1px;
}
.footer-sub a{color:#333;text-decoration:none}
.footer-sub a:hover{color:var(--green-dim)}
/* ========== RESPONSIVE ========== */
@media(max-width:640px){
.level{flex-direction:column;gap:12px}
.level-badge{align-self:flex-start}
.boot-text{font-size:12px}
.pixel-art{font-size:6px}
}
/* ========== SCREEN FLICKER (subtle) ========== */
@keyframes flicker{
0%{opacity:1}3%{opacity:.95}6%{opacity:1}7%{opacity:.9}9%{opacity:1}100%{opacity:1}
}
.container{animation:flicker 8s linear infinite}
/* ========== SCROLL ANIMATIONS ========== */
.reveal{opacity:0;transform:translateY(20px);transition:all .6s ease}
.reveal.visible{opacity:1;transform:translateY(0)}
/* High Score Table styling */
.stats{
padding:40px 0;
text-align:center;
}
.stats-grid{
display:grid;
grid-template-columns:repeat(3,1fr);
gap:16px;
max-width:600px;
margin:32px auto 0;
}
.stat{
border:1px solid #1a1a2e;
border-radius:4px;
padding:20px 12px;
background:rgba(51,255,51,.02);
}
.stat-val{
font-family:'Press Start 2P',monospace;
font-size:clamp(16px,3vw,28px);
color:var(--green);
text-shadow:var(--green-glow);
}
.stat-label{
font-size:14px;
color:var(--green-dim);
margin-top:8px;
}
@media(max-width:640px){.stats-grid{grid-template-columns:1fr}}
</style>
</head>
<body>
<div class="noise"></div>
<!-- ===== HERO ===== -->
<section class="hero">
<div class="container">
<h1 class="hero-title">
Commander<span class="ki">KI</span>n<span class="cursor-blink"></span>
</h1>
<p class="hero-sub" data-de="Level 1: &lt;span class=&quot;ki-text&quot;&gt;KI&lt;/span&gt; Loading" data-en="Level 1: &lt;span class=&quot;ki-text&quot;&gt;AI&lt;/span&gt; Loading">Level 1: <span class="ki-text">KI</span> Loading<span class="loading-dots"></span></p>
<div class="boot-text" id="bootSequence">
<span style="animation-delay:0.3s">C:\COMMANDERKIN> boot_sequence.exe</span><br>
<span style="animation-delay:0.8s" data-de="Initializing neural_network.dll ........ OK" data-en="Initializing neural_network.dll ........ OK">Initializing neural_network.dll ........ OK</span><br>
<span style="animation-delay:1.3s" data-de="Loading retro_vibes.dat ................ OK" data-en="Loading retro_vibes.dat ................ OK">Loading retro_vibes.dat ................ OK</span><br>
<span style="animation-delay:1.8s" data-de="Calibrating pixel_cannon.sys ........... OK" data-en="Calibrating pixel_cannon.sys ........... OK">Calibrating pixel_cannon.sys ........... OK</span><br>
<span style="animation-delay:2.3s" data-de="Mounting galaxy_drive D:\ .............. OK" data-en="Mounting galaxy_drive D:\ .............. OK">Mounting galaxy_drive D:\ .............. OK</span><br>
<span style="animation-delay:2.8s" style="color:var(--green)" data-de="SYSTEM READY. PRESS START." data-en="SYSTEM READY. PRESS START.">SYSTEM READY. PRESS START.</span>
</div>
</div>
</section>
<!-- ===== CONCEPT ===== -->
<div class="section-divider">- - - - - - - - - -</div>
<section class="concept container reveal">
<p class="concept-text" data-de="Wie Commander Keen die Galaxie rettete, rettet &lt;em&gt;CommanderKIn&lt;/em&gt; deine Daten.&lt;br&gt;&lt;br&gt;Old-School Vibes. New-School &lt;em&gt;AI&lt;/em&gt;." data-en="Like Commander Keen saved the galaxy, &lt;em&gt;CommanderKIn&lt;/em&gt; saves your data.&lt;br&gt;&lt;br&gt;Old-School Vibes. New-School &lt;em&gt;AI&lt;/em&gt;.">
Wie Commander Keen die Galaxie rettete, rettet <em>CommanderKIn</em> deine Daten.<br><br>
Old-School Vibes. New-School <em>AI</em>.
</p>
</section>
<!-- ===== HIGH SCORES ===== -->
<div class="section-divider">HIGH SCORES</div>
<section class="stats container reveal">
<div class="stats-grid">
<div class="stat">
<div class="stat-val">9001</div>
<div class="stat-label" data-de="Bugs vernichtet" data-en="Bugs destroyed">Bugs vernichtet</div>
</div>
<div class="stat">
<div class="stat-val">256</div>
<div class="stat-label" data-de="Deploys überlebt" data-en="Deploys survived">Deploys überlebt</div>
</div>
<div class="stat">
<div class="stat-val">1UP</div>
<div class="stat-label" data-de="Extra-Leben dank KI" data-en="Extra life thanks to AI">Extra-Leben dank KI</div>
</div>
</div>
</section>
<!-- ===== LEVELS ===== -->
<div class="section-divider">SELECT YOUR LEVEL</div>
<section class="levels container">
<h2 class="levels-title" data-de="// MISSION SELECT //" data-en="// MISSION SELECT //">// MISSION SELECT //</h2>
<div class="level reveal">
<div class="level-badge">LVL 1</div>
<div>
<div class="level-name">Data Rescue</div>
<div class="level-desc" data-de="Verschollene Daten aus den Tiefen korrupter Datenbanken bergen. Kein Byte bleibt zurück." data-en="Recovering lost data from the depths of corrupt databases. No byte left behind.">Verschollene Daten aus den Tiefen korrupter Datenbanken bergen. Kein Byte bleibt zurück.</div>
</div>
</div>
<div class="level reveal">
<div class="level-badge">LVL 2</div>
<div>
<div class="level-name">Code Crusade</div>
<div class="level-desc" data-de="Legacy-Code durchforsten, Spaghetti entwirren. Der Kreuzzug gegen technische Schulden." data-en="Scouring legacy code, untangling spaghetti. The crusade against technical debt.">Legacy-Code durchforsten, Spaghetti entwirren. Der Kreuzzug gegen technische Schulden.</div>
</div>
</div>
<div class="level reveal">
<div class="level-badge">LVL 3</div>
<div>
<div class="level-name">Bug Blaster</div>
<div class="level-desc" data-de="Bugs jagen im Pixel-Dschungel. Jeder Stacktrace ein Hinweis, jeder Fix ein Power-Up." data-en="Bug hunting in the pixel jungle. Every stacktrace a clue, every fix a power-up.">Bugs jagen im Pixel-Dschungel. Jeder Stacktrace ein Hinweis, jeder Fix ein Power-Up.</div>
</div>
</div>
<div class="level reveal">
<div class="level-badge">LVL 4</div>
<div>
<div class="level-name">Deploy Dynasty</div>
<div class="level-desc" data-de="CI/CD-Pipelines bauen, Container orchestrieren. Von der Garage ins Rechenzentrum." data-en="Building CI/CD pipelines, orchestrating containers. From the garage to the data center.">CI/CD-Pipelines bauen, Container orchestrieren. Von der Garage ins Rechenzentrum.</div>
</div>
</div>
<div class="level boss reveal">
<div class="level-badge">BOSS</div>
<div>
<div class="level-name">Production</div>
<div class="level-desc" data-de="Der finale Boss. Freitag, 17:00 Uhr. &quot;Können wir das noch schnell deployen?&quot; — Nein. Doch. Ohhh!" data-en="The final boss. Friday, 5pm. &quot;Can we quickly deploy that?&quot; — No. Yes. Ohhh!">Der finale Boss. Freitag, 17:00 Uhr. "Können wir das noch schnell deployen?" — Nein. Doch. Ohhh!</div>
</div>
</div>
</section>
<!-- ===== PIXEL ART ===== -->
<div class="pixel-art reveal">
___________
/ \
| GAME OVER |
| Continue? |
| > YES |
\___________/
</div>
<!-- ===== CTA ===== -->
<section class="cta container reveal">
<p class="cta-label" data-de="~ PLAYER 1 READY ~" data-en="~ PLAYER 1 READY ~">~ PLAYER 1 READY ~</p>
<a href="mailto:commanderkin@msbls.de" class="btn-start" data-de="Press START" data-en="Press START">Press START</a>
</section>
<!-- ===== FOOTER ===== -->
<footer class="footer">
<div class="container">
<p class="insert-coin" data-de="INSERT COIN TO CONTINUE" data-en="INSERT COIN TO CONTINUE">INSERT COIN TO CONTINUE</p>
<p class="footer-sub" data-de="&copy; 2026 CommanderKIn &mdash; Powered by Pixel &amp; KI" data-en="&copy; 2026 CommanderKIn &mdash; Powered by Pixel &amp; AI">&copy; 2026 CommanderKIn &mdash; Powered by Pixel &amp; KI</p>
<div style="text-align:center;margin-top:16px;">
<button data-i18n-toggle title="Maschinell übersetzt / Machine-translated — German is the original." style="background:none;border:1px solid #333;color:#333;font-size:0.65rem;letter-spacing:0.1em;padding:4px 12px;border-radius:4px;cursor:pointer;">EN</button>
<br><small data-de="Maschinell übersetzt" data-en="Machine-translated" style="color:#333;font-size:0.6rem;opacity:0.5;">Maschinell übersetzt</small>
</div>
</div>
</footer>
<script>
// Scroll reveal
const obs = new IntersectionObserver((entries) => {
entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });
}, { threshold: 0.15 });
document.querySelectorAll('.reveal').forEach(el => obs.observe(el));
// Konami Code Easter Egg
const konami = [38,38,40,40,37,39,37,39,66,65];
let kPos = 0;
document.addEventListener('keydown', (e) => {
if (e.keyCode === konami[kPos]) {
kPos++;
if (kPos === konami.length) {
kPos = 0;
document.body.style.animation = 'none';
document.body.offsetHeight; // reflow
document.body.style.animation = '';
alert('🕹️ CHEAT ACTIVATED: Unlimited AI Credits 🕹️');
}
} else {
kPos = 0;
}
});
</script>
<script src="/shared/ai-disclosure.js" data-tone="playful"></script>
<script src="/shared/i18n.js"></script>
</body>
</html>