# Project export: SafeWing AI

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: UC Berkeley AI Hackathon 2025
- Tagline: On June 12, 2025, Air India Flight 171 crashed in Ahmedabad just 40 seconds after takeoff, killing 280 people. We made a dashboard to allows pilots to inspect potential failures before it's too late.
- Devpost: https://devpost.com/software/safewing-ai
- GitHub: https://github.com/hetpatel-11/BerkeleyHackathon
- Video: https://www.youtube.com/embed/i9rsh3Wbzz0?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — hetpatel-11 (1 commits)

## Devpost submission (written by the team)

### Overview

Here's a concise hackathon project description for SafeWing AI:

### Inspiration

Air India Flight 171's tragic crash in June 2025 killed 280 people due to preventable system failures. We built SafeWing AI to predict potential aircraft subsystem failures to allow pilots to inspect before they become catastrophic.

### What it does

Real-time aviation safety dashboard with 3D aircraft visualization that monitors 6 critical subsystems (engine, hydraulic, electrical, control surface, cabin, altimeter) using LSTM neural networks and random forest to predict Remaining Useful Life (RUL) and prevent crashes.

### How we built it

Frontend: Next.js with Three.js for 3D aircraft visualization ML Backend: LSTM and random forest models deployed using FastAPI, Docker, and GCP Data: NASA CMAPSS turbofan engine dataset + synthetic subsystem data Integration: Real-time sensor monitoring with color-coded alerts on actual aircraft parts

### Challenges we ran into

CORS issues with external ML API requiring proxy implementation Complex 3D model integration and part highlighting Real-time data synchronization between multiple subsystems Matching API data formats with frontend expectations

### Accomplishments we're proud of

Successfully integrated live LSTM predictions with 3D visualization Created realistic takeoff simulation with authentic sensor degradation Built comprehensive multi-system monitoring (engines + 5 subsystems) Achieved sub-100ms API response times

### What we learned

Real-time ML integration challenges in web applications Three.js 3D visualization and material manipulation Aviation system complexities and failure patterns Importance of predictive maintenance in safety-critical systems

### What's next

Integration with real aircraft sensor data streams Advanced anomaly detection algorithms Regulatory compliance for aviation safety standards Partnership with airlines for pilot training simulations

## README (from the GitHub repository)

# 🛩️ SafeWing AI - Aviation Safety Dashboard

**Predictive Aircraft Maintenance Using LSTM and Random Forest Neural Networks**

