-
- OpenFund
-
+
);
};
diff --git a/src/components/common/layout/header/components/AuthenticatedHeader.tsx b/src/components/common/layout/header/components/AuthenticatedHeader.tsx
index de766c3..7f1bfce 100644
--- a/src/components/common/layout/header/components/AuthenticatedHeader.tsx
+++ b/src/components/common/layout/header/components/AuthenticatedHeader.tsx
@@ -16,8 +16,8 @@ const AuthenticatedHeader = () => {
],
}}
>
-
diff --git a/src/components/common/layout/header/components/UnauthenticatedHeader.tsx b/src/components/common/layout/header/components/UnauthenticatedHeader.tsx
index 68e1740..5207532 100644
--- a/src/components/common/layout/header/components/UnauthenticatedHeader.tsx
+++ b/src/components/common/layout/header/components/UnauthenticatedHeader.tsx
@@ -1,44 +1,27 @@
-import { Button, Modal } from "antd";
-import { LoginModalContent, SignUpModalContent } from "./modal-contents";
-import { useState } from "react";
+import { Modal } from "antd";
+import { LoginModalContent } from "./modal-contents";
+import { useLoginModalStore } from "@/store";
const UnauthenticatedHeader = () => {
- const [isModalOpen, setIsModalOpen] = useState
(false);
- const [isLogin, setIsLogin] = useState(false);
+ const { isOpen, open, close } = useLoginModalStore();
- const handleModalOpen = (login: boolean) => {
- setIsModalOpen(true);
- setIsLogin(login);
- };
-
- const handleCancel = () => {
- setIsModalOpen(false);
- };
return (
<>
- {isLogin ? (
-
- ) : (
-
- )}
+
-
-
-
+
+
>
);
diff --git a/src/components/common/layout/header/components/modal-contents/LoginModalContent.tsx b/src/components/common/layout/header/components/modal-contents/LoginModalContent.tsx
index 99a3e3e..9e386f8 100644
--- a/src/components/common/layout/header/components/modal-contents/LoginModalContent.tsx
+++ b/src/components/common/layout/header/components/modal-contents/LoginModalContent.tsx
@@ -1,112 +1,54 @@
-import { Button, Input, message } from "antd";
import type { LoginModalContentT } from "./types";
-import { GoogleIcon24 } from "../../../../../../assets";
-import { useAuthFormStore, useAuthStore } from "@/store";
-import { usePostLoginService } from "@/api";
+import { GoogleIcon24, YouTubeIcon24 } from "../../../../../../assets";
+import { useGetGoogleLinkService } from "@/api";
-const LoginModalContent: React.FC
= ({
- setIsLogin,
- handleCancel,
-}) => {
- const { data, setData } = useAuthFormStore();
- const { mutate: loginHandler } = usePostLoginService();
- const { login } = useAuthStore();
+interface LoginModalContentProps extends LoginModalContentT {
+ onClose?: () => void;
+}
- const handleClose = () => {
- setData({
- email: "",
- password: "",
- userName: "",
- });
- handleCancel();
- };
+const LoginModalContent: React.FC = ({ onClose }) => {
+ const { data: googleLinkData } = useGetGoogleLinkService();
- const handleChange = (e: React.ChangeEvent) => {
- const { name, value } = e.target;
- setData({ ...data, [name]: value });
- };
-
- const handleLogin = () => {
- loginHandler(
- {
- email: data.email ?? "",
- password: data.password ?? "",
- },
- {
- onSuccess: (res) => {
- message.success("Login successful!");
- login(res.data.accessToken);
- handleClose();
- },
- onError: (err) => {
- const errorRenrerer = () => {
- if (err.response?.data?.errors) {
- return Object.entries(err.response.data.errors).map(
- ([field, messages]) => (
-
- {field}: {messages.join(", ")}
-
- )
- );
- }
-
- return "Login failed. Please try again.";
- };
- message.error(errorRenrerer());
- },
- }
- );
+ const handleGoogleSignIn = () => {
+ if (googleLinkData?.url) {
+ window.location.href = googleLinkData.url;
+ }
};
return (
-
-
Login
-
-
-
-
-
-
-
-
setIsLogin(false)}
+
+
+
შესვლა
+
-
-
+
+
+
-
-
-
+
+
+
+
);
diff --git a/src/components/common/layout/header/components/modal-contents/types.ts b/src/components/common/layout/header/components/modal-contents/types.ts
index a8f564c..9430e2d 100644
--- a/src/components/common/layout/header/components/modal-contents/types.ts
+++ b/src/components/common/layout/header/components/modal-contents/types.ts
@@ -1,4 +1,4 @@
export interface LoginModalContentT {
- setIsLogin: React.Dispatch
>;
- handleCancel: () => void;
+ setIsLogin?: React.Dispatch>;
+ handleCancel?: () => void;
}
diff --git a/src/index.css b/src/index.css
index bd6213e..39e80d9 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,3 +1,122 @@
@tailwind base;
@tailwind components;
-@tailwind utilities;
\ No newline at end of file
+@tailwind utilities;
+
+/* ============================================
+ CSS Variables for Theming
+ ============================================ */
+:root {
+ /* Brand Colors */
+ --color-primary: #b594ff;
+ --color-primary-dark: #a680fa;
+ --color-primary-light: #c1aaf7;
+
+ /* Background Colors */
+ --color-bg-page: #ffffff;
+ --color-bg-cream: #f6f5f2;
+ --color-bg-light: #f9f4f2;
+ --color-bg-card: #ffffff;
+
+ /* Text Colors */
+ --color-text-primary: #202020;
+ --color-text-secondary: #19171c;
+ --color-text-muted: #999999;
+ --color-text-inverse: #ffffff;
+
+ /* Border Colors */
+ --color-border: #e5e7eb;
+ --color-border-light: #f9f4f2;
+
+ /* Layout */
+ --container-max-width: 1650px;
+ --section-padding-y: 50px;
+ --section-padding-x: 109px;
+
+ /* Typography */
+ --font-family-primary: "noto-sans-georgian", sans-serif;
+
+ /* Border Radius */
+ --radius-sm: 4px;
+ --radius-md: 24px;
+ --radius-lg: 30px;
+ --radius-full: 9999px;
+
+ /* Transitions */
+ --transition-fast: 150ms ease;
+ --transition-normal: 200ms ease;
+}
+
+/* Dark Mode Preparation */
+[data-theme="dark"] {
+ --color-bg-page: #0f0f0f;
+ --color-bg-cream: #1a1a1a;
+ --color-bg-light: #242424;
+ --color-bg-card: #1f1f1f;
+
+ --color-text-primary: #f5f5f5;
+ --color-text-secondary: #e0e0e0;
+ --color-text-muted: #888888;
+
+ --color-border: #333333;
+ --color-border-light: #2a2a2a;
+}
+
+@font-face {
+ font-family: "noto-sans-georgian";
+ src: url("/fonts/NotoSansGeorgian-Regular.ttf") format("truetype");
+ font-weight: 400;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: "noto-sans-georgian";
+ src: url("/fonts/NotoSansGeorgian-Medium.ttf") format("truetype");
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: "noto-sans-georgian";
+ src: url("/fonts/NotoSansGeorgian-SemiBold.ttf") format("truetype");
+ font-weight: 600;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: "noto-sans-georgian";
+ src: url("/fonts/NotoSansGeorgian-Bold.ttf") format("truetype");
+ font-weight: 700;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: "noto-sans-georgian";
+ src: url("/fonts/NotoSansGeorgian-ExtraBold.ttf") format("truetype");
+ font-weight: 800;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: "noto-sans-georgian";
+ src: url("/fonts/NotoSansGeorgian-Black.ttf") format("truetype");
+ font-weight: 900;
+ font-style: normal;
+ font-display: swap;
+}
+
+@layer base {
+ body {
+ margin: 0;
+ padding: 0;
+ font-family: "noto-sans-georgian", sans-serif;
+ }
+
+ * {
+ box-sizing: border-box;
+ }
+}
diff --git a/src/main.tsx b/src/main.tsx
index cd17bfb..31a504a 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -7,5 +7,5 @@ import "@ant-design/v5-patch-for-react-19";
createRoot(document.getElementById("root")!).render(
-
+ ,
);
diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx
new file mode 100644
index 0000000..07c09cf
--- /dev/null
+++ b/src/pages/HomePage.tsx
@@ -0,0 +1,325 @@
+import "../styles/main.scss";
+import { useLoginModalStore } from "@/store";
+import { useState } from "react";
+
+// Local asset paths
+const imgDashboard = "/images/dashboard.png";
+const imgLogoIcon = "/images/logo-icon.png";
+const imgCharacter = "/images/character-1.png";
+const imgCharacter2 = "/images/character-2.png";
+
+const faqData = [
+ {
+ id: 1,
+ question: "რამდენია საკომისიო?",
+ answer: (
+ <>
+
+ კრეატორისთვის საკომისიო არის 0%. თანხა ისახება მომენტალურად თქვენს
+ საბანკო ანგარიშზე.
+
+ დონატორისგან ბანკი იღებს მაქსიმუმ 2.5%-ს
+ >
+ ),
+ },
+ {
+ id: 2,
+ question: (
+ <>
+ როგორ გამოვიყენო
+
+ სტრიმზე?
+ >
+ ),
+ answer: ტექსტი
,
+ },
+ {
+ id: 3,
+ question: "რამდენად დაცულია?",
+ answer: ტექსტი
,
+ },
+ {
+ id: 4,
+ question: "როგორ გავიტანო თანხა?",
+ answer: ტექსტი
,
+ },
+ {
+ id: 5,
+ question: (
+ <>
+ რით განსხვავდება სხვა
+
+ პლატფორმებისგან?
+ >
+ ),
+ answer: ტექსტი
,
+ },
+];
+
+const HomePage = () => {
+ const { open: openLoginModal } = useLoginModalStore();
+ const [activeFaqIds, setActiveFaqIds] = useState([1]);
+ const [closingFaqIds, setClosingFaqIds] = useState([]);
+
+ const toggleFaq = (id: number) => {
+ if (activeFaqIds.includes(id)) {
+ setClosingFaqIds((prev) => [...prev, id]);
+ setTimeout(() => {
+ setActiveFaqIds((prev) => prev.filter((faqId) => faqId !== id));
+ setClosingFaqIds((prev) => prev.filter((faqId) => faqId !== id));
+ }, 200);
+ } else {
+ setActiveFaqIds((prev) => [...prev, id]);
+ }
+ };
+ return (
+
+ {/* Hero Section */}
+
+
+ {/* Left Decoration - Character with donation */}
+
+

+
+
გიორგი - 10₾
+
კარგი სტრიმია!
+
+
+
+ {/* Center Content */}
+
+
+ მიიღე დონაციები
+
+ საკომისიოს გარეშე
+
+
+
+
+
+
+
+
+ {/* Right Decoration - Gift goal */}
+
+

+
+
ახალი კომპიუტერი
+
+
+
3000 / 6000 ₾ (50%)
+
+
+
+
+
+ {/* Dashboard Preview */}
+
+
+

+
+
+
+
+ {/* FAQ Section */}
+
+
+ {/* Left side - Title */}
+
+
+
+ ხშირად დასმული კითხვები
+
+
+
+ გაიგეთ როგორ
+
+ მუშაობს ჩვენი
+
+ პლატფორმა
+
+
+
+ {/* Right side - FAQ Items */}
+
+ {faqData.map((faq) => {
+ const isActive = activeFaqIds.includes(faq.id);
+ const isClosing = closingFaqIds.includes(faq.id);
+ return (
+
+
+ {isActive && (
+
+ )}
+
+
+
toggleFaq(faq.id)}
+ style={{ cursor: "pointer" }}
+ >
+
{faq.question}
+
+
+
+ {isActive && (
+
+ {faq.answer}
+
+ )}
+
+ );
+ })}
+
+
+
+
+ {/* Footer */}
+
+
+ );
+};
+
+export default HomePage;
diff --git a/src/pages/index.ts b/src/pages/index.ts
index 431473d..6ba9fc8 100644
--- a/src/pages/index.ts
+++ b/src/pages/index.ts
@@ -1 +1 @@
-// Here will be exported other pages
+export { default as HomePage } from './HomePage';
diff --git a/src/store/index.ts b/src/store/index.ts
index 96a071a..b2abd19 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -1,2 +1,3 @@
export * from "./authFormStore";
export * from "./useAuthStore";
+export * from "./useLoginModalStore";
diff --git a/src/store/useLoginModalStore.ts b/src/store/useLoginModalStore.ts
new file mode 100644
index 0000000..bf4ccc4
--- /dev/null
+++ b/src/store/useLoginModalStore.ts
@@ -0,0 +1,13 @@
+import { create } from "zustand";
+
+interface LoginModalStore {
+ isOpen: boolean;
+ open: () => void;
+ close: () => void;
+}
+
+export const useLoginModalStore = create((set) => ({
+ isOpen: false,
+ open: () => set({ isOpen: true }),
+ close: () => set({ isOpen: false }),
+}));
diff --git a/src/styles/_variables.scss b/src/styles/_variables.scss
new file mode 100644
index 0000000..8b57ba6
--- /dev/null
+++ b/src/styles/_variables.scss
@@ -0,0 +1,70 @@
+// Breakpoints
+$breakpoint-xl: 1440px;
+$breakpoint-lg: 1200px;
+$breakpoint-md: 992px;
+$breakpoint-sm: 768px;
+$breakpoint-xs: 480px;
+
+// Mixins for responsive design
+@mixin desktop-large {
+ @media (max-width: $breakpoint-xl) {
+ @content;
+ }
+}
+
+@mixin desktop {
+ @media (max-width: $breakpoint-lg) {
+ @content;
+ }
+}
+
+@mixin tablet {
+ @media (max-width: $breakpoint-md) {
+ @content;
+ }
+}
+
+@mixin mobile {
+ @media (max-width: $breakpoint-sm) {
+ @content;
+ }
+}
+
+@mixin mobile-small {
+ @media (max-width: $breakpoint-xs) {
+ @content;
+ }
+}
+
+// Container mixin
+@mixin container {
+ width: 100%;
+ max-width: var(--container-max-width);
+ margin: 0 auto;
+ padding-left: var(--section-padding-x);
+ padding-right: var(--section-padding-x);
+
+ @include tablet {
+ padding-left: 40px;
+ padding-right: 40px;
+ }
+
+ @include mobile {
+ padding-left: 20px;
+ padding-right: 20px;
+ }
+}
+
+// Button base mixin
+@mixin button-base {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: var(--radius-full);
+ font-weight: 600;
+ text-transform: uppercase;
+ cursor: pointer;
+ transition: all var(--transition-normal);
+ border: none;
+ text-decoration: none;
+}
diff --git a/src/styles/components/_header.scss b/src/styles/components/_header.scss
new file mode 100644
index 0000000..fac2556
--- /dev/null
+++ b/src/styles/components/_header.scss
@@ -0,0 +1,149 @@
+@use "../variables" as *;
+
+.header {
+ width: 100%;
+ background-color: #f6f5f2;
+ height: 110px;
+ display: flex;
+ align-items: center;
+ padding: 0 48px;
+
+ @include tablet {
+ padding: 0 32px;
+ }
+
+ @include mobile {
+ height: 80px;
+ padding: 0 20px;
+ }
+
+ &__container {
+ width: 100%;
+ max-width: 1650px;
+ margin: 0 auto;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+
+ // Logo section
+ &__logo-section {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ }
+
+ &__logo-img {
+ width: 185px;
+
+ @include mobile {
+ width: 130px;
+ }
+ }
+
+ &__logo-text {
+ font-size: 30px;
+ font-weight: 700;
+ line-height: 72px;
+ color: #000;
+ font-family: "Lota Grotesque Alt 3", sans-serif;
+
+ @include mobile {
+ font-size: 24px;
+ line-height: 1.2;
+ }
+ }
+
+ // Right side section
+ &__actions {
+ display: flex;
+ align-items: center;
+ gap: 20px;
+
+ @include mobile {
+ gap: 16px;
+ }
+ }
+
+ &__settings-btn {
+ width: 52px;
+ height: 52px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 0;
+ border: 1px solid rgba(0, 0, 0, 0.65);
+ border-radius: 100px;
+
+ @include mobile {
+ width: 40px;
+ height: 40px;
+ svg {
+ width: 15px;
+ }
+ }
+
+ img {
+ width: 100%;
+ height: 100%;
+ }
+ }
+
+ // Authenticated user profile
+ &__profile {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ box-shadow:
+ 0 4px 6px -1px rgba(0, 0, 0, 0.1),
+ 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 2px solid #2563eb;
+ cursor: pointer;
+ background: white;
+ }
+
+ &__profile-letter {
+ font-size: 16px;
+ font-weight: 700;
+ color: #000;
+ }
+
+ // Unauthenticated buttons
+ &__auth-buttons {
+ display: flex;
+ align-items: center;
+ gap: 24px;
+ }
+
+ &__login-btn {
+ background-color: #19171c;
+ color: white;
+ font-weight: 600;
+ font-size: 18px;
+ text-transform: uppercase;
+ padding: 0 36px;
+ height: 52px;
+ border-radius: 100px;
+ border: none;
+ cursor: pointer;
+ transition: background-color 0.2s ease;
+ font-family: "noto-sans-georgian", sans-serif;
+ font-feature-settings: "case" on;
+
+ &:hover {
+ background-color: #000;
+ }
+
+ @include mobile {
+ font-size: 16px;
+ height: 44px;
+ padding: 0 20px;
+ }
+ }
+}
diff --git a/src/styles/components/_login-modal.scss b/src/styles/components/_login-modal.scss
new file mode 100644
index 0000000..f386aad
--- /dev/null
+++ b/src/styles/components/_login-modal.scss
@@ -0,0 +1,111 @@
+@use "../variables" as *;
+
+.login-modal {
+ &__content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 29px 33px 40px;
+ gap: 51px;
+ }
+
+ &__header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ }
+
+ &__title {
+ font-family: "Noto Sans Georgian", sans-serif;
+ font-weight: 600;
+ font-size: 24px;
+ line-height: 33px;
+ font-feature-settings: "case" on;
+ text-transform: uppercase;
+ color: #19171c;
+ margin: 0;
+ }
+
+ &__close-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 40px;
+ height: 40px;
+ border: 1px solid #595959;
+ border-radius: 100px;
+ background: transparent;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background: #f5f5f5;
+ }
+
+ svg {
+ width: 12px;
+ height: 12px;
+ }
+ }
+
+ &__buttons {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 25px;
+ width: 100%;
+ max-width: 408px;
+ }
+
+ &__btn {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ padding: 18px 24px;
+ gap: 10px;
+ width: 100%;
+ height: 64px;
+ border: 1px solid #818382;
+ border-radius: 100px;
+ background: transparent;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background: #f5f5f5;
+ border-color: #595959;
+ }
+
+ span {
+ font-family: "Noto Sans Georgian", sans-serif;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 100%;
+ letter-spacing: 0.04em;
+ color: #000000;
+ }
+
+ svg {
+ flex-shrink: 0;
+ }
+ }
+}
+
+.ant-modal.login-modal-wrapper {
+ .ant-modal-content {
+ background: #ffffff;
+ border-radius: 24px;
+ padding: 0;
+ overflow: hidden;
+ }
+
+ .ant-modal-body {
+ padding: 0;
+ }
+
+ .ant-modal-close {
+ display: none;
+ }
+}
diff --git a/src/styles/main.scss b/src/styles/main.scss
new file mode 100644
index 0000000..47c67ff
--- /dev/null
+++ b/src/styles/main.scss
@@ -0,0 +1,9 @@
+// Variables & Mixins
+@use "./variables" as *;
+
+// Components
+@use "./components/header";
+@use "./components/login-modal";
+
+// Pages
+@use "./pages/home";
diff --git a/src/styles/pages/_home.scss b/src/styles/pages/_home.scss
new file mode 100644
index 0000000..d70917f
--- /dev/null
+++ b/src/styles/pages/_home.scss
@@ -0,0 +1,681 @@
+@use "../variables" as *;
+
+.home {
+ width: 100%;
+ background-color: var(--color-bg-page);
+
+ // ==========================================
+ // HERO SECTION
+ // ==========================================
+ &__hero {
+ position: relative;
+ width: 100%;
+ background: linear-gradient(
+ 180deg,
+ var(--color-bg-cream) 11%,
+ var(--color-bg-cream) 47%,
+ var(--color-bg-page) 100%
+ );
+ overflow: hidden;
+ padding-top: 80px;
+
+ @include mobile {
+ padding-top: 40px;
+ }
+ }
+
+ &__hero-container {
+ @include container;
+ display: grid;
+ grid-template-columns: 200px 1fr 260px;
+ gap: 20px;
+ align-items: start;
+
+ @include tablet {
+ grid-template-columns: 1fr;
+ gap: 40px;
+ }
+ }
+
+ // Left decoration (character with donation)
+ &__hero-decoration {
+ position: relative;
+
+ &--left {
+ @include tablet {
+ display: none;
+ }
+ }
+
+ &--right {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ @include tablet {
+ display: none;
+ }
+ }
+ }
+
+ &__character-img {
+ display: block;
+ width: 188px;
+ height: 142px;
+ }
+
+ &__donation-bubble {
+ margin-top: 20px;
+ text-align: center;
+ }
+
+ &__donation-name {
+ font-weight: 700;
+ font-size: 19px;
+ font-feature-settings: "case" on;
+ color: var(--color-primary-dark);
+ margin-bottom: 4px;
+ }
+
+ &__donation-message {
+ font-size: 14px;
+ color: var(--color-text-primary);
+ }
+
+ // Right decoration (gift goal)
+ &__gift-icon {
+ width: 82px;
+ height: 114px;
+ margin-bottom: 20px;
+ }
+
+ &__goal-box {
+ text-align: center;
+ }
+
+ &__goal-title {
+ font-weight: 600;
+ font-size: 15px;
+ font-feature-settings: "case" on;
+ color: var(--color-text-primary);
+ margin-bottom: 8px;
+ }
+
+ &__goal-progress {
+ width: 237px;
+ height: 38px;
+ background: var(--color-bg-card);
+ border-radius: var(--radius-full);
+ position: relative;
+ overflow: hidden;
+ }
+
+ &__goal-bar {
+ position: absolute;
+ left: 0;
+ top: 0;
+ height: 100%;
+ width: 50%;
+ background: var(--color-primary);
+ border-radius: var(--radius-full) 0 0 var(--radius-full);
+ }
+
+ &__goal-text {
+ position: absolute;
+ inset: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 600;
+ font-size: 14px;
+ text-transform: uppercase;
+ color: var(--color-text-primary);
+ }
+
+ // Center content
+ &__hero-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+ }
+
+ &__hero-title {
+ font-weight: 900;
+ font-size: 57px;
+ line-height: 1.26;
+ text-transform: uppercase;
+ color: var(--color-text-primary);
+ margin: 0 0 30px;
+ font-feature-settings: "case" on;
+
+ @media (min-width: 1600px) {
+ font-size: 64px;
+ }
+
+ @include desktop {
+ font-size: 48px;
+ }
+
+ @include tablet {
+ font-size: 40px;
+ margin-bottom: 40px;
+ }
+
+ @include mobile {
+ font-size: 32px;
+ margin-bottom: 30px;
+ }
+ }
+
+ &__hero-buttons {
+ display: flex;
+ align-items: center;
+ gap: 23px;
+
+ @include mobile {
+ flex-direction: column;
+ gap: 16px;
+ width: 100%;
+ }
+ }
+
+ &__btn {
+ @include button-base;
+ height: 62px;
+ padding: 16px 14px;
+ font-size: 20px;
+ font-feature-settings: "case" on;
+
+ @include mobile {
+ width: 100%;
+ height: 56px;
+ font-size: 18px;
+ }
+
+ &--primary {
+ width: 244px;
+ background-color: var(--color-primary);
+ color: var(--color-text-primary);
+
+ @include mobile {
+ width: 100%;
+ }
+ }
+
+ &--secondary {
+ width: 277px;
+ background-color: var(--color-bg-card);
+ border: 1px solid var(--color-border);
+ color: var(--color-text-primary);
+ font-weight: 500;
+
+ @include mobile {
+ width: 100%;
+ }
+ }
+ }
+
+ // Dashboard preview
+ &__dashboard-preview {
+ position: relative;
+ width: 100%;
+ margin-top: 70px;
+ padding-bottom: 100px;
+
+ @include tablet {
+ margin-top: 40px;
+ padding-bottom: 60px;
+ }
+ }
+
+ &__dashboard-img {
+ position: relative;
+ display: block;
+ width: 100%;
+ margin: 0 auto;
+ border-radius: var(--radius-lg);
+ overflow: hidden;
+
+ img {
+ width: 100%;
+ height: auto;
+ display: block;
+ border-radius: var(--radius-lg);
+ }
+ }
+
+ // ==========================================
+ // FAQ SECTION
+ // ==========================================
+ &__faq {
+ padding: var(--section-padding-y) 0;
+
+ @include tablet {
+ padding: 20px 0;
+ }
+ }
+
+ &__faq-container {
+ @include container;
+ display: flex;
+ justify-content: space-between;
+ gap: 40px;
+
+ @include tablet {
+ flex-direction: column;
+ }
+ }
+
+ &__faq-header {
+ max-width: 50%;
+ @include desktop {
+ width: 300px;
+ max-width: 100%;
+ }
+
+ @include tablet {
+ width: 100%;
+ }
+ }
+
+ &__faq-badge {
+ display: inline-block;
+ background-color: var(--color-primary);
+ padding: 2px 14px;
+ border-radius: var(--radius-md);
+ margin-bottom: 15px;
+
+ @include mobile {
+ margin-bottom: 24px;
+ }
+ }
+
+ &__faq-badge-text {
+ font-weight: 500;
+ font-size: 16px;
+ line-height: 26px;
+ color: var(--color-text-primary);
+ }
+
+ &__faq-title {
+ font-weight: 700;
+ font-size: 50px;
+ line-height: 1.4;
+ text-transform: uppercase;
+ color: var(--color-text-primary);
+ margin: 0;
+ font-feature-settings: "case" on;
+
+ @include desktop {
+ font-size: 40px;
+ }
+
+ @include tablet {
+ font-size: 36px;
+ }
+
+ @include mobile {
+ font-size: 28px;
+ }
+ }
+
+ &__faq-list {
+ display: flex;
+ flex-direction: column;
+ gap: 25px;
+ width: 50%;
+
+ @include mobile {
+ gap: 15px;
+ width: 100%;
+ }
+ }
+
+ &__faq-item {
+ &--active {
+ .home__faq-question {
+ color: var(--color-text-primary);
+ }
+ }
+
+ &--closing {
+ .home__faq-question {
+ color: var(--color-text-muted);
+ }
+ }
+ }
+
+ &__faq-divider {
+ position: relative;
+ width: 100%;
+ height: 4px;
+ background-color: var(--color-border-light);
+ border-radius: 2px;
+ margin-bottom: 25px;
+ overflow: hidden;
+
+ @include mobile {
+ margin-bottom: 15px;
+ }
+ }
+
+ &__faq-divider-progress {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ background-color: var(--color-primary);
+ border-radius: 2px;
+ animation: faqProgressBar 0.4s ease-out forwards;
+
+ &--closing {
+ animation: faqProgressBarClose 0.4s ease-out forwards;
+ }
+ }
+
+ @keyframes faqProgressBar {
+ from {
+ width: 0%;
+ }
+ to {
+ width: 100%;
+ }
+ }
+
+ @keyframes faqProgressBarClose {
+ from {
+ width: 100%;
+ }
+ to {
+ width: 0%;
+ }
+ }
+
+ &__faq-row {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 20px;
+ padding: 5px 0;
+ }
+
+ &__faq-question {
+ font-weight: 600;
+ font-size: 30px;
+ line-height: 1.5;
+ text-transform: uppercase;
+ color: var(--color-text-muted);
+ margin: 0;
+ font-feature-settings: "case" on;
+
+ @include desktop {
+ font-size: 24px;
+ }
+
+ @include mobile {
+ font-size: 20px;
+ }
+ }
+
+ &__faq-toggle {
+ width: 44px;
+ height: 44px;
+ padding: 0;
+ cursor: pointer;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ border: 1px solid #9a98a2;
+ border-radius: 17px;
+ transition: box-shadow 0.3s ease;
+
+ img {
+ width: 100%;
+ height: 100%;
+ }
+
+ @include mobile {
+ width: 36px;
+ height: 36px;
+ border-radius: 14px;
+ }
+
+ &--active {
+ box-shadow: 0.3rem 0.3rem 0.5rem #c6b9ed66;
+ border: none;
+ svg {
+ transform: rotate(180deg);
+ animation: fadeRotate 0.2s ease-out forwards;
+ }
+ }
+
+ &--closing {
+ svg {
+ animation: fadeRotateBack 0.2s ease-out forwards;
+ }
+ }
+ }
+
+ @keyframes fadeRotate {
+ 0% {
+ opacity: 0;
+ transform: rotate(0deg);
+ }
+ 100% {
+ opacity: 1;
+ transform: rotate(180deg);
+ }
+ }
+
+ @keyframes fadeRotateBack {
+ 0% {
+ opacity: 1;
+ transform: rotate(180deg);
+ }
+ 100% {
+ opacity: 0;
+ transform: rotate(0deg);
+ }
+ }
+
+ &__faq-answer {
+ position: relative;
+ margin-top: 18px;
+ font-size: 15px;
+ line-height: 1.57;
+ color: var(--color-text-primary);
+ overflow: hidden;
+
+ @include mobile {
+ margin-top: 10px;
+ }
+
+ p {
+ margin: 0 0 1em;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ @include mobile {
+ font-size: 14px;
+ }
+
+ &::after {
+ content: "";
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: #ffffff;
+ animation: faqAnswerReveal 0.4s ease-out forwards;
+ }
+
+ &--closing::after {
+ animation: faqAnswerHide 0.4s ease-out forwards;
+ }
+ }
+
+ @keyframes faqAnswerReveal {
+ from {
+ top: 0;
+ }
+ to {
+ top: 100%;
+ }
+ }
+
+ @keyframes faqAnswerHide {
+ from {
+ top: 100%;
+ bottom: auto;
+ height: 100%;
+ }
+ to {
+ top: 0;
+ bottom: auto;
+ height: 100%;
+ }
+ }
+
+ // ==========================================
+ // FOOTER SECTION
+ // ==========================================
+ &__footer {
+ background-color: var(--color-primary-light);
+ padding: 56px 80px 20px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-top: 100px;
+
+ @include mobile {
+ padding: 40px 20px;
+ }
+ }
+
+ &__footer-card {
+ width: 100%;
+ max-width: 1650px;
+ background-color: var(--color-bg-card);
+ border-radius: var(--radius-md);
+ padding: 38px 37px;
+
+ @include tablet {
+ padding: 30px 24px;
+ }
+
+ @include mobile {
+ padding: 24px 20px;
+ }
+ }
+
+ &__footer-content {
+ display: grid;
+ grid-template-columns: auto 1fr 1fr 1fr;
+ gap: 40px;
+
+ @include tablet {
+ grid-template-columns: repeat(2, 1fr);
+ }
+
+ @include mobile {
+ grid-template-columns: 1fr;
+ gap: 32px;
+ }
+ }
+
+ &__footer-logo {
+ width: 39px;
+ height: 36px;
+ }
+
+ &__footer-section {
+ min-width: 150px;
+ }
+
+ &__footer-heading {
+ font-weight: 600;
+ font-size: 20px;
+ line-height: 1.4;
+ text-transform: uppercase;
+ color: var(--color-text-primary);
+ margin: 0 0 14px;
+
+ @include mobile {
+ font-size: 18px;
+ margin-bottom: 10px;
+ }
+ }
+
+ &__footer-links {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ &__footer-link {
+ font-size: 17px;
+ line-height: 1.65;
+ color: var(--color-text-primary);
+ text-decoration: none;
+ transition: color var(--transition-fast);
+
+ &:hover {
+ color: var(--color-primary);
+ }
+
+ @include mobile {
+ font-size: 15px;
+ }
+ }
+
+ &__footer-social {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ }
+
+ &__social-link {
+ width: 43px;
+ height: 43px;
+ border: 1px solid #cdcbd0;
+ border-radius: 16px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ &:hover {
+ opacity: 0.8;
+ }
+
+ img {
+ width: 100%;
+ height: 100%;
+ }
+
+ @include mobile {
+ width: 38px;
+ height: 38px;
+ }
+ }
+
+ &__copyright {
+ margin-top: 20px;
+ font-weight: 600;
+ font-size: 16px;
+ color: var(--color-text-primary);
+ text-align: center;
+
+ @include mobile {
+ font-size: 14px;
+ margin-top: 16px;
+ }
+ }
+}
diff --git a/tailwind.config.js b/tailwind.config.js
index 89a305e..8c5422a 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,11 +1,48 @@
/** @type {import('tailwindcss').Config} */
export default {
- content: [
- "./index.html",
- "./src/**/*.{js,ts,jsx,tsx}",
- ],
+ content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
- extend: {},
+ extend: {
+ colors: {
+ primary: {
+ DEFAULT: "var(--color-primary)",
+ dark: "var(--color-primary-dark)",
+ light: "var(--color-primary-light)",
+ },
+ background: {
+ page: "var(--color-bg-page)",
+ cream: "var(--color-bg-cream)",
+ light: "var(--color-bg-light)",
+ card: "var(--color-bg-card)",
+ },
+ text: {
+ primary: "var(--color-text-primary)",
+ secondary: "var(--color-text-secondary)",
+ muted: "var(--color-text-muted)",
+ inverse: "var(--color-text-inverse)",
+ },
+ border: {
+ DEFAULT: "var(--color-border)",
+ light: "var(--color-border-light)",
+ },
+ },
+ fontFamily: {
+ primary: ["var(--font-family-primary)"],
+ },
+ borderRadius: {
+ sm: "var(--radius-sm)",
+ md: "var(--radius-md)",
+ lg: "var(--radius-lg)",
+ full: "var(--radius-full)",
+ },
+ transitionDuration: {
+ fast: "var(--transition-fast)",
+ normal: "var(--transition-normal)",
+ },
+ maxWidth: {
+ container: "var(--container-max-width)",
+ },
+ },
},
plugins: [],
-}
\ No newline at end of file
+};