Build dd0c marketing site: Astro + Tailwind, homepage + 6 product landing pages

- Homepage: hero with terminal mock, product grid, how-it-works, pricing (free/pro/self-hosted), CTA
- Product pages: route, drift, alert, portal, cost, run — each with features, install snippets, comparison tables
- Dark theme matching dd0c brand (indigo primary, cyan accent, dark surfaces)
- Astro static output for Cloudflare Pages deployment
- SEO: OG tags, meta descriptions, semantic HTML
This commit is contained in:
2026-03-01 04:12:37 +00:00
parent ee592f00d4
commit 12ca955de5
19 changed files with 839 additions and 6 deletions

View File

@@ -1,23 +1,40 @@
import type { FastifyInstance } from 'fastify';
import pino from 'pino';
import { withTenant } from '../data/db.js';
import Redis from 'ioredis';
import { withTenant, pool } from '../data/db.js';
import { config } from '../config/index.js';
import { AwsDiscoveryScanner } from '../discovery/aws-scanner.js';
import { GitHubDiscoveryScanner } from '../discovery/github-scanner.js';
import { CatalogService } from '../catalog/service.js';
import { ScheduledDiscovery } from '../discovery/scheduler.js';
const logger = pino({ name: 'api-discovery' });
const redis = new Redis(config.REDIS_URL);
const scheduler = new ScheduledDiscovery(redis);
const catalog = new CatalogService(pool);
export function registerDiscoveryRoutes(app: FastifyInstance) {
// Trigger AWS discovery scan
app.post('/api/v1/discovery/aws', async (req, reply) => {
const tenantId = (req as any).tenantId;
// TODO: Enqueue scan job (Redis queue or direct execution)
logger.info({ tenantId }, 'AWS discovery scan triggered');
return reply.status(202).send({ status: 'scan_queued', scanner: 'aws' });
// Get tenant's AWS config
const tenantConfig = await withTenant(tenantId, async (client) => {
return client.query('SELECT * FROM tenants WHERE id = $1', [tenantId]);
});
const result = await scheduler.runScan(tenantId, 'aws');
logger.info({ tenantId, result: result.status }, 'AWS discovery scan completed');
return reply.status(202).send({ status: result.status, discovered: result.discovered });
});
// Trigger GitHub discovery scan
app.post('/api/v1/discovery/github', async (req, reply) => {
const tenantId = (req as any).tenantId;
logger.info({ tenantId }, 'GitHub discovery scan triggered');
return reply.status(202).send({ status: 'scan_queued', scanner: 'github' });
const result = await scheduler.runScan(tenantId, 'github');
logger.info({ tenantId, result: result.status }, 'GitHub discovery scan completed');
return reply.status(202).send({ status: result.status, discovered: result.discovered });
});
// Get scan history

View File

@@ -0,0 +1,8 @@
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
export default defineConfig({
integrations: [tailwind()],
output: 'static',
site: 'https://dd0c.dev',
});

View File

@@ -0,0 +1,15 @@
{
"name": "dd0c-site",
"type": "module",
"version": "0.1.0",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview"
},
"dependencies": {
"astro": "^4.10.0",
"@astrojs/tailwind": "^5.1.0",
"tailwindcss": "^3.4.0"
}
}

View File

@@ -0,0 +1,17 @@
---
---
<section class="py-20 px-6 border-t border-dd0c-border">
<div class="max-w-3xl mx-auto text-center">
<h2 class="text-3xl sm:text-4xl font-bold">Stop paying enterprise prices<br />for tools you half-use</h2>
<p class="mt-6 text-dd0c-muted text-lg leading-relaxed">
dd0c is built by a solo engineer who got tired of $50K/year DevOps platforms
that take 3 months to set up. Each tool does one thing well. Start free. Pay when it saves you money.
</p>
<div class="mt-10">
<a href="https://app.dd0c.dev/signup" class="inline-flex px-8 py-3 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white font-medium transition">
Get started — it's free →
</a>
</div>
</div>
</section>

View File

