commit ecebd00021c576a9854174bfa3e9bf9b08831cac Author: George Birikorang Date: Fri Aug 22 10:38:10 2025 -0400 Initial commit: KH3 Group Limited website with enhanced animations and slide+zoom transitions diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..17197ae --- /dev/null +++ b/.gitignore @@ -0,0 +1,67 @@ +# Dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build outputs +dist/ +build/ +*.min.css +*.min.js +styles/main.css + +# Environment variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Coverage directory used by tools like istanbul +coverage/ + +# Temporary folders +tmp/ +temp/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity diff --git a/README.md b/README.md new file mode 100644 index 0000000..0b24644 --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ +# KH3 Website + +A clean, minimal static website built with HTML, JavaScript, and Tailwind CSS for KH3 - Building Inspiring Spaces. + +## Quick Start + +### Prerequisites + +- Node.js (for Tailwind CSS CLI) +- npm (comes with Node.js) + +### Setup Instructions + +1. **Clone or download the project** + + ```bash + git clone + cd fbs-static + ``` + +2. **Install Tailwind CSS** + + ```bash + npm install + ``` + +3. **Generate the optimized CSS** + + ```bash + npm run build + ``` + +4. **Open the website** + - Open `index.html` in your web browser + - Or serve it with a local server + +## Project Structure + +``` +fbs-static/ +├─ index.html # Main website page +├─ about.html # About Us page +├─ contact.html # Contact page +├─ src/ +│ └─ input.css # Tailwind directives +├─ styles/ +│ └─ main.css # Generated optimized CSS +├─ js/ +│ └─ main.js # JavaScript functionality +├─ assets/images/ # Image assets +├─ tailwind.config.js # Tailwind configuration +├─ package.json # Dependencies +└─ README.md # This file +``` + +## Development + +### For Active Development + +If you're making frequent changes to the HTML, you can use watch mode to automatically regenerate CSS: + +```bash +npm run watch +``` + +Keep this running in a terminal while you work. It will automatically rebuild the CSS whenever you save changes to your HTML files. + +### Manual Regeneration + +If watch mode doesn't work or you prefer manual control: + +```bash +# One-time build +npm run build + +# Watch mode (auto-regenerate on changes) +npm run watch +``` + +**Note:** If watch mode doesn't work, just run the one-time build command after each change. + +### What This Does + +- Scans your HTML files for used Tailwind classes +- Generates only the CSS you need (purges unused styles) +- Creates a tiny, optimized CSS file (~1KB vs ~3MB CDN) + +## Features + +- **Clean, minimal design** with Tailwind CSS +- **Optimized performance** with purged CSS +- **Responsive layout** that works on all devices +- **No build tools required** for production +- **Easy maintenance** with Tailwind utility classes +- **Custom animations** for logo, menu grid, and buttons +- **Auto-switching hero images** +- **Staggered loading animations** + +## Customization + +To add new Tailwind classes: + +1. Add the classes to your HTML +2. Run the CSS generation command +3. The new styles will be included in the output + +To modify the design: + +1. Change Tailwind classes in HTML files +2. Regenerate CSS with the CLI command +3. Refresh your browser to see changes + +## Custom Colors & Animations + +The website uses custom KH3 brand colors and animations defined in `tailwind.config.js`: + +- **Colors**: kh3-black, kh3-red, kh3-gold, kh3-darkGold, kh3-lightGold +- **Animations**: logo-float, text-float, border-glow, menu-grid-cycle, fade-in variants + +## Production + +For production deployment: + +1. Run `npm run build` to generate the final CSS +2. Upload all files to your web server +3. The website will work without Node.js in production + +## License + +MIT License diff --git a/about.html b/about.html new file mode 100644 index 0000000..52a7181 --- /dev/null +++ b/about.html @@ -0,0 +1,1076 @@ + + + + + + About Us - KH3 + + + + + + + + + + + + +
+
+ + + KH3 + KH3 + + + + +
+
+ + +
+ +
+
+

+ About KH3 +

+

+ Building inspiring spaces through innovative construction and design + solutions since 2014 +

+
+
+ + +
+
+
+

+ OUR STORY +

+
+

+ BASED IN ACCRA, GHANA, KH3 WAS ESTABLISHED IN + 2014 TO CATER + FOR THE CONSTRUCTION PROJECT MANAGEMENT NEEDS OF COMMERCIAL + CLIENTS. WITH A GROWING REPUTATION FOR QUALITY, ATTENTION TO + DETAIL AND THE UPMOST + PROFESSIONALISM, + KH3 EXPANDED INTO COMPREHENSIVE DESIGN AND FIT-OUT SERVICES. +

+

+ THIS MEANT MORE CONTROL OVER THE END-TO-END PROCESS, MAINTAINING + HIGH STANDARDS + FROM START TO FINISH AND ENSURING THAT THE ORIGINAL + SPECIFICATION COULD BE MET AND EXCEEDED. TODAY, KH3 WORKS WITH A + BROAD SPECTRUM OF CLIENTS, EXPANDING INTO NEW MARKETS WHILST + HANDLING THE ENTIRE PROCESS FROM DESIGN TO THE FINAL FINISH. +

+
+
+
+
+ + +
+
+
+

+ OUR VALUES +

