diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..6368d79
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,25 @@
+FROM node:18-alpine AS base
+
+# Install dependencies
+FROM base AS deps
+WORKDIR /app
+COPY package.json package-lock.json ./
+RUN npm ci
+
+# Build the app
+FROM base AS builder
+WORKDIR /app
+COPY --from=deps /app/node_modules ./node_modules
+COPY . .
+RUN npm run build
+
+# Production image
+FROM base AS runner
+WORKDIR /app
+ENV NODE_ENV production
+COPY --from=builder /app/public ./public
+COPY --from=builder /app/.next/standalone ./
+COPY --from=builder /app/.next/static ./.next/static
+
+EXPOSE 3000
+CMD ["node", "server.js"]
\ No newline at end of file
diff --git a/app/page.tsx b/app/page.tsx
index 295f8fd..322c0b8 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,65 +1,25 @@
-import Image from "next/image";
+import EventCard from "@/components/EventCard";
+import dynamic from 'next/dynamic';
+
+const Starfield = dynamic(() => import('@/components/Starfield'), {
+ ssr: false
+});
export default function Home() {
return (
-
-
-
+
+
+
+ Mission Control // Ground Station
+
+
+
+
-
-
- To get started, edit the page.tsx file.
-
-
- Looking for a starting point or more instructions? Head over to{" "}
-
- Templates
- {" "}
- or the{" "}
-
- Learning
- {" "}
- center.
-
-
-
-
-
+
+
);
}
diff --git a/components/EventCard.tsx b/components/EventCard.tsx
new file mode 100644
index 0000000..de62a63
--- /dev/null
+++ b/components/EventCard.tsx
@@ -0,0 +1,32 @@
+"use client";
+import { motion } from "framer-motion";
+import { Rocket } from "lucide-react";
+import { EventCardProps } from "@/types/space"
+
+
+export default function EventCard({ title, targetDate, icon }: EventCardProps) {
+ return (
+
+
+
+
+
+ {icon || }
+
+
{title}
+
+
+
+ 02:
+ 14:
+ 55
+
+
+ T-Minus to Horizon
+
+ );
+}
\ No newline at end of file
diff --git a/components/Starfield.tsx b/components/Starfield.tsx
new file mode 100644
index 0000000..9f6947f
--- /dev/null
+++ b/components/Starfield.tsx
@@ -0,0 +1,41 @@
+"use client";
+import { motion } from "framer-motion";
+import { useState } from "react";
+import { Star } from "@/types/space"
+
+export default function Starfield() {
+ const [stars] = useState(() =>
+ Array.from({ length: 80 }).map((_, i) => ({
+ id: i,
+ left: `${Math.random() * 100}%`,
+ top: `${Math.random() * 100}%`,
+ size: Math.random() * 2 + 1,
+ duration: 2 + Math.random() * 3,
+ delay: Math.random() * 5,
+ }))
+ );
+
+ return (
+
+
+ {stars.map((star) => (
+
+ ))}
+
+ );
+}
\ No newline at end of file
diff --git a/next.config.ts b/next.config.ts
index 66e1566..55238ac 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -2,7 +2,7 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
- reactCompiler: true,
+ output: 'standalone',
};
export default nextConfig;
diff --git a/types/cards.ts b/types/cards.ts
new file mode 100644
index 0000000..e0385e5
--- /dev/null
+++ b/types/cards.ts
@@ -0,0 +1,5 @@
+interface EventCardProps {
+ title: string;
+ targetDate: Date;
+ icon?: React.ReactNode;
+}
\ No newline at end of file
diff --git a/types/space.ts b/types/space.ts
new file mode 100644
index 0000000..3beb20c
--- /dev/null
+++ b/types/space.ts
@@ -0,0 +1,30 @@
+import { ReactNode } from "react";
+
+export interface ISSPass {
+ id: string;
+ timestamp: number;
+ duration: number;
+ maxElevation: number;
+}
+
+export interface CelestialEvent {
+ title: string;
+ date: Date;
+ type: 'iss' | 'eclipse' | 'comet' | 'launch';
+ description?: string;
+}
+
+export interface Star {
+ id: number;
+ left: string;
+ top: string;
+ size: number;
+ duration: number;
+ delay: number;
+}
+
+export interface EventCardProps {
+ title: string;
+ targetDate: Date;
+ icon?: ReactNode;
+}
\ No newline at end of file