![Next.js](https://img.shields.io/badge/Next.js-13+-blue) ![TypeScript](https://img.shields.io/badge/TypeScript-5+-blue) ![LSTM](https://img.shields.io/badge/AI-LSTM-red)

> **Inspired by Air India Flight 171 Crash (June 2025)** - A tragic aviation disaster that claimed 280 lives, highlighting the critical need for predictive aircraft maintenance systems.

## 🎯 Mission Statement

SafeWing AI is an advanced aviation safety dashboard that uses Long Short-Term Memory (LSTM) and Random Forest neural networks to predict aircraft component failures **before** they become catastrophic. Our system monitors 6 critical aircraft subsystems in real-time and provides actionable insights to prevent aviation disasters.

<img width="1340" alt="Image" src="https://github.com/user-attachments/assets/52a4d605-da51-4e2f-a758-a499fc6ac413" />


## 🏗️ Architecture Overview

```
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Next.js UI    │───▶│     API Proxy    │───▶│      NGROK      │
│   Dashboard     │    │   (CORS Handler) │    │   LSTM Models   │
└─────────────────┘    └──────────────────┘    └─────────────────┘
        │                        │                        │
        ▼                        ▼                        ▼
┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   3D Aircraft   │    │   Real-time      │    │   Subsystem     │
│   Visualization │    │   Sensor Data    │    │   Predictions   │
└─────────────────┘    └──────────────────┘    └─────────────────┘
```

## 🔧 Technical Stack

### Frontend
- **Framework**: Next.js 13+ with App Router
- **Language**: TypeScript 5+
- **Styling**: Tailwind CSS + shadcn/ui
- **3D Graphics**: Three.js with React Three Fiber
- **State Management**: React Hooks + Context

### Backend
- **API Proxy**: Next.js API Routes
- **ML Models**: LSTM and Random Forest Neural Networks
- **Deployment**: NGROK
- **Database**: Real-time sensor simulation

### AI/ML Components
- **Engine System**: 24-feature Random Forest and LSTM model
- **Subsystem Models**: 5 individual LSTM models and Random Forest model. 
- **Training Data**: Synthetic flight data based on C-MAPSS dataset
- **Prediction Frequency**: Every 3 seconds during simulation

## 🎛️ System Components Monitored

| System | Sensors | Critical Thresholds | LSTM Input |
|--------|---------|-------------------|------------|
| **Engine** | 24 sensors | RUL < 30 cycles | 24 features |
| **Hydraulic** | 3 sensors (Pressure, Flow, Temperature) | RUL < 25 cycles | 50 timesteps |
| **Electrical** | 2 sensors (Voltage, Current) | RUL < 25 cycles | 50 timesteps |
| **Control Surface** | 1 sensor (Deflection) | RUL < 25 cycles | 50 timesteps |
| **Cabin** | 1 sensor (Pressure) | RUL < 25 cycles | 50 timesteps |
| **Altimeter** | 1 sensor (Drift) | RUL < 25 cycles | 50 timesteps |

## 🎮 Key Features

### 1. **Real-Time 3D Aircraft Visualization**
- Interactive 3D aircraft model with part-specific highlighting
- Color-coded risk indicators (Green → Yellow → Red)
- Dynamic part selection based on subsystem health

### 2. **LSTM-Powered Predictions**
- **Engine RUL**: Remaining Useful Life in flight cycles
- **Subsystem Health**: Critical failure predictions
- **Risk Assessment**: Real-time safety scoring

### 3. **50-Second Takeoff Simulation**
- Realistic takeoff sequence (0-175 knots over 45 seconds)
- Dynamic sensor value updates every second
- LSTM predictions every 3 seconds
- Automatic simulation completion

### 4. **Advanced Dashboard Analytics**
- Multi-system health monitoring
- Predictive failure alerts
- Historical trend analysis
- Critical condition notifications

## 🚀 Quick Start

### Prerequisites
```bash
node >= 18.0.0
npm >= 8.0.0
```

### Installation
```bash
# Clone the repository
git clone https://github.com/hetpatel-11/SafeWingAI_UCBerkeleyAIHackathon.git
cd SafeWingAI_UCBerkeleyAIHackathon

# Install dependencies
npm install

# Run development server
npm run dev
```

### Available Scripts
```bash
npm run dev         # Start development server
npm run build       # Build for production
npm run start       # Start production server
npm run lint        # Run ESLint
```

## 🔬 LSTM Model Architecture

### Engine Model
```python
Input: [24 features] → LSTM(64) → Dense(32) → Output: [RUL_cycles]
Features: Temperature, Pressure, Flow, Vibration, etc.
Training: C-MAPSS inspired synthetic data
```

### Subsystem Models (5x)
```python
Input: [50 timesteps × sensors] → LSTM(32) → Dense(16) → Output: [RUL_prediction]
Hydraulic: [50 × 3] (Pressure, Flow, Temperature)
Electrical: [50 × 2] (Voltage, Current)
Control: [50 × 1] (Deflection)
Cabin: [50 × 1] (Pressure)
Altimeter: [50 × 1] (Drift)
```

## 📊 Risk Assessment Logic

### RUL Processing
```typescript
// Negative predictions = Critical failure imminent
if (rul < 0) {
  processedRUL = Math.max(1, Math.abs(rul) + degradationFactor)
  riskLevel = "danger"
}

// Risk thresholds
if (rul < 25) riskLevel = "danger"      // Critical
if (rul < 60) riskLevel = "warning"     // Caution
else riskLevel = "safe"                 // Normal
```

### Alert System
- 🔴 **Critical**: RUL < 25 cycles, immediate attention required
- 🟡 **Warning**: RUL 25-60 cycles, monitor closely
- 🟢 **Safe**: RUL > 60 cycles, normal operation

## 🌐 API Endpoints

### Local Development
```
POST /api/predict
Body: {
  "subsystem": "engine|hydraulic|electrical|control_surface|cabin|altimeter",
  "sequence": [array of sensor values]
}
```

### Production LSTM API
```
POST https://my-lstm-api-537563823214.us-central1.run.app/predict/{subsystem}
Body: {
  "sequence": [sensor_data_array]
}
```

## 📱 User Interface

### Main Dashboard
- **Engine System**: Primary RUL analysis with detailed metrics
- **Subsystem Grid**: 5 subsystem cards with real-time status
- **3D Aircraft**: Interactive model with part highlighting
- **Control Panel**: Simulation controls and settings

### Real-Time Simulation
1. **Pre-flight**: System initialization and checks
2. **Takeoff Roll**: 0-45 seconds, 0-175 knots acceleration
3. **Critical Phase**: V1 speed maintenance, maximum sensor stress
4. **Completion**: 50-second simulation cycle with full analysis

## 🔍 Data Flow

```mermaid
graph TD
    A[Sensor Data Simulation] --> B[Parameter Updates]
    B --> C[LSTM API Calls]
    C --> D[RUL Processing]
    D --> E[Risk Assessment]
    E --> F[UI Updates]
    F --> G[3D Visualization]
    G --> H[Alert Generation]
```

## 🛠️ Development Workflow

### File Structure
```
UC Hackathon/
├── app/                    # Next.js app directory
│   ├── api/predict/       # LSTM API proxy
│   ├── globals.css        # Global styles
│   ├── layout.tsx         # Root layout
│   └── page.tsx           # Home page
├── components/            # React components
│   ├── ui/               # shadcn/ui components
│   ├── aircraft-3d-viewer.tsx
│   ├── aircraft-visualization.tsx
│   ├── aviation-sidebar.tsx
│   └── prediction-panel.tsx
├── Dataset/              # Training data
├── public/               # Static assets
└── styles/               # CSS files
```

### Key Components
- **PredictionPanel**: Main dashboard logic and LSTM integration
- **Aircraft3DViewer**: Three.js 3D aircraft visualization
- **AviationSidebar**: System status and alerts
- **AircraftVisualization**: Component highlighting and risk display

## 🌟 Future Enhancements

### Phase 2 Features
- [ ] **Multi-Aircraft Fleet Management**
- [ ] **Historical Data Analytics**
- [ ] **Custom Alert Thresholds**
- [ ] **Maintenance Scheduling Integration**

### Phase 3 Features
- [ ] **Real Aircraft Sensor Integration**
- [ ] **Advanced ML Models (Transformers)**
- [ ] **Mobile Application**
- [ ] **Regulatory Compliance Module**

## 🤝 Contributing

### Development Setup
1. Fork the repository
2. Create feature branch: `git checkout -b feature/amazing-feature`
3. Commit 

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 67 recognized source files, 268 KB.
- CSS (language) — detected in the code
- Next.js (technology) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code
- TypeScript (language) — detected in the code
- Docker (technology) — claimed on Devpost, not found in the code
- FastAPI (technology) — claimed on Devpost, not found in the code
- JavaScript (language) — claimed on Devpost, not found in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- Python (language) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (85 of 85)

```
.DS_Store
.gitignore
app/api/predict/route.ts
app/globals.css
app/layout.tsx
app/page.tsx
aviation-dashboard.tsx
components.json
components/aircraft-3d-viewer.tsx
components/aircraft-visualization.tsx
components/aviation-sidebar.tsx
components/prediction-panel.tsx
components/theme-provider.tsx
components/ui/accordion.tsx
components/ui/alert-dialog.tsx
components/ui/alert.tsx
components/ui/aspect-ratio.tsx
components/ui/avatar.tsx
components/ui/badge.tsx
components/ui/breadcrumb.tsx
components/ui/button.tsx
components/ui/calendar.tsx
components/ui/card.tsx
components/ui/carousel.tsx
components/ui/chart.tsx
components/ui/checkbox.tsx
components/ui/collapsible.tsx
components/ui/command.tsx
components/ui/context-menu.tsx
components/ui/dialog.tsx
components/ui/drawer.tsx
components/ui/dropdown-menu.tsx
components/ui/form.tsx
components/ui/hover-card.tsx
components/ui/input-otp.tsx
components/ui/input.tsx
components/ui/label.tsx
components/ui/menubar.tsx
components/ui/navigation-menu.tsx
components/ui/pagination.tsx
components/ui/popover.tsx
components/ui/progress.tsx
components/ui/radio-group.tsx
components/ui/resizable.tsx
components/ui/scroll-area.tsx
components/ui/select.tsx
components/ui/separator.tsx
components/ui/sheet.tsx
components/ui/sidebar.tsx
components/ui/skeleton.tsx
components/ui/slider.tsx
components/ui/sonner.tsx
components/ui/switch.tsx
components/ui/table.tsx
components/ui/tabs.tsx
components/ui/textarea.tsx
components/ui/toast.tsx
components/ui/toaster.tsx
components/ui/toggle-group.tsx
components/ui/toggle.tsx
components/ui/tooltip.tsx
components/ui/use-mobile.tsx
components/ui/use-toast.ts
Dataset/PM_test.txt
Dataset/PM_train.txt
Dataset/PM_truth.txt
flight_subsystem_data.ipynb
flight_subsystem_train.ipynb
flight1.ipynb
flight2.ipynb
hooks/use-mobile.tsx
hooks/use-toast.ts
lib/utils.ts
LICENSE
next.config.mjs
package.json
postcss.config.mjs
public/3d-model.obj
README.md
styles/globals.css
synthetic_per_subsystem_test.csv
synthetic_per_subsystem_train.csv
syntheticflightdata.ipynb
tailwind.config.ts
tsconfig.json
```

### Dependencies

- package.json: @hookform/resolvers@^3.9.1, @radix-ui/react-accordion@1.2.2, @radix-ui/react-alert-dialog@1.1.4, @radix-ui/react-aspect-ratio@1.1.1, @radix-ui/react-avatar@1.1.2, @radix-ui/react-checkbox@1.1.3, @radix-ui/react-collapsible@1.1.2, @radix-ui/react-context-menu@2.2.4, @radix-ui/react-dialog@1.1.4, @radix-ui/react-dropdown-menu@2.1.4, @radix-ui/react-hover-card@1.1.4, @radix-ui/react-label@2.1.1, @radix-ui/react-menubar@1.1.4, @radix-ui/react-navigation-menu@1.2.3, @radix-ui/react-popover@1.1.4, @radix-ui/react-progress@1.1.1, @radix-ui/react-radio-group@1.2.2, @radix-ui/react-scroll-area@1.2.2, @radix-ui/react-select@2.1.4, @radix-ui/react-separator@1.1.1, @radix-ui/react-slider@1.2.2, @radix-ui/react-slot@1.1.1, @radix-ui/react-switch@1.1.2, @radix-ui/react-tabs@1.1.2, @radix-ui/react-toast@1.2.4, @radix-ui/react-toggle@1.1.1, @radix-ui/react-toggle-group@1.1.1, @radix-ui/react-tooltip@1.1.6, @react-three/drei@^10.3.0, @react-three/fiber@^9.1.2, @types/node@^22, @types/react@^19, @types/react-dom@^19, @types/three@^0.177.0, autoprefixer@^10.4.20, class-variance-authority@^0.7.1, clsx@^2.1.1, cmdk@1.0.4, date-fns@4.1.0, embla-carousel-react@8.5.1, input-otp@1.4.1, lucide-react@^0.454.0, next@15.2.4, next-themes@^0.4.4, postcss@^8.5, react@^19, react-day-picker@8.10.1, react-dom@^19, react-hook-form@^7.54.1, react-resizable-panels@^2.1.7, recharts@2.15.0, sonner@^1.7.1, tailwind-merge@^2.5.5, tailwindcss@^3.4.17, tailwindcss-animate@^1.0.7, three@^0.177.0, typescript@^5, vaul@^0.9.6, zod@^3.24.1

### Recent commits (newest first)

- Update README.md
- Create LICENSE
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- Update README.md
- ✈️ SafeWing AI: Complete LSTM-powered aviation safety dashboard
- 🚁 AI-Powered Aviation Dashboard - Berkeley Hackathon

## Key source files (fetched from GitHub, selected and truncated for size)

### package.json

```
{
  "name": "my-v0-project",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "build": "next build",
    "dev": "next dev",
    "lint": "next lint",
    "start": "next start"
  },
  "dependencies": {
    "@hookform/resolvers": "^3.9.1",
    "@radix-ui/react-accordion": "1.2.2",
    "@radix-ui/react-alert-dialog": "1.1.4",
    "@radix-ui/react-aspect-ratio": "1.1.1",
    "@radix-ui/react-avatar": "1.1.2",
    "@radix-ui/react-checkbox": "1.1.3",
    "@radix-ui/react-collapsible": "1.1.2",
    "@radix-ui/react-context-menu": "2.2.4",
    "@radix-ui/react-dialog": "1.1.4",
    "@radix-ui/react-dropdown-menu": "2.1.4",
    "@radix-ui/react-hover-card": "1.1.4",
    "@radix-ui/react-label": "2.1.1",
    "@radix-ui/react-menubar": "1.1.4",
    "@radix-ui/react-navigation-menu": "1.2.3",
    "@radix-ui/react-popover": "1.1.4",
    "@radix-ui/react-progress": "1.1.1",
    "@radix-ui/react-radio-group": "1.2.2",
    "@radix-ui/react-scroll-area": "1.2.2",
    "@radix-ui/react-select": "2.1.4",
    "@radix-ui/react-separator": "1.1.1",
    "@radix-ui/react-slider": "1.2.2",
    "@radix-ui/react-slot": "1.1.1",
    "@radix-ui/react-switch": "1.1.2",
    "@radix-ui/react-tabs": "1.1.2",
    "@radix-ui/react-toast": "1.2.4",
    "@radix-ui/react-toggle": "1.1.1",
    "@radix-ui/react-toggle-group": "1.1.1",
    "@radix-ui/react-tooltip": "1.1.6",
    "@react-three/drei": "^10.3.0",
    "@react-three/fiber": "^9.1.2",
    "@types/three": "^0.177.0",
    "autoprefixer": "^10.4.20",
    "class-variance-authority": "^0.7.1",
    "clsx": "^2.1.1",
    "cmdk": "1.0.4",
    "date-fns": "4.1.0",
    "embla-carousel-react": "8.5.1",
    "input-otp": "1.4.1",
    "lucide-react": "^0.454.0",
    "next": "15.2.4",
    "next-themes": "^0.4.4",
    "react": "^19",
    "react-day-picker": "8.10.1",
    "react-dom": "^19",
    "react-hook-form": "^7.54.1",
    "react-resizable-panels": "^2.1.7",
    "recharts": "2.15.0",
    "sonner": "^1.7.1",
    "tailwind-merge": "^2.5.5",
    "tailwindcss-animate": "^1.0.7",
    "three": "^0.177.0",
    "vaul": "^0.9.6",
    "zod": "^3.24.1"
  },
  "devDependencies": {
    "@types/node": "^22",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "postcss": "^8.5",
    "tailwindcss": "^3.4.17",
    "typescript": "^5"
  }
}

```

### app/page.tsx

```typescript
import AviationDashboard from "../aviation-dashboard"

export default function Page() {
  return <AviationDashboard />
}

```

### app/layout.tsx

```typescript
import type { Metadata } from 'next'
import './globals.css'

export const metadata: Metadata = {
  title: 'v0 App',
  description: 'Created with v0',
  generator: 'v0.dev',
}

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode
}>) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

```

### app/api/predict/route.ts

```typescript
import { NextRequest, NextResponse } from 'next/server'

const LSTM_API_BASE = 'https://my-lstm-api-537563823214.us-central1.run.app'

// Handle CORS preflight requests
export async function OPTIONS(request: NextRequest) {
  return new NextResponse(null, {
    status: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
    },
  })
}

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    const { subsystem, sequence } = body

    console.log(`🔍 API Route: Received request for ${subsystem} with ${Array.isArray(sequence) ? sequence.length : 'invalid'} ${subsystem === 'engine' ? 'features' : 'timesteps'}`)

    if (!subsystem || !sequence) {
      return NextResponse.json(
        { error: 'Missing subsystem or sequence' },
        { status: 400 }
      )
    }

    // Validate sequence length based on subsystem type
    if (subsystem === 'engine') {
      // Engine expects 24 features
      if (!Array.isArray(sequence) || sequence.length !== 24) {
        console.error(`❌ Engine prediction requires exactly 24 features, got ${sequence.length}`)
        return NextResponse.json(
          { error: `Engine prediction requires exactly 24 features, got ${sequence.length}` },
          { status: 400 }
        )
      }
    } else {
      // Subsystems expect 50 timesteps
      if (!Array.isArray(sequence) || sequence.length !== 50) {
        console.error(`❌ ${subsystem} prediction requires exactly 50 timesteps, got ${sequence.length}`)
        return NextResponse.json(
          { error: `Sequence length must be 50` },
          { status: 400 }
        )
      }
    }

    // All APIs expect { sequence: ... } format
    const requestBody = { sequence }

    console.log(`🌐 API Route: Making request to ${LSTM_API_BASE}/predict/${subsystem}`)

    // Make request to LSTM API
    const response = await fetch(`${LSTM_API_BASE}/predict/${subsystem}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(requestBody),
    })

    if (!response.ok) {
      const errorText = await response.text()
      console.error(`❌ LSTM API Error: ${response.status} ${response.statusText} - ${errorText}`)
      throw new Error(`API responded with ${response.status}: ${errorText}`)
    }

    const data = await response.json()
    console.log(`✅ API Route: Successful response for ${subsystem}:`, data)

    return NextResponse.json(data, {
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'POST, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type',
      },
    })

  } catch (error) {
    console.error('Prediction API error:', error)
    return NextResponse.json(
      { error: 'Failed to get prediction' },
      { 
        status: 500,
        headers: {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'POST, OPTIONS',
          'Access-Control-Allow-Headers': 'Content-Type',
        },
      }
    )
  }
} 
```

### aviation-dashboard.tsx

```typescript
import { SidebarProvider, SidebarInset } from "@/components/ui/sidebar"
import { AviationSidebar } from "./components/aviation-sidebar"
import { AircraftVisualization } from "./components/aircraft-visualization"