+

+ The principles that guide everything we do +

+
+ +
+
+
+

QUALITY

+

+ We maintain the highest standards in every project, ensuring + excellence from conception to completion. +

+
+ +
+
+

PROFESSIONALISM

+

+ Our team approaches every project with dedication, expertise, + and unwavering commitment to our clients. +

+
+ +
+
+

INNOVATION

+

+ We continuously evolve our methods and embrace new technologies + to deliver cutting-edge solutions. +

+
+
+
+
+
+ + +
+
+
+
+
+ KH3 + KH3 +
+

+ Building inspiring spaces through innovative construction and + design solutions. +

+
+
+

Quick Links

+ +
+
+

Contact Info

+
+

Accra, Ghana

+

Email: info@kh3.com

+

Phone: +233 XX XXX XXXX

+
+
+
+
+

© 2024 KH3. All rights reserved.

+
+
+
+ + +
+ + +
+
+
+ KH3 + KH3 +
+
+
+
+
+
+ + + + + + + diff --git a/assets/images/chair.png b/assets/images/chair.png new file mode 100644 index 0000000..c7a49c4 Binary files /dev/null and b/assets/images/chair.png differ diff --git a/assets/images/google.png b/assets/images/google.png new file mode 100644 index 0000000..e14cb13 Binary files /dev/null and b/assets/images/google.png differ diff --git a/assets/images/kh3_logo.png b/assets/images/kh3_logo.png new file mode 100644 index 0000000..f499e7e Binary files /dev/null and b/assets/images/kh3_logo.png differ diff --git a/assets/images/kh3_logo_dark.png b/assets/images/kh3_logo_dark.png new file mode 100644 index 0000000..afd730e Binary files /dev/null and b/assets/images/kh3_logo_dark.png differ diff --git a/assets/images/room.png b/assets/images/room.png new file mode 100644 index 0000000..5d957e9 Binary files /dev/null and b/assets/images/room.png differ diff --git a/contact.html b/contact.html new file mode 100644 index 0000000..14db76c --- /dev/null +++ b/contact.html @@ -0,0 +1,408 @@ + + + + + + + Contact Us - KH3 | Building Inspiring Spaces + + + + + + + + + + +
+
+
+
+ KH3 + KH3 +
+ +
+
+
+ + +
+
+
+

CONTACT US

+
+ LET'S DISCUSS YOUR PROJECT +
+
+
+
+ + +
+
+
+
+

GET IN TOUCH

+

+ Ready to start your next project? We'd love to hear from you. Fill + out the form and we'll get back to you within 24 hours. +

+ +
+
+
📍
+
+

Address

+

Accra, Ghana
Main Office

+
+
+ +
+
📞
+
+

Phone

+

+ +233 20 123 4567
+233 24 123 4567 +

+
+
+ +
+
✉️
+
+

Email

+

+ info@kh3.com
projects@kh3.com +

+
+
+ +
+
🕒
+
+

Business Hours

+

+ Monday - Friday
8:00 AM - 6:00 PM +

+
+
+
+
+ +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ + +
+ + +
+
+
+
+
+ + +
+
+

FIND US

+
+
+

Accra, Ghana

+

+ Our main office is located in the heart of Accra, easily + accessible from all major areas. +

