Set up Cloudflare Pages deployment with BlackRoad-branded dashboard
- Convert Next.js dashboard from standalone to static export for CF Pages - Update design tokens, Button, and Card components to official brand colors (hot pink, amber, violet, electric blue with golden ratio spacing) - Replace generic service page with infra dashboard showing deploy/setup stats, Terraform/CI/Docker/Operations sections, and network topology - Remove API routes (incompatible with static export) - Add wrangler.toml and postcss.config.js - Deployed to blackroad-infra.pages.dev Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
import { NextResponse } from 'next/server'
|
|
||||||
|
|
||||||
export async function GET() {
|
|
||||||
const serviceName = process.env.SERVICE_NAME || 'blackroad-service'
|
|
||||||
|
|
||||||
return NextResponse.json({
|
|
||||||
status: 'ok',
|
|
||||||
service: serviceName,
|
|
||||||
timestamp: new Date().toISOString(),
|
|
||||||
uptime: process.uptime()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { NextResponse } from 'next/server'
|
|
||||||
|
|
||||||
export async function GET() {
|
|
||||||
// Add any readiness checks here (database connections, external services, etc.)
|
|
||||||
const isReady = true
|
|
||||||
|
|
||||||
if (!isReady) {
|
|
||||||
return NextResponse.json(
|
|
||||||
{ ready: false, reason: 'Service dependencies not available' },
|
|
||||||
{ status: 503 }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return NextResponse.json({
|
|
||||||
ready: true,
|
|
||||||
service: process.env.SERVICE_NAME || 'blackroad-service'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import { NextResponse } from 'next/server'
|
|
||||||
|
|
||||||
export async function GET() {
|
|
||||||
const serviceName = process.env.SERVICE_NAME || 'blackroad-service'
|
|
||||||
const version = process.env.SERVICE_VERSION || '0.0.1'
|
|
||||||
const environment = process.env.SERVICE_ENV || 'development'
|
|
||||||
|
|
||||||
return NextResponse.json({
|
|
||||||
version,
|
|
||||||
service: serviceName,
|
|
||||||
environment,
|
|
||||||
node_version: process.version,
|
|
||||||
build_time: process.env.BUILD_TIME || new Date().toISOString()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,95 +1,18 @@
|
|||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
html,
|
|
||||||
body {
|
body {
|
||||||
max-width: 100vw;
|
background: #000;
|
||||||
overflow-x: hidden;
|
color: #e0e0e0;
|
||||||
|
font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fadeIn {
|
::selection {
|
||||||
from {
|
background: rgba(255, 29, 108, 0.3);
|
||||||
opacity: 0;
|
color: #fff;
|
||||||
transform: translateY(10px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideIn {
|
|
||||||
from {
|
|
||||||
transform: translateX(-10px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translateX(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes pulse {
|
|
||||||
0%, 100% {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.animate-fade-in {
|
|
||||||
animation: fadeIn 0.5s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.animate-slide-in {
|
|
||||||
animation: slideIn 0.4s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.animate-pulse {
|
|
||||||
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Smooth scrolling */
|
|
||||||
html {
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Focus styles for accessibility */
|
|
||||||
*:focus-visible {
|
|
||||||
outline: 2px solid #667eea;
|
|
||||||
outline-offset: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loading skeleton */
|
|
||||||
@keyframes skeleton {
|
|
||||||
0% {
|
|
||||||
background-position: -200px 0;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
background-position: calc(200px + 100%) 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.skeleton {
|
|
||||||
background: linear-gradient(
|
|
||||||
90deg,
|
|
||||||
rgba(255, 255, 255, 0.05) 0px,
|
|
||||||
rgba(255, 255, 255, 0.1) 40px,
|
|
||||||
rgba(255, 255, 255, 0.05) 80px
|
|
||||||
);
|
|
||||||
background-size: 200px 100%;
|
|
||||||
animation: skeleton 1.2s ease-in-out infinite;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
import type { Metadata } from 'next'
|
import type { Metadata } from 'next'
|
||||||
|
import './globals.css'
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: process.env.NEXT_PUBLIC_APP_NAME || 'BlackRoad Service',
|
title: 'BlackRoad Infrastructure',
|
||||||
description: 'BlackRoad infrastructure service',
|
description: 'Deployment automation, CI/CD workflows, Terraform modules, and infrastructure-as-code for the BlackRoad OS distributed network.',
|
||||||
|
icons: {
|
||||||
|
icon: '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>',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
@@ -12,12 +16,7 @@ export default function RootLayout({
|
|||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body style={{
|
<body>
|
||||||
margin: 0,
|
|
||||||
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
||||||
backgroundColor: '#0a0a0a',
|
|
||||||
color: '#e0e0e0'
|
|
||||||
}}>
|
|
||||||
{children}
|
{children}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,8 +1,4 @@
|
|||||||
export default function Home() {
|
export default function Home() {
|
||||||
const serviceName = process.env.SERVICE_NAME || 'blackroad-service'
|
|
||||||
const serviceEnv = process.env.SERVICE_ENV || 'development'
|
|
||||||
const appName = process.env.NEXT_PUBLIC_APP_NAME || 'BlackRoad Service'
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main style={{
|
<main style={{
|
||||||
minHeight: '100vh',
|
minHeight: '100vh',
|
||||||
@@ -10,136 +6,198 @@ export default function Home() {
|
|||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
padding: '2rem'
|
padding: '34px',
|
||||||
}}>
|
|
||||||
<div style={{
|
|
||||||
maxWidth: '800px',
|
|
||||||
width: '100%',
|
|
||||||
padding: '2rem',
|
|
||||||
backgroundColor: '#1a1a1a',
|
|
||||||
borderRadius: '8px',
|
|
||||||
border: '1px solid #333'
|
|
||||||
}}>
|
}}>
|
||||||
|
<div style={{ maxWidth: '900px', width: '100%' }}>
|
||||||
<h1 style={{
|
<h1 style={{
|
||||||
fontSize: '2.5rem',
|
fontSize: '2.5rem',
|
||||||
marginBottom: '0.5rem',
|
marginBottom: '13px',
|
||||||
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
background: 'linear-gradient(135deg, #F5A623 0%, #FF1D6C 38.2%, #9C27B0 61.8%, #2979FF 100%)',
|
||||||
WebkitBackgroundClip: 'text',
|
WebkitBackgroundClip: 'text',
|
||||||
WebkitTextFillColor: 'transparent',
|
WebkitTextFillColor: 'transparent',
|
||||||
backgroundClip: 'text'
|
backgroundClip: 'text',
|
||||||
|
fontWeight: 700,
|
||||||
}}>
|
}}>
|
||||||
{appName}
|
BlackRoad Infrastructure
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div style={{
|
|
||||||
display: 'flex',
|
|
||||||
gap: '1rem',
|
|
||||||
marginBottom: '2rem',
|
|
||||||
fontSize: '0.875rem'
|
|
||||||
}}>
|
|
||||||
<span style={{
|
|
||||||
padding: '0.25rem 0.75rem',
|
|
||||||
backgroundColor: '#2a2a2a',
|
|
||||||
borderRadius: '4px',
|
|
||||||
border: '1px solid #444'
|
|
||||||
}}>
|
|
||||||
{serviceName}
|
|
||||||
</span>
|
|
||||||
<span style={{
|
|
||||||
padding: '0.25rem 0.75rem',
|
|
||||||
backgroundColor: serviceEnv === 'production' ? '#1a472a' : '#2a2a2a',
|
|
||||||
borderRadius: '4px',
|
|
||||||
border: `1px solid ${serviceEnv === 'production' ? '#2d5f3d' : '#444'}`
|
|
||||||
}}>
|
|
||||||
{serviceEnv}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p style={{
|
<p style={{
|
||||||
fontSize: '1.125rem',
|
fontSize: '1.1rem',
|
||||||
lineHeight: '1.75',
|
color: '#999',
|
||||||
marginBottom: '2rem',
|
marginBottom: '55px',
|
||||||
color: '#b0b0b0'
|
lineHeight: 1.618,
|
||||||
}}>
|
}}>
|
||||||
BlackRoad infrastructure service endpoint. This service is part of the BlackRoad ecosystem.
|
Deployment automation, CI/CD workflows, Terraform modules, and infrastructure-as-code for the BlackRoad OS distributed network.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div style={{
|
<div style={{
|
||||||
display: 'grid',
|
display: 'grid',
|
||||||
gap: '1rem',
|
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
||||||
marginTop: '2rem'
|
gap: '21px',
|
||||||
|
marginBottom: '55px',
|
||||||
}}>
|
}}>
|
||||||
<h2 style={{
|
<StatCard label="Deploy Scripts" value="94" desc="Automated pipelines" color="#FF1D6C" />
|
||||||
fontSize: '1.25rem',
|
<StatCard label="Setup Scripts" value="32" desc="Configuration automation" color="#F5A623" />
|
||||||
marginBottom: '0.5rem',
|
<StatCard label="Terraform Modules" value="IaC" desc="Multi-cloud provisioning" color="#9C27B0" />
|
||||||
color: '#e0e0e0'
|
<StatCard label="Fleet Devices" value="8" desc="Connected nodes" color="#2979FF" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
|
||||||
|
gap: '21px',
|
||||||
|
marginBottom: '55px',
|
||||||
}}>
|
}}>
|
||||||
Service Endpoints
|
<SectionCard
|
||||||
</h2>
|
title="Terraform"
|
||||||
|
items={[
|
||||||
|
'Cloudflare DNS & Pages modules',
|
||||||
|
'DigitalOcean droplet provisioning',
|
||||||
|
'Railway service orchestration',
|
||||||
|
'Production & staging environments',
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<SectionCard
|
||||||
|
title="CI / CD"
|
||||||
|
items={[
|
||||||
|
'Reusable GitHub Actions workflows',
|
||||||
|
'Composite action templates',
|
||||||
|
'Auto-deploy on push to main',
|
||||||
|
'Multi-environment promotion',
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<SectionCard
|
||||||
|
title="Docker"
|
||||||
|
items={[
|
||||||
|
'Multi-service compose stacks',
|
||||||
|
'Optimized production images',
|
||||||
|
'Health check integration',
|
||||||
|
'Container orchestration',
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
<SectionCard
|
||||||
|
title="Operations"
|
||||||
|
items={[
|
||||||
|
'Fleet SSH management',
|
||||||
|
'Tailscale mesh networking',
|
||||||
|
'Monitoring & alerting',
|
||||||
|
'Backup & disaster recovery',
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<a
|
<div style={{
|
||||||
href="/api/health"
|
background: '#111',
|
||||||
style={{
|
border: '1px solid #222',
|
||||||
display: 'block',
|
borderRadius: '13px',
|
||||||
padding: '1rem',
|
padding: '21px',
|
||||||
backgroundColor: '#2a2a2a',
|
marginBottom: '55px',
|
||||||
borderRadius: '6px',
|
}}>
|
||||||
border: '1px solid #444',
|
<h3 style={{
|
||||||
textDecoration: 'none',
|
color: '#F5A623',
|
||||||
color: '#667eea',
|
fontSize: '0.85rem',
|
||||||
transition: 'all 0.2s'
|
textTransform: 'uppercase',
|
||||||
}}
|
letterSpacing: '1px',
|
||||||
>
|
marginBottom: '13px',
|
||||||
<strong>/api/health</strong>
|
}}>
|
||||||
<span style={{ color: '#888', marginLeft: '1rem' }}>→ Health check endpoint</span>
|
Network Topology
|
||||||
</a>
|
</h3>
|
||||||
|
<div style={{
|
||||||
<a
|
fontFamily: "'SF Mono', Monaco, Consolas, monospace",
|
||||||
href="/api/version"
|
fontSize: '0.8rem',
|
||||||
style={{
|
color: '#666',
|
||||||
display: 'block',
|
lineHeight: 1.8,
|
||||||
padding: '1rem',
|
}}>
|
||||||
backgroundColor: '#2a2a2a',
|
<div><span style={{color:'#FF1D6C'}}>alexandria</span> <span style={{color:'#444'}}>──</span> Mac host <span style={{color:'#444'}}>│</span> orchestrator</div>
|
||||||
borderRadius: '6px',
|
<div><span style={{color:'#F5A623'}}>cecilia</span> <span style={{color:'#444'}}>────</span> Pi 5 + Hailo-8 (26 TOPS) <span style={{color:'#444'}}>│</span> primary AI agent</div>
|
||||||
border: '1px solid #444',
|
<div><span style={{color:'#9C27B0'}}>lucidia</span> <span style={{color:'#444'}}>────</span> Pi 5 + Pironman + 1TB NVMe <span style={{color:'#444'}}>│</span> inference</div>
|
||||||
textDecoration: 'none',
|
<div><span style={{color:'#2979FF'}}>octavia</span> <span style={{color:'#444'}}>────</span> Pi 5 <span style={{color:'#444'}}>│</span> multi-arm processing</div>
|
||||||
color: '#667eea',
|
<div><span style={{color:'#4ade80'}}>alice</span> <span style={{color:'#444'}}>──────</span> Pi 4 <span style={{color:'#444'}}>│</span> worker node</div>
|
||||||
transition: 'all 0.2s'
|
<div><span style={{color:'#FF1D6C'}}>aria</span> <span style={{color:'#444'}}>───────</span> Pi 5 <span style={{color:'#444'}}>│</span> harmony protocols</div>
|
||||||
}}
|
<div><span style={{color:'#F5A623'}}>shellfish</span> <span style={{color:'#444'}}>───</span> DigitalOcean <span style={{color:'#444'}}>│</span> edge compute</div>
|
||||||
>
|
<div><span style={{color:'#9C27B0'}}>infinity</span> <span style={{color:'#444'}}>────</span> DigitalOcean <span style={{color:'#444'}}>│</span> cloud oracle</div>
|
||||||
<strong>/api/version</strong>
|
</div>
|
||||||
<span style={{ color: '#888', marginLeft: '1rem' }}>→ Version information</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="/api/ready"
|
|
||||||
style={{
|
|
||||||
display: 'block',
|
|
||||||
padding: '1rem',
|
|
||||||
backgroundColor: '#2a2a2a',
|
|
||||||
borderRadius: '6px',
|
|
||||||
border: '1px solid #444',
|
|
||||||
textDecoration: 'none',
|
|
||||||
color: '#667eea',
|
|
||||||
transition: 'all 0.2s'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<strong>/api/ready</strong>
|
|
||||||
<span style={{ color: '#888', marginLeft: '1rem' }}>→ Readiness probe</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer style={{
|
<footer style={{
|
||||||
marginTop: '3rem',
|
textAlign: 'center',
|
||||||
paddingTop: '1.5rem',
|
color: '#444',
|
||||||
borderTop: '1px solid #333',
|
fontSize: '0.75rem',
|
||||||
fontSize: '0.875rem',
|
paddingTop: '21px',
|
||||||
color: '#666',
|
borderTop: '1px solid #1a1a1a',
|
||||||
textAlign: 'center'
|
|
||||||
}}>
|
}}>
|
||||||
BlackRoad Infrastructure · {new Date().getFullYear()}
|
© 2025–2026 BlackRoad OS, Inc. All Rights Reserved.
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function StatCard({ label, value, desc, color }: { label: string; value: string; desc: string; color: string }) {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
background: '#111',
|
||||||
|
border: '1px solid #222',
|
||||||
|
borderRadius: '13px',
|
||||||
|
padding: '21px',
|
||||||
|
}}>
|
||||||
|
<h3 style={{
|
||||||
|
color,
|
||||||
|
fontSize: '0.8rem',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: '1px',
|
||||||
|
marginBottom: '8px',
|
||||||
|
}}>
|
||||||
|
{label}
|
||||||
|
</h3>
|
||||||
|
<div style={{ fontSize: '1.8rem', fontWeight: 700, color: '#fff', marginBottom: '4px' }}>
|
||||||
|
{value}
|
||||||
|
</div>
|
||||||
|
<div style={{ color: '#666', fontSize: '0.85rem' }}>{desc}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function SectionCard({ title, items }: { title: string; items: string[] }) {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
background: '#111',
|
||||||
|
border: '1px solid #222',
|
||||||
|
borderRadius: '13px',
|
||||||
|
padding: '21px',
|
||||||
|
}}>
|
||||||
|
<h3 style={{
|
||||||
|
color: '#FF1D6C',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
letterSpacing: '1px',
|
||||||
|
marginBottom: '13px',
|
||||||
|
}}>
|
||||||
|
{title}
|
||||||
|
</h3>
|
||||||
|
<ul style={{
|
||||||
|
listStyle: 'none',
|
||||||
|
padding: 0,
|
||||||
|
margin: 0,
|
||||||
|
}}>
|
||||||
|
{items.map((item, i) => (
|
||||||
|
<li key={i} style={{
|
||||||
|
color: '#999',
|
||||||
|
fontSize: '0.85rem',
|
||||||
|
lineHeight: 1.618,
|
||||||
|
paddingLeft: '13px',
|
||||||
|
position: 'relative',
|
||||||
|
}}>
|
||||||
|
<span style={{
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
color: '#444',
|
||||||
|
}}>
|
||||||
|
›
|
||||||
|
</span>
|
||||||
|
{item}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,24 +48,24 @@ const getButtonStyles = (variant: ButtonVariant, size: ButtonSize, disabled: boo
|
|||||||
|
|
||||||
const variantStyles: Record<ButtonVariant, CSSProperties> = {
|
const variantStyles: Record<ButtonVariant, CSSProperties> = {
|
||||||
primary: {
|
primary: {
|
||||||
background: gradients.primary,
|
background: gradients.brand,
|
||||||
color: 'white',
|
color: 'white',
|
||||||
boxShadow: '0 4px 15px rgba(102, 126, 234, 0.4)',
|
boxShadow: '0 4px 15px rgba(255, 29, 108, 0.4)',
|
||||||
},
|
},
|
||||||
secondary: {
|
secondary: {
|
||||||
background: gradients.secondary,
|
background: gradients.pinkToViolet,
|
||||||
color: 'white',
|
color: 'white',
|
||||||
boxShadow: '0 4px 15px rgba(240, 147, 251, 0.4)',
|
boxShadow: '0 4px 15px rgba(156, 39, 176, 0.4)',
|
||||||
},
|
},
|
||||||
tertiary: {
|
tertiary: {
|
||||||
background: gradients.tertiary,
|
background: gradients.blueToViolet,
|
||||||
color: 'white',
|
color: 'white',
|
||||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
boxShadow: '0 4px 15px rgba(41, 121, 255, 0.4)',
|
||||||
},
|
},
|
||||||
ghost: {
|
ghost: {
|
||||||
background: 'transparent',
|
background: 'transparent',
|
||||||
color: colors.primary.purple,
|
color: colors.brand.hotPink,
|
||||||
border: `2px solid ${colors.primary.purple}`,
|
border: `2px solid ${colors.brand.hotPink}`,
|
||||||
},
|
},
|
||||||
danger: {
|
danger: {
|
||||||
background: colors.semantic.error,
|
background: colors.semantic.error,
|
||||||
@@ -87,12 +87,6 @@ export function Button({
|
|||||||
style
|
style
|
||||||
}: ButtonProps) {
|
}: ButtonProps) {
|
||||||
const buttonStyles = getButtonStyles(variant, size, disabled)
|
const buttonStyles = getButtonStyles(variant, size, disabled)
|
||||||
const hoverStyles = !disabled ? {
|
|
||||||
':hover': {
|
|
||||||
transform: 'translateY(-2px)',
|
|
||||||
boxShadow: shadows['2xl']
|
|
||||||
}
|
|
||||||
} : {}
|
|
||||||
|
|
||||||
if (href) {
|
if (href) {
|
||||||
return (
|
return (
|
||||||
@@ -102,7 +96,7 @@ export function Button({
|
|||||||
onMouseEnter={(e) => {
|
onMouseEnter={(e) => {
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
e.currentTarget.style.transform = 'translateY(-2px)'
|
e.currentTarget.style.transform = 'translateY(-2px)'
|
||||||
e.currentTarget.style.boxShadow = shadows['2xl']
|
e.currentTarget.style.boxShadow = shadows.xl
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onMouseLeave={(e) => {
|
onMouseLeave={(e) => {
|
||||||
@@ -122,7 +116,7 @@ export function Button({
|
|||||||
onMouseEnter={(e) => {
|
onMouseEnter={(e) => {
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
e.currentTarget.style.transform = 'translateY(-2px)'
|
e.currentTarget.style.transform = 'translateY(-2px)'
|
||||||
e.currentTarget.style.boxShadow = shadows['2xl']
|
e.currentTarget.style.boxShadow = shadows.xl
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onMouseLeave={(e) => {
|
onMouseLeave={(e) => {
|
||||||
|
|||||||
@@ -19,29 +19,31 @@ export function Card({
|
|||||||
hoverable = false
|
hoverable = false
|
||||||
}: CardProps) {
|
}: CardProps) {
|
||||||
const baseStyles: CSSProperties = {
|
const baseStyles: CSSProperties = {
|
||||||
padding: '2rem',
|
padding: '21px',
|
||||||
borderRadius: borderRadius.xl,
|
borderRadius: borderRadius.lg,
|
||||||
transition: transitions.normal,
|
transition: transitions.normal,
|
||||||
cursor: onClick ? 'pointer' : 'default'
|
cursor: onClick ? 'pointer' : 'default'
|
||||||
}
|
}
|
||||||
|
|
||||||
const variantStyles: Record<string, CSSProperties> = {
|
const variantStyles: Record<string, CSSProperties> = {
|
||||||
default: {
|
default: {
|
||||||
backgroundColor: '#ffffff',
|
backgroundColor: '#111',
|
||||||
|
border: '1px solid #222',
|
||||||
boxShadow: shadows.md,
|
boxShadow: shadows.md,
|
||||||
},
|
},
|
||||||
elevated: {
|
elevated: {
|
||||||
backgroundColor: '#ffffff',
|
backgroundColor: '#111',
|
||||||
boxShadow: shadows['2xl'],
|
border: '1px solid #222',
|
||||||
|
boxShadow: shadows.xl,
|
||||||
},
|
},
|
||||||
outlined: {
|
outlined: {
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
border: '1px solid #e0e0e0',
|
border: '1px solid #333',
|
||||||
},
|
},
|
||||||
glass: {
|
glass: {
|
||||||
background: 'rgba(255, 255, 255, 0.1)',
|
background: 'rgba(255, 255, 255, 0.05)',
|
||||||
backdropFilter: 'blur(10px)',
|
backdropFilter: 'blur(10px)',
|
||||||
border: '1px solid rgba(255, 255, 255, 0.2)',
|
border: '1px solid rgba(255, 255, 255, 0.1)',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,13 +61,13 @@ export function Card({
|
|||||||
onMouseEnter={(e) => {
|
onMouseEnter={(e) => {
|
||||||
if (hoverable || onClick) {
|
if (hoverable || onClick) {
|
||||||
e.currentTarget.style.transform = 'translateY(-4px)'
|
e.currentTarget.style.transform = 'translateY(-4px)'
|
||||||
e.currentTarget.style.boxShadow = shadows['2xl']
|
e.currentTarget.style.boxShadow = shadows.xl
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onMouseLeave={(e) => {
|
onMouseLeave={(e) => {
|
||||||
if (hoverable || onClick) {
|
if (hoverable || onClick) {
|
||||||
e.currentTarget.style.transform = 'translateY(0)'
|
e.currentTarget.style.transform = 'translateY(0)'
|
||||||
e.currentTarget.style.boxShadow = variant === 'elevated' ? shadows['2xl'] : shadows.md
|
e.currentTarget.style.boxShadow = variant === 'elevated' ? shadows.xl : shadows.md
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,102 +1,95 @@
|
|||||||
// BlackRoad Design System Tokens
|
// BlackRoad Official Design System Tokens
|
||||||
|
// Reference: ~/BLACKROAD_BRAND_SYSTEM.md
|
||||||
|
|
||||||
export const colors = {
|
export const colors = {
|
||||||
primary: {
|
brand: {
|
||||||
purple: '#667eea',
|
hotPink: '#FF1D6C',
|
||||||
deepPurple: '#764ba2',
|
amber: '#F5A623',
|
||||||
pink: '#f093fb',
|
electricBlue: '#2979FF',
|
||||||
red: '#f5576c'
|
violet: '#9C27B0',
|
||||||
},
|
},
|
||||||
secondary: {
|
primary: {
|
||||||
cyan: '#4facfe',
|
pink: '#FF1D6C',
|
||||||
lightCyan: '#00f2fe',
|
amber: '#F5A623',
|
||||||
teal: '#a8edea',
|
blue: '#2979FF',
|
||||||
lightPink: '#fed6e3'
|
violet: '#9C27B0',
|
||||||
},
|
},
|
||||||
neutral: {
|
neutral: {
|
||||||
black: '#0a0a0a',
|
black: '#000000',
|
||||||
darkGray: '#1a1a1a',
|
darkGray: '#111111',
|
||||||
gray: '#2a2a2a',
|
gray: '#1a1a1a',
|
||||||
midGray: '#666',
|
midGray: '#666666',
|
||||||
lightGray: '#888',
|
lightGray: '#999999',
|
||||||
offWhite: '#e0e0e0'
|
silver: '#b0b0b0',
|
||||||
|
offWhite: '#e0e0e0',
|
||||||
|
white: '#FFFFFF',
|
||||||
},
|
},
|
||||||
semantic: {
|
semantic: {
|
||||||
success: '#4ade80',
|
success: '#4ade80',
|
||||||
warning: '#fbbf24',
|
warning: '#F5A623',
|
||||||
error: '#ef4444',
|
error: '#ef4444',
|
||||||
info: '#3b82f6'
|
info: '#2979FF',
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const gradients = {
|
export const gradients = {
|
||||||
primary: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
brand: 'linear-gradient(135deg, #F5A623 0%, #FF1D6C 38.2%, #9C27B0 61.8%, #2979FF 100%)',
|
||||||
secondary: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
|
pinkToViolet: 'linear-gradient(135deg, #FF1D6C 0%, #9C27B0 100%)',
|
||||||
tertiary: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
|
amberToPink: 'linear-gradient(135deg, #F5A623 0%, #FF1D6C 100%)',
|
||||||
warm: 'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)',
|
blueToViolet: 'linear-gradient(135deg, #2979FF 0%, #9C27B0 100%)',
|
||||||
cool: 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)',
|
|
||||||
rainbow: 'linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #4facfe 75%, #00f2fe 100%)'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Golden Ratio spacing: 8 -> 13 -> 21 -> 34 -> 55 -> 89 -> 144
|
||||||
export const spacing = {
|
export const spacing = {
|
||||||
xs: '0.25rem',
|
xs: '8px',
|
||||||
sm: '0.5rem',
|
sm: '13px',
|
||||||
md: '1rem',
|
md: '21px',
|
||||||
lg: '1.5rem',
|
lg: '34px',
|
||||||
xl: '2rem',
|
xl: '55px',
|
||||||
'2xl': '3rem',
|
'2xl': '89px',
|
||||||
'3xl': '4rem'
|
'3xl': '144px',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const borderRadius = {
|
export const borderRadius = {
|
||||||
sm: '4px',
|
sm: '4px',
|
||||||
md: '8px',
|
md: '8px',
|
||||||
lg: '12px',
|
lg: '13px',
|
||||||
xl: '16px',
|
xl: '21px',
|
||||||
'2xl': '24px',
|
'2xl': '34px',
|
||||||
full: '9999px'
|
full: '9999px',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const shadows = {
|
export const shadows = {
|
||||||
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
|
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.3)',
|
||||||
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
|
md: '0 4px 6px -1px rgba(0, 0, 0, 0.4)',
|
||||||
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',
|
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.4)',
|
||||||
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1)',
|
xl: '0 20px 25px -5px rgba(0, 0, 0, 0.4)',
|
||||||
'2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
glow: '0 0 40px rgba(255, 29, 108, 0.2)',
|
||||||
glow: '0 0 40px rgba(102, 126, 234, 0.3)'
|
glowAmber: '0 0 40px rgba(245, 166, 35, 0.2)',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const transitions = {
|
export const transitions = {
|
||||||
fast: 'all 0.15s ease',
|
fast: 'all 0.15s ease',
|
||||||
normal: 'all 0.2s ease',
|
normal: 'all 0.2s ease',
|
||||||
slow: 'all 0.3s ease'
|
slow: 'all 0.3s ease',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const typography = {
|
export const typography = {
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
sans: "'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
||||||
mono: '"SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Consolas, "Courier New", monospace'
|
mono: "'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace",
|
||||||
},
|
},
|
||||||
fontSize: {
|
fontSize: {
|
||||||
xs: '0.75rem',
|
xs: '0.75rem',
|
||||||
sm: '0.875rem',
|
sm: '0.85rem',
|
||||||
base: '1rem',
|
base: '1rem',
|
||||||
lg: '1.125rem',
|
lg: '1.1rem',
|
||||||
xl: '1.25rem',
|
xl: '1.25rem',
|
||||||
'2xl': '1.5rem',
|
'2xl': '1.5rem',
|
||||||
'3xl': '1.875rem',
|
'3xl': '2rem',
|
||||||
'4xl': '2.25rem',
|
'4xl': '2.5rem',
|
||||||
'5xl': '3rem',
|
'5xl': '3.25rem',
|
||||||
'6xl': '3.75rem',
|
|
||||||
'7xl': '4.5rem'
|
|
||||||
},
|
},
|
||||||
fontWeight: {
|
|
||||||
normal: 400,
|
|
||||||
medium: 500,
|
|
||||||
semibold: 600,
|
|
||||||
bold: 700,
|
|
||||||
extrabold: 800,
|
|
||||||
black: 900
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const breakpoints = {
|
export const breakpoints = {
|
||||||
@@ -104,5 +97,4 @@ export const breakpoints = {
|
|||||||
md: '768px',
|
md: '768px',
|
||||||
lg: '1024px',
|
lg: '1024px',
|
||||||
xl: '1280px',
|
xl: '1280px',
|
||||||
'2xl': '1536px'
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
output: 'standalone',
|
output: 'export',
|
||||||
|
distDir: 'out',
|
||||||
poweredByHeader: false,
|
poweredByHeader: false,
|
||||||
compress: true,
|
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
|
images: {
|
||||||
|
unoptimized: true,
|
||||||
|
},
|
||||||
env: {
|
env: {
|
||||||
SERVICE_NAME: process.env.SERVICE_NAME || 'blackroad-os-infra',
|
SERVICE_NAME: process.env.SERVICE_NAME || 'blackroad-infra',
|
||||||
SERVICE_ENV: process.env.SERVICE_ENV || 'development',
|
SERVICE_ENV: process.env.SERVICE_ENV || 'production',
|
||||||
|
NEXT_PUBLIC_APP_NAME: process.env.NEXT_PUBLIC_APP_NAME || 'BlackRoad Infrastructure',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
502
dashboard/package-lock.json
generated
Normal file
502
dashboard/package-lock.json
generated
Normal file
@@ -0,0 +1,502 @@
|
|||||||
|
{
|
||||||
|
"name": "blackroad-os-infra",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "blackroad-os-infra",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"dependencies": {
|
||||||
|
"next": "14.2.15",
|
||||||
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.17.6",
|
||||||
|
"@types/react": "^18.3.12",
|
||||||
|
"@types/react-dom": "^18.3.1",
|
||||||
|
"typescript": "^5.6.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/env": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-darwin-arm64": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-darwin-x64": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-arm64-musl": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-x64-gnu": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-x64-musl": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@swc/counter": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
|
||||||
|
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
|
"node_modules/@swc/helpers": {
|
||||||
|
"version": "0.5.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
|
||||||
|
"integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@swc/counter": "^0.1.3",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "20.19.33",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz",
|
||||||
|
"integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.21.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/prop-types": {
|
||||||
|
"version": "15.7.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
|
||||||
|
"integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/react": {
|
||||||
|
"version": "18.3.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz",
|
||||||
|
"integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"csstype": "^3.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/react-dom": {
|
||||||
|
"version": "18.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
|
||||||
|
"integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/busboy": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
|
||||||
|
"dependencies": {
|
||||||
|
"streamsearch": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.16.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/caniuse-lite": {
|
||||||
|
"version": "1.0.30001770",
|
||||||
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz",
|
||||||
|
"integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/browserslist"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "CC-BY-4.0"
|
||||||
|
},
|
||||||
|
"node_modules/client-only": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/csstype": {
|
||||||
|
"version": "3.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||||
|
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/graceful-fs": {
|
||||||
|
"version": "4.2.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||||
|
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/js-tokens": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/loose-envify": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"loose-envify": "cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "3.3.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||||
|
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/next": {
|
||||||
|
"version": "14.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/next/-/next-14.2.15.tgz",
|
||||||
|
"integrity": "sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==",
|
||||||
|
"deprecated": "This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/security-update-2025-12-11 for more details.",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@next/env": "14.2.15",
|
||||||
|
"@swc/helpers": "0.5.5",
|
||||||
|
"busboy": "1.6.0",
|
||||||
|
"caniuse-lite": "^1.0.30001579",
|
||||||
|
"graceful-fs": "^4.2.11",
|
||||||
|
"postcss": "8.4.31",
|
||||||
|
"styled-jsx": "5.1.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"next": "dist/bin/next"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.17.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@next/swc-darwin-arm64": "14.2.15",
|
||||||
|
"@next/swc-darwin-x64": "14.2.15",
|
||||||
|
"@next/swc-linux-arm64-gnu": "14.2.15",
|
||||||
|
"@next/swc-linux-arm64-musl": "14.2.15",
|
||||||
|
"@next/swc-linux-x64-gnu": "14.2.15",
|
||||||
|
"@next/swc-linux-x64-musl": "14.2.15",
|
||||||
|
"@next/swc-win32-arm64-msvc": "14.2.15",
|
||||||
|
"@next/swc-win32-ia32-msvc": "14.2.15",
|
||||||
|
"@next/swc-win32-x64-msvc": "14.2.15"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@opentelemetry/api": "^1.1.0",
|
||||||
|
"@playwright/test": "^1.41.2",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"sass": "^1.3.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@opentelemetry/api": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@playwright/test": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"sass": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/picocolors": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/postcss": {
|
||||||
|
"version": "8.4.31",
|
||||||
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
|
||||||
|
"integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/postcss/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "tidelift",
|
||||||
|
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.3.6",
|
||||||
|
"picocolors": "^1.0.0",
|
||||||
|
"source-map-js": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || >=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react": {
|
||||||
|
"version": "18.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||||
|
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/react-dom": {
|
||||||
|
"version": "18.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||||
|
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"scheduler": "^0.23.2"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^18.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/scheduler": {
|
||||||
|
"version": "0.23.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
|
||||||
|
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/source-map-js": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/streamsearch": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/styled-jsx": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"client-only": "0.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">= 16.8.0 || 17.x.x || ^18.0.0-0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@babel/core": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"babel-plugin-macros": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "5.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
dashboard/postcss.config.js
Normal file
3
dashboard/postcss.config.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {},
|
||||||
|
}
|
||||||
3
wrangler.toml
Normal file
3
wrangler.toml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
name = "blackroad-infra"
|
||||||
|
compatibility_date = "2024-01-01"
|
||||||
|
pages_build_output_dir = "dashboard/out"
|
||||||
Reference in New Issue
Block a user