@@ -0,0 +1,50 @@
---
---
<footer class="py-12 px-6 border-t border-dd0c-border">
<div class="max-w-6xl mx-auto">
<div class="grid md:grid-cols-4 gap-8">
<div>
<span class="font-mono font-bold text-lg text-dd0c-primary">dd0c</span>
<p class="mt-2 text-sm text-dd0c-muted">DevOps tools that don't waste your time.</p>
</div>
<div>
<h4 class="font-semibold text-sm mb-3">Products</h4>
<ul class="space-y-2 text-sm text-dd0c-muted">
<li><a href="/route" class="hover:text-dd0c-text transition">dd0c/route</a></li>
<li><a href="/drift" class="hover:text-dd0c-text transition">dd0c/drift</a></li>
<li><a href="/alert" class="hover:text-dd0c-text transition">dd0c/alert</a></li>
<li><a href="/portal" class="hover:text-dd0c-text transition">dd0c/portal</a></li>
<li><a href="/cost" class="hover:text-dd0c-text transition">dd0c/cost</a></li>
<li><a href="/run" class="hover:text-dd0c-text transition">dd0c/run</a></li>
</ul>
</div>
<div>
<h4 class="font-semibold text-sm mb-3">Resources</h4>
<ul class="space-y-2 text-sm text-dd0c-muted">
<li><a href="https://docs.dd0c.dev" class="hover:text-dd0c-text transition">Documentation</a></li>
<li><a href="https://docs.dd0c.dev/self-hosted" class="hover:text-dd0c-text transition">Self-hosted guide</a></li>
<li><a href="https://docs.dd0c.dev/api" class="hover:text-dd0c-text transition">API reference</a></li>
<li><a href="/changelog" class="hover:text-dd0c-text transition">Changelog</a></li>
</ul>
</div>
<div>
<h4 class="font-semibold text-sm mb-3">Company</h4>
<ul class="space-y-2 text-sm text-dd0c-muted">
<li><a href="https://github.com/dd0c" class="hover:text-dd0c-text transition">GitHub</a></li>
<li><a href="https://twitter.com/dd0cdev" class="hover:text-dd0c-text transition">Twitter</a></li>
<li><a href="/privacy" class="hover:text-dd0c-text transition">Privacy</a></li>
<li><a href="/terms" class="hover:text-dd0c-text transition">Terms</a></li>
</ul>
</div>
</div>
<div class="mt-12 pt-8 border-t border-dd0c-border flex flex-col sm:flex-row items-center justify-between gap-4">
<p class="text-xs text-dd0c-muted">© 2026 dd0c. All rights reserved.</p>
<p class="text-xs text-dd0c-muted">Built with ☕ by a solo founder who ships.</p>
</div>
</div>
</footer>

View File

@@ -0,0 +1,51 @@
---
---
<section class="pt-32 pb-20 px-6">
<div class="max-w-4xl mx-auto text-center">
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full border border-dd0c-border text-xs text-dd0c-muted mb-8">
<span class="w-2 h-2 rounded-full bg-emerald-400 animate-pulse"></span>
Now in beta — free while we ship
</div>
<h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold leading-tight tracking-tight">
DevOps tools that<br />
<span class="text-transparent bg-clip-text bg-gradient-to-r from-dd0c-primary to-dd0c-accent">don't waste your time</span>
</h1>
<p class="mt-6 text-lg sm:text-xl text-dd0c-muted max-w-2xl mx-auto leading-relaxed">
Six focused tools for the problems you actually have.
Route LLM costs. Detect drift. Correlate alerts. Catalog services. Catch cost spikes. Automate runbooks.
</p>
<div class="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4">
<a href="https://app.dd0c.dev/signup" class="w-full sm:w-auto px-8 py-3 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white font-medium transition text-center">
Start free →
</a>
<a href="#products" class="w-full sm:w-auto px-8 py-3 rounded-lg border border-dd0c-border hover:border-dd0c-muted text-dd0c-muted hover:text-dd0c-text transition text-center">
See the tools
</a>
</div>
<div class="mt-16 relative">
<div class="absolute inset-0 bg-gradient-to-t from-dd0c-bg via-transparent to-transparent z-10 pointer-events-none"></div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-4 font-mono text-sm text-dd0c-muted overflow-hidden">
<div class="flex items-center gap-2 mb-3">
<span class="w-3 h-3 rounded-full bg-red-500/60"></span>
<span class="w-3 h-3 rounded-full bg-yellow-500/60"></span>
<span class="w-3 h-3 rounded-full bg-green-500/60"></span>
<span class="ml-2 text-xs text-dd0c-muted/50">terminal</span>
</div>
<pre class="text-left"><code><span class="text-dd0c-accent">$</span> curl -s https://api.dd0c.dev/health | jq
<span class="text-emerald-400">{</span>
<span class="text-dd0c-primary">"route"</span>: <span class="text-emerald-400">"healthy"</span>,
<span class="text-dd0c-primary">"drift"</span>: <span class="text-emerald-400">"healthy"</span>,
<span class="text-dd0c-primary">"alert"</span>: <span class="text-emerald-400">"healthy"</span>,
<span class="text-dd0c-primary">"portal"</span>: <span class="text-emerald-400">"healthy"</span>,
<span class="text-dd0c-primary">"cost"</span>: <span class="text-emerald-400">"healthy"</span>,
<span class="text-dd0c-primary">"run"</span>: <span class="text-emerald-400">"healthy"</span>
<span class="text-emerald-400">}</span></code></pre>
</div>
</div>
</div>
</section>

View File