+
+ 📍 5.5600° N, 0.2057° W +
+
+
+
+
+ + + + + + + + diff --git a/data/approach.json b/data/approach.json new file mode 100644 index 0000000..606832e --- /dev/null +++ b/data/approach.json @@ -0,0 +1,18 @@ +[ + { + "number": "01", + "title": "Professional", + "description": "We maintain the highest standards of professionalism in every aspect of our work. From initial consultation to project completion, our team demonstrates expertise, reliability, and unwavering commitment to quality. We adhere to international best practices and local regulations, ensuring your project meets all requirements while exceeding expectations." + }, + { + "number": "02", + "title": "Innovative", + "description": "Innovation drives everything we do at KH3. We embrace cutting-edge technologies, sustainable practices, and creative solutions to deliver exceptional results. Our approach combines traditional construction wisdom with modern methodologies, creating spaces that are both timeless and forward-thinking." + }, + { + "number": "03", + "title": "Caring", + "description": "We care deeply about our clients, our team, and the communities we serve. This commitment to care manifests in our attention to detail, our dedication to client satisfaction, and our responsibility to environmental stewardship. We build relationships that last beyond project completion." + } +] + diff --git a/data/brands.json b/data/brands.json new file mode 100644 index 0000000..29c6d64 --- /dev/null +++ b/data/brands.json @@ -0,0 +1,15 @@ +[ + { + "name": "Symphony", + "blurb": "Symphony specializes in premium audio-visual integration and smart building solutions. We transform spaces with cutting-edge technology that enhances user experience and operational efficiency.", + "logo": "images/brands/symphony-logo.png", + "url": "https://symphony-gh.com" + }, + { + "name": "Knock", + "blurb": "Knock delivers innovative door and access solutions for commercial and residential projects. Our products combine security, aesthetics, and functionality to create seamless entry experiences.", + "logo": "images/brands/knock-logo.png", + "url": "https://knock-gh.com" + } +] + diff --git a/data/projects.json b/data/projects.json new file mode 100644 index 0000000..3ba0e71 --- /dev/null +++ b/data/projects.json @@ -0,0 +1,145 @@ +[ + { + "slug": "accra-corporate-tower", + "title": "Accra Corporate Tower", + "category": "Corporate", + "location": "Accra, Ghana", + "client": "Ghana Investment Promotion Centre", + "typeOfWork": "Turnkey Design & Fit-out", + "sizeM2": 2500, + "year": 2023, + "coverImage": "images/projects/accra-corporate-tower-cover.jpg", + "gallery": [ + "images/projects/accra-corporate-tower-1.jpg", + "images/projects/accra-corporate-tower-2.jpg", + "images/projects/accra-corporate-tower-3.jpg", + "images/projects/accra-corporate-tower-4.jpg", + "images/projects/accra-corporate-tower-5.jpg", + "images/projects/accra-corporate-tower-6.jpg" + ], + "summary": "A state-of-the-art corporate headquarters featuring modern workspace design, sustainable materials, and cutting-edge technology integration.", + "story": { + "challenge": "Create a prestigious corporate environment that reflects Ghana's economic growth while incorporating sustainable design principles.", + "approach": "Implemented modular workspace design with natural lighting, local materials, and flexible meeting spaces.", + "outcome": "Delivered a 2,500 sqm premium office space that increased employee productivity by 40% and achieved LEED certification." + } + }, + { + "slug": "kumasi-university-library", + "title": "Kumasi University Library", + "category": "Education", + "location": "Kumasi, Ghana", + "client": "Kwame Nkrumah University of Science and Technology", + "typeOfWork": "Design & Build", + "sizeM2": 1800, + "year": 2023, + "coverImage": "images/projects/kumasi-library-cover.jpg", + "gallery": [ + "images/projects/kumasi-library-1.jpg", + "images/projects/kumasi-library-2.jpg", + "images/projects/kumasi-library-3.jpg", + "images/projects/kumasi-library-4.jpg" + ], + "summary": "Modern academic library designed to foster learning and research with flexible study spaces and digital integration.", + "story": { + "challenge": "Transform traditional library spaces into modern learning environments that support both individual study and collaborative research.", + "approach": "Designed flexible zones with movable furniture, digital workstations, and natural lighting to create an inspiring academic atmosphere.", + "outcome": "Created a 1,800 sqm learning hub that increased student engagement and became a model for modern academic facilities in West Africa." + } + }, + { + "slug": "tema-harbor-hotel", + "title": "Tema Harbor Hotel", + "category": "Hospitality", + "location": "Tema, Ghana", + "client": "Tema Development Corporation", + "typeOfWork": "Interior Design & Fit-out", + "sizeM2": 3200, + "year": 2022, + "coverImage": "images/projects/tema-hotel-cover.jpg", + "gallery": [ + "images/projects/tema-hotel-1.jpg", + "images/projects/tema-hotel-2.jpg", + "images/projects/tema-hotel-3.jpg", + "images/projects/tema-hotel-4.jpg", + "images/projects/tema-hotel-5.jpg" + ], + "summary": "Luxury hotel interior featuring coastal-inspired design, premium finishes, and world-class amenities for business and leisure travelers.", + "story": { + "challenge": "Create a luxury hotel experience that celebrates Ghana's coastal heritage while meeting international hospitality standards.", + "approach": "Integrated local cultural elements with modern luxury design, using sustainable materials and creating seamless indoor-outdoor connections.", + "outcome": "Delivered a 3,200 sqm luxury hotel that achieved 4-star rating and became a landmark destination in Tema's hospitality sector." + } + }, + { + "slug": "accra-mall-retail", + "title": "Accra Mall Retail Expansion", + "category": "Retail", + "location": "Accra, Ghana", + "client": "Accra Mall Management", + "typeOfWork": "Retail Fit-out & Design", + "sizeM2": 1500, + "year": 2022, + "coverImage": "images/projects/accra-mall-cover.jpg", + "gallery": [ + "images/projects/accra-mall-1.jpg", + "images/projects/accra-mall-2.jpg", + "images/projects/accra-mall-3.jpg", + "images/projects/accra-mall-4.jpg" + ], + "summary": "Modern retail spaces designed to enhance customer experience and maximize sales potential for premium brands.", + "story": { + "challenge": "Transform existing mall spaces into premium retail environments that attract international brands and enhance customer experience.", + "approach": "Implemented modular retail design with flexible layouts, premium lighting, and customer flow optimization.", + "outcome": "Created 1,500 sqm of premium retail space that increased foot traffic by 60% and attracted major international brands." + } + }, + { + "slug": "takoradi-office-complex", + "title": "Takoradi Office Complex", + "category": "Corporate", + "location": "Takoradi, Ghana", + "client": "Ghana National Petroleum Corporation", + "typeOfWork": "Design & Build", + "sizeM2": 2800, + "year": 2021, + "coverImage": "images/projects/takoradi-office-cover.jpg", + "gallery": [ + "images/projects/takoradi-office-1.jpg", + "images/projects/takoradi-office-2.jpg", + "images/projects/takoradi-office-3.jpg", + "images/projects/takoradi-office-4.jpg", + "images/projects/takoradi-office-5.jpg" + ], + "summary": "Modern office complex designed for the energy sector, featuring collaborative workspaces and advanced technology integration.", + "story": { + "challenge": "Design a corporate headquarters that reflects the energy sector's innovation while creating productive work environments.", + "approach": "Created open-plan offices with collaborative zones, advanced AV systems, and sustainable energy features.", + "outcome": "Delivered a 2,800 sqm office complex that improved team collaboration and became a benchmark for corporate design in Ghana's energy sector." + } + }, + { + "slug": "cape-coast-school", + "title": "Cape Coast International School", + "category": "Education", + "location": "Cape Coast, Ghana", + "client": "Cape Coast Education Trust", + "typeOfWork": "Turnkey Design & Build", + "sizeM2": 2200, + "year": 2021, + "coverImage": "images/projects/cape-coast-school-cover.jpg", + "gallery": [ + "images/projects/cape-coast-school-1.jpg", + "images/projects/cape-coast-school-2.jpg", + "images/projects/cape-coast-school-3.jpg", + "images/projects/cape-coast-school-4.jpg" + ], + "summary": "International school campus featuring modern classrooms, science labs, and sports facilities designed for 21st-century learning.", + "story": { + "challenge": "Create an educational environment that meets international standards while incorporating local cultural elements and sustainable design.", + "approach": "Designed flexible learning spaces with integrated technology, outdoor learning areas, and community gathering spaces.", + "outcome": "Built a 2,200 sqm school campus that enhanced learning outcomes and became a model for modern education facilities in Ghana." + } + } +] + diff --git a/data/services.json b/data/services.json new file mode 100644 index 0000000..82da74e --- /dev/null +++ b/data/services.json @@ -0,0 +1,54 @@ +[ + { + "slug": "design", + "title": "Design", + "intro": "Our comprehensive design services transform your vision into detailed, buildable plans that optimize space, functionality, and aesthetics.", + "bullets": [ + "Site assessment and feasibility studies", + "Conceptual design and space planning", + "Detailed architectural drawings and specifications", + "MEP (Mechanical, Electrical, Plumbing) design", + "Interior design and material selection", + "Lighting design and acoustic planning", + "3D visualization and virtual walkthroughs", + "Building Information Modeling (BIM)", + "Value engineering and cost optimization", + "Regulatory compliance and permit documentation" + ] + }, + { + "slug": "build", + "title": "Build", + "intro": "From groundbreaking to completion, our construction management expertise ensures projects are delivered on time, within budget, and to the highest quality standards.", + "bullets": [ + "Project management and coordination", + "Construction planning and scheduling", + "Quality control and assurance", + "Health and safety management", + "Subcontractor management and coordination", + "Material procurement and logistics", + "Progress monitoring and reporting", + "Change order management", + "Commissioning and handover", + "Post-construction support and maintenance" + ] + }, + { + "slug": "furnish", + "title": "Furnish", + "intro": "Complete your space with our comprehensive furnishing services, from custom furniture design to complete fit-out solutions that bring your vision to life.", + "bullets": [ + "Custom furniture design and manufacturing", + "Procurement and supply chain management", + "Installation and fit-out services", + "Workplace consultancy and optimization", + "Furniture layout and space planning", + "Audio-visual and technology integration", + "Signage and branding implementation", + "Soft furnishings and accessories", + "Maintenance and aftercare services", + "Sustainable and ergonomic solutions" + ] + } +] + diff --git a/data/team.json b/data/team.json new file mode 100644 index 0000000..45583c4 --- /dev/null +++ b/data/team.json @@ -0,0 +1,67 @@ +{ + "team": [ + { + "name": "Kwame Asante", + "role": "Managing Director", + "photo": "images/team/kwame-asante.jpg", + "bio": "With over 15 years of experience in construction project management, Kwame leads KH3's strategic vision and oversees all major projects. His expertise spans corporate, hospitality, and educational sectors across West Africa." + }, + { + "name": "Ama Osei", + "role": "Head of Design", + "photo": "images/team/ama-osei.jpg", + "bio": "Ama brings 12 years of architectural and interior design experience to KH3. She specializes in sustainable design solutions and has led award-winning projects in Ghana's corporate and hospitality sectors." + }, + { + "name": "Kofi Mensah", + "role": "Construction Manager", + "photo": "images/team/kofi-mensah.jpg", + "bio": "Kofi manages all construction operations with a focus on quality, safety, and timely delivery. His background in civil engineering and project management ensures excellence in every build." + }, + { + "name": "Efua Addo", + "role": "Project Coordinator", + "photo": "images/team/efua-addo.jpg", + "bio": "Efua coordinates project delivery across all phases, from initial planning to final handover. Her attention to detail and client communication skills ensure seamless project execution." + }, + { + "name": "Yaw Darko", + "role": "Senior Architect", + "photo": "images/team/yaw-darko.jpg", + "bio": "Yaw leads our architectural team with expertise in modern design principles and sustainable building practices. His innovative approach has shaped many of Ghana's landmark projects." + }, + { + "name": "Akosua Boateng", + "role": "Interior Designer", + "photo": "images/team/akosua-boateng.jpg", + "bio": "Akosua creates inspiring interior spaces that balance functionality with aesthetics. Her work spans corporate offices, luxury hotels, and educational facilities across Ghana." + } + ], + "partners": [ + { + "name": "Ghana Investment Promotion Centre", + "logo": "images/partners/gipc-logo.png" + }, + { + "name": "Kwame Nkrumah University of Science and Technology", + "logo": "images/partners/knust-logo.png" + }, + { + "name": "Ghana National Petroleum Corporation", + "logo": "images/partners/gnpc-logo.png" + }, + { + "name": "Tema Development Corporation", + "logo": "images/partners/tdc-logo.png" + }, + { + "name": "Accra Mall Management", + "logo": "images/partners/accra-mall-logo.png" + }, + { + "name": "Cape Coast Education Trust", + "logo": "images/partners/cape-coast-trust-logo.png" + } + ] +} + diff --git a/index.html b/index.html new file mode 100644 index 0000000..cb6f117 --- /dev/null +++ b/index.html @@ -0,0 +1,1249 @@ + + + + + + KH3 - Building Inspiring Spaces + + + + + + + + + + + + +
+
+ +
+
+ KH3 + KH3 +
+
+ + +
+ +
+ + +
+
+

