Website Overall

This commit is contained in:
2025-04-19 18:12:49 +01:00
parent 30c93820f4
commit babcc20166
27 changed files with 295 additions and 200 deletions
+101 -38
View File
@@ -11,6 +11,8 @@
"@emailjs/browser": "^4.3.3",
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^2.1.3",
"caniuse-lite": "^1.0.30001696",
"framer-motion": "^12.7.3",
"i18next": "^23.11.5",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-http-backend": "^2.5.2",
@@ -20,7 +22,7 @@
"react-dom": "^18.2.0",
"react-i18next": "^14.1.2",
"react-icons": "^5.0.1",
"react-phone-input-2": "^2.15.1",
"react-phone-number-input": "^3.4.3",
"react-router-dom": "^6.22.3",
"react-toastify": "^10.0.5",
"sort-by": "^0.0.2"
@@ -1877,10 +1879,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001608",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001608.tgz",
"integrity": "sha512-cjUJTQkk9fQlJR2s4HMuPMvTiRggl0rAVMtthQuyOlDWuqHXqN8azLq+pi8B2TjwKJ32diHjUqRIKeFX4z1FoA==",
"dev": true,
"version": "1.0.30001713",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001713.tgz",
"integrity": "sha512-wCIWIg+A4Xr7NfhTuHdX+/FKh3+Op3LBbSp2N5Pfx6T/LhdQy3GTyoTg48BReaW/MyMNZAkTadsBtai3ldWK0Q==",
"funding": [
{
"type": "opencollective",
@@ -1894,7 +1895,8 @@
"type": "github",
"url": "https://github.com/sponsors/ai"
}
]
],
"license": "CC-BY-4.0"
},
"node_modules/chalk": {
"version": "2.4.2",
@@ -2001,6 +2003,12 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
"node_modules/country-flag-icons": {
"version": "1.5.18",
"resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.18.tgz",
"integrity": "sha512-z+Uzesi8u8IdkViqqbzzbkf3+a7WJpcET5B7sPwTg7GXqPYpVEgNlZ/FC3l8KO4mEf+mNkmzKLppKTN4PlCJEQ==",
"license": "MIT"
},
"node_modules/cross-fetch": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
@@ -2601,6 +2609,33 @@
"url": "https://github.com/sponsors/rawify"
}
},
"node_modules/framer-motion": {
"version": "12.7.3",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.7.3.tgz",
"integrity": "sha512-dNT4l5gEnUo2ytXLUBUf6AI21dZ77TMclDKE3ElaIHZ8m90nJ/NCcExW51zdSIaS0RhAS5iXcF7bEIxZe8XG2g==",
"license": "MIT",
"dependencies": {
"motion-dom": "^12.7.3",
"motion-utils": "^12.7.2",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -2850,6 +2885,27 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"node_modules/input-format": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/input-format/-/input-format-0.3.14.tgz",
"integrity": "sha512-gHMrgrbCgmT4uK5Um5eVDUohuV9lcs95ZUUN9Px2Y0VIfjTzT2wF8Q3Z4fwLFm7c5Z2OXCm53FHoovj6SlOKdg==",
"license": "MIT",
"dependencies": {
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": ">=18.1.0",
"react-dom": ">=18.1.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -3037,6 +3093,12 @@
"node": ">= 0.8.0"
}
},
"node_modules/libphonenumber-js": {
"version": "1.12.6",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.6.tgz",
"integrity": "sha512-PJiS4ETaUfCOFLpmtKzAbqZQjCCKVu2OhTV4SVNNE7c2nu/dACvtCqj4L0i/KWNnIgRv7yrILvBj5Lonv5Ncxw==",
"license": "MIT"
},
"node_modules/lie": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
@@ -3083,32 +3145,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash.debounce": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="
},
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
"node_modules/lodash.reduce": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
"integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw=="
},
"node_modules/lodash.startswith": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/lodash.startswith/-/lodash.startswith-4.2.1.tgz",
"integrity": "sha512-XClYR1h4/fJ7H+mmCKppbiBmljN/nGs73iq2SjCT9SF4CBPoUHzLvWmH1GtZMhMBZSiRkHXfeA2RY1eIlJ75ww=="
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -3184,6 +3226,21 @@
"node": ">=16 || 14 >=14.17"
}
},
"node_modules/motion-dom": {
"version": "12.7.3",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.7.3.tgz",
"integrity": "sha512-IjMt1YJHrvyvruFvmpmd6bGXXGCvmygrnvSb3aZ8KhOzF4H3PulU+cMBzH+U8TBJHjC/mnmJFRIA1Cu4vBfcBA==",
"license": "MIT",
"dependencies": {
"motion-utils": "^12.7.2"
}
},
"node_modules/motion-utils": {
"version": "12.7.2",
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.7.2.tgz",
"integrity": "sha512-XhZwqctxyJs89oX00zn3OGCuIIpVevbTa+u82usWBC6pSHUd2AoNWiYa7Du8tJxJy9TFbZ82pcn5t7NOm1PHAw==",
"license": "MIT"
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -3710,21 +3767,21 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-phone-input-2": {
"version": "2.15.1",
"resolved": "https://registry.npmjs.org/react-phone-input-2/-/react-phone-input-2-2.15.1.tgz",
"integrity": "sha512-W03abwhXcwUoq+vUFvC6ch2+LJYMN8qSOiO889UH6S7SyMCQvox/LF3QWt+cZagZrRdi5z2ON3omnjoCUmlaYw==",
"node_modules/react-phone-number-input": {
"version": "3.4.12",
"resolved": "https://registry.npmjs.org/react-phone-number-input/-/react-phone-number-input-3.4.12.tgz",
"integrity": "sha512-Raob77KdtLGm49iC6nuOX9qy6Mg16idkgC7Y1mHmvG2WBYoauHpzxYNlfmFskQKeiztrJIwPhPzBhjFwjenNCA==",
"license": "MIT",
"dependencies": {
"classnames": "^2.2.6",
"lodash.debounce": "^4.0.8",
"lodash.memoize": "^4.1.2",
"lodash.reduce": "^4.6.0",
"lodash.startswith": "^4.2.1",
"prop-types": "^15.7.2"
"classnames": "^2.5.1",
"country-flag-icons": "^1.5.17",
"input-format": "^0.3.10",
"libphonenumber-js": "^1.11.20",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": "^16.12.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",
"react-dom": "^16.12.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0"
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/react-refresh": {
@@ -4295,6 +4352,12 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"dev": true
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+1
View File
@@ -14,6 +14,7 @@
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^2.1.3",
"caniuse-lite": "^1.0.30001696",
"framer-motion": "^12.7.3",
"i18next": "^23.11.5",
"i18next-browser-languagedetector": "^8.0.0",
"i18next-http-backend": "^2.5.2",
+14 -14
View File
@@ -9,20 +9,20 @@ const Card = ({ title, description, image }: IProps) => {
const imgClasses = image ? defaultImgClasses : `${defaultImgClasses} hidden`;
return (
<div className="mt-5 xl:mt-0 flex flex-1 bg-gradient-to-b from-gold-light to-gold-dark p-0.5 shadow-2xl">
<div className="w-full font-medium flex-col md:px-4 py-1 bg-gradient-to-br from-custom-bglight to-custom-bgdark">
<object type="image/svg+xml" data={image} className={imgClasses} aria-label={title}></object>
<h1 className="mt-2 lg:mt-6 text-3xl xl:text-5xl">{title}</h1>
<h2 className="results-card-content">
{description.split("\n").map((line, i) => (
<span key={i}>
{line}
<br />
</span>
))}
</h2>
</div>
</div>
<div className="glass-premium mt-5 xl:mt-0 flex flex-1 border-2 border-gold-accent shadow-xl rounded-2xl transition-transform duration-300 hover:scale-105 hover:shadow-gold-accent/40">
<div className="w-full font-medium flex-col md:px-4 py-1 bg-gradient-to-br from-custom-bglight to-custom-bgdark rounded-2xl">
<object type="image/svg+xml" data={image} className={imgClasses} aria-label={title}></object>
<h1 className="mt-2 lg:mt-6 text-2xl md:text-3xl xl:text-4xl font-bold text-white drop-shadow-lg break-words truncate max-w-full whitespace-normal">{title}</h1>
<h2 className="results-card-content">
{description.split("\n").map((line, i) => (
<span key={i}>
{line}
<br />
</span>
))}
</h2>
</div>
</div>
);
};
+5 -33
View File
@@ -4,40 +4,12 @@ const Footer = () => {
const { t, i18n } = useTranslation();
return (
//test
<footer className="flex flex-col space-y-10 justify-center m-10">
<div className="flex justify-center space-x-5">
<a
href="/tos"
className={
i18n.language === "en"
? "footer-text hover:text-gold-light"
: "footer-text-pt hover:text-gold-light"
}
>
{t("footer.tos")}
</a>
<a
href="/privacy"
className={
i18n.language === "en"
? "footer-text hover:text-gold-light"
: "footer-text-pt hover:text-gold-light"
}
>
{t("footer.privacy")}
</a>
<footer className="flex flex-col items-center justify-center py-6 px-4 mt-10 border-t border-gray-800 bg-transparent">
<div className="flex space-x-6 mb-2">
<a href="/tos" className="text-sm text-gray-400 hover:underline">{t("footer.tos")}</a>
<a href="/privacy" className="text-sm text-gray-400 hover:underline">{t("footer.privacy")}</a>
</div>
<p
className={
i18n.language === "en"
? "footer-text text-center"
: "footer-text-pt text-center"
}
>
{t("footer.rights")}
</p>
<p className="text-xs text-gray-400 text-center">{t("footer.rights")}</p>
</footer>
);
};
+15 -15
View File
@@ -73,8 +73,8 @@ export default () => {
: "z-10"
}`}
>
<div className="items-center px-4 max-w-screen-xl mx-auto lg:flex lg:justify-between lg:px-8">
<div className="flex items-center justify-between py-3 lg:py-5">
<div className="items-center px-4 max-w-[1400px] mx-auto w-full flex flex-col lg:flex-row lg:justify-between lg:px-8">
<div className="flex flex-row items-center justify-between w-full py-3 lg:py-5 lg:justify-between">
<a
href="Top"
@@ -103,11 +103,11 @@ export default () => {
</div>
{/* Center nav items for desktop */}
<div className="hidden lg:flex lg:items-center lg:justify-center lg:flex-grow">
<ul className="text-text-gold flex space-x-6 items-center">
<div className="hidden lg:flex lg:items-center lg:justify-center lg:absolute lg:left-1/2 lg:-translate-x-1/2">
<ul className="flex space-x-6 items-center">
{navigation.map((item, idx) => {
return (
<li key={idx} className="hover:text-white text-center">
<li key={idx} className="text-white hover:text-gold-accent text-center transition-colors duration-200">
<a
href={item.path}
className="block py-0 px-4 text-xl font-medium"
@@ -125,18 +125,18 @@ export default () => {
</div>
{/* Language toggle for desktop */}
<div className="hidden lg:flex lg:items-center">
<div className="hidden lg:flex lg:items-center ml-auto">
<button
className="text-text-gold hover:text-white"
onClick={() => changeLanguage(i18n.language === "en" ? "pt" : "en")}
className="text-white hover:text-gold-accent transition-colors duration-200"
onClick={() => changeLanguage(i18n.language === "en-GB" ? "pt-PT" : "en-GB")}
>
{i18n.language === "en" ? "PT" : "EN"}
{i18n.language === "en-GB" ? "PT" : "EN"}
</button>
</div>
{/* Mobile slide-in menu */}
<div
className={`fixed top-0 right-0 h-screen w-[70%] z-50 flex flex-col items-center justify-center pt-16 bg-custom-bglight shadow-lg transition-transform duration-300 ease-in-out lg:hidden ${
className={`glass-premium fixed top-0 right-0 h-screen w-[70%] z-50 flex flex-col items-center justify-center pt-16 shadow-lg transition-transform duration-300 ease-in-out lg:hidden ${
state ? "transform-none" : "translate-x-full"
}`}
>
@@ -147,10 +147,10 @@ export default () => {
<FaTimes className="h-6 w-6" />
</button>
<ul className="text-text-gold space-y-8 text-center justify-center items-center">
<ul className="space-y-8 text-center justify-center items-center">
{navigation.map((item, idx) => {
return (
<li key={idx} className="hover:text-white w-full text-center">
<li key={idx} className="text-white hover:text-gold-accent w-full text-center transition-colors duration-200">
<a
href={item.path}
className="block py-2 text-xl font-medium"
@@ -167,10 +167,10 @@ export default () => {
})}
</ul>
<button
className="absolute bottom-10 right-10 text-text-gold hover:text-white"
onClick={() => changeLanguage(i18n.language === "en" ? "pt" : "en")}
className="absolute bottom-10 right-10 text-white hover:text-gold-accent transition-colors duration-200"
onClick={() => changeLanguage(i18n.language === "en-GB" ? "pt-PT" : "en-GB")}
>
{i18n.language === "en" ? "PT" : "EN"}
{i18n.language === "en-GB" ? "PT" : "EN"}
</button>
</div>
+6 -8
View File
@@ -10,6 +10,7 @@ import PhoneInput, {
} from "react-phone-number-input";
import "react-phone-number-input/style.css";
import "./ContactForm.css";
import PremiumButton from "../../Shared/PremiumButton";
const ContactForm = () => {
const { t } = useTranslation();
@@ -176,14 +177,11 @@ const ContactForm = () => {
</div>
</div>
<div className="flex mt-5 mb-10 lg:mt-12 mx-10 sm:mx-40 rounded-full bg-gradient-to-br from-gold-light to-gold-dark p-0.5 shadow-lg">
<button
type="submit"
className="flex-1 font-medium md:px-8 py-3 text-2xl md:text-3xl bg-gradient-to-br from-custom-bglight to-custom-bgdark rounded-full hover:bg-transparent hover:from-transparent hover:to-transparent transition duration-500"
>
{t("contact.form.button")}
</button>
</div>
<div className="flex mx-10 md:mx-40 lg:mx-0 lg:ml-auto mt-5 mb-10 lg:mt-12">
<PremiumButton type="submit" className="sm:mx-40">
{t("contact.form.button")}
</PremiumButton>
</div>
<ToastContainer
position="top-center"
+1 -1
View File
@@ -10,7 +10,7 @@ const ContactPage = () => {
<h1>
{t("contact.heading.part1")} <br />
{t("contact.heading.part2")}{" "}
<span className="gold-text">{t("contact.heading.part3")}</span>{" "}
<span className="gold-text"><span className="gold-text">{t("contact.heading.part3")}</span></span>{" "}
{t("contact.heading.part4")}
</h1>
<h2 className="sub-header-text ">
+6 -14
View File
@@ -1,4 +1,5 @@
import { useTranslation } from "react-i18next";
import PremiumButton from "../../Shared/PremiumButton";
import HeroImg from "../../../assets/HeroImg.svg";
import Stars from "../../../assets/Stars.svg";
@@ -64,23 +65,14 @@ const Hero = () => {
{t("hero.subheading.part2")}
</h2>
</div>
<div className="flex mt-5 lg:mt-12 mx-10 md:mx-40 lg:mx-0 lg:ml-auto rounded-full bg-gradient-to-br from-gold-light to-gold-dark p-0.5 shadow-lg">
<a
className="flex w-full"
href="Contact"
onClick={(e) => {
e.preventDefault();
handleNavigation("Contact");
}}
>
<button className="flex-1 font-medium md:px-8 py-3 text-2xl md:text-3xl bg-gradient-to-br from-custom-bglight to-custom-bgdark rounded-full hover:bg-transparent hover:from-transparent hover:to-transparent transition duration-500">
{t("hero.button")}
</button>
</a>
<div className="flex mt-8 lg:mt-16 mx-10 md:mx-20 lg:mx-0 lg:ml-auto">
<PremiumButton onClick={() => handleNavigation("Contact")} className="sm:mx-40 lg:mx-0">
{t("hero.button")}
</PremiumButton>
</div>
</div>
</div>
</div>
</div>
);
};
+1 -1
View File
@@ -5,7 +5,7 @@ const ResultsPage = () => {
const { t } = useTranslation();
return (
<div className="header-text">
<div className="header-text p-8 md:p-16 mx-4 my-10 rounded-2xl">
<h1>
<span className="gold-text">"</span>
{t("results.heading.part1")} <br /> {t("results.heading.part2")}
@@ -9,7 +9,7 @@ const CameraCards = () => {
const { t } = useTranslation();
return (
<div className="h-full flex lg:mt-20 flex-col flex-wrap xl:flex-row mx-4 gap-5">
<div className="h-full flex lg:mt-20 flex-col flex-wrap md:flex-row md:mx-4 gap-5">
<Card
title={t("services.cards.media.card1.title")}
description={t("services.cards.media.card1.description")}
@@ -9,7 +9,7 @@ const MarketingCards = () => {
const { t } = useTranslation();
return (
<div className="h-full flex lg:mt-20 flex-col flex-wrap xl:flex-row mx-4 gap-5">
<div className="h-full flex lg:mt-20 flex-col flex-wrap md:flex-row md:mx-4 gap-5">
<Card
title={t("services.cards.marketing.card1.title")}
description={t("services.cards.marketing.card1.description")}
+14 -14
View File
@@ -8,7 +8,7 @@ interface IProps {
const Card = ({ title, description, imgSrc, delay }: IProps) => {
return (
<div
className="flex flex-col mt-4 lg:mt-0 justify-end flex-1 h-full border-solid border bg-cover bg-center text-center shadow-2xl"
className="flex flex-col mt-4 lg:mt-0 justify-end flex-1 h-full w-full md:w-96 xl:w-[340px] 2xl:w-[400px] border-solid border bg-cover bg-center text-center shadow-xl rounded-2xl transition-transform duration-300 hover:scale-105 hover:shadow-gold-accent/40"
style={{
backgroundImage: `url(${imgSrc})`,
filter: "saturate(50%)",
@@ -16,19 +16,19 @@ const Card = ({ title, description, imgSrc, delay }: IProps) => {
opacity: 0,
}}
>
<div className="lg:my-6">
<h2
className="drop-shadow-[0_1.2px_1.2px_rgba(0,0,0,0.8)]
text-3xl font-bold"
>
{title}
</h2>
<p
className="drop-shadow-[0_1.2px_1.2px_rgba(0,0,0,0.8)]
xl:mb-10 font-thin text-xl"
>
{description}
</p>
<div className="glass-premium p-6">
<div className="lg:py-6">
<h2
className="drop-shadow-[0_1.2px_1.2px_rgba(0,0,0,0.8)] text-3xl font-bold text-white"
>
{title}
</h2>
<p
className="drop-shadow-[0_1.2px_1.2px_rgba(0,0,0,0.8)] font-thin text-xl"
>
{description}
</p>
</div>
</div>
</div>
);
+7 -7
View File
@@ -6,18 +6,18 @@ const Services = () => {
const { t } = useTranslation();
return (
<div className="header-text">
<div className="header-text p-8 md:p-16 mx-4 my-10 rounded-2xl">
<h1>
{t("services.heading.part1")}
<span className="relative inline-block">
{t("services.heading.part2")}{" "}
<img
{t("services.heading.part1")}
<span className="relative inline-block">
{t("services.heading.part2")}
<img
src={Underline}
alt="underline"
className="absolute bottom-0 left-0"
/>
</span>{" "}
</h1>
</span>{" "}
</h1>
<h1>
{t("services.heading.part3")}
</h1>
@@ -9,7 +9,7 @@ const SocialMediaCards = () => {
const { t } = useTranslation();
return (
<div className="h-full flex lg:mt-20 flex-col flex-wrap xl:flex-row mx-4 gap-5">
<div className="h-full flex lg:mt-20 flex-col flex-wrap md:flex-row md:mx-4 gap-5">
<Card
title={t("services.cards.social.card1.title")}
description={t("services.cards.social.card1.description")}
@@ -9,7 +9,7 @@ const WesiteCards = () => {
const { t } = useTranslation();
return (
<div className="h-full flex lg:mt-20 flex-col flex-wrap xl:flex-row mx-4 gap-5">
<div className="h-full flex lg:mt-20 flex-col flex-wrap md:flex-row md:mx-4 gap-5">
<Card
title={t("services.cards.website.card1.title")}
description={t("services.cards.website.card1.description")}
+23
View File
@@ -0,0 +1,23 @@
import React from "react";
interface PremiumButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children: React.ReactNode;
className?: string;
}
const PremiumButton: React.FC<PremiumButtonProps> = ({
children,
className = "",
...props
}) => (
<div className={`gradient-glow-border p-[2px] rounded-full w-full transition-all duration-300 hover:scale-105 ${className}`}>
<button
className={`flex-1 w-full font-medium md:px-8 py-3 text-2xl md:text-3xl rounded-full bg-gradient-to-br from-custom-bglight to-custom-bgdark text-white shadow-lg transition-all duration-300`}
{...props}
>
{children}
</button>
</div>
);
export default PremiumButton;
+2 -2
View File
@@ -17,10 +17,10 @@ i18n
defaultNS: 'common',
backend: {
// translation file path
loadPath: (lng : string, ns : string) => `/locales/${ns}/${lng}.json`,
loadPath: (lng : string,) => `/public/locales/common/${lng}.json`,
},
debug: true,
fallbackLng: "en",
fallbackLng: "en-GB",
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
+46 -3
View File
@@ -1,14 +1,57 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
@import url("https://fonts.googleapis.com/css2?family=Bai+Jamjuree:wght@400;700&display=swap");
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
@apply bg-gradient-to-br from-custom-bglight to-custom-bgdark antialiased min-h-screen text-white;
/* Gradient Glow Border for Hero Button */
.gradient-glow-border {
position: relative;
z-index: 1;
}
.gradient-glow-border::before {
content: '';
position: absolute;
inset: -4px;
border-radius: 9999px;
background: linear-gradient(to bottom right, theme('colors.gold-gradient-light'), theme('colors.gold-gradient-dark'));
filter: blur(8px) brightness(1.18);
opacity: 0.7;
z-index: -1;
transition: filter 0.3s, opacity 0.3s;
}
.gradient-glow-border:hover::before {
filter: blur(10px) brightness(1.7);
opacity: 0.9;
}
body {
@apply bg-gradient-to-br from-custom-bglight to-custom-bgdark antialiased min-h-screen text-white;
font-family: 'Inter', sans-serif;
}
.glass-premium {
@apply bg-white bg-opacity-10 backdrop-blur-lg rounded-2xl shadow-lg border border-white border-opacity-20;
}
.underline-gold {
position: relative;
display: inline-block;
}
.underline-gold::after {
content: "";
display: block;
width: 100%;
height: 5px;
margin-top: 0.18em;
background: linear-gradient(90deg, #E6C674 0%, #C28818 60%, #8C6B1F 100%);
border-radius: 2px;
opacity: 0.85;
}
.hero-text {
@apply font-medium text-5xl lg:text-7xl xl:text-8xl;
}
@@ -36,7 +79,7 @@ body {
}
.gold-text {
@apply bg-clip-text text-transparent bg-gradient-to-br from-gold-light to-gold-dark;
@apply bg-clip-text text-transparent bg-gradient-to-br from-gold-gradient-light to-gold-gradient-dark;
}
.fade-effect {
+18 -17
View File
@@ -2,60 +2,61 @@ import { useTranslation } from "react-i18next";
import Navbar from "../Components/Navbar/Navbar";
import Footer from "../Components/Footer/Footer";
const PP = () => {
const { t } = useTranslation("PP")
const { t } = useTranslation("PP");
return (
<div className="min-h-screen">
<div className="min-h-screen font-inter">
<Navbar />
<div className="container mx-auto px-4 py-12">
<h1 className="text-3xl font-bold text-center mb-6">{t("pp.pageTitle")}</h1>
<div className="shadow-md rounded-lg p-8">
<p className="mb-4">{t("pp.lastUpdated")}</p>
<p className="mb-4">{t("pp.introText")}</p>
<h2 className="text-2xl font-semibold mb-4">{t("pp.pp1.title")}</h2>
<div className="container mx-auto px-4 py-20 flex flex-col min-h-[70vh]">
<h1 className="text-4xl md:text-5xl font-extrabold gold-text text-center mb-6 tracking-wide animate-fadein">{t("pp.pageTitle")}</h1>
<p className="mb-2 text-white text-sm text-center animate-fadein">{t("pp.lastUpdated")}</p>
<p className="mb-10 text-white text-base text-center animate-fadein">{t("pp.introText")}</p>
<div className="w-full max-w-5xl mx-auto">
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("pp.pp1.title")}</h2>
{t("pp.pp1.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<p key={index} className="mb-4 text-white text-base text-left">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("pp.pp2.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("pp.pp2.title")}</h2>
{t("pp.pp2.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("pp.pp3.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("pp.pp3.title")}</h2>
{t("pp.pp3.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("pp.pp4.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("pp.pp4.title")}</h2>
{t("pp.pp4.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("pp.pp5.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("pp.pp5.title")}</h2>
{t("pp.pp5.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("pp.pp6.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("pp.pp6.title")}</h2>
{t("pp.pp6.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("pp.pp7.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("pp.pp7.title")}</h2>
{t("pp.pp7.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("pp.pp8.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("pp.pp8.title")}</h2>
{t("pp.pp8.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
+19 -18
View File
@@ -6,46 +6,47 @@ const TOS = () => {
const { t } = useTranslation("TOS")
return (
<div className="min-h-screen">
<div className="min-h-screen font-inter">
<Navbar />
<div className="container mx-auto px-4 py-12">
<h1 className="text-3xl font-bold text-center mb-6">{t("tos.pageTitle")}</h1>
<div className="shadow-md rounded-lg p-8">
<p className="mb-4">{t("tos.lastUpdated")}</p>
<p className="mb-4">{t("tos.introText")}</p>
<h2 className="text-2xl font-semibold mb-4">{t("tos.tos1.title")}</h2>
<div className="container mx-auto px-4 py-20 flex flex-col min-h-[70vh]">
<h1 className="text-4xl md:text-5xl font-extrabold gold-text text-center mb-6 tracking-wide animate-fadein">{t("tos.pageTitle")}</h1>
<p className="mb-2 text-white text-sm text-center animate-fadein">{t("tos.lastUpdated")}</p>
<p className="mb-10 text-white text-base text-center animate-fadein">{t("tos.introText")}</p>
<div className="w-full max-w-5xl mx-auto">
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("tos.tos1.title")}</h2>
{t("tos.tos1.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<p key={index} className="mb-4 text-white text-base text-left">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("tos.tos2.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("tos.tos2.title")}</h2>
{t("tos.tos2.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<p key={index} className="mb-4 text-white text-base text-left">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("tos.tos3.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("tos.tos3.title")}</h2>
{t("tos.tos3.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<p key={index} className="mb-4 text-white text-base text-left">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("tos.tos4.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("tos.tos4.title")}</h2>
{t("tos.tos4.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<p key={index} className="mb-4 text-white text-base text-left">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("tos.tos5.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("tos.tos5.title")}</h2>
{t("tos.tos5.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<p key={index} className="mb-4 text-white text-base text-left">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
<h2 className="text-2xl font-semibold mb-4">{t("tos.tos6.title")}</h2>
<h2 className="text-xl font-bold mb-3 gold-text text-left">{t("tos.tos6.title")}</h2>
{t("tos.tos6.desc").split("\n\n").map((paragraph, index) => (
<p key={index} className="mb-4">{paragraph.split("\n").map((line, index) => (
<p key={index} className="mb-4 text-white text-base text-left">{paragraph.split("\n").map((line, index) => (
<span key={index}>{line}<br/></span>
))}</p>
))}
+12 -11
View File
@@ -4,22 +4,23 @@ export default {
theme: {
extend: {
fontFamily: {
inter: ['Inter', 'sans-serif'],
baijam: ['Bai Jamjuree', 'sans-serif'],
},
colors: {
'gold-accent': '#C28818',
'gold-light': '#E6C674',
'gold-dark': '#8C6B1F',
'gold-gradient-light': '#FACC97',
'gold-gradient-dark': '#54330F',
'custom-bglight': '#1C1C1F',
'custom-bgdark': '#06060B',
'text-gold': '#FACC97',
'gray-bg': '#1C1C1C',
},
screens: {
1920: "1921px",
},
colors: {
"custom-bglight": "#1C1C1F",
"custom-bgdark": "#06060B",
"text-gold": "#FACC97",
"gold-light": "#FACC97",
"gold-dark": "#54330F",
"gray-bg": "#1C1C1C",
},
fontFamily: {
baijam: ['"Bai Jamjuree"', "sans-serif"],
},
backgroundImage: {
"hero-pattern": "url('./src/assets/HeroImg.svg')",
},