diff --git a/.gitignore b/.gitignore
index a126f8b..ac76883 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,3 +43,8 @@ next-env.d.ts
.dev.vars*
!.dev.vars.example
!.env.example
+
+# claude code
+.claude/**
+CLAUDE.md
+
diff --git a/app/blog/[slug]/blog-post.module.css b/app/blog/[slug]/blog-post.module.css
new file mode 100755
index 0000000..8c356cc
--- /dev/null
+++ b/app/blog/[slug]/blog-post.module.css
@@ -0,0 +1,77 @@
+.blogContent {
+ font-family: var(--font-sans);
+ color: #334155;
+}
+
+.blogContent p {
+ margin-bottom: 1.5rem;
+ line-height: 1.8;
+ font-size: 1.125rem;
+}
+
+.blogContent p.lead {
+ font-size: 1.5rem;
+ line-height: 1.6;
+ color: #0f172a;
+ font-weight: 500;
+ margin-bottom: 2.5rem;
+}
+
+.blogContent h2 {
+ font-size: 2rem;
+ font-weight: 800;
+ margin-top: 3.5rem;
+ margin-bottom: 1.5rem;
+ color: #0f172a;
+ letter-spacing: -0.02em;
+ line-height: 1.2;
+}
+
+.blogContent h3 {
+ font-size: 1.5rem;
+ font-weight: 700;
+ margin-top: 2.5rem;
+ margin-bottom: 1rem;
+ color: #0f172a;
+}
+
+.blogContent a {
+ color: #0066bf;
+ text-decoration: none;
+ border-bottom: 2px solid rgba(0, 102, 191, 0.2);
+ transition: all 0.2s ease;
+}
+
+.blogContent a:hover {
+ color: #004a8f;
+ border-bottom-color: #0066bf;
+}
+
+.blogContent ul,
+.blogContent ol {
+ margin-left: 1.5rem;
+ margin-bottom: 2rem;
+ padding-left: 1rem;
+}
+
+.blogContent li {
+ margin-bottom: 0.75rem;
+ font-size: 1.125rem;
+ line-height: 1.7;
+}
+
+.blogContent blockquote {
+ border-left: 4px solid #0066bf;
+ padding-left: 1.5rem;
+ margin: 2.5rem 0;
+ font-style: italic;
+ font-size: 1.25rem;
+ color: #0f172a;
+}
+
+.blogContent img {
+ width: 100%;
+ height: auto;
+ border-radius: 0.25rem;
+ margin: 2.5rem 0;
+}
diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx
new file mode 100755
index 0000000..6d27431
--- /dev/null
+++ b/app/blog/[slug]/page.tsx
@@ -0,0 +1,132 @@
+import { SiteHeader } from "@/components/site-header"
+import { SiteFooter } from "@/components/site-footer"
+import { notFound } from "next/navigation"
+import Link from "next/link"
+import { ArrowLeft } from "lucide-react"
+import styles from "./blog-post.module.css"
+
+// This would typically come from a CMS or database
+const posts = {
+ "home-repairs-when-to-call-in-the-pros": {
+ title: "Home Repairs: When to Call in the Pros",
+ date: "January 23, 2020",
+ author: "webmaster",
+ category: "Maintenance",
+ image: "/blog/home-repairs-plumber.jpg",
+ content: `
+
With all the resources available, people are choosing more often to tackle DIY projects around the house by themselves. Certainly, you can save money and hassle by doing it yourself, and you will walk away with the pride of a job well done. However, there are some projects in your home that are best left to the professionals.
+
+ Contributed by: diyguys.net
+
+ What's the Difference?
+
+ When deciding whether to take on the project yourself or hire a professional, first assess how serious the problem is. Minor home repairs, such as touching up paint on your walls or replacing cabinet hardware, are common projects to tackle yourself with success. They have a low risk of injury, accessible tools and equipment, and are going to be acceptable if a less-than-perfect result is achieved.
+
+ Major home repairs, like plumbing leaks and foundation issues, are risky to take on without the help of a professional. These repairs involve a safety risk, structural importance, or require an expert. If you risk attempting some of these more complicated repairs, you risk not only injuring yourself but also damaging your home further.
+
+ Minor vs. Major Plumbing Repairs
+
+ Plumbing issues can often happen at the worst times, and sometimes the problems are well within your abilities to repair. Installing or repairing sink faucets, cleaning clogged drains, and changing out the shower heads are great examples of inexpensive DIY projects that you can successfully undertake. However, if you are experiencing issues such as low water pressure, no hot water, or sewage back up, you need to call in a professional. Plumbers are highly skilled and trained, so you will pay more for their expertise but diagnosing and repairing these types of problems is one best left to an expert plumber.
+
+ Electricity is Dangerous
+
+ Just like plumbers, professional electricians are highly trained and experts in their field. Electrical repair can be dangerous and potentially life-threatening. While you will save money tackling repairs by yourself, you need to consider your knowledge level and capabilities. You may possess basic knowledge in electrical wiring and feel confident installing new light fixtures or ceiling fan. However, more complicated problems can arise, such as dead outlets, flickering light bulbs, and circuit breakers frequently tripping. If you are not skilled in electrical work, you may find that hiring a good electrician is the safest and most efficient route.
+
+ Getting Rid of Junk
+
+ If you're planning to toss old appliances, worn mattresses, or the ratty carpet you ripped out of several rooms, your first thought might be to remove it all yourself. Think again. By calling in professional junk haulers, you can save yourself the hassle and money — not to mention grievous bodily harm. Additionally, reputable haulers will ensure that everything is disposed of in an environmentally friendly manner. That way, if you have items that need recycling, you can rest assured that these objects will end up precisely where they should go. Junk and waste removal services in Colorado Springs typically cost between $397 and $941.
+
+ When Structure is Involved
+
+ Another area of home repair that is best left to the professionals is anything involving the structure of your home. Foundation issues can occur that affect the structure of your home, like uneven floors, poor drainage, or cracked concrete. If any of these problems occur in your home, a professional needs to be called to handle it immediately. Left alone, the foundation will be compromised resulting in a dangerous and expensive domino effect of damage.
+
+ Let's Talk Numbers
+
+ In all these circumstances, we have established that there is a time for professional repair. Obviously, the cost is higher to outsource the repair work, but how much exactly are we talking about? Foundation repair can cost around $5,800 on average, but smaller repairs like cracks cost less and issues with drainage could cost more. Hiring an electrician will not be as expensive, as the repairs are less serious than foundation issues. The cost varies based on the repair; the breaker that keeps tripping may cost less than a dead outlet. Calling a plumber to fix a leaky faucet can be as low as $100, though you might be able to do this yourself.
+
+ Calling a plumber, electrician, or structural engineer costs money, but it is money well spent when you are preventing further damage or personal injury in the repair. Do your research to find a reputable repairman and you will be glad that you called the professionals.
+
+ Photo Credit: Pixabay
+ `,
+ },
+}
+
+export default function BlogPostPage({ params }: { params: { slug: string } }) {
+ const post = posts[params.slug as keyof typeof posts]
+
+ if (!post) {
+ notFound()
+ }
+
+ return (
+
+
+
+
+ {/* Hero Section */}
+
+
+
+
Back to Journal
+
+
+ {post.title}
+
+
+ {post.date}
+
+ {post.category}
+
+ By {post.author}
+
+
+
+
+ {/* Featured Image */}
+
+
+
+
+
+
+
+
+ {/* Content */}
+
+
+
+
+ {/* Share / Footer */}
+
+
Share this article
+
+ {/* Social placeholders */}
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/app/blog/page.tsx b/app/blog/page.tsx
new file mode 100755
index 0000000..a3b15fb
--- /dev/null
+++ b/app/blog/page.tsx
@@ -0,0 +1,101 @@
+import { SiteHeader } from "@/components/site-header"
+import { SiteFooter } from "@/components/site-footer"
+import Link from "next/link"
+import { ArrowRight } from "lucide-react"
+
+export default function BlogPage() {
+ const posts = [
+ {
+ slug: "home-repairs-when-to-call-in-the-pros",
+ title: "Home Repairs: When to Call in the Pros",
+ excerpt:
+ "With all the resources available, people are choosing more often to tackle DIY projects around the house by themselves. However, there are some projects that are best left to the professionals.",
+ date: "January 23, 2020",
+ category: "Maintenance",
+ image: "/blog/home-repairs-plumber.jpg",
+ },
+ // Placeholder posts to fill the grid for visual demonstration
+ {
+ slug: "icf-construction-benefits",
+ title: "The Structural Advantages of ICF Construction",
+ excerpt:
+ "Insulated Concrete Forms (ICF) provide superior energy efficiency and structural integrity compared to traditional framing methods.",
+ date: "February 15, 2020",
+ category: "Construction",
+ image: "/icf-above-grade-walls-construction.jpg",
+ },
+ {
+ slug: "radiant-heating-guide",
+ title: "Complete Guide to Radiant Floor Heating",
+ excerpt:
+ "Discover why radiant floor heating is the most efficient and comfortable way to heat your high-performance home.",
+ date: "March 10, 2020",
+ category: "Systems",
+ image: "/radiant-floor-heating-installation.jpg",
+ },
+ ]
+
+ return (
+
+
+
+
+ {/* Refined header section with better typography and spacing */}
+
+
+
+
+
Insights
+
+ Expert perspectives on structural engineering, modern construction, and high-performance building
+ systems.
+
+
+
+
+
+ {/* Blog Grid */}
+
+
+
+ {posts.map((post, index) => (
+
+
+
+
+
+ {post.category}
+
+
+
+
+
+
{post.date}
+
+ Read Article
+
+
+
+ {post.title}
+
+
{post.excerpt}
+
+
+ ))}
+
+
+
+
+
+
+
+ )
+}
diff --git a/app/contact/page.tsx b/app/contact/page.tsx
new file mode 100755
index 0000000..13409ae
--- /dev/null
+++ b/app/contact/page.tsx
@@ -0,0 +1,351 @@
+"use client"
+
+import type React from "react"
+
+import { SiteHeader } from "@/components/site-header"
+import { SiteFooter } from "@/components/site-footer"
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
+import { Button } from "@/components/ui/button"
+import { Input } from "@/components/ui/input"
+import { Textarea } from "@/components/ui/textarea"
+import { Label } from "@/components/ui/label"
+import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
+import { Mail, Phone, MapPin, Clock, Play, ExternalLink } from "lucide-react"
+import { useState } from "react"
+import Image from "next/image"
+
+export default function ContactPage() {
+ const [formData, setFormData] = useState({
+ firstName: "",
+ lastName: "",
+ email: "",
+ phone: "",
+ interest: "",
+ message: "",
+ })
+
+ const handleSubmit = (e: React.FormEvent) => {
+ e.preventDefault()
+ console.log("Form submitted:", formData)
+ }
+
+ const handleChange = (e: React.ChangeEvent) => {
+ setFormData({
+ ...formData,
+ [e.target.name]: e.target.value,
+ })
+ }
+
+ return (
+
+
+
+
+ {/* Hero Section */}
+
+
+
+
Contact Us
+
+ Get in touch with our team to discuss your next high-performance project.
+
+
+
+
+
+
+ {/* Main Content - Left Column */}
+
+ {/* Intro Text */}
+
+
We want to hear from you!
+
+ We have over 20 years of construction experience and specialize in Insulated Concrete Form (ICFs)
+ installations, Structural Concrete Flooring and Radiant Heating Systems. If you are interested in more
+ information regarding ICF structures or require an estimate, please fill out the contact form, call or
+ email us today.
+
+
+
+
+
+
+
+
Address:
+
+ We are located in beautiful Woodland Park, CO and serve the Rocky Mtn. Region and the Front
+ Range. Please call to set up an appointment.
+
+
+
+
+
+
+
+
+
+
+
Business Hours:
+
8:00a–4:00p M-F
+
+
+
+
+
+
+ {/* Contact Form */}
+
+
+
+
+
+
+
+ {/* Sidebar - Right Column */}
+
+ {/* Newsletter Signup */}
+
+
+ Subscribe to Our Newsletter
+ * indicates required
+
+
+
+
+ Email Address *
+
+
+
+
+
+ First Name
+
+
+
+
+
+ Last Name
+
+
+
+
+
Birthday
+
+
+ /
+
+
+
( mm / dd )
+
+
+ Subscribe
+
+
+
+
+ {/* ProView Badge */}
+
+
+ ProView
+
+ Qualify Us Now!
+
+
+
+
+ {/* BuilderTrend Login */}
+
+
BuilderTrend Login
+
+
+ Client Login
+
+
+
+ Sign in to Buildertrend
+
+
+
+
+
+
+ {/* Video Placeholder */}
+
+
+
+
+
+ HPS
+
+
ICF Install in B...
+
+
+
+ {/* BBB Accredited */}
+
+
BBB Accredited
+
+
BBB
+
+
ACCREDITED BUSINESS
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/app/globals.css b/app/globals.css
new file mode 100755
index 0000000..a0b186b
--- /dev/null
+++ b/app/globals.css
@@ -0,0 +1,184 @@
+@import "tailwindcss";
+@import "tw-animate-css";
+
+@custom-variant dark (&:is(.dark *));
+
+:root {
+ /* HPS Brand Colors - Refined */
+ --primary-blue: #0066bf;
+ --primary-blue-dark: #004d90;
+ --deep-navy: #0f172a;
+ --navy: #1e293b;
+ --cyan-accent: #8cc63f;
+ --cyan-glow: #a3e635;
+
+ /* Base Colors */
+ --background: #ffffff;
+ --foreground: #0f172a;
+
+ --card: #ffffff;
+ --card-foreground: #0f172a;
+
+ --popover: #ffffff;
+ --popover-foreground: #0f172a;
+
+ --primary: #0f172a;
+ --primary-foreground: #ffffff;
+
+ --secondary: #f1f5f9;
+ --secondary-foreground: #0f172a;
+
+ --muted: #f1f5f9;
+ --muted-foreground: #64748b;
+
+ --accent: #f1f5f9;
+ --accent-foreground: #0f172a;
+
+ --destructive: #ef4444;
+ --destructive-foreground: #ffffff;
+
+ --border: #e2e8f0;
+ --input: #e2e8f0;
+ --ring: #0f172a;
+
+ --radius: 0rem;
+
+ --sidebar: #ffffff;
+ --sidebar-foreground: #0f172a;
+ --sidebar-primary: #0066bf;
+ --sidebar-primary-foreground: #ffffff;
+ --sidebar-accent: #f1f5f9;
+ --sidebar-accent-foreground: #0f172a;
+ --sidebar-border: #e2e8f0;
+ --sidebar-ring: #0066bf;
+
+ /* HPS Custom Colors */
+ --hps-blue: #0066bf;
+ --hps-navy: #0f172a;
+ --hps-cyan: #8cc63f;
+ /* Adding a specific grid border color for the dark theme services section */
+ --grid-border: rgba(255, 255, 255, 0.1);
+
+ /* Header specific variables */
+ --header-height: 80px;
+}
+
+.dark {
+ --background: #0f172a;
+ --foreground: #f8fafc;
+
+ --card: #1e293b;
+ --card-foreground: #f8fafc;
+
+ --popover: #0f172a;
+ --popover-foreground: #f8fafc;
+
+ --primary: #f8fafc;
+ --primary-foreground: #0f172a;
+
+ --secondary: #1e293b;
+ --secondary-foreground: #f8fafc;
+
+ --muted: #1e293b;
+ --muted-foreground: #94a3b8;
+
+ --accent: #1e293b;
+ --accent-foreground: #f8fafc;
+
+ --destructive: #7f1d1d;
+ --destructive-foreground: #f8fafc;
+
+ --border: #1e293b;
+ --input: #1e293b;
+ --ring: #cbd5e1;
+
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+
+ --sidebar: #1e293b;
+ --sidebar-foreground: #ffffff;
+ --sidebar-primary: #8cc63f;
+ --sidebar-primary-foreground: #0f172a;
+ --sidebar-accent: #1e293b;
+ --sidebar-accent-foreground: #ffffff;
+ --sidebar-border: #334155;
+ --sidebar-ring: #8cc63f;
+}
+
+@theme inline {
+ --font-sans: "Inter", "sans-serif";
+ --font-mono: "Geist Mono", "monospace";
+
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-destructive-foreground: var(--destructive-foreground);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --color-sidebar: var(--sidebar);
+ --color-sidebar-foreground: var(--sidebar-foreground);
+ --color-sidebar-primary: var(--sidebar-primary);
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+ --color-sidebar-accent: var(--sidebar-accent);
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+ --color-sidebar-border: var(--sidebar-border);
+ --color-sidebar-ring: var(--sidebar-ring);
+
+ /* Custom Colors */
+ --color-deep-navy: var(--deep-navy);
+ --color-navy: var(--navy);
+ --color-primary-blue: var(--primary-blue);
+ --color-primary-blue-dark: var(--primary-blue-dark);
+ --color-cyan-accent: var(--cyan-accent);
+}
+
+@layer base {
+ * {
+ @apply border-border;
+ }
+ body {
+ @apply bg-background text-foreground antialiased;
+ }
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6 {
+ @apply font-sans font-bold tracking-tight;
+ }
+ h1 {
+ @apply text-4xl md:text-5xl lg:text-6xl;
+ }
+ h2 {
+ @apply text-3xl md:text-4xl;
+ }
+ h3 {
+ @apply text-2xl md:text-3xl;
+ }
+}
diff --git a/app/layout.tsx b/app/layout.tsx
new file mode 100755
index 0000000..4785405
--- /dev/null
+++ b/app/layout.tsx
@@ -0,0 +1,47 @@
+import type React from "react"
+import type { Metadata } from "next"
+import { Analytics } from "@vercel/analytics/next"
+import { Inter } from "next/font/google"
+import "./globals.css"
+
+// Updated metadata for HPS website
+const inter = Inter({ subsets: ["latin"] })
+
+export const metadata: Metadata = {
+ title: "High Performance Structures, Inc. | ICF Installation Specialists",
+ description:
+ "High Performance Structures specializes in Insulating Concrete Form (ICF) installations, structural concrete flooring, and radiant heating systems in Colorado.",
+ generator: "v0.app",
+ icons: {
+ icon: [
+ {
+ url: "/icon-light-32x32.png",
+ media: "(prefers-color-scheme: light)",
+ },
+ {
+ url: "/icon-dark-32x32.png",
+ media: "(prefers-color-scheme: dark)",
+ },
+ {
+ url: "/icon.svg",
+ type: "image/svg+xml",
+ },
+ ],
+ apple: "/apple-icon.png",
+ },
+}
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode
+}>) {
+ return (
+
+
+ {children}
+
+
+
+ )
+}
diff --git a/app/page.tsx b/app/page.tsx
new file mode 100755
index 0000000..624d814
--- /dev/null
+++ b/app/page.tsx
@@ -0,0 +1,278 @@
+import { SiteHeader } from "@/components/site-header"
+import { SiteFooter } from "@/components/site-footer"
+import { Button } from "@/components/ui/button"
+import Link from "next/link"
+import { ArrowRight, CheckCircle2, Shield, Zap, Hammer, GraduationCap, Layers } from "lucide-react"
+
+export default function HomePage() {
+ return (
+
+
+
+
+ {/* Hero Section */}
+
+ {/* Background Image with Overlay */}
+
+
+
+
+
+
+
+ Building the Future
+
+ with Concrete Precision
+
+
+ Specializing in Insulating Concrete Form (ICF) installations, structural flooring, and radiant heating
+ systems.
+
+
+
+
+ Get a Quote
+
+
+
+
+ Our Services
+
+
+
+
+
+
+ {/* Intro Section */}
+
+
+
+
+
+ High Performance Structures
+
+
+
+ With over 250,000 wall face sq ft of ICFs installed over the course of 10 years, we are highly
+ capable and able to take on almost any project, from a simple cabin foundation to a multi-level
+ commercial structure.
+
+
+ We know time is a valuable commodity and we aim to complete our installations as quick as we can
+ while maintaining our high level of quality. Our seasoned ICF installation team allows HPS to get in
+ and get the job done on time and on budget.
+
+
+
+ 20+
+
+ Years Experience
+
+
+
+
+ 250k+
+
+ Sq Ft Installed
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Services Grid */}
+
+
+
+
+
Our Expertise
+
+ Comprehensive concrete and construction solutions.
+
+
+
+
+ View All Services
+
+
+
+
+
+ {[
+ {
+ icon: Layers,
+ title: "Footers & Foundations",
+ description:
+ "Start your build off right with a solid foundation. An ICF basement provides a comfortable and energy-efficient environment.",
+ },
+ {
+ icon: Zap,
+ title: "Radiant Heating",
+ description:
+ "Say goodbye to cold floors. Radiant heating systems provide consistent, efficient heat from the floor up.",
+ },
+ {
+ icon: Shield,
+ title: "ICF Above-Grade Walls",
+ description:
+ "Poured walls significantly raise the R-value of your structure compared to traditional builds, ensuring energy efficiency.",
+ },
+ {
+ icon: GraduationCap,
+ title: "Training & Consulting",
+ description:
+ "Want to install your own ICFs? We provide hands-on training and expert guidance for your first project.",
+ },
+ {
+ icon: Hammer,
+ title: "Structural Flooring",
+ description:
+ "Easily install structural concrete flooring and decking for added strength, soundproofing, and fire protection.",
+ },
+ {
+ icon: Shield,
+ title: "Safe Rooms & Shelters",
+ description:
+ "ICFs provide superior protection from fires, tornadoes, and other natural disasters for your peace of mind.",
+ },
+ ].map((service, index) => (
+
+
+
+
+
+ {service.title}
+
+
{service.description}
+
+
+ ))}
+
+
+
+
+ {/* Featured Videos Section */}
+
+
+
+
See Us in Action
+
+ Watch our team at work and learn more about the ICF construction process.
+
+
+
+
+ {["eQAEIYZN4Xs", "xQ51P5oZBuw", "MXCVrOM3kBk"].map((videoId, index) => (
+
+ VIDEO
+
+ ))}
+
+
+
+
+ {/* Why Choose Us / CTA */}
+
+
+
+
+
+
+
Why Choose HPS?
+
+ {[
+ "Over 20 years of specialized ICF experience",
+ "Certified and trained installation crews",
+ "Commitment to energy efficiency and durability",
+ "On-time and on-budget project delivery",
+ "Comprehensive support from design to completion",
+ ].map((item, i) => (
+
+ ))}
+
+
+
+
+ Start Your Project
+
+
+
+
+
+
Ready to build better?
+
+ Contact us today for a consultation or quote on your next residential or commercial project.
+
+
+
+
+
+
+
+ Send Message
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/app/resources/page.tsx b/app/resources/page.tsx
new file mode 100755
index 0000000..ab4bcfb
--- /dev/null
+++ b/app/resources/page.tsx
@@ -0,0 +1,396 @@
+"use client"
+
+import { SiteHeader } from "@/components/site-header"
+import { SiteFooter } from "@/components/site-footer"
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
+import { Button } from "@/components/ui/button"
+import {
+ ExternalLink,
+ Users,
+ Ruler,
+ Calculator,
+ Truck,
+ Hammer,
+ BookOpen,
+ Briefcase,
+ ChevronRight,
+ CheckCircle2,
+ ArrowRight,
+} from "lucide-react"
+import { useState, useEffect } from "react"
+import { cn } from "@/lib/utils"
+
+export default function ResourcesPage() {
+ const [activeSection, setActiveSection] = useState("organizations")
+
+ const sections = [
+ {
+ id: "organizations",
+ title: "Organizations",
+ icon: Users,
+ description: "Industry organizations and community resources for ICF construction.",
+ type: "links",
+ items: [
+ {
+ name: "Concrete Network",
+ url: "https://www.concretenetwork.com/concrete-homes/advantages.html",
+ description: "Information about concrete homes and their advantages",
+ },
+ {
+ name: "ICF Builder Group",
+ url: "http://icfbuildergroup.com",
+ description: "Resources and community for ICF builders",
+ },
+ ],
+ },
+ {
+ id: "design",
+ title: "Design & Engineering",
+ icon: Ruler,
+ description: "Technical resources, CAD details, and engineering consultation.",
+ type: "links",
+ items: [
+ {
+ name: "CAD Details",
+ url: "http://autocaddetails.net/cad_directory/Residential/ICF%20System/ICF_Systems.htm",
+ description: "AutoCAD details for ICF systems",
+ },
+ {
+ name: "Innovative Engineering Solutions, LLC",
+ contact: "Larry Matejcek",
+ email: "matco11749@msn.com",
+ description: "Engineering consultation services",
+ },
+ {
+ name: "Fox Block CAD Details",
+ url: "http://www.foxblocks.com/resource-center/autocad-2d-details/",
+ description: "Fox Block AutoCAD 2D details",
+ },
+ ],
+ },
+ {
+ id: "estimating",
+ title: "Estimating Tools",
+ icon: Calculator,
+ description: "Tools and calculators for project estimation.",
+ type: "links",
+ items: [
+ {
+ name: "Fox Block Project Estimator",
+ url: "http://www.foxblocks.com/project-estimator/",
+ description: "Tool for estimating Fox Block projects",
+ },
+ ],
+ },
+ {
+ id: "suppliers",
+ title: "Suppliers",
+ icon: Truck,
+ description: "Trusted suppliers for ICF materials and equipment.",
+ type: "links",
+ items: [
+ {
+ name: "Nu-Tech Systems",
+ url: "http://nutechcolorado.com",
+ description: "ICF supplies and bracing rental",
+ },
+ ],
+ },
+ {
+ id: "builders",
+ title: "Builders",
+ icon: Hammer,
+ description: "Experienced ICF custom builders and contractors.",
+ type: "links",
+ items: [
+ {
+ name: "Open Range Construction, Ltd.",
+ url: "http://openrangeconstruction.com",
+ description: "ICF custom builder",
+ },
+ ],
+ },
+ {
+ id: "publications",
+ title: "Publications",
+ icon: BookOpen,
+ description: "Industry magazines and reading materials.",
+ type: "links",
+ items: [
+ {
+ name: "ICF Builder Magazine",
+ url: "https://www.icfmag.com/",
+ description: "Industry magazine for ICF builders",
+ },
+ ],
+ },
+ {
+ id: "employment",
+ title: "Employment",
+ icon: Briefcase,
+ description: "Join our growing team of high performance building professionals.",
+ type: "custom",
+ content: {
+ intro:
+ "High Performance Structures is a Foundation Subcontractor specializing in installing Insulating Concrete Forms (ICFs) with over 10 years experience. The ICFs industry is growing and so are we! We are looking to hire 4 installers to accommodate the increase in ICF foundation jobs.",
+ role: "ICF Installers",
+ requirements: [
+ "At least 18 years old",
+ "Reliable personal transportation (4-Wheel drive helpful)",
+ "Willingness to work at multiple job sites throughout the Front Range",
+ "Comfortable working at heights from ladders and scaffolding",
+ "Flexibility with changing construction schedules",
+ ],
+ skills: [
+ "Basic knowledge of general construction and repair methods",
+ "Ability to interpret sketches and blueprints",
+ "Ability to communicate effectively in English",
+ "Manual work requiring heavy lifting, reaching, and bending",
+ "Ability to operate hand/power tools",
+ "Ability to quickly pick up on new skills",
+ ],
+ tasks: [
+ "Installing ICF forms",
+ "Placing reinforcement/rebar",
+ "Installing scaffolding and bracing",
+ "Aligning, leveling and plumbing ICF walls",
+ "Placing concrete and forms",
+ "Installing temporary beams and structural posts",
+ ],
+ applyUrl: "https://goo.gl/forms/VuoaPSst4SR4Hzos1",
+ },
+ },
+ ]
+
+ useEffect(() => {
+ const handleScroll = () => {
+ const sectionElements = sections.map((s) => document.getElementById(s.id))
+ const scrollPosition = window.scrollY + 200
+
+ for (const section of sectionElements) {
+ if (
+ section &&
+ section.offsetTop <= scrollPosition &&
+ section.offsetTop + section.offsetHeight > scrollPosition
+ ) {
+ setActiveSection(section.id)
+ }
+ }
+ }
+
+ window.addEventListener("scroll", handleScroll)
+ return () => window.removeEventListener("scroll", handleScroll)
+ }, [])
+
+ const scrollToSection = (id: string) => {
+ const element = document.getElementById(id)
+ if (element) {
+ const offset = 120
+ const bodyRect = document.body.getBoundingClientRect().top
+ const elementRect = element.getBoundingClientRect().top
+ const elementPosition = elementRect - bodyRect
+ const offsetPosition = elementPosition - offset
+
+ window.scrollTo({
+ top: offsetPosition,
+ behavior: "smooth",
+ })
+ }
+ }
+
+ return (
+
+
+
+
+ {/* Hero Section */}
+
+
+
+
+
+ Resources & Careers
+
+
+ Industry tools, partnerships, and opportunities to join our team.
+
+
+
+
+
+
+ {/* Sticky Sidebar Navigation */}
+
+
+
Quick Navigation
+
+ {sections.map((section) => (
+ scrollToSection(section.id)}
+ className={cn(
+ "w-full text-left px-4 py-3 rounded-lg text-sm font-medium transition-all duration-200 flex items-center justify-between group",
+ activeSection === section.id
+ ? "bg-deep-navy text-white shadow-md"
+ : "text-gray-600 hover:bg-gray-100 hover:text-deep-navy",
+ )}
+ >
+
+
+ {section.title}
+
+ {activeSection === section.id && }
+
+ ))}
+
+
+
+
+ {/* Main Content */}
+
+ {sections.map((section, index) => (
+
+
+
+
+
+
+
{section.title}
+
{section.description}
+
+
+
+ {section.type === "links" && (
+
+ {section.items?.map((item, i) => (
+
+
+
+ {item.name}
+ {item.url && (
+
+ )}
+
+
+
+ {item.description}
+ {/* @ts-ignore */}
+ {item.contact && (
+
+ Contact: {item.contact}
+
+ )}
+ {/* @ts-ignore */}
+ {item.email && (
+
+ {item.email}
+
+ )}
+ {item.url && (
+
+ Visit Website
+
+ )}
+
+
+ ))}
+
+ )}
+
+ {section.type === "custom" && section.content && (
+
+
+
{section.content.intro}
+
+
+
+
+ {section.content.role}
+
+
+
+
+
Basic Requirements
+
+ {section.content.requirements.map((req, i) => (
+
+
+ {req}
+
+ ))}
+
+
+
+
Job Tasks
+
+ {section.content.tasks.map((task, i) => (
+
+
+ {task}
+
+ ))}
+
+
+
+
+
+
Knowledge, Skills & Abilities
+
+ {section.content.skills.map((skill, i) => (
+
+ ))}
+
+
+
+
+
+
Ready to Join the Team?
+
+ If you are willing to work outdoors during any season, have a desire to grow into leadership
+ roles, and are willing to listen and learn our processes, we want to hear from you!
+
+
+
+ Apply Now
+
+
+
+
+
+ )}
+
+ {index !== sections.length - 1 &&
}
+
+ ))}
+
+
+
+
+
+
+
+ )
+}
diff --git a/app/services/page.tsx b/app/services/page.tsx
new file mode 100755
index 0000000..726ca16
--- /dev/null
+++ b/app/services/page.tsx
@@ -0,0 +1,270 @@
+"use client"
+
+import { SiteHeader } from "@/components/site-header"
+import { SiteFooter } from "@/components/site-footer"
+import { Button } from "@/components/ui/button"
+import Link from "next/link"
+import { ArrowRight, CheckCircle2, Shield, Zap, Hammer, GraduationCap, Layers, ChevronRight } from "lucide-react"
+import { useState, useEffect } from "react"
+import { cn } from "@/lib/utils"
+
+export default function ServicesPage() {
+ const [activeSection, setActiveSection] = useState("foundations")
+
+ const services = [
+ {
+ id: "foundations",
+ title: "Footers & Foundations",
+ icon: Layers,
+ description:
+ "Start your build off right with a solid foundation. An ICF basement provides a comfortable and energy-efficient environment - even on cold Colorado winter nights.",
+ details: [
+ "Superior insulation values (R-22+)",
+ "Waterproofing and drainage solutions",
+ "Precision leveling and layout",
+ "Reinforced concrete core strength",
+ ],
+ image: "/icf-foundation-construction.jpg",
+ },
+ {
+ id: "heating",
+ title: "Radiant Heating Systems",
+ icon: Zap,
+ description:
+ "Say goodbye to cold floors and fluctuating heat. Radiant heating systems provide consistent heat from the floor up keeping your energy bills down. Paired with a concrete structural floor, you can have the best of both worlds.",
+ details: [
+ "Even heat distribution",
+ "Reduced energy costs (up to 30%)",
+ "Silent operation",
+ "Allergen-free heating method",
+ ],
+ image: "/radiant-floor-heating-installation.jpg",
+ },
+ {
+ id: "walls",
+ title: "ICF Above-Grade Walls",
+ icon: Shield,
+ description:
+ "ICFs aren't only for foundations. Poured walls will significantly raise the R value of your structure as compared to a traditional build. It also provides a high level of protection from fires and the ever-present Colorado winds.",
+ details: [
+ "Sound dampening (STC 50+)",
+ "Fire resistance (up to 4 hours)",
+ "Wind resistance (up to 250mph)",
+ "Mold and pest resistance",
+ ],
+ image: "/icf-above-grade-walls-construction.jpg",
+ },
+ {
+ id: "training",
+ title: "Training and Consulting",
+ icon: GraduationCap,
+ description:
+ "Want to install your own ICFs but need a little guidance for the first project? With over 20 years experience building with ICFs, the installers at High Performance Structures can provide you with a number of options to suit your needs.",
+ details: [
+ "On-site installation training",
+ "Project planning and estimation",
+ "Tool and equipment guidance",
+ "Quality assurance checks",
+ ],
+ image: "/construction-training-consultation.jpg",
+ },
+ {
+ id: "flooring",
+ title: "Structural Flooring",
+ icon: Hammer,
+ description:
+ "With the use of LiteDeck, we can easily install structural concrete flooring and decking for added strength and protection. Don't like the look of concrete floors? Not a problem as the floors can be stamped, stained or covered with your choice of flooring.",
+ details: [
+ "Long spans without columns",
+ "Integrated soundproofing",
+ "High load-bearing capacity",
+ "Compatible with radiant heating",
+ ],
+ image: "/concrete-structural-flooring.jpg",
+ },
+ {
+ id: "shelters",
+ title: "Safe Rooms & Shelters",
+ icon: Shield,
+ description:
+ "Whether it's to protect your family or your valuables in case of a fire, tornado or other natural disaster, ICFs provide superior protection.",
+ details: [
+ "FEMA-grade protection",
+ "Integrated into home design",
+ "Ballistic protection",
+ "Emergency supply storage",
+ ],
+ image: "/safe-room-shelter-construction.jpg",
+ },
+ ]
+
+ useEffect(() => {
+ const handleScroll = () => {
+ const sections = services.map((s) => document.getElementById(s.id))
+ const scrollPosition = window.scrollY + 200 // Offset for header
+
+ for (const section of sections) {
+ if (
+ section &&
+ section.offsetTop <= scrollPosition &&
+ section.offsetTop + section.offsetHeight > scrollPosition
+ ) {
+ setActiveSection(section.id)
+ }
+ }
+ }
+
+ window.addEventListener("scroll", handleScroll)
+ return () => window.removeEventListener("scroll", handleScroll)
+ }, []) // Removed services from dependencies
+
+ const scrollToSection = (id: string) => {
+ const element = document.getElementById(id)
+ if (element) {
+ const offset = 120 // Increased offset to account for header height + spacing
+ const bodyRect = document.body.getBoundingClientRect().top
+ const elementRect = element.getBoundingClientRect().top
+ const elementPosition = elementRect - bodyRect
+ const offsetPosition = elementPosition - offset
+
+ window.scrollTo({
+ top: offsetPosition,
+ behavior: "smooth",
+ })
+ }
+ }
+
+ return (
+
+
+
+
+ {/* Hero Section */}
+
+
+
+
+
+
+
+
+ Our Services
+
+
+ Comprehensive concrete and construction solutions tailored to your project's needs.
+
+
+
+
+
+
+ {/* Sticky Sidebar Navigation */}
+
+
+
Service Menu
+
+ {services.map((service) => (
+ scrollToSection(service.id)}
+ className={cn(
+ "w-full text-left px-4 py-3 rounded-lg text-sm font-medium transition-all duration-200 flex items-center justify-between group",
+ activeSection === service.id
+ ? "bg-deep-navy text-white shadow-md"
+ : "text-gray-600 hover:bg-gray-100 hover:text-deep-navy",
+ )}
+ >
+ {service.title}
+ {activeSection === service.id && }
+
+ ))}
+
+
+
Need a Quote?
+
Contact us today to discuss your project requirements.
+
+
Contact Us
+
+
+
+
+
+ {/* Main Content */}
+
+ {services.map((service, index) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
{service.title}
+
+
+
{service.description}
+
+
+ {service.details.map((detail, i) => (
+
+
+ {detail}
+
+ ))}
+
+
+
+
+
+ Request {service.title}
+
+
+
+
+
+ {index !== services.length - 1 &&
}
+
+ ))}
+
+
+
+
+ {/* Bottom CTA */}
+
+
+
Ready to Start Your Project?
+
+ Our team of experts is ready to help you build with confidence and precision.
+
+
+
+ Get a Free Quote
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/components.json b/components.json
new file mode 100644
index 0000000..edcaef2
--- /dev/null
+++ b/components.json
@@ -0,0 +1,22 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": true,
+ "tsx": true,
+ "tailwind": {
+ "config": "",
+ "css": "src/app/globals.css",
+ "baseColor": "neutral",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "iconLibrary": "lucide",
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/lib/utils",
+ "ui": "@/components/ui",
+ "lib": "@/lib",
+ "hooks": "@/hooks"
+ },
+ "registries": {}
+}
diff --git a/components/hps-logo.tsx b/components/hps-logo.tsx
new file mode 100755
index 0000000..6c0bde4
--- /dev/null
+++ b/components/hps-logo.tsx
@@ -0,0 +1,27 @@
+import Link from "next/link"
+import { cn } from "@/lib/utils"
+
+interface HpsLogoProps {
+ showCompanyName?: boolean
+ showPhone?: boolean
+ size?: "sm" | "md" | "lg"
+ className?: string
+}
+
+export function HpsLogo({ showCompanyName = false, showPhone = false, size = "md", className }: HpsLogoProps) {
+ const heightMap = {
+ sm: "h-10",
+ md: "h-14",
+ lg: "h-20",
+ }
+
+ return (
+
+
+
+ )
+}
diff --git a/components/site-footer.tsx b/components/site-footer.tsx
new file mode 100755
index 0000000..0ca44f3
--- /dev/null
+++ b/components/site-footer.tsx
@@ -0,0 +1,104 @@
+import Link from "next/link"
+import { Facebook, Instagram, Linkedin, Mail, MapPin, Phone } from "lucide-react"
+
+export function SiteFooter() {
+ return (
+
+
+
+ {/* Brand Info */}
+
+
+
+
+
+ High Performance Structures specializes in Insulating Concrete Form (ICF) installations, structural
+ concrete flooring, and radiant heating systems. Building the future, one structure at a time.
+
+
+
+
+ {/* Quick Links */}
+
+
Quick Links
+
+ {["Home", "Services", "Resources", "Blog", "Contact"].map((item) => (
+
+ {item}
+
+ ))}
+
+
+
+ {/* Services */}
+
+
Our Services
+
+ {[
+ "ICF Foundations",
+ "Above Grade Walls",
+ "Structural Floors",
+ "Radiant Heating",
+ "Safe Rooms",
+ "Consultation",
+ ].map((item) => (
+
+ {item}
+
+ ))}
+
+
+
+ {/* Contact Info */}
+
+
+
+
+
© {new Date().getFullYear()} High Performance Structures, Inc. All rights reserved.
+
+
+ Privacy Policy
+
+
+ Terms of Service
+
+
+
+
+
+ )
+}
diff --git a/components/site-header.tsx b/components/site-header.tsx
new file mode 100755
index 0000000..961a52e
--- /dev/null
+++ b/components/site-header.tsx
@@ -0,0 +1,140 @@
+"use client"
+
+import Link from "next/link"
+import { useState, useEffect } from "react"
+import { Menu, X, Phone, ArrowRight } from "lucide-react"
+import { Button } from "@/components/ui/button"
+import { HpsLogo } from "@/components/hps-logo"
+import { cn } from "@/lib/utils"
+
+export function SiteHeader() {
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
+ const [scrolled, setScrolled] = useState(false)
+
+ useEffect(() => {
+ const handleScroll = () => {
+ setScrolled(window.scrollY > 20)
+ }
+ window.addEventListener("scroll", handleScroll)
+ return () => window.removeEventListener("scroll", handleScroll)
+ }, [])
+
+ const navigation = [
+ { name: "Home", href: "/" },
+ { name: "Services", href: "/services" },
+ { name: "Resources", href: "/resources" },
+ { name: "Blog", href: "/blog" },
+ { name: "Contact", href: "/contact" },
+ ]
+
+ return (
+
+
+
+ {/* Logo */}
+
+
+ {/* Desktop Navigation - Minimalist Centered */}
+
+
+ {navigation.map((item) => (
+
+ {item.name}
+
+ ))}
+
+
+
+ {/* Right Side Actions */}
+
+
+ {/* Mobile Navigation Toggle */}
+
+ setMobileMenuOpen(!mobileMenuOpen)}
+ className={cn(
+ "relative z-50 rounded-full w-12 h-12 transition-colors",
+ scrolled || mobileMenuOpen ? "text-deep-navy hover:bg-gray-100" : "text-white hover:bg-white/10",
+ )}
+ >
+ {mobileMenuOpen ? : }
+
+
+
+
+
+ {/* Mobile Navigation Overlay */}
+
+
+
+ {navigation.map((item, index) => (
+ setMobileMenuOpen(false)}
+ style={{ transitionDelay: `${index * 50}ms` }}
+ >
+ {item.name}
+
+
+ ))}
+
+
+
+
+
+
+ )
+}
diff --git a/components/theme-provider.tsx b/components/theme-provider.tsx
new file mode 100755
index 0000000..55c2f6e
--- /dev/null
+++ b/components/theme-provider.tsx
@@ -0,0 +1,11 @@
+'use client'
+
+import * as React from 'react'
+import {
+ ThemeProvider as NextThemesProvider,
+ type ThemeProviderProps,
+} from 'next-themes'
+
+export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
+ return {children}
+}
diff --git a/components/ui/accordion.tsx b/components/ui/accordion.tsx
new file mode 100755
index 0000000..e538a33
--- /dev/null
+++ b/components/ui/accordion.tsx
@@ -0,0 +1,66 @@
+'use client'
+
+import * as React from 'react'
+import * as AccordionPrimitive from '@radix-ui/react-accordion'
+import { ChevronDownIcon } from 'lucide-react'
+
+import { cn } from '@/lib/utils'
+
+function Accordion({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function AccordionItem({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AccordionTrigger({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ svg]:rotate-180',
+ className,
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+ )
+}
+
+function AccordionContent({
+ className,
+ children,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ {children}
+
+ )
+}
+
+export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
diff --git a/components/ui/alert-dialog.tsx b/components/ui/alert-dialog.tsx
new file mode 100755
index 0000000..9704452
--- /dev/null
+++ b/components/ui/alert-dialog.tsx
@@ -0,0 +1,157 @@
+'use client'
+
+import * as React from 'react'
+import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog'
+
+import { cn } from '@/lib/utils'
+import { buttonVariants } from '@/components/ui/button'
+
+function AlertDialog({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+function AlertDialogTrigger({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogPortal({
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogOverlay({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogContent({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+
+
+ )
+}
+
+function AlertDialogHeader({
+ className,
+ ...props
+}: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function AlertDialogFooter({
+ className,
+ ...props
+}: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function AlertDialogTitle({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogDescription({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogAction({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AlertDialogCancel({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ AlertDialog,
+ AlertDialogPortal,
+ AlertDialogOverlay,
+ AlertDialogTrigger,
+ AlertDialogContent,
+ AlertDialogHeader,
+ AlertDialogFooter,
+ AlertDialogTitle,
+ AlertDialogDescription,
+ AlertDialogAction,
+ AlertDialogCancel,
+}
diff --git a/components/ui/alert.tsx b/components/ui/alert.tsx
new file mode 100755
index 0000000..e6751ab
--- /dev/null
+++ b/components/ui/alert.tsx
@@ -0,0 +1,66 @@
+import * as React from 'react'
+import { cva, type VariantProps } from 'class-variance-authority'
+
+import { cn } from '@/lib/utils'
+
+const alertVariants = cva(
+ 'relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
+ {
+ variants: {
+ variant: {
+ default: 'bg-card text-card-foreground',
+ destructive:
+ 'text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90',
+ },
+ },
+ defaultVariants: {
+ variant: 'default',
+ },
+ },
+)
+
+function Alert({
+ className,
+ variant,
+ ...props
+}: React.ComponentProps<'div'> & VariantProps) {
+ return (
+
+ )
+}
+
+function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function AlertDescription({
+ className,
+ ...props
+}: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+export { Alert, AlertTitle, AlertDescription }
diff --git a/components/ui/aspect-ratio.tsx b/components/ui/aspect-ratio.tsx
new file mode 100755
index 0000000..40bb120
--- /dev/null
+++ b/components/ui/aspect-ratio.tsx
@@ -0,0 +1,11 @@
+'use client'
+
+import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio'
+
+function AspectRatio({
+ ...props
+}: React.ComponentProps) {
+ return
+}
+
+export { AspectRatio }
diff --git a/components/ui/avatar.tsx b/components/ui/avatar.tsx
new file mode 100755
index 0000000..aa98465
--- /dev/null
+++ b/components/ui/avatar.tsx
@@ -0,0 +1,53 @@
+'use client'
+
+import * as React from 'react'
+import * as AvatarPrimitive from '@radix-ui/react-avatar'
+
+import { cn } from '@/lib/utils'
+
+function Avatar({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AvatarImage({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+function AvatarFallback({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export { Avatar, AvatarImage, AvatarFallback }
diff --git a/components/ui/badge.tsx b/components/ui/badge.tsx
new file mode 100755
index 0000000..fc4126b
--- /dev/null
+++ b/components/ui/badge.tsx
@@ -0,0 +1,46 @@
+import * as React from 'react'
+import { Slot } from '@radix-ui/react-slot'
+import { cva, type VariantProps } from 'class-variance-authority'
+
+import { cn } from '@/lib/utils'
+
+const badgeVariants = cva(
+ 'inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
+ {
+ variants: {
+ variant: {
+ default:
+ 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
+ secondary:
+ 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
+ destructive:
+ 'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
+ outline:
+ 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
+ },
+ },
+ defaultVariants: {
+ variant: 'default',
+ },
+ },
+)
+
+function Badge({
+ className,
+ variant,
+ asChild = false,
+ ...props
+}: React.ComponentProps<'span'> &
+ VariantProps & { asChild?: boolean }) {
+ const Comp = asChild ? Slot : 'span'
+
+ return (
+
+ )
+}
+
+export { Badge, badgeVariants }
diff --git a/components/ui/breadcrumb.tsx b/components/ui/breadcrumb.tsx
new file mode 100755
index 0000000..1750ff2
--- /dev/null
+++ b/components/ui/breadcrumb.tsx
@@ -0,0 +1,109 @@
+import * as React from 'react'
+import { Slot } from '@radix-ui/react-slot'
+import { ChevronRight, MoreHorizontal } from 'lucide-react'
+
+import { cn } from '@/lib/utils'
+
+function Breadcrumb({ ...props }: React.ComponentProps<'nav'>) {
+ return
+}
+
+function BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {
+ return (
+
+ )
+}
+
+function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {
+ return (
+
+ )
+}
+
+function BreadcrumbLink({
+ asChild,
+ className,
+ ...props
+}: React.ComponentProps<'a'> & {
+ asChild?: boolean
+}) {
+ const Comp = asChild ? Slot : 'a'
+
+ return (
+
+ )
+}
+
+function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
+ return (
+
+ )
+}
+
+function BreadcrumbSeparator({
+ children,
+ className,
+ ...props
+}: React.ComponentProps<'li'>) {
+ return (
+ svg]:size-3.5', className)}
+ {...props}
+ >
+ {children ?? }
+
+ )
+}
+
+function BreadcrumbEllipsis({
+ className,
+ ...props
+}: React.ComponentProps<'span'>) {
+ return (
+
+
+ More
+
+ )
+}
+
+export {
+ Breadcrumb,
+ BreadcrumbList,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+ BreadcrumbEllipsis,
+}
diff --git a/components/ui/button-group.tsx b/components/ui/button-group.tsx
new file mode 100755
index 0000000..09d4430
--- /dev/null
+++ b/components/ui/button-group.tsx
@@ -0,0 +1,83 @@
+import { Slot } from '@radix-ui/react-slot'
+import { cva, type VariantProps } from 'class-variance-authority'
+
+import { cn } from '@/lib/utils'
+import { Separator } from '@/components/ui/separator'
+
+const buttonGroupVariants = cva(
+ "flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2",
+ {
+ variants: {
+ orientation: {
+ horizontal:
+ '[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',
+ vertical:
+ 'flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',
+ },
+ },
+ defaultVariants: {
+ orientation: 'horizontal',
+ },
+ },
+)
+
+function ButtonGroup({
+ className,
+ orientation,
+ ...props
+}: React.ComponentProps<'div'> & VariantProps) {
+ return (
+
+ )
+}
+
+function ButtonGroupText({
+ className,
+ asChild = false,
+ ...props
+}: React.ComponentProps<'div'> & {
+ asChild?: boolean
+}) {
+ const Comp = asChild ? Slot : 'div'
+
+ return (
+
+ )
+}
+
+function ButtonGroupSeparator({
+ className,
+ orientation = 'vertical',
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ )
+}
+
+export {
+ ButtonGroup,
+ ButtonGroupSeparator,
+ ButtonGroupText,
+ buttonGroupVariants,
+}
diff --git a/components/ui/button.tsx b/components/ui/button.tsx
new file mode 100755
index 0000000..f64632d
--- /dev/null
+++ b/components/ui/button.tsx
@@ -0,0 +1,60 @@
+import * as React from 'react'
+import { Slot } from '@radix-ui/react-slot'
+import { cva, type VariantProps } from 'class-variance-authority'
+
+import { cn } from '@/lib/utils'
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ {
+ variants: {
+ variant: {
+ default: 'bg-primary text-primary-foreground hover:bg-primary/90',
+ destructive:
+ 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
+ outline:
+ 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
+ secondary:
+ 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
+ ghost:
+ 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
+ link: 'text-primary underline-offset-4 hover:underline',
+ },
+ size: {
+ default: 'h-9 px-4 py-2 has-[>svg]:px-3',
+ sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
+ lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
+ icon: 'size-9',
+ 'icon-sm': 'size-8',
+ 'icon-lg': 'size-10',
+ },
+ },
+ defaultVariants: {
+ variant: 'default',
+ size: 'default',
+ },
+ },
+)
+
+function Button({
+ className,
+ variant,
+ size,
+ asChild = false,
+ ...props
+}: React.ComponentProps<'button'> &
+ VariantProps & {
+ asChild?: boolean
+ }) {
+ const Comp = asChild ? Slot : 'button'
+
+ return (
+
+ )
+}
+
+export { Button, buttonVariants }
diff --git a/components/ui/calendar.tsx b/components/ui/calendar.tsx
new file mode 100755
index 0000000..eaa373e
--- /dev/null
+++ b/components/ui/calendar.tsx
@@ -0,0 +1,213 @@
+'use client'
+
+import * as React from 'react'
+import {
+ ChevronDownIcon,
+ ChevronLeftIcon,
+ ChevronRightIcon,
+} from 'lucide-react'
+import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker'
+
+import { cn } from '@/lib/utils'
+import { Button, buttonVariants } from '@/components/ui/button'
+
+function Calendar({
+ className,
+ classNames,
+ showOutsideDays = true,
+ captionLayout = 'label',
+ buttonVariant = 'ghost',
+ formatters,
+ components,
+ ...props
+}: React.ComponentProps & {
+ buttonVariant?: React.ComponentProps['variant']
+}) {
+ const defaultClassNames = getDefaultClassNames()
+
+ return (
+ svg]:rotate-180`,
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
+ className,
+ )}
+ captionLayout={captionLayout}
+ formatters={{
+ formatMonthDropdown: (date) =>
+ date.toLocaleString('default', { month: 'short' }),
+ ...formatters,
+ }}
+ classNames={{
+ root: cn('w-fit', defaultClassNames.root),
+ months: cn(
+ 'flex gap-4 flex-col md:flex-row relative',
+ defaultClassNames.months,
+ ),
+ month: cn('flex flex-col w-full gap-4', defaultClassNames.month),
+ nav: cn(
+ 'flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between',
+ defaultClassNames.nav,
+ ),
+ button_previous: cn(
+ buttonVariants({ variant: buttonVariant }),
+ 'size-(--cell-size) aria-disabled:opacity-50 p-0 select-none',
+ defaultClassNames.button_previous,
+ ),
+ button_next: cn(
+ buttonVariants({ variant: buttonVariant }),
+ 'size-(--cell-size) aria-disabled:opacity-50 p-0 select-none',
+ defaultClassNames.button_next,
+ ),
+ month_caption: cn(
+ 'flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)',
+ defaultClassNames.month_caption,
+ ),
+ dropdowns: cn(
+ 'w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5',
+ defaultClassNames.dropdowns,
+ ),
+ dropdown_root: cn(
+ 'relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md',
+ defaultClassNames.dropdown_root,
+ ),
+ dropdown: cn(
+ 'absolute bg-popover inset-0 opacity-0',
+ defaultClassNames.dropdown,
+ ),
+ caption_label: cn(
+ 'select-none font-medium',
+ captionLayout === 'label'
+ ? 'text-sm'
+ : 'rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5',
+ defaultClassNames.caption_label,
+ ),
+ table: 'w-full border-collapse',
+ weekdays: cn('flex', defaultClassNames.weekdays),
+ weekday: cn(
+ 'text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none',
+ defaultClassNames.weekday,
+ ),
+ week: cn('flex w-full mt-2', defaultClassNames.week),
+ week_number_header: cn(
+ 'select-none w-(--cell-size)',
+ defaultClassNames.week_number_header,
+ ),
+ week_number: cn(
+ 'text-[0.8rem] select-none text-muted-foreground',
+ defaultClassNames.week_number,
+ ),
+ day: cn(
+ 'relative w-full h-full p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none',
+ defaultClassNames.day,
+ ),
+ range_start: cn(
+ 'rounded-l-md bg-accent',
+ defaultClassNames.range_start,
+ ),
+ range_middle: cn('rounded-none', defaultClassNames.range_middle),
+ range_end: cn('rounded-r-md bg-accent', defaultClassNames.range_end),
+ today: cn(
+ 'bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none',
+ defaultClassNames.today,
+ ),
+ outside: cn(
+ 'text-muted-foreground aria-selected:text-muted-foreground',
+ defaultClassNames.outside,
+ ),
+ disabled: cn(
+ 'text-muted-foreground opacity-50',
+ defaultClassNames.disabled,
+ ),
+ hidden: cn('invisible', defaultClassNames.hidden),
+ ...classNames,
+ }}
+ components={{
+ Root: ({ className, rootRef, ...props }) => {
+ return (
+
+ )
+ },
+ Chevron: ({ className, orientation, ...props }) => {
+ if (orientation === 'left') {
+ return (
+
+ )
+ }
+
+ if (orientation === 'right') {
+ return (
+
+ )
+ }
+
+ return (
+
+ )
+ },
+ DayButton: CalendarDayButton,
+ WeekNumber: ({ children, ...props }) => {
+ return (
+
+
+ {children}
+
+
+ )
+ },
+ ...components,
+ }}
+ {...props}
+ />
+ )
+}
+
+function CalendarDayButton({
+ className,
+ day,
+ modifiers,
+ ...props
+}: React.ComponentProps) {
+ const defaultClassNames = getDefaultClassNames()
+
+ const ref = React.useRef(null)
+ React.useEffect(() => {
+ if (modifiers.focused) ref.current?.focus()
+ }, [modifiers.focused])
+
+ return (
+ span]:text-xs [&>span]:opacity-70',
+ defaultClassNames.day,
+ className,
+ )}
+ {...props}
+ />
+ )
+}
+
+export { Calendar, CalendarDayButton }
diff --git a/components/ui/card.tsx b/components/ui/card.tsx
new file mode 100755
index 0000000..db7dd3c
--- /dev/null
+++ b/components/ui/card.tsx
@@ -0,0 +1,92 @@
+import * as React from 'react'
+
+import { cn } from '@/lib/utils'
+
+function Card({ className, ...props }: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
+ return (
+
+ )
+}
+
+export {
+ Card,
+ CardHeader,
+ CardFooter,
+ CardTitle,
+ CardAction,
+ CardDescription,
+ CardContent,
+}
diff --git a/components/ui/carousel.tsx b/components/ui/carousel.tsx
new file mode 100755
index 0000000..d4a768e
--- /dev/null
+++ b/components/ui/carousel.tsx
@@ -0,0 +1,241 @@
+'use client'
+
+import * as React from 'react'
+import useEmblaCarousel, {
+ type UseEmblaCarouselType,
+} from 'embla-carousel-react'
+import { ArrowLeft, ArrowRight } from 'lucide-react'
+
+import { cn } from '@/lib/utils'
+import { Button } from '@/components/ui/button'
+
+type CarouselApi = UseEmblaCarouselType[1]
+type UseCarouselParameters = Parameters
+type CarouselOptions = UseCarouselParameters[0]
+type CarouselPlugin = UseCarouselParameters[1]
+
+type CarouselProps = {
+ opts?: CarouselOptions
+ plugins?: CarouselPlugin
+ orientation?: 'horizontal' | 'vertical'
+ setApi?: (api: CarouselApi) => void
+}
+
+type CarouselContextProps = {
+ carouselRef: ReturnType[0]
+ api: ReturnType[1]
+ scrollPrev: () => void
+ scrollNext: () => void
+ canScrollPrev: boolean
+ canScrollNext: boolean
+} & CarouselProps
+
+const CarouselContext = React.createContext(null)
+
+function useCarousel() {
+ const context = React.useContext(CarouselContext)
+
+ if (!context) {
+ throw new Error('useCarousel must be used within a ')
+ }
+
+ return context
+}
+
+function Carousel({
+ orientation = 'horizontal',
+ opts,
+ setApi,
+ plugins,
+ className,
+ children,
+ ...props
+}: React.ComponentProps<'div'> & CarouselProps) {
+ const [carouselRef, api] = useEmblaCarousel(
+ {
+ ...opts,
+ axis: orientation === 'horizontal' ? 'x' : 'y',
+ },
+ plugins,
+ )
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false)
+ const [canScrollNext, setCanScrollNext] = React.useState(false)
+
+ const onSelect = React.useCallback((api: CarouselApi) => {
+ if (!api) return
+ setCanScrollPrev(api.canScrollPrev())
+ setCanScrollNext(api.canScrollNext())
+ }, [])
+
+ const scrollPrev = React.useCallback(() => {
+ api?.scrollPrev()
+ }, [api])
+
+ const scrollNext = React.useCallback(() => {
+ api?.scrollNext()
+ }, [api])
+
+ const handleKeyDown = React.useCallback(
+ (event: React.KeyboardEvent) => {
+ if (event.key === 'ArrowLeft') {
+ event.preventDefault()
+ scrollPrev()
+ } else if (event.key === 'ArrowRight') {
+ event.preventDefault()
+ scrollNext()
+ }
+ },
+ [scrollPrev, scrollNext],
+ )
+
+ React.useEffect(() => {
+ if (!api || !setApi) return
+ setApi(api)
+ }, [api, setApi])
+
+ React.useEffect(() => {
+ if (!api) return
+ onSelect(api)
+ api.on('reInit', onSelect)
+ api.on('select', onSelect)
+
+ return () => {
+ api?.off('select', onSelect)
+ }
+ }, [api, onSelect])
+
+ return (
+
+
+ {children}
+
+
+ )
+}
+
+function CarouselContent({ className, ...props }: React.ComponentProps<'div'>) {
+ const { carouselRef, orientation } = useCarousel()
+
+ return (
+
+ )
+}
+
+function CarouselItem({ className, ...props }: React.ComponentProps<'div'>) {
+ const { orientation } = useCarousel()
+
+ return (
+
+ )
+}
+
+function CarouselPrevious({
+ className,
+ variant = 'outline',
+ size = 'icon',
+ ...props
+}: React.ComponentProps) {
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel()
+
+ return (
+
+
+ Previous slide
+
+ )
+}
+
+function CarouselNext({
+ className,
+ variant = 'outline',
+ size = 'icon',
+ ...props
+}: React.ComponentProps) {
+ const { orientation, scrollNext, canScrollNext } = useCarousel()
+
+ return (
+
+
+ Next slide
+
+ )
+}
+
+export {
+ type CarouselApi,
+ Carousel,
+ CarouselContent,
+ CarouselItem,
+ CarouselPrevious,
+ CarouselNext,
+}
diff --git a/components/ui/chart.tsx b/components/ui/chart.tsx
new file mode 100755
index 0000000..421fe58
--- /dev/null
+++ b/components/ui/chart.tsx
@@ -0,0 +1,353 @@
+'use client'
+
+import * as React from 'react'
+import * as RechartsPrimitive from 'recharts'
+
+import { cn } from '@/lib/utils'
+
+// Format: { THEME_NAME: CSS_SELECTOR }
+const THEMES = { light: '', dark: '.dark' } as const
+
+export type ChartConfig = {
+ [k in string]: {
+ label?: React.ReactNode
+ icon?: React.ComponentType
+ } & (
+ | { color?: string; theme?: never }
+ | { color?: never; theme: Record }
+ )
+}
+
+type ChartContextProps = {
+ config: ChartConfig
+}
+
+const ChartContext = React.createContext(null)
+
+function useChart() {
+ const context = React.useContext(ChartContext)
+
+ if (!context) {
+ throw new Error('useChart must be used within a ')
+ }
+
+ return context
+}
+
+function ChartContainer({
+ id,
+ className,
+ children,
+ config,
+ ...props
+}: React.ComponentProps<'div'> & {
+ config: ChartConfig
+ children: React.ComponentProps<
+ typeof RechartsPrimitive.ResponsiveContainer
+ >['children']
+}) {
+ const uniqueId = React.useId()
+ const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`
+
+ return (
+
+
+
+
+ {children}
+
+
+
+ )
+}
+
+const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
+ const colorConfig = Object.entries(config).filter(
+ ([, config]) => config.theme || config.color,
+ )
+
+ if (!colorConfig.length) {
+ return null
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/public/placeholder-logo.png b/public/placeholder-logo.png
new file mode 100755
index 0000000..8a792ac
Binary files /dev/null and b/public/placeholder-logo.png differ
diff --git a/public/placeholder-logo.svg b/public/placeholder-logo.svg
new file mode 100755
index 0000000..b1695aa
--- /dev/null
+++ b/public/placeholder-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/placeholder-user.jpg b/public/placeholder-user.jpg
new file mode 100755
index 0000000..6fa7543
Binary files /dev/null and b/public/placeholder-user.jpg differ
diff --git a/public/placeholder.jpg b/public/placeholder.jpg
new file mode 100755
index 0000000..6bfe963
Binary files /dev/null and b/public/placeholder.jpg differ
diff --git a/public/placeholder.svg b/public/placeholder.svg
new file mode 100755
index 0000000..e763910
--- /dev/null
+++ b/public/placeholder.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/radiant-floor-heating-installation.jpg b/public/radiant-floor-heating-installation.jpg
new file mode 100755
index 0000000..9289961
Binary files /dev/null and b/public/radiant-floor-heating-installation.jpg differ
diff --git a/public/safe-room-shelter-construction.jpg b/public/safe-room-shelter-construction.jpg
new file mode 100755
index 0000000..38cb07a
Binary files /dev/null and b/public/safe-room-shelter-construction.jpg differ
diff --git a/src/app/globals.css b/src/app/globals.css
deleted file mode 100644
index 0673ff0..0000000
--- a/src/app/globals.css
+++ /dev/null
@@ -1,26 +0,0 @@
-@import "tailwindcss";
-
-:root {
- --background: #ffffff;
- --foreground: #171717;
-}
-
-@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --background: #0a0a0a;
- --foreground: #ededed;
- }
-}
-
-body {
- background: var(--background);
- color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
-}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
deleted file mode 100644
index eaf080d..0000000
--- a/src/app/layout.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
-import "./globals.css";
-
-const geistSans = Geist({
- variable: "--font-geist-sans",
- subsets: ["latin"],
-});
-
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
- subsets: ["latin"],
-});
-
-export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
-};
-
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
-
-
-
- {children}
-
- );
-}
diff --git a/src/app/page.tsx b/src/app/page.tsx
deleted file mode 100644
index bf3c7e7..0000000
--- a/src/app/page.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import Image from "next/image";
-
-export default function Home() {
- return (
-
-
-
-
-
- Get started by editing{" "}
-
- src/app/page.tsx
-
- .
-
- Save and see your changes instantly.
-
-
-
-
-
-
- );
-}
diff --git a/styles/globals.css b/styles/globals.css
new file mode 100755
index 0000000..dc2aea1
--- /dev/null
+++ b/styles/globals.css
@@ -0,0 +1,125 @@
+@import 'tailwindcss';
+@import 'tw-animate-css';
+
+@custom-variant dark (&:is(.dark *));
+
+:root {
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.145 0 0);
+ --card: oklch(1 0 0);
+ --card-foreground: oklch(0.145 0 0);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.145 0 0);
+ --primary: oklch(0.205 0 0);
+ --primary-foreground: oklch(0.985 0 0);
+ --secondary: oklch(0.97 0 0);
+ --secondary-foreground: oklch(0.205 0 0);
+ --muted: oklch(0.97 0 0);
+ --muted-foreground: oklch(0.556 0 0);
+ --accent: oklch(0.97 0 0);
+ --accent-foreground: oklch(0.205 0 0);
+ --destructive: oklch(0.577 0.245 27.325);
+ --destructive-foreground: oklch(0.577 0.245 27.325);
+ --border: oklch(0.922 0 0);
+ --input: oklch(0.922 0 0);
+ --ring: oklch(0.708 0 0);
+ --chart-1: oklch(0.646 0.222 41.116);
+ --chart-2: oklch(0.6 0.118 184.704);
+ --chart-3: oklch(0.398 0.07 227.392);
+ --chart-4: oklch(0.828 0.189 84.429);
+ --chart-5: oklch(0.769 0.188 70.08);
+ --radius: 0.625rem;
+ --sidebar: oklch(0.985 0 0);
+ --sidebar-foreground: oklch(0.145 0 0);
+ --sidebar-primary: oklch(0.205 0 0);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.97 0 0);
+ --sidebar-accent-foreground: oklch(0.205 0 0);
+ --sidebar-border: oklch(0.922 0 0);
+ --sidebar-ring: oklch(0.708 0 0);
+}
+
+.dark {
+ --background: oklch(0.145 0 0);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.145 0 0);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.145 0 0);
+ --popover-foreground: oklch(0.985 0 0);
+ --primary: oklch(0.985 0 0);
+ --primary-foreground: oklch(0.205 0 0);
+ --secondary: oklch(0.269 0 0);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.269 0 0);
+ --muted-foreground: oklch(0.708 0 0);
+ --accent: oklch(0.269 0 0);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.396 0.141 25.723);
+ --destructive-foreground: oklch(0.637 0.237 25.331);
+ --border: oklch(0.269 0 0);
+ --input: oklch(0.269 0 0);
+ --ring: oklch(0.439 0 0);
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+ --sidebar: oklch(0.205 0 0);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.488 0.243 264.376);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.269 0 0);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(0.269 0 0);
+ --sidebar-ring: oklch(0.439 0 0);
+}
+
+@theme inline {
+ --font-sans: 'Geist', 'Geist Fallback';
+ --font-mono: 'Geist Mono', 'Geist Mono Fallback';
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-destructive-foreground: var(--destructive-foreground);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --color-sidebar: var(--sidebar);
+ --color-sidebar-foreground: var(--sidebar-foreground);
+ --color-sidebar-primary: var(--sidebar-primary);
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+ --color-sidebar-accent: var(--sidebar-accent);
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+ --color-sidebar-border: var(--sidebar-border);
+ --color-sidebar-ring: var(--sidebar-ring);
+}
+
+@layer base {
+ * {
+ @apply border-border outline-ring/50;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/tsconfig.json b/tsconfig.json
index c354369..8e8f7b4 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,33 +1,47 @@
{
- "compilerOptions": {
- "target": "ES2017",
- "lib": ["dom", "dom.iterable", "esnext"],
- "allowJs": true,
- "skipLibCheck": true,
- "strict": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "esnext",
- "moduleResolution": "bundler",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve",
- "incremental": true,
- "plugins": [
- {
- "name": "next"
- }
- ],
- "paths": {
- "@/*": ["./src/*"]
- },
- "types": [
- "./cloudflare-env.d.ts",
- "./cloudflare-env.d.ts",
- "node",
- "node"
- ]
- },
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
- "exclude": ["node_modules"]
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": [
+ "./*"
+ ]
+ },
+ "types": [
+ "./cloudflare-env.d.ts",
+ "./cloudflare-env.d.ts",
+ "node",
+ "node"
+ ]
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ ".next/dev/types/**/*.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
}