@@ -0,0 +1,42 @@
---
const steps = [
{
num: '01',
title: 'Sign up in 30 seconds',
description: 'Email and password. No credit card. No sales call. No "schedule a demo" button.',
},
{
num: '02',
title: 'Connect your stuff',
description: 'AWS credentials, Terraform state, PagerDuty webhook, GitHub org — whatever the tool needs. 5-minute setup guides.',
},
{
num: '03',
title: 'See results immediately',
description: 'First drift scan in under a minute. First cost baseline in an hour. First correlated incident the next time your pager fires.',
},
];
---
<section class="py-20 px-6 border-t border-dd0c-border">
<div class="max-w-4xl mx-auto">
<div class="text-center mb-16">
<h2 class="text-3xl sm:text-4xl font-bold">How it works</h2>
<p class="mt-4 text-dd0c-muted text-lg">No enterprise onboarding. No professional services.</p>
</div>
<div class="space-y-12">
{steps.map((step) => (
<div class="flex gap-6 items-start">
<div class="flex-shrink-0 w-12 h-12 rounded-lg bg-dd0c-primary/10 border border-dd0c-primary/20 flex items-center justify-center">
<span class="font-mono text-sm font-bold text-dd0c-primary">{step.num}</span>
</div>
<div>
<h3 class="text-xl font-semibold mb-2">{step.title}</h3>
<p class="text-dd0c-muted leading-relaxed">{step.description}</p>
</div>
</div>
))}
</div>
</div>
</section>

View File

@@ -0,0 +1,53 @@
---
interface Props {
title: string;
description?: string;
}
const { title, description = 'Six DevOps tools. One platform. Built for teams that ship.' } = Astro.props;
---
<!doctype html>
<html lang="en" class="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content={description} />
<meta name="theme-color" content="#0a0a0f" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<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=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
<!-- OG -->
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://dd0c.dev" />
<meta name="twitter:card" content="summary_large_image" />
<title>{title}</title>
</head>
<body class="bg-dd0c-bg text-dd0c-text font-sans antialiased">
<nav class="fixed top-0 w-full z-50 border-b border-dd0c-border bg-dd0c-bg/80 backdrop-blur-xl">
<div class="max-w-6xl mx-auto px-6 h-16 flex items-center justify-between">
<a href="/" class="flex items-center gap-2">
<span class="font-mono font-bold text-xl text-dd0c-primary">dd0c</span>
<span class="text-dd0c-muted text-sm hidden sm:inline">/devops</span>
</a>
<div class="hidden md:flex items-center gap-8 text-sm text-dd0c-muted">
<a href="#products" class="hover:text-dd0c-text transition">Products</a>
<a href="#pricing" class="hover:text-dd0c-text transition">Pricing</a>
<a href="https://docs.dd0c.dev" class="hover:text-dd0c-text transition">Docs</a>
</div>
<div class="flex items-center gap-4">
<a href="https://app.dd0c.dev/login" class="text-sm text-dd0c-muted hover:text-dd0c-text transition">Log in</a>
<a href="https://app.dd0c.dev/signup" class="text-sm px-4 py-2 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white transition font-medium">Start free</a>
</div>
</div>
</nav>
<main>
<slot />
</main>
</body>
</html>

View File

@@ -0,0 +1,91 @@
---
const plans = [
{
name: 'Free',
price: '$0',
period: 'forever',
description: 'Try any tool with generous limits.',
features: [
'All 6 tools included',
'1 connected account per tool',
'10K events/month (alert)',
'50 services (portal)',
'7-day data retention',
'Community support',
],
cta: 'Start free',
ctaLink: 'https://app.dd0c.dev/signup',
highlight: false,
},
{
name: 'Pro',
price: 'From $19',
period: '/mo per tool',
description: 'Pay only for what you use. Mix and match.',
features: [
'Unlimited connected accounts',
'Unlimited events',
'Unlimited services',
'90-day data retention',
'Slack + email notifications',
'API access + webhooks',
'Priority support',
],
cta: 'Start free, upgrade later',
ctaLink: 'https://app.dd0c.dev/signup',
highlight: true,
},
{
name: 'Self-hosted',
price: '$0',
period: 'your infra',
description: 'Run the whole stack on your own servers.',
features: [
'Docker Compose one-liner',
'All 6 tools included',
'Unlimited everything',
'Your data stays on your network',
'Auto-TLS via Caddy',
'Community support',
],
cta: 'View setup guide',
ctaLink: 'https://docs.dd0c.dev/self-hosted',
highlight: false,
},
];
---
<section id="pricing" class="py-20 px-6 border-t border-dd0c-border">
<div class="max-w-6xl mx-auto">
<div class="text-center mb-16">
<h2 class="text-3xl sm:text-4xl font-bold">Simple pricing</h2>
<p class="mt-4 text-dd0c-muted text-lg">Free tier is real. No "contact sales" trap.</p>
</div>
<div class="grid md:grid-cols-3 gap-6">
{plans.map((plan) => (
<div class={`rounded-xl border p-8 ${plan.highlight ? 'border-dd0c-primary bg-dd0c-primary/5' : 'border-dd0c-border bg-dd0c-surface'}`}>
<h3 class="text-xl font-bold">{plan.name}</h3>
<div class="mt-4 flex items-baseline gap-1">
<span class="text-3xl font-bold">{plan.price}</span>
<span class="text-dd0c-muted text-sm">{plan.period}</span>
</div>
<p class="mt-2 text-dd0c-muted text-sm">{plan.description}</p>
<ul class="mt-6 space-y-3">
{plan.features.map((f) => (
<li class="flex items-start gap-2 text-sm">
<span class="text-emerald-400 mt-0.5">✓</span>
<span class="text-dd0c-muted">{f}</span>
</li>
))}
</ul>
<a href={plan.ctaLink} class={`mt-8 block text-center py-3 rounded-lg font-medium text-sm transition ${plan.highlight ? 'bg-dd0c-primary hover:bg-dd0c-primary-light text-white' : 'border border-dd0c-border hover:border-dd0c-muted text-dd0c-muted hover:text-dd0c-text'}`}>
{plan.cta}
</a>
</div>
))}
</div>
</div>
</section>

