refactoring, fixes

This commit is contained in:
2024-07-19 14:42:44 +05:00
parent 99dcce1271
commit 4d5703b71f
25 changed files with 171 additions and 175 deletions
+4 -4
View File
@@ -3,10 +3,10 @@ import LogoWithTextIcon from '../icons/LogoWithTextIcon';
export function Footer() {
return (
<footer className="sm:grid xl:grid-cols-[2fr_1fr_1fr] sm:max-xl:grid-cols-2 sm:max-xl:grid-rows-2">
<div className="flex sm:items-center mobile:max-sm:flex-col sm:px-10 mobile:px-4 sm:py-9 mobile:py-4 border-t border-[#3D425C] gap-6 sm:max-xl:row-start-1 sm:max-xl:col-span-2">
<Link to={'/'} className="h-[50px]">
<LogoWithTextIcon />
<footer className="sm:grid xl:grid-cols-[2fr_1fr_1fr] sm:grid-cols-2 sm:max-xl:grid-rows-2">
<div className="flex sm:items-center max-sm:flex-col sm:px-10 px-4 sm:py-9 py-4 border-t border-[#3D425C] gap-6 sm:max-xl:row-start-1 sm:max-xl:col-span-2">
<Link to={'/'}>
<LogoWithTextIcon className="h-[50px]" />
</Link>
<div className="flex flex-col gap-y-1">
<Link
+7 -8
View File
@@ -32,11 +32,10 @@ export function Header() {
return (
<header>
<nav className="flex items-stretch justify-between border-b border-[#3D425C] lg:pl-10 mobile:pl-4 lg:min-h-[72px] mobile:min-h-16">
<nav className="flex items-stretch justify-between border-b border-[#3D425C] lg:pl-10 pl-4 lg:min-h-[72px] min-h-16">
<Link to={'/'} className="flex items-center">
<LogoWithTextIcon className="sm:block hidden" />
<LogoIcon className="sm:hidden" />
{/* {width >= 1024 && <LogoWithTextIcon />} */}
<LogoIcon className="lg:hidden" />
{width >= 1024 && <LogoWithTextIcon />}
</Link>
<div className="flex">
<AnchorLink route="#products">Типы тренажеров</AnchorLink>
@@ -45,7 +44,7 @@ export function Header() {
<AnchorLink route="#events">События</AnchorLink>
<Button
onClick={() => setModal(<ModalWithForm />)}
className="rounded-none btn-text font-semibold sm:block mobile:hidden px-10"
className="rounded-none btn-text font-semibold max-sm:hidden px-10"
>
Оставить заявку
</Button>
@@ -53,7 +52,7 @@ export function Header() {
<button
ref={menuBtnRef}
onClick={() => setMenuOpen(prev => !prev)}
className="px-6 py-5 min-[1350px]:hidden mobile:block border-[#3D425C] mobile:max-sm:border-l"
className="px-6 py-5 min-[1350px]:hidden border-[#3D425C] max-sm:border-l"
>
{!menuOpen ? <BurgerIcon /> : <CloseIcon />}
</button>
@@ -76,7 +75,7 @@ export function Header() {
<BurgerAnchor route="#projects">Проекты</BurgerAnchor>
<BurgerAnchor route="#events">События</BurgerAnchor>
</div>
<div className="grid mobile:max-sm:grid-cols-[216px_1fr_1fr] sm:grid-cols-2 ">
<div className="grid grid-cols-[2fr_1fr_1fr] sm:grid-cols-2">
<Button
onClick={() => {
setMenuOpen(false);
@@ -135,7 +134,7 @@ function LangToggler({ lang }: { lang: Lang }) {
return (
<div
ref={langTogglerRef}
className="min-w-[101px] mobile:max-[1349px]:hidden hover:bg-[#3D425C] active:bg-[#14161F]"
className="min-w-[101px] max-[1349px]:hidden hover:bg-[#3D425C] active:bg-[#14161F]"
>
<button
onClick={() => setOpen(prev => !prev)}
+2 -2
View File
@@ -6,7 +6,7 @@ import ModalContainer from '../Main/ModalContainer';
export default function Layout() {
return (
<div className="bg-[#14161F]">
<>
<Header />
<Motivation />
<main>
@@ -14,6 +14,6 @@ export default function Layout() {
</main>
<Footer />
<ModalContainer />
</div>
</>
);
}
+12 -11
View File
@@ -9,18 +9,18 @@ import { getIcon } from '../../utils/getIcon';
export function Availables() {
return (
<div className="lg:py-[70px] lg:px-10 mobile:py-14 sm:px-6 mobile:px-4">
<Title className="desktop-figma:mb-[77px] lg:mb-14 mobile:mb-6">
<span className="text-gradient">Многопользовательский</span>
<div className="lg:py-[70px] lg:px-10 py-14 sm:px-6 px-4 overflow-hidden">
<Title className="desktop-figma:mb-[77px] lg:mb-14 mb-6">
<span className="text-gradient text-wrap">Многопользовательский</span>
<br />
режим обучения
</Title>
<AppearanceHr className="mobile:max-sm:hidden" />
<div className="flex mobile:max-lg:flex-col items-start lg:w-fit sm:pt-5">
<AppearanceHr className="max-sm:hidden" />
<div className="flex max-lg:flex-col items-start lg:w-fit sm:pt-5">
<MiniTitle text="возможности" />
<AppearanceHr className="sm:hidden w-full mt-2" />
<div className="sm:max-desktop-figma:mt-4 mobile:max-sm:mt-2">
<div className="flex mobile:max-sm:flex-col mobile:max-sm:gap-y-2 lg:gap-x-4 sm:max-lg:gap-x-3 sm:pb-5 mobile:pb-2 mobile:max-sm:pt-2">
<AppearanceHr className="sm:hidden w-full mt-2" />
<div className="sm:max-desktop-figma:mt-4 max-sm:mt-2">
<div className="flex max-sm:flex-col max-sm:gap-y-2 lg:gap-x-4 sm:gap-x-3 sm:pb-5 pb-2 max-sm:pt-2">
<MultiUserFeature
type="processes"
text="отработка производственных процессов, в которых участвует группа людей"
@@ -65,7 +65,9 @@ function MultiUserFeature({
}) {
const ref = useRef<HTMLDivElement>(null);
const hovered = useHover(ref);
const isInView = useInView(ref, { margin: '33%' });
const isInView = useInView(ref, {
margin: `0px 0px -${window.innerHeight - (ref.current?.clientHeight ?? 0)}px`,
});
return (
<motion.div
@@ -73,10 +75,9 @@ function MultiUserFeature({
backgroundImage: 'url(src/assets/efficiency_backlight.svg)',
backgroundSize: '100% 100%',
}}
animate={{}}
transition={{ duration: 0.075 }}
ref={ref}
className="bg-right-bottom bg-no-repeat flex flex-col bg-[length:100%_0%] desktop-figma:max-w-[22vw] w-full justify-between items-start p-6 bg-[#3D425C4D] rounded-2xl lg:min-h-[214px] sm:min-h-[240px] mobile:min-h-[220px]"
className="bg-right-bottom bg-no-repeat flex flex-col bg-[length:100%_0%] desktop-figma:max-w-[22vw] w-full justify-between items-start p-6 bg-[#3D425C4D] rounded-2xl lg:min-h-[214px] sm:min-h-[240px] min-h-[220px]"
>
{getIcon(type, hovered || isInView, 'mb-4')}
<p className="l-text desktop-figma:max-w-[70%]">{text}</p>
+7 -7
View File
@@ -8,11 +8,11 @@ import ContactsForm from './ContactsForm';
export function Contacts() {
return (
<div className="lg:py-[70px] lg:px-10 mobile:py-14 sm:px-6 mobile:px-4 lg:flex justify-between gap-x-4">
<div className="lg:py-[70px] lg:px-10 py-14 sm:px-6 px-4 lg:flex justify-between gap-x-4">
<div>
<div className="lg:flex gap-x-4">
<div className="sm:max-lg:grid grid-cols-2 mobile:max-lg:mb-6">
<h1 className="w-fit text-gradient lg:mb-6 mobile:max-sm:mb-4 2xl:text-[64px] xl:text-5xl text-[40px] leading-none">
<div className="sm:max-lg:grid grid-cols-2 max-lg:mb-6">
<h1 className="w-fit text-gradient lg:mb-6 max-sm:mb-4 2xl:text-[64px] xl:text-5xl text-[40px] leading-none">
Свяжитесь
<br />с нами
</h1>
@@ -84,8 +84,8 @@ export function Contacts() {
</div>
</div>
</div>{' '}
{/* <div className="sm:max-lg:mb-20 mobile:mb-14">
<Title className="desktop-figma:mb-[77px] lg:mb-[68px] desktop-figma:max-w-[899px] lg:max-w-[720px] mobile:mb-6">
{/* <div className="sm:max-lg:mb-20 mb-14">
<Title className="desktop-figma:mb-[77px] lg:mb-[68px] desktop-figma:max-w-[899px] lg:max-w-[720px] mb-6">
Хотите использовать интерактивные тренажеры в обучении?
<br />
<span
@@ -96,7 +96,7 @@ export function Contacts() {
</Title>
<button
onClick={() => setModal(<ContactsForm />)}
className="bg-gradient-to-r from-[#798FFF] to-[#D375FF] rounded-[104px] py-4 px-6 flex font-semibold text-[#ffffff] justify-between desktop-figma:min-w-[23vw] lg:max-desktop-figma:min-w-[368px] sm:max-lg:min-w-[332px] mobile:max-sm:w-full items-center btn-text"
className="bg-gradient-to-r from-[#798FFF] to-[#D375FF] rounded-[104px] py-4 px-6 flex font-semibold text-[#ffffff] justify-between desktop-figma:min-w-[23vw] lg:max-desktop-figma:min-w-[368px] sm:max-lg:min-w-[332px] max-sm:w-full items-center btn-text"
>
Оставить заявку <img src="src/assets/send.svg" alt="" />
</button>
@@ -104,7 +104,7 @@ export function Contacts() {
<div className="min-w-[31.69vw] sm:max-lg:flex items-stretch justify-between gap-x-4">
<div className="lg:min-w-[20.75vw] sm:w-full">
<p className="text-[#ffffff] mb-4 l-text">Свяжитесь с нами</p>
<div className="flex flex-col gap-y-3 lg:mb-20 mobile:max-sm:mb-6">
<div className="flex flex-col gap-y-3 lg:mb-20 max-sm:mb-6">
<Link
to={'mailto:info@graff.tech'}
className="text-[#ffffff] font-semibold py-4 px-6 flex items-center justify-between rounded-[104px] border border-[#3D425C] btn-text"
+5 -7
View File
@@ -85,7 +85,7 @@ export default function ContactsForm({
}
className={
(!inModal
? 'sm:border-l-0 lg:border-x-0 border mobile:max-sm:border-t-0 '
? 'sm:border-l-0 lg:border-x-0 border max-sm:border-t-0 '
: 'border-x ') +
'feedback-field bg-transparent rounded-none border-[#3D425C] sm:pt-12 sm:pb-4 sm:px-4 pt-8 pb-3 px-3 outline-none outline-1 -outline-offset-1 focus:outline-[#D375FF] transition-all w-full'
}
@@ -105,7 +105,7 @@ export default function ContactsForm({
value={email}
onChange={e => setEmail(e.target.value)}
className={
(!inModal ? 'mobile:max-lg:border-t-0' : '') +
(!inModal ? 'max-lg:border-t-0' : '') +
' feedback-field bg-transparent border rounded-none border-[#3D425C] sm:pt-12 sm:pb-4 sm:px-4 pt-8 pb-3 px-3 outline-none outline-1 -outline-offset-1 focus:outline-[#D375FF] transition-all w-full'
}
/>
@@ -130,7 +130,7 @@ export default function ContactsForm({
<div
className={
!inModal ? 'col-start-1 mobile:max-lg:hidden pt-4 pr-4' : 'hidden'
!inModal ? 'col-start-1 max-lg:hidden pt-4 pr-4' : 'hidden'
}
>
<Button
@@ -152,7 +152,7 @@ export default function ContactsForm({
<div
className={
(!inModal
? 'border sm:border-r-0 mobile:max-sm:border-b-0 sm:border-t-0 lg:col-start-2 mobile:max-sm:mt-6'
? 'border sm:border-r-0 max-sm:border-b-0 sm:border-t-0 lg:col-start-2 max-sm:mt-6'
: 'mt-6 border-x') +
' border-[#3D425C] 2xl:p-6 p-4 sm:mt-0 flex items-center'
}
@@ -179,9 +179,7 @@ export default function ContactsForm({
<div
className={
(!inModal
? 'sm:border-t-0 mobile:max-sm:border-t lg:col-start-3'
: '') +
(!inModal ? 'sm:border-t-0 border-t lg:col-start-3' : '') +
' border border-[#3D425C] 2xl:p-6 p-4 sm:mt-0 text-xs desktop-figma:text-base flex items-center gap-2 '
}
>
+5 -5
View File
@@ -3,8 +3,8 @@ import { Title } from '../../ui/Title';
export function Decreasing() {
return (
<div className="lg:py-[70px] mobile:py-14 lg:px-10 sm:px-6 mobile:px-4">
<Title className="sm:block mobile:max-sm:hidden">
<div className="lg:py-[70px] py-14 lg:px-10 sm:px-6 px-4">
<Title className="max-sm:hidden">
<span className="text-gradient">Достигайте положительный эффект</span>
<br /> за счет снижения издержек
</Title>
@@ -12,8 +12,8 @@ export function Decreasing() {
<span className="text-gradient">Помогаем</span> сократить затраты на
обучение, повысить безопасность и производительность
</Title>
<div className="flex md:flex-row mobile:max-md:flex-col justify-normal desktop-figma:gap-x-[10vw] md:max-desktop-figma:gap-x-[clamp(16px,16px+(100vw-1024px)/576*142,160px)] desktop-figma:max-w-[calc(70.8vw+256px)] desktop-figma:justify-between sm:items-end xl:pl-64 desktop-figma:mt-[77px] lg:mt-14 mobile:mt-6">
<ul className="xl:max-w-[47vw] w-full sm:min-w-[318px] mobile:mb-6">
<div className="flex max-md:flex-col justify-normal desktop-figma:gap-x-[10vw] md:max-desktop-figma:gap-x-[clamp(16px,16px+(100vw-1024px)/576*142,160px)] desktop-figma:max-w-[calc(70.8vw+256px)] desktop-figma:justify-between sm:items-end xl:pl-64 desktop-figma:mt-[77px] lg:mt-14 mt-6">
<ul className="xl:max-w-[47vw] w-full sm:min-w-[318px] mb-6">
<DecreasingOption
text="снижение количества несчастных случаев"
number="[01]"
@@ -34,7 +34,7 @@ export function Decreasing() {
</ul>
<img
src="src/assets/effect.png"
className="mobile:max-md:self-center mobile:max-md:w-full object-contain"
className="max-md:self-center max-md:w-full object-contain"
alt="снижение издержек"
/>
</div>
+4 -4
View File
@@ -2,15 +2,15 @@ import { Title } from '../../ui/Title';
export function Distance() {
return (
<div className="lg:py-[70px] lg:px-10 mobile:py-14 sm:px-6 mobile:px-4">
<Title className="desktop-figma:mb-[77px] lg:mb-14 sm:mb-6 mobile:mb-4">
<div className="lg:py-[70px] lg:px-10 py-14 sm:px-6 px-4">
<Title className="desktop-figma:mb-[77px] lg:mb-14 sm:mb-6 mb-4">
Платформа GRAFF.training поволяет осуществлять{' '}
<span className="text-gradient">дистанционное обучение</span> с любого
устройства
</Title>
<div className="xl:pl-64">
<div className="sm:grid lg:gap-x-4 lg:gap-y-6 sm:gap-x-3 sm:gap-y-4 lg:grid-cols-2 md:max-[956px]:grid-cols-[446px_1fr]">
<p className="row-start-1 mobile:max-sm:mb-6 l-text">
<p className="row-start-1 max-sm:mb-6 l-text">
Обучающиеся будут получать доступ к системе с высоко
детализированной 3D графикой для прохождения сценариев на любом
устройстве, без необходимости установки дополнительного ПО.
@@ -18,7 +18,7 @@ export function Distance() {
<img
src="src/assets/datamining_2.png"
alt="дистанционное обучение с любого устройства"
className="row-start-2 mobile:max-sm:mb-4 w-full"
className="row-start-2 max-sm:mb-4 w-full"
/>
<img
src="src/assets/datamining_1.png"
+8 -8
View File
@@ -6,12 +6,12 @@ import { useEffect, useRef } from 'react';
export function Effeciency() {
return (
<div className="lg:py-[70px] mobile:py-14 lg:px-10 sm:px-6 mobile:px-4">
<AppearanceHr className="mobile:max-sm:hidden" />
<div className="flex mobile:max-lg:flex-col pt-5 sm:max-lg:gap-4">
<div className="lg:py-[70px] py-14 lg:px-10 sm:px-6 px-4">
<AppearanceHr className="max-sm:hidden" />
<div className="flex max-lg:flex-col pt-5 sm:max-lg:gap-4">
<MiniTitle text={'экономическая эффективность'} />
<div className="mobile:max-sm:mt-4">
<div className="flex mobile:max-sm:flex-col lg:max-desktop-figma:w-[clamp(728px,728px+(100vw-1024px)/576*405,1133px)] justify-stretch gap-x-4 gap-y-2 mobile:max-sm:py-5 sm:pb-5">
<div className="max-sm:mt-4">
<div className="flex max-sm:flex-col lg:max-desktop-figma:w-[clamp(728px,728px+(100vw-1024px)/576*405,1133px)] justify-stretch gap-x-4 gap-y-2 max-sm:py-5 sm:pb-5">
<Figure
percents={50}
title={'сокращение бюджета на обучение сотрудников'}
@@ -93,13 +93,13 @@ function Figure({
}}
className="flex px-6 bg-[#3D425C4D] desktop-figma:max-w-[22vw] w-full rounded-2xl pt-6 bg-no-repeat bg-[position:bottom_right_24px,bottom_right] h-[262px]"
>
<div className="flex flex-col justify-between py-6 mobile:max-sm:max-w-[50vw]">
<div className="flex flex-col justify-between py-6 max-sm:max-w-[50vw]">
<h3 className="lg:font-medium l-text desktop-figma:max-w-[70%]">
{title}
</h3>
<h1 className="font-medium flex items-center md:text-[clamp(64px,64px+(100vw-768px)/832*32,96px)] md:leading-[clamp(57.6px,57.6px+(100vw-768px)/832*28.8,86.4px)] mobile:text-[64px] mobile:leading-[57.6px]">
<h1 className="font-medium flex items-center md:text-[clamp(64px,64px+(100vw-768px)/832*32,96px)] md:leading-[clamp(57.6px,57.6px+(100vw-768px)/832*28.8,86.4px)] text-[64px] leading-[57.6px]">
<span ref={figureRef}>{percents}</span>
<span className="md:text-[clamp(32px,32px+(100vw-768px)/832*32,64px)] md:leading-[clamp(32px,32px+(100vw-768px)/832*25.6,57.6px)] mobile:text-[32px] mobile:leading-8">
<span className="md:text-[clamp(32px,32px+(100vw-768px)/832*32,64px)] md:leading-[clamp(32px,32px+(100vw-768px)/832*25.6,57.6px)] text-[32px] leading-8">
%
</span>
</h1>
+11 -14
View File
@@ -8,21 +8,18 @@ import ArrowInsertIcon from '../icons/ArrowInsertIcon';
export function Events() {
return (
<div
className="lg:py-[70px] lg:px-10 sm:py-14 sm:px-6 mobile:px-4"
id="events"
>
<AppearanceHr className="mobile:max-lg:hidden" />
<div className="flex mobile:max-lg:flex-col pt-5 gap-x-4 w-full">
<MiniTitle text="события" className="mobile:max-sm:mb-2" />
<div className="lg:py-[70px] lg:px-10 sm:py-14 sm:px-6 px-4" id="events">
<AppearanceHr className="max-lg:hidden" />
<div className="flex max-lg:flex-col pt-5 gap-x-4 w-full">
<MiniTitle text="события" className="max-sm:mb-2" />
<div className="lg:max-desktop-figma:min-w-[clamp(688px,688px+(100vw-1024px)/576*425,1133px)] desktop-figma:min-w-[70.9vw]">
<AppearanceHr className="sm:hidden" />
<div className="lg:py-7 sm:max-lg:py-6 mobile:max-sm:py-5 flex justify-between mobile:max-sm:flex-col items-start gap-x-4">
<div className="lg:py-7 sm:py-6 py-5 flex justify-between max-sm:flex-col items-start gap-x-4">
<div className="w-fit">
<EventTitle className="sm:mb-8 w-fit">
Макет кабины машиниста «Иволга» на выставке ВДНХ
</EventTitle>
<div className="flex items-start gap-2 mobile:max-sm:mt-5 w-fit">
<div className="flex items-start gap-2 max-sm:mt-5 w-fit">
<img
src="src/assets/ivolga.png"
className="rounded-2xl w-[calc(584/1133*100%)]"
@@ -30,7 +27,7 @@ export function Events() {
/>
<img
src="src/assets/ivolga_mini.png"
className="rounded-2xl mobile:max-md:hidden w-[calc(286/1133*100%)]"
className="rounded-2xl max-md:hidden w-[calc(286/1133*100%)]"
alt="Иволга"
/>
</div>
@@ -38,12 +35,12 @@ export function Events() {
<LinkButton href="/" />
</div>
<AppearanceHr />
<div className="py-7 flex mobile:max-sm:flex-col sm:items-center justify-between gap-x-4">
<div className="py-7 flex max-sm:flex-col sm:items-center justify-between gap-x-4">
<EventTitle>Победа на BuildUP 2023 в номинации IT</EventTitle>
<LinkButton href="/" />
</div>
<AppearanceHr />
<div className="py-7 flex mobile:max-sm:flex-col sm:items-center justify-between gap-x-4">
<div className="py-7 flex max-sm:flex-col sm:items-center justify-between gap-x-4">
<EventTitle>
Транспортное и специальное тренажеростроение 2023
</EventTitle>
@@ -72,7 +69,7 @@ function LinkButton({ href }: { href: string }) {
<Link
to={href}
ref={ref}
className=" text-nowrap opacity-60 uppercase flex items-center w-fit lg:min-w-[min(133px,fit)] gap-x-2 sm:max-lg:min-w-[140px] mobile:max-sm:self-end link mobile:max-sm:mt-4"
className=" text-nowrap opacity-60 uppercase flex items-center w-fit lg:min-w-[min(133px,fit)] gap-x-2 sm:min-w-[140px] max-sm:self-end link max-sm:mt-4"
>
как это было <ArrowInsertIcon />
</Link>
@@ -80,7 +77,7 @@ function LinkButton({ href }: { href: string }) {
{hovered && (
<AppearanceHr
delay={0}
className="w-full border-[#ffffff] opacity-60 mobile:max-lg:hidden"
className="w-full border-[#ffffff] opacity-60 max-lg:hidden"
/>
)}
</AnimatePresence>
+3 -3
View File
@@ -1,7 +1,7 @@
export function Marquee() {
return (
<div className="flex flex-nowrap w-full overflow-hidden lg:max-h-[100px] sm:max-h-[82px] mobile:max-h-20">
<div className="flex absolute z-40 right-0 mobile:max-sm:hidden">
<div className="flex flex-nowrap w-full overflow-hidden lg:max-h-[100px] sm:max-h-[82px] max-h-20">
<div className="flex absolute z-40 right-0 max-sm:hidden">
<div className="w-0 h-0 lg:border-b-[100px] lg:border-l-[100px] sm:border-b-[82px] sm:border-l-[82px] border-[transparent_transparent_#D0D6DF_transparent]" />
<div className="lg:w-[260px] sm:w-[216px] bg-[#D0D6DF]" />
</div>
@@ -42,7 +42,7 @@ function MarqueeHalf() {
function MarqueeItem({ src, alt }: { src: string; alt: string }) {
return (
<div className="lg:min-w-[212px] sm:min-w-[180px] mobile:min-w-[170px] flex border-l border-y border-[#3D425C] lg:first:py-[30px]">
<div className="lg:min-w-[212px] sm:min-w-[180px] min-w-[170px] flex border-l border-y border-[#3D425C] lg:first:py-[30px]">
<img src={src} className="m-auto" alt={alt} />
</div>
);
+4 -4
View File
@@ -3,16 +3,16 @@ import { Marquee } from '../Main/Marquee';
export function Motivation() {
return (
<div>
<div className="lg:px-10 sm:px-6 mobile:px-4 lg:py-28 sm:py-12 mobile:py-14">
<h1 className="desktop-figma:mb-[38px] pb-8 font-medium lg:block mobile:max-lg:hidden h1">
<div className="lg:px-10 sm:px-6 px-4 lg:py-28 sm:py-12 py-14">
<h1 className="desktop-figma:mb-[38px] pb-8 font-medium lg:block max-lg:hidden h1">
Создаем <span className="text-gradient">интерактивные тренажеры</span>{' '}
для промышленности и образования
</h1>
<h1 className="font-medium lg:hidden mobile:max-lg:block h1">
<h1 className="font-medium lg:hidden h1">
Интерактивные тренажеры{' '}
<span className="text-gradient">для обучения сотрудников</span>
</h1>
<h3 className="max-w-[768px] lg:block mobile:max-lg:hidden h3">
<h3 className="max-w-[768px] lg:block max-lg:hidden h3">
Помогаем сократить затраты на обучение, повысить безопасность и
производительность
</h3>
+4 -4
View File
@@ -27,9 +27,9 @@ export function Products() {
itemScope
itemType="https://graff.training/#products"
id="products"
className="lg:py-[70px] sm:max-lg:pt-14 sm:max-lg:pb-8 mobile:max-sm:py-14 lg:px-10 sm:max-lg:px-6 mobile:max-sm:px-4"
className="lg:py-[70px] sm:max-lg:pt-14 sm:max-lg:pb-8 max-sm:py-14 lg:px-10 sm:px-6 px-4"
>
<Title className="desktop-figma:mb-[77px] mb-14 lg:block mobile:hidden">
<Title className="desktop-figma:mb-[77px] mb-14 lg:block hidden">
Процесс обучения сотрудников станет безопасней и эффективней с
<span className="text-gradient"> продуктами GRAFF.training</span>
</Title>
@@ -37,9 +37,9 @@ export function Products() {
<MiniTitle className="lg:hidden" text="Продукты" />
<div
className={
'flex gax-y-4 bg-[#3D425C4D] bg-opacity-3 scrollbar-none rounded-xl p-1 mb-2 w-fit max-w-full overflow-auto sm:max-lg:mt-[13px] mobile:mt-6' +
'flex gax-y-4 bg-[#3D425C4D] bg-opacity-3 scrollbar-none rounded-xl p-1 mb-2 w-fit max-w-full overflow-auto sm:max-lg:mt-[13px] mt-6' +
(curTab !== 2
? ' mobile:max-[912px]:[-webkit-mask-image:_linear-gradient(to_left,rgba(32,35,50,0)_0%,rgba(32,35,50,1)_20%)]'
? ' max-[912px]:[-webkit-mask-image:_linear-gradient(to_left,rgba(32,35,50,0)_0%,rgba(32,35,50,1)_20%)]'
: '')
}
ref={ref}
@@ -1,12 +1,13 @@
import { useRef } from 'react';
import { useHover } from 'usehooks-ts';
import { getIcon } from '../../../../utils/getIcon';
import { useInView } from 'framer-motion';
export function ForTeachingTab() {
return (
<div className="lg:bg-[url('src/assets/mask_group2.png')] lg:aspect-[1520/546] sm:max-lg:aspect-[720/460] w-full lg:h-[max(534px,34vw)] md:max-lg:h-[min(460px,60vw)] sm:max-md:h-[max(460px,60vw)] mobile:max-sm:min-h-[746pxsdf] bg-[#3D425C4D] bg-no-repeat lg:p-10 sm:p-7 mobile:p-5 rounded-xl 2xl:bg-contain bg-right lg:max-2xl:bg-[length:50%]">
<div className='sm:max-lg:bg-[url("src/assets/mask_group2.png")] bg-no-repeat bg-right bg-[length:50%] sm:max-lg:pb-[55px] mobile:max-lg:border-b border-[#3D425C] sm:mb-8 mobile:mb-4'>
<h3 className=" font-medium lg:max-w-[455px] sm:max-w-[326px] mobile:max-sm:mb-0 h3">
<div className="lg:bg-[url('src/assets/mask_group2.png')] lg:aspect-[1520/546] sm:aspect-[720/460] w-full lg:h-[max(534px,34vw)] md:h-[min(460px,60vw)] sm:h-[max(460px,60vw)] max-sm:min-h-[746pxsdf] bg-[#3D425C4D] bg-no-repeat lg:p-10 sm:p-7 p-5 rounded-xl 2xl:bg-contain bg-right lg:bg-[length:50%]">
<div className='sm:max-lg:bg-[url("src/assets/mask_group2.png")] bg-no-repeat bg-right bg-[length:50%] sm:max-lg:pb-[55px] max-lg:border-b border-[#3D425C] sm:mb-8 mb-4'>
<h3 className=" font-medium lg:max-w-[455px] sm:max-w-[326px] max-sm:mb-0 h3">
Интерактивные тренажеры для учебных заведений
</h3>
<img
@@ -15,7 +16,7 @@ export function ForTeachingTab() {
alt="Интерактивные тренажеры для учебных заведений"
/>
</div>
<div className="flex lg:flex-col mobile:max-sm:flex-col lg:gap-y-6 mobile:gap-y-4 lg:mb-12 sm:max-lg:mb-8 mobile:max-sm:mb-4 sm:max-lg:border-b border-[#3D425C] sm:max-lg:pb-8">
<div className="flex lg:flex-col max-sm:flex-col lg:gap-y-6 gap-y-4 lg:mb-12 sm:mb-8 mb-4 sm:max-lg:border-b border-[#3D425C] sm:max-lg:pb-8">
<ForTeachingOption
title="cоздание обучающих VR систем"
description="Проведение виртуальных практических работ, создание учебных
@@ -48,19 +49,22 @@ function ForTeachingOption({
}) {
const ref = useRef<HTMLDivElement>(null);
const hovered = useHover(ref);
const isInView = useInView(ref, {
margin: `0px 0px -${window.innerHeight - (ref.current?.clientHeight ?? 0)}px`,
});
return (
<div
ref={ref}
className="flex gap-x-7 items-start lg:max-w-[437px] sm:w-fit sm:max-lg:pr-3 mobile:max-sm:pb-4 mobile:max-sm:border-b border-[#3D425C]"
className="flex gap-x-7 items-start lg:max-w-[437px] sm:w-fit sm:max-lg:pr-3 max-sm:pb-4 max-sm:border-b border-[#3D425C]"
>
{getIcon(type, hovered, 'mobile:max-lg:hidden min-w-11')}
{getIcon(type, hovered, 'max-lg:hidden min-w-11')}
<div className="lg:pl-4 sm:pl-[13px] sm:border-l border-[#3D425C]">
<div className="flex mobile:max-sm:items-center sm:items-start sm:max-lg:flex-col gap-x-2 mb-2">
{getIcon(type, hovered, 'lg:hidden min-w-11')}
<h4 className=" font-medium l-text">{title}</h4>
<div className="flex items-center sm:items-start sm:max-lg:flex-col gap-x-2 mb-2">
{getIcon(type, hovered || isInView, 'lg:hidden min-w-11')}
<h4 className="font-medium l-text">{title}</h4>
</div>
<p className=" opacity-60 lg:font-medium m-text">{description}</p>
<p className="opacity-60 lg:font-medium m-text">{description}</p>
</div>
</div>
);
@@ -49,14 +49,14 @@ export function SimulatorsTab() {
});
return (
<div className="bg-[#3D425C4D] rounded-xl flex lg:aspect-[1520/546] sm:max-lg:aspect-[720/460] mobile:max-sm:min-h-[746psfgx] w-full lg:h-[max(534px,34vw)] md:max-lg:h-[min(460px,60vw)] sm:max-md:h-[max(460px,60vw)] lg:p-10 sm:max-lg:p-7 mobile:max-sm:p-5 select-none mobile:max-sm:overflow-hidden">
<div className="flex sm:justify-between w-full h-full mobile:max-sm:flex-col mobile:max-sm:justify-between items-center gap-x-2">
<div className="bg-[#3D425C4D] rounded-xl flex lg:aspect-[1520/546] sm:aspect-[720/460] max-sm:min-h-[746psfgx] w-full lg:h-[max(534px,34vw)] md:h-[min(460px,60vw)] sm:h-[max(460px,60vw)] lg:p-10 sm:p-7 p-5 select-none max-sm:overflow-hidden">
<div className="flex sm:justify-between w-full h-full max-sm:flex-col items-center gap-x-2">
<div className="lg:max-w-[539px] sm:max-w-[50vw] self-start flex flex-col sm:max-lg:justify-between sm:max-lg:h-full">
<div className="flex flex-col">
<h3 className="sm:max-lg:max-w-[455px] font-medium h3 lg:mb-8 sm:mb-6 mobile:mb-5">
<h3 className="sm:max-lg:max-w-[455px] font-medium h3 lg:mb-8 sm:mb-6 mb-5">
Интерактивные симуляторы управления техникой
</h3>
<ul className="flex flex-wrap mobile:max-sm:grid lg:gap-2 mobile:max-lg:gap-1 lg:mb-12 mobile:max-sm:mb-5 sm:max-lg:max-w-[325px]">
<ul className="flex flex-wrap max-sm:grid lg:gap-2 gap-1 lg:mb-12 max-sm:mb-5 sm:max-lg:max-w-[325px]">
<SimulatorsItem text="авиационные симуляторы" />
<SimulatorsItem text="погрузчики – ричстракеры" />
<SimulatorsItem text="тяговые составы железной дороги" />
@@ -66,11 +66,11 @@ export function SimulatorsTab() {
</ul>
</div>
<div className="sm:max-lg:max-w-[455px]">
<h4 className="font-medium l-text lg:mb-2 mobile:max-sm:mb-3">
<h4 className="font-medium l-text lg:mb-2 max-sm:mb-3">
В основу симуляторов заложена математическая модель, полностью
соответствующая работе настоящего оборудования
</h4>
<p className="sm:max-lg:hidden mb-5 opacity-60 m-text">
<p className="sm:max-lg:hidden mb-5 opacity-60 m-text">
модель позволяет производить расчеты характеристик работы,
отслеживать безопасность работы устройств и симулировать
внештатные ситуации.
@@ -80,7 +80,7 @@ export function SimulatorsTab() {
<div className="self-center sm:max-lg:max-w-[234px]">
<div {...handlers}>
<div
className="flex h-full lg:justify-end select-none mobile:max-sm:relative xl:max-desktop-figma:max-w-[clamp(553px,553px+(100vw-1280px)/320*160,713px)] desktop-figma:max-w-[calc((100vw-256px)*0.53)] lg:max-xl:max-w-[300px] sm:max-lg:flex-col sm:flex-wrap gap-2 sm:max-lg:mb-10 mobile:max-sm:duration-1000"
className="flex h-full lg:justify-end select-none max-sm:relative xl:max-w-[clamp(553px,553px+(100vw-1280px)/320*160,713px)] desktop-figma:max-w-[calc((100vw-256px)*0.53)] lg:max-w-[300px] sm:max-lg:flex-col sm:flex-wrap gap-2 sm:max-lg:mb-10"
style={
width < 640
? {
@@ -113,34 +113,34 @@ export function SimulatorsTab() {
<>
<img
src="src/assets/train.png"
className="rounded-lg xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
className="rounded-lg xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
alt="Симулятор"
/>
<img
src="src/assets/dispatcher.png"
className="xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
className="xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
alt="Симулятор"
/>
<img
src="src/assets/winda.png"
className="xl:max-desktop-figma:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
className="xl:w-[clamp(178px,178px+(100vw-1280px)/320*54,232px)] desktop-figma:w-[calc((100vw-256px)*0.145)] sm:max-xl:hidden"
alt="Симулятор"
/>
<img
src="src/assets/rzhd.png"
className="xl:max-desktop-figma:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[calc((100vw-256px)*0.22)]"
className="xl:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[calc((100vw-256px)*0.22)]"
alt="Симулятор"
/>
<img
src="src/assets/rzhd2.png"
className="xl:max-desktop-figma:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[calc((100vw-256px)*0.22)]"
className="xl:w-[clamp(272px,272px+(100vw-1280px)/320*80,352px)] desktop-figma:w-[calc((100vw-256px)*0.22)]"
alt="Симулятор"
/>
</>
)}
</div>
</div>
<p className="lg:hidden mobile:max-sm:hidden opacity-60 m-text">
<p className="lg:hidden max-sm:hidden opacity-60 m-text">
модель позволяет производить расчеты характеристик работы,
отслеживать безопасность работы устройств и симулировать внештатные
ситуации.
@@ -153,7 +153,7 @@ export function SimulatorsTab() {
function SimulatorsItem({ text }: { text: string }) {
return (
<li className=" l-text bg-[#3D425C4D] rounded-[44px] w-fit lg:px-5 lg:py-2 mobile:px-4 mobile:py-[6px]">
<li className=" l-text bg-[#3D425C4D] rounded-[44px] w-fit lg:px-5 lg:py-2 px-4 py-[6px]">
{text}
</li>
);
@@ -1,14 +1,15 @@
import { useRef } from 'react';
import { getIcon } from '../../../../utils/getIcon';
import { useHover } from 'usehooks-ts';
import { useInView } from 'framer-motion';
export function TrainingsTab() {
return (
<div className="bg-[#3D425C4D] rounded-xl lg:aspect-[1520/546] sm:aspect-[720/460] lg:h-[max(534px,34vw)] md:max-lg:h-[min(460px,60vw)] sm:max-md:h-[max(460px,60vw)] mobile:max-sm: w-full lg:bg-[url('src/assets/mask_group.png')] desktop-figma:bg-[length:70%] bg-right-bottom lg:bg-[length:55%] lg:p-10 sm:max-lg:p-7 mobile:max-sm:p-5 bg-no-repeat">
<div className="bg-[#3D425C4D] rounded-xl lg:aspect-[1520/546] sm:aspect-[720/460] lg:h-[max(534px,34vw)] md:h-[min(460px,60vw)] sm:h-[max(460px,60vw)] w-full lg:bg-[url('src/assets/mask_group.png')] desktop-figma:bg-[length:70%] bg-right-bottom lg:bg-[length:55%] lg:p-10 sm:p-7 p-5 bg-no-repeat">
<div className="lg:max-w-[max(455px,28vw)]">
<div className="sm:max-lg:border-b border-[#3D425C] sm:max-lg:bg-[url('src/assets/mask_group.png')] bg-no-repeat bg-contain bg-right-bottom sm:max-md:bg-[length:40%]">
<div className="sm:max-lg:max-w-[51vw] mobile:max-sm:border-b border-[#3D425C]">
<h3 className=" font-medium lg:mb-8 sm:max-lg:mb-28 h3">
<div className="sm:max-lg:border-b border-[#3D425C] sm:max-lg:bg-[url('src/assets/mask_group.png')] bg-no-repeat md:bg-contain bg-right-bottom sm:bg-[length:40%]">
<div className="sm:max-lg:max-w-[51vw] max-sm:border-b border-[#3D425C]">
<h3 className=" font-medium lg:mb-8 sm:mb-28 h3">
Промышленные тренажеры виртуальной реальности
</h3>
<img
@@ -18,7 +19,7 @@ export function TrainingsTab() {
/>
</div>
</div>
<div className="lg:flex mobile:max-sm:flex lg:flex-col sm:grid grid-cols-3 lg:gap-y-6 sm:max-lg:mt-8 mobile:max-sm:mt-4 h-full mobile:max-sm:flex-col mobile:max-sm:gap-y-4 sm:max-lg:gap-x-3">
<div className="lg:flex flex lg:flex-col sm:grid grid-cols-3 lg:gap-y-6 sm:max-lg:mt-8 max-sm:mt-4 h-full max-sm:flex-col max-sm:gap-y-4 sm:max-lg:gap-x-3">
<TeachingItem
iconType="danger"
text="Отработка проведения технологических операций: оказание первой помощи, работы на высоте, работа с доменной печью и т.п."
@@ -51,23 +52,22 @@ function TeachingItem({
}) {
const ref = useRef<HTMLDivElement>(null);
const hovered = useHover(ref);
const isInView = useInView(ref, {
margin: `0px 0px -${window.innerHeight - (ref.current?.clientHeight ?? 0)}px`,
});
return (
<div
ref={ref}
className="lg:border-l-0 sm:border-l mobile:max-sm:first:border-t-0 mobile:max-sm:border-t border-[#3D425C] lg:flex lg:items-start lg:gap-x-7 sm:max-lg:pl-3 mobile:max-sm:first:pt-0 mobile:max-sm:pt-4"
className="lg:border-l-0 sm:border-l max-sm:first:border-t-0 max-sm:border-t border-[#3D425C] lg:flex lg:items-start lg:gap-x-7 sm:max-lg:pl-3 max-sm:first:pt-0 max-sm:pt-4"
>
{getIcon(
iconType,
hovered,
'mobile:max-sm:hidden sm:max-lg:mb-[14px] min-w-11',
)}
{getIcon(iconType, hovered, 'max-sm:hidden sm:max-lg:mb-[14px] min-w-11')}
<div className="lg:border-l border-[#3D425C] lg:pl-4">
<h4 className=" flex items-center gap-x-2 font-medium l-text mb-2">
{getIcon(iconType, hovered, 'sm:hidden min-w-11')}
<h4 className="flex items-center gap-x-2 font-medium l-text mb-2">
{getIcon(iconType, hovered || isInView, 'sm:hidden min-w-11')}
{title}
</h4>
<p className=" m-text opacity-60">{text}</p>
<p className="m-text opacity-60">{text}</p>
</div>
</div>
);
+7 -7
View File
@@ -10,9 +10,9 @@ export function Projects() {
return (
<div
id="projects"
className="lg:py-[70px] lg:px-10 mobile:py-14 sm:px-6 mobile:px-5 overflow-hidden select-none"
className="lg:py-[70px] lg:px-10 py-14 sm:px-6 px-5 overflow-hidden select-none"
>
<Title className="desktop-figma:mb-[77px] lg:mb-14 mobile:mb-6">
<Title className="desktop-figma:mb-[77px] lg:mb-14 mb-6">
<span className="text-gradient">Большой опыт в работе</span> с
промышленными предприятиями и учебными заведениями
</Title>
@@ -50,7 +50,7 @@ function Project({
tags: string[];
}) {
return (
<div className="bg-[#3D425C] bg-opacity-50 rounded-2xl box-border lg:min-w-[624px] sm:min-w-[520px] mobile:min-w-[328px] duration-1000 lg:translate-x-[264px] pointer-events-none">
<div className="bg-[#3D425C] bg-opacity-50 rounded-2xl box-border lg:min-w-[624px] sm:min-w-[520px] min-w-[328px] duration-1000 lg:translate-x-[264px] pointer-events-none">
<div
className="bg-cover bg-center bg-no-repeat h-[340px] rounded-2xl"
style={{ backgroundImage: `url(${src})` }}
@@ -119,7 +119,7 @@ function Slider({
}, [order, baseOffset, slide]);
return (
<div className="flex flex-col lg:mt-4 sm:mt-3 mobile:mt-2">
<div className="flex flex-col lg:mt-4 sm:mt-3 mt-2">
<div {...handlers}>
<div
className="flex gap-2 overflow-visible relative mb-[18px] -mr-10 select-none"
@@ -133,13 +133,13 @@ function Slider({
))}
</div>
</div>
<div className="flex items-center gap-4 lg:max-desktop-figma:w-[clamp(720px,100vw-465px,1135px)] desktop-figma:w-[70.9vw] mobile:w-full self-start lg:ml-64">
<div className="flex items-center gap-4 lg:w-[clamp(720px,100vw-465px,1135px)] desktop-figma:w-[70.9vw] w-full self-start lg:ml-64">
<button
onClick={() => {
setSlide(prev => (prev === 0 ? order.length - 3 : prev - 1));
dispatch('prev');
}}
className="mobile:max-sm:hidden"
className="max-sm:hidden"
>
<ArrowLeftIcon />
</button>
@@ -154,7 +154,7 @@ function Slider({
setSlide(prev => (prev === order.length - 3 ? 0 : prev + 1));
dispatch('next');
}}
className="mobile:max-sm:hidden"
className="max-sm:hidden"
>
<ArrowRightIcon />
</button>
+20 -20
View File
@@ -3,14 +3,14 @@ import { Title } from '../../ui/Title';
export function Teaching() {
return (
<div className="lg:py-[70px] lg:mb-[60px] lg:px-10 sm:max-lg:px-6 mobile:max-sm:px-4 mobile:max-lg:py-14 lg:flex gap-x-4">
<Title className="mobile:max-lg:hidden desktop-figma:mb-[38px] mb-8 lg:sticky top-14 h-fit max-w-[45vw]">
<div className="lg:py-[70px] lg:mb-[60px] lg:px-10 sm:px-6 px-4 py-14 lg:flex gap-x-4">
<Title className="max-lg:hidden desktop-figma:mb-[38px] mb-8 lg:sticky top-14 h-fit max-w-[45vw]">
<span className="text-gradient">Тренинг модуль</span>
<br className="mobile:max-lg:hidden" />
<br className="max-lg:hidden" />
<span className="lg:hidden">&nbsp;</span>помогает осуществлять
координацию между всеми участниками процесса
</Title>
<Title className="desktop-figma:mb-[29px] lg:hidden mobile:mb-6">
<Title className="desktop-figma:mb-[29px] lg:hidden mb-6">
<span className="text-gradient">Дистанционное обучение</span> на базе
платформы GRAFF TRANING
</Title>
@@ -22,8 +22,8 @@ export function Teaching() {
function TeachingFeaturesForDesktop() {
return (
<div className="mobile:max-lg:hidden lg:flex-col gap-y-4 flex-wrap lg:flex">
<div className="p-10 bg-[#3D425C4D] flex flex-col pr-20 rounded-2xl lg:min-h-[400px] bg-[url(src/assets/schedule_big.svg)] bg-no-repeat bg-[right_bottom] bg-[length:50%] lg:max-desktop-figma:min-w-[clamp(575px,575px+(100vw-1024px)/576*305,880px)] desktop-figma:min-w-[51vw]">
<div className="hidden flex-col gap-y-4 flex-wrap lg:flex">
<div className="p-10 bg-[#3D425C4D] flex flex-col pr-20 rounded-2xl min-h-[400px] bg-[url(src/assets/schedule_big.svg)] bg-no-repeat bg-[right_bottom] bg-[length:50%] max-desktop-figma:min-w-[clamp(575px,575px+(100vw-1024px)/576*305,880px)] desktop-figma:min-w-[51vw]">
<div className="mb-[85px] max-w-[380px]">
<TeachingFeatureTitle>Управление процессом</TeachingFeatureTitle>
<TeachingFeatureDescription className="max-w-[361px]">
@@ -39,7 +39,7 @@ function TeachingFeaturesForDesktop() {
/>
</div>
<div className="p-10 bg-[#3D425C4D] rounded-2xl lg:flex min-h-[400px]">
<div className="p-10 bg-[#3D425C4D] rounded-2xl flex min-h-[400px]">
<div className="w-fit">
<TeachingFeatureTitle className="w-fit">
Управление пользователями
@@ -71,7 +71,7 @@ function TeachingFeaturesForDesktop() {
/>
</div>
<div className="p-10 bg-[#3D425C4D] rounded-2xl lg:flex min-h-[400px] flex">
<div className="p-10 bg-[#3D425C4D] rounded-2xl min-h-[400px] flex">
<div className="">
<TeachingFeatureTitle>Статистика обучения</TeachingFeatureTitle>
<TeachingFeatureDescription>
@@ -99,23 +99,23 @@ function TeachingFeaturesForDesktop() {
function TeachingFeaturesForOtherScreens() {
return (
<div className="mobile:max-sm:flex mobile:max-sm:flex-col mobile:max-sm:gap-y-2 md:max-lg:grid grid-rows-[272px_113px_249px] gap-3 grid-cols-2 lg:hidden sm:max-md:flex sm:max-md:flex-col">
<div className="bg-[#3D425C4D] rounded-2xl sm:max-lg:pt-6 sm:max-lg:px-6 mobile:max-sm:pt-5 mobile:max-sm:px-5 overflow-hidden row-start-1 col-start-1 mobile:max-sm:flex mobile:max-sm:flex-col">
<div className="flex flex-col gap-y-2 md:grid grid-rows-[272px_113px_249px] sm:gap-3 grid-cols-2 lg:hidden">
<div className="bg-[#3D425C4D] rounded-2xl sm:pt-6 sm:px-6 pt-5 px-5 overflow-hidden row-start-1 col-start-1">
<TeachingFeatureTitle>
Управление
<br /> пользователями
</TeachingFeatureTitle>
<TeachingFeatureDescription className="sm:max-lg:-mb-[18px]">
<TeachingFeatureDescription className="sm:-mb-[18px]">
Добавление, удаление и назначение ролей
</TeachingFeatureDescription>
<img
src="src/assets/modal.svg"
className="relative mobile:max-sm:w-[351px] md:max-lg:top-7 sm:max-md:top-11 mobile:max-sm:top-5 mobile:max-sm:left-[92px] self-end sm:max-md:m-auto"
className="relative max-sm:w-[351px] md:top-7 sm:top-11 top-5 max-sm:left-[92px] self-end sm:max-md:m-auto"
alt="Управление пользователями"
/>
</div>
<div className="bg-[#3D425C4D] rounded-2xl sm:max-lg:pt-6 sm:max-lg:px-6 mobile:max-sm:pt-5 mobile:max-sm:px-5 bg-[url(src/assets/schedule_big.svg)] md:max-lg:bg-contain mobile:max-sm:bg-contain mobile:max-sm:bg-[140px_150px] sm:max-md:bg-[length:50%] bg-no-repeat md:max-lg:bg-[73px_130px] sm:max-md:bg-right-bottom row-start-1 row-span-2 col-start-2">
<div className="bg-[#3D425C4D] rounded-2xl sm:pt-6 sm:px-6 pt-5 px-5 bg-[url(src/assets/schedule_big.svg)] md:bg-contain bg-contain bg-[140px_150px] sm:bg-[length:50%] bg-no-repeat md:bg-[73px_130px] sm:bg-right-bottom row-start-1 row-span-2 col-start-2">
<TeachingFeatureTitle>Управление процессом</TeachingFeatureTitle>
<TeachingFeatureDescription>
Назначение сценария обучения
@@ -129,7 +129,7 @@ function TeachingFeaturesForOtherScreens() {
/>
</div>
<div className="bg-[#3D425C4D] rounded-2xl sm:max-lg:pt-6 sm:max-lg:px-6 mobile:max-sm:pt-5 mobile:max-sm:px-5 bg-[url(src/assets/pinned_windows_mini.svg)] sm:max-md:bg-[100%_100px] md:max-lg:bg-contain bg-no-repeat md:max-lg:bg-[67px_150px] mobile:max-sm:bg-[100%_120px] mobile:max-sm:flex mobile:max-sm:flex-col row-start-2 row-span-2 col-start-1">
<div className="bg-[#3D425C4D] rounded-2xl sm:pt-6 sm:px-6 pt-5 px-5 bg-[url(src/assets/pinned_windows_mini.svg)] sm:bg-[100%_100px] md:bg-contain bg-no-repeat md:bg-[67px_150px] bg-[100%_150px] row-start-2 row-span-2 col-start-1">
<TeachingFeatureTitle>Видеозапись обучения</TeachingFeatureTitle>
<TeachingFeatureDescription>
Фиксация и хранение сессий обучения, тренировки и тестирования.
@@ -142,22 +142,22 @@ function TeachingFeaturesForOtherScreens() {
/>
</div>
<div className="bg-[#3D425C4D] rounded-2xl sm:max-lg:pt-6 sm:max-lg:px-6 mobile:max-sm:pt-5 mobile:max-sm:px-5 sm:max-md:pb-6 mobile:max-sm:pb-5 overflow-hidden row-start-3 col-start-2">
<div className="bg-[#3D425C4D] rounded-2xl sm:pt-6 sm:px-6 pt-5 px-5 sm:max-md:pb-6 max-sm:pb-5 overflow-hidden row-start-3 col-start-2">
<TeachingFeatureTitle>Статистика обучения</TeachingFeatureTitle>
<TeachingFeatureDescription className="mobile:max-md:mb-5">
<TeachingFeatureDescription className="max-md:mb-5">
Фиксация правильных и неправильных действий. <br />
Отчет об ошибках
</TeachingFeatureDescription>
<div className="flex flex-col">
<div className="flex items-end mobile:max-md:justify-center md:max-lg:overflow-hidden mt-0.5 mobile:max-sm:pl-11 mx-auto">
<div className="flex items-end max-md:justify-center md:overflow-hidden mt-0.5 max-sm:pl-11 mx-auto">
<img
src="src/assets/schedule.svg"
className="rounded-lg mobile:max-lg:w-[166px] sm:max-lg:relative z-10"
className="rounded-lg w-[166px] sm:relative z-10"
alt="Расписание"
/>
<img
src="src/assets/stats.svg"
className="rounded-lg relative md:max-lg:right-[27px] sm:max-md:right-[31px] mobile:max-lg:w-[166px] sm:max-md:bottom-[27px] mobile:max-sm:bottom-[14px] mobile:max-sm:right-11"
className="rounded-lg relative md:right-[27px] sm:right-[31px] w-[166px] sm:max-md:bottom-[27px] max-sm:bottom-[14px] right-11"
alt="Статистика обучения"
/>
</div>
@@ -182,5 +182,5 @@ function TeachingFeatureDescription({
}: PropsWithChildren<{
className?: string;
}>) {
return <p className={'l-text opacity-60 ' + className}>{children}</p>;
return <p className={'l-text opacity-60 ' + className}>{children}</p>;
}
+11 -14
View File
@@ -7,16 +7,13 @@ import VrBacklightIcon from '../icons/VrBacklightIcon';
export function Trainings() {
return (
<div
id="trainings"
className="lg:py-[70px] lg:px-10 mobile:py-14 sm:px-7 mobile:px-4"
>
<Title className="desktop-figma:mb-[77px] lg:mb-14 mobile:mb-6">
<div id="trainings" className="lg:py-[70px] lg:px-10 py-14 sm:px-7 px-4">
<Title className="desktop-figma:mb-[77px] lg:mb-14 mb-6">
Предлагаем различные{' '}
<span className="text-gradient">варианты комплектации тренажеров</span>,
основываясь на специфике вашего тренировочного процесса
</Title>
<div className="xl:max-desktop-figma:pl-[16vw] desktop-figma:pl-[256px] w-fit">
<div className="xl:pl-[16vw] desktop-figma:pl-[256px] w-fit">
<TrainingsFeature
order="[01]"
src="src/assets/vr_1.svg"
@@ -60,13 +57,13 @@ function TrainingsFeature({
<AppearanceHr />
<div
ref={ref}
className="lg:first:h-[200px] lg:last:h-[200px] lg:h-[176px] sm:flex items-stretch justify-between sm:py-10 mobile:max-sm:pt-5"
className="lg:first:h-[200px] lg:last:h-[200px] lg:h-[176px] sm:flex items-stretch justify-between sm:py-10 max-sm:pt-5"
>
<div className="sm:flex flex-col gap-y-4 mobile:max-sm:mb-[42px] md:w-[43.7%] sm:max-md:min-w-[76%]">
<h3 className="font-medium mobile:max-sm:mb-2 h3">{title}</h3>
<div className="sm:flex flex-col gap-y-4 max-sm:mb-[42px] md:w-[43.7%] sm:max-md:min-w-[76%]">
<h3 className="font-medium max-sm:mb-2 h3">{title}</h3>
<p className=" opacity-60 l-text">{text}</p>
</div>
<div className="mobile:max-sm:flex sm:hidden justify-between items-end">
<div className="flex sm:hidden justify-between items-end">
<p className="text-[#52587A] m-text mb-5">{order}</p>
<div className="flex flex-col items-center">
<img
@@ -77,14 +74,14 @@ function TrainingsFeature({
<VrBacklightIcon className="absolute w-[36vw] h-fit" />
</div>
</div>
<div className="md:flex mobile:max-md:hidden">
<div className="md:flex hidden">
<motion.div
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: +hovered, scale: 1 }}
transition={{
duration: 0.4,
}}
className="-my-10 mobile:max-lg:hidden flex items-center justify-center"
className="-my-10 hidden lg:flex items-center justify-center"
>
<img
src={src}
@@ -103,11 +100,11 @@ function TrainingsFeature({
</div>
<p className="text-[#52587A] lg:font-medium m-text">{order}</p>
</div>
<div className="w-[calc(280/768*100%)] mobile:max-sm:hidden md:hidden flex justify-center items-center">
<div className="w-[calc(280/768*100%)] max-sm:hidden md:hidden flex justify-center items-center">
<img src={src} className="relative z-20" alt="VR-тренажер" />
<VrBacklightIcon className="absolute w-[24vw]" />
</div>
<p className="text-[#52587A] lg:font-medium m-text mobile:max-sm:hidden md:hidden">
<p className="text-[#52587A] lg:font-medium m-text max-sm:hidden md:hidden">
{order}
</p>
</div>
+2 -2
View File
@@ -15,11 +15,11 @@ export function Video() {
return (
<>
<div className="flex bg-[url(src/assets/video.png)] lg:h-[836px] sm:h-[561px] mobile:h-[400px] bg-cover bg-right bg-no-repeat justify-center">
<div className="flex bg-[url(src/assets/video.png)] lg:h-[836px] sm:h-[561px] h-[400px] bg-cover bg-right bg-no-repeat justify-center">
<button className="self-center" onClick={() => setOpen(true)}>
<PlayIcon className="lg:w-[114px] sm:w-[94px]" />
</button>
<div className="flex self-end absolute right-0 mobile:max-sm:hidden">
<div className="flex self-end absolute right-0 max-sm:hidden">
<div className="w-0 h-0 lg:border-b-[100px] lg:border-l-[100px] sm:border-b-[82px] sm:border-l-[82px] border-[transparent_transparent_#14161F_transparent]" />
<div className="lg:w-[260px] sm:w-[216px] mobile bg-[#14161F]" />
</div>
+1 -1
View File
@@ -13,7 +13,7 @@ export default function TeamworkIcon({
viewBox="0 0 44 44"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className} // style="maxWidth: 100%; max-height: 100%;"
className={className}
style={{
maxWidth: '100%',
maxHeight: '100%',
+10 -9
View File
@@ -11,42 +11,43 @@ html {
body {
font-family: 'TTHovesPro';
color: #fff;
background-color: #14161f;
}
@layer components {
.h1 {
@apply -tracking-[.02em] leading-[90%] desktop-figma:text-[clamp(96px,6vw,128px)] lg:max-desktop-figma:text-[clamp(76px,76px+(100vw-1024px)/576*20,96px)] md:max-lg:text-[clamp(64px,64px+(100vw-768px)/256*16,80px)] sm:max-md:text-[clamp(56px,56px+(100vw-640px)/128*8,64px)] mobile:max-sm:text-[clamp(40px,40px+(100vw-360px)/280*4,44px)];
@apply -tracking-[.02em] leading-[90%] desktop-figma:text-[clamp(96px,6vw,128px)] lg:text-[clamp(76px,76px+(100vw-1024px)/576*20,96px)] md:text-[clamp(64px,64px+(100vw-768px)/256*16,80px)] sm:text-[clamp(56px,56px+(100vw-640px)/128*8,64px)] text-[clamp(36px,11.11vw,44px)];
}
.h2 {
@apply -tracking-[.02em] lg:leading-[90%] mobile:max-lg:leading-[100%] desktop-figma:text-[clamp(64px,4vw,80px)] lg:max-desktop-figma:text-[clamp(56px,56px+(100vw-1024px)/576*8,64px)] md:max-lg:text-[clamp(40px,40px+(100vw-768px)/256*12,52px)] sm:max-md:text-[clamp(32px,32px+(1000vw-640px)/128*8,40px)] mobile:max-sm:text-[clamp(28px,28px+(100vw-360px)/280*4,32px)];
@apply -tracking-[.02em] lg:leading-[90%] leading-[100%] desktop-figma:text-[clamp(64px,4vw,80px)] lg:text-[clamp(56px,56px+(100vw-1024px)/576*8,64px)] md:text-[clamp(40px,40px+(100vw-768px)/256*12,52px)] sm:text-[clamp(32px,32px+(1000vw-640px)/128*8,40px)] text-[clamp(28px,7.78vw,32px)];
}
.h3 {
@apply leading-[100%] desktop-figma:text-[clamp(32px,2vw,40px)] lg:max-desktop-figma:text-[clamp(28px,28px+(100vw-1024px)/576*4,32px)] md:max-lg:text-[clamp(24px,24px+(100vw-768px)/256*4,28px)] sm:max-md:text-[clamp(20px,20px+(100vw-640px)/128*4,24px)] mobile:max-sm:text-[clamp(20px,20px+(100vw-360px)/280*4,24px)];
@apply leading-[100%] desktop-figma:text-[clamp(32px,2vw,40px)] lg:text-[clamp(28px,28px+(100vw-1024px)/576*4,32px)] md:text-[clamp(24px,24px+(100vw-768px)/256*4,28px)] sm:text-[clamp(20px,20px+(100vw-640px)/128*4,24px)] text-[clamp(20px,5.55vw,24px)];
}
.h4 {
@apply leading-[120%] desktop-figma:text-[clamp(14px,0.875vw,16px)] lg:max-desktop-figma:text-sm md:max-lg:text-[clamp(16px,16px+(100vw-768px)/256*2,18px)] sm:max-md:text-[clamp(14px,14px+(100vw-640px)/128*2,16px)] mobile:max-sm:text-[clamp(14px,14px+(100vw-360px)/280*2,16px,18px)];
@apply leading-[120%] desktop-figma:text-[clamp(14px,0.875vw,16px)] lg:text-sm md:text-[clamp(16px,16px+(100vw-768px)/256*2,18px)] sm:text-[clamp(14px,14px+(100vw-640px)/128*2,16px)] text-[clamp(14px,3.89vw,16px)];
}
.l-text {
@apply leading-[135%] desktop-figma:text-[clamp(18px,1.125vw,20px)] lg:max-desktop-figma:text-[clamp(16px,16px+(100vw-1024px)/576*2,18px)] md:max-lg:text-[clamp(16px,16px+(100vw-768px)/256*2,18px)] sm:max-md:text-[clamp(14px,14px+(100vw-640px)/128*2,16px)] mobile:max-sm:text-[clamp(14px,14px+(100vw-360px)/280*2,16px)];
@apply leading-[135%] desktop-figma:text-[clamp(18px,1.125vw,20px)] lg:text-[clamp(16px,16px+(100vw-1024px)/576*2,18px)] md:text-[clamp(16px,16px+(100vw-768px)/256*2,18px)] sm:text-[clamp(14px,14px+(100vw-640px)/128*2,16px)] text-[clamp(14px,3.89vw,16px)];
}
.m-text {
@apply leading-[140%] desktop-figma:text-[clamp(14px,0.875vw,16px)] lg:max-desktop-figma:text-sm md:max-lg:text-[clamp(12px,12px+(100vw-768px)/576*2,14px)] sm:max-md:text-xs mobile:max-sm:text-[clamp(12px,12px+(100vw-360px)/280*2,14px)];
@apply leading-[140%] desktop-figma:text-[clamp(14px,0.875vw,16px)] lg:text-sm md:text-[clamp(12px,12px+(100vw-768px)/576*2,14px)] sm:text-xs text-[clamp(12px,3.33vw,14px)];
}
.btn-text {
@apply -tracking-[.02em] leading-[100%] desktop-figma:text-[clamp(18px,1.125vw,20px)] lg:max-desktop-figma:text-[clamp(16px,16px+(100vw-1024px)/576*2,18px)] md:max-lg:text-[clamp(16px,16px+(100vw-768px)/256*2,18px)] sm:max-md:text-[clamp(14px,14px+(100vw-640px)/128*2,16px)] mobile:max-sm:text-[clamp(14px,14px+(100vw-360px)/280*2,16px)];
@apply -tracking-[.02em] leading-[100%] desktop-figma:text-[clamp(18px,1.125vw,20px)] lg:text-[clamp(16px,16px+(100vw-1024px)/576*2,18px)] md:text-[clamp(16px,16px+(100vw-768px)/256*2,18px)] sm:text-[clamp(14px,14px+(100vw-640px)/128*2,16px)] text-[clamp(12px,3.89vw,16px)];
}
.link {
@apply tracking-[.02em] leading-[120%] desktop-figma:text-[clamp(14px,0.875vw,16px)] lg:max-desktop-figma:text-[clamp(12px,12px+(100vw-1024px)/576*2,14px)] md:max-lg:text-[clamp(12px,12px+(100vw-768px)/256*2,14px)] sm:max-md:text-xs mobile:max-sm:text-[clamp(12px,12px+(100vw-360px)/280*2,14px)];
@apply tracking-[.02em] leading-[120%] desktop-figma:text-[clamp(14px,0.875vw,16px)] lg:text-[clamp(12px,12px+(100vw-1024px)/576*2,14px)] md:text-[clamp(12px,12px+(100vw-768px)/256*2,14px)] sm:text-xs text-[clamp(12px,3.33vw,14px)];
}
.descriptor {
@apply tracking-[.02em] leading-[120%] desktop-figma:text-[clamp(14px,0.875vw,16px)] lg:max-desktop-figma:text-[clamp(12px,12px+(100vw-1024px)/576*2,14px)] md:max-lg:text-[clamp(12px,12px+(100vw-640px)/256*2,14px)] sm:max-md:text-xs mobile:max-sm:text-[clamp(12px,12px+(100vw-360px)/280*2,14px)];
@apply tracking-[.02em] leading-[120%] desktop-figma:text-[clamp(14px,0.875vw,16px)] lg:text-[clamp(12px,12px+(100vw-1024px)/576*2,14px)] md:text-[clamp(12px,12px+(100vw-640px)/256*2,14px)] sm:text-xs text-[clamp(12px,3.33vw,14px)];
}
.feedback-field:focus ~ .feedback-placeholder {
+1 -1
View File
@@ -14,7 +14,7 @@ export function AnchorLink({
<HashLink
itemProp="url"
className={
'btn-text font-semibold border-l border-[#3D425C] mobile:hidden py-[30px] px-10 min-[1350px]:block hover:bg-[#3D425C] active:bg-[#14161F] ' +
'btn-text font-semibold border-l border-[#3D425C] hidden py-[30px] px-10 min-[1350px]:block hover:bg-[#3D425C] active:bg-[#14161F] ' +
className
}
to={route}
+1 -1
View File
@@ -13,7 +13,7 @@ function AppearanceItem({ text, order }: { text: string; order: number }) {
const { scrollY } = useScroll({});
const isInView = useInView(ref, {
once: true,
margin: `0px 0px -${window.innerHeight / 3}px`,
margin: '0px 0px -33%',
});
useMotionValueEvent(scrollY, 'change', latest => {
-1
View File
@@ -6,7 +6,6 @@ export default {
theme: {
extend: {
screens: {
mobile: '360px',
'desktop-figma': '1600px',
},
animation: {