diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts index 1511519..9edff1c 100644 --- a/apps/web/next-env.d.ts +++ b/apps/web/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import './.next/types/routes.d.ts'; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/web/src/app/about/page.module.scss b/apps/web/src/app/about/page.module.scss new file mode 100644 index 0000000..1740061 --- /dev/null +++ b/apps/web/src/app/about/page.module.scss @@ -0,0 +1,53 @@ +.container { + max-width: 800px; + margin: 0 auto; + padding: var(--space-lg); +} + +.title { + font-size: 28px; + font-weight: 700; + color: var(--color-slate-900); + margin-bottom: var(--space-xl); +} + +.content { + display: flex; + flex-direction: column; + gap: var(--space-md); + font-size: 15px; + line-height: 1.7; + color: var(--color-slate-700); + margin-bottom: var(--space-2xl); +} + +.stats { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: var(--space-md); + padding: var(--space-xl); + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-lg); + margin-bottom: var(--space-2xl); + + @media (max-width: 640px) { + grid-template-columns: repeat(2, 1fr); + } +} + +.statItem { + text-align: center; +} + +.statNum { + font-size: 28px; + font-weight: 800; + color: var(--color-orange-500); +} + +.statLabel { + font-size: 12px; + color: var(--color-text-muted); + margin-top: 4px; +} diff --git a/apps/web/src/app/about/page.tsx b/apps/web/src/app/about/page.tsx new file mode 100644 index 0000000..707b754 --- /dev/null +++ b/apps/web/src/app/about/page.tsx @@ -0,0 +1,53 @@ +import { Breadcrumb } from '@/components/Breadcrumb/Breadcrumb'; +import { TrustStrip } from '@/components/TrustStrip/TrustStrip'; +import styles from './page.module.scss'; + +export const metadata = { + title: 'О компании | PAN-PROM', +}; + +export default function AboutPage() { + return ( + <> +
+ +

О компании PAN-PROM

+ +
+

+ PAN-PROM — поставщик промышленного оборудования и комплектующих от + ведущих европейских производителей. Мы специализируемся на + гидравлике, пневматике, системах автоматизации (АСУ) и запасных + частях. +

+

+ Наша компания работает напрямую с такими брендами, как Bosch Rexroth, + Festo, Siemens, Parker, HYDAC, Beckhoff и многими другими. Это + гарантирует оригинальность продукции и оптимальные сроки поставки. +

+

+ Склады в Берлине и Гуанчжоу позволяют нам обеспечивать быструю + логистику и конкурентные цены для наших клиентов. +

+
+ +
+ {[ + { num: '50+', label: 'Европейских брендов' }, + { num: '10 000+', label: 'Позиций в каталоге' }, + { num: '14 дней', label: 'Средний срок поставки' }, + { num: '100%', label: 'Оригинальная продукция' }, + ].map((s, i) => ( +
+
{s.num}
+
{s.label}
+
+ ))} +
+
+ + + ); +} diff --git a/apps/web/src/app/brand/[id]/page.module.scss b/apps/web/src/app/brand/[id]/page.module.scss new file mode 100644 index 0000000..44b4580 --- /dev/null +++ b/apps/web/src/app/brand/[id]/page.module.scss @@ -0,0 +1,67 @@ +.container { + max-width: var(--max-width); + margin: 0 auto; + padding: var(--space-lg); +} + +.brandHeader { + display: flex; + align-items: center; + gap: var(--space-md); + margin: var(--space-lg) 0; + padding-bottom: var(--space-lg); + border-bottom: 1px solid var(--color-border); +} + +.logoBox { + width: 64px; + height: 64px; + border-radius: var(--border-radius-lg); + background: var(--color-slate-100); + display: flex; + align-items: center; + justify-content: center; + font-weight: 800; + font-size: 22px; + color: var(--color-slate-600); + flex-shrink: 0; +} + +.brandName { + font-size: 28px; + font-weight: 700; + color: var(--color-slate-900); +} + +.brandMeta { + font-size: 14px; + color: var(--color-text-muted); + margin-top: 4px; +} + +.sectionTitle { + font-size: 18px; + font-weight: 600; + color: var(--color-slate-800); + margin-bottom: var(--space-md); +} + +.grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--space-md); + + @media (max-width: 1024px) { + grid-template-columns: repeat(2, 1fr); + } + + @media (max-width: 640px) { + grid-template-columns: 1fr; + } +} + +.empty { + text-align: center; + color: var(--color-text-muted); + padding: var(--space-2xl) 0; +} diff --git a/apps/web/src/app/brand/[id]/page.tsx b/apps/web/src/app/brand/[id]/page.tsx new file mode 100644 index 0000000..35b945c --- /dev/null +++ b/apps/web/src/app/brand/[id]/page.tsx @@ -0,0 +1,71 @@ +import { notFound } from 'next/navigation'; +import { brands } from '@/data/brands'; +import { products } from '@/data/products'; +import { Breadcrumb } from '@/components/Breadcrumb/Breadcrumb'; +import { ProductCard } from '@/components/ProductCard/ProductCard'; +import styles from './page.module.scss'; + +export function generateStaticParams() { + return brands.map((b) => ({ id: String(b.id) })); +} + +export async function generateMetadata({ + params, +}: { + params: Promise<{ id: string }>; +}) { + const { id } = await params; + const brand = brands.find((b) => b.id === Number(id)); + return { + title: brand ? `${brand.name} | PAN-PROM` : 'Бренд | PAN-PROM', + }; +} + +export default async function BrandPage({ + params, +}: { + params: Promise<{ id: string }>; +}) { + const { id } = await params; + const brand = brands.find((b) => b.id === Number(id)); + if (!brand) notFound(); + + const brandProducts = products.filter((p) => p.brand === brand.name); + + return ( +
+ + +
+
{brand.logo}
+
+

{brand.name}

+
+ {brand.country} · {brand.category} +
+
+
+ +

+ Продукция ({brandProducts.length}) +

+
+ {brandProducts.map((p) => ( + + ))} +
+ + {brandProducts.length === 0 && ( +

+ Продукция этого бренда скоро появится в каталоге. +

+ )} +
+ ); +} diff --git a/apps/web/src/app/cart/layout.tsx b/apps/web/src/app/cart/layout.tsx new file mode 100644 index 0000000..2a789b2 --- /dev/null +++ b/apps/web/src/app/cart/layout.tsx @@ -0,0 +1,11 @@ +export const metadata = { + title: 'Корзина | PAN-PROM', +}; + +export default function CartLayout({ + children, +}: { + children: React.ReactNode; +}) { + return children; +} diff --git a/apps/web/src/app/cart/page.module.scss b/apps/web/src/app/cart/page.module.scss new file mode 100644 index 0000000..205e54f --- /dev/null +++ b/apps/web/src/app/cart/page.module.scss @@ -0,0 +1,122 @@ +.container { + max-width: var(--max-width); + margin: 0 auto; + padding: var(--space-lg); +} + +.title { + font-size: 28px; + font-weight: 700; + color: var(--color-slate-900); + margin-bottom: var(--space-lg); +} + +.empty { + text-align: center; + padding: var(--space-2xl) 0; + color: var(--color-text-muted); + + p { + margin-bottom: var(--space-md); + font-size: 16px; + } +} + +.items { + display: flex; + flex-direction: column; + gap: 1px; + background: var(--color-border); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-lg); + overflow: hidden; +} + +.item { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--space-md) var(--space-lg); + background: var(--color-surface); +} + +.itemSku { + font-family: var(--font-mono); + font-size: 12px; + color: var(--color-orange-500); + font-weight: 600; +} + +.itemName { + font-size: 14px; + font-weight: 600; + color: var(--color-slate-800); + margin-top: 2px; +} + +.itemBrand { + font-size: 12px; + color: var(--color-text-muted); + margin-top: 2px; +} + +.itemActions { + display: flex; + align-items: center; + gap: var(--space-md); +} + +.qtyControl { + display: flex; + align-items: center; + gap: 8px; + border: 1px solid var(--color-border); + border-radius: var(--border-radius-sm); + padding: 4px; +} + +.qtyBtn { + background: none; + border: none; + padding: 4px; + display: flex; + cursor: pointer; + color: var(--color-slate-500); + + &:hover { + color: var(--color-slate-800); + } +} + +.qty { + font-size: 14px; + font-weight: 600; + min-width: 24px; + text-align: center; +} + +.removeBtn { + background: none; + border: none; + padding: 4px; + cursor: pointer; + + &:hover { + opacity: 0.7; + } +} + +.footer { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: var(--space-lg); + padding-top: var(--space-lg); + border-top: 1px solid var(--color-border); +} + +.totalLabel { + font-size: 14px; + font-weight: 600; + color: var(--color-slate-600); +} diff --git a/apps/web/src/app/cart/page.tsx b/apps/web/src/app/cart/page.tsx new file mode 100644 index 0000000..0508764 --- /dev/null +++ b/apps/web/src/app/cart/page.tsx @@ -0,0 +1,78 @@ +'use client'; + +import Link from 'next/link'; +import { useCart } from '@/components/CartProvider/CartProvider'; +import { Icon } from '@/components/Icon/Icon'; +import { Button } from '@/components/ui/Button/Button'; +import { Breadcrumb } from '@/components/Breadcrumb/Breadcrumb'; +import styles from './page.module.scss'; + +export default function CartPage() { + const { cart, removeFromCart, updateQuantity } = useCart(); + + return ( +
+ +

Корзина запроса

+ + {cart.length === 0 ? ( +
+

Корзина пуста

+ + + +
+ ) : ( + <> +
+ {cart.map((item) => ( +
+
+
{item.sku}
+
{item.name}
+
{item.brand}
+
+
+
+ + {item.qty} + +
+ +
+
+ ))} +
+
+ + Позиций: {cart.length} + + + + +
+ + )} +
+ ); +} diff --git a/apps/web/src/app/catalog/[category]/page.tsx b/apps/web/src/app/catalog/[category]/page.tsx new file mode 100644 index 0000000..45ba61b --- /dev/null +++ b/apps/web/src/app/catalog/[category]/page.tsx @@ -0,0 +1,61 @@ +import { Suspense } from 'react'; +import { notFound } from 'next/navigation'; +import { products } from '@/data/products'; +import { categories } from '@/data/categories'; +import { categoryNameMap, CategorySlug } from '@/types'; +import { Breadcrumb } from '@/components/Breadcrumb/Breadcrumb'; +import { CatalogSidebar } from '@/components/CatalogSidebar/CatalogSidebar'; +import { ProductCard } from '@/components/ProductCard/ProductCard'; +import styles from '../page.module.scss'; + +export function generateStaticParams() { + return categories.map((c) => ({ category: c.slug })); +} + +export function generateMetadata({ + params, +}: { + params: Promise<{ category: string }>; +}) { + return params.then(({ category }) => { + const name = categoryNameMap[category as CategorySlug]; + return { title: name ? `${name} | PAN-PROM` : 'Каталог | PAN-PROM' }; + }); +} + +export default async function CategoryPage({ + params, +}: { + params: Promise<{ category: string }>; +}) { + const { category } = await params; + const catName = categoryNameMap[category as CategorySlug]; + if (!catName) notFound(); + + const filtered = products.filter((p) => p.category === catName); + + return ( +
+ + + +
+
+ + {filtered.length} позиций +
+
+ {filtered.map((p) => ( + + ))} +
+
+
+ ); +} diff --git a/apps/web/src/app/catalog/page.module.scss b/apps/web/src/app/catalog/page.module.scss new file mode 100644 index 0000000..48a27f6 --- /dev/null +++ b/apps/web/src/app/catalog/page.module.scss @@ -0,0 +1,37 @@ +.layout { + max-width: var(--max-width); + margin: 0 auto; + padding: var(--space-lg); + display: flex; + gap: var(--space-lg); +} + +.main { + flex: 1; +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: var(--space-md); +} + +.count { + font-size: 12px; + color: var(--color-slate-400); +} + +.grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--space-md); + + @media (max-width: 1024px) { + grid-template-columns: repeat(2, 1fr); + } + + @media (max-width: 640px) { + grid-template-columns: 1fr; + } +} diff --git a/apps/web/src/app/catalog/page.tsx b/apps/web/src/app/catalog/page.tsx new file mode 100644 index 0000000..5e43059 --- /dev/null +++ b/apps/web/src/app/catalog/page.tsx @@ -0,0 +1,36 @@ +import { Suspense } from 'react'; +import { products } from '@/data/products'; +import { Breadcrumb } from '@/components/Breadcrumb/Breadcrumb'; +import { CatalogSidebar } from '@/components/CatalogSidebar/CatalogSidebar'; +import { ProductCard } from '@/components/ProductCard/ProductCard'; +import styles from './page.module.scss'; + +export const metadata = { + title: 'Каталог | PAN-PROM', +}; + +export default function CatalogPage() { + return ( +
+ + + +
+
+ + {products.length} позиций +
+
+ {products.map((p) => ( + + ))} +
+
+
+ ); +} diff --git a/apps/web/src/app/contact/page.module.scss b/apps/web/src/app/contact/page.module.scss new file mode 100644 index 0000000..3e15385 --- /dev/null +++ b/apps/web/src/app/contact/page.module.scss @@ -0,0 +1,60 @@ +.container { + max-width: var(--max-width); + margin: 0 auto; + padding: var(--space-lg); +} + +.title { + font-size: 28px; + font-weight: 700; + color: var(--color-slate-900); + margin-bottom: var(--space-xl); +} + +.grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: var(--space-lg); + + @media (max-width: 768px) { + grid-template-columns: 1fr; + } +} + +.card { + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--border-radius-lg); + padding: var(--space-xl); + text-align: center; +} + +.iconBox { + width: 56px; + height: 56px; + border-radius: var(--border-radius-lg); + background: var(--color-orange-50); + display: flex; + align-items: center; + justify-content: center; + margin: 0 auto var(--space-md); +} + +.cardTitle { + font-size: 16px; + font-weight: 600; + color: var(--color-slate-800); + margin-bottom: 8px; +} + +.cardText { + font-size: 15px; + color: var(--color-slate-700); + font-weight: 500; +} + +.cardNote { + font-size: 12px; + color: var(--color-text-muted); + margin-top: 4px; +} diff --git a/apps/web/src/app/contact/page.tsx b/apps/web/src/app/contact/page.tsx new file mode 100644 index 0000000..8e6b4f8 --- /dev/null +++ b/apps/web/src/app/contact/page.tsx @@ -0,0 +1,47 @@ +import { Icon } from '@/components/Icon/Icon'; +import { Breadcrumb } from '@/components/Breadcrumb/Breadcrumb'; +import styles from './page.module.scss'; + +export const metadata = { + title: 'Контакты | PAN-PROM', +}; + +export default function ContactPage() { + return ( +
+ +

Контакты

+ +
+
+
+ +
+

Телефон

+

+49 (0) 40 123-4567

+

Пн-Пт: 09:00 - 18:00 CET

+
+ +
+
+ +
+

Email

+

info@pan-prom.eu

+

Ответ в течение 24 часов

+
+ +
+
+ +
+

Офис

+

Hamburg, Germany

+

Склады: Берлин, Гуанчжоу

+
+
+
+ ); +} diff --git a/apps/web/src/app/global.css b/apps/web/src/app/global.css index bb41dd8..6e32479 100644 --- a/apps/web/src/app/global.css +++ b/apps/web/src/app/global.css @@ -1,501 +1,122 @@ -html { - -webkit-text-size-adjust: 100%; - font-family: - ui-sans-serif, - system-ui, - -apple-system, - BlinkMacSystemFont, - Segoe UI, - Roboto, - Helvetica Neue, - Arial, - Noto Sans, - sans-serif, - Apple Color Emoji, - Segoe UI Emoji, - Segoe UI Symbol, - Noto Color Emoji; - line-height: 1.5; - tab-size: 4; - scroll-behavior: smooth; -} -body { - font-family: inherit; - line-height: inherit; - margin: 0; -} -h1, -h2, -p, -pre { - margin: 0; -} +/* Reset */ *, -::before, -::after { +*::before, +*::after { box-sizing: border-box; - border-width: 0; - border-style: solid; - border-color: currentColor; -} -h1, -h2 { - font-size: inherit; - font-weight: inherit; -} -a { - color: inherit; - text-decoration: inherit; -} -pre { - font-family: - ui-monospace, - SFMono-Regular, - Menlo, - Monaco, - Consolas, - Liberation Mono, - Courier New, - monospace; -} -svg { - display: block; - vertical-align: middle; - shape-rendering: auto; - text-rendering: optimizeLegibility; -} -pre { - background-color: rgba(55, 65, 81, 1); - border-radius: 0.25rem; - color: rgba(229, 231, 235, 1); - font-family: - ui-monospace, - SFMono-Regular, - Menlo, - Monaco, - Consolas, - Liberation Mono, - Courier New, - monospace; - overflow: scroll; - padding: 0.5rem 0.75rem; + margin: 0; + padding: 0; } -.shadow { - box-shadow: - 0 0 #0000, - 0 0 #0000, - 0 10px 15px -3px rgba(0, 0, 0, 0.1), - 0 4px 6px -2px rgba(0, 0, 0, 0.05); +html { + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } -.rounded { - border-radius: 1.5rem; + +body { + min-height: 100vh; + font-family: var(--font-sans); + font-size: 14px; + line-height: 1.5; + color: var(--color-text); + background: var(--color-bg); } -.wrapper { - width: 100%; + +a { + color: inherit; + text-decoration: none; } -.container { - margin-left: auto; - margin-right: auto; - max-width: 768px; - padding-bottom: 3rem; - padding-left: 1rem; - padding-right: 1rem; - color: rgba(55, 65, 81, 1); - width: 100%; -} -#welcome { - margin-top: 2.5rem; -} -#welcome h1 { - font-size: 3rem; - font-weight: 500; - letter-spacing: -0.025em; - line-height: 1; -} -#welcome span { - display: block; - font-size: 1.875rem; - font-weight: 300; - line-height: 2.25rem; - margin-bottom: 0.5rem; -} -#hero { - align-items: center; - background-color: hsla(214, 62%, 21%, 1); - border: none; - box-sizing: border-box; - color: rgba(55, 65, 81, 1); - display: grid; - grid-template-columns: 1fr; - margin-top: 3.5rem; -} -#hero .text-container { - color: rgba(255, 255, 255, 1); - padding: 3rem 2rem; -} -#hero .text-container h2 { - font-size: 1.5rem; - line-height: 2rem; - position: relative; -} -#hero .text-container h2 svg { - color: hsla(162, 47%, 50%, 1); - height: 2rem; - left: -0.25rem; - position: absolute; - top: 0; - width: 2rem; -} -#hero .text-container h2 span { - margin-left: 2.5rem; -} -#hero .text-container a { - background-color: rgba(255, 255, 255, 1); - border-radius: 0.75rem; - color: rgba(55, 65, 81, 1); - display: inline-block; - margin-top: 1.5rem; - padding: 1rem 2rem; - text-decoration: inherit; -} -#hero .logo-container { - display: none; - justify-content: center; - padding-left: 2rem; - padding-right: 2rem; -} -#hero .logo-container svg { - color: rgba(255, 255, 255, 1); - width: 66.666667%; -} -#middle-content { - align-items: flex-start; - display: grid; - gap: 4rem; - grid-template-columns: 1fr; - margin-top: 3.5rem; -} -#learning-materials { - padding: 2.5rem 2rem; -} -#learning-materials h2 { - font-weight: 500; - font-size: 1.25rem; - letter-spacing: -0.025em; - line-height: 1.75rem; - padding-left: 1rem; - padding-right: 1rem; -} -.list-item-link { - align-items: center; - border-radius: 0.75rem; - display: flex; - margin-top: 1rem; - padding: 1rem; - transition-property: - background-color, - border-color, - color, - fill, - stroke, - opacity, - box-shadow, - transform, - filter, - backdrop-filter, - -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; - width: 100%; -} -.list-item-link svg:first-child { - margin-right: 1rem; - height: 1.5rem; - transition-property: - background-color, - border-color, - color, - fill, - stroke, - opacity, - box-shadow, - transform, - filter, - backdrop-filter, - -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; - width: 1.5rem; -} -.list-item-link > span { - flex-grow: 1; - font-weight: 400; - transition-property: - background-color, - border-color, - color, - fill, - stroke, - opacity, - box-shadow, - transform, - filter, - backdrop-filter, - -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} -.list-item-link > span > span { - color: rgba(107, 114, 128, 1); - display: block; - flex-grow: 1; - font-size: 0.75rem; - font-weight: 300; - line-height: 1rem; - transition-property: - background-color, - border-color, - color, - fill, - stroke, - opacity, - box-shadow, - transform, - filter, - backdrop-filter, - -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} -.list-item-link svg:last-child { - height: 1rem; - transition-property: all; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; - width: 1rem; -} -.list-item-link:hover { - color: rgba(255, 255, 255, 1); - background-color: hsla(162, 47%, 50%, 1); -} -.list-item-link:hover > span { -} -.list-item-link:hover > span > span { - color: rgba(243, 244, 246, 1); -} -.list-item-link:hover svg:last-child { - transform: translateX(0.25rem); -} -#other-links { -} -.button-pill { - padding: 1.5rem 2rem; - transition-duration: 300ms; - transition-property: - background-color, - border-color, - color, - fill, - stroke, - opacity, - box-shadow, - transform, - filter, - backdrop-filter, - -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - align-items: center; - display: flex; -} -.button-pill svg { - transition-property: - background-color, - border-color, - color, - fill, - stroke, - opacity, - box-shadow, - transform, - filter, - backdrop-filter, - -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; - flex-shrink: 0; - width: 3rem; -} -.button-pill > span { - letter-spacing: -0.025em; - font-weight: 400; - font-size: 1.125rem; - line-height: 1.75rem; - padding-left: 1rem; - padding-right: 1rem; -} -.button-pill span span { - display: block; - font-size: 0.875rem; - font-weight: 300; - line-height: 1.25rem; -} -.button-pill:hover svg, -.button-pill:hover { - color: rgba(255, 255, 255, 1) !important; -} -#nx-console:hover { - background-color: rgba(0, 122, 204, 1); -} -#nx-console svg { - color: rgba(0, 122, 204, 1); -} -#nx-console-jetbrains { - margin-top: 2rem; -} -#nx-console-jetbrains:hover { - background-color: rgba(255, 49, 140, 1); -} -#nx-console-jetbrains svg { - color: rgba(255, 49, 140, 1); -} -#nx-repo:hover { - background-color: rgba(24, 23, 23, 1); -} -#nx-repo svg { - color: rgba(24, 23, 23, 1); -} -#nx-cloud { - margin-bottom: 2rem; - margin-top: 2rem; - padding: 2.5rem 2rem; -} -#nx-cloud > div { - align-items: center; - display: flex; -} -#nx-cloud > div svg { - border-radius: 0.375rem; - flex-shrink: 0; - width: 3rem; -} -#nx-cloud > div h2 { - font-size: 1.125rem; - font-weight: 400; - letter-spacing: -0.025em; - line-height: 1.75rem; - padding-left: 1rem; - padding-right: 1rem; -} -#nx-cloud > div h2 span { - display: block; - font-size: 0.875rem; - font-weight: 300; - line-height: 1.25rem; -} -#nx-cloud p { - font-size: 1rem; - line-height: 1.5rem; - margin-top: 1rem; -} -#nx-cloud pre { - margin-top: 1rem; -} -#nx-cloud a { - color: rgba(107, 114, 128, 1); - display: block; - font-size: 0.875rem; - line-height: 1.25rem; - margin-top: 1.5rem; - text-align: right; -} -#nx-cloud a:hover { - text-decoration: underline; -} -#commands { - padding: 2.5rem 2rem; - margin-top: 3.5rem; -} -#commands h2 { - font-size: 1.25rem; - font-weight: 400; - letter-spacing: -0.025em; - line-height: 1.75rem; - padding-left: 1rem; - padding-right: 1rem; -} -#commands p { - font-size: 1rem; - font-weight: 300; - line-height: 1.5rem; - margin-top: 1rem; - padding-left: 1rem; - padding-right: 1rem; -} -details { - align-items: center; - display: flex; - margin-top: 1rem; - padding-left: 1rem; - padding-right: 1rem; - width: 100%; -} -details pre > span { - color: rgba(181, 181, 181, 1); + +img { + max-width: 100%; display: block; } -summary { - border-radius: 0.5rem; - display: flex; - font-weight: 400; - padding: 0.5rem; + +button { + font-family: inherit; cursor: pointer; - transition-property: - background-color, - border-color, - color, - fill, - stroke, - opacity, - box-shadow, - transform, - filter, - backdrop-filter, - -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; } -summary:hover { - background-color: rgba(243, 244, 246, 1); + +input, +textarea, +select { + font-family: inherit; + font-size: inherit; } -summary svg { - height: 1.5rem; - margin-right: 1rem; - width: 1.5rem; -} -#love { - color: rgba(107, 114, 128, 1); - font-size: 0.875rem; - line-height: 1.25rem; - margin-top: 3.5rem; - opacity: 0.6; - text-align: center; -} -#love svg { - color: rgba(252, 165, 165, 1); - width: 1.25rem; - height: 1.25rem; - display: inline; - margin-top: -0.25rem; -} -@media screen and (min-width: 768px) { - #hero { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - #hero .logo-container { - display: flex; - } - #middle-content { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } + +/* Design Tokens */ +:root { + /* Orange */ + --color-orange-50: #fff3e0; + --color-orange-100: #ffe0b2; + --color-orange-200: #ffcc80; + --color-orange-400: #ffa726; + --color-orange-500: #e8600a; + --color-orange-600: #d4560a; + --color-orange-700: #bf4d09; + --color-orange-800: #993e07; + --color-orange-900: #733006; + + /* Navy */ + --color-navy-50: #e8eaf6; + --color-navy-100: #c5cae9; + --color-navy-200: #9fa8da; + --color-navy-300: #7986cb; + --color-navy-400: #5c6bc0; + --color-navy-500: #1a237e; + --color-navy-600: #151b6b; + --color-navy-700: #101358; + --color-navy-800: #0b0d45; + --color-navy-900: #060732; + + /* Teal */ + --color-teal-50: #e0f2f1; + --color-teal-100: #b2dfdb; + --color-teal-200: #80cbc4; + --color-teal-300: #4db6ac; + --color-teal-400: #26a69a; + --color-teal-500: #00695c; + + /* Slate */ + --color-slate-50: #f8fafc; + --color-slate-100: #f1f5f9; + --color-slate-200: #e2e8f0; + --color-slate-300: #cbd5e1; + --color-slate-400: #94a3b8; + --color-slate-500: #64748b; + --color-slate-600: #475569; + --color-slate-700: #334155; + --color-slate-800: #1e293b; + --color-slate-900: #0f172a; + + /* Semantic */ + --color-primary: var(--color-orange-500); + --color-primary-hover: var(--color-orange-600); + --color-bg: var(--color-slate-50); + --color-surface: #ffffff; + --color-text: var(--color-slate-800); + --color-text-muted: var(--color-slate-500); + --color-border: var(--color-slate-200); + + /* Spacing */ + --space-xs: 4px; + --space-sm: 8px; + --space-md: 16px; + --space-lg: 24px; + --space-xl: 32px; + --space-2xl: 48px; + + /* Typography */ + --font-sans: -apple-system, 'Segoe UI', Arial, sans-serif; + --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace; + + /* Layout */ + --max-width: 1280px; + --header-height: 120px; + + /* Border radius */ + --border-radius-sm: 6px; + --border-radius-md: 10px; + --border-radius-lg: 12px; + --border-radius-xl: 16px; } diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 8580125..e89202a 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -1,8 +1,12 @@ import './global.css'; +import { Header } from '@/components/Header/Header'; +import { Footer } from '@/components/Footer/Footer'; +import { CartProvider } from '@/components/CartProvider/CartProvider'; export const metadata = { - title: 'Welcome to web', - description: 'Generated by create-nx-workspace', + title: 'PAN-PROM | Промышленное оборудование из Европы', + description: + 'Гидравлика, пневматика, АСУ, запасные части. Прямые поставки оригинальных комплектующих от ведущих европейских производителей.', }; export default function RootLayout({ @@ -11,8 +15,14 @@ export default function RootLayout({ children: React.ReactNode; }) { return ( - - {children} + + + +
+
{children}
+