View File

@@ -0,0 +1,86 @@
---
const products = [
{
name: 'route',
tagline: 'LLM Cost Router',
description: 'Route AI API calls to the cheapest provider automatically. Set cost caps, get usage dashboards, stop burning money on GPT-4 when GPT-3.5 works fine.',
price: '$49/mo',
icon: '🔀',
keywords: ['llm cost optimization', 'ai api router', 'openai cost management'],
color: 'from-violet-500 to-purple-600',
},
{
name: 'drift',
tagline: 'IaC Drift Detection',
description: 'Lightweight agent scans your Terraform state, detects drift, scrubs secrets, and alerts your team on Slack. No ClickOps surprises.',
price: '$29/stack/mo',
icon: '🔍',
keywords: ['terraform drift detection', 'infrastructure drift', 'iac compliance'],
color: 'from-cyan-500 to-blue-600',
},
{
name: 'alert',
tagline: 'Alert Intelligence',
description: 'Correlate alerts from PagerDuty, Datadog, OpsGenie, and Grafana into incidents. Cut noise by 80%. Stop waking up for duplicates.',
price: '$39/mo',
icon: '🔔',
keywords: ['alert fatigue', 'alert correlation', 'pagerduty alternative'],
color: 'from-amber-500 to-orange-600',
},
{
name: 'portal',
tagline: 'Service Catalog',
description: 'Auto-discover services from AWS and GitHub. Know who owns what. Search everything. No more "who runs this Lambda?"',
price: '$29/mo',
icon: '📋',
keywords: ['service catalog', 'internal developer portal', 'backstage alternative'],
color: 'from-emerald-500 to-green-600',
},
{
name: 'cost',
tagline: 'AWS Cost Anomaly',
description: 'Statistical anomaly detection on your AWS bill. Welford baselines, z-score alerts, Slack notifications before the bill lands.',
price: '$19/account/mo',
icon: '💰',
keywords: ['aws cost anomaly', 'cloud cost monitoring', 'aws billing alerts'],
color: 'from-rose-500 to-pink-600',
},
{
name: 'run',
tagline: 'Runbook Automation',
description: 'Write runbooks in YAML. Classify commands by safety. Destructive ops require Slack approval. Full audit trail.',
price: '$39/mo',
icon: '⚡',
keywords: ['runbook automation', 'incident response automation', 'rundeck alternative'],
color: 'from-indigo-500 to-blue-600',
},
];
---
<section id="products" class="py-20 px-6">
<div class="max-w-6xl mx-auto">
<div class="text-center mb-16">
<h2 class="text-3xl sm:text-4xl font-bold">Six tools. One login.</h2>
<p class="mt-4 text-dd0c-muted text-lg">Use one. Use all. Each works standalone.</p>
</div>
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
{products.map((p) => (
<a href={`/${p.name}`} class="group block rounded-xl border border-dd0c-border bg-dd0c-surface p-6 hover:border-dd0c-primary/40 transition-all duration-200">
<div class="flex items-center gap-3 mb-4">
<span class="text-2xl">{p.icon}</span>
<div>
<span class="font-mono text-sm text-dd0c-primary">dd0c/{p.name}</span>
<h3 class="font-semibold text-lg">{p.tagline}</h3>
</div>
</div>
<p class="text-dd0c-muted text-sm leading-relaxed mb-4">{p.description}</p>
<div class="flex items-center justify-between">
<span class="text-sm font-medium text-dd0c-accent">{p.price}</span>
<span class="text-xs text-dd0c-muted group-hover:text-dd0c-primary transition">Learn more →</span>
</div>
</a>
))}
</div>
</div>
</section>

