Landingpage (site/) mit Screenshots und Vorschau
BIN
site-preview/desktop.png
Normal file
|
After Width: | Height: | Size: 688 KiB |
BIN
site-preview/mobile.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
site/assets/chat_dark.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
site/assets/chat_dark.webp
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
site/assets/chat_light.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
site/assets/chat_light.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
site/assets/chat_provider_dark.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
site/assets/chat_provider_dark.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
site/assets/chat_provider_light.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
site/assets/chat_provider_light.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
site/assets/icon-180.png
Normal file
|
After Width: | Height: | Size: 5 KiB |
1
site/assets/icon.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 108 108" role="img" aria-label="ByteClaw Logo"><rect width="108" height="108" rx="26" fill="#14202E"/><path fill="#1D2C3D" d="M0 27h108v1H0zM0 54h108v1H0zM0 81h108v1H0zM27 0h1v108h-1zM54 0h1v108h-1zM81 0h1v108h-1z"/><g fill="none" stroke="#FF6A3D" stroke-width="7" stroke-linecap="round"><path d="M45 33Q38 53 33 74"/><path d="M57 30Q50 53 45 78"/><path d="M69 33Q62 53 57 74"/></g><path fill="#39D3C3" d="M70 52h7v7h-7zM70 64h7v7h-7z"/><path fill="none" stroke="#39D3C3" stroke-width="1.6" d="M70.8 40.8h5.4v5.4h-5.4z"/></svg>
|
||||
|
After Width: | Height: | Size: 581 B |
BIN
site/assets/og.png
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
site/assets/providers_dark.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
site/assets/providers_dark.webp
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
site/assets/providers_light.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
site/assets/providers_light.webp
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
site/assets/sessions_dark.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
site/assets/sessions_dark.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
site/assets/sessions_light.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
site/assets/sessions_light.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
site/assets/settings_dark.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
site/assets/settings_dark.webp
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
site/assets/settings_light.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
site/assets/settings_light.webp
Normal file
|
After Width: | Height: | Size: 21 KiB |
99
site/index.html
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<!doctype html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>ByteClaw – selbst gehosteter, schlanker KI-Assistent</title>
|
||||
<meta name="description" content="ByteClaw ist ein selbst gehosteter, schlanker KI-Assistent: Go-Backend plus native Android-App. OpenAI-kompatible Anbieter, Live-Streaming, Tools, sichere Defaults.">
|
||||
<meta name="theme-color" content="#14202E">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="ByteClaw – selbst gehosteter KI-Assistent">
|
||||
<meta property="og:description" content="Go-Backend + Android-App. OpenAI, OpenRouter, Ollama, Dahl, GonkaRouter oder eigener Endpunkt.">
|
||||
<meta property="og:image" content="assets/og.png">
|
||||
<meta property="og:locale" content="de_DE">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<link rel="icon" href="assets/icon.svg" type="image/svg+xml">
|
||||
<link rel="apple-touch-icon" href="assets/icon-180.png">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header class="nav">
|
||||
<a class="brand" href="#top"><img src="assets/icon.svg" alt="" width="32" height="32">ByteClaw</a>
|
||||
<nav aria-label="Hauptnavigation">
|
||||
<a href="#features">Features</a><a href="#screens">Screenshots</a><a href="#quickstart">Quickstart</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main id="top">
|
||||
<section class="hero">
|
||||
<div class="hero-text">
|
||||
<img class="hero-icon" src="assets/icon.svg" alt="ByteClaw-Logo: drei Krallenspuren und Byte-Bits" width="112" height="112">
|
||||
<h1>ByteClaw</h1>
|
||||
<p class="claim">Selbst gehosteter, schlanker KI-Assistent – <span>Go-Backend</span> + <span>Android-App</span>.</p>
|
||||
<p class="lead">Ein einzelnes Go-Binary mit SQLite spricht mit jedem OpenAI-kompatiblen Anbieter, nutzt Tools und streamt Antworten live in die native Android-App. Deine Schlüssel bleiben auf deinem Server.</p>
|
||||
<div class="cta">
|
||||
<span class="btn btn-primary" aria-disabled="true">Bald verfügbar</span>
|
||||
<a class="btn btn-ghost" href="#quickstart">Quickstart ansehen</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-phones" aria-hidden="true">
|
||||
<div class="phone tilt-l"><picture><source srcset="assets/chat_dark.webp" type="image/webp"><img src="assets/chat_dark.png" alt="" width="450" height="1000"></picture></div>
|
||||
<div class="phone tilt-r"><picture><source srcset="assets/providers_light.webp" type="image/webp"><img src="assets/providers_light.png" alt="" width="450" height="1000"></picture></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="features" class="section">
|
||||
<h2>Was ByteClaw kann</h2>
|
||||
<div class="grid">
|
||||
<article class="card"><h3>Viele Anbieter</h3><p>Presets für OpenAI, OpenRouter, Ollama, Dahl und GonkaRouter – oder ein eigener OpenAI-kompatibler Endpunkt.</p></article>
|
||||
<article class="card"><h3>Live-Streaming</h3><p>Antworten erscheinen Wort für Wort per WebSocket in der App.</p></article>
|
||||
<article class="card"><h3>Tools</h3><p>Uhrzeit, Web-Abruf mit SSRF-Schutz, Datei-Tools im Workspace und ein optionales, streng begrenztes Shell-Tool.</p></article>
|
||||
<article class="card"><h3>Abbrechen</h3><p>Stopp-Button in der App: Der Abbruch reicht bis zum Anbieter, die Teilantwort bleibt gespeichert.</p></article>
|
||||
<article class="card"><h3>Session-Zusammenfassung</h3><p>Lange Chats werden automatisch per LLM zusammengefasst – die Originalnachrichten bleiben erhalten.</p></article>
|
||||
<article class="card"><h3>Anbieter pro Session</h3><p>Global umschalten oder für einzelne Chats ein anderes Modell wählen – direkt aus der App.</p></article>
|
||||
<article class="card"><h3>Sichere Defaults</h3><p>Token-Pflicht, nur localhost, Origin-Prüfung, TLS immer an, Keys nie in der App, Release nur HTTPS.</p></article>
|
||||
<article class="card"><h3>ARM & Termux</h3><p>Statische Builds für Linux amd64, arm64 und armv7 sowie Termux auf Android.</p></article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="screens" class="section">
|
||||
<h2>Screenshots</h2>
|
||||
<p class="sub">Android-App mit Demo-Daten, hell und dunkel.</p>
|
||||
<div class="gallery">
|
||||
<figure><div class="phone"><picture><source srcset="assets/chat_light.webp" type="image/webp"><img loading="lazy" src="assets/chat_light.png" alt="Chat mit Tool-Aufrufen und Stopp-Button, helles Design" width="450" height="1000"></picture></div><figcaption>Chat mit Tools & Stopp</figcaption></figure>
|
||||
<figure><div class="phone"><picture><source srcset="assets/chat_provider_dark.webp" type="image/webp"><img loading="lazy" src="assets/chat_provider_dark.png" alt="Chat mit Anbieter-Auswahl pro Session im Header, dunkles Design" width="450" height="1000"></picture></div><figcaption>Anbieter pro Session</figcaption></figure>
|
||||
<figure><div class="phone"><picture><source srcset="assets/providers_dark.webp" type="image/webp"><img loading="lazy" src="assets/providers_dark.png" alt="Einstellungen mit Anbieter- und Modellauswahl, dunkles Design" width="450" height="1000"></picture></div><figcaption>Anbieter & Modell</figcaption></figure>
|
||||
<figure><div class="phone"><picture><source srcset="assets/sessions_light.webp" type="image/webp"><img loading="lazy" src="assets/sessions_light.png" alt="Liste der Sessions, helles Design" width="450" height="1000"></picture></div><figcaption>Sessions</figcaption></figure>
|
||||
<figure><div class="phone"><picture><source srcset="assets/settings_light.webp" type="image/webp"><img loading="lazy" src="assets/settings_light.png" alt="Einstellungen mit Server-URL und Token, helles Design" width="450" height="1000"></picture></div><figcaption>Verbindung</figcaption></figure>
|
||||
<figure><div class="phone"><picture><source srcset="assets/chat_dark.webp" type="image/webp"><img loading="lazy" src="assets/chat_dark.png" alt="Chat, dunkles Design" width="450" height="1000"></picture></div><figcaption>Dunkles Design</figcaption></figure>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="quickstart" class="section">
|
||||
<h2>Quickstart</h2>
|
||||
<p class="sub">Backend starten (Go 1.25), dann in der App Server-URL und Token eintragen.</p>
|
||||
<div class="code">
|
||||
<button class="copy" type="button" data-copy="qs">Kopieren</button>
|
||||
<pre id="qs"><code>cp config.example.yaml config.yaml
|
||||
export BYTECLAW_AUTH_TOKEN=$(openssl rand -hex 32)
|
||||
export BYTECLAW_LLM_PROVIDER=dahl # openai | openrouter | ollama | dahl | gonkarouter | custom
|
||||
export DAHL_API_KEY=... # Key bleibt auf dem Server
|
||||
make run
|
||||
|
||||
curl -H "Authorization: Bearer $BYTECLAW_AUTH_TOKEN" \
|
||||
-d '{"text":"Wie spät ist es in Berlin?"}' localhost:8787/api/chat</code></pre>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<p><img src="assets/icon.svg" alt="" width="20" height="20"> ByteClaw · selbst gehostet, Go + Android</p>
|
||||
<p class="muted">Screenshots zeigen Demo-Daten. Download folgt.</p>
|
||||
</footer>
|
||||
<script>
|
||||
document.querySelectorAll('[data-copy]').forEach(b=>b.addEventListener('click',()=>{
|
||||
navigator.clipboard?.writeText(document.getElementById(b.dataset.copy).innerText).then(()=>{b.textContent='Kopiert';setTimeout(()=>b.textContent='Kopieren',1500)});
|
||||
}));
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
55
site/style.css
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
:root{--ink:#14202E;--ink2:#1B2A3B;--ink3:#24364A;--claw:#FF6A3D;--byte:#39D3C3;--text:#E8EEF5;--muted:#9AABBE;--r:18px}
|
||||
*{box-sizing:border-box}
|
||||
html{scroll-behavior:smooth}
|
||||
body{margin:0;background:var(--ink);color:var(--text);font:16px/1.6 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}
|
||||
a{color:var(--byte)}
|
||||
img{max-width:100%;height:auto;display:block}
|
||||
.nav{position:sticky;top:0;z-index:5;display:flex;justify-content:space-between;align-items:center;padding:14px clamp(16px,4vw,48px);background:rgba(20,32,46,.85);backdrop-filter:blur(8px);border-bottom:1px solid var(--ink3)}
|
||||
.brand{display:flex;gap:10px;align-items:center;color:var(--text);text-decoration:none;font-weight:700;font-size:1.1rem}
|
||||
.nav nav a{color:var(--muted);text-decoration:none;margin-left:22px;font-size:.95rem}
|
||||
.nav nav a:hover{color:var(--text)}
|
||||
.hero{display:grid;grid-template-columns:1.1fr 1fr;gap:40px;align-items:center;max-width:1200px;margin:0 auto;padding:clamp(40px,8vw,96px) clamp(16px,4vw,48px)}
|
||||
.hero-icon{border-radius:28px;box-shadow:0 10px 40px rgba(255,106,61,.25)}
|
||||
h1{font-size:clamp(2.6rem,6vw,4.2rem);line-height:1.05;margin:22px 0 10px;letter-spacing:-.02em}
|
||||
.claim{font-size:clamp(1.15rem,2.2vw,1.45rem);margin:0 0 16px;font-weight:600}
|
||||
.claim span{color:var(--claw)}
|
||||
.lead{color:var(--muted);max-width:560px;margin:0 0 28px}
|
||||
.cta{display:flex;gap:12px;flex-wrap:wrap}
|
||||
.btn{display:inline-block;padding:12px 22px;border-radius:999px;font-weight:600;text-decoration:none}
|
||||
.btn-primary{background:var(--claw);color:#2a0a00;cursor:default;opacity:.95}
|
||||
.btn-ghost{border:1px solid var(--ink3);color:var(--text)}
|
||||
.btn-ghost:hover{border-color:var(--byte)}
|
||||
.hero-phones{position:relative;display:flex;justify-content:center;gap:0;min-height:420px}
|
||||
.hero-phones .phone{width:min(46%,240px)}
|
||||
.tilt-l{transform:rotate(-6deg) translateY(10px);z-index:1}
|
||||
.tilt-r{transform:rotate(5deg) translate(-18px,-14px)}
|
||||
.phone{background:#0b1118;border-radius:34px;padding:10px;box-shadow:0 0 0 2px var(--ink3),0 24px 60px rgba(0,0,0,.45);position:relative}
|
||||
.phone::before{content:"";position:absolute;top:16px;left:50%;width:12px;height:12px;margin-left:-6px;border-radius:50%;background:#000;box-shadow:0 0 0 2px #1d2733;z-index:2}
|
||||
.phone img{border-radius:26px;width:100%}
|
||||
.section{max-width:1200px;margin:0 auto;padding:clamp(40px,6vw,80px) clamp(16px,4vw,48px)}
|
||||
h2{font-size:clamp(1.7rem,3.4vw,2.4rem);margin:0 0 8px}
|
||||
h2::after{content:"";display:block;width:56px;height:4px;border-radius:2px;margin-top:10px;background:linear-gradient(90deg,var(--claw),var(--byte))}
|
||||
.sub{color:var(--muted);margin:12px 0 28px}
|
||||
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:18px;margin-top:28px}
|
||||
.card{background:var(--ink2);border:1px solid var(--ink3);border-radius:var(--r);padding:22px}
|
||||
.card h3{margin:0 0 6px;font-size:1.1rem;color:var(--byte)}
|
||||
.card p{margin:0;color:var(--muted)}
|
||||
.gallery{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:28px}
|
||||
.gallery figure{margin:0}
|
||||
.gallery figcaption{text-align:center;color:var(--muted);margin-top:12px;font-size:.95rem}
|
||||
.code{position:relative;background:#0b1118;border:1px solid var(--ink3);border-radius:var(--r)}
|
||||
.code pre{margin:0;padding:22px;overflow-x:auto;font:14px/1.6 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:#cfe3f2}
|
||||
.copy{position:absolute;top:10px;right:10px;background:var(--ink3);color:var(--text);border:0;border-radius:8px;padding:6px 12px;cursor:pointer;font:inherit;font-size:.85rem}
|
||||
.footer{border-top:1px solid var(--ink3);text-align:center;padding:32px 16px;color:var(--text)}
|
||||
.footer p{margin:4px 0;display:flex;gap:8px;justify-content:center;align-items:center}
|
||||
.muted{color:var(--muted);font-size:.9rem}
|
||||
@media (max-width:860px){
|
||||
.hero{grid-template-columns:1fr;text-align:center}
|
||||
.hero-icon{margin:0 auto}
|
||||
.lead{margin-left:auto;margin-right:auto}
|
||||
.cta{justify-content:center}
|
||||
.hero-phones{min-height:0}
|
||||
.nav nav a{margin-left:14px}
|
||||
}
|
||||
@media (max-width:420px){.nav nav{display:none}.gallery{grid-template-columns:1fr 1fr;gap:14px}.phone{border-radius:24px;padding:6px}.phone img{border-radius:19px}.phone::before{display:none}}
|
||||
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
|
||||