Add initial README.md for Astro Starter Kit: Minimal
This commit is contained in:
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# build output
|
||||||
|
dist/
|
||||||
|
# generated types
|
||||||
|
.astro/
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# logs
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
|
||||||
|
# environment variables
|
||||||
|
.env
|
||||||
|
.env.production
|
||||||
|
|
||||||
|
# macOS-specific files
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# jetbrains setting folder
|
||||||
|
.idea/
|
4
.vscode/extensions.json
vendored
Normal file
4
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["astro-build.astro-vscode"],
|
||||||
|
"unwantedRecommendations": []
|
||||||
|
}
|
11
.vscode/launch.json
vendored
Normal file
11
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"command": "./node_modules/.bin/astro dev",
|
||||||
|
"name": "Development server",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "node-terminal"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
47
README.md
47
README.md
@@ -0,0 +1,47 @@
|
|||||||
|
# Astro Starter Kit: Minimal
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm create astro@latest -- --template minimal
|
||||||
|
```
|
||||||
|
|
||||||
|
[](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal)
|
||||||
|
[](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/minimal)
|
||||||
|
[](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/minimal/devcontainer.json)
|
||||||
|
|
||||||
|
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
||||||
|
|
||||||
|
## 🚀 Project Structure
|
||||||
|
|
||||||
|
Inside of your Astro project, you'll see the following folders and files:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/
|
||||||
|
├── public/
|
||||||
|
├── src/
|
||||||
|
│ └── pages/
|
||||||
|
│ └── index.astro
|
||||||
|
└── package.json
|
||||||
|
```
|
||||||
|
|
||||||
|
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
||||||
|
|
||||||
|
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
||||||
|
|
||||||
|
Any static assets, like images, can be placed in the `public/` directory.
|
||||||
|
|
||||||
|
## 🧞 Commands
|
||||||
|
|
||||||
|
All commands are run from the root of the project, from a terminal:
|
||||||
|
|
||||||
|
| Command | Action |
|
||||||
|
| :------------------------ | :----------------------------------------------- |
|
||||||
|
| `npm install` | Installs dependencies |
|
||||||
|
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
||||||
|
| `npm run build` | Build your production site to `./dist/` |
|
||||||
|
| `npm run preview` | Preview your build locally, before deploying |
|
||||||
|
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
||||||
|
| `npm run astro -- --help` | Get help using the Astro CLI |
|
||||||
|
|
||||||
|
## 👀 Want to learn more?
|
||||||
|
|
||||||
|
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
||||||
|
15
astro.config.mjs
Normal file
15
astro.config.mjs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// @ts-check
|
||||||
|
import { defineConfig } from 'astro/config';
|
||||||
|
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
|
||||||
|
import react from '@astrojs/react';
|
||||||
|
|
||||||
|
// https://astro.build/config
|
||||||
|
export default defineConfig({
|
||||||
|
vite: {
|
||||||
|
plugins: [tailwindcss()]
|
||||||
|
},
|
||||||
|
|
||||||
|
integrations: [react()]
|
||||||
|
});
|
8
content/events/2023-03-15-cultural-night.md
Normal file
8
content/events/2023-03-15-cultural-night.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "Omoluabi Cultural Night"
|
||||||
|
date: "2023-03-15"
|
||||||
|
category: "Cultural"
|
||||||
|
image: "/images/events/cultural-night.jpg"
|
||||||
|
description: "A night to celebrate Yoruba culture, music, and food."
|
||||||
|
---
|
||||||
|
Experience the richness of Yoruba culture with music, dance, and traditional cuisine.
|
8
content/events/2023-04-01-women-ambassador.md
Normal file
8
content/events/2023-04-01-women-ambassador.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "OMOLUABI WOMEN WING COURTESY VISIT TO THE NEW AMBASSADOR (DR ENIOLA AJAYI)"
|
||||||
|
date: "2023-04-01"
|
||||||
|
category: "Programme"
|
||||||
|
image: "/images/events/women-ambassador.jpg"
|
||||||
|
description: "4 man delegate of Omoluabi ladies to welcome the new ambassador to the Netherlands."
|
||||||
|
---
|
||||||
|
A beautiful courtesy visit by the Omoluabi women to the new ambassador.
|
8
content/events/2023-04-25-covid-relief.md
Normal file
8
content/events/2023-04-25-covid-relief.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "Omoluabi Association Netherland Covid-19 Relief Programme"
|
||||||
|
date: "2023-04-25"
|
||||||
|
category: "Programme"
|
||||||
|
image: "/images/events/covid-relief.jpg"
|
||||||
|
description: "Covid-19 Relief Programme for the Nigerian community in the Netherlands."
|
||||||
|
---
|
||||||
|
Supporting our community during challenging times with relief efforts and solidarity.
|
8
content/events/2023-08-26-omoluabi-day.md
Normal file
8
content/events/2023-08-26-omoluabi-day.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: "Omoluabi Association Netherland Day & Launching"
|
||||||
|
date: "2023-08-26"
|
||||||
|
category: "Programme"
|
||||||
|
image: "/images/events/omoluabi-day.jpg"
|
||||||
|
description: "Omoluabi Association Netherlands Day and Launching 2023 Date: Saturday 26th August, 2023 Time: 5pm - 1:00am Location: Egoli 1, 1103 AC Amsterdam."
|
||||||
|
---
|
||||||
|
The Omoluabi Association Netherlands Day and Launching is a celebration of Yoruba culture and community in the Netherlands. Join us for a day of festivities, music, and cultural exchange!
|
9
content/gallery/gallery-sample.md
Normal file
9
content/gallery/gallery-sample.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: "Homepage Gallery"
|
||||||
|
images:
|
||||||
|
- "/images/gallery/photo1.jpg"
|
||||||
|
- "/images/gallery/photo2.jpg"
|
||||||
|
- "/images/gallery/photo3.jpg"
|
||||||
|
- "/images/gallery/photo4.jpg"
|
||||||
|
---
|
||||||
|
A sample gallery for the homepage. Add or remove images as needed.
|
23
content/members/members-sample.md
Normal file
23
content/members/members-sample.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
intro: |
|
||||||
|
Membership Benefits/Welfare Packages
|
||||||
|
1. A member recipients of any benefits must have been a financial member for a minimum period of 6(six) months and must be financially up to date.
|
||||||
|
2. The next of kin of a deceased member are entitled to the sum of 250.00 Euro.
|
||||||
|
3. Bereavement of an immediate family member ( e.g. Father, Mother, Wife, Son or Daughter) attracts the sum of 200.00 Euro.
|
||||||
|
4. Any financial member who is sent or deported home is entitled to the sum of 200.00 Euro.
|
||||||
|
5. Happy Ceremonies or Occasions (excluding Birthdays) of members on official invitation of the association attracts the sum of 200.00 Euro
|
||||||
|
members:
|
||||||
|
- name: "Chief (Mrs) Example A"
|
||||||
|
role: "President"
|
||||||
|
image: "/images/members/member1.jpg"
|
||||||
|
- name: "Chief Example B"
|
||||||
|
role: "Vice President"
|
||||||
|
image: "/images/members/member2.jpg"
|
||||||
|
- name: "Chief Example C"
|
||||||
|
role: "Secretary"
|
||||||
|
image: "/images/members/member3.jpg"
|
||||||
|
- name: "Chief Example D"
|
||||||
|
role: "Treasurer"
|
||||||
|
image: "/images/members/member4.jpg"
|
||||||
|
---
|
||||||
|
Sample members and benefits for the Omoluabi Association.
|
6101
package-lock.json
generated
Normal file
6101
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
package.json
Normal file
23
package.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "omoluabi",
|
||||||
|
"type": "module",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "astro dev",
|
||||||
|
"build": "astro build",
|
||||||
|
"preview": "astro preview",
|
||||||
|
"astro": "astro"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@astrojs/react": "^4.3.0",
|
||||||
|
"@tailwindcss/vite": "^4.1.10",
|
||||||
|
"@types/react": "^19.1.8",
|
||||||
|
"@types/react-dom": "^19.1.6",
|
||||||
|
"astro": "^5.9.4",
|
||||||
|
"daisyui": "^5.0.43",
|
||||||
|
"keen-slider": "^6.8.6",
|
||||||
|
"react": "^19.1.0",
|
||||||
|
"react-dom": "^19.1.0",
|
||||||
|
"tailwindcss": "^4.1.10"
|
||||||
|
}
|
||||||
|
}
|
9
public/favicon.svg
Normal file
9
public/favicon.svg
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
||||||
|
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
||||||
|
<style>
|
||||||
|
path { fill: #000; }
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
path { fill: #FFF; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 749 B |
0
public/images/gallery/photo1.jpg
Normal file
0
public/images/gallery/photo1.jpg
Normal file
0
public/images/gallery/photo2.jpg
Normal file
0
public/images/gallery/photo2.jpg
Normal file
0
public/images/gallery/photo3.jpg
Normal file
0
public/images/gallery/photo3.jpg
Normal file
0
public/images/gallery/photo4.jpg
Normal file
0
public/images/gallery/photo4.jpg
Normal file
0
public/images/hero1.jpg
Normal file
0
public/images/hero1.jpg
Normal file
0
public/images/hero2.jpg
Normal file
0
public/images/hero2.jpg
Normal file
0
public/images/hero3.jpg
Normal file
0
public/images/hero3.jpg
Normal file
0
public/images/members/member1.jpg
Normal file
0
public/images/members/member1.jpg
Normal file
0
public/images/members/member2.jpg
Normal file
0
public/images/members/member2.jpg
Normal file
0
public/images/members/member3.jpg
Normal file
0
public/images/members/member3.jpg
Normal file
0
public/images/members/member4.jpg
Normal file
0
public/images/members/member4.jpg
Normal file
BIN
public/images/whoAreWe.webp
Normal file
BIN
public/images/whoAreWe.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 236 KiB |
46
src/components/ContactForm.jsx
Normal file
46
src/components/ContactForm.jsx
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export default function ContactForm() {
|
||||||
|
const [status, setStatus] = useState("");
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const form = e.target;
|
||||||
|
// Honeypot check
|
||||||
|
if (form.honey.value !== "") {
|
||||||
|
setStatus("Spam detected.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setStatus("Sending...");
|
||||||
|
// Placeholder: would POST to /api/contact
|
||||||
|
setTimeout(() => setStatus("Message sent (placeholder, not yet implemented)."), 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form className="max-w-xl mx-auto bg-base-100 p-8 rounded-xl shadow-lg" onSubmit={handleSubmit} autoComplete="off">
|
||||||
|
<div className="mb-4">
|
||||||
|
<label htmlFor="name" className="block font-bold mb-1">Name</label>
|
||||||
|
<input type="text" id="name" name="name" className="input input-bordered w-full" required autoComplete="off" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label htmlFor="email" className="block font-bold mb-1">Email</label>
|
||||||
|
<input type="email" id="email" name="email" className="input input-bordered w-full" required autoComplete="off" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label htmlFor="subject" className="block font-bold mb-1">Subject</label>
|
||||||
|
<input type="text" id="subject" name="subject" className="input input-bordered w-full" required autoComplete="off" />
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<label htmlFor="message" className="block font-bold mb-1">Message</label>
|
||||||
|
<textarea id="message" name="message" className="textarea textarea-bordered w-full" rows={5} required></textarea>
|
||||||
|
</div>
|
||||||
|
{/* Honeypot field for spam protection */}
|
||||||
|
<div style={{ display: "none" }}>
|
||||||
|
<label htmlFor="honey">Do not fill this out</label>
|
||||||
|
<input type="text" id="honey" name="honey" tabIndex="-1" autoComplete="off" />
|
||||||
|
</div>
|
||||||
|
<button type="submit" className="btn btn-primary w-full">Send Message</button>
|
||||||
|
{status && <div className="mt-4 text-center text-sm text-success">{status}</div>}
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
206
src/components/Footer.astro
Normal file
206
src/components/Footer.astro
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
---
|
||||||
|
// Footer.astro - Modern Nigerian-themed footer
|
||||||
|
---
|
||||||
|
|
||||||
|
<footer class="bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900 text-white relative overflow-hidden">
|
||||||
|
<!-- Background Pattern -->
|
||||||
|
<div class="absolute inset-0 opacity-5">
|
||||||
|
<div class="absolute inset-0" style="background-image: url('data:image/svg+xml,%3Csvg width=\"60\" height=\"60\" viewBox=\"0 0 60 60\" xmlns=\"http://www.w3.org/2000/svg\"%3E%3Cg fill=\"none\" fill-rule=\"evenodd\"%3E%3Cg fill=\"%23ffffff\" fill-opacity=\"0.1\"%3E%3Cpath d=\"M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z\"/%3E%3C/g%3E%3C/g%3E%3C/svg%3E');"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Decorative Top Border -->
|
||||||
|
<div class="h-2 bg-gradient-to-r from-nigerian-green-500 via-kente-gold-500 to-ankara-red-500"></div>
|
||||||
|
|
||||||
|
<div class="container mx-auto px-4 py-16 relative z-10">
|
||||||
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-12">
|
||||||
|
|
||||||
|
<!-- Brand Section -->
|
||||||
|
<div class="lg:col-span-2">
|
||||||
|
<div class="flex items-center gap-4 mb-6">
|
||||||
|
<!-- Logo -->
|
||||||
|
<div class="relative">
|
||||||
|
<div class="w-16 h-16 rounded-full bg-gradient-to-r from-nigerian-green-500 via-white to-nigerian-green-500 p-0.5 shadow-xl">
|
||||||
|
<div class="w-full h-full rounded-full bg-gray-800 flex items-center justify-center">
|
||||||
|
<div class="w-12 h-12 rounded-full bg-gradient-to-br from-nigerian-green-500 to-kente-gold-500 flex items-center justify-center">
|
||||||
|
<span class="text-white font-bold text-xl">O</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="absolute -top-1 -right-1 w-5 h-5 bg-kente-gold-400 rounded-full animate-pulse"></div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 class="font-headline text-3xl font-bold bg-gradient-to-r from-nigerian-green-400 to-kente-gold-400 bg-clip-text text-transparent">
|
||||||
|
Omoluabi Foundation
|
||||||
|
</h3>
|
||||||
|
<p class="text-gray-400 text-sm">Building Bridges, Celebrating Heritage</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-gray-300 leading-relaxed mb-6 max-w-md">
|
||||||
|
Connecting Nigerian hearts in the Netherlands through culture, community, and compassion.
|
||||||
|
Together, we preserve our heritage while embracing our future.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<!-- Nigerian Flag Colors Accent -->
|
||||||
|
<div class="flex items-center gap-4 mb-6">
|
||||||
|
<div class="flex gap-1">
|
||||||
|
<div class="w-4 h-6 bg-nigerian-green-500 rounded-sm"></div>
|
||||||
|
<div class="w-4 h-6 bg-white rounded-sm"></div>
|
||||||
|
<div class="w-4 h-6 bg-nigerian-green-500 rounded-sm"></div>
|
||||||
|
</div>
|
||||||
|
<span class="text-sm text-gray-400">Proudly Nigerian 🇳🇬 in the Netherlands 🇳🇱</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Social Media Links -->
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<a href="#" class="group bg-gray-800 hover:bg-nigerian-green-500 p-3 rounded-full transition-all duration-300 transform hover:scale-110 hover:rotate-6">
|
||||||
|
<svg class="w-5 h-5 group-hover:text-white transition-colors" fill="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="group bg-gray-800 hover:bg-kente-gold-500 p-3 rounded-full transition-all duration-300 transform hover:scale-110 hover:rotate-6">
|
||||||
|
<svg class="w-5 h-5 group-hover:text-white transition-colors" fill="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path d="M22.46 6c-.77.35-1.6.58-2.46.69.88-.53 1.56-1.37 1.88-2.38-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29 0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15 0 1.49.75 2.81 1.91 3.56-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07 4.28 4.28 0 0 0 4 2.98 8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21 16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56.84-.6 1.56-1.36 2.14-2.23z"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="group bg-gray-800 hover:bg-ankara-red-500 p-3 rounded-full transition-all duration-300 transform hover:scale-110 hover:rotate-6">
|
||||||
|
<svg class="w-5 h-5 group-hover:text-white transition-colors" fill="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path d="M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.174-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.097.118.112.221.083.343-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.402.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.357-.629-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24.009 12.017 24.009c6.624 0 11.99-5.367 11.99-11.988C24.007 5.367 18.641.001.012.001z"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<a href="#" class="group bg-gray-800 hover:bg-adire-blue-500 p-3 rounded-full transition-all duration-300 transform hover:scale-110 hover:rotate-6">
|
||||||
|
<svg class="w-5 h-5 group-hover:text-white transition-colors" fill="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Quick Links -->
|
||||||
|
<div>
|
||||||
|
<h4 class="font-headline text-xl font-bold mb-6 text-white flex items-center gap-2">
|
||||||
|
<span class="w-1 h-6 bg-gradient-to-b from-nigerian-green-400 to-kente-gold-400 rounded-full"></span>
|
||||||
|
Quick Links
|
||||||
|
</h4>
|
||||||
|
<nav class="space-y-3">
|
||||||
|
<a href="/" class="block text-gray-300 hover:text-nigerian-green-400 transition-colors duration-200 hover:translate-x-1 transform">
|
||||||
|
Home
|
||||||
|
</a>
|
||||||
|
<a href="/events" class="block text-gray-300 hover:text-nigerian-green-400 transition-colors duration-200 hover:translate-x-1 transform">
|
||||||
|
Events
|
||||||
|
</a>
|
||||||
|
<a href="/members" class="block text-gray-300 hover:text-nigerian-green-400 transition-colors duration-200 hover:translate-x-1 transform">
|
||||||
|
Members
|
||||||
|
</a>
|
||||||
|
<a href="/orphanage" class="block text-gray-300 hover:text-nigerian-green-400 transition-colors duration-200 hover:translate-x-1 transform">
|
||||||
|
Orphanage
|
||||||
|
</a>
|
||||||
|
<a href="/contact" class="block text-gray-300 hover:text-nigerian-green-400 transition-colors duration-200 hover:translate-x-1 transform">
|
||||||
|
Contact
|
||||||
|
</a>
|
||||||
|
<a href="/join" class="block text-kente-gold-400 hover:text-kente-gold-300 transition-colors duration-200 hover:translate-x-1 transform font-semibold">
|
||||||
|
Join Us →
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Contact Info -->
|
||||||
|
<div>
|
||||||
|
<h4 class="font-headline text-xl font-bold mb-6 text-white flex items-center gap-2">
|
||||||
|
<span class="w-1 h-6 bg-gradient-to-b from-ankara-red-400 to-nigerian-green-400 rounded-full"></span>
|
||||||
|
Get in Touch
|
||||||
|
</h4>
|
||||||
|
<div class="space-y-4">
|
||||||
|
<div class="flex items-start gap-3">
|
||||||
|
<div class="bg-nigerian-green-500/20 p-2 rounded-lg mt-1">
|
||||||
|
<svg class="w-4 h-4 text-nigerian-green-400" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-gray-300 text-sm leading-relaxed">
|
||||||
|
Amsterdam, Netherlands<br/>
|
||||||
|
Various locations across NL
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-start gap-3">
|
||||||
|
<div class="bg-kente-gold-500/20 p-2 rounded-lg mt-1">
|
||||||
|
<svg class="w-4 h-4 text-kente-gold-400" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-gray-300 text-sm">
|
||||||
|
+31 (0) 123 456 789
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex items-start gap-3">
|
||||||
|
<div class="bg-ankara-red-500/20 p-2 rounded-lg mt-1">
|
||||||
|
<svg class="w-4 h-4 text-ankara-red-400" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"></path>
|
||||||
|
<path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"></path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p class="text-gray-300 text-sm">
|
||||||
|
info@omoluabi.nl
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Newsletter Signup -->
|
||||||
|
<div class="mt-8 p-4 bg-gray-800/50 rounded-xl border border-gray-700">
|
||||||
|
<h5 class="font-semibold mb-3 text-white">Stay Updated</h5>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="Your email"
|
||||||
|
class="flex-1 px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-sm text-white placeholder-gray-400 focus:border-nigerian-green-400 focus:outline-none"
|
||||||
|
/>
|
||||||
|
<button class="bg-nigerian-green-500 hover:bg-nigerian-green-600 px-4 py-2 rounded-lg transition-colors duration-200">
|
||||||
|
<svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Bottom Section -->
|
||||||
|
<div class="border-t border-gray-700 mt-12 pt-8">
|
||||||
|
<div class="flex flex-col md:flex-row justify-between items-center gap-4">
|
||||||
|
<!-- Copyright -->
|
||||||
|
<div class="text-gray-400 text-sm">
|
||||||
|
<span>© {new Date().getFullYear()} Omoluabi Foundation Netherlands. </span>
|
||||||
|
<span class="text-nigerian-green-400">Made with ❤️ </span>
|
||||||
|
<span>for the Nigerian community.</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Additional Links -->
|
||||||
|
<div class="flex gap-6 text-sm">
|
||||||
|
<a href="/privacy" class="text-gray-400 hover:text-white transition-colors">Privacy Policy</a>
|
||||||
|
<a href="/terms" class="text-gray-400 hover:text-white transition-colors">Terms of Service</a>
|
||||||
|
<a href="/sitemap" class="text-gray-400 hover:text-white transition-colors">Sitemap</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Cultural Quote -->
|
||||||
|
<div class="mt-6 text-center">
|
||||||
|
<p class="text-gray-500 italic text-sm">
|
||||||
|
"Omoluabi ni wa" - We are people of good character
|
||||||
|
</p>
|
||||||
|
<div class="flex justify-center mt-2 gap-1">
|
||||||
|
<span class="text-nigerian-green-400">🌟</span>
|
||||||
|
<span class="text-kente-gold-400">🌟</span>
|
||||||
|
<span class="text-ankara-red-400">🌟</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
189
src/components/Header.astro
Normal file
189
src/components/Header.astro
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
---
|
||||||
|
// Header.astro - Updated with better navigation and active states
|
||||||
|
---
|
||||||
|
|
||||||
|
<header class="fixed top-0 left-0 right-0 z-50 bg-white/95 backdrop-blur-lg border-b border-gray-200/50 shadow-lg">
|
||||||
|
<div class="max-w-7xl mx-auto px-4">
|
||||||
|
<!-- Top bar with cultural elements -->
|
||||||
|
<div class="hidden md:flex items-center justify-between py-2 text-sm border-b border-gray-100">
|
||||||
|
<div class="flex items-center gap-4 text-gray-600">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<svg class="w-4 h-4 text-green-600" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fill-rule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
<span>Netherlands</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<svg class="w-4 h-4 text-amber-600" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"></path>
|
||||||
|
</svg>
|
||||||
|
<span>+31 (0) 123 456 789</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<span class="text-gray-500">🇳🇬</span>
|
||||||
|
<span class="font-semibold text-green-700">Celebrating Nigerian Heritage</span>
|
||||||
|
<span class="text-gray-500">🇳🇱</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Main navigation -->
|
||||||
|
<nav class="flex items-center justify-between py-4">
|
||||||
|
<!-- Logo -->
|
||||||
|
<a href="/" class="flex items-center gap-3 group">
|
||||||
|
<div class="relative">
|
||||||
|
<!-- Nigerian flag inspired logo -->
|
||||||
|
<div class="w-12 h-12 rounded-full bg-gradient-to-r from-green-500 via-white to-green-500 p-0.5 shadow-lg group-hover:shadow-xl transition-all duration-300">
|
||||||
|
<div class="w-full h-full rounded-full bg-white flex items-center justify-center">
|
||||||
|
<div class="w-8 h-8 rounded-full bg-gradient-to-br from-green-500 to-amber-500 flex items-center justify-center">
|
||||||
|
<span class="text-white font-bold text-sm">O</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Floating accent -->
|
||||||
|
<div class="absolute -top-1 -right-1 w-4 h-4 bg-amber-400 rounded-full animate-bounce"></div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<span class="font-bold text-2xl bg-gradient-to-r from-green-600 to-amber-600 bg-clip-text text-transparent">
|
||||||
|
Omoluabi
|
||||||
|
</span>
|
||||||
|
<span class="text-sm text-gray-600 font-medium -mt-1">Foundation</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Desktop Navigation -->
|
||||||
|
<div class="hidden lg:flex items-center gap-1">
|
||||||
|
<a href="/" class="nav-link px-4 py-2 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200 relative group">
|
||||||
|
Home
|
||||||
|
<span class="absolute bottom-0 left-0 w-0 h-0.5 bg-green-600 group-hover:w-full transition-all duration-300"></span>
|
||||||
|
</a>
|
||||||
|
<a href="/about" class="nav-link px-4 py-2 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200 relative group">
|
||||||
|
About
|
||||||
|
<span class="absolute bottom-0 left-0 w-0 h-0.5 bg-green-600 group-hover:w-full transition-all duration-300"></span>
|
||||||
|
</a>
|
||||||
|
<a href="/events" class="nav-link px-4 py-2 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200 relative group">
|
||||||
|
Events
|
||||||
|
<span class="absolute bottom-0 left-0 w-0 h-0.5 bg-green-600 group-hover:w-full transition-all duration-300"></span>
|
||||||
|
</a>
|
||||||
|
<a href="/members" class="nav-link px-4 py-2 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200 relative group">
|
||||||
|
Members
|
||||||
|
<span class="absolute bottom-0 left-0 w-0 h-0.5 bg-green-600 group-hover:w-full transition-all duration-300"></span>
|
||||||
|
</a>
|
||||||
|
<a href="/orphanage" class="nav-link px-4 py-2 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200 relative group">
|
||||||
|
Orphanage
|
||||||
|
<span class="absolute bottom-0 left-0 w-0 h-0.5 bg-green-600 group-hover:w-full transition-all duration-300"></span>
|
||||||
|
</a>
|
||||||
|
<a href="/contact" class="nav-link px-4 py-2 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200 relative group">
|
||||||
|
Contact
|
||||||
|
<span class="absolute bottom-0 left-0 w-0 h-0.5 bg-green-600 group-hover:w-full transition-all duration-300"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- CTA Buttons -->
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<a href="/donate" class="inline-flex items-center px-6 py-2 bg-gradient-to-r from-red-500 to-red-600 text-white rounded-lg shadow-lg hover:shadow-xl hover:from-red-600 hover:to-red-700 transition-all duration-200 font-medium">
|
||||||
|
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fill-rule="evenodd" d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z" clip-rule="evenodd"></path>
|
||||||
|
</svg>
|
||||||
|
Donate
|
||||||
|
</a>
|
||||||
|
<a href="/join" class="inline-flex items-center px-6 py-2 bg-gradient-to-r from-amber-500 to-amber-600 text-white rounded-lg shadow-lg hover:shadow-xl hover:from-amber-600 hover:to-amber-700 transition-all duration-200 font-medium">
|
||||||
|
<svg class="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path d="M8 9a3 3 0 100-6 3 3 0 000 6zM8 11a6 6 0 016 6H2a6 6 0 016-6zM16 7a1 1 0 10-2 0v1h-1a1 1 0 100 2h1v1a1 1 0 102 0v-1h1a1 1 0 100-2h-1V7z"></path>
|
||||||
|
</svg>
|
||||||
|
Join Us
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<!-- Mobile menu button -->
|
||||||
|
<button class="lg:hidden p-2 rounded-lg hover:bg-gray-100 transition-colors duration-200" onclick="toggleMobileMenu()">
|
||||||
|
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Mobile Navigation -->
|
||||||
|
<div id="mobile-menu" class="lg:hidden hidden bg-white border-t border-gray-200 shadow-lg">
|
||||||
|
<div class="max-w-7xl mx-auto px-4 py-4 space-y-2">
|
||||||
|
<a href="/" class="block px-4 py-3 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200">
|
||||||
|
🏠 Home
|
||||||
|
</a>
|
||||||
|
<a href="/about" class="block px-4 py-3 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200">
|
||||||
|
ℹ️ About
|
||||||
|
</a>
|
||||||
|
<a href="/events" class="block px-4 py-3 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200">
|
||||||
|
📅 Events
|
||||||
|
</a>
|
||||||
|
<a href="/members" class="block px-4 py-3 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200">
|
||||||
|
👥 Members
|
||||||
|
</a>
|
||||||
|
<a href="/orphanage" class="block px-4 py-3 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200">
|
||||||
|
🏠 Orphanage
|
||||||
|
</a>
|
||||||
|
<a href="/contact" class="block px-4 py-3 rounded-lg font-medium text-gray-700 hover:text-green-600 hover:bg-green-50 transition-all duration-200">
|
||||||
|
📞 Contact
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function toggleMobileMenu() {
|
||||||
|
const menu = document.getElementById('mobile-menu');
|
||||||
|
menu.classList.toggle('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add active state to current page
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
|
const navLinks = document.querySelectorAll('.nav-link');
|
||||||
|
|
||||||
|
navLinks.forEach(link => {
|
||||||
|
const href = link.getAttribute('href');
|
||||||
|
if (href === currentPath || (currentPath !== '/' && href !== '/' && currentPath.startsWith(href))) {
|
||||||
|
link.classList.add('text-green-600', 'bg-green-50');
|
||||||
|
const underline = link.querySelector('span');
|
||||||
|
if (underline) {
|
||||||
|
underline.classList.add('w-full');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Add some breathing room for fixed header */
|
||||||
|
body {
|
||||||
|
padding-top: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
body {
|
||||||
|
padding-top: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure smooth transitions */
|
||||||
|
.nav-link {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom bounce animation */
|
||||||
|
@keyframes bounce {
|
||||||
|
0%, 20%, 53%, 80%, 100% {
|
||||||
|
transform: translate3d(0,0,0);
|
||||||
|
}
|
||||||
|
40%, 43% {
|
||||||
|
transform: translate3d(0,-8px,0);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: translate3d(0,-4px,0);
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
transform: translate3d(0,-2px,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
220
src/components/HeroCarousel.jsx
Normal file
220
src/components/HeroCarousel.jsx
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
const slides = [
|
||||||
|
{
|
||||||
|
image: "/images/hero1.jpg",
|
||||||
|
alt: "Nigerian community gathering",
|
||||||
|
title: "Celebrating Nigerian Culture",
|
||||||
|
subtitle: "in the Heart of Netherlands",
|
||||||
|
description: "Join our vibrant community events that showcase the rich traditions, music, and cuisine of Nigeria while building lasting friendships.",
|
||||||
|
cta: "Join Our Events",
|
||||||
|
theme: "green"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: "/images/hero2.jpg",
|
||||||
|
alt: "Children at orphanage",
|
||||||
|
title: "Supporting Our Future",
|
||||||
|
subtitle: "Orphanage Outreach Program",
|
||||||
|
description: "Making a real difference in the lives of children through education, healthcare, and providing hope for a brighter tomorrow.",
|
||||||
|
cta: "Learn More",
|
||||||
|
theme: "gold"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: "/images/hero3.jpg",
|
||||||
|
alt: "Nigerian textiles and art",
|
||||||
|
title: "Proud Heritage",
|
||||||
|
subtitle: "United in Our Mission",
|
||||||
|
description: "Preserving and promoting Nigerian arts, crafts, and cultural traditions while fostering integration in Dutch society.",
|
||||||
|
cta: "Explore Culture",
|
||||||
|
theme: "red"
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const themeColors = {
|
||||||
|
green: {
|
||||||
|
primary: "from-green-600 to-green-800",
|
||||||
|
secondary: "from-green-500 to-green-700",
|
||||||
|
accent: "bg-green-500",
|
||||||
|
text: "text-green-600"
|
||||||
|
},
|
||||||
|
gold: {
|
||||||
|
primary: "from-yellow-500 to-orange-600",
|
||||||
|
secondary: "from-yellow-400 to-orange-500",
|
||||||
|
accent: "bg-yellow-500",
|
||||||
|
text: "text-yellow-600"
|
||||||
|
},
|
||||||
|
red: {
|
||||||
|
primary: "from-red-600 to-red-800",
|
||||||
|
secondary: "from-red-500 to-red-700",
|
||||||
|
accent: "bg-red-500",
|
||||||
|
text: "text-red-600"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function HeroCarousel() {
|
||||||
|
const [currentSlide, setCurrentSlide] = useState(0);
|
||||||
|
const [isPlaying, setIsPlaying] = useState(true);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isPlaying) return;
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
setCurrentSlide((prev) => (prev + 1) % slides.length);
|
||||||
|
}, 6000);
|
||||||
|
|
||||||
|
return () => clearInterval(interval);
|
||||||
|
}, [isPlaying]);
|
||||||
|
|
||||||
|
const nextSlide = () => {
|
||||||
|
setCurrentSlide((prev) => (prev + 1) % slides.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
const prevSlide = () => {
|
||||||
|
setCurrentSlide((prev) => (prev - 1 + slides.length) % slides.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
const goToSlide = (index) => {
|
||||||
|
setCurrentSlide(index);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative w-full max-w-6xl mx-auto rounded-2xl overflow-hidden shadow-2xl bg-white">
|
||||||
|
{/* Main Carousel Container */}
|
||||||
|
<div className="relative h-[600px] overflow-hidden">
|
||||||
|
{slides.map((slide, index) => {
|
||||||
|
const theme = themeColors[slide.theme];
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className={`absolute inset-0 transition-all duration-1000 ease-in-out ${
|
||||||
|
index === currentSlide
|
||||||
|
? 'opacity-100 translate-x-0'
|
||||||
|
: index < currentSlide
|
||||||
|
? 'opacity-0 -translate-x-full'
|
||||||
|
: 'opacity-0 translate-x-full'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{/* Background Image */}
|
||||||
|
<div className="absolute inset-0">
|
||||||
|
<img
|
||||||
|
src={slide.image}
|
||||||
|
alt={slide.alt}
|
||||||
|
className="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
<div className={`absolute inset-0 bg-gradient-to-r ${theme.primary} opacity-80`}></div>
|
||||||
|
<div className="absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-transparent"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<div className="relative z-10 h-full flex items-center">
|
||||||
|
<div className="container mx-auto px-8">
|
||||||
|
<div className="max-w-2xl text-white">
|
||||||
|
{/* Animated Content */}
|
||||||
|
<div className={`transition-all duration-1000 delay-300 ${
|
||||||
|
index === currentSlide ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-8'
|
||||||
|
}`}>
|
||||||
|
<div className="flex items-center gap-3 mb-4">
|
||||||
|
<div className={`w-2 h-12 ${theme.accent} rounded-full`}></div>
|
||||||
|
<span className="text-sm font-semibold uppercase tracking-wider opacity-90">
|
||||||
|
Omoluabi Foundation
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 className="text-5xl md:text-6xl font-bold mb-2 leading-tight">
|
||||||
|
{slide.title}
|
||||||
|
</h1>
|
||||||
|
<h2 className="text-2xl md:text-3xl font-light mb-6 text-yellow-200">
|
||||||
|
{slide.subtitle}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<p className="text-lg md:text-xl mb-8 leading-relaxed opacity-90 max-w-xl">
|
||||||
|
{slide.description}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
|
<button className="bg-white text-gray-900 px-8 py-4 rounded-xl font-bold hover:bg-gray-100 transition-all duration-300 transform hover:scale-105 shadow-lg">
|
||||||
|
{slide.cta}
|
||||||
|
</button>
|
||||||
|
<button className="border-2 border-white text-white px-8 py-4 rounded-xl font-bold hover:bg-white hover:text-gray-900 transition-all duration-300 transform hover:scale-105">
|
||||||
|
Learn More
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Decorative Elements */}
|
||||||
|
<div className="absolute top-10 right-10 w-32 h-32 border-2 border-white/20 rounded-full animate-spin" style={{animationDuration: '20s'}}></div>
|
||||||
|
<div className="absolute bottom-10 left-10 w-24 h-24 border-2 border-white/20 rounded-full animate-bounce"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Navigation Arrows */}
|
||||||
|
<button
|
||||||
|
onClick={prevSlide}
|
||||||
|
className="absolute left-4 top-1/2 -translate-y-1/2 bg-white/20 backdrop-blur-sm hover:bg-white/30 text-white p-3 rounded-full transition-all duration-300 hover:scale-110 group"
|
||||||
|
aria-label="Previous slide"
|
||||||
|
>
|
||||||
|
<svg className="w-6 h-6 group-hover:-translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={nextSlide}
|
||||||
|
className="absolute right-4 top-1/2 -translate-y-1/2 bg-white/20 backdrop-blur-sm hover:bg-white/30 text-white p-3 rounded-full transition-all duration-300 hover:scale-110 group"
|
||||||
|
aria-label="Next slide"
|
||||||
|
>
|
||||||
|
<svg className="w-6 h-6 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Slide Indicators */}
|
||||||
|
<div className="absolute bottom-6 left-1/2 -translate-x-1/2 flex gap-3">
|
||||||
|
{slides.map((_, index) => (
|
||||||
|
<button
|
||||||
|
key={index}
|
||||||
|
onClick={() => goToSlide(index)}
|
||||||
|
className={`w-3 h-3 rounded-full transition-all duration-300 ${
|
||||||
|
index === currentSlide
|
||||||
|
? 'bg-white scale-125'
|
||||||
|
: 'bg-white/50 hover:bg-white/75'
|
||||||
|
}`}
|
||||||
|
aria-label={`Go to slide ${index + 1}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Play/Pause Button */}
|
||||||
|
<button
|
||||||
|
onClick={() => setIsPlaying(!isPlaying)}
|
||||||
|
className="absolute top-4 right-4 bg-white/20 backdrop-blur-sm hover:bg-white/30 text-white p-2 rounded-full transition-all duration-300 hover:scale-110"
|
||||||
|
aria-label={isPlaying ? "Pause slideshow" : "Play slideshow"}
|
||||||
|
>
|
||||||
|
{isPlaying ? (
|
||||||
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z" clipRule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
) : (
|
||||||
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" clipRule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Progress Bar */}
|
||||||
|
<div className="absolute bottom-0 left-0 right-0 h-1 bg-white/20">
|
||||||
|
<div
|
||||||
|
className="h-full bg-gradient-to-r from-yellow-400 to-red-500 transition-all duration-100"
|
||||||
|
style={{
|
||||||
|
width: `${((currentSlide + 1) / slides.length) * 100}%`
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
14
src/components/HomeGallery.astro
Normal file
14
src/components/HomeGallery.astro
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
const gallery = await Astro.glob('../../content/gallery/gallery-sample.md');
|
||||||
|
const images = gallery[0]?.frontmatter.images || [];
|
||||||
|
---
|
||||||
|
<section class="max-w-6xl mx-auto my-20">
|
||||||
|
<h2 class="text-2xl font-headline font-bold mb-6 text-primary text-center">Gallery</h2>
|
||||||
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
|
{images.map((img, idx) => (
|
||||||
|
<div class="rounded-lg overflow-hidden shadow-md bg-base-100" key={idx}>
|
||||||
|
<img src={img} alt={`Gallery photo ${idx + 1}`} class="w-full h-40 object-cover hover:scale-105 transition-transform duration-200 cursor-pointer" />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
41
src/layouts/BaseLayout.astro
Normal file
41
src/layouts/BaseLayout.astro
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
---
|
||||||
|
// Base layout for all pages
|
||||||
|
import Header from '../components/Header.astro';
|
||||||
|
import Footer from '../components/Footer.astro';
|
||||||
|
---
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Omoluabi Foundation</title>
|
||||||
|
<meta name="description" content="Supporting Nigerians in the Netherlands" />
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Poppins:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||||
|
<slot name="head" />
|
||||||
|
</head>
|
||||||
|
<body style="
|
||||||
|
font-family: 'Inter', system-ui, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: linear-gradient(135deg, #fafafa 0%, #f0fdf4 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-top: 80px;
|
||||||
|
">
|
||||||
|
<Header />
|
||||||
|
<main style="flex: 1;">
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
body {
|
||||||
|
padding-top: 120px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
1038
src/pages/about.astro
Normal file
1038
src/pages/about.astro
Normal file
File diff suppressed because it is too large
Load Diff
9
src/pages/contact.astro
Normal file
9
src/pages/contact.astro
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
import ContactForm from '../components/ContactForm.jsx';
|
||||||
|
---
|
||||||
|
<BaseLayout>
|
||||||
|
<h1 class="text-3xl font-headline font-bold text-primary mt-12 text-center">Contact Us</h1>
|
||||||
|
<p class="mt-4 text-center">We'd love to hear from you! Please use the form below or reach out via our contact details.</p>
|
||||||
|
<ContactForm client:load />
|
||||||
|
</BaseLayout>
|
0
src/pages/donate.astro
Normal file
0
src/pages/donate.astro
Normal file
27
src/pages/events.astro
Normal file
27
src/pages/events.astro
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
const events = await Astro.glob('../../content/events/*.md');
|
||||||
|
const sortedEvents = events.sort((a, b) => new Date(b.frontmatter.date) - new Date(a.frontmatter.date));
|
||||||
|
---
|
||||||
|
<BaseLayout>
|
||||||
|
<h1 class="text-3xl font-headline font-bold text-primary mt-12 text-center">Events</h1>
|
||||||
|
<p class="mt-4 text-center">See our upcoming and past events below.</p>
|
||||||
|
<section class="max-w-5xl mx-auto mt-8 grid grid-cols-1 md:grid-cols-2 gap-8 px-4">
|
||||||
|
{sortedEvents.map(event => (
|
||||||
|
<article class="card bg-base-100 shadow-lg">
|
||||||
|
<figure>
|
||||||
|
<img src={event.frontmatter.image} alt={event.frontmatter.title} class="w-full h-48 object-cover" />
|
||||||
|
</figure>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="flex items-center gap-2 mb-2">
|
||||||
|
<span class="badge badge-secondary">{event.frontmatter.category}</span>
|
||||||
|
<span class="text-xs text-gray-500">{new Date(event.frontmatter.date).toLocaleDateString()}</span>
|
||||||
|
</div>
|
||||||
|
<h2 class="card-title text-lg font-bold">{event.frontmatter.title}</h2>
|
||||||
|
<p class="text-sm mb-2">{event.frontmatter.description}</p>
|
||||||
|
<div class="text-xs text-gray-400">{event.compiledContent()}</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
))}
|
||||||
|
</section>
|
||||||
|
</BaseLayout>
|
1299
src/pages/index.astro
Normal file
1299
src/pages/index.astro
Normal file
File diff suppressed because it is too large
Load Diff
22
src/pages/members.astro
Normal file
22
src/pages/members.astro
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
const membersData = await Astro.glob('../../content/members/members-sample.md');
|
||||||
|
const intro = membersData[0]?.frontmatter.intro || '';
|
||||||
|
const members = membersData[0]?.frontmatter.members || [];
|
||||||
|
---
|
||||||
|
<BaseLayout>
|
||||||
|
<h1 class="text-3xl font-headline font-bold text-primary mt-12 text-center">Meet Our Members</h1>
|
||||||
|
<section class="max-w-3xl mx-auto mt-8 mb-12 bg-base-100 rounded-xl shadow p-6">
|
||||||
|
<h2 class="text-xl font-bold mb-4 text-accent">Membership Benefits/Welfare Packages</h2>
|
||||||
|
<div class="text-gray-700 whitespace-pre-line">{intro}</div>
|
||||||
|
</section>
|
||||||
|
<section class="max-w-6xl mx-auto grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-8 px-4 mb-20">
|
||||||
|
{members.map(member => (
|
||||||
|
<div class="card bg-base-100 shadow-lg rounded-xl flex flex-col items-center p-4">
|
||||||
|
<img src={member.image} alt={member.name} class="w-40 h-40 object-cover rounded-lg mb-4" />
|
||||||
|
<h3 class="font-bold text-lg text-primary mb-1">{member.name}</h3>
|
||||||
|
<p class="text-sm text-gray-600">{member.role}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</section>
|
||||||
|
</BaseLayout>
|
8
src/pages/orphanage.astro
Normal file
8
src/pages/orphanage.astro
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||||
|
---
|
||||||
|
<BaseLayout>
|
||||||
|
<h1 class="text-3xl font-headline font-bold text-nigerian-green mt-12 text-center">Orphanage</h1>
|
||||||
|
<p class="mt-4 text-center">Learn more about our affiliated orphanage and how you can help.</p>
|
||||||
|
<!-- Orphanage info, gallery, and donation details will go here -->
|
||||||
|
</BaseLayout>
|
397
src/styles/global.css
Normal file
397
src/styles/global.css
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Poppins:wght@400;500;600;700;800&family=Noto+Serif:wght@400;600;700&display=swap');
|
||||||
|
@import "tailwindcss/base";
|
||||||
|
@import "tailwindcss/components";
|
||||||
|
@import "tailwindcss/utilities";
|
||||||
|
|
||||||
|
/* Root Variables for Nigerian Theme */
|
||||||
|
:root {
|
||||||
|
--nigerian-green: #16a34a;
|
||||||
|
--nigerian-white: #ffffff;
|
||||||
|
--kente-gold: #f59e0b;
|
||||||
|
--adire-blue: #2563eb;
|
||||||
|
--ankara-red: #dc2626;
|
||||||
|
--earth-brown: #a18072;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', system-ui, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #fafafa 0%, #f0fdf4 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom scrollbar */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--nigerian-green);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #15803d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smooth hover transitions */
|
||||||
|
* {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nigerian pattern overlay */
|
||||||
|
.nigerian-pattern {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nigerian-pattern::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23f59e0b' fill-opacity='0.03'%3E%3Cpath d='M20 20c0 11.046-8.954 20-20 20v-40c11.046 0 20 8.954 20 20zM40 20c0 11.046-8.954 20-20 20v-40c11.046 0 20 8.954 20 20z'/%3E%3C/g%3E%3C/svg%3E");
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced button styles */
|
||||||
|
.btn {
|
||||||
|
border-radius: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.025em;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background: var(--nigerian-green);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background: var(--kente-gold);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-accent {
|
||||||
|
background: var(--ankara-red);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
|
||||||
|
transition: left 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover::before {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-lg {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card enhancements */
|
||||||
|
.card {
|
||||||
|
border-radius: 16px;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
border: 1px solid rgba(229, 229, 229, 0.8);
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 20px 40px -12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input styling */
|
||||||
|
.input, .textarea {
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 2px solid #e5e5e5;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
width: 100%;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input:focus, .textarea:focus {
|
||||||
|
border-color: var(--nigerian-green);
|
||||||
|
box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.1);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Badge styling */
|
||||||
|
.badge {
|
||||||
|
border-radius: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.025em;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-primary {
|
||||||
|
background: var(--nigerian-green);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-secondary {
|
||||||
|
background: var(--kente-gold);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-lg {
|
||||||
|
padding: 0.75rem 1.25rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hero text animations */
|
||||||
|
@keyframes textShine {
|
||||||
|
0% { background-position: -200% center; }
|
||||||
|
100% { background-position: 200% center; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-shine {
|
||||||
|
background: linear-gradient(90deg, var(--nigerian-green), var(--kente-gold), var(--ankara-red), var(--nigerian-green));
|
||||||
|
background-size: 200% auto;
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
animation: textShine 3s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animations */
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translateY(0px); }
|
||||||
|
50% { transform: translateY(-10px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
0% { transform: translateY(30px); opacity: 0; }
|
||||||
|
100% { transform: translateY(0px); opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
0% { opacity: 0; }
|
||||||
|
100% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bounceGentle {
|
||||||
|
0%, 100% { transform: translateY(0px); }
|
||||||
|
50% { transform: translateY(-5px); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-float {
|
||||||
|
animation: float 6s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-up {
|
||||||
|
animation: slideUp 0.8s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-fade-in {
|
||||||
|
animation: fadeIn 1s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-bounce-gentle {
|
||||||
|
animation: bounceGentle 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Color utilities */
|
||||||
|
.text-nigerian-green { color: var(--nigerian-green); }
|
||||||
|
.text-kente-gold { color: var(--kente-gold); }
|
||||||
|
.text-ankara-red { color: var(--ankara-red); }
|
||||||
|
.text-primary { color: var(--nigerian-green); }
|
||||||
|
.text-secondary { color: var(--kente-gold); }
|
||||||
|
.text-accent { color: var(--ankara-red); }
|
||||||
|
|
||||||
|
.bg-nigerian-green { background-color: var(--nigerian-green); }
|
||||||
|
.bg-kente-gold { background-color: var(--kente-gold); }
|
||||||
|
.bg-ankara-red { background-color: var(--ankara-red); }
|
||||||
|
.bg-primary { background-color: var(--nigerian-green); }
|
||||||
|
.bg-secondary { background-color: var(--kente-gold); }
|
||||||
|
.bg-accent { background-color: var(--ankara-red); }
|
||||||
|
|
||||||
|
/* Gradient backgrounds */
|
||||||
|
.bg-nigerian-gradient {
|
||||||
|
background: linear-gradient(135deg, var(--nigerian-green) 0%, var(--kente-gold) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-cultural-gradient {
|
||||||
|
background: linear-gradient(135deg, var(--nigerian-green) 0%, var(--kente-gold) 25%, var(--ankara-red) 75%, var(--nigerian-green) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section padding utility */
|
||||||
|
.section-padding {
|
||||||
|
padding: 5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.section-padding {
|
||||||
|
padding: 3rem 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grid utilities */
|
||||||
|
.container {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Typography */
|
||||||
|
.font-headline { font-family: 'Poppins', system-ui, sans-serif; }
|
||||||
|
.font-body { font-family: 'Inter', system-ui, sans-serif; }
|
||||||
|
.font-cultural { font-family: 'Noto Serif', serif; }
|
||||||
|
|
||||||
|
/* Text sizes */
|
||||||
|
.text-xs { font-size: 0.75rem; }
|
||||||
|
.text-sm { font-size: 0.875rem; }
|
||||||
|
.text-base { font-size: 1rem; }
|
||||||
|
.text-lg { font-size: 1.125rem; }
|
||||||
|
.text-xl { font-size: 1.25rem; }
|
||||||
|
.text-2xl { font-size: 1.5rem; }
|
||||||
|
.text-3xl { font-size: 1.875rem; }
|
||||||
|
.text-4xl { font-size: 2.25rem; }
|
||||||
|
.text-5xl { font-size: 3rem; }
|
||||||
|
.text-6xl { font-size: 3.75rem; }
|
||||||
|
.text-7xl { font-size: 4.5rem; }
|
||||||
|
|
||||||
|
/* Font weights */
|
||||||
|
.font-light { font-weight: 300; }
|
||||||
|
.font-normal { font-weight: 400; }
|
||||||
|
.font-medium { font-weight: 500; }
|
||||||
|
.font-semibold { font-weight: 600; }
|
||||||
|
.font-bold { font-weight: 700; }
|
||||||
|
|
||||||
|
/* Spacing utilities */
|
||||||
|
.p-4 { padding: 1rem; }
|
||||||
|
.p-6 { padding: 1.5rem; }
|
||||||
|
.p-8 { padding: 2rem; }
|
||||||
|
.px-4 { padding-left: 1rem; padding-right: 1rem; }
|
||||||
|
.py-4 { padding-top: 1rem; padding-bottom: 1rem; }
|
||||||
|
.m-4 { margin: 1rem; }
|
||||||
|
.mb-4 { margin-bottom: 1rem; }
|
||||||
|
.mb-6 { margin-bottom: 1.5rem; }
|
||||||
|
.mb-8 { margin-bottom: 2rem; }
|
||||||
|
.mt-8 { margin-top: 2rem; }
|
||||||
|
.mt-12 { margin-top: 3rem; }
|
||||||
|
.mt-16 { margin-top: 4rem; }
|
||||||
|
.mt-20 { margin-top: 5rem; }
|
||||||
|
|
||||||
|
/* Layout utilities */
|
||||||
|
.flex { display: flex; }
|
||||||
|
.grid { display: grid; }
|
||||||
|
.block { display: block; }
|
||||||
|
.inline-flex { display: inline-flex; }
|
||||||
|
.items-center { align-items: center; }
|
||||||
|
.justify-center { justify-content: center; }
|
||||||
|
.justify-between { justify-content: space-between; }
|
||||||
|
.gap-4 { gap: 1rem; }
|
||||||
|
.gap-6 { gap: 1.5rem; }
|
||||||
|
.gap-8 { gap: 2rem; }
|
||||||
|
.gap-12 { gap: 3rem; }
|
||||||
|
|
||||||
|
/* Grid utilities */
|
||||||
|
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
|
||||||
|
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||||
|
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.md\\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
||||||
|
.md\\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
.lg\\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
||||||
|
.lg\\:col-span-2 { grid-column: span 2 / span 2; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Positioning */
|
||||||
|
.relative { position: relative; }
|
||||||
|
.absolute { position: absolute; }
|
||||||
|
.fixed { position: fixed; }
|
||||||
|
.top-0 { top: 0; }
|
||||||
|
.left-0 { left: 0; }
|
||||||
|
.right-0 { right: 0; }
|
||||||
|
.bottom-0 { bottom: 0; }
|
||||||
|
.inset-0 { top: 0; right: 0; bottom: 0; left: 0; }
|
||||||
|
.z-10 { z-index: 10; }
|
||||||
|
.z-50 { z-index: 50; }
|
||||||
|
|
||||||
|
/* Width and height */
|
||||||
|
.w-full { width: 100%; }
|
||||||
|
.h-full { height: 100%; }
|
||||||
|
.min-h-screen { min-height: 100vh; }
|
||||||
|
.max-w-2xl { max-width: 42rem; }
|
||||||
|
.max-w-3xl { max-width: 48rem; }
|
||||||
|
.max-w-4xl { max-width: 56rem; }
|
||||||
|
.max-w-5xl { max-width: 64rem; }
|
||||||
|
.max-w-6xl { max-width: 72rem; }
|
||||||
|
.mx-auto { margin-left: auto; margin-right: auto; }
|
||||||
|
|
||||||
|
/* Rounded corners */
|
||||||
|
.rounded-lg { border-radius: 0.5rem; }
|
||||||
|
.rounded-xl { border-radius: 0.75rem; }
|
||||||
|
.rounded-2xl { border-radius: 1rem; }
|
||||||
|
.rounded-full { border-radius: 9999px; }
|
||||||
|
|
||||||
|
/* Shadows */
|
||||||
|
.shadow-lg { box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); }
|
||||||
|
.shadow-xl { box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); }
|
||||||
|
.shadow-2xl { box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); }
|
||||||
|
|
||||||
|
/* Transforms */
|
||||||
|
.transform { transform: translateX(var(--tw-translate-x, 0)) translateY(var(--tw-translate-y, 0)) rotate(var(--tw-rotate, 0)) skewX(var(--tw-skew-x, 0)) skewY(var(--tw-skew-y, 0)) scaleX(var(--tw-scale-x, 1)) scaleY(var(--tw-scale-y, 1)); }
|
||||||
|
.hover\\:scale-105:hover { --tw-scale-x: 1.05; --tw-scale-y: 1.05; }
|
||||||
|
.hover\\:-translate-y-2:hover { --tw-translate-y: -0.5rem; }
|
||||||
|
|
||||||
|
/* Text alignment */
|
||||||
|
.text-center { text-align: center; }
|
||||||
|
.text-left { text-align: left; }
|
||||||
|
|
||||||
|
/* Overflow */
|
||||||
|
.overflow-hidden { overflow: hidden; }
|
||||||
|
|
||||||
|
/* Background opacity */
|
||||||
|
.bg-opacity-80 { background-color: rgba(var(--tw-bg-opacity-value, 1), 0.8); }
|
||||||
|
.bg-opacity-90 { background-color: rgba(var(--tw-bg-opacity-value, 1), 0.9); }
|
||||||
|
|
||||||
|
/* Object fit */
|
||||||
|
.object-cover { object-fit: cover; }
|
||||||
|
.object-contain { object-fit: contain; }
|
284
tailwind.config.js
Normal file
284
tailwind.config.js
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
// tailwind.config.mjs
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
// Nigerian flag colors as primary palette
|
||||||
|
'nigerian-green': {
|
||||||
|
50: '#f0fdf4',
|
||||||
|
100: '#dcfce7',
|
||||||
|
200: '#bbf7d0',
|
||||||
|
300: '#86efac',
|
||||||
|
400: '#4ade80',
|
||||||
|
500: '#22c55e',
|
||||||
|
600: '#16a34a',
|
||||||
|
700: '#15803d',
|
||||||
|
800: '#166534',
|
||||||
|
900: '#14532d',
|
||||||
|
},
|
||||||
|
'nigerian-white': {
|
||||||
|
50: '#ffffff',
|
||||||
|
100: '#fefefe',
|
||||||
|
200: '#fafafa',
|
||||||
|
300: '#f5f5f5',
|
||||||
|
400: '#efefef',
|
||||||
|
500: '#e5e5e5',
|
||||||
|
},
|
||||||
|
// Rich cultural colors inspired by Nigerian textiles
|
||||||
|
'kente-gold': {
|
||||||
|
50: '#fffbeb',
|
||||||
|
100: '#fef3c7',
|
||||||
|
200: '#fde68a',
|
||||||
|
300: '#fcd34d',
|
||||||
|
400: '#fbbf24',
|
||||||
|
500: '#f59e0b',
|
||||||
|
600: '#d97706',
|
||||||
|
700: '#b45309',
|
||||||
|
800: '#92400e',
|
||||||
|
900: '#78350f',
|
||||||
|
},
|
||||||
|
'adire-blue': {
|
||||||
|
50: '#eff6ff',
|
||||||
|
100: '#dbeafe',
|
||||||
|
200: '#bfdbfe',
|
||||||
|
300: '#93c5fd',
|
||||||
|
400: '#60a5fa',
|
||||||
|
500: '#3b82f6',
|
||||||
|
600: '#2563eb',
|
||||||
|
700: '#1d4ed8',
|
||||||
|
800: '#1e40af',
|
||||||
|
900: '#1e3a8a',
|
||||||
|
},
|
||||||
|
'ankara-red': {
|
||||||
|
50: '#fef2f2',
|
||||||
|
100: '#fee2e2',
|
||||||
|
200: '#fecaca',
|
||||||
|
300: '#fca5a5',
|
||||||
|
400: '#f87171',
|
||||||
|
500: '#ef4444',
|
||||||
|
600: '#dc2626',
|
||||||
|
700: '#b91c1c',
|
||||||
|
800: '#991b1b',
|
||||||
|
900: '#7f1d1d',
|
||||||
|
},
|
||||||
|
'earth-brown': {
|
||||||
|
50: '#fdf8f6',
|
||||||
|
100: '#f2e8e5',
|
||||||
|
200: '#eaddd7',
|
||||||
|
300: '#e0cfc5',
|
||||||
|
400: '#d2bab0',
|
||||||
|
500: '#bfa094',
|
||||||
|
600: '#a18072',
|
||||||
|
700: '#977669',
|
||||||
|
800: '#846358',
|
||||||
|
900: '#43302b',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
'headline': ['Poppins', 'system-ui', 'sans-serif'],
|
||||||
|
'body': ['Inter', 'system-ui', 'sans-serif'],
|
||||||
|
'cultural': ['Noto Serif', 'serif'],
|
||||||
|
},
|
||||||
|
backgroundImage: {
|
||||||
|
'nigerian-pattern': `url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23f59e0b' fill-opacity='0.05'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E")`,
|
||||||
|
'kente-gradient': 'linear-gradient(135deg, #f59e0b 0%, #dc2626 25%, #16a34a 50%, #2563eb 75%, #f59e0b 100%)',
|
||||||
|
'hero-overlay': 'linear-gradient(135deg, rgba(22, 163, 74, 0.9) 0%, rgba(245, 158, 11, 0.8) 100%)',
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
'float': 'float 6s ease-in-out infinite',
|
||||||
|
'slide-up': 'slideUp 0.8s ease-out',
|
||||||
|
'fade-in': 'fadeIn 1s ease-out',
|
||||||
|
'bounce-gentle': 'bounceGentle 2s ease-in-out infinite',
|
||||||
|
},
|
||||||
|
keyframes: {
|
||||||
|
float: {
|
||||||
|
'0%, 100%': { transform: 'translateY(0px)' },
|
||||||
|
'50%': { transform: 'translateY(-10px)' },
|
||||||
|
},
|
||||||
|
slideUp: {
|
||||||
|
'0%': { transform: 'translateY(30px)', opacity: '0' },
|
||||||
|
'100%': { transform: 'translateY(0px)', opacity: '1' },
|
||||||
|
},
|
||||||
|
fadeIn: {
|
||||||
|
'0%': { opacity: '0' },
|
||||||
|
'100%': { opacity: '1' },
|
||||||
|
},
|
||||||
|
bounceGentle: {
|
||||||
|
'0%, 100%': { transform: 'translateY(0px)' },
|
||||||
|
'50%': { transform: 'translateY(-5px)' },
|
||||||
|
}
|
||||||
|
},
|
||||||
|
boxShadow: {
|
||||||
|
'nigerian': '0 10px 25px -3px rgba(22, 163, 74, 0.1), 0 4px 6px -2px rgba(22, 163, 74, 0.05)',
|
||||||
|
'kente': '0 10px 25px -3px rgba(245, 158, 11, 0.2), 0 4px 6px -2px rgba(245, 158, 11, 0.1)',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
daisyui: {
|
||||||
|
themes: [
|
||||||
|
{
|
||||||
|
omoluabi: {
|
||||||
|
"primary": "#16a34a", // Nigerian green
|
||||||
|
"secondary": "#f59e0b", // Kente gold
|
||||||
|
"accent": "#dc2626", // Ankara red
|
||||||
|
"neutral": "#fafafa", // Clean white base
|
||||||
|
"base-100": "#ffffff", // Pure white
|
||||||
|
"base-200": "#f5f5f5", // Light gray
|
||||||
|
"base-300": "#e5e5e5", // Medium gray
|
||||||
|
"info": "#2563eb", // Adire blue
|
||||||
|
"success": "#22c55e", // Success green
|
||||||
|
"warning": "#f59e0b", // Warning gold
|
||||||
|
"error": "#dc2626", // Error red
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
plugins: [require("daisyui")],
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Updated global.css */
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Poppins:wght@400;500;600;700;800&family=Noto+Serif:wght@400;600;700&display=swap');
|
||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', system-ui, sans-serif;
|
||||||
|
background: linear-gradient(135deg, #fafafa 0%, #f0fdf4 100%);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom scrollbar */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: #16a34a;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #15803d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smooth hover transitions */
|
||||||
|
* {
|
||||||
|
transition: all 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nigerian pattern overlay */
|
||||||
|
.nigerian-pattern {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nigerian-pattern::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23f59e0b' fill-opacity='0.03'%3E%3Cpath d='M20 20c0 11.046-8.954 20-20 20v-40c11.046 0 20 8.954 20 20zM40 20c0 11.046-8.954 20-20 20v-40c11.046 0 20 8.954 20 20z'/%3E%3C/g%3E%3C/svg%3E");
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced button styles */
|
||||||
|
.btn {
|
||||||
|
border-radius: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.025em;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
|
||||||
|
transition: left 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover::before {
|
||||||
|
left: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 10px 25px -3px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card enhancements */
|
||||||
|
.card {
|
||||||
|
border-radius: 16px;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
border: 1px solid rgba(229, 229, 229, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-4px);
|
||||||
|
box-shadow: 0 20px 40px -12px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input styling */
|
||||||
|
.input, .textarea {
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 2px solid #e5e5e5;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input:focus, .textarea:focus {
|
||||||
|
border-color: #16a34a;
|
||||||
|
box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Badge styling */
|
||||||
|
.badge {
|
||||||
|
border-radius: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.025em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hero text animations */
|
||||||
|
@keyframes textShine {
|
||||||
|
0% { background-position: -200% center; }
|
||||||
|
100% { background-position: 200% center; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-shine {
|
||||||
|
background: linear-gradient(90deg, #16a34a, #f59e0b, #dc2626, #16a34a);
|
||||||
|
background-size: 200% auto;
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
animation: textShine 3s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loading animations */
|
||||||
|
.animate-pulse-slow {
|
||||||
|
animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom spacing utilities */
|
||||||
|
.section-padding {
|
||||||
|
padding: 5rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.section-padding {
|
||||||
|
padding: 3rem 1rem;
|
||||||
|
}
|
||||||
|
}
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "astro/tsconfigs/strict",
|
||||||
|
"include": [
|
||||||
|
".astro/types.d.ts",
|
||||||
|
"**/*"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"jsxImportSource": "react"
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user