View File

@@ -0,0 +1,49 @@
---
import Layout from '../components/Layout.astro';
import Footer from '../components/Footer.astro';
import CTA from '../components/CTA.astro';
---
<Layout title="dd0c/alert — Alert Intelligence" description="Correlate alerts from PagerDuty, Datadog, OpsGenie into incidents. Cut alert noise by 80%.">
<section class="pt-32 pb-20 px-6">
<div class="max-w-4xl mx-auto">
<div class="mb-8">
<span class="font-mono text-sm text-dd0c-primary">dd0c/alert</span>
<h1 class="text-4xl sm:text-5xl font-bold mt-2">Alert fatigue is a bug, not a feature</h1>
<p class="mt-6 text-lg text-dd0c-muted leading-relaxed max-w-2xl">
Ingest webhooks from PagerDuty, Datadog, OpsGenie, and Grafana. Group related alerts into incidents using time-window correlation. Stop waking up three times for the same outage.
</p>
</div>
<div class="mt-10 flex gap-4">
<a href="https://app.dd0c.dev/signup" class="px-6 py-3 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white font-medium transition">Start free →</a>
<a href="https://docs.dd0c.dev/alert" class="px-6 py-3 rounded-lg border border-dd0c-border hover:border-dd0c-muted text-dd0c-muted hover:text-dd0c-text transition">Read docs</a>
</div>
<div class="mt-16 grid md:grid-cols-2 gap-6">
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🔗</div>
<h3 class="font-semibold mb-2">Multi-source correlation</h3>
<p class="text-sm text-dd0c-muted">HMAC-verified webhooks from 4 providers. Canonical alert schema normalizes everything into one format.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">⏱️</div>
<h3 class="font-semibold mb-2">Time-window grouping</h3>
<p class="text-sm text-dd0c-muted">5-minute correlation windows. Late alerts attach to existing incidents. Very late alerts create new ones.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">📉</div>
<h3 class="font-semibold mb-2">80% noise reduction</h3>
<p class="text-sm text-dd0c-muted">20 alerts from the same root cause become 1 incident. Your on-call engineer sees one notification, not twenty.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">📧</div>
<h3 class="font-semibold mb-2">Slack, email, webhook</h3>
<p class="text-sm text-dd0c-muted">Severity-gated notifications. Critical goes to Slack + email. Low goes to a dashboard. You decide.</p>
</div>
</div>
</div>
</section>
<CTA />
<Footer />
</Layout>

View File

@@ -0,0 +1,49 @@
---
import Layout from '../components/Layout.astro';
import Footer from '../components/Footer.astro';
import CTA from '../components/CTA.astro';
---
<Layout title="dd0c/cost — AWS Cost Anomaly Detection" description="Statistical anomaly detection on your AWS bill. Welford baselines, z-score alerts, Slack notifications.">
<section class="pt-32 pb-20 px-6">
<div class="max-w-4xl mx-auto">
<div class="mb-8">
<span class="font-mono text-sm text-dd0c-primary">dd0c/cost</span>
<h1 class="text-4xl sm:text-5xl font-bold mt-2">Know about cost spikes before the bill arrives</h1>
<p class="mt-6 text-lg text-dd0c-muted leading-relaxed max-w-2xl">
Welford's algorithm builds running baselines per resource type. Z-score anomaly detection catches spikes in real time. Slack alerts with one-click snooze for expected costs. Governance engine auto-promotes from shadow to enforce.
</p>
</div>
<div class="mt-10 flex gap-4">
<a href="https://app.dd0c.dev/signup" class="px-6 py-3 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white font-medium transition">Start free →</a>
<a href="https://docs.dd0c.dev/cost" class="px-6 py-3 rounded-lg border border-dd0c-border hover:border-dd0c-muted text-dd0c-muted hover:text-dd0c-text transition">Read docs</a>
</div>
<div class="mt-16 grid md:grid-cols-2 gap-6">
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">📈</div>
<h3 class="font-semibold mb-2">Statistical baselines</h3>
<p class="text-sm text-dd0c-muted">Welford's online algorithm. No batch jobs. Baselines update with every data point. Optimistic locking prevents corruption.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🎯</div>
<h3 class="font-semibold mb-2">0-100 anomaly score</h3>
<p class="text-sm text-dd0c-muted">Z-score mapped to a simple 0-100 scale. Set your threshold. Default 50 (2σ). Tune per resource type.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🛡️</div>
<h3 class="font-semibold mb-2">Governance engine</h3>
<p class="text-sm text-dd0c-muted">Shadow → audit → enforce. Auto-promotes after 14 days with &lt;10% false positive rate. Safe by default.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">💤</div>
<h3 class="font-semibold mb-2">Snooze & mark expected</h3>
<p class="text-sm text-dd0c-muted">Known cost spike? Snooze for 1-168 hours or mark as expected. Reduces false positive rate over time.</p>
</div>
</div>
</div>
</section>
<CTA />
<Footer />
</Layout>