+ KH3 Group Limited +

+
+
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+ + +
+
+ CONSTRUCTION +
+
+ PROJECT MANAGEMENT +
+
+ FIT-OUTS +
+
+
+
+
+ + +
+
+ + Sample interior fit-out by KH3 + + Sample interior fit-out by KH3 +
+
+
+ + + + + + +
+
+ + +
+ + +
+
+
+ KH3 + KH3 +
+
+
+
+
+
+ + + + + + + diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..fe5ad6e --- /dev/null +++ b/js/main.js @@ -0,0 +1,392 @@ +// Main JavaScript for FBS Website +document.addEventListener("DOMContentLoaded", function () { + // Initialize all functionality + initNavigation(); + initScrollAnimations(); + initSmoothScrolling(); + initSlider(); + initCustomCursor(); + initScrollProgress(); + initLoadingScreen(); + initTextReveal(); + initParallax(); +}); + +// Navigation functionality +function initNavigation() { + const menuToggle = document.getElementById("menuToggle"); + const navOverlay = document.getElementById("navOverlay"); + const navClose = document.getElementById("navClose"); + const navLinks = document.querySelectorAll(".nav-link"); + + // Open navigation + menuToggle.addEventListener("click", function () { + navOverlay.classList.add("active"); + document.body.style.overflow = "hidden"; + }); + + // Close navigation + navClose.addEventListener("click", function () { + navOverlay.classList.remove("active"); + document.body.style.overflow = ""; + }); + + // Close navigation when clicking outside + navOverlay.addEventListener("click", function (e) { + if (e.target === navOverlay) { + navOverlay.classList.remove("active"); + document.body.style.overflow = ""; + } + }); + + // Close navigation when clicking on a link + navLinks.forEach((link) => { + link.addEventListener("click", function () { + navOverlay.classList.remove("active"); + document.body.style.overflow = ""; + }); + }); + + // Close navigation with Escape key + document.addEventListener("keydown", function (e) { + if (e.key === "Escape" && navOverlay.classList.contains("active")) { + navOverlay.classList.remove("active"); + document.body.style.overflow = ""; + } + }); +} + +// Scroll-triggered animations +function initScrollAnimations() { + const observerOptions = { + threshold: 0.1, + rootMargin: "0px 0px -50px 0px", + }; + + const observer = new IntersectionObserver(function (entries) { + entries.forEach((entry) => { + if (entry.isIntersecting) { + entry.target.classList.add("animated"); + } + }); + }, observerOptions); + + // Observe all elements with animation classes + const animatedElements = document.querySelectorAll( + ".animate-on-scroll, .animate-on-scroll-left, .animate-on-scroll-right, .animate-on-scroll-scale" + ); + + animatedElements.forEach((el) => { + observer.observe(el); + }); +} + +// Smooth scrolling for anchor links +function initSmoothScrolling() { + const links = document.querySelectorAll('a[href^="#"]'); + + links.forEach((link) => { + link.addEventListener("click", function (e) { + e.preventDefault(); + const targetId = this.getAttribute("href"); + const targetElement = document.querySelector(targetId); + + if (targetElement) { + const offsetTop = targetElement.offsetTop; + window.scrollTo({ + top: offsetTop, + behavior: "smooth", + }); + } + }); + }); +} + +// Global scroll to section function +function scrollToSection(sectionId) { + const section = document.getElementById(sectionId); + if (section) { + section.scrollIntoView({ + behavior: "smooth", + block: "start", + }); + } +} + +// Slider functionality +function initSlider() { + const sliderDots = document.querySelectorAll(".slider-dot"); + let currentSlide = 0; + + sliderDots.forEach((dot, index) => { + dot.addEventListener("click", function () { + // Remove active class from all dots + sliderDots.forEach((d) => d.classList.remove("active")); + + // Add active class to clicked dot + this.classList.add("active"); + + // Update current slide + currentSlide = index; + + // Here you would typically change the background image + // For now, we'll just add a visual effect + const heroImage = document.querySelector(".hero-image"); + heroImage.style.transform = `scale(1.05)`; + + setTimeout(() => { + heroImage.style.transform = "scale(1)"; + }, 300); + }); + }); + + // Auto-slide functionality (optional) + setInterval(() => { + currentSlide = (currentSlide + 1) % sliderDots.length; + sliderDots.forEach((dot, index) => { + dot.classList.toggle("active", index === currentSlide); + }); + }, 5000); +} + +// Custom cursor +function initCustomCursor() { + // Only enable on desktop + if (window.innerWidth <= 768) return; + + const cursor = document.createElement("div"); + cursor.className = "custom-cursor"; + document.body.appendChild(cursor); + + document.addEventListener("mousemove", function (e) { + cursor.style.left = e.clientX + "px"; + cursor.style.top = e.clientY + "px"; + }); + + // Add hover effect for interactive elements + const interactiveElements = document.querySelectorAll( + "a, button, .cta-button, .service-card" + ); + + interactiveElements.forEach((el) => { + el.addEventListener("mouseenter", function () { + cursor.classList.add("hover"); + }); + + el.addEventListener("mouseleave", function () { + cursor.classList.remove("hover"); + }); + }); +} + +// Scroll progress indicator +function initScrollProgress() { + const progressBar = document.createElement("div"); + progressBar.className = "scroll-progress"; + document.body.appendChild(progressBar); + + window.addEventListener("scroll", function () { + const scrollTop = window.pageYOffset; + const docHeight = document.body.scrollHeight - window.innerHeight; + const scrollPercent = (scrollTop / docHeight) * 100; + + progressBar.style.width = scrollPercent + "%"; + }); +} + +// Loading screen +function initLoadingScreen() { + const loading = document.createElement("div"); + loading.className = "loading"; + loading.innerHTML = '
'; + document.body.appendChild(loading); + + // Hide loading screen after page loads + window.addEventListener("load", function () { + setTimeout(() => { + loading.classList.add("hidden"); + setTimeout(() => { + loading.remove(); + }, 500); + }, 1000); + }); +} + +// Text reveal animations +function initTextReveal() { + const textElements = document.querySelectorAll( + ".main-headline, .section-title" + ); + + textElements.forEach((element) => { + const text = element.textContent; + element.innerHTML = ""; + element.classList.add("text-reveal"); + + text.split("").forEach((char) => { + const span = document.createElement("span"); + span.textContent = char === " " ? "\u00A0" : char; + element.appendChild(span); + }); + }); + + // Trigger text reveal on scroll + const textObserver = new IntersectionObserver( + function (entries) { + entries.forEach((entry) => { + if (entry.isIntersecting) { + entry.target.classList.add("revealed"); + } + }); + }, + { threshold: 0.5 } + ); + + document.querySelectorAll(".text-reveal").forEach((el) => { + textObserver.observe(el); + }); +} + +// Parallax effects +function initParallax() { + const parallaxElements = document.querySelectorAll( + ".hero-image, .vertical-line" + ); + + window.addEventListener("scroll", function () { + const scrolled = window.pageYOffset; + + parallaxElements.forEach((element) => { + const speed = element.dataset.speed || 0.5; + const yPos = -(scrolled * speed); + element.style.transform = `translateY(${yPos}px)`; + }); + }); +} + +// Utility functions +function debounce(func, wait) { + let timeout; + return function executedFunction(...args) { + const later = () => { + clearTimeout(timeout); + func(...args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; +} + +// Handle window resize +window.addEventListener( + "resize", + debounce(function () { + // Reinitialize cursor on resize + const cursor = document.querySelector(".custom-cursor"); + if (cursor && window.innerWidth <= 768) { + cursor.remove(); + } else if (!cursor && window.innerWidth > 768) { + initCustomCursor(); + } + }, 250) +); + +// Add ripple effect to buttons +document.addEventListener("click", function (e) { + if ( + e.target.classList.contains("cta-button") || + e.target.closest(".cta-button") + ) { + const button = e.target.classList.contains("cta-button") + ? e.target + : e.target.closest(".cta-button"); + button.classList.add("ripple"); + + setTimeout(() => { + button.classList.remove("ripple"); + }, 600); + } +}); + +// Form handling (for contact forms) +function handleFormSubmit(form) { + const formData = new FormData(form); + const submitButton = form.querySelector('button[type="submit"]'); + const originalText = submitButton.textContent; + + // Show loading state + submitButton.textContent = "Sending..."; + submitButton.disabled = true; + + // Simulate form submission (replace with actual endpoint) + setTimeout(() => { + submitButton.textContent = "Sent!"; + submitButton.style.backgroundColor = "var(--color-primary)"; + + setTimeout(() => { + submitButton.textContent = originalText; + submitButton.disabled = false; + submitButton.style.backgroundColor = ""; + form.reset(); + }, 2000); + }, 1500); +} + +// Initialize form handlers +document.addEventListener("DOMContentLoaded", function () { + const forms = document.querySelectorAll("form"); + forms.forEach((form) => { + form.addEventListener("submit", function (e) { + e.preventDefault(); + handleFormSubmit(this); + }); + }); +}); + +// Add some interactive effects to service cards +document.addEventListener("DOMContentLoaded", function () { + const serviceCards = document.querySelectorAll(".service-card"); + + serviceCards.forEach((card) => { + card.addEventListener("mouseenter", function () { + this.style.transform = "translateY(-10px) scale(1.02)"; + }); + + card.addEventListener("mouseleave", function () { + this.style.transform = "translateY(0) scale(1)"; + }); + }); +}); + +// Keyboard navigation support +document.addEventListener("keydown", function (e) { + // Tab navigation for accessibility + if (e.key === "Tab") { + document.body.classList.add("keyboard-navigation"); + } +}); + +document.addEventListener("mousedown", function () { + document.body.classList.remove("keyboard-navigation"); +}); + +// Performance optimization: Lazy load images +function initLazyLoading() { + const images = document.querySelectorAll("img[data-src]"); + + const imageObserver = new IntersectionObserver(function (entries) { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const img = entry.target; + img.src = img.dataset.src; + img.classList.remove("lazy"); + imageObserver.unobserve(img); + } + }); + }); + + images.forEach((img) => imageObserver.observe(img)); +} + +// Initialize lazy loading +document.addEventListener("DOMContentLoaded", initLazyLoading); diff --git a/js/projects.js b/js/projects.js new file mode 100644 index 0000000..fc9c6db --- /dev/null +++ b/js/projects.js @@ -0,0 +1,130 @@ +// Projects Page JavaScript +document.addEventListener("DOMContentLoaded", function () { + const pills = document.querySelectorAll("[data-filter]"); + const grid = document.querySelector("#projectsGrid"); + let projectsData = []; + + // Load projects data + async function loadProjects() { + try { + const response = await fetch("/data/projects.json"); + projectsData = await response.json(); + renderProjects("All"); + } catch (error) { + console.error("Error loading projects:", error); + grid.innerHTML = + '

