upd
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 12 KiB |
@@ -20,8 +20,9 @@ export default async function BlogLayout({
|
||||
<section className="space-y-12">
|
||||
<div className="flex flex-col gap-6 items-center">
|
||||
<Title className="text-center" headerLevel={2}>
|
||||
В блоге собраны все публикации о работе компании:
|
||||
<span className="text-[#7A7A7A]"> новости, статьи и видео</span>
|
||||
Все о работе компании:
|
||||
<br />
|
||||
<span className="text-[#7A7A7A]"> статьи, видео и публикации</span>
|
||||
</Title>
|
||||
<StoriesButton />
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export default function Page() {
|
||||
return <></>;
|
||||
return <div className="h-[6.432vw]" />;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import { Prime } from '@/components/pages/PrimePage/PrimePage';
|
||||
|
||||
export default function PrimePage() {
|
||||
return <div className="relative">{/* <Prime /> */}</div>;
|
||||
return (
|
||||
<div className="relative">
|
||||
<Prime />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@ export function Feedback() {
|
||||
return (
|
||||
<div
|
||||
id="contacts"
|
||||
className={`lg:mb-20 sm:mb-12 lg:flex lg:gap-3 max-lg:space-y-12 justify-between${
|
||||
pathname !== '/form' ? ' lg:mt-[11.458vw] mt-25' : ''
|
||||
} mb-10`}
|
||||
className={`lg:mb-20 md:mb-12 lg:flex lg:gap-3 max-lg:space-y-12 justify-between lg:mt-[14.07vh] mt-25 mb-10`}
|
||||
>
|
||||
<h2 className="line2 font-medium max-lg:mb-6 lg:max-w-[45%]">
|
||||
<span className="text-[#7A7A7A]">Хотите увеличить конверсию?</span>
|
||||
@@ -73,10 +71,13 @@ export function FeedbackForm() {
|
||||
{!formState.isSubmitted ? (
|
||||
<FormProvider {...form}>
|
||||
<form
|
||||
className="sm:space-y-7 space-y-3"
|
||||
className="lg:space-y-[1.944vw] md:max-lg:space-y-7 space-y-3"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<CheckboxesGroup name="products" options={projectsTags} />
|
||||
<div className="lg:space-y-[1.111vw] space-y-4">
|
||||
<p className="heading2 font-medium">Нам надо</p>
|
||||
<CheckboxesGroup name="products" options={projectsTags} />
|
||||
</div>
|
||||
<input
|
||||
id="name"
|
||||
type="text"
|
||||
@@ -109,17 +110,17 @@ export function FeedbackForm() {
|
||||
{...register('email')}
|
||||
className="bg-transparent border-b border-[#37393B] focus:border-white py-4 rounded-none btnl outline-none transition-all w-full placeholder:btnl placeholder:font-medium placeholder:select-none"
|
||||
/>
|
||||
<div className="sm:flex items-stretch gap-3">
|
||||
<div className="md:flex items-stretch lg:gap-[0.833vw] gap-3">
|
||||
<Button
|
||||
type="submit"
|
||||
rounded="2xl"
|
||||
className="btnl max-sm:mb-3 max-sm:w-full py-5 cursor-pointer"
|
||||
className="btnl max-md:mb-3 max-md:w-full py-5 cursor-pointer"
|
||||
>
|
||||
Оставить заявку
|
||||
</Button>
|
||||
<Link
|
||||
href={'/policy'}
|
||||
className="text2 xl:max-w-[60%] sm:max-lg:max-w-[40%] sm:max-lg:py-1"
|
||||
className="text2 xl:max-w-[60%] md:max-lg:max-w-[40%] md:max-lg:py-1"
|
||||
>
|
||||
<p>
|
||||
<span className="text-[#7A7A7A]">
|
||||
|
||||
@@ -8,29 +8,29 @@ import YoutubeIcon from '../../../public/icons/youtube.svg';
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="lg:px-5 lg:pb-5 sm:px-4 sm:pb-4 px-[10px] pb-[10px] space-y-6">
|
||||
<div className="max-sm:flex-col lg:gap-3 sm:gap-2 flex gap-1">
|
||||
<footer className="lg:px-5 lg:pb-5 md:max-lg:px-4 md:max-lg:pb-4 px-[10px] pb-[10px] space-y-6 mb-0">
|
||||
<div className="max-md:flex-col lg:gap-[0.833vw] md:max-lg:gap-2 flex gap-1">
|
||||
<Link
|
||||
href={'tel:' + '8 800 770 00 67'.replaceAll(' ', '')}
|
||||
className="p-6 flex flex-col justify-between max-sm:gap-y-10 bg-[linear-gradient(to_top_left,#7A7A7A50,transparent)] rounded-2xl flex-1 hover:bg-[#37393B99] bg-transparent transition-colors"
|
||||
className="p-6 flex flex-col justify-between max-md:gap-y-10 bg-[linear-gradient(to_top_left,#7A7A7A50,transparent)] lg:rounded-[1.111vw] rounded-2xl lg:aspect-[696/248] w-[48.333vw] hover:bg-[#37393B99] bg-transparent transition-colors"
|
||||
>
|
||||
<p className="text-[#7A7A7A] text1 font-medium">Позвонить</p>
|
||||
<div className="lg:line2 sm:max-lg:heading1 line2 flex items-center font-medium">
|
||||
<div className="lg:line2 md:max-lg:heading1 line2 flex items-center font-medium">
|
||||
8 800 770 00 67
|
||||
<ArrowMoreIcon className="text-white lg:w-[5.556vw] lg:h-[5.556vw] md:max-lg:w-[4.167vw] md:max-lg:h-[4.167vw] w-[10vw] h-[10vw]" />
|
||||
</div>
|
||||
</Link>
|
||||
<Link
|
||||
href={'mailto:' + 'info@graff.tech'}
|
||||
className="p-6 flex flex-col justify-between max-sm:gap-y-10 bg-[linear-gradient(to_top_left,#7A7A7A50,transparent)] rounded-2xl flex-1 hover:bg-[#37393B99] bg-transparent transition-colors"
|
||||
className="p-6 flex flex-col justify-between max-md:gap-y-10 bg-[linear-gradient(to_top_left,#7A7A7A50,transparent)] lg:rounded-[1.111vw] rounded-2xl lg:aspect-[624/248] flex-1a w-[43.333vw] hover:bg-[#37393B99] bg-transparent transition-colors"
|
||||
>
|
||||
<p className="text-[#7A7A7A] text1 font-medium">Написать</p>
|
||||
<div className="lg:line2 sm:max-lg:heading1 line2 flex items-center font-medium">
|
||||
<div className="lg:line2 md:max-lg:heading1 line2 flex items-center font-medium">
|
||||
info@graff.tech
|
||||
<ArrowMoreIcon className="text-white lg:w-[5.556vw] lg:h-[5.556vw] md:max-lg:w-[4.167vw] md:max-lg:h-[4.167vw] w-[10vw] h-[10vw]" />
|
||||
</div>
|
||||
</Link>
|
||||
<div className="gap-y-2 justify-stretch sm:gap-x-2 gap-x-1 sm:flex-col flex">
|
||||
<div className="gap-y-2 justify-stretch md:gap-x-2 gap-x-1 md:flex-col flex">
|
||||
<ContactLink href="https://t.me/graffestate">
|
||||
<TelegramIcon className="lg:w-[1.389vw] lg:h-[1.389vw] md:max-lg:w-[2.083vw] md:max-lg:h-[2.083vw] w-[5.556vw] h-[5.556vw] text-white group-hover:text-black" />
|
||||
</ContactLink>
|
||||
@@ -57,7 +57,7 @@ export function Footer() {
|
||||
</p>
|
||||
<Link
|
||||
href={'https://graff.tech'}
|
||||
className="text-[#37393B] text1 font-medium leading-[18.9px] lg:w-fit sm:col-start-2 sm:text-right w-full"
|
||||
className="text-[#37393B] text1 font-medium leading-[18.9px] lg:w-fit md:col-start-2 md:text-right w-full"
|
||||
>
|
||||
graff.tech
|
||||
</Link>
|
||||
@@ -74,7 +74,7 @@ export function ContactLink({
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={`rounded-2xl bg-[#37393B99] p-[18px] hover:bg-white transition-colors hover:text-black flex justify-center w-full group ${className}`}
|
||||
className={`lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99] lg:p-[1.25vw] p-[18px] hover:bg-white transition-colors hover:text-black flex justify-center w-full group ${className}`}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
|
||||
@@ -27,7 +27,7 @@ export function ArticleCard({
|
||||
onClick={() => !drafted && push('/blog/' + slug)}
|
||||
className={`${
|
||||
className ? className + ' ' : ''
|
||||
}hover:backdrop-blur-[500px] cursor-pointer h-full group max-lg:bg-[radial-gradient(ellipse_at_bottom,#7A7A7A50,transparent)] hover:bg-[radial-gradient(ellipse_at_bottom,#7A7A7A50,transparent)] flex flex-col justify-between gap-3 transition-[background-size] lg:bg-[length:100%_0%] bg-bottom hover:bg-[length:100%_100%] bg-no-repeat rounded-2xl p-3 relative`}
|
||||
}hover:backdrop-blur-[500px] cursor-pointer h-full group max-lg:bg-[radial-gradient(ellipse_at_bottom,#7A7A7A50,transparent)] hover:bg-[radial-gradient(ellipse_at_bottom,#7A7A7A50,transparent)] flex flex-col justify-between gap-3 transition-[background-size] lg:bg-[length:100%_0%] bg-bottom hover:bg-[length:100%_100%] bg-no-repeat rounded-2xl lg:p-[0.833vw] p-3 relative`}
|
||||
>
|
||||
<Image
|
||||
src={process.env.NEXT_PUBLIC_S3_BUCKET + cardImage}
|
||||
@@ -39,7 +39,7 @@ export function ArticleCard({
|
||||
<p className="heading2 font-medium text-ellipsis [-webkit-line-clamp:2] line-clamp-2">
|
||||
{title}
|
||||
</p>
|
||||
<div className="flex flex-nowrap lg:gap-[0.278vw]a gap-1">
|
||||
<div className="flex flex-wrap lg:gap-[0.278vw] gap-1">
|
||||
{tags.map((tag) => (
|
||||
<PostTag
|
||||
text={tag}
|
||||
|
||||
@@ -7,7 +7,7 @@ export function DraftsList({ tags }: { tags: string[] | string }) {
|
||||
return (
|
||||
<div className="space-y-2 ml-3 max-lg:hidden">
|
||||
<p className="text-[#7A7A7A] text1">Черновики</p>
|
||||
<div className="gap-x-3 gap-y-6 flex flex-wrap">
|
||||
<div className="lg:gap-x-[0.833vw] md:gap-x-3 gap-y-6 flex flex-wrap">
|
||||
{drafts && drafts.length > 0 ? (
|
||||
drafts?.map((article) => (
|
||||
<ArticleCard
|
||||
|
||||
@@ -44,7 +44,7 @@ export function AwardItem({
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`bg-[radial-gradient(ellipse_at_right_center,#7a7a7a50,transparent)] rounded-2xl p-6 flex flex-col justify-between lg:w-1/3 lg:aspect-[459/496] sm:aspect-[362/412] relative transition-all ${
|
||||
className={`bg-[radial-gradient(ellipse_at_right_center,#7a7a7a50,transparent)] lg:rounded-[1.111vw] rounded-2xl lg:p-[1.667vw] p-6 flex flex-col justify-between lg:w-1/3 lg:aspect-[459/496] sm:aspect-[362/412] relative transition-all ${
|
||||
index === 0
|
||||
? 'lg:self-end'
|
||||
: index === 1
|
||||
|
||||
@@ -15,7 +15,7 @@ export const ClientItem = forwardRef<HTMLDivElement, ICompany>(
|
||||
<GridItem className="!relativea">
|
||||
<div
|
||||
ref={ref}
|
||||
className="rounded-2xl select-none cursor-grab lg:w-[calc((100vw-120px)/11)] md:max-lg:w-[calc((100vw-64px)/5)] w-[calc((100vw-36px)/3)] aspect-square backdrop-blur-3xl relative bg-[#23242599] group hover:bg-[#232425] transition-colors overflow-hidden"
|
||||
className="lg:rounded-[1.111vw] rounded-2xl select-none cursor-grab lg:w-[calc((100vw-120px)/11)] md:max-lg:w-[calc((100vw-64px)/5)] w-[calc((100vw-36px)/3)] aspect-square backdrop-blur-3xl relative bg-[#23242599] group hover:bg-[#232425] transition-colors overflow-hidden"
|
||||
>
|
||||
<div className="aspect-square relative flex items-center justify-center p-5">
|
||||
<div className="max-w-4/5 absolute w-full">
|
||||
|
||||
@@ -32,7 +32,10 @@ export function Motivation() {
|
||||
|
||||
return (
|
||||
<div className="lg:space-y-[4.444vw] md:max-lg:space-y-[6.25vw] max-md:space-y-[11.111vw]">
|
||||
<Title headerLevel={1} className="text-center">
|
||||
<Title
|
||||
headerLevel={1}
|
||||
className="text-center min-[2560px]:max-w-3/4 min-[2560px]:mx-auto"
|
||||
>
|
||||
Помогаем девелоперам продавать
|
||||
<span className="max-lg:hidden"> </span>
|
||||
<span className="lg:hidden"> </span>недвижимость проще и
|
||||
@@ -40,7 +43,6 @@ export function Motivation() {
|
||||
<span className="text-[#37393B]">быстрее </span>
|
||||
<span className="absolute top-[55%] -left-[2.5%] 2xl:h-1.5 h-1 w-[105%] bg-white" />
|
||||
</span>
|
||||
{/* <span className="max-md:hidden"> </span> */}
|
||||
дороже
|
||||
</Title>
|
||||
<div className="grid lg:gap-[0.833vw] md:max-lg:gap-[1.563vw] gap-[2.222vw]">
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import { videos } from '@/consts/presentation/videos';
|
||||
import { Title } from '@/ui/Title';
|
||||
import {
|
||||
motion,
|
||||
useInView,
|
||||
useMotionValueEvent,
|
||||
useScroll,
|
||||
} from 'framer-motion';
|
||||
import { useRef, useState, useTransition } from 'react';
|
||||
import RestartIcon from '../../../../../public/icons/restart.svg';
|
||||
import { useInView, useMotionValueEvent, useScroll } from 'framer-motion';
|
||||
import { useRef, useState } from 'react';
|
||||
import { PrimeProgressItem } from '../../PrimePage/PrimePage';
|
||||
import { Infrastructure } from './Infrastructure';
|
||||
import { Insolation } from './Insolation';
|
||||
import { IntegrationCRM } from './IntegrationCRM';
|
||||
@@ -20,7 +16,7 @@ export function PresentationDesktop() {
|
||||
|
||||
const { scrollYProgress } = useScroll({ container: target });
|
||||
|
||||
const inView = useInView(target, { margin: '80% 0% -80% 0%' });
|
||||
const inView = useInView(target, { margin: '85% 0% -85% 0%' });
|
||||
|
||||
const [slide, setSlide] = useState(0);
|
||||
|
||||
@@ -28,16 +24,21 @@ export function PresentationDesktop() {
|
||||
setSlide(Math.trunc(value * 6))
|
||||
);
|
||||
|
||||
const [isPending, startTransition] = useTransition();
|
||||
|
||||
return (
|
||||
<div className="space-y-16 mt-[100px] max-lg:hidden">
|
||||
<Title>
|
||||
<div className="mt-25 mb-50 max-lg:hidden relative">
|
||||
<Title className="mb-16">
|
||||
Интерактивная презентация{' '}
|
||||
<span className="text-gradient">улучшает опыт выбора недвижимости</span>{' '}
|
||||
и увеличивают темпы продаж квартир в жилом комплексе
|
||||
</Title>
|
||||
<div className="relative">
|
||||
<div className="flex gap-x-3 items-stretch h-[80vh] absolute overflow-hidden w-full top-0">
|
||||
<SearchAndSelect scroll={scrollYProgress} />
|
||||
<VideoLayer scroll={scrollYProgress} />
|
||||
<Infrastructure scroll={scrollYProgress} />
|
||||
<Insolation scroll={scrollYProgress} />
|
||||
<IntegrationCRM scroll={scrollYProgress} />
|
||||
</div>
|
||||
<div
|
||||
className={`snap-y snap-mandatory h-[80vh] z-10 relative [scrollbar-width:none] ${
|
||||
inView ? 'overflow-y-scroll' : 'overflow-hidden'
|
||||
@@ -51,59 +52,25 @@ export function PresentationDesktop() {
|
||||
<div className="h-full snap-start snap-always" />
|
||||
<div className="h-full snap-start snap-always" />
|
||||
</div>
|
||||
<div className="flex gap-x-3 items-stretch h-[80vh] absolute overflow-hidden w-full top-0">
|
||||
<SearchAndSelect scroll={scrollYProgress} />
|
||||
<VideoLayer scroll={scrollYProgress} />
|
||||
<Infrastructure scroll={scrollYProgress} />
|
||||
<Insolation scroll={scrollYProgress} />
|
||||
<IntegrationCRM scroll={scrollYProgress} />
|
||||
<div className="flex absolute p-2 rounded-[27px] bg-[#37393B99] backdrop-blur-[20px] left-1/2 -translate-x-1/2 mt-5">
|
||||
{videos.map(({ src, anchorImg }, index) => (
|
||||
<PrimeProgressItem
|
||||
onClick={() => {
|
||||
target.current?.scrollTo({
|
||||
top: (index * target.current?.scrollHeight) / videos.length,
|
||||
});
|
||||
}}
|
||||
active={
|
||||
index === slide ||
|
||||
(index === videos.length - 1 && slide === videos.length)
|
||||
}
|
||||
src={anchorImg}
|
||||
title={src}
|
||||
key={src}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-[97.222vw] gap-3 items-center -mt-5">
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<SlideProgress
|
||||
key={i}
|
||||
active={slide >= i}
|
||||
clickHandler={() => {
|
||||
target.current?.scrollTo({
|
||||
top: (i * target.current?.scrollHeight) / 6,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<button
|
||||
onClick={() =>
|
||||
startTransition(() => target.current?.scrollTo({ top: 0 }))
|
||||
}
|
||||
className="cursor-pointer group"
|
||||
>
|
||||
<RestartIcon
|
||||
className={`lg:w-[1.111vw] lg:h-[1.111vw] w-4 h-4 text-white transition-transform${
|
||||
isPending ? ' -rotate-360' : ''
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SlideProgress({
|
||||
active,
|
||||
clickHandler,
|
||||
}: {
|
||||
active: boolean;
|
||||
clickHandler: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className="w-full bg-[#7a7a7a] h-2 rounded-2xl relative overflow-hidden cursor-pointer"
|
||||
onClick={clickHandler}
|
||||
>
|
||||
<motion.div
|
||||
animate={active ? { scaleX: 1 } : { scaleX: 0 }}
|
||||
className="h-2 bg-white w-full origin-left left-0 top-0 rounded-2xl absolute"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,10 +72,10 @@ export function PresentationMini() {
|
||||
ref={videoContainer}
|
||||
className="md:aspect-[721/400] aspect-[340/193] w-[94.444vw] md:w-[93.88vw] mx-auto relative max-md:scale-115"
|
||||
>
|
||||
{videos.map((video, index) => (
|
||||
{videos.map(({ src }, index) => (
|
||||
<video
|
||||
key={video}
|
||||
src={`/videos/pages/home/presentation/${video}.mp4`}
|
||||
key={src}
|
||||
src={`/videos/pages/home/presentation/${src}.mp4`}
|
||||
loop
|
||||
muted
|
||||
playsInline
|
||||
@@ -83,12 +83,12 @@ export function PresentationMini() {
|
||||
style={{
|
||||
zIndex: videos.length - index,
|
||||
}}
|
||||
className={`absolute h-fullw-full object-covera transition-opacity${
|
||||
className={`absolute h-full w-full transition-opacity${
|
||||
slide > index && index !== videos.length - 1 ? ' opacity-0' : ''
|
||||
}`}
|
||||
/>
|
||||
))}
|
||||
<div className="left-1/2 -bottom-px z-10 absolute -translate-x-1/2 bg-gradient-to-b from-[#0F101100] to-[#0F1011] w-full h-[calc(80/400*100%)]" />
|
||||
<div className="left-1/2 bottom-0 z-10 absolute -translate-x-1/2 bg-gradient-to-b from-[#0F101100] to-[#0F1011] w-full h-1/5" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-[40vh]" ref={target}>
|
||||
|
||||
@@ -20,7 +20,7 @@ export function SearchAndSelect({
|
||||
return (
|
||||
<motion.div
|
||||
style={isLg ? { opacity } : { top, opacity: opacityMini }}
|
||||
className="xs:max-md:p-5 p-4 flex max-md:flex-col lg:flex-col h-full md:gap-3 xs:max-md:gap-y-7 gap-y-3 lg:z-10 lg:w-[31.875vw] max-md:rounded-2xl max-lg:sticky select-none max-md:bg-radial-[at_100%_100%] from-[#7A7A7A66] max-md:backdrop-blur-[500px]"
|
||||
className="xs:max-md:p-5 flex max-md:flex-col lg:flex-col h-full md:gap-3 xs:max-md:gap-y-7 gap-y-3 lg:z-10 lg:w-[31.875vw] max-md:rounded-2xl max-lg:sticky select-none max-md:bg-radial-[at_100%_100%] from-[#7A7A7A66] max-md:backdrop-blur-[500px]"
|
||||
>
|
||||
<div className="lg:p-[1.667vw] md:max-lg:p-6 md:rounded-2xl md:bg-radial-[at_100%_100%] from-[#7A7A7A66] md:backdrop-blur-[500px] xs:max-md:space-y-4 space-y-20 md:flex flex-col justify-between md:flex-1">
|
||||
<p className="heading2 font-medium">Выбор квартиры на генплане</p>
|
||||
|
||||
@@ -42,10 +42,10 @@ export function VideoLayer({ scroll }: { scroll: MotionValue<number> }) {
|
||||
className="absolute overflow-hidden h-full transition-all"
|
||||
>
|
||||
{videoRefs.length &&
|
||||
videos.map((video, index) => (
|
||||
videos.map(({ src }, index) => (
|
||||
<motion.video
|
||||
key={video}
|
||||
src={`/videos/pages/home/presentation/${video}.mp4`}
|
||||
key={src}
|
||||
src={`/videos/pages/home/presentation/${src}.mp4`}
|
||||
ref={videoRefs[index]}
|
||||
loop
|
||||
muted
|
||||
|
||||
@@ -83,23 +83,23 @@ export function Statistics() {
|
||||
<span className="line1">4</span>раз
|
||||
</p>
|
||||
<div className="absolute md:w-[13.438vw] w-[28.667vw] md:max-lg:bottom-12 md:max-lg:right-16 bottom-12 right-14 lg:hidden">
|
||||
<div className="relative">
|
||||
<div className="relative rounded-2xl">
|
||||
<Image
|
||||
src="/img/pages/home/stats/Forum_Zoolog_09-03(2).png"
|
||||
src="/img/pages/home/stats/Forum_Zoolog_09-03(2).jpg"
|
||||
fill
|
||||
alt="forum zoolog"
|
||||
className="!relative"
|
||||
className="!relative rounded-2xl"
|
||||
sizes="100%"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="absolute md:w-[13.438vw] w-[28.667vw] md:max-lg:bottom-6 md:max-lg:right-6 bottom-6 right-4 lg:hidden">
|
||||
<div className="relative">
|
||||
<div className="relative rounded-2xl">
|
||||
<Image
|
||||
src="/img/pages/home/stats/Forum_Zoolog_09-03.png"
|
||||
src="/img/pages/home/stats/Forum_Zoolog_09-03.jpg"
|
||||
fill
|
||||
alt="forum zoolog"
|
||||
className="!relative"
|
||||
className="!relative rounded-2xl"
|
||||
sizes="100%"
|
||||
/>
|
||||
</div>
|
||||
@@ -118,7 +118,7 @@ export function Statistics() {
|
||||
src="/img/pages/home/stats/Forum_Zoolog_09-03(2).jpg"
|
||||
fill
|
||||
alt="forum zoolog"
|
||||
className="!relative rounded-lg"
|
||||
className="!relative rounded-2xl"
|
||||
sizes="100%"
|
||||
/>
|
||||
</div>
|
||||
@@ -127,7 +127,7 @@ export function Statistics() {
|
||||
src="/img/pages/home/stats/Forum_Zoolog_09-03.jpg"
|
||||
fill
|
||||
alt="forum zoolog"
|
||||
className="!relative rounded-lg"
|
||||
className="!relative rounded-2xl"
|
||||
sizes="100%"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -52,7 +52,7 @@ export function Streaming() {
|
||||
/>
|
||||
))}
|
||||
<div
|
||||
className={`border border-[#3D425C] rounded-2xl flex flex-1 justify-center duration-500 items-center p-6 md:max-lg:min-w-[300px] group max-md:absolute self-stretch max-md:h-full transition-transform select-none max-md:w-[calc(100%-40px)] max-md:bg-[#0F101199] max-md:backdrop-blur-2xl ${
|
||||
className={`bg-gradient-to-r from-[#FFFFFF14] to-[#FFFFFF00] p-0.5 rounded-2xl flex flex-1 justify-center duration-500 items-center md:max-lg:min-w-[300px] group max-md:absolute self-stretch max-md:h-full transition-transform select-none max-md:w-[calc(100%-40px)] max-md:bg-[#0F101199] max-md:backdrop-blur-2xl ${
|
||||
data &&
|
||||
(data.length - 1 === current
|
||||
? 'max-md:translate-z-10'
|
||||
@@ -67,16 +67,18 @@ export function Streaming() {
|
||||
: '')
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-col items-center space-y-6">
|
||||
<p className="heading2 font-medium text-center">
|
||||
Расскажем и покажем как это работает на созвоне
|
||||
</p>
|
||||
<Link
|
||||
href={'/form'}
|
||||
className="btnm font-medium group-hover:scale-105 px-6 py-[17px] transition-transform rounded-xl bg-gradient"
|
||||
>
|
||||
Оставить заявку
|
||||
</Link>
|
||||
<div className="md:bg-[#0F1011] h-full w-full rounded-2xl content-center p-6">
|
||||
<div className="flex flex-col items-center space-y-6">
|
||||
<p className="heading2 font-medium text-center">
|
||||
Расскажем и покажем как это работает на созвоне
|
||||
</p>
|
||||
<Link
|
||||
href={'/form'}
|
||||
className="btnm font-medium group-hover:scale-105 px-6 py-[17px] transition-transform rounded-xl bg-gradient"
|
||||
>
|
||||
Оставить заявку
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,7 +64,7 @@ export function StreamingProject({
|
||||
</div>
|
||||
<Link
|
||||
href={streaming.find((s) => s.title === title)?.url ?? '/'}
|
||||
className="hidden lg:group-hover:block absolute w-full h-full left-0 bottom-0 md:max-lg:rounded-2xl rounded-xl font-medium backdrop-blur-[3px] content-center text-center z-0"
|
||||
className="lg:group-hover:opacity-100 opacity-0 transition-opacity duration-500 absolute w-full h-full left-0 bottom-0 md:max-lg:rounded-2xl rounded-xl font-medium backdrop-blur-[3px] content-center text-center z-0"
|
||||
>
|
||||
<p className="btnl flex justify-center gap-2">
|
||||
Начать демонстрацию{' '}
|
||||
|
||||
@@ -2,13 +2,14 @@ import { motion, MotionValue, useTransform } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
|
||||
export function CommercialOffer({ scroll }: { scroll: MotionValue<number> }) {
|
||||
const x = useTransform(scroll, [], []);
|
||||
const opacity = useTransform(scroll, [], []);
|
||||
const x = useTransform(scroll, [5 / 6, 6 / 6], ['100%', '0%']);
|
||||
|
||||
const opacity = useTransform(scroll, [5 / 6, 6 / 6], [0, 1]);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
// style={{ x, opacity }}
|
||||
className="p-6 backdrop-blur-xs rounded-2xl bg-[radial-gradient(ellipse_at_right,#7A7A7A66,transparent)] absolute h-full w-[23.611vw] flex flex-col justify-between gap-6"
|
||||
style={{ x, opacity }}
|
||||
className="p-6 backdrop-blur-xs rounded-2xl right-0 bg-[radial-gradient(ellipse_at_right,#7A7A7A66,transparent)] absolute h-full w-[23.611vw] flex flex-col justify-between gap-6"
|
||||
>
|
||||
<p className="heading2 font-medium">Отправка коммерческого предложения</p>
|
||||
<div className="w-[20.278vw] aspect-[292/264] relative flex justify-center items-center">
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import { motion, MotionValue, useTransform } from 'framer-motion';
|
||||
|
||||
export function Favorites({ scroll }: { scroll: MotionValue<number> }) {
|
||||
const x = useTransform(scroll, [], []);
|
||||
const opacity = useTransform(scroll, [0, 1 / 6, 2 / 6], [0, 1, 0]);
|
||||
const x = useTransform(
|
||||
scroll,
|
||||
[2 / 6, 3 / 6, 4 / 6],
|
||||
['-100%', '0%', '-100%']
|
||||
);
|
||||
const opacity = useTransform(scroll, [2 / 6, 3 / 6, 4 / 6], [0, 1, 0]);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
// style={{ x, opacity }}
|
||||
style={{ x, opacity }}
|
||||
className="p-6 backdrop-blur-xs rounded-2xl bg-[radial-gradient(ellipse_at_right,#7A7A7A66,transparent)] absolute h-full w-[23.611vw] flex flex-col justify-between gap-6"
|
||||
>
|
||||
<p className="heading2 font-medium">Формирование списка избранного</p>
|
||||
|
||||
@@ -5,42 +5,39 @@ import NatureIcon from '../../../../public/icons/nature.svg';
|
||||
import ShopIcon from '../../../../public/icons/shop.svg';
|
||||
|
||||
export function Infrastructure({ scroll }: { scroll: MotionValue<number> }) {
|
||||
const x = useTransform(scroll, [1 / 5, 2 / 5], ['100%', '0%']);
|
||||
const x = useTransform(scroll, [1 / 6, 2 / 6, 3 / 6], ['100%', '0%', '100%']);
|
||||
|
||||
const opacity = useTransform(scroll, [1 / 5, 2 / 5, 3 / 5], [0, 1, 0]);
|
||||
const opacity = useTransform(scroll, [1 / 6, 2 / 6, 3 / 6], [0, 1, 0]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
style={{ x, opacity }}
|
||||
className="absolute right-0 rounded-2xl transition-[transform,opacity] p-[1.667vw] h-full bg-radial-[at_0%_100%] from-[#7A7A7A99] flex flex-col gap-2 z-10 backdrop-blur-[500px] select-none w-[23.611vw]"
|
||||
>
|
||||
<p className="heading2 font-medium">
|
||||
Демонстрация инфраструктуры вокруг будущего комплекса
|
||||
</p>
|
||||
<div className="flex flex-1">
|
||||
<div className="grid grid-cols-2 grid-rows-2 gap-[5px] m-auto">
|
||||
<div className="w-[6.806vw] aspect-square rounded-full bg-[#B5F54E] flex justify-center items-center">
|
||||
<NatureIcon className="w-[4.444vw] text-[#232425]" />
|
||||
</div>
|
||||
<div className="w-[6.806vw] aspect-square rounded-full bg-[#B5F54E] flex justify-center items-center">
|
||||
<KidsIcon className="w-[4.444vw] text-[#232425]" />
|
||||
</div>
|
||||
<div className="w-[6.806vw] aspect-square rounded-full bg-[#B5F54E] flex justify-center items-center">
|
||||
<MetroIcon className="w-[4.444vw] text-[#232425]" />
|
||||
</div>
|
||||
<div className="w-[6.806vw] aspect-square rounded-full bg-[#B5F54E] flex justify-center items-center">
|
||||
<ShopIcon className="w-[4.444vw] text-[#232425]" />
|
||||
</div>
|
||||
<motion.div
|
||||
style={{ x, opacity }}
|
||||
className="absolute right-0 rounded-2xl transition-[transform,opacity] p-[1.667vw] top-1/2 -translate-y-1/2 h-[85.959%] bg-radial-[at_100%_100%] from-[#7A7A7A99] flex flex-col gap-2 z-10 backdrop-blur-[500px] select-none w-[23.611vw]"
|
||||
>
|
||||
<p className="heading2 font-medium">
|
||||
Демонстрация инфраструктуры вокруг будущего комплекса
|
||||
</p>
|
||||
<div className="flex flex-1">
|
||||
<div className="grid grid-cols-2 grid-rows-2 gap-[5px] m-auto">
|
||||
<div className="w-[5.556vw] aspect-square rounded-full bg-[#B5F54E] flex justify-center items-center">
|
||||
<NatureIcon className="w-[3.644vw] text-[#232425]" />
|
||||
</div>
|
||||
<div className="w-[5.556vw] aspect-square rounded-full bg-[#B5F54E] flex justify-center items-center">
|
||||
<KidsIcon className="w-[3.644vw] text-[#232425]" />
|
||||
</div>
|
||||
<div className="w-[5.556vw] aspect-square rounded-full bg-[#B5F54E] flex justify-center items-center">
|
||||
<MetroIcon className="w-[3.644vw] text-[#232425]" />
|
||||
</div>
|
||||
<div className="w-[5.556vw] aspect-square rounded-full bg-[#B5F54E] flex justify-center items-center">
|
||||
<ShopIcon className="w-[3.644vw] text-[#232425]" />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text1">
|
||||
Режим «Инфраструктура» знакомит пользователя с перспективной
|
||||
застройкой целого района. В зависимости от срока сдачи либо
|
||||
функциональной нагрузки того или иного блока можно ввести выделение
|
||||
цветом.
|
||||
</p>
|
||||
</motion.div>
|
||||
</>
|
||||
</div>
|
||||
<p className="text2">
|
||||
Режим «Инфраструктура» знакомит пользователя с перспективной застройкой
|
||||
целого района. В зависимости от срока сдачи либо функциональной нагрузки
|
||||
того или иного блока можно ввести выделение цветом.
|
||||
</p>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import { seasons } from '@/consts/presentation/seasons';
|
||||
import { SeasonCard } from '@/ui/SeasonCard';
|
||||
import { motion, MotionValue, useTransform } from 'framer-motion';
|
||||
|
||||
export function Insolation({ scroll }: { scroll: MotionValue<number> }) {
|
||||
const x = useTransform(
|
||||
scroll,
|
||||
[4 / 6, 5 / 6, 6 / 6],
|
||||
['-100%', '0%', '-100%']
|
||||
);
|
||||
|
||||
const opacity = useTransform(scroll, [4 / 6, 5 / 6, 6 / 6], [0, 1, 0]);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
style={{ x, opacity }}
|
||||
className="absolute h-full w-[23.611vw] rounded-2xl p-[1.667vw] bg-radial-[at_100%_100%] from-[#7A7A7A99] flex flex-col gap-2 z-10 backdrop-blur-[500px] select-none"
|
||||
>
|
||||
<p className="heading2 font-medium">Интерактивная инсоляция</p>
|
||||
<div className="flex items-center justify-center w-full h-full">
|
||||
{seasons.map(({ src, title }, index) => (
|
||||
<SeasonCard
|
||||
src={src}
|
||||
title={title}
|
||||
key={title}
|
||||
className={
|
||||
index === 1
|
||||
? 'z-1'
|
||||
: index === 0
|
||||
? '-translate-y-42/194 translate-x-22/146'
|
||||
: 'translate-y-67/194 -translate-x-42/146'
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<p className="text1">
|
||||
Клиент может наблюдать, как световое пятно перемещается в зависимости от
|
||||
времени суток и сезона, поскольку солнечный свет имеет физическое
|
||||
воздействие.
|
||||
</p>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { motion, MotionValue, useTransform } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
import MailIcon from '../../../../public/icons/mail.svg';
|
||||
import PhoneIcon from '../../../../public/icons/phone.svg';
|
||||
|
||||
export function IntegrationCRM({ scroll }: { scroll: MotionValue<number> }) {
|
||||
const opacity = useTransform(scroll, [3 / 6, 4 / 6, 5 / 6], [0, 1, 0]);
|
||||
|
||||
const x = useTransform(scroll, [3 / 6, 4 / 6, 5 / 6], ['100%', '0%', '100%']);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
style={{ x, opacity }}
|
||||
className="absolute max-lg:hidden w-[23.611vw] h-full z-10 right-0 transition-[transform,opacity] p-[1.667vw] rounded-2xl bg-radial-[at_100%_100%] from-[#7A7A7A66] backdrop-blur-[500px] to-transparent flex flex-col justify-between select-none"
|
||||
>
|
||||
<p className="heading2 font-medium">
|
||||
Интеграция с CRM-системой
|
||||
<br />
|
||||
застройщика
|
||||
</p>
|
||||
<div className="space-y-15 max-w-9/10">
|
||||
<div className="space-y-4">
|
||||
<div className="flex">
|
||||
<div className="w-16 h-16 rounded-[18px] bg-[#B5F54E] flex items-center text-black font-medium justify-center -rotate-[4deg] text1 shadow-[0_2px_10px_0_#00000033] z-[2]">
|
||||
2K
|
||||
</div>
|
||||
<div className="right-2 relative shadow-[0_2px_10px_0_#00000033] z-[1]">
|
||||
<Image
|
||||
src={'/img/pages/home/presentation/flat1.jpg'}
|
||||
width={64}
|
||||
height={64}
|
||||
className="rounded-[18px]"
|
||||
alt="rooms"
|
||||
/>
|
||||
</div>
|
||||
<div className="-rotate-[4deg] right-4 relative shadow-[0_2px_10px_0_#00000033]">
|
||||
<Image
|
||||
src={'/img/pages/home/presentation/flat2.jpg'}
|
||||
width={64}
|
||||
height={64}
|
||||
className="rounded-[18px]"
|
||||
alt="rooms"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text1">
|
||||
Клиент всегда видит актуальные данные об интересующем его лоте,
|
||||
включая статус и стоимость.
|
||||
</p>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="flex">
|
||||
<Image
|
||||
src={'/img/pages/home/presentation/vova.jpg'}
|
||||
width={64}
|
||||
height={64}
|
||||
alt="vovka"
|
||||
className="rounded-[18px] -rotate-[4deg] shadow-[0_2px_10px_0_#00000033] z-[2]"
|
||||
/>
|
||||
<div className="rounded-[18px] bg-[#37393B] flex justify-center items-center relative right-2 w-16 h-16 shadow-[0_2px_10px_0_#00000033] z-[1]">
|
||||
<MailIcon className="text-white w-8 h-8" />
|
||||
</div>
|
||||
<div className="rounded-[18px] bg-[#37393B] flex justify-center items-center relative right-4 -rotate-[4deg] w-16 h-16 shadow-[0_2px_10px_0_#00000033]">
|
||||
<PhoneIcon className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
</div>
|
||||
<p className="text1">
|
||||
Инструмент продаж сам создаст карточку клиента в вашей CRM-системе и
|
||||
назначит ответственного менеджера.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
'use client';
|
||||
|
||||
import { primeVideos } from '@/consts/presentation/videos';
|
||||
import { Title } from '@/ui/Title';
|
||||
import { useInView, useMotionValueEvent, useScroll } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
import { useRef, useState } from 'react';
|
||||
import { Insolation } from '../MainPage/Presentation/Insolation';
|
||||
import { IntegrationCRM } from '../MainPage/Presentation/IntegrationCRM';
|
||||
import { CommercialOffer } from './CommercialOffer';
|
||||
import { Favorites } from './Favorites';
|
||||
import { Infrastructure } from './Infrastructure';
|
||||
import { Insolation } from './Insolation';
|
||||
import { IntegrationCRM } from './IntegrationCRM';
|
||||
import { SearchAndSelect } from './SearchAndSelect';
|
||||
import { ThreeDTour } from './ThreeDTour';
|
||||
import { VideoLayer } from './VideoLayer';
|
||||
@@ -20,7 +24,7 @@ export function Prime() {
|
||||
const [slide, setSlide] = useState(0);
|
||||
|
||||
useMotionValueEvent(scrollYProgress, 'change', (value) =>
|
||||
setSlide(Math.trunc(value * 7))
|
||||
setSlide(Math.trunc(value * primeVideos.length))
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -50,12 +54,74 @@ export function Prime() {
|
||||
<ThreeDTour scroll={scrollYProgress} />
|
||||
<SearchAndSelect scroll={scrollYProgress} />
|
||||
<Infrastructure scroll={scrollYProgress} />
|
||||
{/* <Favorites scroll={scrollYProgress} /> */}
|
||||
<Favorites scroll={scrollYProgress} />
|
||||
<IntegrationCRM scroll={scrollYProgress} />
|
||||
<Insolation scroll={scrollYProgress} />
|
||||
{/* <CommercialOffer scroll={scrollYProgress} /> */}
|
||||
<CommercialOffer scroll={scrollYProgress} />
|
||||
</div>
|
||||
<div className="flex absolute p-2 rounded-[27px] bg-[#37393B99] backdrop-blur-[20px] left-1/2 -translate-x-1/2">
|
||||
{primeVideos.map(({ src, anchorImg }, index) => (
|
||||
<PrimeProgressItem
|
||||
onClick={() => {
|
||||
target.current?.scrollTo({
|
||||
top: (index * target.current?.scrollHeight) / 7,
|
||||
});
|
||||
}}
|
||||
active={index === slide || (slide === 7 && index === 6)}
|
||||
src={anchorImg}
|
||||
title={src}
|
||||
key={src}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function PrimeProgressItem({
|
||||
active,
|
||||
src,
|
||||
title,
|
||||
onClick,
|
||||
}: {
|
||||
active: boolean;
|
||||
src: string;
|
||||
title: string;
|
||||
onClick: () => void;
|
||||
}) {
|
||||
return (
|
||||
<div onClick={onClick} className="group flex items-center cursor-pointer">
|
||||
<div
|
||||
className={
|
||||
'h-px w-3 group-first:hidden transition-colors ' +
|
||||
(!active
|
||||
? 'bg-[#37393B]'
|
||||
: 'bg-gradient-to-r from-[#37393B] to-white')
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className={
|
||||
'p-1 border relative rounded-2xl transition-colors' +
|
||||
(!active ? ' border-[#37393B]' : '')
|
||||
}
|
||||
>
|
||||
<Image
|
||||
src={src}
|
||||
fill
|
||||
alt={title}
|
||||
className="rounded-xl !relative"
|
||||
sizes="(min-width: 1440px) 3.333vw"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
'h-px w-3 group-last:hidden transition-colors ' +
|
||||
(!active
|
||||
? 'bg-[#37393B]'
|
||||
: 'bg-gradient-to-r from-white to-[#37393B]')
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ import HeartIcon from '../../../../public/icons/hearth.svg';
|
||||
import LocationIcon from '../../../../public/icons/location.svg';
|
||||
|
||||
export function SearchAndSelect({ scroll }: { scroll: MotionValue<number> }) {
|
||||
const opacity = useTransform(scroll, [1 / 7, 2 / 7, 3 / 7], [0, 1, 0]);
|
||||
const opacity = useTransform(scroll, [0, 1 / 6, 2 / 6], [0, 1, 0]);
|
||||
|
||||
const x = useTransform(scroll, [0, 1 / 6, 2 / 6], ['-100%', '0%', '-100%']);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
style={{ opacity }}
|
||||
className="p-4 flex flex-col h-full gap-3 z-10 w-[23.611vw] select-none"
|
||||
style={{ opacity, x }}
|
||||
className="flex flex-col h-full gap-3 z-10 w-[23.611vw] select-none absolute"
|
||||
>
|
||||
<div className="p-[1.667vw] rounded-2xl bg-radial-[at_100%_100%] from-[#7A7A7A66] backdrop-blur-[500px] space-y-20a flex flex-col justify-between flex-1">
|
||||
<p className="heading2 font-medium">Выбор квартиры на генплане</p>
|
||||
|
||||
@@ -3,14 +3,14 @@ import { motion, MotionValue, useTransform } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
|
||||
export function ThreeDTour({ scroll }: { scroll: MotionValue<number> }) {
|
||||
const opacity = useTransform(scroll, [0, 1 / 7], [1, 0]);
|
||||
const opacity = useTransform(scroll, [0, 1 / 6], [1, 0]);
|
||||
|
||||
const x = useTransform(scroll, [0, 1 / 7], ['100%', '200%']);
|
||||
const x = useTransform(scroll, [0, 1 / 6], ['0%', '100%']);
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
style={{ opacity, x }}
|
||||
className="p-[1.667vw] rounded-2xl bg-radial-[at_100%_100%] from-[#7A7A7A66] backdrop-blur-[500px] h-[63.014%] flex flex-col justify-between gap-16 absolute"
|
||||
className="p-[1.667vw] rounded-2xl bg-radial-[at_100%_100%] from-[#7A7A7A66] backdrop-blur-[500px] aspect-[340/368] flex flex-col justify-between gap-16 absolute right-0 w-[23.611vw] top-1/2 -translate-y-1/2"
|
||||
>
|
||||
<p className="heading2 font-medium">
|
||||
Виртуальный тур по жилому комплексу
|
||||
@@ -18,7 +18,7 @@ export function ThreeDTour({ scroll }: { scroll: MotionValue<number> }) {
|
||||
<div className="grid grid-cols-3 gap-x-3 gap-y-6">
|
||||
{threeDTour.map(({ src, title }) => (
|
||||
<div className="space-y-1" key={title}>
|
||||
<div className="relative aspect-square">
|
||||
<div className="relative aspect-square max-w-[4.444vw] max-h-[4.444vw]">
|
||||
<Image
|
||||
src={src}
|
||||
alt={title}
|
||||
|
||||
@@ -23,17 +23,17 @@ export function VideoLayer({ scroll }: { scroll: MotionValue<number> }) {
|
||||
return (
|
||||
<motion.div className="absolute overflow-hidden h-full transition-all w-[97.222vw]">
|
||||
{videoRefs.length &&
|
||||
primeVideos.map((video, index) =>
|
||||
video ? (
|
||||
primeVideos.map(({ src }, index) =>
|
||||
src ? (
|
||||
<motion.video
|
||||
key={video}
|
||||
src={`/videos/pages/home/presentation/${video}.mp4`}
|
||||
key={src}
|
||||
src={`/videos/pages/home/presentation/${src}.mp4`}
|
||||
ref={videoRefs[index]}
|
||||
loop
|
||||
muted
|
||||
playsInline
|
||||
style={{ zIndex: primeVideos.length - index }}
|
||||
className={`absolute w-[48.333vw] left-1/2 -translate-x-1/2 h-full object-cover transition-opacity${
|
||||
className={`absolute w-[48.333vw] left-1/2 -translate-x-1/2 h-full transition-opacity${
|
||||
slide > index && index !== primeVideos.length - 1
|
||||
? ' opacity-0'
|
||||
: ''
|
||||
@@ -41,9 +41,9 @@ export function VideoLayer({ scroll }: { scroll: MotionValue<number> }) {
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
key={video}
|
||||
key={src}
|
||||
style={{ zIndex: primeVideos.length - index }}
|
||||
className={`inset-0 bg-[green] transition-opacity${
|
||||
className={`inset-0 transition-opacity${
|
||||
slide > index && index !== primeVideos.length - 1
|
||||
? ' opacity-0'
|
||||
: ''
|
||||
|
||||
@@ -4,7 +4,7 @@ import Link from 'next/link';
|
||||
export function AwardsCard({ className }: { className?: string }) {
|
||||
return (
|
||||
<div
|
||||
className={`p-6 rounded-2xl bg-[#37393B99] xl:hidden max-sm:aspect-square relative flex flex-col justify-between overflow-hidden${
|
||||
className={`lg:p-[1.667vw] p-6 lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99] xl:hidden max-sm:aspect-square relative flex flex-col justify-between overflow-hidden${
|
||||
className ? ' ' + className : ''
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -14,7 +14,7 @@ export function ProjectCard(project: IProject) {
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true, margin: '-100px' }}
|
||||
transition={{ duration: 1, ease: [0.58, 0.12, 0.27, 0.98], delay: 0.2 }}
|
||||
className="group aspect-square rounded-2xl relative flex items-end p-4 overflow-hidden"
|
||||
className="group aspect-square lg:rounded-[1.111vw] rounded-2xl relative flex items-end p-4 overflow-hidden"
|
||||
>
|
||||
<ItemActions item={project} />
|
||||
<div
|
||||
|
||||
@@ -33,7 +33,7 @@ export function ProjectsSection({ projects }: { projects: IProject[] }) {
|
||||
delay: 0.2,
|
||||
}}
|
||||
href={'/projects'}
|
||||
className="rounded-xl bg-[#232425] hover:bg-[#23242599] transition-colors aspect-square self-center p-5 flex items-center justify-center btnl font-medium gap-2"
|
||||
className="lg:rounded-[1.111vw] rounded-2xl bg-[#232425] hover:bg-[#23242599] transition-colors aspect-square self-center p-5 flex items-center justify-center btnl font-medium gap-2"
|
||||
>
|
||||
Смотреть все
|
||||
<ArrowRightIcon className="lg:w-[1.389vw] lg:h-[1.389vw] md:max-lg:w-[2.604vw] md:max-lg:h-[2.604vw] w-5 h-5 text-white" />
|
||||
|
||||
@@ -1,18 +1,42 @@
|
||||
export const videos = [
|
||||
'1_search',
|
||||
'2_3dtour',
|
||||
'3_infrastructure',
|
||||
'4_insolation',
|
||||
'5_engine',
|
||||
'6_reservation',
|
||||
{ src: '1_search', anchorImg: '/img/pages/prime/search-select.png' },
|
||||
{ src: '2_3dtour', anchorImg: '/img/pages/prime/3dtour.png' },
|
||||
{
|
||||
src: '3_infrastructure',
|
||||
anchorImg: '/img/pages/prime/infra.png',
|
||||
},
|
||||
{
|
||||
src: '4_insolation',
|
||||
anchorImg: '/img/pages/prime/insolation.png',
|
||||
},
|
||||
{ src: '5_engine', anchorImg: '/img/pages/prime/engine.png' },
|
||||
{
|
||||
src: '6_reservation',
|
||||
anchorImg: '/img/pages/prime/crm.png',
|
||||
},
|
||||
];
|
||||
|
||||
export const primeVideos = [
|
||||
'2_3dtour',
|
||||
'1_search',
|
||||
'3_infrastructure',
|
||||
'',
|
||||
'6_reservation',
|
||||
'4_insolation',
|
||||
'',
|
||||
{ src: '2_3dtour', anchorImg: '/img/pages/prime/3dtour.png' },
|
||||
{
|
||||
src: '1_search',
|
||||
anchorImg: '/img/pages/prime/search-select.png',
|
||||
},
|
||||
{
|
||||
src: '3_infrastructure',
|
||||
anchorImg: '/img/pages/prime/infra.png',
|
||||
},
|
||||
{
|
||||
src: '',
|
||||
anchorImg: '/img/pages/prime/favorites.png',
|
||||
},
|
||||
{
|
||||
src: '6_reservation',
|
||||
anchorImg: '/img/pages/prime/crm.png',
|
||||
},
|
||||
{
|
||||
src: '4_insolation',
|
||||
anchorImg: '/img/pages/prime/insolation.png',
|
||||
},
|
||||
{ src: '', anchorImg: '/img/pages/prime/cp.png' },
|
||||
];
|
||||
|
||||
@@ -22,12 +22,12 @@ export function CheckboxesGroup<IFieldValues extends FieldValues>({
|
||||
const values: string[] = useWatch({ control, name }) || [];
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<div className="flex flex-wrap lg:gap-[0.556vw] gap-2">
|
||||
{options.map((option) => (
|
||||
<label
|
||||
htmlFor={name + '_' + option}
|
||||
key={option}
|
||||
className={`cursor-pointer transition-colors rounded-xl font-medium text-nowrap select-none px-6 py-[17px] btnm ${
|
||||
className={`cursor-pointer transition-colors rounded-[1.111vw] font-medium text-nowrap select-none lg:px-[1.667vw] px-6 lg:py-[1.181vw] py-[17px] btnm ${
|
||||
value.includes(option)
|
||||
? 'bg-white text-black'
|
||||
: 'bg-[#37393B99] hover:bg-[#37393B]'
|
||||
|
||||
@@ -8,7 +8,7 @@ export function PostTag({
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
'lg:px-[0.833vw]a px-3 lg:py-[0.486vw]a py-[7px] rounded-[17px] btns font-medium ' +
|
||||
'lg:px-[0.833vw] px-3 lg:py-[0.486vw] py-[7px] rounded-[17px] btns font-medium ' +
|
||||
(active ? 'bg-gradient' : 'bg-[#37393B99]')
|
||||
}
|
||||
>
|
||||
|
||||