Files
uncloud/website/landing/hub.html
T
2026-06-07 20:24:27 +02:00

717 lines
51 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Uncloud Hub | Hosted dashboard and observability for Uncloud</title>
<meta name="description"
content="Uncloud Hub is the UI and hosted Grafana stack for your Uncloud clusters. Get metrics, logs, and alerts out of the box to catch issues early and fix faster.">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="./style.css" rel="stylesheet">
<link rel="apple-touch-icon" href="./images/apple-touch-icon.png" sizes="180x180"/>
<link rel="icon" type="image/svg+xml" href="./images/logo.svg"/>
<link rel="alternate icon" type="image/png" href="./images/favicon.png" sizes="96x96"/>
<!-- OpenGraph tags for social media -->
<meta property="og:title"
content="Uncloud Hub | Hosted dashboard and observability for Uncloud"/>
<meta property="og:description"
content="Uncloud Hub is the UI and hosted Grafana stack for your Uncloud clusters. Get metrics, logs, and alerts out of the box to catch issues early and fix faster."/>
<meta property="og:image" content="https://uncloud.run/images/logo-wide.png"/>
<meta property="og:image:alt" content="Uncloud Hub - Observability for self-hosted apps"/>
<meta property="og:url" content="https://uncloud.run/hub"/>
<meta property="og:type" content="website"/>
<meta property="og:site_name" content="Uncloud"/>
<!-- Twitter card tags -->
<meta property="twitter:domain" content="uncloud.run">
<meta property="twitter:url" content="https://uncloud.run/hub">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title"
content="Uncloud Hub | Hosted dashboard and observability for Uncloud">
<meta name="twitter:description"
content="Uncloud Hub is the UI and hosted Grafana stack for your Uncloud clusters. Get metrics, logs, and alerts out of the box to catch issues early and fix faster.">
<meta name="twitter:image" content="https://uncloud.run/images/logo-wide.png">
<meta name="twitter:image:alt" content="Uncloud Hub - Observability for self-hosted apps">
<style>
/* Prevent all inline SVGs from appearing full screen. */
svg {
max-width: 24px;
max-height: 24px;
}
/* Feature cards */
.hub-feature-card {
padding: 1.5rem;
border: 1px solid #e4e4e7;
border-radius: 0.75rem;
background: #fff;
transition: box-shadow 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
display: flex;
flex-direction: column;
}
.hub-feature-card:hover {
box-shadow: 0 8px 32px -8px rgba(0,0,0,0.12);
border-color: #a1a1aa;
transform: translateY(-2px);
}
.hub-feature-icon {
width: 2.5rem;
height: 2.5rem;
border-radius: 0.5rem;
background: #f5f3ff;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1rem;
flex-shrink: 0;
}
.hub-feature-grid {
display: grid;
gap: 1.25rem;
max-width: 56rem;
margin: 0 auto;
}
@media (min-width: 768px) {
.hub-feature-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>
</head>
<body class="font-inter antialiased bg-white text-zinc-900 tracking-tight">
<!-- Page wrapper -->
<div class="flex flex-col min-h-screen overflow-hidden supports-[overflow:clip]:overflow-clip">
<!-- Site header -->
<header class="absolute top-2 md:top-6 w-full z-30">
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<div class="flex items-center justify-between h-14">
<!-- Site branding -->
<div class="shrink-0 mr-4">
<a class="flex items-center" href="/">
<img class="w-8 h-8 rounded-lg shadow-sm shadow-zinc-950/20" src="./images/logo.svg" alt="Logo"
width="32" height="32">
<span class="ml-2 font-semibold text-lg text-zinc-900">uncloud</span>
</a>
</div>
<!-- Navigation links -->
<nav class="flex grow">
<!-- Left side navigation -->
<ul class="flex items-center">
<li>
<a class="text-sm font-medium text-zinc-500 hover:text-zinc-900 px-2 sm:px-5 py-2 transition inline-flex items-center"
href="/hub">
Hub
<span class="ml-1.5 text-[10px] font-semibold uppercase tracking-wide text-emerald-700 bg-emerald-100 px-1.5 py-0.5 rounded">
New
</span>
</a>
</li>
<li>
<a class="text-sm font-medium text-zinc-500 hover:text-zinc-900 px-2 sm:px-5 py-2 transition"
href="/docs">Docs</a>
</li>
<li>
<a class="text-sm font-medium text-zinc-500 hover:text-zinc-900 px-2 sm:px-5 py-2 transition"
href="/blog">Blog</a>
</li>
<li>
<a class="text-sm font-medium text-zinc-500 hover:text-zinc-900 px-2 sm:px-5 py-2 transition"
href="https://psviderski.substack.com/" target="_blank">Newsletter</a>
</li>
</ul>
<!-- Right side navigation -->
<ul class="flex grow justify-end items-center shrink-0">
<li>
<a class="text-sm font-medium text-zinc-500 hover:text-zinc-900 px-2 sm:px-5 py-2 flex items-center transition"
href="https://discord.gg/eR35KQJhPu">
<svg class="w-4 h-4 sm:mr-1 fill-current" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24">
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/>
</svg>
<span class="ml-1 hidden sm:inline">Discord</span>
</a>
</li>
<li>
<a class="text-sm font-medium text-zinc-500 hover:text-zinc-900 px-1 sm:px-5 py-2 flex items-center transition"
href="https://github.com/psviderski/uncloud">
<svg class="w-4 h-4 sm:mr-1 fill-current" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24">
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
</svg>
<span class="ml-1 hidden sm:inline">GitHub</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</header>
<!-- Page content -->
<main class="grow">
<!-- Hero -->
<section
class="relative before:absolute before:inset-0 before:h-80 before:pointer-events-none before:bg-gradient-to-b before:from-zinc-100 before:-z-10">
<div class="pt-32 pb-12 md:pt-40 md:pb-20">
<!-- Section content -->
<div class="px-4 sm:px-6">
<div class="max-w-3xl mx-auto">
<div class="text-center pb-12 md:pb-16">
<!-- Eyebrow -->
<div class="inline-flex items-center text-base font-semibold text-violet-700 px-5 py-1.5 mb-6 border border-transparent rounded-full [background:linear-gradient(theme(colors.violet.50),theme(colors.violet.50))_padding-box,linear-gradient(120deg,theme(colors.violet.400),theme(colors.purple.300),theme(colors.violet.400))_border-box]">
<span class="relative flex w-2 h-2 mr-2.5">
<span class="absolute inline-flex w-full h-full rounded-full bg-violet-500 opacity-75 animate-ping"></span>
<span class="relative inline-flex w-2 h-2 rounded-full bg-violet-500"></span>
</span>
Coming soon
</div>
<h1 class="font-inter-tight text-4xl md:text-5xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-zinc-500 via-zinc-900 to-zinc-900 pb-4">
Uncloud <span class="text-violet-600">Hub</span>:<br>
See what's happening in production
</h1>
<p class="text-lg text-zinc-500 mb-8">
<b>Uncloud Hub</b> is the command center for your Uncloud clusters.<br>
Get real-time metrics, logs, and alerts out of the box to catch issues early and fix
faster.
</p>
<div class="max-w-xs mx-auto sm:max-w-none sm:inline-flex sm:justify-center space-y-4 sm:space-y-0 sm:space-x-4">
<div>
<a class="btn text-zinc-100 bg-zinc-900 hover:bg-zinc-800 w-full shadow"
href="#feedback">
Get early access
</a>
</div>
<div>
<a class="btn text-zinc-600 bg-white hover:text-zinc-900 w-full shadow flex items-center justify-center"
href="#how-it-works">
How it works
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Hero image -->
<div class="max-w-6xl mx-auto px-4 sm:px-6 flex justify-center pb-12 md:pb-20 relative before:absolute before:-top-12 before:w-96 before:h-96 before:bg-zinc-900 before:opacity-[.15] before:rounded-full before:blur-3xl before:-z-10">
<img class="rounded-lg shadow-2xl" src="./images/hub-hero.webp" width="2560" height="1520"
alt="Uncloud Hub services dashboard, design preview">
</div>
<!-- Trust / stats -->
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<p class="text-center text-base text-zinc-500 mb-8">
Hub is built for Uncloud, the open-source orchestrator that runs your apps across machines.
</p>
<div class="max-w-sm mx-auto grid gap-12 sm:grid-cols-2 md:grid-cols-4 md:-mx-5 md:gap-0 items-start md:max-w-none">
<!-- GitHub stars -->
<a href="https://github.com/psviderski/uncloud" target="_blank" rel="noopener"
class="group block relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden">
<h4 class="font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2"><span x-data="counter(5.2)" x-text="counterValue">0</span>K+</h4>
<p class="text-sm text-zinc-500 transition-colors group-hover:text-zinc-800">GitHub stars</p>
</a>
<!-- Downloads -->
<a href="https://github.com/psviderski/uncloud/releases" target="_blank" rel="noopener"
class="group block relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden">
<h4 class="font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2"><span x-data="counter(19)" x-text="counterValue">0</span>K+</h4>
<p class="text-sm text-zinc-500 transition-colors group-hover:text-zinc-800">Downloads</p>
</a>
<!-- Hacker News front-page -->
<a href="https://news.ycombinator.com/item?id=46144275" target="_blank" rel="noopener"
class="group block relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden">
<h4 class="font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2"><span x-data="counter(2)" x-text="counterValue">0</span>x</h4>
<p class="text-sm text-zinc-500 transition-colors group-hover:text-zinc-800">Hacker News front page</p>
</a>
<!-- Discord members. -->
<a href="https://uncloud.run/discord" target="_blank" rel="noopener"
class="group block relative text-center md:px-5 after:hidden md:after:block after:absolute after:right-0 after:top-1/2 after:-translate-y-1/2 after:w-px after:h-8 after:border-l after:border-zinc-300 after:border-dashed last:after:hidden">
<h4 class="font-inter-tight text-2xl md:text-3xl font-bold tabular-nums mb-2"><span x-data="counter(368)" x-text="counterValue">0</span></h4>
<p class="text-sm text-zinc-500 transition-colors group-hover:text-zinc-800">Fans on Discord</p>
</a>
</div>
<!-- Animate counter functionality: https://github.com/alpinejs/alpine -->
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('counter', (target = 0, duration = 3000) => ({
startTimestamp: null,
step: null,
rawValue: 0,
counterValue: 0,
target: target,
precision: (target % 1 === 0) ? 0 : (target.toString().split('.')[1] || []).length,
animationRequestId: null,
animationCompleted: false,
observer: null,
init() {
// Intersection observer to watch visibility.
this.observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
// Check if element is in view.
if (entry.isIntersecting && !this.animationCompleted) {
this.startAnimation()
}
})
})
this.observer.observe(this.$el)
},
startAnimation() {
this.step = (timestamp) => {
if (!this.startTimestamp) this.startTimestamp = timestamp
const progress = Math.min((timestamp - this.startTimestamp) / duration, 1)
const easedProgress = this.easeOut(progress)
this.rawValue = parseFloat((easedProgress * this.target).toFixed(this.precision))
this.counterValue = this.rawValue.toFixed(this.precision)
if (progress < 1) {
this.animationRequestId = window.requestAnimationFrame(this.step)
} else {
this.animationCompleted = true
}
}
this.animationRequestId = window.requestAnimationFrame(this.step);
},
easeOut(t) {
return 1 - Math.pow(1 - t, 5)
},
destroy() {
// Detach the handler to avoid memory and side-effect leakage.
this.animationRequestId && window.cancelAnimationFrame(this.step)
this.observer && this.observer.disconnect()
},
}))
})
</script>
</div>
</div>
</section>
<!-- Day 2 problem: the long part of running an app. -->
<section class="relative bg-zinc-50">
<div class="py-12 md:py-20">
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<!-- Section heading -->
<div class="max-w-3xl mx-auto text-center pb-12 md:pb-16">
<h2 class="font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4">
Your app is deployed. Now what?
</h2>
<p class="text-lg text-zinc-500">
Deploying is the easy part. Everything after is where most teams get stuck.
</p>
</div>
<!-- Day-2 checklist: setup done, observability still open. -->
<div class="max-w-3xl mx-auto">
<div class="relative pb-10">
<ul class="space-y-4">
<!-- Setup steps: done. -->
<li class="flex items-center gap-3">
<span class="w-8 h-8 rounded-full bg-emerald-100 border border-emerald-300 flex items-center justify-center shrink-0" aria-hidden="true">
<svg class="w-4 h-4 text-emerald-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
</span>
<span class="text-lg text-zinc-700">Machines provisioned</span>
</li>
<li class="flex items-center gap-3">
<span class="w-8 h-8 rounded-full bg-emerald-100 border border-emerald-300 flex items-center justify-center shrink-0" aria-hidden="true">
<svg class="w-4 h-4 text-emerald-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
</span>
<span class="text-lg text-zinc-700">App deployed — <code class="font-mono text-base text-zinc-900">uc deploy</code></span>
</li>
<li class="flex items-center gap-3">
<span class="w-8 h-8 rounded-full bg-emerald-100 border border-emerald-300 flex items-center justify-center shrink-0" aria-hidden="true">
<svg class="w-4 h-4 text-emerald-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"/></svg>
</span>
<span class="text-lg text-zinc-700">HTTPS and custom domain</span>
</li>
<!-- Divider -->
<li class="pt-2 pb-1" aria-hidden="true"><hr class="border-dashed border-zinc-200"></li>
<!-- Day-2 operations: still open. -->
<li class="flex items-center gap-3">
<span class="w-8 h-8 rounded-full border-2 border-dashed border-zinc-400 flex items-center justify-center shrink-0 text-sm font-bold text-zinc-500 leading-none" aria-hidden="true">?</span>
<span class="text-lg text-zinc-500">Services healthy right now?</span>
</li>
<li class="flex items-center gap-3">
<span class="w-8 h-8 rounded-full border-2 border-dashed border-zinc-400 flex items-center justify-center shrink-0 text-sm font-bold text-zinc-500 leading-none" aria-hidden="true">?</span>
<span class="text-lg text-zinc-500">Logs you can search when something breaks?</span>
</li>
<li class="flex items-center gap-3">
<span class="w-8 h-8 rounded-full border-2 border-dashed border-zinc-400 flex items-center justify-center shrink-0 text-sm font-bold text-zinc-500 leading-none" aria-hidden="true">?</span>
<span class="text-lg text-zinc-500">Alerts before users notice?</span>
</li>
<li class="flex items-center gap-3">
<span class="w-8 h-8 rounded-full border-2 border-dashed border-zinc-400 flex items-center justify-center shrink-0 text-sm font-bold text-zinc-500 leading-none" aria-hidden="true">?</span>
<span class="text-lg text-zinc-500">Which deploy caused that error spike?</span>
</li>
<li class="flex items-center gap-3">
<span class="w-8 h-8 rounded-full border-2 border-dashed border-zinc-400 flex items-center justify-center shrink-0 text-sm font-bold text-zinc-500 leading-none" aria-hidden="true">?</span>
<span class="text-lg text-zinc-500">Memory or CPU creeping up overnight?</span>
</li>
</ul>
<!-- Arrow pointing into the next section. -->
<span class="absolute left-1/2 -bottom-1 -translate-x-1/2 translate-y-full" aria-hidden="true">
<svg width="10" height="10" viewBox="0 0 10 10" class="block fill-zinc-300">
<path d="M5 10 0 0 H10 Z"/>
</svg>
</span>
</div>
</div>
</div>
</div>
</section>
<!-- Dashboard overview: what Hub shows you. -->
<section class="relative bg-white">
<div class="py-12 md:py-20">
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<div class="max-w-3xl mx-auto text-center pb-12 md:pb-16">
<h2 class="font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4">Your cluster, at a glance</h2>
<p class="text-lg text-zinc-500">Hub provides you with a comprehensive view of your cluster's health and activity.</p>
</div>
<div style="display:grid;grid-template-columns:2fr 4.5fr;gap:4rem;align-items:center;max-width:72rem;margin:0 auto;">
<!-- Left: feature list -->
<div style="display:flex;flex-direction:column;gap:2rem;">
<div style="display:flex;align-items:flex-start;gap:1rem;">
<div style="width:2.75rem;height:2.75rem;border-radius:0.75rem;background:#f3e8ff;display:flex;align-items:center;justify-content:center;flex-shrink:0;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="max-width:20px;max-height:20px;">
<rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/>
</svg>
</div>
<div>
<p style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:1rem;color:#18181b;margin:0 0 0.3rem;">Services</p>
<p style="font-size:0.875rem;color:#71717a;line-height:1.6;margin:0;">See what's running, where it's deployed, and whether it's healthy - across every machine.</p>
</div>
</div>
<div style="display:flex;align-items:flex-start;gap:1rem;">
<div style="width:2.75rem;height:2.75rem;border-radius:0.75rem;background:#f3e8ff;display:flex;align-items:center;justify-content:center;flex-shrink:0;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="max-width:20px;max-height:20px;">
<rect x="2" y="2" width="20" height="8" rx="2"/><rect x="2" y="14" width="20" height="8" rx="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/>
</svg>
</div>
<div>
<p style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:1rem;color:#18181b;margin:0 0 0.3rem;">Machines</p>
<p style="font-size:0.875rem;color:#71717a;line-height:1.6;margin:0;">See all nodes, their status, and what's running on each one. No terminal required.</p>
</div>
</div>
<div style="display:flex;align-items:flex-start;gap:1rem;">
<div style="width:2.75rem;height:2.75rem;border-radius:0.75rem;background:#f3e8ff;display:flex;align-items:center;justify-content:center;flex-shrink:0;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="max-width:20px;max-height:20px;">
<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="4"/><line x1="4.93" y1="4.93" x2="9.17" y2="9.17"/><line x1="14.83" y1="14.83" x2="19.07" y2="19.07"/><line x1="14.83" y1="9.17" x2="19.07" y2="4.93"/><line x1="4.93" y1="19.07" x2="9.17" y2="14.83"/>
</svg>
</div>
<div>
<p style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:1rem;color:#18181b;margin:0 0 0.3rem;">Clusters</p>
<p style="font-size:0.875rem;color:#71717a;line-height:1.6;margin:0;">Manage multiple clusters from one place. Switch context without touching a config file.</p>
</div>
</div>
</div>
<!-- Right: dashboard screenshot -->
<div>
<div style="border-radius:1rem;overflow:hidden;border:1px solid #e4e4e7;">
<img src="images/dashboard-machines.png" alt="Hub cluster dashboard" style="width:100%;display:block;">
</div>
<p style="font-size:0.75rem;font-weight:600;color:#ef4444;text-align:center;margin:0.5rem 0 0;letter-spacing:0.05em;">PLACEHOLDER IMAGE</p>
</div>
</div>
</div>
</div>
</section>
<section class="relative bg-white text-zinc-800">
<div class="py-12 md:py-20">
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<div class="max-w-3xl mx-auto text-center pb-12 md:pb-16">
<h2 class="font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4">
Untangle the observability mess and start monitoring instantly
</h2>
<p class="text-lg text-zinc-500">
Hub provides a hosted Grafana stack that knows about your Uncloud apps.
</p>
</div>
<!-- Feature blocks: 2x2 grid -->
<div class="hub-feature-grid">
<!-- HTTP request metrics -->
<div class="hub-feature-card">
<div class="hub-feature-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="max-width:18px;max-height:18px;">
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
</svg>
</div>
<h3 style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:1.0625rem;color:#18181b;margin-bottom:0.5rem;letter-spacing:-0.017em;">HTTP request metrics</h3>
<p style="font-size:0.875rem;color:#71717a;line-height:1.65;">Response times, error rates, and traffic patterns from every service. Caddy is already collecting this. Hub just shows it to you.</p>
</div>
<!-- Container logs -->
<div class="hub-feature-card">
<div class="hub-feature-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="max-width:18px;max-height:18px;">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="16" y1="13" x2="8" y2="13"/>
<line x1="16" y1="17" x2="8" y2="17"/>
</svg>
</div>
<h3 style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:1.0625rem;color:#18181b;margin-bottom:0.5rem;letter-spacing:-0.017em;">Container logs, always searchable</h3>
<p style="font-size:0.875rem;color:#71717a;line-height:1.65;">Filter by service, level, or time range. Jump from an anomaly in your metrics straight to the logs from that exact window.</p>
</div>
<!-- Slow Postgres queries -->
<div class="hub-feature-card">
<div class="hub-feature-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="max-width:18px;max-height:18px;">
<ellipse cx="12" cy="5" rx="9" ry="3"/>
<path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/>
<path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/>
</svg>
</div>
<h3 style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:1.0625rem;color:#18181b;margin-bottom:0.5rem;letter-spacing:-0.017em;">Slow Postgres queries</h3>
<p style="font-size:0.875rem;color:#71717a;line-height:1.65;">Find which queries are dragging down response times. Sorted by impact so you know where to look first, not a wall of query logs.</p>
</div>
<!-- Alerts -->
<div class="hub-feature-card">
<div class="hub-feature-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="max-width:18px;max-height:18px;">
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/>
<path d="M13.73 21a2 2 0 0 1-3.46 0"/>
</svg>
</div>
<h3 style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:1.0625rem;color:#18181b;margin-bottom:0.5rem;letter-spacing:-0.017em;">Alerts on what actually affects users</h3>
<p style="font-size:0.875rem;color:#71717a;line-height:1.65;">Get notified when error rates spike or latency climbs past your threshold. Know before a user reports it. Not after.</p>
</div>
</div>
</div>
</div>
</section>
<!-- Roadmap -->
<section class="relative bg-zinc-50">
<div class="py-12 md:py-20">
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<div class="max-w-2xl mx-auto">
<div class="text-center pb-10 md:pb-14">
<h2 class="font-inter-tight text-3xl md:text-4xl font-bold text-zinc-900 mb-4">What's next for Uncloud Hub</h2>
<p class="text-lg text-zinc-500">Upcoming features to make Hub even more useful</p>
</div>
<ul style="list-style:none;padding:0;margin:0;">
<li style="padding:1.25rem 0;border-bottom:1px solid #e4e4e7;display:flex;align-items:flex-start;gap:1rem;">
<span style="width:0.5rem;height:0.5rem;border-radius:9999px;background:#7c3aed;flex-shrink:0;margin-top:0.45rem;"></span>
<div>
<p style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:0.9375rem;color:#18181b;margin:0 0 0.25rem;">Team access</p>
<p style="font-size:0.875rem;color:#71717a;margin:0;line-height:1.6;">Share cluster access with your team without handling SSH keys or root credentials.</p>
</div>
</li>
<li style="padding:1.25rem 0;border-bottom:1px solid #e4e4e7;display:flex;align-items:flex-start;gap:1rem;">
<span style="width:0.5rem;height:0.5rem;border-radius:9999px;background:#7c3aed;flex-shrink:0;margin-top:0.45rem;"></span>
<div>
<p style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:0.9375rem;color:#18181b;margin:0 0 0.25rem;">Push to deploy</p>
<p style="font-size:0.875rem;color:#71717a;margin:0;line-height:1.6;">Deploy applications from your Git repository automatically.</p>
</div>
</li>
<li style="padding:1.25rem 0;border-bottom:1px solid #e4e4e7;display:flex;align-items:flex-start;gap:1rem;">
<span style="width:0.5rem;height:0.5rem;border-radius:9999px;background:#7c3aed;flex-shrink:0;margin-top:0.45rem;"></span>
<div>
<p style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:0.9375rem;color:#18181b;margin:0 0 0.25rem;">Migration assistant</p>
<p style="font-size:0.875rem;color:#71717a;margin:0;line-height:1.6;">Move your data and services from the cloud and onto your own machines automagically.</p>
</div>
</li>
</ul>
<a href="#feedback" style="display:block;margin-top:1.5rem;border:1.5px dashed #c4b5fd;border-radius:0.75rem;padding:1.25rem 1.5rem;background:#faf5ff;text-decoration:none;transition:border-color 0.2s,background 0.2s;"
onmouseover="this.style.borderColor='#7c3aed';this.style.background='#f3e8ff';"
onmouseout="this.style.borderColor='#c4b5fd';this.style.background='#faf5ff';">
<p style="font-family:'Inter Tight',Inter,sans-serif;font-weight:600;font-size:0.9375rem;color:#7c3aed;margin:0 0 0.2rem;">...Add your most-needed feature</p>
<p style="font-size:0.875rem;color:#71717a;margin:0;line-height:1.6;">Something missing from this list? Tell us about your pain points.</p>
</a>
</div>
</div>
</div>
</section>
<!-- Final CTA: early access -->
<section id="feedback" class="relative bg-zinc-900">
<div class="py-16 md:py-24">
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<div class="max-w-lg mx-auto">
<div class="text-center pb-10">
<h2 class="font-inter-tight text-3xl md:text-4xl font-bold text-white mb-4">
Get early access
</h2>
<p class="text-lg text-zinc-400">
Leave your email and we'll reach out with updates.
</p>
</div>
<form action="/fill-form" method="POST">
<div class="mb-4">
<label for="hub-email" class="block text-sm font-medium text-zinc-300 mb-1.5">Your email</label>
<input type="email" name="email" id="hub-email" required
placeholder="you@example.com"
style="display:block;width:100%;background:#fff;border:1px solid #3f3f46;border-radius:0.5rem;padding:0.75rem 1rem;font-size:0.875rem;color:#18181b;outline:none;box-sizing:border-box;">
</div>
<div class="mb-6">
<label for="hub-message" class="block text-sm font-medium text-zinc-300 mb-1.5">
What will you use Hub for? What features would you like to see?
<span class="text-zinc-500 font-normal">(optional)</span>
</label>
<textarea name="message" id="hub-message" rows="3"
placeholder="e.g. searchable logs across all my services, or alerts when something goes down..."
style="display:block;width:100%;background:#fff;border:1px solid #3f3f46;border-radius:0.5rem;padding:0.75rem 1rem;font-size:0.875rem;color:#18181b;outline:none;resize:none;box-sizing:border-box;"></textarea>
</div>
<button type="submit"
class="btn text-zinc-900 bg-white hover:bg-zinc-100 w-full shadow font-semibold">
Register interest
</button>
</form>
<p class="text-center text-sm text-zinc-500 mt-6">
Or email <a href="mailto:pasha@uncloud.run"
class="underline text-zinc-400 hover:text-white transition">pasha@uncloud.run</a> directly.
</p>
</div>
</div>
</div>
</section>
</main>
<!-- Site footer -->
<footer>
<div class="max-w-6xl mx-auto px-4 sm:px-6">
<!-- Top area: Blocks -->
<div class="grid sm:grid-cols-12 gap-8 py-8 md:py-12 border-t border-zinc-200">
<!-- 1st block - Brand -->
<div class="sm:col-span-6 md:col-span-6 lg:col-span-8 max-md:order-1 flex flex-col">
<div class="mb-4">
<!-- Logo -->
<a class="flex items-center" href="index.html">
<img class="w-8 h-8 rounded shadow-sm shadow-zinc-950/20" src="./images/logo.svg"
alt="Logo">
<span class="ml-2 font-semibold text-lg text-zinc-900">uncloud</span>
</a>
</div>
<div class="grow text-sm text-zinc-500">
Made with ❤️ by
<a class="underline hover:text-zinc-900" href="https://github.com/unlabs-dev">unLabs</a>
in Australia
</div>
<!-- Social links -->
<ul class="flex space-x-4 mt-4 mb-1">
<li>
<a class="flex justify-center items-center text-zinc-700 hover:text-zinc-900 transition"
href="https://discord.gg/eR35KQJhPu" aria-label="Discord">
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
width="20"
height="20">
<path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"/>
</svg>
</a>
</li>
<li>
<a class="flex justify-center items-center text-zinc-700 hover:text-zinc-900 transition"
href="https://x.com/psviderski" aria-label="X/Twitter">
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
<path d="m7.063 3 3.495 4.475L14.601 3h2.454l-5.359 5.931L18 17h-4.938l-3.866-4.893L4.771 17H2.316l5.735-6.342L2 3h5.063Zm-.74 1.347H4.866l8.875 11.232h1.36L6.323 4.347Z"/>
</svg>
</a>
</li>
<li>
<a class="flex justify-center items-center text-zinc-700 hover:text-zinc-900 transition"
href="https://t.me/spyyy" aria-label="Telegram">
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
<path d="M17.968 3.276a.338.338 0 0 0-.232-.253 1.192 1.192 0 0 0-.63.045S3.087 8.106 2.286 8.664c-.172.121-.23.19-.259.272-.138.4.293.573.293.573l3.613 1.177a.388.388 0 0 0 .183-.011c.822-.519 8.27-5.222 8.7-5.38.068-.02.118 0 .1.049-.172.6-6.606 6.319-6.64 6.354a.138.138 0 0 0-.05.118l-.337 3.528s-.142 1.1.956 0a30.66 30.66 0 0 1 1.9-1.738c1.242.858 2.58 1.806 3.156 2.3a1 1 0 0 0 .732.283.825.825 0 0 0 .7-.622S17.894 5.292 17.98 3.909c.008-.135.021-.217.021-.317a1.177 1.177 0 0 0-.032-.316Z"/>
</svg>
</a>
</li>
<li>
<a class="flex justify-center items-center text-zinc-700 hover:text-zinc-900 transition"
href="https://github.com/psviderski/uncloud" aria-label="GitHub">
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
width="20"
height="20">
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
</svg>
</a>
</li>
</ul>
</div>
<!-- 2nd block - Documentation -->
<div class="sm:col-span-6 md:col-span-3 lg:col-span-2">
<h6 class="text-sm text-zinc-800 font-medium mb-2">Documentation</h6>
<ul class="text-sm space-y-2">
<li>
<a class="text-zinc-500 hover:text-zinc-900 transition"
href="/docs/#use-cases">Use cases</a>
</li>
<li>
<a class="text-zinc-500 hover:text-zinc-900 transition"
href="/docs/getting-started/deploy-demo-app">Quick start</a>
</li>
<li>
<a class="text-zinc-500 hover:text-zinc-900 transition"
href="/blog">Blog</a>
</li>
</ul>
</div>
<!-- 3rd block - Resources -->
<div class="sm:col-span-6 md:col-span-3 lg:col-span-2">
<h6 class="text-sm text-zinc-800 font-medium mb-2">Resources</h6>
<ul class="text-sm space-y-2">
<li>
<a class="text-zinc-500 hover:text-zinc-900 transition"
href="https://github.com/psviderski/uncloud">GitHub project</a>
</li>
<li>
<a class="text-zinc-500 hover:text-zinc-900 transition"
href="https://github.com/psviderski/uncloud/releases">Releases</a>
</li>
<li>
<a class="text-zinc-500 hover:text-zinc-900 transition"
href="https://github.com/psviderski/uncloud/blob/main/LICENSE">License</a>
</li>
<li>
<a class="text-zinc-500 hover:text-zinc-900 transition"
href="https://discord.gg/eR35KQJhPu">Community</a>
</li>
</ul>
</div>
</div>
</div>
</footer>
</div>
<script src="./js/vendors/alpinejs.min.js" defer></script>
</body>
</html>