diff --git a/frontend/public/images/hero_background.png b/frontend/public/images/hero_background.png new file mode 100644 index 0000000..70685f8 Binary files /dev/null and b/frontend/public/images/hero_background.png differ diff --git a/frontend/src/components/Header/Header.module.css b/frontend/src/components/Header/Header.module.css new file mode 100644 index 0000000..ffa5264 --- /dev/null +++ b/frontend/src/components/Header/Header.module.css @@ -0,0 +1,86 @@ +.header { + height: 96px; + background-color: #fff; + border-bottom: 1px solid #e8e8e8; +} + +.logo { + flex-shrink: 0; + margin: 0; + font-size: 28px; + font-weight: 700; + line-height: 1; + letter-spacing: -1.5px; +} + +.navigation { + display: flex; + align-items: center; + gap: 32px; + margin-left: 40px; +} + +.navigationItem { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 0; + border: 0; + background: transparent; + color: #111; + font-family: inherit; + font-size: 15px; + font-weight: 400; + line-height: 1; + text-decoration: none; + white-space: nowrap; + cursor: pointer; + transition: opacity 0.2s ease; +} + +.navigationItem:hover { + opacity: 0.6; +} + +.arrow { + font-size: 9px; + line-height: 1; +} + +.search { + display: flex; + align-items: center; + width: 320px; + height: 44px; + margin-left: 40px; + padding: 0 16px; + border-radius: 24px; + background-color: #f5f5f5; +} + +.searchIcon { + flex-shrink: 0; + width: 20px; + height: 20px; + color: #666; +} + +.searchInput { + width: 100%; + margin-left: 10px; + padding: 0; + border: 0; + outline: none; + background: transparent; + color: #111; + font-family: inherit; + font-size: 14px; +} + +.searchInput::placeholder { + color: #777; +} + +.searchInput::-webkit-search-cancel-button { + cursor: pointer; +} \ No newline at end of file diff --git a/frontend/src/components/Header/Header.tsx b/frontend/src/components/Header/Header.tsx new file mode 100644 index 0000000..8da2178 --- /dev/null +++ b/frontend/src/components/Header/Header.tsx @@ -0,0 +1,72 @@ +import { useState } from 'react' + +import { navigationItems } from '../../shared/navigation/navigation.data' +import styles from './Header.module.css' + +function Header() { + const [isShopOpen, setIsShopOpen] = useState(false) + + return ( +
+
+

shop.co

+ + + +
+ + + +
+
+
+ ) +} + +export default Header \ No newline at end of file diff --git a/frontend/src/components/Hero/Hero.module.css b/frontend/src/components/Hero/Hero.module.css new file mode 100644 index 0000000..702bf2a --- /dev/null +++ b/frontend/src/components/Hero/Hero.module.css @@ -0,0 +1,172 @@ +.hero { + background-color: #F2F0F1; /* Светло-серый фон как на макете */ + min-height: 90vh; + padding: 40px 0; + display: flex; + align-items: center; + font-family: 'Inter', sans-serif; /* Или ваш шрифт */ +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + gap: 40px; +} + +/* Левая часть */ +.left { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; +} + +.headline { + font-size: 64px; + font-weight: 800; + line-height: 1.1; + text-transform: uppercase; + margin-bottom: 24px; + color: #000; + letter-spacing: -1px; +} + +.description { + font-size: 16px; + line-height: 1.6; + color: #666; + margin-bottom: 32px; + max-width: 450px; +} + +.ctaButton { + background-color: #000; + color: #fff; + border: none; + padding: 16px 48px; + font-size: 16px; + font-weight: 500; + border-radius: 50px; + cursor: pointer; + transition: transform 0.2s ease, background-color 0.2s; + width: fit-content; + margin-bottom: 60px; /* Отступ до статистики */ +} + +.ctaButton:hover { + background-color: #333; + transform: translateY(-2px); +} + +/* Статистика */ +.stats { + display: flex; + align-items: center; + gap: 40px; +} + +.statItem { + display: flex; + flex-direction: column; +} + +.statNumber { + font-size: 32px; + font-weight: 700; + color: #000; +} + +.statLabel { + font-size: 14px; + color: #888; + margin-top: 4px; +} + +.statDivider { + width: 1px; + height: 40px; + background-color: #ddd; +} + +/* Правая часть */ +.right { + flex: 1; + position: relative; + height: 600px; /* Фиксированная высота для контейнера */ + display: flex; + justify-content: center; + align-items: center; +} + +.heroImage { + width: 100%; + height: 100%; + object-fit: contain; /* Или cover, в зависимости от желаемого эффекта */ + object-position: center; + /* Маска для плавного перехода, если нужно, но здесь просто картинка */ +} + +/* Декоративные звездочки */ +.sparkle { + position: absolute; + color: #000; + z-index: 10; +} + +.sparkleTop { + top: 50px; + right: 50px; + width: 60px; + height: 60px; +} + +.sparkleMiddle { + top: 40%; + left: -20px; + width: 40px; + height: 40px; +} + +/* Адаптивность */ +@media (max-width: 968px) { + .container { + flex-direction: column; + text-align: center; + } + + .left { + align-items: center; + } + + .description { + max-width: 100%; + } + + .stats { + flex-direction: column; + gap: 20px; + } + + .statDivider { + width: 40px; + height: 1px; + } + + .headline { + font-size: 40px; + } + + .right { + height: 400px; + width: 100%; + } + + .sparkleMiddle { + display: none; /* Скрываем лишние элементы на мобильных */ + } +} \ No newline at end of file diff --git a/frontend/src/components/Hero/Hero.tsx b/frontend/src/components/Hero/Hero.tsx new file mode 100644 index 0000000..fab68c4 --- /dev/null +++ b/frontend/src/components/Hero/Hero.tsx @@ -0,0 +1,60 @@ +import styles from './Hero.module.css' + +const SparkleIcon = ({ className }: { className?: string }) => ( + + + +); + +function Hero() { + return ( +
+
+
+

+ Find clothes
that matches
your style +

+

+ Browse through our diverse range of meticulously crafted garments, + designed to bring out your individuality and cater to your sense of style. +

+ + +
+
+ 200+ + International Brands +
+
+
+ 2,000+ + High-Quality Products +
+
+
+ 30,000+ + Happy Customers +
+
+
+ +
+ + + Fashion models +
+
+
+ ) +} + +export default Hero \ No newline at end of file diff --git a/frontend/src/pages/Home/Home.tsx b/frontend/src/pages/Home/Home.tsx index 12c443c..9882555 100644 --- a/frontend/src/pages/Home/Home.tsx +++ b/frontend/src/pages/Home/Home.tsx @@ -1,9 +1,15 @@ import AnnouncementBar from '../../components/AnnouncementBar/AnnouncementBar' +import Header from '../../components/Header/Header' +import Hero from '../../components/Hero/Hero' function Home() { return ( <> + +
+ + ) } diff --git a/frontend/src/shared/navigation/navigation.data.ts b/frontend/src/shared/navigation/navigation.data.ts new file mode 100644 index 0000000..6137b0b --- /dev/null +++ b/frontend/src/shared/navigation/navigation.data.ts @@ -0,0 +1,33 @@ +import type { NavigationItem } from './navigation.types' + +export const navigationItems: NavigationItem[] = [ + { + label: 'Shop', + children: [ + { + label: 'All', + href: '/shop', + }, + { + label: 'Men', + href: '/shop/men', + }, + { + label: 'Women', + href: '/shop/women', + }, + ], + }, + { + label: 'On Sale', + href: '/sale', + }, + { + label: 'New Arrivals', + href: '/new-arrivals', + }, + { + label: 'Brands', + href: '/brands', + }, +] \ No newline at end of file diff --git a/frontend/src/shared/navigation/navigation.types.ts b/frontend/src/shared/navigation/navigation.types.ts new file mode 100644 index 0000000..5cd55cb --- /dev/null +++ b/frontend/src/shared/navigation/navigation.types.ts @@ -0,0 +1,5 @@ +export type NavigationItem = { + label: string + href?: string + children?: NavigationItem[] +} \ No newline at end of file diff --git a/frontend/src/styles/globals.css b/frontend/src/styles/globals.css index 76d66b2..13db9a4 100644 --- a/frontend/src/styles/globals.css +++ b/frontend/src/styles/globals.css @@ -16,4 +16,15 @@ body { background-color: #fff; color: #000; font-family: "integralcf", sans-serif; +} + +.container { + width: 100%; + max-width: 1240px; + height: 100%; + margin: 0 auto; + padding: 0 24px; + + display: flex; + align-items: center; } \ No newline at end of file