Error loading projects. Please try again later.

'; + } + } + + // Render projects based on category + function renderProjects(category = "All") { + const filteredProjects = + category === "All" + ? projectsData + : projectsData.filter((project) => project.category === category); + + grid.classList.add("fade-out"); + + setTimeout(() => { + grid.innerHTML = filteredProjects + .map( + (project) => ` +
+
+
+
+
+
${project.category}
+

${project.title}

+

${project.location}

+ View Project +
+
+ ` + ) + .join(""); + + grid.classList.remove("fade-out"); + grid.classList.add("fade-in"); + + setTimeout(() => { + grid.classList.remove("fade-in"); + }, 180); + }, 120); + } + + // Handle filter pill clicks + pills.forEach((pill) => { + pill.addEventListener("click", (e) => { + e.preventDefault(); + const category = pill.dataset.filter; + + // Update pill states + pills.forEach((p) => { + p.setAttribute("aria-pressed", p === pill ? "true" : "false"); + }); + + // Update URL + const url = new URL(location); + if (category === "All") { + url.searchParams.delete("category"); + } else { + url.searchParams.set("category", category); + } + history.pushState({}, "", url); + + // Render filtered projects + renderProjects(category); + }); + }); + + // Handle browser back/forward + window.addEventListener("popstate", () => { + const category = new URL(location).searchParams.get("category") || "All"; + const activePill = document.querySelector(`[data-filter="${category}"]`); + + if (activePill) { + pills.forEach((p) => { + p.setAttribute("aria-pressed", p === activePill ? "true" : "false"); + }); + renderProjects(category); + } + }); + + // Initialize with URL category if present + const initialCategory = + new URL(location).searchParams.get("category") || "All"; + const initialPill = document.querySelector( + `[data-filter="${initialCategory}"]` + ); + + if (initialPill) { + pills.forEach((p) => { + p.setAttribute("aria-pressed", p === initialPill ? "true" : "false"); + }); + } + + // Load projects on page load + loadProjects(); +}); + +// Keyboard navigation for filter pills +document.addEventListener("keydown", function (e) { + const activePill = document.querySelector('.pill[aria-pressed="true"]'); + const pills = Array.from(document.querySelectorAll(".pill")); + const currentIndex = pills.indexOf(activePill); + + if (e.key === "ArrowRight" || e.key === "ArrowDown") { + e.preventDefault(); + const nextIndex = (currentIndex + 1) % pills.length; + pills[nextIndex].click(); + pills[nextIndex].focus(); + } else if (e.key === "ArrowLeft" || e.key === "ArrowUp") { + e.preventDefault(); + const prevIndex = currentIndex === 0 ? pills.length - 1 : currentIndex - 1; + pills[prevIndex].click(); + pills[prevIndex].focus(); + } +}); + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..040b8bc --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1483 @@ +{ + "name": "kh3-website", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "kh3-website", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "tailwindcss": "^3.4.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.30", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..b37d2e9 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "kh3-website", + "version": "1.0.0", + "description": "KH3 - Building Inspiring Spaces", + "main": "index.html", + "scripts": { + "build": "tailwindcss -i ./src/input.css -o ./styles/main.css", + "watch": "tailwindcss -i ./src/input.css -o ./styles/main.css --watch", + "dev": "tailwindcss -i ./src/input.css -o ./styles/main.css --watch" + }, + "devDependencies": { + "tailwindcss": "^3.4.0" + }, + "keywords": [ + "construction", + "project-management", + "fit-outs", + "ghana" + ], + "author": "KH3", + "license": "MIT" +} diff --git a/project-accra-corporate-tower.html b/project-accra-corporate-tower.html new file mode 100644 index 0000000..5e18f0b --- /dev/null +++ b/project-accra-corporate-tower.html @@ -0,0 +1,320 @@ + + + + + + Accra Corporate Tower - KH3 | Building Inspiring Spaces + + + + + + + + + + + + + +
+ +
+
+
+
+
Corporate
+

Accra Corporate Tower

+

Accra, Ghana

+
+
+ Accra Corporate Tower +
+
+
+
+ + +
+
+
+ + + + +
+
+

Project Overview

+

+ A state-of-the-art corporate headquarters featuring modern + workspace design, sustainable materials, and cutting-edge + technology integration. +

+
+ +
+
+

The Challenge

+

+ Create a prestigious corporate environment that reflects + Ghana's economic growth while incorporating sustainable + design principles. +

+
+
+

Our Approach

+

+ Implemented modular workspace design with natural lighting, + local materials, and flexible meeting spaces. +

+
+
+

The Outcome

+

+ Delivered a 2,500 sqm premium office space that increased + employee productivity by 40% and achieved LEED + certification. +

+
+
+ + + +
+
+
+
+ + + +
+ + + + + + + + diff --git a/projects.html b/projects.html new file mode 100644 index 0000000..6ad1426 --- /dev/null +++ b/projects.html @@ -0,0 +1,194 @@ + + + + + + Projects - KH3 | Building Inspiring Spaces + + + + + + + + + + + + + +
+ +
+
+
+

Our Projects

+

+ Discover our portfolio of construction and project management + excellence across Ghana +

+
+
+
+ + +
+
+
+
+ + + + + +
+
+
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+

Ready to Start Your Project?

+

Let's discuss how KH3 can bring your vision to life

+ Get in Touch +
+
+
+
+ + + + + + + + + diff --git a/src/input.css b/src/input.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/src/input.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..2f67c61 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,106 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: ["./*.html", "./js/*.js"], + darkMode: "class", + theme: { + extend: { + colors: { + kh3: { + black: "#212629", + red: "#B03037", + gold: "#b8860b", + darkGold: "#8b6914", + lightGold: "#daa520", + }, + black: "#000000", + white: "#ffffff", + }, + fontFamily: { + montserrat: ["Montserrat", "sans-serif"], + calibri: ["Calibri", "sans-serif"], + }, + animation: { + "logo-float": "logoFloat 3s ease-in-out infinite", + "text-float": "textFloat 4s ease-in-out infinite", + "border-glow": "borderGlow 3s ease-in-out infinite", + "menu-grid-cycle": "menuGridCycle 15s ease-in-out infinite", + "fade-in-up": "fadeInUp 1s ease-out forwards", + "fade-in-left": "fadeInLeft 1s ease-out forwards", + "fade-in-right": "fadeInRight 1s ease-out forwards", + "fade-in-center": "fadeInCenter 1s ease-out forwards", + "logo-glow": "logoGlow 3s ease-in-out infinite", + }, + keyframes: { + logoFloat: { + "0%, 100%": { transform: "translateY(0px)" }, + "50%": { transform: "translateY(-10px)" }, + }, + textFloat: { + "0%, 100%": { transform: "translateY(0px)" }, + "50%": { transform: "translateY(-5px)" }, + }, + borderGlow: { + "0%, 100%": { + borderColor: "#ffffff", + boxShadow: "0 0 5px rgba(255, 255, 255, 0.3)", + }, + "50%": { + borderColor: "#B03037", + boxShadow: "0 0 15px rgba(176, 48, 55, 0.6)", + }, + }, + menuGridCycle: { + "0%, 33.33%": { + transform: "rotate(0deg) scale(1)", + color: "#ffffff", + }, + "6.67%, 26.67%": { + transform: "rotate(360deg) scale(1.2)", + color: "#B03037", + }, + "33.34%, 66.67%": { + transform: "rotate(0deg) scale(1)", + color: "#ffffff", + }, + "40%, 60%": { + transform: "rotate(360deg) scale(1.2)", + color: "#B03037", + }, + "66.68%, 100%": { + transform: "rotate(0deg) scale(1)", + color: "#ffffff", + }, + }, + fadeInUp: { + "0%": { opacity: "0", transform: "translateY(30px)" }, + "100%": { opacity: "1", transform: "translateY(0)" }, + }, + fadeInLeft: { + "0%": { opacity: "0", transform: "translateX(-30px)" }, + "100%": { opacity: "1", transform: "translateX(0)" }, + }, + fadeInRight: { + "0%": { opacity: "0", transform: "translateX(30px)" }, + "100%": { opacity: "1", transform: "translateX(0)" }, + }, + fadeInCenter: { + "0%": { opacity: "0", transform: "scale(0.9)" }, + "100%": { opacity: "1", transform: "scale(1)" }, + }, + logoGlow: { + "0%, 100%": { + textShadow: + "0 0 1px rgba(255, 255, 255, 0.1), 0 0 1px rgba(176, 48, 55, 0.05)", + filter: "brightness(1)", + }, + "50%": { + textShadow: + "0 0 2px rgba(255, 255, 255, 0.15), 0 0 3px rgba(176, 48, 55, 0.08)", + filter: "brightness(1.02)", + }, + }, + }, + }, + }, + plugins: [], +};