export default function AviationDashboard() {
  return (
    <div className="min-h-screen bg-white">
      <SidebarProvider defaultOpen={true}>
        <AviationSidebar />
        <SidebarInset>
          <AircraftVisualization />
        </SidebarInset>
      </SidebarProvider>
    </div>
  )
}

```

### tailwind.config.ts

```typescript
import type { Config } from "tailwindcss";

const config: Config = {
    darkMode: ["class"],
    content: [
    "./pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./components/**/*.{js,ts,jsx,tsx,mdx}",
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "*.{js,ts,jsx,tsx,mdx}"
  ],
  theme: {
  	extend: {
  		colors: {
  			background: 'hsl(var(--background))',
  			foreground: 'hsl(var(--foreground))',
  			card: {
  				DEFAULT: 'hsl(var(--card))',
  				foreground: 'hsl(var(--card-foreground))'
  			},
  			popover: {
  				DEFAULT: 'hsl(var(--popover))',
  				foreground: 'hsl(var(--popover-foreground))'
  			},
  			primary: {
  				DEFAULT: 'hsl(var(--primary))',
  				foreground: 'hsl(var(--primary-foreground))'
  			},
  			secondary: {
  				DEFAULT: 'hsl(var(--secondary))',
  				foreground: 'hsl(var(--secondary-foreground))'
  			},
  			muted: {
  				DEFAULT: 'hsl(var(--muted))',
  				foreground: 'hsl(var(--muted-foreground))'
  			},
  			accent: {
  				DEFAULT: 'hsl(var(--accent))',
  				foreground: 'hsl(var(--accent-foreground))'
  			},
  			destructive: {
  				DEFAULT: 'hsl(var(--destructive))',
  				foreground: 'hsl(var(--destructive-foreground))'
  			},
  			border: 'hsl(var(--border))',
  			input: 'hsl(var(--input))',
  			ring: 'hsl(var(--ring))',
  			chart: {
  				'1': 'hsl(var(--chart-1))',
  				'2': 'hsl(var(--chart-2))',
  				'3': 'hsl(var(--chart-3))',
  				'4': 'hsl(var(--chart-4))',
  				'5': 'hsl(var(--chart-5))'
  			},
  			sidebar: {
  				DEFAULT: 'hsl(var(--sidebar-background))',
  				foreground: 'hsl(var(--sidebar-foreground))',
  				primary: 'hsl(var(--sidebar-primary))',
  				'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
  				accent: 'hsl(var(--sidebar-accent))',
  				'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
  				border: 'hsl(var(--sidebar-border))',
  				ring: 'hsl(var(--sidebar-ring))'
  			}
  		},
  		borderRadius: {
  			lg: 'var(--radius)',
  			md: 'calc(var(--radius) - 2px)',
  			sm: 'calc(var(--radius) - 4px)'
  		},
  		keyframes: {
  			'accordion-down': {
  				from: {
  					height: '0'
  				},
  				to: {
  					height: 'var(--radix-accordion-content-height)'
  				}
  			},
  			'accordion-up': {
  				from: {
  					height: 'var(--radix-accordion-content-height)'
  				},
  				to: {
  					height: '0'
  				}
  			}
  		},
  		animation: {
  			'accordion-down': 'accordion-down 0.2s ease-out',
  			'accordion-up': 'accordion-up 0.2s ease-out'
  		}
  	}
  },
  plugins: [require("tailwindcss-animate")],
};
export default config;

