);
}
function PageShell({ route, onNav, children }) {
return (
{children}
);
}
function PageHero({ eyebrow, title, sub, children }) {
return (
{eyebrow &&
{eyebrow}
}
{title}
{sub &&
{sub}
}
{children}
);
}
/* ============================================================
STATUS PAGE
============================================================ */
// Everything on this page comes from /app/api/status.php — the live per-service probes plus the
// incidents and monitoring coverage that status-monitor.php records every 5 minutes. Nothing is
// hardcoded. The previous version shipped a fixed service list, three invented incidents, a
// literal "99.98%" and uptime bars drawn from a seeded RNG, so it reported "All systems
// operational" straight through a multi-day outage.
const STATUS_API = "/app/api/status.php";
const STATUS_META = {
operational: { label: "Operational", cls: "ok" },
degraded: { label: "Degraded performance", cls: "warn" },
outage: { label: "Outage", cls: "bad" },
};
function statusTone(v) {
if (v === "outage") return "oklch(0.65 0.20 25)";
if (v === "degraded") return "oklch(0.82 0.15 75)";
if (v === "nodata") return "var(--ink-2)";
return "color-mix(in oklch, var(--accent) 70%, transparent)";
}
function fmtDuration(secs) {
if (secs == null) return "";
const s = Math.max(0, secs | 0);
if (s < 60) return s + "s";
if (s < 3600) return Math.round(s / 60) + "m";
if (s < 86400) return (s / 3600).toFixed(1).replace(/\.0$/, "") + "h";
return (s / 86400).toFixed(1).replace(/\.0$/, "") + "d";
}
function fmtWhen(iso) {
if (!iso) return "";
const d = new Date(String(iso).replace(" ", "T"));
if (isNaN(d)) return String(iso);
return d.toLocaleString(undefined, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
}
// One bar per day. A day the monitor never ran renders as "no data" instead of green — claiming
// uptime for a window nobody measured is exactly the lie this page used to tell.
function UptimeBars({ marks, days }) {
const ticks = Array.isArray(marks) ? marks : [];
if (!ticks.length) {
return
{err && !data
? `Could not reach the status service (${err})`
: data
? `Updated ${age < 5 ? "just now" : age + "s ago"} · auto-refreshes every 60s`
: "Contacting the status service…"}
{ongoing
? `Detected by automated monitoring; ongoing for ${fmtDuration(inc.duration_secs)}.`
: `Detected by automated monitoring. Lasted ${fmtDuration(inc.duration_secs)}, resolved ${fmtWhen(inc.resolved_at)}.`}
{fmtWhen(inc.started_at)}
);
})}
);
}
/* ============================================================
CHANGELOG PAGE
============================================================ */
const TAG_STYLE = {
New: { bg: "color-mix(in oklch, var(--accent) 16%, transparent)", fg: "var(--accent)", bd: "color-mix(in oklch, var(--accent) 34%, transparent)" },
Improved: { bg: "color-mix(in oklch, oklch(0.7 0.13 250) 18%, transparent)", fg: "oklch(0.8 0.12 250)", bd: "color-mix(in oklch, oklch(0.7 0.13 250) 36%, transparent)" },
Fixed: { bg: "color-mix(in oklch, oklch(0.8 0.14 75) 16%, transparent)", fg: "oklch(0.84 0.14 75)", bd: "color-mix(in oklch, oklch(0.8 0.14 75) 34%, transparent)" },
};
function Tag({ kind }) {
const s = TAG_STYLE[kind] || TAG_STYLE.New;
return {kind};
}
const RELEASES = [
{ v: "2.0.0", date: "June 6, 2026", title: "KVB 2.0 — the rebuild", featured: true,
items: [["New", "Brand-new dashboard with live charts for every bot"], ["New", "AI Chatbot, Poll Bot & Clip Viewbot added to the toolkit"], ["New", "Auto-Start Slots — bots launch the moment you go live"], ["Improved", "Server-sided engine now sustains 5,000 concurrent viewers"], ["Improved", "Connect times cut by ~20% with the new routing layer"]] },
{ v: "1.9.0", date: "May 18, 2026", title: "Smarter chat & routing",
items: [["New", "Personality presets for the Chat Bot (Hype, Casual, Support)"], ["Improved", "Region routing for viewers (NA / EU / Asia)"], ["Fixed", "Rare disconnect when switching channels mid-session"]] },
{ v: "1.8.0", date: "April 29, 2026", title: "Follow Bot overhaul",
items: [["New", "Natural drip pacing so growth never looks artificial"], ["New", "Follower milestone tracking"], ["Fixed", "Credits occasionally double-counting on annual plans"]] },
{ v: "1.7.0", date: "April 2, 2026", title: "Performance pass",
items: [["Improved", "0% local CPU usage — fully server-sided delivery"], ["Improved", "Dashboard loads ~2× faster"], ["Fixed", "Dark-mode contrast issues on the billing page"]] },
];
function ChangelogPage({ onNav }) {
return (
Changelog>} title="What's new in KVB"
sub="Every improvement we ship, in one place. We update KVB every week to stay ahead of the curve." />
{RELEASES.map((rel, i) => (
v{rel.v}
{rel.featured && }
{rel.date}
{rel.title}
{rel.items.map(([k, txt], j) => (
{txt}
))}
))}
);
}
/* ============================================================
DISCORD PAGE
============================================================ */
const DISCORD_PERKS = [
["headset", "24/7 live support", "Get help from our team and community any hour of the day — most questions answered in minutes."],
["trophy", "Giveaways & drops", "Free credits, plan upgrades and viewer boosts dropped regularly for active members."],
["zap", "Early access", "Be first to try new bots and features before they hit everyone else."],
["star", "Holiday discounts", "Exclusive promo codes around Christmas, Halloween and every major holiday."],
["users", "Creator network", "Connect with thousands of streamers growing their channels with KVB."],
["bolt", "Status & updates", "Instant notifications for new releases, maintenance and incident updates."],
];
const DISCORD_CHANNELS = [
["announcements", "New drops & release notes"],
["support", "Get help fast"],
["giveaways", "Free credits & boosts"],
["general", "Hang with the community"],
];
function DiscordPage({ onNav }) {
return (
18,400+ members · 2,140 online
Join the KVB community
Support, giveaways, early access and thousands of streamers leveling up together. The fastest way to get help — and free stuff.
Free to join. Jump in, say hi, and grab your first giveaway.
);
}
/* ============================================================
ABOUT PAGE
============================================================ */
const ABOUT_VALUES = [
["zap", "Speed over everything", "Viewers in seconds, weekly updates, support that replies in minutes. We move at the pace creators do."],
["shield", "Built to stay invisible", "Anti-fingerprint routing and AES-256 from day one. Your growth should never look — or feel — artificial."],
["heart", "Creator-first pricing", "Plans designed so everyone can afford to grow, from first-time streamers to full-time pros."],
["gauge", "Zero compromise", "0% local CPU, 99.98% uptime, 5,000 concurrent. Premium performance, no asterisks."],
];
function AboutPage({ onNav }) {
return (
About KVB>}
title={<>We help creators fill the room.>}
sub="KVB started with one frustration: growing a stream is brutally hard, and the tools that promised to help were slow, sketchy, and overpriced. So we built the opposite." />
Every creator deserves a fighting chance at being seen. KVB gives you the momentum to get discovered — real-time viewers, smart chat, and a toolkit that runs itself — so you can focus on what you do best: streaming.
The story
From a frustration to a platform.
We were streamers ourselves, tired of tools that lagged our PCs and risked our channels. KVB is what we wished existed: server-sided, undetectable, affordable, and genuinely fast. Today it's trusted by tens of thousands of creators worldwide.
What we stand for
Principles we ship by.
{ABOUT_VALUES.map(([ic, t, d], i) => (
{t}
{d}
))}
Ready to grow with us?
Start free — no card required. Be live with viewers in under a minute.