Initial commit: CHORUS Services marketing website
Complete Next.js website with Docker containerization: - Next.js 14 with TypeScript and Tailwind CSS - Responsive design with modern UI components - Hero section, features showcase, testimonials - FAQ section with comprehensive content - Contact forms and newsletter signup - Docker production build with Nginx - Health checks and monitoring support - SEO optimization and performance tuning Ready for integration as git submodule in main CHORUS project. Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
427
app/globals.css
Normal file
427
app/globals.css
Normal file
@@ -0,0 +1,427 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* Import SF Pro Text font from Apple */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
||||
|
||||
/* CSS Variables for CHORUS theme */
|
||||
:root {
|
||||
--chorus-blue: #007aff;
|
||||
--chorus-green: #30d158;
|
||||
--chorus-charcoal: #1a1a1a;
|
||||
--chorus-charcoal-light: #2a2a2a;
|
||||
--chorus-charcoal-dark: #0f0f0f;
|
||||
|
||||
--text-primary: #ffffff;
|
||||
--text-secondary: #a8a8a8;
|
||||
--text-tertiary: #6d6d6d;
|
||||
|
||||
--border-color: #2a2a2a;
|
||||
--border-color-light: #3a3a3a;
|
||||
}
|
||||
|
||||
/* Base styles */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
scroll-padding-top: 80px; /* Account for fixed navigation */
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'SF Pro Text', 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background-color: var(--chorus-charcoal);
|
||||
color: var(--text-primary);
|
||||
line-height: 1.6;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* Remove focus outline and add custom focus styles */
|
||||
button:focus,
|
||||
input:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Custom focus ring */
|
||||
.focus-ring {
|
||||
@apply ring-2 ring-chorus-blue ring-opacity-50 ring-offset-2 ring-offset-chorus-charcoal;
|
||||
}
|
||||
|
||||
/* Scrollbar styling for webkit browsers */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--chorus-charcoal);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--chorus-charcoal-light);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--border-color-light);
|
||||
}
|
||||
|
||||
/* Selection styling */
|
||||
::selection {
|
||||
background-color: rgba(0, 122, 255, 0.3);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background-color: rgba(0, 122, 255, 0.3);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Typography enhancements */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
letter-spacing: -0.025em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 2.25rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Utility classes */
|
||||
.text-gradient {
|
||||
background: linear-gradient(135deg, var(--chorus-blue) 0%, var(--chorus-green) 100%);
|
||||
background-size: 200% 200%;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
animation: gradient-shift 5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes gradient-shift {
|
||||
0%, 100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Respect reduced motion preferences */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.text-gradient {
|
||||
animation: none;
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.bg-gradient-chorus {
|
||||
background: linear-gradient(135deg, var(--chorus-blue) 0%, var(--chorus-green) 100%);
|
||||
}
|
||||
|
||||
.glass-effect {
|
||||
background: rgba(26, 26, 26, 0.8);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.card-hover {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.card-hover:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Performance optimizations */
|
||||
.will-change-transform {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.will-change-opacity {
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
.gpu-accelerated {
|
||||
transform: translateZ(0);
|
||||
backface-visibility: hidden;
|
||||
perspective: 1000px;
|
||||
}
|
||||
|
||||
/* Animation utilities */
|
||||
.animate-float {
|
||||
animation: float 6s ease-in-out infinite;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-pulse-slow {
|
||||
animation: pulse-slow 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse-slow {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-slide-up {
|
||||
animation: slideUp 0.6s ease-out forwards;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Container utilities */
|
||||
.container-chorus {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.container-chorus {
|
||||
padding: 0 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Button enhancements */
|
||||
.btn-primary {
|
||||
@apply bg-chorus-blue hover:bg-blue-600 text-white font-semibold py-3 px-6 rounded-lg transition-all duration-200 transform hover:scale-105 focus:ring-2 focus:ring-chorus-blue focus:ring-opacity-50;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply bg-transparent border-2 border-chorus-blue text-chorus-blue hover:bg-chorus-blue hover:text-white font-semibold py-3 px-6 rounded-lg transition-all duration-200;
|
||||
}
|
||||
|
||||
/* Loading states */
|
||||
.loading-shimmer {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.05),
|
||||
transparent
|
||||
);
|
||||
background-size: 200% 100%;
|
||||
animation: shimmer 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive text utilities */
|
||||
.text-responsive-xl {
|
||||
@apply text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl;
|
||||
}
|
||||
|
||||
.text-responsive-lg {
|
||||
@apply text-lg sm:text-xl md:text-2xl lg:text-3xl;
|
||||
}
|
||||
|
||||
.text-responsive-md {
|
||||
@apply text-base sm:text-lg md:text-xl;
|
||||
}
|
||||
|
||||
/* Next.js specific overrides */
|
||||
#__next {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Ant Design customizations */
|
||||
.ant-layout {
|
||||
background: var(--chorus-charcoal) !important;
|
||||
}
|
||||
|
||||
.ant-layout-header {
|
||||
background: var(--chorus-charcoal-dark) !important;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
.ant-layout-footer {
|
||||
background: var(--chorus-charcoal-dark) !important;
|
||||
border-top: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
/* Custom component spacing */
|
||||
.section-padding {
|
||||
@apply py-16 sm:py-20 md:py-24 lg:py-32;
|
||||
}
|
||||
|
||||
.section-padding-sm {
|
||||
@apply py-8 sm:py-12 md:py-16;
|
||||
}
|
||||
|
||||
/* Hide scrollbar but keep functionality */
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Section Navigation Tooltip Styles */
|
||||
.section-nav-tooltip .ant-tooltip-content {
|
||||
background: rgba(26, 26, 26, 0.95) !important;
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
.section-nav-tooltip .ant-tooltip-inner {
|
||||
background: transparent !important;
|
||||
color: #ffffff !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
|
||||
/* Technical Specs Page Styles */
|
||||
.glass-tabs .ant-tabs-nav {
|
||||
background: rgba(26, 26, 26, 0.8);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.glass-tabs .ant-tabs-tab {
|
||||
border-radius: 8px !important;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.glass-tabs .ant-tabs-tab-active {
|
||||
background: rgba(0, 122, 255, 0.2) !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.glass-tabs .ant-tabs-tab:hover {
|
||||
background: rgba(255, 255, 255, 0.05) !important;
|
||||
}
|
||||
|
||||
.glass-search .ant-input {
|
||||
background: rgba(26, 26, 26, 0.8) !important;
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1) !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
.glass-search .ant-input:focus {
|
||||
border-color: var(--chorus-blue) !important;
|
||||
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2) !important;
|
||||
}
|
||||
|
||||
.glass-search .ant-input::placeholder {
|
||||
color: #6d6d6d !important;
|
||||
}
|
||||
|
||||
/* Table customizations for technical specs */
|
||||
.ant-table-thead > tr > th {
|
||||
background: rgba(42, 42, 42, 0.8) !important;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1) !important;
|
||||
color: #ffffff !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr > td {
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05) !important;
|
||||
}
|
||||
|
||||
.ant-table-tbody > tr:hover > td {
|
||||
background: rgba(255, 255, 255, 0.02) !important;
|
||||
}
|
||||
|
||||
/* Progress bar customizations */
|
||||
.ant-progress-bg {
|
||||
background: linear-gradient(135deg, var(--chorus-blue) 0%, var(--chorus-green) 100%) !important;
|
||||
}
|
||||
|
||||
/* Collapse panel customizations */
|
||||
.ant-collapse-ghost > .ant-collapse-item > .ant-collapse-header {
|
||||
background: rgba(42, 42, 42, 0.5);
|
||||
border-radius: 8px;
|
||||
margin-bottom: 8px;
|
||||
padding: 12px 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.ant-collapse-ghost > .ant-collapse-item > .ant-collapse-content > .ant-collapse-content-box {
|
||||
background: rgba(26, 26, 26, 0.5);
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* Badge customizations */
|
||||
.ant-badge-status-success {
|
||||
background-color: var(--chorus-green) !important;
|
||||
}
|
||||
|
||||
/* Tag customizations for technical specs */
|
||||
.ant-tag {
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
/* Description list customizations */
|
||||
.ant-descriptions-bordered .ant-descriptions-row > th,
|
||||
.ant-descriptions-bordered .ant-descriptions-row > td {
|
||||
border-color: rgba(255, 255, 255, 0.1) !important;
|
||||
}
|
||||
|
||||
.ant-descriptions-bordered .ant-descriptions-row > th {
|
||||
background: rgba(42, 42, 42, 0.5) !important;
|
||||
color: #ffffff !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.ant-descriptions-bordered .ant-descriptions-row > td {
|
||||
background: rgba(26, 26, 26, 0.3) !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
138
app/layout.tsx
Normal file
138
app/layout.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
import type { Metadata } from 'next';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import { chorusTheme } from '@/theme/chorusTheme';
|
||||
import './globals.css';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: 'CHORUS Services - Distributed AI Orchestration Platform',
|
||||
template: '%s | CHORUS Services',
|
||||
},
|
||||
description: 'Harness the power of distributed AI with CHORUS Services. Orchestrate WHOOSH, BZZZ, SLURP, and COOEE components for scalable, intelligent automation.',
|
||||
keywords: [
|
||||
'AI orchestration',
|
||||
'distributed AI',
|
||||
'automation platform',
|
||||
'CHORUS',
|
||||
'WHOOSH',
|
||||
'BZZZ',
|
||||
'SLURP',
|
||||
'COOEE',
|
||||
'artificial intelligence',
|
||||
'machine learning',
|
||||
'workflow automation',
|
||||
],
|
||||
authors: [{ name: 'CHORUS Services Team' }],
|
||||
creator: 'CHORUS Services',
|
||||
publisher: 'CHORUS Services',
|
||||
openGraph: {
|
||||
type: 'website',
|
||||
locale: 'en_US',
|
||||
url: 'https://chorus.services',
|
||||
siteName: 'CHORUS Services',
|
||||
title: 'CHORUS Services - Distributed AI Orchestration Platform',
|
||||
description: 'Harness the power of distributed AI with CHORUS Services. Orchestrate intelligent components for scalable automation.',
|
||||
images: [
|
||||
{
|
||||
url: '/og-image.png',
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: 'CHORUS Services Platform',
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
title: 'CHORUS Services - Distributed AI Orchestration',
|
||||
description: 'Harness the power of distributed AI with CHORUS Services.',
|
||||
images: ['/og-image.png'],
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
googleBot: {
|
||||
index: true,
|
||||
follow: true,
|
||||
'max-video-preview': -1,
|
||||
'max-image-preview': 'large',
|
||||
'max-snippet': -1,
|
||||
},
|
||||
},
|
||||
verification: {
|
||||
google: '', // Add Google Search Console verification code
|
||||
yandex: '', // Add Yandex verification code if needed
|
||||
},
|
||||
icons: {
|
||||
icon: '/favicon.ico',
|
||||
shortcut: '/favicon-16x16.png',
|
||||
apple: '/apple-touch-icon.png',
|
||||
},
|
||||
manifest: '/manifest.json',
|
||||
viewport: {
|
||||
width: 'device-width',
|
||||
initialScale: 1,
|
||||
maximumScale: 5,
|
||||
},
|
||||
themeColor: [
|
||||
{ media: '(prefers-color-scheme: light)', color: '#007aff' },
|
||||
{ media: '(prefers-color-scheme: dark)', color: '#1a1a1a' },
|
||||
],
|
||||
};
|
||||
|
||||
interface RootLayoutProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function RootLayout({ children }: RootLayoutProps) {
|
||||
return (
|
||||
<html lang="en" className="dark" suppressHydrationWarning>
|
||||
<head>
|
||||
{/* Preconnect to external domains for performance */}
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
|
||||
|
||||
{/* DNS prefetch for better performance */}
|
||||
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
|
||||
|
||||
{/* Viewport meta tag for proper mobile rendering */}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
|
||||
{/* Additional meta tags for better SEO and user experience */}
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
|
||||
{/* Structured data for better SEO */}
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify({
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'Organization',
|
||||
name: 'CHORUS Services',
|
||||
description: 'Distributed AI Orchestration Platform',
|
||||
url: 'https://chorus.services',
|
||||
logo: 'https://chorus.services/logo.png',
|
||||
sameAs: [
|
||||
// Add social media links when available
|
||||
],
|
||||
contactPoint: {
|
||||
'@type': 'ContactPoint',
|
||||
contactType: 'Customer Service',
|
||||
url: 'https://chorus.services/contact',
|
||||
},
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</head>
|
||||
<body className="antialiased bg-chorus-charcoal text-white">
|
||||
<ConfigProvider theme={chorusTheme}>
|
||||
<div className="min-h-screen flex flex-col">
|
||||
{children}
|
||||
</div>
|
||||
</ConfigProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
93
app/page.tsx
Normal file
93
app/page.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
'use client';
|
||||
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Layout, Typography, Button, Space } from 'antd';
|
||||
import Header from '@/components/layout/Header';
|
||||
import Footer from '@/components/layout/Footer';
|
||||
import EnhancedHero from '@/components/sections/EnhancedHero';
|
||||
import WHOOSHShowcase from '@/components/sections/WHOOSHShowcase';
|
||||
import BZZZShowcase from '@/components/sections/BZZZShowcase';
|
||||
import SLURPShowcase from '@/components/sections/SLURPShowcase';
|
||||
import COOEEShowcase from '@/components/sections/COOEEShowcase';
|
||||
import IntegrationShowcase from '@/components/sections/IntegrationShowcase';
|
||||
import SectionNavigation from '@/components/ui/SectionNavigation';
|
||||
import ProgressIndicator from '@/components/ui/ProgressIndicator';
|
||||
|
||||
const { Content } = Layout;
|
||||
const { Title, Paragraph } = Typography;
|
||||
|
||||
// Animation variants for Framer Motion
|
||||
const fadeInUp = {
|
||||
hidden: { opacity: 0, y: 30 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.6, ease: 'easeOut' }
|
||||
}
|
||||
};
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<Layout className="min-h-screen bg-chorus-charcoal">
|
||||
<Content>
|
||||
{/* Enhanced Hero Section */}
|
||||
<EnhancedHero />
|
||||
|
||||
{/* Component Showcase Sections */}
|
||||
<WHOOSHShowcase />
|
||||
<BZZZShowcase />
|
||||
<SLURPShowcase />
|
||||
<COOEEShowcase />
|
||||
<IntegrationShowcase />
|
||||
|
||||
{/* CTA Section */}
|
||||
<section className="section-padding-sm">
|
||||
<div className="container-chorus">
|
||||
<motion.div
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true }}
|
||||
variants={fadeInUp}
|
||||
className="text-center max-w-3xl mx-auto"
|
||||
>
|
||||
<div className="glass-effect rounded-2xl p-8 md:p-12">
|
||||
<Title level={2} className="text-white mb-4">
|
||||
Ready to Transform Your AI Workflow?
|
||||
</Title>
|
||||
<Paragraph className="text-lg text-gray-300 mb-8">
|
||||
Join the next generation of AI orchestration with CHORUS Services.
|
||||
</Paragraph>
|
||||
<Space size="large" className="flex flex-wrap justify-center">
|
||||
<Button
|
||||
type="primary"
|
||||
size="large"
|
||||
className="btn-primary min-w-[140px] h-12"
|
||||
>
|
||||
Get Started
|
||||
</Button>
|
||||
<Button
|
||||
size="large"
|
||||
className="btn-secondary min-w-[140px] h-12"
|
||||
>
|
||||
Learn More
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</Content>
|
||||
</Layout>
|
||||
<Footer />
|
||||
|
||||
{/* Progress Indicator */}
|
||||
<ProgressIndicator />
|
||||
|
||||
{/* Floating Section Navigation */}
|
||||
<SectionNavigation />
|
||||
</>
|
||||
);
|
||||
}
|
||||
47
app/technical-specs/layout.tsx
Normal file
47
app/technical-specs/layout.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Technical Specifications - CHORUS Services',
|
||||
description: 'Comprehensive technical documentation, system requirements, API specifications, and deployment guides for CHORUS Services distributed AI orchestration platform.',
|
||||
keywords: [
|
||||
'technical specifications',
|
||||
'system requirements',
|
||||
'API documentation',
|
||||
'deployment guide',
|
||||
'enterprise features',
|
||||
'performance metrics',
|
||||
'CHORUS Services',
|
||||
'distributed AI',
|
||||
'infrastructure requirements',
|
||||
'scalability',
|
||||
'security specifications',
|
||||
'integration documentation'
|
||||
],
|
||||
openGraph: {
|
||||
title: 'Technical Specifications - CHORUS Services',
|
||||
description: 'Complete technical reference for enterprise decision makers and system architects implementing CHORUS Services.',
|
||||
type: 'website',
|
||||
images: [
|
||||
{
|
||||
url: '/technical-specs-og.png',
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: 'CHORUS Services Technical Specifications',
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
title: 'Technical Specifications - CHORUS Services',
|
||||
description: 'Complete technical reference for enterprise decision makers and system architects.',
|
||||
images: ['/technical-specs-og.png'],
|
||||
},
|
||||
};
|
||||
|
||||
interface TechnicalSpecsLayoutProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function TechnicalSpecsLayout({ children }: TechnicalSpecsLayoutProps) {
|
||||
return children;
|
||||
}
|
||||
668
app/technical-specs/page.tsx
Normal file
668
app/technical-specs/page.tsx
Normal file
@@ -0,0 +1,668 @@
|
||||
'use client';
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import {
|
||||
Layout,
|
||||
Typography,
|
||||
Card,
|
||||
Row,
|
||||
Col,
|
||||
Table,
|
||||
Descriptions,
|
||||
Tabs,
|
||||
Tag,
|
||||
Space,
|
||||
Button,
|
||||
Input,
|
||||
Progress,
|
||||
Statistic,
|
||||
Alert,
|
||||
Collapse,
|
||||
Badge
|
||||
} from 'antd';
|
||||
import {
|
||||
ServerIcon,
|
||||
ShieldIcon,
|
||||
CloudIcon,
|
||||
CodeIcon,
|
||||
DownloadIcon,
|
||||
BarChart3Icon
|
||||
} from 'lucide-react';
|
||||
import Header from '@/components/layout/Header';
|
||||
import Footer from '@/components/layout/Footer';
|
||||
import {
|
||||
performanceMetrics,
|
||||
systemRequirements,
|
||||
apiEndpoints,
|
||||
deploymentOptions,
|
||||
versionCompatibility,
|
||||
enterpriseFeatures,
|
||||
performanceStatistics,
|
||||
downloadableResources,
|
||||
installationGuides,
|
||||
sdkSupport,
|
||||
authenticationMethods,
|
||||
monitoringFeatures,
|
||||
securityFeatures
|
||||
} from '@/utils/technical-specs-data';
|
||||
|
||||
const { Content } = Layout;
|
||||
const { Title, Paragraph, Text } = Typography;
|
||||
const { Search } = Input;
|
||||
const { Panel } = Collapse;
|
||||
|
||||
// Animation variants
|
||||
const fadeInUp = {
|
||||
hidden: { opacity: 0, y: 30 },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: { duration: 0.6, ease: 'easeOut' }
|
||||
}
|
||||
};
|
||||
|
||||
const stagger = {
|
||||
visible: {
|
||||
transition: {
|
||||
staggerChildren: 0.1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Performance columns
|
||||
const performanceColumns = [
|
||||
{
|
||||
title: 'Metric',
|
||||
dataIndex: 'metric',
|
||||
key: 'metric',
|
||||
render: (text: string, record: any) => (
|
||||
<Space>
|
||||
{record.icon}
|
||||
<Text strong>{text}</Text>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Value',
|
||||
dataIndex: 'value',
|
||||
key: 'value',
|
||||
render: (text: string) => <Tag color="blue">{text}</Tag>,
|
||||
},
|
||||
{
|
||||
title: 'Component',
|
||||
dataIndex: 'component',
|
||||
key: 'component',
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
render: (status: string) => {
|
||||
return <Badge status="success" text={status} />;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// System requirements columns
|
||||
const requirementsColumns = [
|
||||
{
|
||||
title: 'Category',
|
||||
dataIndex: 'category',
|
||||
key: 'category',
|
||||
render: (text: string, record: any) => (
|
||||
<Space>
|
||||
{record.icon}
|
||||
<Text strong>{text}</Text>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Minimum',
|
||||
dataIndex: 'minimum',
|
||||
key: 'minimum',
|
||||
},
|
||||
{
|
||||
title: 'Recommended',
|
||||
dataIndex: 'recommended',
|
||||
key: 'recommended',
|
||||
render: (text: string) => <Text type="success">{text}</Text>,
|
||||
},
|
||||
{
|
||||
title: 'Enterprise',
|
||||
dataIndex: 'enterprise',
|
||||
key: 'enterprise',
|
||||
render: (text: string) => <Text type="warning">{text}</Text>,
|
||||
},
|
||||
];
|
||||
|
||||
// API endpoints columns
|
||||
const apiColumns = [
|
||||
{
|
||||
title: 'Method',
|
||||
dataIndex: 'method',
|
||||
key: 'method',
|
||||
render: (method: string) => {
|
||||
const color =
|
||||
method === 'POST' ? 'green' :
|
||||
method === 'GET' ? 'blue' :
|
||||
method === 'WS' ? 'purple' : 'default';
|
||||
return <Tag color={color}>{method}</Tag>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Endpoint',
|
||||
dataIndex: 'endpoint',
|
||||
key: 'endpoint',
|
||||
render: (text: string) => <Text code>{text}</Text>,
|
||||
},
|
||||
{
|
||||
title: 'Description',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
},
|
||||
{
|
||||
title: 'Authentication',
|
||||
dataIndex: 'authentication',
|
||||
key: 'authentication',
|
||||
},
|
||||
{
|
||||
title: 'Rate Limit',
|
||||
dataIndex: 'rateLimit',
|
||||
key: 'rateLimit',
|
||||
},
|
||||
];
|
||||
|
||||
export default function TechnicalSpecsPage() {
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [activeTab, setActiveTab] = useState('performance');
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
key: 'performance',
|
||||
label: (
|
||||
<Space>
|
||||
<BarChart3Icon className="w-4 h-4" />
|
||||
Performance Metrics
|
||||
</Space>
|
||||
),
|
||||
children: (
|
||||
<div className="space-y-6">
|
||||
<Alert
|
||||
message="Performance Benchmarks"
|
||||
description="All metrics are measured under standard production conditions with optimal configuration."
|
||||
type="info"
|
||||
showIcon
|
||||
className="mb-6"
|
||||
/>
|
||||
|
||||
<Row gutter={[24, 24]} className="mb-6">
|
||||
{performanceStatistics.map((stat, index) => (
|
||||
<Col key={index} xs={24} sm={12} lg={6}>
|
||||
<Card className="glass-effect text-center">
|
||||
<Statistic
|
||||
title={stat.title}
|
||||
value={stat.value}
|
||||
suffix={stat.suffix}
|
||||
valueStyle={{ color: stat.color }}
|
||||
prefix={stat.icon}
|
||||
/>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
|
||||
<Table
|
||||
columns={performanceColumns}
|
||||
dataSource={performanceMetrics}
|
||||
pagination={false}
|
||||
className="glass-effect"
|
||||
/>
|
||||
|
||||
<Card className="glass-effect">
|
||||
<Title level={4}>Scalability Architecture</Title>
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col xs={24} md={12}>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Text strong>Horizontal Scaling:</Text>
|
||||
<Progress percent={95} status="active" strokeColor="#30d158" />
|
||||
</div>
|
||||
<div>
|
||||
<Text strong>Load Distribution:</Text>
|
||||
<Progress percent={88} status="active" strokeColor="#007aff" />
|
||||
</div>
|
||||
<div>
|
||||
<Text strong>Auto-scaling:</Text>
|
||||
<Progress percent={92} status="active" strokeColor="#ff9500" />
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs={24} md={12}>
|
||||
<Paragraph>
|
||||
CHORUS Services employs a microservices architecture with automatic horizontal
|
||||
scaling capabilities. Each component can scale independently based on demand,
|
||||
ensuring optimal resource utilization and consistent performance under varying loads.
|
||||
</Paragraph>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'requirements',
|
||||
label: (
|
||||
<Space>
|
||||
<ServerIcon className="w-4 h-4" />
|
||||
System Requirements
|
||||
</Space>
|
||||
),
|
||||
children: (
|
||||
<div className="space-y-6">
|
||||
<Alert
|
||||
message="Infrastructure Planning"
|
||||
description="Choose the configuration that best matches your deployment scale and requirements."
|
||||
type="success"
|
||||
showIcon
|
||||
className="mb-6"
|
||||
/>
|
||||
|
||||
<Table
|
||||
columns={requirementsColumns}
|
||||
dataSource={systemRequirements}
|
||||
pagination={false}
|
||||
className="glass-effect"
|
||||
/>
|
||||
|
||||
<Row gutter={[24, 24]}>
|
||||
<Col xs={24} lg={12}>
|
||||
<Card className="glass-effect" title="Monitoring & Observability">
|
||||
<Space direction="vertical" className="w-full">
|
||||
{monitoringFeatures.map((feature, index) => (
|
||||
<div key={index} className="flex items-center justify-between">
|
||||
<Text>{feature.name}</Text>
|
||||
{feature.icon}
|
||||
</div>
|
||||
))}
|
||||
</Space>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} lg={12}>
|
||||
<Card className="glass-effect" title="Security Features">
|
||||
<Space direction="vertical" className="w-full">
|
||||
{securityFeatures.map((feature, index) => (
|
||||
<div key={index} className="flex items-center justify-between">
|
||||
<Text>{feature.name}</Text>
|
||||
{feature.icon}
|
||||
</div>
|
||||
))}
|
||||
</Space>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'api',
|
||||
label: (
|
||||
<Space>
|
||||
<CodeIcon className="w-4 h-4" />
|
||||
API Documentation
|
||||
</Space>
|
||||
),
|
||||
children: (
|
||||
<div className="space-y-6">
|
||||
<Alert
|
||||
message="RESTful API & WebSocket Support"
|
||||
description="Comprehensive API access with multiple authentication methods and real-time capabilities."
|
||||
type="info"
|
||||
showIcon
|
||||
className="mb-6"
|
||||
/>
|
||||
|
||||
<Table
|
||||
columns={apiColumns}
|
||||
dataSource={apiEndpoints}
|
||||
pagination={false}
|
||||
className="glass-effect"
|
||||
/>
|
||||
|
||||
<Row gutter={[24, 24]}>
|
||||
<Col xs={24} lg={12}>
|
||||
<Card className="glass-effect" title="Authentication Methods">
|
||||
<Collapse ghost>
|
||||
{authenticationMethods.map((method, index) => (
|
||||
<Panel header={method.title} key={index}>
|
||||
<div className="space-y-2">
|
||||
<Text code>{method.example}</Text>
|
||||
<Paragraph className="text-sm text-gray-400">
|
||||
{method.description}
|
||||
</Paragraph>
|
||||
</div>
|
||||
</Panel>
|
||||
))}
|
||||
</Collapse>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col xs={24} lg={12}>
|
||||
<Card className="glass-effect" title="SDK Support">
|
||||
<div className="space-y-4">
|
||||
{sdkSupport.map((sdk, index) => (
|
||||
<div key={index} className="flex items-center justify-between">
|
||||
<Text>{sdk.language}</Text>
|
||||
<Tag color={sdk.color}>{sdk.status}</Tag>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Card className="glass-effect" title="Example Request">
|
||||
<div className="bg-gray-900 rounded-lg p-4 overflow-x-auto">
|
||||
<pre className="text-sm text-gray-300">
|
||||
{`curl -X POST https://api.chorus.services/v1/whoosh/workflow \\
|
||||
-H "Authorization: Bearer YOUR_JWT_TOKEN" \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-d '{
|
||||
"workflow_id": "example-workflow",
|
||||
"parameters": {
|
||||
"target": "production",
|
||||
"agents": ["bzzz-1", "bzzz-2"],
|
||||
"context": "semantic-search-enabled"
|
||||
}
|
||||
}'`}
|
||||
</pre>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'enterprise',
|
||||
label: (
|
||||
<Space>
|
||||
<ShieldIcon className="w-4 h-4" />
|
||||
Enterprise Features
|
||||
</Space>
|
||||
),
|
||||
children: (
|
||||
<div className="space-y-6">
|
||||
<Alert
|
||||
message="Enterprise-Grade Capabilities"
|
||||
description="Advanced features designed for mission-critical deployments and large-scale operations."
|
||||
type="success"
|
||||
showIcon
|
||||
className="mb-6"
|
||||
/>
|
||||
|
||||
<Row gutter={[24, 24]}>
|
||||
{enterpriseFeatures.map((feature, index) => (
|
||||
<Col key={index} xs={24} lg={8}>
|
||||
<Card className="glass-effect h-full" title={feature.category}>
|
||||
<div className="space-y-3">
|
||||
{feature.features.map((item, itemIndex) => (
|
||||
<div key={itemIndex} className="flex items-center space-x-2">
|
||||
<span className={feature.color}>{feature.icon}</span>
|
||||
<Text>{item}</Text>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
|
||||
<Card className="glass-effect" title="Enterprise Support">
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col xs={24} md={12}>
|
||||
<Descriptions column={1} bordered size="small">
|
||||
<Descriptions.Item label="Support Level">24/7 Premium Support</Descriptions.Item>
|
||||
<Descriptions.Item label="Response Time">< 1 hour (Critical)</Descriptions.Item>
|
||||
<Descriptions.Item label="Dedicated CSM">Yes</Descriptions.Item>
|
||||
<Descriptions.Item label="Training">Included</Descriptions.Item>
|
||||
<Descriptions.Item label="Professional Services">Available</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Col>
|
||||
<Col xs={24} md={12}>
|
||||
<div className="space-y-4">
|
||||
<Title level={5}>Included Services</Title>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li className="flex items-center space-x-2">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500 flex-shrink-0" />
|
||||
<Text>Architecture review and optimization</Text>
|
||||
</li>
|
||||
<li className="flex items-center space-x-2">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500 flex-shrink-0" />
|
||||
<Text>Custom integration development</Text>
|
||||
</li>
|
||||
<li className="flex items-center space-x-2">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500 flex-shrink-0" />
|
||||
<Text>Performance tuning and monitoring</Text>
|
||||
</li>
|
||||
<li className="flex items-center space-x-2">
|
||||
<CheckCircleIcon className="w-4 h-4 text-green-500 flex-shrink-0" />
|
||||
<Text>Security audits and recommendations</Text>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'deployment',
|
||||
label: (
|
||||
<Space>
|
||||
<CloudIcon className="w-4 h-4" />
|
||||
Deployment Options
|
||||
</Space>
|
||||
),
|
||||
children: (
|
||||
<div className="space-y-6">
|
||||
<Alert
|
||||
message="Flexible Deployment Models"
|
||||
description="Choose from cloud, on-premises, or hybrid deployments to meet your specific requirements."
|
||||
type="info"
|
||||
showIcon
|
||||
className="mb-6"
|
||||
/>
|
||||
|
||||
<Row gutter={[24, 24]}>
|
||||
{deploymentOptions.map((option) => (
|
||||
<Col key={option.key} xs={24} lg={12}>
|
||||
<Card className="glass-effect h-full" title={option.option}>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Text strong>Platforms:</Text>
|
||||
<div className="mt-2 space-x-1">
|
||||
{option.platforms.map((platform) => (
|
||||
<Tag key={platform} color="blue">{platform}</Tag>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Text strong>Key Features:</Text>
|
||||
<ul className="mt-2 space-y-1">
|
||||
{option.features.map((feature, idx) => (
|
||||
<li key={idx} className="text-sm flex items-center space-x-2">
|
||||
<CheckCircleIcon className="w-3 h-3 text-green-500 flex-shrink-0" />
|
||||
<Text>{feature}</Text>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="flex justify-between items-center pt-2 border-t border-gray-700">
|
||||
<div>
|
||||
<Text strong>Complexity: </Text>
|
||||
<Tag color={
|
||||
option.complexity === 'Low' ? 'green' :
|
||||
option.complexity === 'Medium' ? 'orange' : 'red'
|
||||
}>
|
||||
{option.complexity}
|
||||
</Tag>
|
||||
</div>
|
||||
<div>
|
||||
<Text strong>Cost: </Text>
|
||||
<Tag color="purple">{option.cost}</Tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
|
||||
<Card className="glass-effect" title="Installation Guides">
|
||||
<Row gutter={[16, 16]}>
|
||||
{installationGuides.map((guide, index) => (
|
||||
<Col key={index} xs={24} md={8}>
|
||||
<Button
|
||||
type={index === 0 ? "primary" : undefined}
|
||||
icon={<DownloadIcon className="w-4 h-4" />}
|
||||
block
|
||||
size="large"
|
||||
className="mb-2"
|
||||
href={guide.href}
|
||||
>
|
||||
{guide.title}
|
||||
</Button>
|
||||
<Text className="text-sm text-gray-400">{guide.description}</Text>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<Card className="glass-effect" title="Version Compatibility Matrix">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-gray-700">
|
||||
<th className="text-left p-2">CHORUS Version</th>
|
||||
<th className="text-left p-2">Kubernetes</th>
|
||||
<th className="text-left p-2">Docker</th>
|
||||
<th className="text-left p-2">PostgreSQL</th>
|
||||
<th className="text-left p-2">Redis</th>
|
||||
<th className="text-left p-2">Node.js</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{versionCompatibility.map((version, index) => (
|
||||
<tr key={index} className={index < versionCompatibility.length - 1 ? "border-b border-gray-800" : ""}>
|
||||
<td className="p-2">{version.chorusVersion}</td>
|
||||
<td className="p-2">{version.kubernetes}</td>
|
||||
<td className="p-2">{version.docker}</td>
|
||||
<td className="p-2">{version.postgresql}</td>
|
||||
<td className="p-2">{version.redis}</td>
|
||||
<td className="p-2">{version.nodejs}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<Layout className="min-h-screen bg-chorus-charcoal">
|
||||
<Content>
|
||||
{/* Hero Section */}
|
||||
<section className="section-padding-sm bg-gradient-to-br from-chorus-charcoal via-slate-900 to-chorus-charcoal">
|
||||
<div className="container-chorus">
|
||||
<motion.div
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
variants={fadeInUp}
|
||||
className="text-center max-w-4xl mx-auto"
|
||||
>
|
||||
<Title level={1} className="text-white mb-4">
|
||||
Technical Specifications
|
||||
</Title>
|
||||
<Paragraph className="text-xl text-gray-300 mb-8">
|
||||
Comprehensive technical documentation for enterprise decision makers,
|
||||
system architects, and development teams implementing CHORUS Services.
|
||||
</Paragraph>
|
||||
|
||||
<div className="max-w-md mx-auto mb-8">
|
||||
<Search
|
||||
placeholder="Search technical documentation..."
|
||||
size="large"
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="glass-search"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Main Content */}
|
||||
<section className="section-padding">
|
||||
<div className="container-chorus">
|
||||
<motion.div
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true }}
|
||||
variants={stagger}
|
||||
>
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
items={tabItems}
|
||||
size="large"
|
||||
className="glass-tabs"
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Download Resources Section */}
|
||||
<section className="section-padding-sm bg-gradient-to-r from-slate-900 to-chorus-charcoal">
|
||||
<div className="container-chorus">
|
||||
<motion.div
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true }}
|
||||
variants={fadeInUp}
|
||||
className="text-center"
|
||||
>
|
||||
<Title level={2} className="text-white mb-6">
|
||||
Additional Resources
|
||||
</Title>
|
||||
<Row gutter={[24, 24]} justify="center">
|
||||
{downloadableResources.map((resource, index) => (
|
||||
<Col key={index} xs={24} sm={12} md={8}>
|
||||
<Card className="glass-effect text-center h-full">
|
||||
<div className={`mx-auto mb-4 ${resource.color}`}>
|
||||
{resource.icon}
|
||||
</div>
|
||||
<Title level={4} className="text-white mb-2">{resource.title}</Title>
|
||||
<Paragraph className="text-gray-400 mb-4">
|
||||
{resource.description}
|
||||
</Paragraph>
|
||||
<Button type="primary" block href={resource.href}>
|
||||
{resource.buttonText}
|
||||
</Button>
|
||||
</Card>
|
||||
</Col>
|
||||
))}
|
||||
</Row>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
</Content>
|
||||
</Layout>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user