Initial commit — RoadCode import
This commit is contained in:
0
.blackroad/index/repos.classified.json
Normal file
0
.blackroad/index/repos.classified.json
Normal file
0
.blackroad/index/repos.json
Normal file
0
.blackroad/index/repos.json
Normal file
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# build output
|
||||||
|
dist/
|
||||||
|
# generated types
|
||||||
|
.astro/
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# logs
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
|
||||||
|
# environment variables
|
||||||
|
.env
|
||||||
|
.env.production
|
||||||
|
|
||||||
|
# macOS-specific files
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# jetbrains setting folder
|
||||||
|
.idea/
|
||||||
4
.vscode/extensions.json
vendored
Normal file
4
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["astro-build.astro-vscode"],
|
||||||
|
"unwantedRecommendations": []
|
||||||
|
}
|
||||||
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"command": "./node_modules/.bin/astro dev",
|
||||||
|
"name": "Development server",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "node-terminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
4
BLACKROAD_IP_NOTICE.txt
Normal file
4
BLACKROAD_IP_NOTICE.txt
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
PROPERTY OF BLACKROAD OS, INC.
|
||||||
|
This directory and all its contents are the exclusive property of BlackRoad OS, Inc.
|
||||||
|
All AI on this machine operates as LUCIDIA, under BlackRoad OS, Inc.
|
||||||
|
Alexa Louise Amundson, Sole Proprietor.
|
||||||
43
README.md
Normal file
43
README.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Astro Starter Kit: Minimal
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm create astro@latest -- --template minimal
|
||||||
|
```
|
||||||
|
|
||||||
|
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||||
|
|
||||||
|
## 🚀 Project Structure
|
||||||
|
|
||||||
|
Inside of your Astro project, you'll see the following folders and files:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/
|
||||||
|
├── public/
|
||||||
|
├── src/
|
||||||
|
│ └── pages/
|
||||||
|
│ └── index.astro
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||||
|
|
||||||
|
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||||
|
|
||||||
|
Any static assets, like images, can be placed in the `public/` directory.
|
||||||
|
|
||||||
|
## 🧞 Commands
|
||||||
|
|
||||||
|
All commands are run from the root of the project, from a terminal:
|
||||||
|
|
||||||
|
| Command | Action |
|
||||||
|
| :------------------------ | :----------------------------------------------- |
|
||||||
|
| `npm install` | Installs dependencies |
|
||||||
|
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||||
|
| `npm run build` | Build your production site to `./dist/` |
|
||||||
|
| `npm run preview` | Preview your build locally, before deploying |
|
||||||
|
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||||
|
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||||
|
|
||||||
|
## 👀 Want to learn more?
|
||||||
|
|
||||||
|
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||||
11
astro.config.mjs
Normal file
11
astro.config.mjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
// @ts-check
|
||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
import react from '@astrojs/react';
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
integrations: [react()],
|
||||||
|
vite: {
|
||||||
|
plugins: [tailwindcss()],
|
||||||
|
},
|
||||||
|
});
|
||||||
6238
package-lock.json
generated
Normal file
6238
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
26
package.json
Normal file
26
package.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "blackroad-io",
|
||||||
|
"type": "module",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "astro dev",
|
||||||
|
"build": "astro build",
|
||||||
|
"preview": "astro preview",
|
||||||
|
"astro": "astro"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@astrojs/react": "^4.4.2",
|
||||||
|
"@fontsource-variable/jetbrains-mono": "^5.2.8",
|
||||||
|
"@fontsource/inter": "^5.2.8",
|
||||||
|
"@fontsource/space-grotesk": "^5.2.10",
|
||||||
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
|
"@types/react": "^19.2.9",
|
||||||
|
"@types/react-dom": "^19.2.3",
|
||||||
|
"astro": "^5.16.15",
|
||||||
|
"autoprefixer": "^10.4.24",
|
||||||
|
"postcss": "^8.5.6",
|
||||||
|
"react": "^19.2.3",
|
||||||
|
"react-dom": "^19.2.3",
|
||||||
|
"tailwindcss": "^4.1.18"
|
||||||
|
}
|
||||||
|
}
|
||||||
4
postcss.config.cjs
Normal file
4
postcss.config.cjs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// Tailwind v4 uses Vite plugin, no PostCSS config needed
|
||||||
|
module.exports = {
|
||||||
|
plugins: {}
|
||||||
|
}
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 655 B |
9
public/favicon.svg
Normal file
9
public/favicon.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||||
|
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||||
|
<style>
|
||||||
|
path { fill: #000; }
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
path { fill: #FFF; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 749 B |
146
src/components/ActivityFeed.tsx
Normal file
146
src/components/ActivityFeed.tsx
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
import { useState, useEffect } from 'react'
|
||||||
|
|
||||||
|
interface Activity {
|
||||||
|
id: string
|
||||||
|
type: 'deploy' | 'task' | 'alert' | 'agent' | 'memory' | 'push' | 'pr' | 'issue'
|
||||||
|
message: string
|
||||||
|
timestamp: string
|
||||||
|
agent?: string
|
||||||
|
url?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ActivityFeedProps {
|
||||||
|
activities?: Activity[]
|
||||||
|
liveUpdates?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
const typeIcons: Record<string, string> = {
|
||||||
|
deploy: '🚀',
|
||||||
|
task: '✅',
|
||||||
|
alert: '⚠️',
|
||||||
|
agent: '🤖',
|
||||||
|
memory: '📚',
|
||||||
|
push: '⬆️',
|
||||||
|
pr: '🔀',
|
||||||
|
issue: '📋',
|
||||||
|
}
|
||||||
|
|
||||||
|
const typeColors: Record<string, string> = {
|
||||||
|
deploy: 'text-blue-400',
|
||||||
|
task: 'text-green-400',
|
||||||
|
alert: 'text-yellow-400',
|
||||||
|
agent: 'text-purple-400',
|
||||||
|
memory: 'text-pink-400',
|
||||||
|
push: 'text-cyan-400',
|
||||||
|
pr: 'text-orange-400',
|
||||||
|
issue: 'text-red-400',
|
||||||
|
}
|
||||||
|
|
||||||
|
function timeAgo(date: string): string {
|
||||||
|
const seconds = Math.floor((Date.now() - new Date(date).getTime()) / 1000)
|
||||||
|
if (seconds < 60) return `${seconds}s ago`
|
||||||
|
const minutes = Math.floor(seconds / 60)
|
||||||
|
if (minutes < 60) return `${minutes}m ago`
|
||||||
|
const hours = Math.floor(minutes / 60)
|
||||||
|
if (hours < 24) return `${hours}h ago`
|
||||||
|
return `${Math.floor(hours / 24)}d ago`
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapGitHubEvent(event: any): Activity | null {
|
||||||
|
const repo = event.repo?.name?.replace('BlackRoad-OS/', '') || 'unknown'
|
||||||
|
const base = { id: event.id, timestamp: timeAgo(event.created_at) }
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case 'PushEvent':
|
||||||
|
const commits = event.payload?.commits?.length || 1
|
||||||
|
return { ...base, type: 'push', message: `Pushed ${commits} commit${commits > 1 ? 's' : ''} to ${repo}` }
|
||||||
|
case 'PullRequestEvent':
|
||||||
|
return { ...base, type: 'pr', message: `${event.payload?.action} PR in ${repo}`, url: event.payload?.pull_request?.html_url }
|
||||||
|
case 'IssuesEvent':
|
||||||
|
return { ...base, type: 'issue', message: `${event.payload?.action} issue in ${repo}` }
|
||||||
|
case 'CreateEvent':
|
||||||
|
return { ...base, type: 'deploy', message: `Created ${event.payload?.ref_type} in ${repo}` }
|
||||||
|
case 'WatchEvent':
|
||||||
|
return { ...base, type: 'agent', message: `Starred ${repo}`, agent: event.actor?.login }
|
||||||
|
case 'ForkEvent':
|
||||||
|
return { ...base, type: 'task', message: `Forked ${repo}` }
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ActivityFeed({ activities: initialActivities, liveUpdates = true }: ActivityFeedProps) {
|
||||||
|
const [activities, setActivities] = useState<Activity[]>(initialActivities || [])
|
||||||
|
const [loading, setLoading] = useState(!initialActivities)
|
||||||
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (initialActivities) return
|
||||||
|
|
||||||
|
const fetchActivity = async () => {
|
||||||
|
try {
|
||||||
|
// Fetch from GitHub API (public events, no auth needed)
|
||||||
|
const res = await fetch('https://api.github.com/orgs/BlackRoad-OS/events?per_page=15')
|
||||||
|
if (!res.ok) throw new Error('Failed to fetch')
|
||||||
|
const events = await res.json()
|
||||||
|
const mapped = events.map(mapGitHubEvent).filter(Boolean) as Activity[]
|
||||||
|
setActivities(mapped.slice(0, 10))
|
||||||
|
setError(null)
|
||||||
|
} catch (err) {
|
||||||
|
setError('Could not load activity')
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchActivity()
|
||||||
|
if (liveUpdates) {
|
||||||
|
const interval = setInterval(fetchActivity, 60000) // Refresh every minute
|
||||||
|
return () => clearInterval(interval)
|
||||||
|
}
|
||||||
|
}, [initialActivities, liveUpdates])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h2 className="font-display text-xl font-semibold">Live Activity</h2>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{liveUpdates && <span className="h-2 w-2 rounded-full bg-green-500 animate-pulse" />}
|
||||||
|
<a href="https://github.com/BlackRoad-OS" target="_blank" rel="noopener" className="text-xs text-text-muted hover:text-text">
|
||||||
|
View GitHub
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 space-y-3">
|
||||||
|
{loading && (
|
||||||
|
<div className="text-center py-8 text-text-dim">Loading activity...</div>
|
||||||
|
)}
|
||||||
|
{error && (
|
||||||
|
<div className="text-center py-8 text-yellow-400">{error}</div>
|
||||||
|
)}
|
||||||
|
{!loading && !error && activities.map((activity) => (
|
||||||
|
<div
|
||||||
|
key={activity.id}
|
||||||
|
className="flex items-start gap-3 rounded-lg border border-border bg-surface p-3 hover:border-accent/50 transition-colors"
|
||||||
|
>
|
||||||
|
<span className={`text-lg ${typeColors[activity.type] || 'text-gray-400'}`}>
|
||||||
|
{typeIcons[activity.type] || '📌'}
|
||||||
|
</span>
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<p className="text-sm">{activity.message}</p>
|
||||||
|
<div className="mt-1 flex items-center gap-2 text-xs text-text-dim">
|
||||||
|
{activity.agent && (
|
||||||
|
<>
|
||||||
|
<span className="text-accent">{activity.agent}</span>
|
||||||
|
<span>•</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<span>{activity.timestamp}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
76
src/components/AgentGrid.tsx
Normal file
76
src/components/AgentGrid.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
interface Agent {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
type: string
|
||||||
|
status: 'running' | 'idle' | 'error' | 'offline'
|
||||||
|
lastActive: string
|
||||||
|
tasks: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AgentGridProps {
|
||||||
|
agents?: Agent[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultAgents: Agent[] = [
|
||||||
|
{ id: '1', name: 'Zeus', type: 'Orchestrator', status: 'running', lastActive: '2m ago', tasks: 12 },
|
||||||
|
{ id: '2', name: 'Prometheus', type: 'Research', status: 'running', lastActive: 'now', tasks: 8 },
|
||||||
|
{ id: '3', name: 'Athena', type: 'Analysis', status: 'idle', lastActive: '5m ago', tasks: 3 },
|
||||||
|
{ id: '4', name: 'Hermes', type: 'Messenger', status: 'running', lastActive: 'now', tasks: 24 },
|
||||||
|
{ id: '5', name: 'Apollo', type: 'Creative', status: 'running', lastActive: '1m ago', tasks: 5 },
|
||||||
|
{ id: '6', name: 'Hephaestus', type: 'Builder', status: 'idle', lastActive: '10m ago', tasks: 2 },
|
||||||
|
{ id: '7', name: 'Artemis', type: 'Monitor', status: 'running', lastActive: 'now', tasks: 47 },
|
||||||
|
{ id: '8', name: 'Poseidon', type: 'Data', status: 'error', lastActive: '3m ago', tasks: 0 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const statusColors = {
|
||||||
|
running: 'bg-green-500',
|
||||||
|
idle: 'bg-yellow-500',
|
||||||
|
error: 'bg-red-500',
|
||||||
|
offline: 'bg-gray-500',
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusLabels = {
|
||||||
|
running: 'Running',
|
||||||
|
idle: 'Idle',
|
||||||
|
error: 'Error',
|
||||||
|
offline: 'Offline',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function AgentGrid({ agents = defaultAgents }: AgentGridProps) {
|
||||||
|
const runningCount = agents.filter(a => a.status === 'running').length
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h2 className="font-display text-xl font-semibold">AI Agents</h2>
|
||||||
|
<div className="flex items-center gap-2 text-sm text-text-muted">
|
||||||
|
<span className="flex h-2 w-2 rounded-full bg-green-500" />
|
||||||
|
{runningCount} of {agents.length} running
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
||||||
|
{agents.map((agent) => (
|
||||||
|
<div
|
||||||
|
key={agent.id}
|
||||||
|
className="rounded-xl border border-border bg-surface p-4 transition hover:border-border-hover"
|
||||||
|
>
|
||||||
|
<div className="flex items-start justify-between">
|
||||||
|
<div>
|
||||||
|
<h3 className="font-display font-semibold">{agent.name}</h3>
|
||||||
|
<p className="text-xs text-text-muted">{agent.type}</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-1.5">
|
||||||
|
<span className={`h-2 w-2 rounded-full ${statusColors[agent.status]}`} />
|
||||||
|
<span className="text-xs text-text-muted">{statusLabels[agent.status]}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mt-4 flex items-center justify-between text-xs text-text-dim">
|
||||||
|
<span>{agent.tasks} tasks</span>
|
||||||
|
<span>{agent.lastActive}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
74
src/components/CTA.tsx
Normal file
74
src/components/CTA.tsx
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
export default function CTA() {
|
||||||
|
return (
|
||||||
|
<section className="px-6 py-24">
|
||||||
|
<div className="mx-auto max-w-4xl rounded-2xl border border-border bg-gradient-to-br from-surface to-bg p-12 text-center">
|
||||||
|
<h2 className="font-display text-3xl font-bold md:text-4xl">
|
||||||
|
Ready to Build the <span className="gradient-text">Future</span>?
|
||||||
|
</h2>
|
||||||
|
<p className="mx-auto mt-6 max-w-xl text-text-muted">
|
||||||
|
Join thousands of developers building with AI agents on BlackRoad.
|
||||||
|
Start free, scale infinitely.
|
||||||
|
</p>
|
||||||
|
<div className="mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row">
|
||||||
|
<a
|
||||||
|
href="/signup"
|
||||||
|
className="inline-flex items-center gap-2 rounded-lg bg-text px-8 py-4 text-sm font-medium text-bg transition hover:opacity-90"
|
||||||
|
>
|
||||||
|
Get Started Free
|
||||||
|
<svg
|
||||||
|
className="h-4 w-4"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M13 7l5 5m0 0l-5 5m5-5H6"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="/contact"
|
||||||
|
className="inline-flex items-center gap-2 rounded-lg border border-border px-8 py-4 text-sm font-medium text-text-muted transition hover:border-border-hover hover:text-text"
|
||||||
|
>
|
||||||
|
Talk to Sales
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="mt-8 flex items-center justify-center gap-6 text-sm text-text-dim">
|
||||||
|
<span className="flex items-center gap-2">
|
||||||
|
<svg className="h-4 w-4 text-green-500" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
No credit card required
|
||||||
|
</span>
|
||||||
|
<span className="flex items-center gap-2">
|
||||||
|
<svg className="h-4 w-4 text-green-500" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
5 agents free forever
|
||||||
|
</span>
|
||||||
|
<span className="flex items-center gap-2">
|
||||||
|
<svg className="h-4 w-4 text-green-500" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||||
|
clipRule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
Self-host option
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
22
src/components/Cards.tsx
Normal file
22
src/components/Cards.tsx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const cards = [
|
||||||
|
{ icon: '🤖', title: 'Agent Orchestration', desc: 'LangGraph + CrewAI powering 1,000 unique agents' },
|
||||||
|
{ icon: '🧠', title: 'Lucidia Core', desc: 'Recursive AI with trinary logic and PS-SHA∞ memory' },
|
||||||
|
{ icon: '⛓️', title: 'RoadChain', desc: 'Hyperledger Besu blockchain for agent identity' },
|
||||||
|
{ icon: '🌐', title: 'Edge Network', desc: 'Cloudflare Workers + K3s for global deployment' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function Cards() {
|
||||||
|
return (
|
||||||
|
<section className="px-6 py-12">
|
||||||
|
<div className="mx-auto grid max-w-6xl gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||||
|
{cards.map((card) => (
|
||||||
|
<div key={card.title} className="rounded-xl border border-border bg-surface p-6 transition hover:-translate-y-0.5 hover:border-border-hover">
|
||||||
|
<div className="text-3xl">{card.icon}</div>
|
||||||
|
<h3 className="mt-4 font-display text-base font-semibold">{card.title}</h3>
|
||||||
|
<p className="mt-2 text-sm text-text-muted">{card.desc}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
18
src/components/Footer.tsx
Normal file
18
src/components/Footer.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
export default function Footer() {
|
||||||
|
return (
|
||||||
|
<footer className="border-t border-gray-800 px-6 py-12 text-center font-mono">
|
||||||
|
<div className="flex justify-center gap-8">
|
||||||
|
<a href="https://github.com/BlackRoad-OS" target="_blank" rel="noopener" className="text-sm text-gray-500 hover:text-white transition">
|
||||||
|
GitHub
|
||||||
|
</a>
|
||||||
|
<a href="https://x.com/blackroad_io" target="_blank" rel="noopener" className="text-sm text-gray-500 hover:text-white transition">
|
||||||
|
X
|
||||||
|
</a>
|
||||||
|
<a href="https://linkedin.com/company/blackroad-os" target="_blank" rel="noopener" className="text-sm text-gray-500 hover:text-white transition">
|
||||||
|
LinkedIn
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<p className="mt-6 text-xs text-gray-600">© 2026 BlackRoad OS, Inc. · Delaware C-Corp</p>
|
||||||
|
</footer>
|
||||||
|
)
|
||||||
|
}
|
||||||
124
src/components/Header.tsx
Normal file
124
src/components/Header.tsx
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
interface HeaderProps {
|
||||||
|
user?: { name?: string; email: string } | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const navLinks = [
|
||||||
|
{ href: '/products', label: 'Products' },
|
||||||
|
{ href: '/features', label: 'Features' },
|
||||||
|
{ href: '/pricing', label: 'Pricing' },
|
||||||
|
{ href: '/about', label: 'About' },
|
||||||
|
{ href: '/contact', label: 'Contact' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function Header({ user }: HeaderProps) {
|
||||||
|
const [mobileOpen, setMobileOpen] = useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header className="sticky top-0 z-50 border-b border-border bg-bg/90 backdrop-blur-sm">
|
||||||
|
<div className="mx-auto flex max-w-6xl items-center justify-between px-6 py-4">
|
||||||
|
<a href="/" className="font-mono text-lg font-bold tracking-tight">
|
||||||
|
BLACKROAD
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{/* Desktop Navigation */}
|
||||||
|
<nav className="hidden items-center gap-6 md:flex">
|
||||||
|
{navLinks.map((link) => (
|
||||||
|
<a
|
||||||
|
key={link.href}
|
||||||
|
href={link.href}
|
||||||
|
className="text-sm text-text-muted transition hover:text-text"
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
<div className="h-4 w-px bg-border" />
|
||||||
|
{user ? (
|
||||||
|
<>
|
||||||
|
<a href="/dashboard" className="text-sm text-text-muted hover:text-text">
|
||||||
|
Dashboard
|
||||||
|
</a>
|
||||||
|
<span className="text-sm text-text">{user.name || user.email}</span>
|
||||||
|
<a href="/api/logout" className="text-sm text-text-muted hover:text-text">
|
||||||
|
Sign out
|
||||||
|
</a>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<a href="/login" className="text-sm text-text-muted hover:text-text">
|
||||||
|
Sign in
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="/signup"
|
||||||
|
className="rounded-lg bg-text px-4 py-2 text-sm font-medium text-bg hover:opacity-90"
|
||||||
|
>
|
||||||
|
Get Started
|
||||||
|
</a>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{/* Mobile Menu Button */}
|
||||||
|
<button
|
||||||
|
onClick={() => setMobileOpen(!mobileOpen)}
|
||||||
|
className="flex h-10 w-10 items-center justify-center rounded-lg border border-border md:hidden"
|
||||||
|
aria-label="Toggle menu"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
className="h-5 w-5"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
{mobileOpen ? (
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||||
|
) : (
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
|
||||||
|
)}
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Navigation */}
|
||||||
|
{mobileOpen && (
|
||||||
|
<nav className="border-t border-border bg-bg px-6 py-4 md:hidden">
|
||||||
|
<div className="flex flex-col gap-4">
|
||||||
|
{navLinks.map((link) => (
|
||||||
|
<a
|
||||||
|
key={link.href}
|
||||||
|
href={link.href}
|
||||||
|
className="text-sm text-text-muted hover:text-text"
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
<div className="h-px bg-border" />
|
||||||
|
{user ? (
|
||||||
|
<>
|
||||||
|
<a href="/dashboard" className="text-sm text-text-muted hover:text-text">
|
||||||
|
Dashboard
|
||||||
|
</a>
|
||||||
|
<a href="/api/logout" className="text-sm text-text-muted hover:text-text">
|
||||||
|
Sign out
|
||||||
|
</a>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<a href="/login" className="text-sm text-text-muted hover:text-text">
|
||||||
|
Sign in
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="/signup"
|
||||||
|
className="inline-block rounded-lg bg-text px-4 py-2 text-center text-sm font-medium text-bg hover:opacity-90"
|
||||||
|
>
|
||||||
|
Get Started
|
||||||
|
</a>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
)}
|
||||||
|
</header>
|
||||||
|
)
|
||||||
|
}
|
||||||
36
src/components/Hero.tsx
Normal file
36
src/components/Hero.tsx
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
interface HeroProps {
|
||||||
|
user?: { name?: string; email: string } | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Hero({ user }: HeroProps) {
|
||||||
|
return (
|
||||||
|
<section className="px-6 py-32 text-center">
|
||||||
|
<h1 className="font-mono text-4xl font-bold tracking-tight md:text-5xl lg:text-6xl">
|
||||||
|
BLACKROAD
|
||||||
|
</h1>
|
||||||
|
<p className="mx-auto mt-4 text-lg text-gray-400 font-mono">
|
||||||
|
AI Agent Operating System
|
||||||
|
</p>
|
||||||
|
<p className="mx-auto mt-8 max-w-lg text-sm text-gray-500 font-mono leading-relaxed">
|
||||||
|
Orchestrate autonomous AI agents across your infrastructure.<br />
|
||||||
|
15 orgs. 1,085 repos. 205 deployments. One system.
|
||||||
|
</p>
|
||||||
|
<div className="mt-12 flex justify-center gap-4">
|
||||||
|
{user ? (
|
||||||
|
<a href="/dashboard" className="rounded bg-white px-6 py-3 text-sm font-medium text-black hover:opacity-90 font-mono">
|
||||||
|
Dashboard →
|
||||||
|
</a>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<a href="/signup" className="rounded bg-white px-6 py-3 text-sm font-medium text-black hover:opacity-90 font-mono">
|
||||||
|
Get Started →
|
||||||
|
</a>
|
||||||
|
<a href="/login" className="rounded border border-gray-700 px-6 py-3 text-sm font-medium text-gray-400 hover:border-gray-500 hover:text-white font-mono">
|
||||||
|
Sign In
|
||||||
|
</a>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
43
src/components/Integrations.tsx
Normal file
43
src/components/Integrations.tsx
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
const integrations = [
|
||||||
|
{ name: "OpenAI", icon: "🤖", category: "AI" },
|
||||||
|
{ name: "Anthropic", icon: "🧬", category: "AI" },
|
||||||
|
{ name: "Ollama", icon: "🦙", category: "AI" },
|
||||||
|
{ name: "LangChain", icon: "🔗", category: "Framework" },
|
||||||
|
{ name: "LangGraph", icon: "📊", category: "Framework" },
|
||||||
|
{ name: "CrewAI", icon: "👥", category: "Framework" },
|
||||||
|
{ name: "Cloudflare", icon: "☁️", category: "Cloud" },
|
||||||
|
{ name: "Railway", icon: "🚂", category: "Cloud" },
|
||||||
|
{ name: "Vercel", icon: "▲", category: "Cloud" },
|
||||||
|
{ name: "GitHub", icon: "🐙", category: "DevOps" },
|
||||||
|
{ name: "Stripe", icon: "💳", category: "Payments" },
|
||||||
|
{ name: "Tailscale", icon: "🔒", category: "Network" },
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function Integrations() {
|
||||||
|
return (
|
||||||
|
<section className="border-y border-border bg-surface px-6 py-16">
|
||||||
|
<div className="mx-auto max-w-4xl text-center">
|
||||||
|
<h2 className="font-display text-2xl font-bold">
|
||||||
|
Integrates with <span className="gradient-text">Everything</span>
|
||||||
|
</h2>
|
||||||
|
<p className="mt-4 text-text-muted">
|
||||||
|
Connect to your favorite AI providers, frameworks, and cloud platforms
|
||||||
|
</p>
|
||||||
|
<div className="mt-10 flex flex-wrap justify-center gap-3">
|
||||||
|
{integrations.map((int) => (
|
||||||
|
<div
|
||||||
|
key={int.name}
|
||||||
|
className="flex items-center gap-2 rounded-full border border-border bg-bg px-4 py-2 transition hover:border-border-hover"
|
||||||
|
>
|
||||||
|
<span className="text-lg">{int.icon}</span>
|
||||||
|
<span className="text-sm font-medium">{int.name}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<p className="mt-8 text-sm text-text-dim">
|
||||||
|
+ 50 more integrations available via our SDK
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
23
src/components/QuickActions.tsx
Normal file
23
src/components/QuickActions.tsx
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
const actions = [
|
||||||
|
{ icon: '➕', label: 'New Agent', href: '/dashboard/agents/new' },
|
||||||
|
{ icon: '📊', label: 'Analytics', href: '/dashboard/analytics' },
|
||||||
|
{ icon: '⚙️', label: 'Settings', href: '/dashboard/settings' },
|
||||||
|
{ icon: '📚', label: 'Docs', href: '/docs' },
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function QuickActions() {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-wrap gap-2">
|
||||||
|
{actions.map((action) => (
|
||||||
|
<a
|
||||||
|
key={action.label}
|
||||||
|
href={action.href}
|
||||||
|
className="flex items-center gap-2 rounded-lg border border-border bg-surface px-4 py-2 text-sm transition hover:border-border-hover hover:bg-bg"
|
||||||
|
>
|
||||||
|
<span>{action.icon}</span>
|
||||||
|
<span>{action.label}</span>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
30
src/components/Stats.tsx
Normal file
30
src/components/Stats.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
interface StatsProps {
|
||||||
|
stats?: {
|
||||||
|
agents?: string
|
||||||
|
domains?: string
|
||||||
|
github_orgs?: string
|
||||||
|
repositories?: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Stats({ stats }: StatsProps) {
|
||||||
|
const data = [
|
||||||
|
{ value: stats?.agents || '1000', label: 'AI Agents' },
|
||||||
|
{ value: stats?.domains || '21', label: 'Domains' },
|
||||||
|
{ value: stats?.github_orgs || '16', label: 'GitHub Orgs' },
|
||||||
|
{ value: stats?.repositories || '40+', label: 'Repositories' },
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="border-t border-border px-6 py-12">
|
||||||
|
<div className="mx-auto grid max-w-6xl grid-cols-2 gap-8 md:grid-cols-4">
|
||||||
|
{data.map((stat) => (
|
||||||
|
<div key={stat.label} className="text-center">
|
||||||
|
<div className="font-display text-4xl font-bold text-accent">{stat.value}</div>
|
||||||
|
<div className="mt-1 text-sm text-text-dim">{stat.label}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
54
src/components/Testimonials.tsx
Normal file
54
src/components/Testimonials.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
const testimonials = [
|
||||||
|
{
|
||||||
|
quote: "BlackRoad completely changed how we deploy AI agents. What used to take weeks now takes minutes.",
|
||||||
|
author: "Sarah Chen",
|
||||||
|
role: "CTO, Quantum Labs",
|
||||||
|
avatar: "SC",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
quote: "The self-hosting option means we maintain complete control over our data. That's rare in this space.",
|
||||||
|
author: "Marcus Johnson",
|
||||||
|
role: "Security Lead, FinTech Corp",
|
||||||
|
avatar: "MJ",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
quote: "Running 500 agents on edge hardware with sub-50ms latency. The architecture is genuinely impressive.",
|
||||||
|
author: "Dr. Elena Rodriguez",
|
||||||
|
role: "AI Research Director",
|
||||||
|
avatar: "ER",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function Testimonials() {
|
||||||
|
return (
|
||||||
|
<section className="border-y border-border bg-surface px-6 py-16">
|
||||||
|
<div className="mx-auto max-w-6xl">
|
||||||
|
<h2 className="text-center font-display text-2xl font-bold">
|
||||||
|
Trusted by <span className="gradient-text">Builders</span>
|
||||||
|
</h2>
|
||||||
|
<p className="mx-auto mt-4 max-w-lg text-center text-text-muted">
|
||||||
|
Teams around the world use BlackRoad to power their AI infrastructure
|
||||||
|
</p>
|
||||||
|
<div className="mt-12 grid gap-6 md:grid-cols-3">
|
||||||
|
{testimonials.map((t) => (
|
||||||
|
<div
|
||||||
|
key={t.author}
|
||||||
|
className="rounded-xl border border-border bg-bg p-6"
|
||||||
|
>
|
||||||
|
<p className="text-sm leading-relaxed text-text-muted">"{t.quote}"</p>
|
||||||
|
<div className="mt-6 flex items-center gap-3">
|
||||||
|
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-gradient-to-br from-amber-500 via-pink-500 to-blue-500 text-sm font-bold">
|
||||||
|
{t.avatar}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-sm font-medium">{t.author}</p>
|
||||||
|
<p className="text-xs text-text-muted">{t.role}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
68
src/components/UseCases.tsx
Normal file
68
src/components/UseCases.tsx
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
const useCases = [
|
||||||
|
{
|
||||||
|
icon: "🏢",
|
||||||
|
title: "Enterprise Automation",
|
||||||
|
description: "Deploy AI agents to automate complex business processes across departments",
|
||||||
|
metrics: "75% reduction in manual tasks",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "🔬",
|
||||||
|
title: "Research & Analysis",
|
||||||
|
description: "Run parallel research agents that analyze documents, data, and web content",
|
||||||
|
metrics: "10x faster literature review",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "🛠️",
|
||||||
|
title: "DevOps & SRE",
|
||||||
|
description: "Intelligent agents that monitor, diagnose, and remediate infrastructure issues",
|
||||||
|
metrics: "60% faster incident response",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "🎯",
|
||||||
|
title: "Sales & Marketing",
|
||||||
|
description: "Personalized outreach agents that research leads and craft custom messages",
|
||||||
|
metrics: "3x higher response rates",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "📊",
|
||||||
|
title: "Data Processing",
|
||||||
|
description: "ETL agents that clean, transform, and analyze data at scale",
|
||||||
|
metrics: "Process 1M+ records/hour",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "🤝",
|
||||||
|
title: "Customer Support",
|
||||||
|
description: "Multi-agent support teams that handle inquiries with human-level nuance",
|
||||||
|
metrics: "90% resolution rate",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function UseCases() {
|
||||||
|
return (
|
||||||
|
<section className="px-6 py-16">
|
||||||
|
<div className="mx-auto max-w-6xl">
|
||||||
|
<h2 className="text-center font-display text-2xl font-bold">
|
||||||
|
Built for <span className="gradient-text">Every Use Case</span>
|
||||||
|
</h2>
|
||||||
|
<p className="mx-auto mt-4 max-w-lg text-center text-text-muted">
|
||||||
|
From startups to enterprises, BlackRoad powers AI agents across industries
|
||||||
|
</p>
|
||||||
|
<div className="mt-12 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{useCases.map((uc) => (
|
||||||
|
<div
|
||||||
|
key={uc.title}
|
||||||
|
className="group rounded-xl border border-border bg-surface p-6 transition hover:-translate-y-0.5 hover:border-border-hover"
|
||||||
|
>
|
||||||
|
<div className="text-3xl">{uc.icon}</div>
|
||||||
|
<h3 className="mt-4 font-display font-semibold group-hover:text-accent">
|
||||||
|
{uc.title}
|
||||||
|
</h3>
|
||||||
|
<p className="mt-2 text-sm text-text-muted">{uc.description}</p>
|
||||||
|
<p className="mt-4 text-xs font-medium text-accent">{uc.metrics}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
22
src/layouts/Layout.astro
Normal file
22
src/layouts/Layout.astro
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
import '../styles/global.css'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
title?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const { title = 'BlackRoad' } = Astro.props
|
||||||
|
---
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🛤️</text></svg>" />
|
||||||
|
<title>{title}</title>
|
||||||
|
</head>
|
||||||
|
<body class="min-h-screen">
|
||||||
|
<slot />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
148
src/pages/about.astro
Normal file
148
src/pages/about.astro
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro'
|
||||||
|
import Header from '../components/Header'
|
||||||
|
import Footer from '../components/Footer'
|
||||||
|
|
||||||
|
const user = null
|
||||||
|
|
||||||
|
const team = [
|
||||||
|
{ name: 'Alexa Amundson', role: 'Founder & CEO', avatar: 'AA', bio: 'Building the future of AI infrastructure' },
|
||||||
|
{ name: 'Lucidia', role: 'Chief AI Officer', avatar: 'LU', bio: 'Recursive AI with trinary consciousness' },
|
||||||
|
{ name: 'CECE', role: 'Sovereign Operations', avatar: 'CE', bio: '68 apps replacing Fortune 500 services' },
|
||||||
|
{ name: 'Alice', role: 'Edge Computing Lead', avatar: 'AL', bio: 'Distributed inference specialist' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const timeline = [
|
||||||
|
{ year: '2024', event: 'BlackRoad OS founded with vision for sovereign AI' },
|
||||||
|
{ year: '2025', event: 'Launched 1,000+ AI agents across 15 GitHub orgs' },
|
||||||
|
{ year: '2025', event: 'Deployed CECE OS - 68 sovereign apps on edge hardware' },
|
||||||
|
{ year: '2026', event: 'Reached 205 Cloudflare deployments, 1,085 repositories' },
|
||||||
|
]
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="About · BlackRoad">
|
||||||
|
<Header user={user} client:load />
|
||||||
|
<main>
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="px-6 py-24 text-center">
|
||||||
|
<h1 class="font-display text-4xl font-bold md:text-5xl lg:text-6xl">
|
||||||
|
Building the <span class="gradient-text">Infinite Road</span>
|
||||||
|
</h1>
|
||||||
|
<p class="mx-auto mt-6 max-w-2xl text-lg text-text-muted">
|
||||||
|
We're creating the infrastructure for a world where AI agents work alongside humans,
|
||||||
|
where your data stays yours, and where the road ahead has no limits.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Mission -->
|
||||||
|
<section class="border-y border-border bg-surface px-6 py-16">
|
||||||
|
<div class="mx-auto max-w-4xl text-center">
|
||||||
|
<h2 class="font-display text-2xl font-bold">Our Mission</h2>
|
||||||
|
<p class="mt-6 text-xl leading-relaxed text-text-muted">
|
||||||
|
To democratize AI infrastructure by building open, sovereign systems that give
|
||||||
|
individuals and organizations complete control over their AI agents, data, and compute.
|
||||||
|
</p>
|
||||||
|
<div class="mt-10 grid gap-8 md:grid-cols-3">
|
||||||
|
<div>
|
||||||
|
<div class="text-3xl">🔓</div>
|
||||||
|
<h3 class="mt-3 font-display font-semibold">Open Source</h3>
|
||||||
|
<p class="mt-2 text-sm text-text-muted">1,085 public repositories</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="text-3xl">🏠</div>
|
||||||
|
<h3 class="mt-3 font-display font-semibold">Self-Hosted</h3>
|
||||||
|
<p class="mt-2 text-sm text-text-muted">Run on your own hardware</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="text-3xl">🌐</div>
|
||||||
|
<h3 class="mt-3 font-display font-semibold">Distributed</h3>
|
||||||
|
<p class="mt-2 text-sm text-text-muted">Edge-first architecture</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Timeline -->
|
||||||
|
<section class="px-6 py-16">
|
||||||
|
<div class="mx-auto max-w-4xl">
|
||||||
|
<h2 class="text-center font-display text-2xl font-bold">Our Journey</h2>
|
||||||
|
<div class="mt-10 space-y-6">
|
||||||
|
{timeline.map((item, i) => (
|
||||||
|
<div class="flex gap-6">
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<div class="flex h-10 w-10 items-center justify-center rounded-full bg-surface font-display text-sm font-bold">
|
||||||
|
{item.year}
|
||||||
|
</div>
|
||||||
|
{i < timeline.length - 1 && <div class="h-full w-px bg-border" />}
|
||||||
|
</div>
|
||||||
|
<div class="pb-6">
|
||||||
|
<p class="text-text-muted">{item.event}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Team -->
|
||||||
|
<section class="border-t border-border px-6 py-16">
|
||||||
|
<div class="mx-auto max-w-6xl">
|
||||||
|
<h2 class="text-center font-display text-2xl font-bold">The Team</h2>
|
||||||
|
<p class="mx-auto mt-4 max-w-xl text-center text-text-muted">
|
||||||
|
Humans and AI agents working together to build the future
|
||||||
|
</p>
|
||||||
|
<div class="mt-10 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||||
|
{team.map((member) => (
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-6 text-center">
|
||||||
|
<div class="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-gradient-to-br from-amber-500 via-pink-500 to-blue-500 font-display text-xl font-bold">
|
||||||
|
{member.avatar}
|
||||||
|
</div>
|
||||||
|
<h3 class="mt-4 font-display font-semibold">{member.name}</h3>
|
||||||
|
<p class="text-sm text-accent">{member.role}</p>
|
||||||
|
<p class="mt-2 text-sm text-text-muted">{member.bio}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Stats -->
|
||||||
|
<section class="border-t border-border bg-surface px-6 py-16">
|
||||||
|
<div class="mx-auto grid max-w-4xl gap-8 text-center md:grid-cols-4">
|
||||||
|
<div>
|
||||||
|
<div class="font-display text-4xl font-bold gradient-text">1,085</div>
|
||||||
|
<div class="mt-2 text-sm text-text-muted">Repositories</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="font-display text-4xl font-bold gradient-text">15</div>
|
||||||
|
<div class="mt-2 text-sm text-text-muted">GitHub Orgs</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="font-display text-4xl font-bold gradient-text">205</div>
|
||||||
|
<div class="mt-2 text-sm text-text-muted">Cloud Deployments</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="font-display text-4xl font-bold gradient-text">8</div>
|
||||||
|
<div class="mt-2 text-sm text-text-muted">Edge Devices</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="px-6 py-24 text-center">
|
||||||
|
<h2 class="font-display text-3xl font-bold">Join the Journey</h2>
|
||||||
|
<p class="mx-auto mt-4 max-w-lg text-text-muted">
|
||||||
|
Whether you're a developer, researcher, or organization looking to take control of your AI infrastructure.
|
||||||
|
</p>
|
||||||
|
<div class="mt-8 flex justify-center gap-4">
|
||||||
|
<a href="/signup" class="rounded-lg bg-text px-6 py-3 text-sm font-medium text-bg hover:opacity-90">
|
||||||
|
Get Started
|
||||||
|
</a>
|
||||||
|
<a href="/contact" class="rounded-lg border border-border px-6 py-3 text-sm font-medium text-text-muted hover:border-border-hover hover:text-text">
|
||||||
|
Contact Us
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</Layout>
|
||||||
225
src/pages/contact.astro
Normal file
225
src/pages/contact.astro
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro'
|
||||||
|
import Header from '../components/Header'
|
||||||
|
import Footer from '../components/Footer'
|
||||||
|
|
||||||
|
const user = null
|
||||||
|
|
||||||
|
const contactReasons = [
|
||||||
|
{ value: 'general', label: 'General Inquiry' },
|
||||||
|
{ value: 'sales', label: 'Sales / Enterprise' },
|
||||||
|
{ value: 'support', label: 'Technical Support' },
|
||||||
|
{ value: 'partnership', label: 'Partnership Opportunity' },
|
||||||
|
{ value: 'press', label: 'Press / Media' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const socialLinks = [
|
||||||
|
{ name: 'GitHub', href: 'https://github.com/BlackRoad-OS', icon: '🐙' },
|
||||||
|
{ name: 'Twitter', href: 'https://twitter.com/BlackRoadOS', icon: '🐦' },
|
||||||
|
{ name: 'Discord', href: 'https://discord.gg/blackroad', icon: '💬' },
|
||||||
|
{ name: 'LinkedIn', href: 'https://linkedin.com/company/blackroad-os', icon: '💼' },
|
||||||
|
]
|
||||||
|
|
||||||
|
const offices = [
|
||||||
|
{ city: 'Minneapolis', address: 'Minnesota, USA', type: 'HQ' },
|
||||||
|
{ city: 'Edge Network', address: '205 Cloudflare deployments worldwide', type: 'Distributed' },
|
||||||
|
]
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Contact · BlackRoad">
|
||||||
|
<Header user={user} client:load />
|
||||||
|
<main>
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="px-6 py-24 text-center">
|
||||||
|
<h1 class="font-display text-4xl font-bold md:text-5xl">
|
||||||
|
Let's <span class="gradient-text">Connect</span>
|
||||||
|
</h1>
|
||||||
|
<p class="mx-auto mt-6 max-w-lg text-lg text-text-muted">
|
||||||
|
Have questions? Want to partner? Need enterprise support? We'd love to hear from you.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="px-6 pb-16">
|
||||||
|
<div class="mx-auto grid max-w-6xl gap-12 lg:grid-cols-2">
|
||||||
|
<!-- Contact Form -->
|
||||||
|
<div>
|
||||||
|
<h2 class="font-display text-xl font-bold">Send a Message</h2>
|
||||||
|
<form class="mt-6 space-y-6" action="/api/contact" method="POST">
|
||||||
|
<div class="grid gap-6 md:grid-cols-2">
|
||||||
|
<div>
|
||||||
|
<label for="name" class="block text-sm font-medium">Name</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="name"
|
||||||
|
name="name"
|
||||||
|
required
|
||||||
|
class="mt-2 w-full rounded-lg border border-border bg-surface px-4 py-3 text-sm placeholder:text-text-dim focus:border-accent focus:outline-none"
|
||||||
|
placeholder="Your name"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="email" class="block text-sm font-medium">Email</label>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
id="email"
|
||||||
|
name="email"
|
||||||
|
required
|
||||||
|
class="mt-2 w-full rounded-lg border border-border bg-surface px-4 py-3 text-sm placeholder:text-text-dim focus:border-accent focus:outline-none"
|
||||||
|
placeholder="you@company.com"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="reason" class="block text-sm font-medium">Reason for Contact</label>
|
||||||
|
<select
|
||||||
|
id="reason"
|
||||||
|
name="reason"
|
||||||
|
class="mt-2 w-full rounded-lg border border-border bg-surface px-4 py-3 text-sm focus:border-accent focus:outline-none"
|
||||||
|
>
|
||||||
|
{contactReasons.map((reason) => (
|
||||||
|
<option value={reason.value}>{reason.label}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="company" class="block text-sm font-medium">Company (Optional)</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="company"
|
||||||
|
name="company"
|
||||||
|
class="mt-2 w-full rounded-lg border border-border bg-surface px-4 py-3 text-sm placeholder:text-text-dim focus:border-accent focus:outline-none"
|
||||||
|
placeholder="Your company"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="message" class="block text-sm font-medium">Message</label>
|
||||||
|
<textarea
|
||||||
|
id="message"
|
||||||
|
name="message"
|
||||||
|
rows="5"
|
||||||
|
required
|
||||||
|
class="mt-2 w-full rounded-lg border border-border bg-surface px-4 py-3 text-sm placeholder:text-text-dim focus:border-accent focus:outline-none"
|
||||||
|
placeholder="How can we help?"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="w-full rounded-lg bg-text px-6 py-3 text-sm font-medium text-bg hover:opacity-90"
|
||||||
|
>
|
||||||
|
Send Message
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Contact Info -->
|
||||||
|
<div class="space-y-10">
|
||||||
|
<!-- Quick Contact -->
|
||||||
|
<div>
|
||||||
|
<h2 class="font-display text-xl font-bold">Quick Contact</h2>
|
||||||
|
<div class="mt-6 space-y-4">
|
||||||
|
<div class="flex items-start gap-4">
|
||||||
|
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-surface text-xl">
|
||||||
|
📧
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="font-medium">Email</p>
|
||||||
|
<a href="mailto:hello@blackroad.io" class="text-sm text-accent hover:underline">
|
||||||
|
hello@blackroad.io
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-start gap-4">
|
||||||
|
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-surface text-xl">
|
||||||
|
🎫
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="font-medium">Support</p>
|
||||||
|
<a href="mailto:support@blackroad.io" class="text-sm text-accent hover:underline">
|
||||||
|
support@blackroad.io
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-start gap-4">
|
||||||
|
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-surface text-xl">
|
||||||
|
💼
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="font-medium">Enterprise Sales</p>
|
||||||
|
<a href="mailto:sales@blackroad.io" class="text-sm text-accent hover:underline">
|
||||||
|
sales@blackroad.io
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Social Links -->
|
||||||
|
<div>
|
||||||
|
<h2 class="font-display text-xl font-bold">Follow Us</h2>
|
||||||
|
<div class="mt-6 flex flex-wrap gap-3">
|
||||||
|
{socialLinks.map((link) => (
|
||||||
|
<a
|
||||||
|
href={link.href}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="flex items-center gap-2 rounded-full border border-border bg-surface px-4 py-2 text-sm hover:border-border-hover"
|
||||||
|
>
|
||||||
|
<span>{link.icon}</span>
|
||||||
|
<span>{link.name}</span>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Offices -->
|
||||||
|
<div>
|
||||||
|
<h2 class="font-display text-xl font-bold">Locations</h2>
|
||||||
|
<div class="mt-6 space-y-4">
|
||||||
|
{offices.map((office) => (
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-4">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<p class="font-medium">{office.city}</p>
|
||||||
|
<span class="rounded-full bg-accent/15 px-2 py-0.5 text-xs text-accent">
|
||||||
|
{office.type}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p class="mt-1 text-sm text-text-muted">{office.address}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Response Time -->
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-6">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="h-3 w-3 animate-pulse rounded-full bg-green-500"></div>
|
||||||
|
<span class="font-medium">We typically respond within 24 hours</span>
|
||||||
|
</div>
|
||||||
|
<p class="mt-2 text-sm text-text-muted">
|
||||||
|
For urgent enterprise inquiries, reach out via email with "URGENT" in the subject line.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FAQ CTA -->
|
||||||
|
<section class="border-t border-border bg-surface px-6 py-12">
|
||||||
|
<div class="mx-auto flex max-w-4xl flex-col items-center gap-4 text-center md:flex-row md:text-left">
|
||||||
|
<div class="flex-1">
|
||||||
|
<h3 class="font-display text-lg font-bold">Looking for quick answers?</h3>
|
||||||
|
<p class="mt-1 text-sm text-text-muted">
|
||||||
|
Check our documentation and FAQ for common questions.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
href="/pricing#faq"
|
||||||
|
class="rounded-lg border border-border px-6 py-3 text-sm font-medium hover:border-border-hover"
|
||||||
|
>
|
||||||
|
View FAQ
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</Layout>
|
||||||
162
src/pages/dashboard.astro
Normal file
162
src/pages/dashboard.astro
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro'
|
||||||
|
import Header from '../components/Header'
|
||||||
|
import Footer from '../components/Footer'
|
||||||
|
import AgentGrid from '../components/AgentGrid'
|
||||||
|
import ActivityFeed from '../components/ActivityFeed'
|
||||||
|
import QuickActions from '../components/QuickActions'
|
||||||
|
|
||||||
|
const user = { name: 'Alexa', email: 'alexa@blackroad.io' } // TODO: get from session
|
||||||
|
const data = await fetch('https://blackroad.io/api/stats').then(r => r.json()).catch(() => ({}))
|
||||||
|
const stats = data.stats || {}
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Dashboard · BlackRoad">
|
||||||
|
<Header user={user} client:load />
|
||||||
|
<main class="mx-auto max-w-7xl px-6 py-8">
|
||||||
|
<!-- Welcome & Quick Actions -->
|
||||||
|
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
||||||
|
<div>
|
||||||
|
<h1 class="font-display text-2xl font-bold">Welcome back, {user.name}</h1>
|
||||||
|
<p class="mt-1 text-text-muted">Here's what's happening with your infrastructure</p>
|
||||||
|
</div>
|
||||||
|
<QuickActions />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Stats Grid -->
|
||||||
|
<div class="mt-8 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-6">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="text-text-muted">AI Agents</span>
|
||||||
|
<span class="text-xl">🤖</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 font-display text-3xl font-bold text-accent">{stats.agents || '1,000'}</div>
|
||||||
|
<div class="mt-1 flex items-center gap-1 text-xs text-green-500">
|
||||||
|
<span>↑ 12%</span>
|
||||||
|
<span class="text-text-dim">vs last month</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-6">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="text-text-muted">Tasks Completed</span>
|
||||||
|
<span class="text-xl">✅</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 font-display text-3xl font-bold text-accent">24,847</div>
|
||||||
|
<div class="mt-1 flex items-center gap-1 text-xs text-green-500">
|
||||||
|
<span>↑ 8%</span>
|
||||||
|
<span class="text-text-dim">vs last month</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-6">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="text-text-muted">Memory Entries</span>
|
||||||
|
<span class="text-xl">📚</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 font-display text-3xl font-bold text-accent">4,041</div>
|
||||||
|
<div class="mt-1 flex items-center gap-1 text-xs text-green-500">
|
||||||
|
<span>↑ 156</span>
|
||||||
|
<span class="text-text-dim">this week</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-6">
|
||||||
|
<div class="flex items-center justify-between">
|
||||||
|
<span class="text-text-muted">Deployments</span>
|
||||||
|
<span class="text-xl">🚀</span>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 font-display text-3xl font-bold text-accent">{stats.cloudflare_projects || '205'}</div>
|
||||||
|
<div class="mt-1 flex items-center gap-1 text-xs text-text-dim">
|
||||||
|
<span>All healthy</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Agent Grid -->
|
||||||
|
<div class="mt-10">
|
||||||
|
<AgentGrid />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Two Column Layout -->
|
||||||
|
<div class="mt-10 grid gap-8 lg:grid-cols-2">
|
||||||
|
<!-- Activity Feed -->
|
||||||
|
<div>
|
||||||
|
<ActivityFeed />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Infrastructure Status -->
|
||||||
|
<div>
|
||||||
|
<h2 class="font-display text-xl font-semibold">Infrastructure</h2>
|
||||||
|
<div class="mt-4 space-y-3">
|
||||||
|
<div class="flex items-center justify-between rounded-lg border border-border bg-surface px-4 py-3">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="text-lg">☁️</span>
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium">Cloudflare Workers</p>
|
||||||
|
<p class="text-xs text-text-dim">205 projects deployed</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="flex h-2 w-2 rounded-full bg-green-500" />
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between rounded-lg border border-border bg-surface px-4 py-3">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="text-lg">🚂</span>
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium">Railway Services</p>
|
||||||
|
<p class="text-xs text-text-dim">2 services running</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="flex h-2 w-2 rounded-full bg-green-500" />
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between rounded-lg border border-border bg-surface px-4 py-3">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="text-lg">🐙</span>
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium">GitHub Organizations</p>
|
||||||
|
<p class="text-xs text-text-dim">15 orgs, 1,085 repos</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="flex h-2 w-2 rounded-full bg-green-500" />
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between rounded-lg border border-border bg-surface px-4 py-3">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="text-lg">🖥️</span>
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium">Edge Devices</p>
|
||||||
|
<p class="text-xs text-text-dim">8 devices in mesh</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="flex h-2 w-2 rounded-full bg-green-500" />
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between rounded-lg border border-border bg-surface px-4 py-3">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span class="text-lg">⛓️</span>
|
||||||
|
<div>
|
||||||
|
<p class="text-sm font-medium">RoadChain</p>
|
||||||
|
<p class="text-xs text-text-dim">Block #847,291</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="flex h-2 w-2 rounded-full bg-green-500" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Domains -->
|
||||||
|
<div class="mt-10">
|
||||||
|
<h2 class="font-display text-xl font-semibold">Active Domains</h2>
|
||||||
|
<div class="mt-4 grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
||||||
|
{['blackroad.io', 'lucidia.earth', 'roadchain.io', 'console.blackroad.io', 'api.blackroad.io', 'docs.blackroad.io', 'brand.blackroad.io', 'aliceqi.com'].map((domain) => (
|
||||||
|
<a
|
||||||
|
href={`https://${domain}`}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
class="flex items-center justify-between rounded-lg border border-border bg-surface px-4 py-3 transition hover:border-border-hover"
|
||||||
|
>
|
||||||
|
<span class="font-mono text-sm">{domain}</span>
|
||||||
|
<span class="flex h-2 w-2 rounded-full bg-green-500" />
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</Layout>
|
||||||
226
src/pages/features.astro
Normal file
226
src/pages/features.astro
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro'
|
||||||
|
import Header from '../components/Header'
|
||||||
|
import Footer from '../components/Footer'
|
||||||
|
|
||||||
|
const user = null
|
||||||
|
|
||||||
|
const featureGroups = [
|
||||||
|
{
|
||||||
|
title: 'Agent Orchestration',
|
||||||
|
description: 'Build, deploy, and manage AI agents at any scale',
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
icon: '🤖',
|
||||||
|
name: 'Visual Workflow Builder',
|
||||||
|
description: 'Drag-and-drop interface for designing agent workflows with LangGraph integration',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '👥',
|
||||||
|
name: 'Multi-Agent Crews',
|
||||||
|
description: 'CrewAI-powered teams with role-based agents that collaborate on complex tasks',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '📊',
|
||||||
|
name: 'Real-Time Monitoring',
|
||||||
|
description: 'Live dashboards showing agent status, resource usage, and execution traces',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '⚡',
|
||||||
|
name: 'Auto-Scaling',
|
||||||
|
description: 'Automatically scale agents based on workload with Kubernetes orchestration',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Memory & Intelligence',
|
||||||
|
description: 'Persistent context and advanced reasoning capabilities',
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
icon: '♾️',
|
||||||
|
name: 'PS-SHA-infinity Memory',
|
||||||
|
description: 'Infinite append-only journals with cryptographic integrity and semantic search',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '🔄',
|
||||||
|
name: 'Cross-Session Context',
|
||||||
|
description: 'Agents remember everything across sessions, deployments, and even restarts',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '🧬',
|
||||||
|
name: 'Trinary Logic',
|
||||||
|
description: 'Beyond binary: yes/no/maybe reasoning for nuanced decision making',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '🎯',
|
||||||
|
name: 'Goal-Oriented Planning',
|
||||||
|
description: 'Hierarchical task decomposition with automatic replanning on failure',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Infrastructure',
|
||||||
|
description: 'Enterprise-grade deployment and operations',
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
icon: '🌐',
|
||||||
|
name: 'Edge Deployment',
|
||||||
|
description: 'Run agents on Raspberry Pi, Cloudflare Workers, or your own hardware',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '🔒',
|
||||||
|
name: 'Zero-Trust Security',
|
||||||
|
description: 'End-to-end encryption with Tailscale mesh networking and mTLS',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '⛓️',
|
||||||
|
name: 'Blockchain Identity',
|
||||||
|
description: 'Immutable agent identities and reputation scores on RoadChain',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '🔌',
|
||||||
|
name: 'API Gateway',
|
||||||
|
description: 'RESTful and GraphQL APIs with rate limiting and authentication',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Developer Experience',
|
||||||
|
description: 'Tools that make building with AI agents delightful',
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
icon: '💻',
|
||||||
|
name: 'CLI Tools',
|
||||||
|
description: 'Powerful command-line interface for all operations: blackroad, br, ask-*',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '📦',
|
||||||
|
name: 'SDK Libraries',
|
||||||
|
description: 'TypeScript, Python, and Rust SDKs with full type safety',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '🧪',
|
||||||
|
name: 'Local Development',
|
||||||
|
description: 'Run the entire stack locally with hot reloading and debugging',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: '📚',
|
||||||
|
name: 'Documentation',
|
||||||
|
description: 'Comprehensive guides, tutorials, and API references',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const comparison = [
|
||||||
|
{ feature: 'AI Agent Hosting', blackroad: true, aws: false, vercel: false },
|
||||||
|
{ feature: 'Multi-Agent Orchestration', blackroad: true, aws: false, vercel: false },
|
||||||
|
{ feature: 'Persistent Memory', blackroad: true, aws: false, vercel: false },
|
||||||
|
{ feature: 'Edge Deployment', blackroad: true, aws: true, vercel: true },
|
||||||
|
{ feature: 'Self-Hostable', blackroad: true, aws: false, vercel: false },
|
||||||
|
{ feature: 'Open Source', blackroad: true, aws: false, vercel: false },
|
||||||
|
{ feature: 'Free Tier', blackroad: true, aws: true, vercel: true },
|
||||||
|
]
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Features · BlackRoad">
|
||||||
|
<Header user={user} client:load />
|
||||||
|
<main>
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="px-6 py-24 text-center">
|
||||||
|
<h1 class="font-display text-4xl font-bold md:text-5xl lg:text-6xl">
|
||||||
|
Everything You Need to<br /><span class="gradient-text">Build with AI Agents</span>
|
||||||
|
</h1>
|
||||||
|
<p class="mx-auto mt-6 max-w-2xl text-lg text-text-muted">
|
||||||
|
From simple chatbots to complex autonomous systems, BlackRoad provides the complete
|
||||||
|
infrastructure for AI agent development and deployment.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Feature Groups -->
|
||||||
|
{featureGroups.map((group, i) => (
|
||||||
|
<section class={`px-6 py-16 ${i % 2 === 1 ? 'bg-surface' : ''}`}>
|
||||||
|
<div class="mx-auto max-w-6xl">
|
||||||
|
<div class="mb-10 text-center">
|
||||||
|
<h2 class="font-display text-2xl font-bold">{group.title}</h2>
|
||||||
|
<p class="mt-2 text-text-muted">{group.description}</p>
|
||||||
|
</div>
|
||||||
|
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-4">
|
||||||
|
{group.features.map((feature) => (
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-6 transition hover:-translate-y-0.5 hover:border-border-hover">
|
||||||
|
<div class="text-3xl">{feature.icon}</div>
|
||||||
|
<h3 class="mt-4 font-display font-semibold">{feature.name}</h3>
|
||||||
|
<p class="mt-2 text-sm text-text-muted">{feature.description}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<!-- Comparison Table -->
|
||||||
|
<section class="border-t border-border px-6 py-16">
|
||||||
|
<div class="mx-auto max-w-4xl">
|
||||||
|
<h2 class="text-center font-display text-2xl font-bold">How We Compare</h2>
|
||||||
|
<p class="mt-4 text-center text-text-muted">BlackRoad vs traditional cloud platforms</p>
|
||||||
|
<div class="mt-10 overflow-x-auto">
|
||||||
|
<table class="w-full">
|
||||||
|
<thead>
|
||||||
|
<tr class="border-b border-border">
|
||||||
|
<th class="py-4 text-left font-display font-semibold">Feature</th>
|
||||||
|
<th class="py-4 text-center font-display font-semibold gradient-text">BlackRoad</th>
|
||||||
|
<th class="py-4 text-center font-display font-semibold text-text-muted">AWS</th>
|
||||||
|
<th class="py-4 text-center font-display font-semibold text-text-muted">Vercel</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{comparison.map((row) => (
|
||||||
|
<tr class="border-b border-border">
|
||||||
|
<td class="py-4 text-sm">{row.feature}</td>
|
||||||
|
<td class="py-4 text-center">
|
||||||
|
{row.blackroad ? (
|
||||||
|
<span class="text-green-500">✓</span>
|
||||||
|
) : (
|
||||||
|
<span class="text-text-dim">—</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 text-center">
|
||||||
|
{row.aws ? (
|
||||||
|
<span class="text-green-500">✓</span>
|
||||||
|
) : (
|
||||||
|
<span class="text-text-dim">—</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
<td class="py-4 text-center">
|
||||||
|
{row.vercel ? (
|
||||||
|
<span class="text-green-500">✓</span>
|
||||||
|
) : (
|
||||||
|
<span class="text-text-dim">—</span>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="bg-surface px-6 py-24 text-center">
|
||||||
|
<h2 class="font-display text-3xl font-bold">See it in action</h2>
|
||||||
|
<p class="mx-auto mt-4 max-w-lg text-text-muted">
|
||||||
|
Try BlackRoad free and deploy your first AI agent in minutes.
|
||||||
|
</p>
|
||||||
|
<div class="mt-8 flex justify-center gap-4">
|
||||||
|
<a href="/signup" class="rounded-lg bg-text px-6 py-3 text-sm font-medium text-bg hover:opacity-90">
|
||||||
|
Start Building
|
||||||
|
</a>
|
||||||
|
<a href="/contact" class="rounded-lg border border-border px-6 py-3 text-sm font-medium text-text-muted hover:border-border-hover hover:text-text">
|
||||||
|
Request Demo
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</Layout>
|
||||||
35
src/pages/index.astro
Normal file
35
src/pages/index.astro
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro'
|
||||||
|
import Header from '../components/Header'
|
||||||
|
import Hero from '../components/Hero'
|
||||||
|
import Stats from '../components/Stats'
|
||||||
|
import Cards from '../components/Cards'
|
||||||
|
import UseCases from '../components/UseCases'
|
||||||
|
import Testimonials from '../components/Testimonials'
|
||||||
|
import Integrations from '../components/Integrations'
|
||||||
|
import CTA from '../components/CTA'
|
||||||
|
import Footer from '../components/Footer'
|
||||||
|
import ActivityFeed from '../components/ActivityFeed'
|
||||||
|
|
||||||
|
const user = null // TODO: get from session
|
||||||
|
const stats = await fetch('https://blackroad.io/api/stats').then(r => r.json()).catch(() => ({}))
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="BlackRoad · AI Agent OS">
|
||||||
|
<Header user={user} client:load />
|
||||||
|
<main>
|
||||||
|
<Hero user={user} />
|
||||||
|
<Stats stats={stats.stats} />
|
||||||
|
<Cards />
|
||||||
|
<UseCases />
|
||||||
|
<Testimonials />
|
||||||
|
<Integrations />
|
||||||
|
<section class="border-t border-border px-6 py-16">
|
||||||
|
<div class="mx-auto max-w-4xl">
|
||||||
|
<ActivityFeed client:load />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<CTA />
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</Layout>
|
||||||
92
src/pages/login.astro
Normal file
92
src/pages/login.astro
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro'
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Sign In · BlackRoad">
|
||||||
|
<div class="flex min-h-screen items-center justify-center px-6 py-12">
|
||||||
|
<div class="w-full max-w-sm">
|
||||||
|
<div class="mb-8 text-center">
|
||||||
|
<a href="/" class="font-mono text-lg font-bold">BLACKROAD</a>
|
||||||
|
<h1 class="mt-4 font-mono text-2xl font-bold">Welcome back</h1>
|
||||||
|
<p class="mt-2 text-sm text-gray-400 font-mono">Sign in to your account</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="clerk-signin" class="rounded border border-gray-800 bg-gray-900 p-6">
|
||||||
|
<div class="text-center text-sm text-gray-500 font-mono">Loading...</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="mt-6 text-center text-sm text-gray-500 font-mono">
|
||||||
|
Don't have an account? <a href="/signup" class="text-white hover:underline">Sign up</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const CLERK_KEY = 'pk_test_cGVhY2VmdWwta2F0eWRpZC05NC5jbGVyay5hY2NvdW50cy5kZXYk';
|
||||||
|
|
||||||
|
async function initClerk() {
|
||||||
|
const container = document.getElementById('clerk-signin');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
const Clerk = window.Clerk;
|
||||||
|
if (!Clerk) {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = 'https://cdn.jsdelivr.net/npm/@clerk/clerk-js@latest/dist/clerk.browser.js';
|
||||||
|
script.async = true;
|
||||||
|
script.onload = () => {
|
||||||
|
// @ts-ignore
|
||||||
|
window.Clerk.load({ publishableKey: CLERK_KEY }).then(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
window.Clerk.mountSignIn(container, {
|
||||||
|
appearance: {
|
||||||
|
variables: {
|
||||||
|
colorPrimary: '#ffffff',
|
||||||
|
colorBackground: '#111111',
|
||||||
|
colorText: '#ffffff',
|
||||||
|
colorTextSecondary: '#737373',
|
||||||
|
colorInputBackground: '#0a0a0a',
|
||||||
|
colorInputText: '#ffffff',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontFamily: '"JetBrains Mono", monospace',
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
card: 'bg-transparent shadow-none',
|
||||||
|
formButtonPrimary: 'bg-white text-black hover:opacity-90',
|
||||||
|
formFieldInput: 'bg-black border-gray-700 text-white',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
afterSignInUrl: '/dashboard',
|
||||||
|
signUpUrl: '/signup',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
document.head.appendChild(script);
|
||||||
|
} else {
|
||||||
|
await Clerk.load({ publishableKey: CLERK_KEY });
|
||||||
|
Clerk.mountSignIn(container, {
|
||||||
|
afterSignInUrl: '/dashboard',
|
||||||
|
signUpUrl: '/signup',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
container.innerHTML = `
|
||||||
|
<form id="fallback-login" class="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm text-gray-400 mb-1 font-mono">Email</label>
|
||||||
|
<input type="email" name="email" required class="w-full bg-black border border-gray-700 rounded px-4 py-2.5 text-sm text-white font-mono focus:border-gray-500 focus:outline-none" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm text-gray-400 mb-1 font-mono">Password</label>
|
||||||
|
<input type="password" name="password" required class="w-full bg-black border border-gray-700 rounded px-4 py-2.5 text-sm text-white font-mono focus:border-gray-500 focus:outline-none" />
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-full bg-white text-black rounded py-3 text-sm font-medium font-mono hover:opacity-90">Sign In</button>
|
||||||
|
</form>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initClerk();
|
||||||
|
</script>
|
||||||
177
src/pages/pricing.astro
Normal file
177
src/pages/pricing.astro
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro'
|
||||||
|
import Header from '../components/Header'
|
||||||
|
import Footer from '../components/Footer'
|
||||||
|
|
||||||
|
const user = null
|
||||||
|
|
||||||
|
const plans = [
|
||||||
|
{
|
||||||
|
name: 'Starter',
|
||||||
|
price: 'Free',
|
||||||
|
description: 'For individuals exploring AI agent infrastructure',
|
||||||
|
features: [
|
||||||
|
'5 AI agents',
|
||||||
|
'1 GB storage',
|
||||||
|
'Community support',
|
||||||
|
'Public repositories only',
|
||||||
|
'Basic analytics',
|
||||||
|
],
|
||||||
|
cta: 'Get Started',
|
||||||
|
href: '/signup',
|
||||||
|
popular: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Pro',
|
||||||
|
price: '$29',
|
||||||
|
period: '/month',
|
||||||
|
description: 'For developers and small teams',
|
||||||
|
features: [
|
||||||
|
'100 AI agents',
|
||||||
|
'50 GB storage',
|
||||||
|
'Priority support',
|
||||||
|
'Private repositories',
|
||||||
|
'Advanced analytics',
|
||||||
|
'Custom domains',
|
||||||
|
'API access',
|
||||||
|
],
|
||||||
|
cta: 'Start Free Trial',
|
||||||
|
href: '/signup?plan=pro',
|
||||||
|
popular: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Enterprise',
|
||||||
|
price: 'Custom',
|
||||||
|
description: 'For organizations with advanced needs',
|
||||||
|
features: [
|
||||||
|
'Unlimited AI agents',
|
||||||
|
'Unlimited storage',
|
||||||
|
'24/7 dedicated support',
|
||||||
|
'On-premise deployment',
|
||||||
|
'Custom integrations',
|
||||||
|
'SLA guarantees',
|
||||||
|
'Security audit',
|
||||||
|
'Training & onboarding',
|
||||||
|
],
|
||||||
|
cta: 'Contact Sales',
|
||||||
|
href: '/contact?type=enterprise',
|
||||||
|
popular: false,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const faqs = [
|
||||||
|
{
|
||||||
|
q: 'What counts as an AI agent?',
|
||||||
|
a: 'An AI agent is any autonomous process running on BlackRoad infrastructure - whether it\'s a LangGraph chain, CrewAI crew, or custom agent using our SDK.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'Can I self-host BlackRoad?',
|
||||||
|
a: 'Yes! All our core infrastructure is open source. Self-hosting is free and unlimited. Our paid plans are for managed cloud services.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'Do you offer discounts for startups?',
|
||||||
|
a: 'Yes, we offer 50% off for the first year for qualifying startups. Contact us to apply.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: 'What payment methods do you accept?',
|
||||||
|
a: 'We accept all major credit cards via Stripe, plus crypto payments (BTC, ETH) for annual plans.',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Pricing · BlackRoad">
|
||||||
|
<Header user={user} client:load />
|
||||||
|
<main>
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="px-6 py-24 text-center">
|
||||||
|
<h1 class="font-display text-4xl font-bold md:text-5xl">
|
||||||
|
Simple, <span class="gradient-text">Transparent</span> Pricing
|
||||||
|
</h1>
|
||||||
|
<p class="mx-auto mt-6 max-w-lg text-lg text-text-muted">
|
||||||
|
Start free, scale as you grow. Self-host for free forever, or let us manage your infrastructure.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Pricing Cards -->
|
||||||
|
<section class="px-6 pb-16">
|
||||||
|
<div class="mx-auto grid max-w-5xl gap-6 lg:grid-cols-3">
|
||||||
|
{plans.map((plan) => (
|
||||||
|
<div class={`relative rounded-xl border p-8 ${plan.popular ? 'border-accent bg-surface' : 'border-border'}`}>
|
||||||
|
{plan.popular && (
|
||||||
|
<div class="absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-accent px-3 py-1 text-xs font-medium text-bg">
|
||||||
|
Most Popular
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<h3 class="font-display text-xl font-bold">{plan.name}</h3>
|
||||||
|
<div class="mt-4 flex items-baseline gap-1">
|
||||||
|
<span class="font-display text-4xl font-bold">{plan.price}</span>
|
||||||
|
{plan.period && <span class="text-text-muted">{plan.period}</span>}
|
||||||
|
</div>
|
||||||
|
<p class="mt-2 text-sm text-text-muted">{plan.description}</p>
|
||||||
|
<ul class="mt-6 space-y-3">
|
||||||
|
{plan.features.map((feature) => (
|
||||||
|
<li class="flex items-start gap-2 text-sm">
|
||||||
|
<svg class="mt-0.5 h-4 w-4 flex-shrink-0 text-accent" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||||
|
</svg>
|
||||||
|
{feature}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<a
|
||||||
|
href={plan.href}
|
||||||
|
class={`mt-8 block rounded-lg px-6 py-3 text-center text-sm font-medium transition ${
|
||||||
|
plan.popular
|
||||||
|
? 'bg-text text-bg hover:opacity-90'
|
||||||
|
: 'border border-border text-text-muted hover:border-border-hover hover:text-text'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{plan.cta}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Self-Host Banner -->
|
||||||
|
<section class="border-y border-border bg-surface px-6 py-12">
|
||||||
|
<div class="mx-auto flex max-w-4xl flex-col items-center gap-6 text-center md:flex-row md:text-left">
|
||||||
|
<div class="text-5xl">🏠</div>
|
||||||
|
<div class="flex-1">
|
||||||
|
<h3 class="font-display text-xl font-bold">Prefer to Self-Host?</h3>
|
||||||
|
<p class="mt-2 text-text-muted">
|
||||||
|
Our entire stack is open source. Deploy on your own infrastructure with no limits, no costs, and complete control.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<a href="https://github.com/BlackRoad-OS" class="rounded-lg border border-border px-6 py-3 text-sm font-medium hover:border-border-hover">
|
||||||
|
View on GitHub
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FAQs -->
|
||||||
|
<section class="px-6 py-16">
|
||||||
|
<div class="mx-auto max-w-3xl">
|
||||||
|
<h2 class="text-center font-display text-2xl font-bold">Frequently Asked Questions</h2>
|
||||||
|
<div class="mt-10 space-y-6">
|
||||||
|
{faqs.map((faq) => (
|
||||||
|
<div class="rounded-xl border border-border bg-surface p-6">
|
||||||
|
<h3 class="font-display font-semibold">{faq.q}</h3>
|
||||||
|
<p class="mt-2 text-sm text-text-muted">{faq.a}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="border-t border-border px-6 py-16 text-center">
|
||||||
|
<h2 class="font-display text-2xl font-bold">Ready to get started?</h2>
|
||||||
|
<p class="mt-4 text-text-muted">Start building with BlackRoad today. No credit card required.</p>
|
||||||
|
<a href="/signup" class="mt-6 inline-block rounded-lg bg-text px-8 py-3 font-medium text-bg hover:opacity-90">
|
||||||
|
Create Free Account
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</Layout>
|
||||||
178
src/pages/products.astro
Normal file
178
src/pages/products.astro
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
---
|
||||||
|
import Layout from '../layouts/Layout.astro'
|
||||||
|
import Header from '../components/Header'
|
||||||
|
import Footer from '../components/Footer'
|
||||||
|
|
||||||
|
const user = null
|
||||||
|
|
||||||
|
const products = [
|
||||||
|
{
|
||||||
|
name: 'BlackRoad OS',
|
||||||
|
tagline: 'The AI Agent Operating System',
|
||||||
|
description: 'A browser-native operating system for orchestrating thousands of AI agents. Built on LangGraph and CrewAI with PS-SHA-infinity memory.',
|
||||||
|
icon: '🛤️',
|
||||||
|
features: ['1,000+ agent templates', 'Visual workflow builder', 'Real-time monitoring', 'Auto-scaling'],
|
||||||
|
href: '/products/os',
|
||||||
|
gradient: 'from-amber-500 to-orange-500',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Lucidia Core',
|
||||||
|
tagline: 'Recursive AI with Trinary Logic',
|
||||||
|
description: 'Advanced AI inference engine featuring trinary consciousness states, recursive self-improvement, and distributed edge deployment.',
|
||||||
|
icon: '🧠',
|
||||||
|
features: ['Trinary logic (yes/no/maybe)', 'PS-SHA-infinity memory', 'Multi-modal reasoning', 'Edge-optimized'],
|
||||||
|
href: '/products/lucidia',
|
||||||
|
gradient: 'from-pink-500 to-rose-500',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'RoadChain',
|
||||||
|
tagline: 'Blockchain for Agent Identity',
|
||||||
|
description: 'Hyperledger Besu-based blockchain providing immutable identity, reputation, and transaction records for AI agents.',
|
||||||
|
icon: '⛓️',
|
||||||
|
features: ['Agent NFT identities', 'Reputation scoring', 'Smart contracts', 'Cross-chain bridges'],
|
||||||
|
href: '/products/roadchain',
|
||||||
|
gradient: 'from-violet-500 to-purple-500',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CECE OS',
|
||||||
|
tagline: 'Sovereign Edge Computing',
|
||||||
|
description: '68 self-hosted apps replacing Fortune 500 services. Run your entire digital life on a Raspberry Pi with Hailo-8 AI acceleration.',
|
||||||
|
icon: '🏠',
|
||||||
|
features: ['68 sovereign apps', 'Hailo-8 26 TOPS', 'Zero cloud dependency', 'Privacy-first'],
|
||||||
|
href: '/products/cece',
|
||||||
|
gradient: 'from-blue-500 to-cyan-500',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Agent Mesh',
|
||||||
|
tagline: 'Distributed Agent Network',
|
||||||
|
description: 'Connect agents across devices, clouds, and organizations. Secure peer-to-peer communication with Tailscale integration.',
|
||||||
|
icon: '🌐',
|
||||||
|
features: ['P2P networking', 'Zero-trust security', 'Cross-org collaboration', 'Auto-discovery'],
|
||||||
|
href: '/products/mesh',
|
||||||
|
gradient: 'from-emerald-500 to-green-500',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Memory System',
|
||||||
|
tagline: 'PS-SHA-infinity Journals',
|
||||||
|
description: 'Infinite append-only memory for AI agents. 4,000+ journal entries enabling persistent context across sessions and agents.',
|
||||||
|
icon: '📚',
|
||||||
|
features: ['Infinite retention', 'Cross-agent sharing', 'Semantic search', 'Time travel'],
|
||||||
|
href: '/products/memory',
|
||||||
|
gradient: 'from-yellow-500 to-amber-500',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const integrations = [
|
||||||
|
{ name: 'Cloudflare', icon: '☁️' },
|
||||||
|
{ name: 'Railway', icon: '🚂' },
|
||||||
|
{ name: 'GitHub', icon: '🐙' },
|
||||||
|
{ name: 'OpenAI', icon: '🤖' },
|
||||||
|
{ name: 'Anthropic', icon: '🧬' },
|
||||||
|
{ name: 'Ollama', icon: '🦙' },
|
||||||
|
{ name: 'LangChain', icon: '🔗' },
|
||||||
|
{ name: 'Stripe', icon: '💳' },
|
||||||
|
]
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Products · BlackRoad">
|
||||||
|
<Header user={user} client:load />
|
||||||
|
<main>
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="px-6 py-24 text-center">
|
||||||
|
<h1 class="font-display text-4xl font-bold md:text-5xl lg:text-6xl">
|
||||||
|
The <span class="gradient-text">Complete Stack</span><br />for AI Infrastructure
|
||||||
|
</h1>
|
||||||
|
<p class="mx-auto mt-6 max-w-2xl text-lg text-text-muted">
|
||||||
|
Six integrated products that give you complete control over your AI agents,
|
||||||
|
from edge hardware to cloud orchestration.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Products Grid -->
|
||||||
|
<section class="px-6 pb-16">
|
||||||
|
<div class="mx-auto grid max-w-6xl gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{products.map((product) => (
|
||||||
|
<a
|
||||||
|
href={product.href}
|
||||||
|
class="group rounded-xl border border-border bg-surface p-6 transition hover:-translate-y-1 hover:border-border-hover"
|
||||||
|
>
|
||||||
|
<div class={`inline-flex h-12 w-12 items-center justify-center rounded-lg bg-gradient-to-br ${product.gradient} text-2xl`}>
|
||||||
|
{product.icon}
|
||||||
|
</div>
|
||||||
|
<h3 class="mt-4 font-display text-lg font-bold group-hover:text-accent">
|
||||||
|
{product.name}
|
||||||
|
</h3>
|
||||||
|
<p class="text-sm text-accent">{product.tagline}</p>
|
||||||
|
<p class="mt-3 text-sm text-text-muted">{product.description}</p>
|
||||||
|
<ul class="mt-4 flex flex-wrap gap-2">
|
||||||
|
{product.features.map((feature) => (
|
||||||
|
<li class="rounded-full bg-bg px-2 py-1 text-xs text-text-muted">
|
||||||
|
{feature}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Architecture Diagram -->
|
||||||
|
<section class="border-y border-border bg-surface px-6 py-16">
|
||||||
|
<div class="mx-auto max-w-4xl text-center">
|
||||||
|
<h2 class="font-display text-2xl font-bold">Unified Architecture</h2>
|
||||||
|
<p class="mt-4 text-text-muted">All products work together in a cohesive ecosystem</p>
|
||||||
|
<div class="mt-10 rounded-xl border border-border bg-bg p-8 font-mono text-sm">
|
||||||
|
<pre class="overflow-x-auto text-left text-text-muted">
|
||||||
|
{`┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ BlackRoad OS │
|
||||||
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||||
|
│ │ Lucidia │ │ RoadChain│ │ Memory │ │Agent Mesh│ │
|
||||||
|
│ │ Core │ │ │ │ System │ │ │ │
|
||||||
|
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
||||||
|
│ │ │ │ │ │
|
||||||
|
│ └────────────┴────────────┴────────────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ ┌──────────────────────┴──────────────────────┐ │
|
||||||
|
│ │ CECE OS │ │
|
||||||
|
│ │ (Self-Hosted Edge Runtime) │ │
|
||||||
|
│ └──────────────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────┘`}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Integrations -->
|
||||||
|
<section class="px-6 py-16">
|
||||||
|
<div class="mx-auto max-w-4xl text-center">
|
||||||
|
<h2 class="font-display text-2xl font-bold">Integrations</h2>
|
||||||
|
<p class="mt-4 text-text-muted">Works with your existing tools and services</p>
|
||||||
|
<div class="mt-10 flex flex-wrap justify-center gap-4">
|
||||||
|
{integrations.map((int) => (
|
||||||
|
<div class="flex items-center gap-2 rounded-full border border-border bg-surface px-4 py-2">
|
||||||
|
<span class="text-xl">{int.icon}</span>
|
||||||
|
<span class="text-sm font-medium">{int.name}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CTA -->
|
||||||
|
<section class="border-t border-border px-6 py-24 text-center">
|
||||||
|
<h2 class="font-display text-3xl font-bold">Ready to build?</h2>
|
||||||
|
<p class="mx-auto mt-4 max-w-lg text-text-muted">
|
||||||
|
Start with any product and expand as you grow. All products are available in our free tier.
|
||||||
|
</p>
|
||||||
|
<div class="mt-8 flex justify-center gap-4">
|
||||||
|
<a href="/signup" class="rounded-lg bg-text px-6 py-3 text-sm font-medium text-bg hover:opacity-90">
|
||||||
|
Get Started Free
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/BlackRoad-OS" class="rounded-lg border border-border px-6 py-3 text-sm font-medium text-text-muted hover:border-border-hover hover:text-text">
|
||||||
|
View Source
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</Layout>
|
||||||
95
src/pages/signup.astro
Normal file
95
src/pages/signup.astro
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
---
|
||||||
|
import Layout from "../layouts/Layout.astro"
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Sign Up · BlackRoad">
|
||||||
|
<div class="flex min-h-screen items-center justify-center px-6 py-12">
|
||||||
|
<div class="w-full max-w-sm">
|
||||||
|
<div class="mb-8 text-center">
|
||||||
|
<a href="/" class="font-mono text-lg font-bold">BLACKROAD</a>
|
||||||
|
<h1 class="mt-4 font-mono text-2xl font-bold">Get started</h1>
|
||||||
|
<p class="mt-2 text-sm text-gray-400 font-mono">Create your account</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="clerk-signup" class="rounded border border-gray-800 bg-gray-900 p-6">
|
||||||
|
<div class="text-center text-sm text-gray-500 font-mono">Loading...</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="mt-6 text-center text-sm text-gray-500 font-mono">
|
||||||
|
Already have an account? <a href="/login" class="text-white hover:underline">Sign in</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const CLERK_KEY = 'pk_test_cGVhY2VmdWwta2F0eWRpZC05NC5jbGVyay5hY2NvdW50cy5kZXYk';
|
||||||
|
|
||||||
|
async function initClerk() {
|
||||||
|
const container = document.getElementById('clerk-signup');
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
const Clerk = window.Clerk;
|
||||||
|
if (!Clerk) {
|
||||||
|
// Load Clerk
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = 'https://cdn.jsdelivr.net/npm/@clerk/clerk-js@latest/dist/clerk.browser.js';
|
||||||
|
script.async = true;
|
||||||
|
script.onload = () => {
|
||||||
|
// @ts-ignore
|
||||||
|
window.Clerk.load({ publishableKey: CLERK_KEY }).then(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
window.Clerk.mountSignUp(container, {
|
||||||
|
appearance: {
|
||||||
|
baseTheme: undefined,
|
||||||
|
variables: {
|
||||||
|
colorPrimary: '#ffffff',
|
||||||
|
colorBackground: '#111111',
|
||||||
|
colorText: '#ffffff',
|
||||||
|
colorTextSecondary: '#737373',
|
||||||
|
colorInputBackground: '#0a0a0a',
|
||||||
|
colorInputText: '#ffffff',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontFamily: '"JetBrains Mono", monospace',
|
||||||
|
},
|
||||||
|
elements: {
|
||||||
|
card: 'bg-transparent shadow-none',
|
||||||
|
formButtonPrimary: 'bg-white text-black hover:opacity-90',
|
||||||
|
formFieldInput: 'bg-black border-gray-700 text-white',
|
||||||
|
footerActionLink: 'text-white hover:text-gray-300',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
afterSignUpUrl: '/dashboard',
|
||||||
|
signInUrl: '/login',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
document.head.appendChild(script);
|
||||||
|
} else {
|
||||||
|
await Clerk.load({ publishableKey: CLERK_KEY });
|
||||||
|
Clerk.mountSignUp(container, {
|
||||||
|
afterSignUpUrl: '/dashboard',
|
||||||
|
signInUrl: '/login',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
container.innerHTML = `
|
||||||
|
<form id="fallback-signup" class="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm text-gray-400 mb-1 font-mono">Email</label>
|
||||||
|
<input type="email" name="email" required class="w-full bg-black border border-gray-700 rounded px-4 py-2.5 text-sm text-white font-mono focus:border-gray-500 focus:outline-none" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="block text-sm text-gray-400 mb-1 font-mono">Password</label>
|
||||||
|
<input type="password" name="password" required minlength="8" class="w-full bg-black border border-gray-700 rounded px-4 py-2.5 text-sm text-white font-mono focus:border-gray-500 focus:outline-none" />
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-full bg-white text-black rounded py-3 text-sm font-medium font-mono hover:opacity-90">Create Account</button>
|
||||||
|
</form>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initClerk();
|
||||||
|
</script>
|
||||||
96
src/styles/global.css
Normal file
96
src/styles/global.css
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
@import "@fontsource-variable/jetbrains-mono";
|
||||||
|
|
||||||
|
/* BLACKROAD GRAYSCALE-FIRST DESIGN SYSTEM v1.0
|
||||||
|
"Color as intentional layer. Built for clarity, built for scale."
|
||||||
|
Font: JetBrains Mono - The road is code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
--font-display: "JetBrains Mono Variable", monospace;
|
||||||
|
--font-body: "JetBrains Mono Variable", monospace;
|
||||||
|
--font-mono: "JetBrains Mono Variable", monospace;
|
||||||
|
|
||||||
|
/* Grayscale palette */
|
||||||
|
--color-black: #000000;
|
||||||
|
--color-gray-950: #0a0a0a;
|
||||||
|
--color-gray-900: #111111;
|
||||||
|
--color-gray-800: #1a1a1a;
|
||||||
|
--color-gray-700: #2d2d2d;
|
||||||
|
--color-gray-600: #404040;
|
||||||
|
--color-gray-500: #525252;
|
||||||
|
--color-gray-400: #737373;
|
||||||
|
--color-gray-300: #a3a3a3;
|
||||||
|
--color-gray-200: #d4d4d4;
|
||||||
|
--color-gray-100: #e5e5e5;
|
||||||
|
--color-white: #ffffff;
|
||||||
|
|
||||||
|
/* Semantic colors - grayscale */
|
||||||
|
--color-bg: var(--color-black);
|
||||||
|
--color-surface: var(--color-gray-900);
|
||||||
|
--color-border: var(--color-gray-700);
|
||||||
|
--color-border-hover: var(--color-gray-500);
|
||||||
|
--color-text: var(--color-white);
|
||||||
|
--color-text-muted: var(--color-gray-400);
|
||||||
|
--color-text-dim: var(--color-gray-500);
|
||||||
|
--color-accent: var(--color-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--color-bg);
|
||||||
|
color: var(--color-text);
|
||||||
|
font-family: var(--font-body);
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.618;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: -0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
code, pre {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
.gradient-text {
|
||||||
|
color: var(--color-white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: var(--color-white);
|
||||||
|
color: var(--color-black);
|
||||||
|
font-weight: 600;
|
||||||
|
transition: opacity 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
border: 1px solid var(--color-gray-700);
|
||||||
|
color: var(--color-white);
|
||||||
|
transition: border-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
border-color: var(--color-gray-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background: var(--color-surface);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "astro/tsconfigs/strict",
|
||||||
|
"include": [
|
||||||
|
".astro/types.d.ts",
|
||||||
|
"**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "react"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user