```

### lib/utils.ts

```typescript
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

```

### components/theme-provider.tsx

```typescript
'use client'

import * as React from 'react'
import {
  ThemeProvider as NextThemesProvider,
  type ThemeProviderProps,
} from 'next-themes'

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
  return <NextThemesProvider {...props}>{children}</NextThemesProvider>
}

```

### hooks/use-mobile.tsx

```typescript
import * as React from "react"

const MOBILE_BREAKPOINT = 768

export function useIsMobile() {
  const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)

  React.useEffect(() => {
    const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
    const onChange = () => {
      setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
    }
    mql.addEventListener("change", onChange)
    setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
    return () => mql.removeEventListener("change", onChange)
  }, [])

  return !!isMobile
}

```

### app/globals.css

```css
@tailwind base;
@tailwind components;
@tailwind utilities;

body {
  font-family: Arial, Helvetica, sans-serif;
}

@layer utilities {
  .text-balance {
    text-wrap: balance;
  }
}

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 0 0% 3.9%;
    --card: 0 0% 100%;
    --card-foreground: 0 0% 3.9%;
    --popover: 0 0% 100%;
    --popover-foreground: 0 0% 3.9%;
    --primary: 0 0% 9%;
    --primary-foreground: 0 0% 98%;
    --secondary: 0 0% 96.1%;
    --secondary-foreground: 0 0% 9%;
    --muted: 0 0% 96.1%;
    --muted-foreground: 0 0% 45.1%;
    --accent: 0 0% 96.1%;
    --accent-foreground: 0 0% 9%;
    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 0 0% 98%;
    --border: 0 0% 89.8%;
    --input: 0 0% 89.8%;
    --ring: 0 0% 3.9%;
    --chart-1: 12 76% 61%;
    --chart-2: 173 58% 39%;
    --chart-3: 197 37% 24%;
    --chart-4: 43 74% 66%;
    --chart-5: 27 87% 67%;
    --radius: 0.5rem;
    --sidebar-background: 0 0% 98%;
    --sidebar-foreground: 240 5.3% 26.1%;
    --sidebar-primary: 240 5.9% 10%;
    --sidebar-primary-foreground: 0 0% 98%;
    --sidebar-accent: 240 4.8% 95.9%;
    --sidebar-accent-foreground: 240 5.9% 10%;
    --sidebar-border: 220 13% 91%;
    --sidebar-ring: 217.2 91.2% 59.8%;
  }
  .dark {
    --background: 0 0% 3.9%;
    --foreground: 0 0% 98%;
    --card: 0 0% 3.9%;
    --card-foreground: 0 0% 98%;
    --popover: 0 0% 3.9%;
    --popover-foreground: 0 0% 98%;
    --primary: 0 0% 98%;
    --primary-foreground: 0 0% 9%;
    --secondary: 0 0% 14.9%;
    --secondary-foreground: 0 0% 98%;
    --muted: 0 0% 14.9%;
    --muted-foreground: 0 0% 63.9%;
    --accent: 0 0% 14.9%;
    --accent-foreground: 0 0% 98%;
    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 0 0% 98%;
    --border: 0 0% 14.9%;
    --input: 0 0% 14.9%;
    --ring: 0 0% 83.1%;
    --chart-1: 220 70% 50%;
    --chart-2: 160 60% 45%;
    --chart-3: 30 80% 55%;
    --chart-4: 280 65% 60%;
    --chart-5: 340 75% 55%;
    --sidebar-background: 240 5.9% 10%;
    --sidebar-foreground: 240 4.8% 95.9%;
    --sidebar-primary: 224.3 76.3% 48%;
    --sidebar-primary-foreground: 0 0% 100%;
    --sidebar-accent: 240 3.7% 15.9%;
    --sidebar-accent-foreground: 240 4.8% 95.9%;
    --sidebar-border: 240 3.7% 15.9%;
    --sidebar-ring: 217.2 91.2% 59.8%;
  }
}

@layer base {
  * {
    @apply border-border;
  }
  body {
    @apply bg-background text-foreground;
  }
}

```

[55 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]