View File

@@ -0,0 +1,52 @@
---
import Layout from '../components/Layout.astro';
import Footer from '../components/Footer.astro';
import CTA from '../components/CTA.astro';
---
<Layout title="dd0c/drift — IaC Drift Detection" description="Lightweight Terraform drift detection agent. Scans state, scrubs secrets, alerts on Slack. No ClickOps surprises.">
<section class="pt-32 pb-20 px-6">
<div class="max-w-4xl mx-auto">
<div class="mb-8">
<span class="font-mono text-sm text-dd0c-primary">dd0c/drift</span>
<h1 class="text-4xl sm:text-5xl font-bold mt-2">Catch Terraform drift before it catches you</h1>
<p class="mt-6 text-lg text-dd0c-muted leading-relaxed max-w-2xl">
Lightweight Go agent scans your Terraform state files, compares against live infrastructure, scrubs secrets from reports, and alerts your team on Slack. Know when someone ClickOps'd your production VPC.
</p>
</div>
<div class="mt-10 flex gap-4">
<a href="https://app.dd0c.dev/signup" class="px-6 py-3 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white font-medium transition">Start free →</a>
<a href="https://docs.dd0c.dev/drift" class="px-6 py-3 rounded-lg border border-dd0c-border hover:border-dd0c-muted text-dd0c-muted hover:text-dd0c-text transition">Read docs</a>
</div>
<div class="mt-16 grid md:grid-cols-3 gap-6">
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🔍</div>
<h3 class="font-semibold mb-2">State scanning</h3>
<p class="text-sm text-dd0c-muted">Parses Terraform v4 state files. Detects resource changes, attribute drift, and deleted resources.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🔒</div>
<h3 class="font-semibold mb-2">Secret scrubbing</h3>
<p class="text-sm text-dd0c-muted">Regex + Shannon entropy detection. AWS keys, RSA keys, PEM certs — scrubbed before reports leave your network.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🔔</div>
<h3 class="font-semibold mb-2">Slack alerts</h3>
<p class="text-sm text-dd0c-muted">Block Kit messages with severity, affected resources, and one-click remediate/accept buttons.</p>
</div>
</div>
<div class="mt-16 rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<h3 class="font-semibold mb-4">Install the agent</h3>
<pre class="font-mono text-sm text-dd0c-muted overflow-x-auto"><code><span class="text-dd0c-accent">$</span> curl -sSL https://install.dd0c.dev/drift | bash
<span class="text-dd0c-accent">$</span> dd0c-drift check --state terraform.tfstate --endpoint https://drift.dd0c.dev
<span class="text-emerald-400">✓</span> Scanned 47 resources in 1.2s
<span class="text-amber-400">⚠</span> 3 drifted resources detected (1 critical, 2 medium)</code></pre>
</div>
</div>
</section>
<CTA />
<Footer />
</Layout>

View File

@@ -0,0 +1,18 @@
---
import Layout from '../components/Layout.astro';
import Hero from '../components/Hero.astro';
import Products from '../components/Products.astro';
import HowItWorks from '../components/HowItWorks.astro';
import Pricing from '../components/Pricing.astro';
import CTA from '../components/CTA.astro';
import Footer from '../components/Footer.astro';
---
<Layout title="dd0c — DevOps tools that don't waste your time">
<Hero />
<Products />
<HowItWorks />
<Pricing />
<CTA />
<Footer />
</Layout>

View File

@@ -0,0 +1,44 @@
---
import Layout from '../components/Layout.astro';
import Footer from '../components/Footer.astro';
import CTA from '../components/CTA.astro';
---
<Layout title="dd0c/portal — Service Catalog" description="Auto-discover services from AWS and GitHub. Know who owns what. Lightweight Backstage alternative.">
<section class="pt-32 pb-20 px-6">
<div class="max-w-4xl mx-auto">
<div class="mb-8">
<span class="font-mono text-sm text-dd0c-primary">dd0c/portal</span>
<h1 class="text-4xl sm:text-5xl font-bold mt-2">"Who owns this service?"<br />answered in 2 seconds</h1>
<p class="mt-6 text-lg text-dd0c-muted leading-relaxed max-w-2xl">
Auto-discovers ECS services, Lambda functions, and RDS instances from AWS. Reads CODEOWNERS from GitHub. Full-text search across your entire service catalog. Like Backstage, but you can set it up before lunch.
</p>
</div>
<div class="mt-10 flex gap-4">
<a href="https://app.dd0c.dev/signup" class="px-6 py-3 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white font-medium transition">Start free →</a>
<a href="https://docs.dd0c.dev/portal" class="px-6 py-3 rounded-lg border border-dd0c-border hover:border-dd0c-muted text-dd0c-muted hover:text-dd0c-text transition">Read docs</a>
</div>
<div class="mt-16 grid md:grid-cols-3 gap-6">
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🔎</div>
<h3 class="font-semibold mb-2">Auto-discovery</h3>
<p class="text-sm text-dd0c-muted">Scans AWS (ECS, Lambda, RDS) and GitHub orgs. Partial scan failures stage results — never corrupts your catalog.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">👤</div>
<h3 class="font-semibold mb-2">Ownership resolution</h3>
<p class="text-sm text-dd0c-muted">Config > CODEOWNERS > AWS tags > heuristic. Explicit always wins. No more guessing.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">⚡</div>
<h3 class="font-semibold mb-2">Instant search</h3>
<p class="text-sm text-dd0c-muted">Meilisearch-powered full-text search. Falls back to PostgreSQL if Meili is down. Always available.</p>
</div>
</div>
</div>
</section>
<CTA />
<Footer />
</Layout>

