This commit is contained in:
2026-03-30 16:39:53 +09:00
parent 99f5f2a507
commit da981cfc69
42 changed files with 446 additions and 230 deletions

View File

@@ -5,12 +5,16 @@
"": { "": {
"name": "commit-it", "name": "commit-it",
"dependencies": { "dependencies": {
"@react-input/mask": "^2.0.4",
"@tailwindcss/vite": "^4.2.2", "@tailwindcss/vite": "^4.2.2",
"axios": "^1.13.6", "axios": "^1.13.6",
"clsx": "^2.1.1",
"embla-carousel-react": "^8.6.0", "embla-carousel-react": "^8.6.0",
"inter-ui": "^4.1.1",
"motion": "^12.38.0", "motion": "^12.38.0",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
"react-hook-form": "^7.72.0",
"tailwindcss": "^4.2.2", "tailwindcss": "^4.2.2",
}, },
"devDependencies": { "devDependencies": {
@@ -113,6 +117,10 @@
"@oxc-project/types": ["@oxc-project/types@0.122.0", "", {}, "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA=="], "@oxc-project/types": ["@oxc-project/types@0.122.0", "", {}, "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA=="],
"@react-input/core": ["@react-input/core@2.0.2", "", { "peerDependencies": { "@types/react": ">=16.8", "react": ">=16.8 || ^19.0.0-rc", "react-dom": ">=16.8 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-xLLBueYFbant9308uv3cIJQz5NYSixeGspjP3Nt6jogRHTcHYMRmlVFUuSzQiP8Z8/5BdnPkudRSsN0/AJ1fbw=="],
"@react-input/mask": ["@react-input/mask@2.0.4", "", { "dependencies": { "@react-input/core": "^2.0.2" }, "peerDependencies": { "@types/react": ">=16.8", "react": ">=16.8 || ^19.0.0-rc", "react-dom": ">=16.8 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-NOielvQSBOlGLVuEcxtkjaGneC0GJFXjC7KOF99ed9H9XSDruWnQirjht5uSbWqLeeiOup0VD2YjM+6FH+aWBg=="],
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.11", "", { "os": "android", "cpu": "arm64" }, "sha512-SJ+/g+xNnOh6NqYxD0V3uVN4W3VfnrGsC9/hoglicgTNfABFG9JjISvkkU0dNY84MNHLWyOgxP9v9Y9pX4S7+A=="], "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.11", "", { "os": "android", "cpu": "arm64" }, "sha512-SJ+/g+xNnOh6NqYxD0V3uVN4W3VfnrGsC9/hoglicgTNfABFG9JjISvkkU0dNY84MNHLWyOgxP9v9Y9pX4S7+A=="],
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-7WQgR8SfOPwmDZGFkThUvsmd/nwAWv91oCO4I5LS7RKrssPZmOt7jONN0cW17ydGC1n/+puol1IpoieKqQidmg=="], "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-7WQgR8SfOPwmDZGFkThUvsmd/nwAWv91oCO4I5LS7RKrssPZmOt7jONN0cW17ydGC1n/+puol1IpoieKqQidmg=="],
@@ -251,6 +259,8 @@
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
@@ -377,6 +387,8 @@
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
"inter-ui": ["inter-ui@4.1.1", "", {}, "sha512-451h0J29HyOmA+JXgSi/6M12tL7ZCZ8arYKZUXiOXTJpJbAKqJvFh3k5SiV3x7tKe0C0KyrKUUiQIvvZ2PQDcA=="],
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
@@ -485,6 +497,8 @@
"react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
"react-hook-form": ["react-hook-form@7.72.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-V4v6jubaf6JAurEaVnT9aUPKFbNtDgohj5CIgVGyPHvT9wRx5OZHVjz31GsxnPNI278XMu+ruFz+wGOscHaLKw=="],
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
"rolldown": ["rolldown@1.0.0-rc.11", "", { "dependencies": { "@oxc-project/types": "=0.122.0", "@rolldown/pluginutils": "1.0.0-rc.11" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.11", "@rolldown/binding-darwin-arm64": "1.0.0-rc.11", "@rolldown/binding-darwin-x64": "1.0.0-rc.11", "@rolldown/binding-freebsd-x64": "1.0.0-rc.11", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.11", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.11", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.11", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.11", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.11", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.11", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.11", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.11", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.11", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.11", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.11" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-NRjoKMusSjfRbSYiH3VSumlkgFe7kYAa3pzVOsVYVFY3zb5d7nS+a3KGQ7hJKXuYWbzJKPVQ9Wxq2UvyK+ENpw=="], "rolldown": ["rolldown@1.0.0-rc.11", "", { "dependencies": { "@oxc-project/types": "=0.122.0", "@rolldown/pluginutils": "1.0.0-rc.11" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.11", "@rolldown/binding-darwin-arm64": "1.0.0-rc.11", "@rolldown/binding-darwin-x64": "1.0.0-rc.11", "@rolldown/binding-freebsd-x64": "1.0.0-rc.11", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.11", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.11", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.11", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.11", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.11", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.11", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.11", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.11", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.11", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.11", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.11" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-NRjoKMusSjfRbSYiH3VSumlkgFe7kYAa3pzVOsVYVFY3zb5d7nS+a3KGQ7hJKXuYWbzJKPVQ9Wxq2UvyK+ENpw=="],

BIN
dist/assets/Inter-Black-BJbWHna9.woff2 vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
dist/assets/Inter-Bold-BOs3KVhN.woff2 vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dist/assets/Inter-Italic-Bm_w1qmz.woff2 vendored Normal file

Binary file not shown.

BIN
dist/assets/Inter-Light-14LG-y7V.woff2 vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
dist/assets/Inter-Medium-CDhBSFyE.woff2 vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
dist/assets/Inter-Regular-COLGFB3M.woff2 vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dist/assets/Inter-Thin-DzN99i8q.woff2 vendored Normal file

Binary file not shown.

Binary file not shown.

2
dist/assets/index-BdO-_d9-.css vendored Normal file

File diff suppressed because one or more lines are too long

46
dist/assets/index-DR6J_FuZ.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

BIN
dist/assets/sign.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

6
dist/index.html vendored
View File

@@ -4,9 +4,9 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>commit-it</title> <title>ООО «КОММИТ»</title>
<script type="module" crossorigin src="/assets/index-Dm_P0vS5.js"></script> <script type="module" crossorigin src="/assets/index-DR6J_FuZ.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Ds0M9zyc.css"> <link rel="stylesheet" crossorigin href="/assets/index-BdO-_d9-.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@@ -10,6 +10,7 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@react-input/mask": "^2.0.4",
"@tailwindcss/vite": "^4.2.2", "@tailwindcss/vite": "^4.2.2",
"axios": "^1.13.6", "axios": "^1.13.6",
"clsx": "^2.1.1", "clsx": "^2.1.1",
@@ -18,6 +19,7 @@
"motion": "^12.38.0", "motion": "^12.38.0",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
"react-hook-form": "^7.72.0",
"tailwindcss": "^4.2.2" "tailwindcss": "^4.2.2"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -2,7 +2,6 @@ import { useState } from 'react'
import { motion, useMotionValueEvent, useScroll } from "motion/react" import { motion, useMotionValueEvent, useScroll } from "motion/react"
import TypingEffect from './components/TypingEffect' import TypingEffect from './components/TypingEffect'
import CardsSection from './components/CardsSection' import CardsSection from './components/CardsSection'
import Section from './components/Section'
import Marquee from './components/Marquee' import Marquee from './components/Marquee'
import Navbar from './components/Navbar' import Navbar from './components/Navbar'
import ServicesSection from './components/ServicesSection' import ServicesSection from './components/ServicesSection'
@@ -67,7 +66,7 @@ function App() {
const programs = ['/assets/1c_franch.svg', '/assets/astralinux.svg', '/assets/drweb.svg', '/assets/kasperskylab.svg'] const programs = ['/assets/1c_franch.svg', '/assets/astralinux.svg', '/assets/drweb.svg', '/assets/kasperskylab.svg']
return ( return (
<main className='w-full flex flex-col sm:gap-8 items-center'> <main className='relative w-full flex flex-col gap-4 sm:gap-8 items-center'>
<dialog id="navbar_modal" className="modal modal-end"> <dialog id="navbar_modal" className="modal modal-end">
<div className="modal-box w-3/4 flex flex-col gap-8"> <div className="modal-box w-3/4 flex flex-col gap-8">
<div className='flex flex-row justify-between items-center'> <div className='flex flex-row justify-between items-center'>
@@ -80,11 +79,11 @@ function App() {
</div> </div>
<form method="dialog" className='flex flex-col gap-4'> <form method="dialog" className='flex flex-col gap-4'>
<a onClick={handleLink} href="#about" className='text-xl text-base-content/70 hover:text-blue-500'>О компании</a> <a onClick={handleLink} href="#about" className='text-lg text-base-content/70 hover:text-blue-500'>О компании</a>
<a onClick={handleLink} href="#products" className='text-xl text-base-content/70 hover:text-blue-500'>Программные продукты</a> <a onClick={handleLink} href="#products" className='text-lg text-base-content/70 hover:text-blue-500'>Программные продукты</a>
<a onClick={handleLink} href="#services" className='text-xl text-base-content/70 hover:text-blue-500'>Услуги</a> <a onClick={handleLink} href="#services" className='text-lg text-base-content/70 hover:text-blue-500'>Услуги</a>
<a onClick={handleLink} href="#case" className='text-xl text-base-content/70 hover:text-blue-500'>Главный кейс</a> <a onClick={handleLink} href="#case" className='text-lg text-base-content/70 hover:text-blue-500'>Главный кейс</a>
<a onClick={handleLink} href="#contacts" className='text-xl text-base-content/70 hover:text-blue-500'>Контакты</a> <a onClick={handleLink} href="#contacts" className='text-lg text-base-content/70 btn rounded-full font-light not-disabled:bg-[#1C8EFF] w-min text-white'>Контакты</a>
</form> </form>
</div> </div>
<form method="dialog" className="modal-backdrop backdrop-blur-xs"> <form method="dialog" className="modal-backdrop backdrop-blur-xs">
@@ -204,6 +203,10 @@ function App() {
</div> </div>
<CardsSection /> <CardsSection />
{/* <CardSection /> */}
{/* <StackSection /> */}
{/* <CardStackSection /> */}
<AboutSection /> <AboutSection />

View File

@@ -1,4 +1,3 @@
import Section from './Section'
import CompanyInfoMockup from './CompanyInfoMockup' import CompanyInfoMockup from './CompanyInfoMockup'
import Thesis from './Thesis' import Thesis from './Thesis'
@@ -93,34 +92,36 @@ const AboutSection = () => {
] ]
return ( return (
<Section id='about'> <section id='about' className='h-auto w-full flex justify-center'>
<CompanyInfoMockup> <div className='max-w-7xl w-full h-auto xl:py-4'>
<div className='w-full sm:p-8 flex flex-col space-y-8 justify-center'> <CompanyInfoMockup>
<span className='text-4xl text-center my-4'>О компании</span> <div className='w-full sm:p-8 flex flex-col space-y-8 justify-center'>
<span className='text-4xl text-center my-4'>О компании</span>
<div className='grid grid-rows-2 sm:grid-rows-1 sm:grid-cols-2 gap-8 p-2 xl:p-0'>
<div className='p-8 flex flex-col space-y-4 bg-base-100 rounded-2xl'>
<span className='text-2xl'>Виды деятельности:</span>
<div className='flex flex-col space-y-4'>
{actInfo.map(info => (
<Thesis info={info} />
))}
</div>
<div className='grid grid-rows-2 sm:grid-rows-1 sm:grid-cols-2 gap-8 p-2 xl:p-0'>
<div className='p-8 flex flex-col space-y-4 bg-base-100 rounded-2xl'>
<span className='text-2xl'>Виды деятельности:</span>
<div className='flex flex-col space-y-4'>
{actInfo.map(info => (
<Thesis info={info} />
))}
</div> </div>
</div> <div className='p-8 flex flex-col space-y-4 bg-black/90 rounded-2xl text-white'>
<span className='text-2xl'>Почему мы?</span>
<div className='p-8 flex flex-col space-y-4 bg-black/90 rounded-2xl text-white'> <div className='flex flex-col space-y-4'>
<span className='text-2xl'>Почему мы?</span> {whyInfo.map(info => (
<div className='flex flex-col space-y-4'> <Thesis info={info} />
{whyInfo.map(info => ( ))}
<Thesis info={info} /> </div>
))}
</div> </div>
</div> </div>
</div> </div>
</div> </CompanyInfoMockup>
</CompanyInfoMockup> </div>
</Section> </section>
) )
} }

View File

@@ -0,0 +1,163 @@
import { motion, useMotionValueEvent, useScroll, useTransform } from "motion/react"
import { useEffect, useRef, useState } from "react"
import Braces from "./Braces"
const CardSection = () => {
const containerRef = useRef(null)
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start start", "end end"]
})
const leftValue = 100
const [xValue, setXvalue] = useState(leftValue)
const x = useTransform(scrollYProgress, [0, 1], [leftValue, 0])
useMotionValueEvent(x, "change", (latest) => setXvalue(latest))
const items = [
{ id: 1, color: "#ff0088", label: "Из идеи — в работающую концепцию", description: 'Мы погружаемся в задачу, формируем понятную и реализуемую концепцию и сразу определяем дальнейшие шаги', image: "/assets/idea-BxLjsotP.png" },
{ id: 2, color: "#dd00ee", label: "Цены и процессы — без сюрпризов", description: 'Заранее фиксируем стоимость, этапы и зону ответственности, чтобы вы всегда понимали, за что платите и какой результат будет получен', image: "/assets/money-DcU00l9G.png" },
{ id: 3, color: "#9911ff", label: "Ориентируемся на результат", description: 'Каждое решение мы строим так, чтобы приносить измеримый результат и реальную ценность вашему бизнесу', image: "/assets/goal-BRVwp_WA.png" },
{ id: 4, color: "#0d63f8", label: "Контролируем сбои и устраняем", description: 'Мы оперативно реагируем на любые сбои, быстро устраняем их и гарантируем, что ваш проект всегда остаётся под полным контролем', image: "/assets/info-CE1fB6DT.png" },
]
const [height, setHeight] = useState(0)
useEffect(() => {
const update = () => {
const vh = window.innerHeight
const animationDistance = items.length * 120
setHeight(vh + animationDistance)
}
update()
window.addEventListener("resize", update)
return () => window.removeEventListener("resize", update)
}, [])
return (
<div className="relative max-w-7xl flex flex-col">
<div className='sticky top-0 w-full flex justify-center mb-8'>
<span className='px-4 text-3xl sm:text-4xl py-2 sm:text-center'>
<span className='text-blue-500'>Преимущества</span> работы с нами
</span>
</div>
<div className="">
{items.map((item, index) => (
<motion.div
key={item.id}
className='relative grid grid-rows-[min-content_min-content_min-content_1fr] gap-2 px-8 pt-4 min-w-full w-full shrink-0 overflow-visible rounded-2xl bg-base-200 outline-2 outline-base-100'
style={{
marginLeft: `${xValue * index}px`,
zIndex: index,
}}>
<Braces text={(index + 1).toString()} />
<span className='text-xl'>
{item.label}
</span>
<span className="text-base-content/70">
{item.description}
</span>
<img className='mt-auto' src={item.image} />
<div className='absolute left-0 top-0 bottom-0 -right-8 rounded-2xl bg-base-200 outline-2 outline-base-100 -z-10 w-auto h-full'>
</div>
</motion.div>
))}
</div>
</div>
)
return (
<div ref={containerRef} style={{ height: height }} className='p-2 sm:p-0 flex justify-center overflow-clip'>
<div
style={{ position: "sticky", top: 0 }}
className="h-screen sm:min-h-96 sm:h-fit flex flex-col sm:justify-center py-16 sm:py-24 max-w-7xl overflow-clip"
>
<div className='w-full flex justify-center mb-8'>
<span className='px-4 text-3xl sm:text-4xl py-2 sm:text-center'>
<span className='text-blue-500'>Преимущества</span> работы с нами
</span>
</div>
<motion.div
className='hidden sm:grid grid-cols-4 overflow-visible h-min min-h-96'
>
{items.map((item, index) => (
<motion.div
key={item.id}
className='relative grid grid-rows-[min-content_min-content_min-content_1fr] gap-2 px-8 pt-4 min-w-full w-full shrink-0 overflow-visible'
style={{
marginLeft: `${xValue * index}px`,
zIndex: index,
}}>
<Braces text={(index + 1).toString()} />
<span className='text-xl'>
{item.label}
</span>
<span className="text-base-content/70">
{item.description}
</span>
<img className='mt-auto' src={item.image} />
<div className='absolute left-0 top-0 bottom-0 -right-8 rounded-2xl bg-base-200 outline-2 outline-base-100 -z-10 w-auto h-full'>
</div>
</motion.div>
))}
</motion.div>
<motion.div
className='relative flex flex-col sm:hidden w-full min-h-96 overflow-visible'
>
{items.reverse().map((item, index) => {
const n = items.length;
const progress = Math.min(1, Math.max(0, (xValue - (index * 100) / n) * n / 100));
return (
<motion.div
key={item.id}
className="absolute grid grid-rows-[min-content_min-content_min-content_1fr] gap-2 w-full px-8 pt-4 h-auto shrink-0 overflow-visible"
style={{
top: index === items.length - 1 ? '0%' : `${100 * (progress) + (5 * (n - index - 1))}%`, // from bottom → top
zIndex: n - index,
}}
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.4 }}
viewport={{ once: true, margin: "-100px" }}
>
<Braces
text={(n - index).toString()}
/>
<span className='text-xl'>
{item.label}
</span>
<span className="text-base-content/70">
{item.description}
</span>
<img className="mt-auto" src={item.image} />
<div className="absolute left-0 top-0 right-0 bottom-0 rounded-2xl bg-base-200 outline-2 outline-base-100 -z-10 w-auto h-full" />
</motion.div>
);
})}
</motion.div>
</div>
</div>
)
}
export default CardSection

View File

@@ -0,0 +1,67 @@
import { motion, useMotionValueEvent, useScroll, useTransform } from 'motion/react'
import { useRef, useState } from 'react'
import Braces from './Braces'
const items = [
{ id: 1, color: "#ff0088", label: "Из идеи — в работающую концепцию", description: 'Мы погружаемся в задачу, формируем понятную и реализуемую концепцию и сразу определяем дальнейшие шаги', image: "/assets/idea-BxLjsotP.png" },
{ id: 2, color: "#dd00ee", label: "Цены и процессы — без сюрпризов", description: 'Заранее фиксируем стоимость, этапы и зону ответственности, чтобы вы всегда понимали, за что платите и какой результат будет получен', image: "/assets/money-DcU00l9G.png" },
{ id: 3, color: "#9911ff", label: "Ориентируемся на результат", description: 'Каждое решение мы строим так, чтобы приносить измеримый результат и реальную ценность вашему бизнесу', image: "/assets/goal-BRVwp_WA.png" },
{ id: 4, color: "#0d63f8", label: "Контролируем сбои и устраняем", description: 'Мы оперативно реагируем на любые сбои, быстро устраняем их и гарантируем, что ваш проект всегда остаётся под полным контролем', image: "/assets/info-CE1fB6DT.png" },
]
const CardStackSection = () => {
const containerRef = useRef(null)
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start start", "end end"]
})
const leftValue = 100
const [_, setXvalue] = useState(leftValue)
const x = useTransform(scrollYProgress, [0, 1], [leftValue, 0])
useMotionValueEvent(x, "change", (latest) => setXvalue(latest))
return (
<div className="relative h-auto max-h-full w-full max-w-7xl lg:h-[200vh]">
<div className='sticky top-24 z-10 w-full flex justify-center'>
<span className='px-4 text-3xl sm:text-4xl py-2 sm:text-center'>
<span className='text-blue-500'>Преимущества</span> работы с нами
</span>
</div>
<div className='sticky top-36 flex flex-row'>
{items.map((item, index) => (
<motion.div
key={item.id}
className='grid grid-rows-[min-content_min-content_min-content_1fr] gap-2 px-8 pt-4 w-full max-w-96 shrink-0 overflow-visible rounded-2xl bg-base-200 outline-2 outline-base-100'
style={{
// marginLeft: `${xValue}px`,
//zIndex: index,
//top: `${(index + 1) * 20 + 160}px`
}}
>
<Braces text={(index + 1).toString()} />
<span className='text-xl'>
{item.label}
</span>
<span className="text-base-content/70">
{item.description}
</span>
<img className='mt-auto' src={item.image} />
{/* <div className='absolute left-0 top-0 bottom-0 -right-8 rounded-2xl bg-base-200 outline-2 outline-base-100 -z-10 w-auto h-full'>
</div> */}
</motion.div>
))}
</div>
</div>
)
}
export default CardStackSection

View File

@@ -1,6 +1,7 @@
import { motion, useMotionValueEvent, useScroll, useTransform } from "motion/react" import { motion, useMotionValueEvent, useScroll, useTransform } from "motion/react"
import { useRef, useState } from "react" import { useRef, useState } from "react"
import Braces from "./Braces" import Braces from "./Braces"
import StackSection from "./StackSection"
const CardsSection = () => { const CardsSection = () => {
const containerRef = useRef(null) const containerRef = useRef(null)
@@ -18,52 +19,56 @@ const CardsSection = () => {
useMotionValueEvent(x, "change", (latest) => setXvalue(latest)) useMotionValueEvent(x, "change", (latest) => setXvalue(latest))
const items = [ const items = [
{ id: 1, color: "#ff0088", label: "Из идеи — в работающую концепцию", description: 'Мы погружаемся в задачу, формируем понятную и реализуемую концепцию и сразу определяем дальнейшие шаги', image: "/assets/idea-BxLjsotP.png" }, { id: 1, color: "#ff0088", label: "От идеи — до работающей концепции", description: 'Мы погружаемся в задачу, формируем понятную и реализуемую концепцию и сразу определяем дальнейшие шаги', image: "/assets/idea-BxLjsotP.png" },
{ id: 2, color: "#dd00ee", label: "Цены и процессы — без сюрпризов", description: 'Заранее фиксируем стоимость, этапы и зону ответственности, чтобы вы всегда понимали, за что платите и какой результат будет получен', image: "/assets/money-DcU00l9G.png" }, { id: 2, color: "#dd00ee", label: "Цены и процессы — без сюрпризов", description: 'Заранее фиксируем стоимость, этапы и зону ответственности, чтобы вы всегда понимали, за что платите и какой результат будет получен', image: "/assets/money-DcU00l9G.png" },
{ id: 3, color: "#9911ff", label: "Ориентируемся на результат", description: 'Каждое решение мы строим так, чтобы приносить измеримый результат и реальную ценность вашему бизнесу', image: "/assets/goal-BRVwp_WA.png" }, { id: 3, color: "#9911ff", label: "Ориентируемся на результат", description: 'Каждое решение мы строим так, чтобы приносить измеримый результат и реальную ценность вашему бизнесу', image: "/assets/goal-BRVwp_WA.png" },
{ id: 4, color: "#0d63f8", label: "Контролируем сбои и устраняем", description: 'Мы оперативно реагируем на любые сбои, быстро устраняем их и гарантируем, что ваш проект всегда остаётся под полным контролем', image: "/assets/info-CE1fB6DT.png" }, { id: 4, color: "#0d63f8", label: "Контролируем сбои и устраняем", description: 'Мы оперативно реагируем на любые сбои, быстро устраняем их и гарантируем, что ваш проект всегда остаётся под полным контролем', image: "/assets/info-CE1fB6DT.png" },
] ]
return ( return (
<div ref={containerRef} style={{ height: "300vh" }} className='p-2 sm:p-0 flex justify-center overflow-clip'> <>
<div style={{ position: "sticky", top: 0, height: "100vh" }} className='min-h-screen flex flex-col py-16 sm:py-24 max-w-7xl overflow-clip'> <div className="lg:hidden py-8">
<div className='w-full flex justify-center mb-8'> <StackSection />
<span className='px-4 text-3xl sm:text-4xl py-2 sm:text-center'> </div>
<span className='text-blue-500'>Преимущества</span> работы с нами <div ref={containerRef} className='hidden lg:flex p-2 lg:p-0 justify-center overflow-clip lg:h-[300vh]'>
</span> <div style={{ position: "sticky", top: 0, height: "100vh" }} className='min-h-screen flex flex-col py-16 lg:py-24 max-w-7xl overflow-clip'>
</div> <div className='w-full flex justify-center mb-8'>
<span className='px-4 text-3xl lg:text-4xl py-2 lg:text-center'>
<span className='text-blue-500'>Преимущества</span> работы с нами
</span>
</div>
<motion.div <motion.div
className='hidden sm:grid grid-cols-4 overflow-visible h-min min-h-96' className='hidden lg:grid grid-cols-4 overflow-visible h-min min-h-96'
> >
{items.map((item, index) => ( {items.map((item, index) => (
<motion.div <motion.div
key={item.id} key={item.id}
className='relative grid grid-rows-[min-content_min-content_min-content_1fr] gap-2 px-8 pt-4 min-w-full w-full shrink-0 overflow-visible' className='relative grid grid-rows-[min-content_min-content_min-content_1fr] gap-2 px-8 pt-4 min-w-full w-full shrink-0 overflow-visible'
style={{ style={{
marginLeft: `${xValue * index}px`, marginLeft: `${xValue * index}px`,
zIndex: index, zIndex: index,
}}> }}>
<Braces text={(index + 1).toString()} /> <Braces text={(index + 1).toString()} />
<span className='text-xl'> <span className='text-xl'>
{item.label} {item.label}
</span> </span>
<span className="text-base-content/70"> <span className="text-base-content/70">
{item.description} {item.description}
</span> </span>
<img className='mt-auto' src={item.image} /> <img className='mt-auto' src={item.image} />
<div className='absolute left-0 top-0 bottom-0 -right-8 rounded-2xl bg-base-200 outline-2 outline-base-100 -z-10 w-auto h-full'> <div className='absolute left-0 top-0 bottom-0 -right-8 rounded-2xl bg-[#F6F6F9] outline-2 outline-base-100 -z-10 w-auto h-full'>
</div> </div>
</motion.div> </motion.div>
))} ))}
</motion.div> </motion.div>
<motion.div {/* <motion.div
className='relative flex flex-col sm:hidden w-full h-full overflow-visible' className='relative flex flex-col lg:hidden w-full h-full overflow-visible'
> >
{items.reverse().map((item, index) => { {items.reverse().map((item, index) => {
const n = items.length; const n = items.length;
@@ -100,9 +105,10 @@ const CardsSection = () => {
</motion.div> </motion.div>
); );
})} })}
</motion.div> </motion.div> */}
</div>
</div> </div>
</div> </>
) )
} }

View File

@@ -23,7 +23,7 @@ const CaseSection = () => {
<span className='text-nowrap text-xs text-white'>Цифровая трансформация</span> <span className='text-nowrap text-xs text-white'>Цифровая трансформация</span>
</div> </div>
<span className='text-4xl text-white'>ГУП «ЖКХ РС(Я)»</span> <span className='text-4xl text-white'>ГУП «ЖКХ РС(Я)»</span>
<span className='text-white'>Комплексная цифровизация жилищно-коммунального одного из крупных предприятий РС(Я)</span> <span className='text-white'>Комплексная цифровизация жилищно-коммунального хозяйства одного из крупных предприятий Республики Саха (Якутия)</span>
</div> </div>
<div className='flex my-auto'> <div className='flex my-auto'>
@@ -71,7 +71,7 @@ const CaseSection = () => {
<div className='p-8 bg-black flex flex-col gap-4 rounded-2xl text-white'> <div className='p-8 bg-black flex flex-col gap-4 rounded-2xl text-white'>
<span className='text-xl'>Результат:</span> <span className='text-xl'>Результат:</span>
<span className=''> <span className=''>
Сокращение времени обработки платежей на 60%, полное импортозамещение базового ПО, интеграция с ГИС ЖКХ Сокращение времени обработки платежей, полное импортозамещение базового ПО, интеграция с ГИС ЖКХ
</span> </span>
</div> </div>

View File

@@ -4,7 +4,7 @@ const CompanyInfoMockup = ({
children children
}: PropsWithChildren) => { }: PropsWithChildren) => {
return ( return (
<div className='bg-base-300 w-full h-min rounded-4xl sm:border-8 sm:border-black'> <div className='bg-[#F6F6F9] w-full h-min sm:rounded-4xl sm:border-8 sm:border-black'>
<div className='hidden sm:flex flex-col w-full'> <div className='hidden sm:flex flex-col w-full'>
<div className='w-full grid grid-cols-3 p-2'> <div className='w-full grid grid-cols-3 p-2'>
<div className='flex space-x-2 overflow-hidden'> <div className='flex space-x-2 overflow-hidden'>

View File

@@ -20,7 +20,7 @@ const DirectorSection = () => {
</svg> </svg>
</div> </div>
<span className='text-xs sm:text-3xl'> <span className='text-xs sm:text-3xl text-justify'>
Нашей стратегией является превращать сложные задачи сферы ЖКХ <span className='text-blue-500'>в эффективные цифровые решения</span>. Мы разрабатываем автоматизацию для жизненно важной отрасли. Нашей стратегией является превращать сложные задачи сферы ЖКХ <span className='text-blue-500'>в эффективные цифровые решения</span>. Мы разрабатываем автоматизацию для жизненно важной отрасли.
</span> </span>

View File

@@ -3,6 +3,7 @@ import Braces from './Braces'
import Thesis from './Thesis' import Thesis from './Thesis'
import { useState } from 'react' import { useState } from 'react'
import axios from 'axios' import axios from 'axios'
import { InputMask } from '@react-input/mask'
const DiscussSection = () => { const DiscussSection = () => {
const [consult, setConsult] = useState({ const [consult, setConsult] = useState({
@@ -52,19 +53,19 @@ const DiscussSection = () => {
<CheckLabel text='Обсудим формат сотрудничества' /> <CheckLabel text='Обсудим формат сотрудничества' />
<div id='form' className='flex flex-col gap-4'> <div id='form' className='flex flex-col gap-4'>
<input type="name" onChange={(e) => { setConsult({ ...consult, fio: e.target.value }) }} value={consult.fio} placeholder="Введите ваше имя *" required className="input rounded-full w-full" /> <input type="name" onChange={(e) => { setConsult({ ...consult, fio: e.target.value }) }} value={consult.fio} placeholder="Введите ваше имя *" required className="input rounded-full w-full border-[#1C8EFF] outline-none" />
<input type="number" onChange={(e) => { setConsult({ ...consult, phone: e.target.value }) }} value={consult.phone} placeholder="+7(000)000-00-00 *" required className="input rounded-full w-full" /> <InputMask type='tel' mask="+7 (___) ___-__-__" replacement={{ _: /\d/ }} onChange={(e) => { setConsult({ ...consult, phone: e.target.value }) }} value={consult.phone} placeholder="+7(000)000-00-00 *" required className="input rounded-full w-full border-[#1C8EFF] outline-none" />
<input onChange={(e) => { setConsult({ ...consult, email: e.target.value }) }} value={consult.email} type="email" placeholder="mail@company.ru *" required className="input validator rounded-full w-full" /> <input onChange={(e) => { setConsult({ ...consult, email: e.target.value }) }} value={consult.email} type="email" placeholder="mail@company.ru *" required className="input validator rounded-full w-full border-[#1C8EFF] outline-none" />
<textarea onChange={(e) => { setConsult({ ...consult, desc: e.target.value }) }} value={consult.desc} rows={5} cols={30} className="textarea rounded-2xl w-full" placeholder="Опишите вашу ситуацию (необязательно)"></textarea> <textarea onChange={(e) => { setConsult({ ...consult, desc: e.target.value }) }} value={consult.desc} rows={5} cols={30} className="textarea rounded-2xl w-full border-[#1C8EFF] outline-none" placeholder="Опишите вашу ситуацию (необязательно)"></textarea>
<label className="label flex flex-row items-start"> <label className="label flex flex-row items-start">
<input type="checkbox" onChange={(e) => { setConsult({ ...consult, conf: e.target.checked }) }} checked={consult.conf} className="mt-1 checkbox checkbox-xs checked:border-blue-500 checked:bg-blue-400 checked:text-white rounded-sm" /> <input type="checkbox" onChange={(e) => { setConsult({ ...consult, conf: e.target.checked }) }} checked={consult.conf} className="mt-1 checkbox checkbox-xs checked:border-blue-500 checked:bg-blue-400 checked:text-white rounded-sm" />
<span className='text-wrap'> <span className='text-wrap'>
Я согласен(-на) с условиями <a className='text-blue-500'>Политики конфиденциальности</a> и разрешаю обработку моих персональных данных согласно <a className='text-blue-500'>Политики обработки персональных данных</a> Я разрешаю обработку моих персональных данных согласно <a href='/assets/legal/Политика_обработки_персональныханных_КОММИТ.pdf' target='_blank' className='text-blue-500'>Политики обработки персональных данных</a>
</span> </span>
</label> </label>
<button disabled={(consult.phone == '') || (consult.email == '') || (consult.desc == '') || (consult.fio == '') || (!consult.conf)} onClick={() => mail()} className='btn btn-lg text-white rounded-full font-light not-disabled:bg-[#1C8EFF]'> <button disabled={(consult.phone == '') || (consult.email == '') || (consult.fio == '') || (!consult.conf)} onClick={() => mail()} className='btn btn-lg text-white rounded-full font-light not-disabled:bg-[#1C8EFF]'>
Оставить заявку Оставить заявку
</button> </button>
@@ -82,14 +83,14 @@ const DiscussSection = () => {
<circle cx="11" cy="11" r="11" fill="#1C8EFF" /> <circle cx="11" cy="11" r="11" fill="#1C8EFF" />
<path d="M5.75008 15.0837H6.33341V7.71036C6.33343 7.52669 6.39125 7.34768 6.49866 7.1987C6.60608 7.04972 6.75766 6.93832 6.93191 6.88028L11.5986 5.32511C11.7301 5.2813 11.8701 5.26937 12.0072 5.2903C12.1442 5.31123 12.2743 5.36441 12.3868 5.44547C12.4992 5.52654 12.5908 5.63315 12.654 5.75655C12.7171 5.87994 12.7501 6.01657 12.7501 6.15519V15.0837H13.3334V9.82786C13.3334 9.78472 13.343 9.74213 13.3615 9.70315C13.38 9.66417 13.4069 9.62977 13.4402 9.60243C13.4736 9.57509 13.5126 9.55549 13.5545 9.54505C13.5963 9.5346 13.6399 9.53357 13.6822 9.54203L14.9632 9.79869C15.1615 9.83832 15.34 9.94541 15.4682 10.1017C15.5965 10.2581 15.6666 10.454 15.6667 10.6562V15.0837H16.2501C16.4048 15.0837 16.5532 15.1451 16.6626 15.2545C16.772 15.3639 16.8334 15.5123 16.8334 15.667C16.8334 15.8217 16.772 15.9701 16.6626 16.0795C16.5532 16.1889 16.4048 16.2504 16.2501 16.2504H5.75008C5.59537 16.2504 5.447 16.1889 5.3376 16.0795C5.22821 15.9701 5.16675 15.8217 5.16675 15.667C5.16675 15.5123 5.22821 15.3639 5.3376 15.2545C5.447 15.1451 5.59537 15.0837 5.75008 15.0837Z" fill="white" /> <path d="M5.75008 15.0837H6.33341V7.71036C6.33343 7.52669 6.39125 7.34768 6.49866 7.1987C6.60608 7.04972 6.75766 6.93832 6.93191 6.88028L11.5986 5.32511C11.7301 5.2813 11.8701 5.26937 12.0072 5.2903C12.1442 5.31123 12.2743 5.36441 12.3868 5.44547C12.4992 5.52654 12.5908 5.63315 12.654 5.75655C12.7171 5.87994 12.7501 6.01657 12.7501 6.15519V15.0837H13.3334V9.82786C13.3334 9.78472 13.343 9.74213 13.3615 9.70315C13.38 9.66417 13.4069 9.62977 13.4402 9.60243C13.4736 9.57509 13.5126 9.55549 13.5545 9.54505C13.5963 9.5346 13.6399 9.53357 13.6822 9.54203L14.9632 9.79869C15.1615 9.83832 15.34 9.94541 15.4682 10.1017C15.5965 10.2581 15.6666 10.454 15.6667 10.6562V15.0837H16.2501C16.4048 15.0837 16.5532 15.1451 16.6626 15.2545C16.772 15.3639 16.8334 15.5123 16.8334 15.667C16.8334 15.8217 16.772 15.9701 16.6626 16.0795C16.5532 16.1889 16.4048 16.2504 16.2501 16.2504H5.75008C5.59537 16.2504 5.447 16.1889 5.3376 16.0795C5.22821 15.9701 5.16675 15.8217 5.16675 15.667C5.16675 15.5123 5.22821 15.3639 5.3376 15.2545C5.447 15.1451 5.59537 15.0837 5.75008 15.0837Z" fill="white" />
</svg> </svg>
, title: '110+ компаний', description: 'Уже доверили нам разработку ПО' , title: 'Проверенная экспертиза', description: 'Реализовали проекты для отраслевых лидеров и государственных заказчиков'
}} /> }} />
<Thesis info={{ <Thesis info={{
icon: <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"> icon: <svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="11" cy="11" r="11" fill="#1C8EFF" /> <circle cx="11" cy="11" r="11" fill="#1C8EFF" />
<path d="M10.2999 11.953L9.11059 10.7637C9.04525 10.6988 8.96859 10.6643 8.88059 10.6603C8.79259 10.6563 8.71192 10.6908 8.63859 10.7637C8.56525 10.8366 8.52836 10.9159 8.52792 11.0017C8.52747 11.0874 8.56436 11.1668 8.63859 11.2397L9.92325 12.5277C10.0308 12.6357 10.1564 12.6897 10.2999 12.6897C10.4435 12.6897 10.5693 12.6357 10.6773 12.5277L13.3693 9.83567C13.4341 9.77078 13.4688 9.69367 13.4733 9.60433C13.4777 9.515 13.443 9.43367 13.3693 9.36033C13.2955 9.287 13.2161 9.25011 13.1313 9.24967C13.0464 9.24922 12.9673 9.28611 12.8939 9.36033L10.2999 11.953ZM10.9999 16.895C10.9395 16.895 10.8759 16.8894 10.8093 16.8783C10.7426 16.8672 10.6801 16.8506 10.6219 16.8283C9.30947 16.3279 8.26659 15.4797 7.49325 14.2837C6.71992 13.0877 6.33325 11.793 6.33325 10.3997V7.54433C6.33325 7.31767 6.39881 7.11256 6.52992 6.929C6.66103 6.74544 6.82881 6.61211 7.03325 6.529L10.6233 5.19567C10.753 5.14856 10.8786 5.125 10.9999 5.125C11.1213 5.125 11.247 5.14856 11.3773 5.19567L14.9666 6.529C15.171 6.61211 15.3388 6.74544 15.4699 6.929C15.601 7.11256 15.6666 7.31767 15.6666 7.54433V10.3997C15.6666 11.793 15.2799 13.0877 14.5066 14.2837C13.7333 15.4797 12.6904 16.3277 11.3779 16.8277C11.3201 16.8499 11.2579 16.8666 11.1913 16.8777C11.1246 16.8888 11.0608 16.8943 10.9999 16.8943" fill="white" /> <path d="M10.2999 11.953L9.11059 10.7637C9.04525 10.6988 8.96859 10.6643 8.88059 10.6603C8.79259 10.6563 8.71192 10.6908 8.63859 10.7637C8.56525 10.8366 8.52836 10.9159 8.52792 11.0017C8.52747 11.0874 8.56436 11.1668 8.63859 11.2397L9.92325 12.5277C10.0308 12.6357 10.1564 12.6897 10.2999 12.6897C10.4435 12.6897 10.5693 12.6357 10.6773 12.5277L13.3693 9.83567C13.4341 9.77078 13.4688 9.69367 13.4733 9.60433C13.4777 9.515 13.443 9.43367 13.3693 9.36033C13.2955 9.287 13.2161 9.25011 13.1313 9.24967C13.0464 9.24922 12.9673 9.28611 12.8939 9.36033L10.2999 11.953ZM10.9999 16.895C10.9395 16.895 10.8759 16.8894 10.8093 16.8783C10.7426 16.8672 10.6801 16.8506 10.6219 16.8283C9.30947 16.3279 8.26659 15.4797 7.49325 14.2837C6.71992 13.0877 6.33325 11.793 6.33325 10.3997V7.54433C6.33325 7.31767 6.39881 7.11256 6.52992 6.929C6.66103 6.74544 6.82881 6.61211 7.03325 6.529L10.6233 5.19567C10.753 5.14856 10.8786 5.125 10.9999 5.125C11.1213 5.125 11.247 5.14856 11.3773 5.19567L14.9666 6.529C15.171 6.61211 15.3388 6.74544 15.4699 6.929C15.601 7.11256 15.6666 7.31767 15.6666 7.54433V10.3997C15.6666 11.793 15.2799 13.0877 14.5066 14.2837C13.7333 15.4797 12.6904 16.3277 11.3779 16.8277C11.3201 16.8499 11.2579 16.8666 11.1913 16.8777C11.1246 16.8888 11.0608 16.8943 10.9999 16.8943" fill="white" />
</svg> </svg>
, title: '15+ лет опыта', description: 'Оценка стоимости и сроков' , title: 'Прозрачный расчёт', description: 'Оценим стоимость и сроки без скрытых допущений'
}} /> }} />
</div> </div>
@@ -106,8 +107,8 @@ const DiscussSection = () => {
</div> </div>
<div className='flex justify-center'> <div className='flex justify-center mt-auto px-8'>
<img src='/assets/withLogo.png' /> <img className='' src='/assets/withLogo.png' />
</div> </div>
</div> </div>
</section> </section>

View File

@@ -15,8 +15,8 @@ const Footer = () => {
<span className='text-2xl text-base-content'>Компания</span> <span className='text-2xl text-base-content'>Компания</span>
<a href='#about' className='text-base-content/70 hover:text-blue-500'>О компании</a> <a href='#about' className='text-base-content/70 hover:text-blue-500'>О компании</a>
<a href='#products' className='text-base-content/70 hover:text-blue-500'>Программные продукты</a> <a href='#products' className='text-base-content/70 hover:text-blue-500'>Программные продукты</a>
<a href='#seervices' className='text-base-content/70 hover:text-blue-500'>Услуги</a> <a href='#services' className='text-base-content/70 hover:text-blue-500'>Услуги</a>
<a href='#case' className='text-base-content/70 hover:text-blue-500'>Портфолио</a> <a href='#license' className='text-base-content/70 hover:text-blue-500'>Документы</a>
</div> </div>
<section id="contacts" className='flex flex-col text-nowrap gap-4 text-base-content/70'> <section id="contacts" className='flex flex-col text-nowrap gap-4 text-base-content/70'>
@@ -38,7 +38,7 @@ const Footer = () => {
</span> </span>
<div className='flex flex-col text-base-content/70'> <div className='flex flex-col text-base-content/70'>
<a className="hover:text-blue-500" target="_blank" href='/legal/Политика_обработки_персональныханных_КОММИТ.pdf'>Политика обработки персональных данных</a> <a className="hover:text-blue-500" target="_blank" href='/assets/legal/Политика_обработки_персональныханных_КОММИТ.pdf'>Политика обработки персональных данных</a>
</div> </div>
</div> </div>

View File

@@ -11,7 +11,7 @@ const LicenseSection = () => {
return ( return (
<section id='license' className='max-w-7xl w-full h-auto px-2 xl:px-0'> <section id='license' className='max-w-7xl w-full h-auto px-2 xl:px-0'>
<div className='w-full h-auto flex flex-col items-center py-8 bg-base-200 rounded-2xl'> <div className='w-full h-auto flex flex-col items-center pb-8 bg-base-200 rounded-2xl'>
<span className='px-4 text-3xl sm:text-4xl sm:text-center my-8'> <span className='px-4 text-3xl sm:text-4xl sm:text-center my-8'>
<span className='text-blue-500'>Наши</span> лицензии и сертификаты <span className='text-blue-500'>Наши</span> лицензии и сертификаты
</span> </span>

View File

@@ -6,7 +6,7 @@ const Navbar = () => {
</div> </div>
<nav className='p-4 hidden lg:flex items-center'> <nav className='p-4 hidden lg:flex items-center'>
<a href="#about" className='text-sm mx-4 text-base-content/70 hover:text-blue-500'>О компании</a> <a href="#about" className='text-sm mx-4 text-base-content/70 hover:text-blue-500'>О компании</a>
<a href="#products" className='text-sm mx-4 text-base-content/70tent/70 hover:text-blue-500'>Программные продукты</a> <a href="#products" className='text-sm mx-4 text-base-content/70 hover:text-blue-500'>Программные продукты</a>
<a href="#services" className='text-sm mx-4 text-base-content/70 hover:text-blue-500'>Услуги</a> <a href="#services" className='text-sm mx-4 text-base-content/70 hover:text-blue-500'>Услуги</a>
<a href="#case" className='text-sm mx-4 text-base-content/70 hover:text-blue-500'>Главный кейс</a> <a href="#case" className='text-sm mx-4 text-base-content/70 hover:text-blue-500'>Главный кейс</a>
<a href="#contacts" className='text-sm mx-4 btn text-white rounded-full font-light not-disabled:bg-[#1C8EFF]'>Контакты</a> <a href="#contacts" className='text-sm mx-4 btn text-white rounded-full font-light not-disabled:bg-[#1C8EFF]'>Контакты</a>

View File

@@ -63,7 +63,7 @@ const ProductsSection = () => {
</span> </span>
</div> </div>
<div className='grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-8'> <div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8'>
{products.map(product => ( {products.map(product => (
<motion.div <motion.div
whileHover={{ whileHover={{

View File

@@ -30,9 +30,9 @@ const ServiceItem = ({ service }: {
style={{ style={{
opacity: opacity opacity: opacity
}} }}
className='col-span-1 text-5xl sm:text-8xl leading-12 sm:leading-20 text-blue-500 sm:text-base-content/10 sm:group-hover:text-blue-500 transition-colors'>{service.id}</motion.span> className='col-span-1 text-5xl lg:text-8xl leading-12 lg:leading-20 text-blue-500 lg:text-base-content/10 lg:group-hover:text-blue-500 transition-colors'>{service.id}</motion.span>
<span className='col-span-3 sm:col-span-1 text-2xl sm:text-xl'>{service.title}</span> <span className='col-span-3 lg:col-span-1 text-2xl lg:text-xl'>{service.title}</span>
<div className='row-start-2 sm:row-start-1 col-span-4 sm:col-start-3 sm:col-span-2 flex flex-col gap-4'> <div className='row-start-2 lg:row-start-1 col-span-4 lg:col-start-3 lg:col-span-2 flex flex-col gap-4'>
{service.descriptions.map(desc => ( {service.descriptions.map(desc => (
<div className='flex flex-row gap-2'> <div className='flex flex-row gap-2'>
<svg className='shrink-0' width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg className='shrink-0' width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -61,7 +61,7 @@ const ServicesSection = () => {
id: '02', id: '02',
title: 'ИТ-аутсорсинг и инфраструктура', title: 'ИТ-аутсорсинг и инфраструктура',
descriptions: [ descriptions: [
'Обсуждение АРМ (ПК, моноблоки), серверов и оргтехники', 'Обслуживание АРМ (ПК, моноблоки), серверов и оргтехники',
'Администрирование локальных сетей и IP-телефонии', 'Администрирование локальных сетей и IP-телефонии',
'Обеспечение ИТ-безопасности (антивирусная защита, резервное копирование)' 'Обеспечение ИТ-безопасности (антивирусная защита, резервное копирование)'
] ]
@@ -78,7 +78,8 @@ const ServicesSection = () => {
id: '04', id: '04',
title: '1С: Франчайзинг', title: '1С: Франчайзинг',
descriptions: [ descriptions: [
'Продажа лицензий, внедрение и доработка конфигураций (1С: Управление холдингом, 1С: ЗУП, 1С: Бухгалтерия)' 'Продажа лицензий, внедрение и доработка конфигураций',
'1С: Управление холдингом, 1С: ЗУП, 1С: Бухгалтерия'
] ]
} }
] ]
@@ -86,11 +87,11 @@ const ServicesSection = () => {
return ( return (
<section id='services' className='max-w-7xl w-full h-auto'> <section id='services' className='max-w-7xl w-full h-auto'>
<div className='w-full h-auto flex flex-col items-center mb-8'> <div className='w-full h-auto flex flex-col items-center mb-8'>
<span className='px-4 text-3xl sm:text-4xl sm:text-center my-8'> <span className='px-4 text-3xl lg:text-4xl lg:text-center my-8'>
<span className='text-blue-500'>Предоставляемые услуги</span> нашей компании <span className='text-blue-500'>Предоставляемые услуги</span> нашей компании
</span> </span>
<div className='h-full grid grid-cols-1 sm:grid-cols-3 font-light sm:gap-4 p-2 xl:p-0'> <div className='h-full grid grid-cols-1 lg:grid-cols-3 font-light lg:gap-4 p-2 xl:p-0'>
<div className='flex flex-col gap-8'> <div className='flex flex-col gap-8'>
<div className='bg-blue-500 flex flex-col gap-6 p-10 col-span-1 rounded-2xl overflow-hidden'> <div className='bg-blue-500 flex flex-col gap-6 p-10 col-span-1 rounded-2xl overflow-hidden'>
<div className='bg-base-300/50 py-2 px-4 flex w-min rounded-3xl'> <div className='bg-base-300/50 py-2 px-4 flex w-min rounded-3xl'>
@@ -112,7 +113,7 @@ const ServicesSection = () => {
</div> </div>
</div> </div>
<div className='my-8 sm:my-0 flex flex-col gap-4 col-span-2 rounded-2xl overflow-hidden'> <div className='my-8 lg:my-0 flex flex-col gap-4 col-span-2 rounded-2xl overflow-hidden'>
{services.map(service => ( {services.map(service => (
<ServiceItem service={service} /> <ServiceItem service={service} />
))} ))}

View File

@@ -1,57 +0,0 @@
.wrapper {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
.card {
top: 30px;
position: sticky;
border: 1px solid #ccc;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.1);
background-color: white;
color: #333;
padding: 40px;
border-radius: 10px;
margin-bottom: 20px;
}
.card h2 {
padding: 0;
}
.card span {
display: block;
font-size: 14px;
color: #0c4eb9;
}
.card:nth-child(1n) {
top: 20px;
}
.card:nth-child(2n) {
top: 40px;
}
.card:nth-child(3n) {
top: 60px;
}
.card:nth-child(4n) {
top: 80px;
}
.card:nth-child(5n) {
top: 100px;
}
.card:nth-child(6n) {
top: 120px;
}
.card:nth-child(7n) {
top: 140px;
}
.card:nth-child(8n) {
top: 160px;
}

View File

@@ -1,35 +1,49 @@
import './StackSection.css' import { motion } from 'motion/react'
import Braces from './Braces'
const items = [
{ id: 1, color: "#ff0088", label: "Из идеи — в работающую концепцию", description: 'Мы погружаемся в задачу, формируем понятную и реализуемую концепцию и сразу определяем дальнейшие шаги', image: "/assets/idea-BxLjsotP.png" },
{ id: 2, color: "#dd00ee", label: "Цены и процессы — без сюрпризов", description: 'Заранее фиксируем стоимость, этапы и зону ответственности, чтобы вы всегда понимали, за что платите и какой результат будет получен', image: "/assets/money-DcU00l9G.png" },
{ id: 3, color: "#9911ff", label: "Ориентируемся на результат", description: 'Каждое решение мы строим так, чтобы приносить измеримый результат и реальную ценность вашему бизнесу', image: "/assets/goal-BRVwp_WA.png" },
{ id: 4, color: "#0d63f8", label: "Контролируем сбои и устраняем", description: 'Мы оперативно реагируем на любые сбои, быстро устраняем их и гарантируем, что ваш проект всегда остаётся под полным контролем', image: "/assets/info-CE1fB6DT.png" },
]
const StackSection = () => { const StackSection = () => {
return ( return (
<div className="wrapper h-auto max-h-full"> <div className="h-auto max-h-full w-full max-w-7xl">
<div className="card"> <div className='sticky top-24 w-full flex justify-center'>
<h2><span>Project #1</span>Title of the Project</h2> <span className='px-4 text-3xl sm:text-4xl py-2 sm:text-center'>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Harum, perspiciatis blanditiis accusamus commodi consectetur id tempora rem iure eligendi quos eos et autem ratione exercitationem earum laborum ad a sequi!</p> <span className='text-blue-500'>Преимущества</span> работы с нами
</div> </span>
<div className="card">
<h2><span>Project #2</span>Title of the Project</h2>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Harum, perspiciatis blanditiis accusamus commodi consectetur id tempora rem iure eligendi quos eos et autem ratione exercitationem earum laborum ad a sequi!</p>
</div>
<div className="card">
<h2><span>Project #3</span>Title of the Project</h2>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Harum, perspiciatis blanditiis accusamus commodi consectetur id tempora rem iure eligendi quos eos et autem ratione exercitationem earum laborum ad a sequi!</p>
</div>
<div className="card">
<h2><span>Project #4</span>Title of the Project</h2>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Harum, perspiciatis blanditiis accusamus commodi consectetur id tempora rem iure eligendi quos eos et autem ratione exercitationem earum laborum ad a sequi!</p>
</div>
<div className="card">
<h2><span>Project #5</span>Title of the Project</h2>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Harum, perspiciatis blanditiis accusamus commodi consectetur id tempora rem iure eligendi quos eos et autem ratione exercitationem earum laborum ad a sequi!</p>
</div>
<div className="card">
<h2><span>Project #6</span>Title of the Project</h2>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Harum, perspiciatis blanditiis accusamus commodi consectetur id tempora rem iure eligendi quos eos et autem ratione exercitationem earum laborum ad a sequi!</p>
</div>
<div className="card">
<h2><span>Project #7</span>Title of the Project</h2>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Harum, perspiciatis blanditiis accusamus commodi consectetur id tempora rem iure eligendi quos eos et autem ratione exercitationem earum laborum ad a sequi!</p>
</div> </div>
{items.map((item, index) => (
<motion.div
key={item.id}
className='sticky top-7.5 grid grid-rows-[min-content_min-content_min-content_1fr] gap-2 px-8 pt-4 min-w-full w-full shrink-0 overflow-visible rounded-2xl bg-base-200 outline-2 outline-base-100'
style={{
//marginLeft: `${xValue * index}px`,
//zIndex: index,
top: `${(index + 1) * 20 + 160}px`
}}
>
<Braces text={(index + 1).toString()} />
<span className='text-xl'>
{item.label}
</span>
<span className="text-base-content/70">
{item.description}
</span>
<img className='mt-auto ml-auto' src={item.image} />
{/* <div className='absolute left-0 top-0 bottom-0 -right-8 rounded-2xl bg-base-200 outline-2 outline-base-100 -z-10 w-auto h-full'>
</div> */}
</motion.div>
))}
</div> </div>
) )
} }