View File

@@ -0,0 +1,95 @@
---
import Layout from '../components/Layout.astro';
import Footer from '../components/Footer.astro';
import CTA from '../components/CTA.astro';
---
<Layout title="dd0c/route — LLM Cost Router" description="Route AI API calls to the cheapest provider. Set cost caps. Get usage dashboards. Stop overpaying for GPT-4.">
<section class="pt-32 pb-20 px-6">
<div class="max-w-4xl mx-auto">
<div class="mb-8">
<span class="font-mono text-sm text-dd0c-primary">dd0c/route</span>
<h1 class="text-4xl sm:text-5xl font-bold mt-2">Stop burning money on LLM APIs</h1>
<p class="mt-6 text-lg text-dd0c-muted leading-relaxed max-w-2xl">
Drop-in proxy that sits between your app and OpenAI/Anthropic/Google. Routes each request to the cheapest provider that meets your quality threshold. Real-time cost dashboards. Budget alerts before you blow through $10K.
</p>
</div>
<div class="mt-10 flex gap-4">
<a href="https://app.dd0c.dev/signup" class="px-6 py-3 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white font-medium transition">Start free →</a>
<a href="https://docs.dd0c.dev/route" class="px-6 py-3 rounded-lg border border-dd0c-border hover:border-dd0c-muted text-dd0c-muted hover:text-dd0c-text transition">Read docs</a>
</div>
<div class="mt-16 grid md:grid-cols-3 gap-6">
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">💸</div>
<h3 class="font-semibold mb-2">Cost-based routing</h3>
<p class="text-sm text-dd0c-muted">Classify prompt complexity. Route simple queries to cheap models, complex ones to GPT-4. Save 40-60% on average.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">📊</div>
<h3 class="font-semibold mb-2">Real-time dashboard</h3>
<p class="text-sm text-dd0c-muted">Cost per model, per team, per endpoint. Token usage breakdowns. Anomaly detection when spend spikes.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🔑</div>
<h3 class="font-semibold mb-2">API key management</h3>
<p class="text-sm text-dd0c-muted">Issue scoped keys per team. Set budget caps. Rotate without downtime. Full audit trail.</p>
</div>
</div>
<div class="mt-16 rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<h3 class="font-semibold mb-4">Integration is one line</h3>
<pre class="font-mono text-sm text-dd0c-muted overflow-x-auto"><code><span class="text-dd0c-muted"># Before</span>
<span class="text-dd0c-accent">OPENAI_BASE_URL</span>=https://api.openai.com/v1
<span class="text-dd0c-muted"># After</span>
<span class="text-dd0c-accent">OPENAI_BASE_URL</span>=https://route.dd0c.dev/v1</code></pre>
</div>
<div class="mt-16">
<h3 class="text-xl font-semibold mb-6">Compared to alternatives</h3>
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-dd0c-border text-left text-dd0c-muted">
<th class="py-3 pr-4">Feature</th>
<th class="py-3 px-4">dd0c/route</th>
<th class="py-3 px-4">LiteLLM</th>
<th class="py-3 px-4">Helicone</th>
</tr>
</thead>
<tbody class="text-dd0c-muted">
<tr class="border-b border-dd0c-border/50">
<td class="py-3 pr-4">Cost-based routing</td>
<td class="py-3 px-4 text-emerald-400">✓</td>
<td class="py-3 px-4">Partial</td>
<td class="py-3 px-4 text-red-400">✗</td>
</tr>
<tr class="border-b border-dd0c-border/50">
<td class="py-3 pr-4">Self-hosted option</td>
<td class="py-3 px-4 text-emerald-400">✓</td>
<td class="py-3 px-4 text-emerald-400">✓</td>
<td class="py-3 px-4 text-red-400">✗</td>
</tr>
<tr class="border-b border-dd0c-border/50">
<td class="py-3 pr-4">Sub-ms latency overhead</td>
<td class="py-3 px-4 text-emerald-400">✓ (Rust)</td>
<td class="py-3 px-4">~5ms (Python)</td>
<td class="py-3 px-4">~10ms</td>
</tr>
<tr>
<td class="py-3 pr-4">Starting price</td>
<td class="py-3 px-4 text-emerald-400">$49/mo</td>
<td class="py-3 px-4">Free (OSS)</td>
<td class="py-3 px-4">$20/mo</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
<CTA />
<Footer />
</Layout>

View File

@@ -0,0 +1,64 @@
---
import Layout from '../components/Layout.astro';
import Footer from '../components/Footer.astro';
import CTA from '../components/CTA.astro';
---
<Layout title="dd0c/run — Runbook Automation" description="Write runbooks in YAML. Classify commands by safety. Destructive ops require Slack approval. Full audit trail.">
<section class="pt-32 pb-20 px-6">
<div class="max-w-4xl mx-auto">
<div class="mb-8">
<span class="font-mono text-sm text-dd0c-primary">dd0c/run</span>
<h1 class="text-4xl sm:text-5xl font-bold mt-2">Runbooks that run themselves<br />(with your permission)</h1>
<p class="mt-6 text-lg text-dd0c-muted leading-relaxed max-w-2xl">
Write runbooks in YAML. The Rust agent classifies every command as read-only, modifying, or destructive. Read-only runs automatically. Destructive commands pause and ask for Slack approval. Full audit trail. No YOLO.
</p>
</div>
<div class="mt-10 flex gap-4">
<a href="https://app.dd0c.dev/signup" class="px-6 py-3 rounded-lg bg-dd0c-primary hover:bg-dd0c-primary-light text-white font-medium transition">Start free →</a>
<a href="https://docs.dd0c.dev/run" class="px-6 py-3 rounded-lg border border-dd0c-border hover:border-dd0c-muted text-dd0c-muted hover:text-dd0c-text transition">Read docs</a>
</div>
<div class="mt-16 rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<h3 class="font-semibold mb-4">Example runbook</h3>
<pre class="font-mono text-sm text-dd0c-muted overflow-x-auto"><code><span class="text-dd0c-primary">name:</span> restart-ecs-service
<span class="text-dd0c-primary">steps:</span>
- <span class="text-dd0c-accent">description:</span> Check current task count
<span class="text-dd0c-accent">command:</span> aws ecs describe-services --cluster prod --services api
<span class="text-dd0c-muted"># → classified: read_only (auto-approved)</span>
- <span class="text-dd0c-accent">description:</span> Force new deployment
<span class="text-dd0c-accent">command:</span> aws ecs update-service --cluster prod --service api --force-new-deployment
<span class="text-dd0c-muted"># → classified: modifying (requires approval)</span>
- <span class="text-dd0c-accent">description:</span> Wait for stable
<span class="text-dd0c-accent">command:</span> aws ecs wait services-stable --cluster prod --services api
<span class="text-dd0c-accent">timeout_seconds:</span> 300
<span class="text-dd0c-accent">on_failure:</span>
<span class="text-dd0c-accent">action:</span> retry
<span class="text-dd0c-accent">max_attempts:</span> 3</code></pre>
</div>
<div class="mt-16 grid md:grid-cols-3 gap-6">
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">🛑</div>
<h3 class="font-semibold mb-2">Safety classification</h3>
<p class="text-sm text-dd0c-muted">Pattern-based classification for shell, AWS CLI, kubectl, and terraform commands. Destructive ops always require human approval.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">💬</div>
<h3 class="font-semibold mb-2">Slack approval flow</h3>
<p class="text-sm text-dd0c-muted">Block Kit messages with approve/reject buttons. Click to approve from your phone. No SSH required.</p>
</div>
<div class="rounded-xl border border-dd0c-border bg-dd0c-surface p-6">
<div class="text-2xl mb-3">📝</div>
<h3 class="font-semibold mb-2">Immutable audit log</h3>
<p class="text-sm text-dd0c-muted">Every command, every approval, every exit code. SHA-256 hashed stdout. Append-only. Compliance-ready.</p>
</div>
</div>
</div>
</section>
<CTA />
<Footer />
</Layout>

View File

@@ -0,0 +1,26 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {
colors: {
dd0c: {
bg: '#0a0a0f',
surface: '#12121a',
border: '#1e1e2e',
primary: '#6366f1',
'primary-light': '#818cf8',
accent: '#06b6d4',
'accent-light': '#22d3ee',
text: '#e2e8f0',
muted: '#94a3b8',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'Fira Code', 'monospace'],
},
},
},
plugins: [],
};

View File

@@ -0,0 +1,6 @@
{
"compilerOptions": {
"strict": true,
"jsx": "preserve"
}
}