diff --git a/src/fonts/.gitkeep b/src/fonts/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/fonts/FontFont_FF.Mark.Pro.Heavy.otf b/src/fonts/FontFont_FF.Mark.Pro.Heavy.otf deleted file mode 100644 index c9caaccd..00000000 Binary files a/src/fonts/FontFont_FF.Mark.Pro.Heavy.otf and /dev/null differ diff --git a/src/fonts/FontFont_FF.Mark.Pro.Medium.otf b/src/fonts/FontFont_FF.Mark.Pro.Medium.otf deleted file mode 100644 index d5999d8c..00000000 Binary files a/src/fonts/FontFont_FF.Mark.Pro.Medium.otf and /dev/null differ diff --git a/src/fonts/FontFont_FF.Mark.Pro.otf b/src/fonts/FontFont_FF.Mark.Pro.otf deleted file mode 100644 index 3b72bc1f..00000000 Binary files a/src/fonts/FontFont_FF.Mark.Pro.otf and /dev/null differ diff --git a/src/fonts/Quantum-400.otf b/src/fonts/Quantum-400.otf deleted file mode 100644 index b26c7892..00000000 Binary files a/src/fonts/Quantum-400.otf and /dev/null differ diff --git a/src/icons/benefits-flow.svg b/src/icons/benefits-flow.svg new file mode 100644 index 00000000..37e8765f --- /dev/null +++ b/src/icons/benefits-flow.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/benefits-sound.svg b/src/icons/benefits-sound.svg new file mode 100644 index 00000000..7850ac02 --- /dev/null +++ b/src/icons/benefits-sound.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/icons/benefits-vr.svg b/src/icons/benefits-vr.svg new file mode 100644 index 00000000..0f09382d --- /dev/null +++ b/src/icons/benefits-vr.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/icons/button play-video.svg b/src/icons/button play-video.svg new file mode 100644 index 00000000..b1f949ab --- /dev/null +++ b/src/icons/button play-video.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/card-MC.svg b/src/icons/card-MC.svg new file mode 100644 index 00000000..2ce8f2da --- /dev/null +++ b/src/icons/card-MC.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/card-visa.svg b/src/icons/card-visa.svg new file mode 100644 index 00000000..84cebcb6 --- /dev/null +++ b/src/icons/card-visa.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/fav-big.svg b/src/icons/fav-big.svg new file mode 100644 index 00000000..a4259452 --- /dev/null +++ b/src/icons/fav-big.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/icons/fav-small.svg b/src/icons/fav-small.svg new file mode 100644 index 00000000..61cb0d54 --- /dev/null +++ b/src/icons/fav-small.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/icons/logo-small.png b/src/icons/logo-small.png new file mode 100644 index 00000000..373173d0 Binary files /dev/null and b/src/icons/logo-small.png differ diff --git a/src/icons/menu-burger.svg b/src/icons/menu-burger.svg new file mode 100644 index 00000000..31499720 --- /dev/null +++ b/src/icons/menu-burger.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/icons/menu-close.svg b/src/icons/menu-close.svg new file mode 100644 index 00000000..77623147 --- /dev/null +++ b/src/icons/menu-close.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/icons/menu-closeBlue.svg b/src/icons/menu-closeBlue.svg new file mode 100644 index 00000000..b5e21280 --- /dev/null +++ b/src/icons/menu-closeBlue.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/icons/mob-arrow.svg b/src/icons/mob-arrow.svg new file mode 100644 index 00000000..6d4ea073 --- /dev/null +++ b/src/icons/mob-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/more-building.svg b/src/icons/more-building.svg new file mode 100644 index 00000000..988d7f22 --- /dev/null +++ b/src/icons/more-building.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/more-building1.svg b/src/icons/more-building1.svg new file mode 100644 index 00000000..cba7a221 --- /dev/null +++ b/src/icons/more-building1.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/more-cap.svg b/src/icons/more-cap.svg new file mode 100644 index 00000000..ed2e4f00 --- /dev/null +++ b/src/icons/more-cap.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/icons/more-cap1.svg b/src/icons/more-cap1.svg new file mode 100644 index 00000000..19e56acc --- /dev/null +++ b/src/icons/more-cap1.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/icons/more-circle.svg b/src/icons/more-circle.svg new file mode 100644 index 00000000..5bc6e3b8 --- /dev/null +++ b/src/icons/more-circle.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/icons/more-circle1.svg b/src/icons/more-circle1.svg new file mode 100644 index 00000000..85ed68c3 --- /dev/null +++ b/src/icons/more-circle1.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/icons/more-flow.svg b/src/icons/more-flow.svg new file mode 100644 index 00000000..6236a12c --- /dev/null +++ b/src/icons/more-flow.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/more-flow1.svg b/src/icons/more-flow1.svg new file mode 100644 index 00000000..53104dab --- /dev/null +++ b/src/icons/more-flow1.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/icons/social/footer-facebook.svg b/src/icons/social/footer-facebook.svg new file mode 100644 index 00000000..e4de883e --- /dev/null +++ b/src/icons/social/footer-facebook.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/social/footer-redit.svg b/src/icons/social/footer-redit.svg new file mode 100644 index 00000000..53bade5b --- /dev/null +++ b/src/icons/social/footer-redit.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/social/footer-twitter.svg b/src/icons/social/footer-twitter.svg new file mode 100644 index 00000000..084900b8 --- /dev/null +++ b/src/icons/social/footer-twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/social/footer-youtube.svg b/src/icons/social/footer-youtube.svg new file mode 100644 index 00000000..d0756ed2 --- /dev/null +++ b/src/icons/social/footer-youtube.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/icons/social/social-fb.svg b/src/icons/social/social-fb.svg new file mode 100644 index 00000000..e4de883e --- /dev/null +++ b/src/icons/social/social-fb.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/social/social-reddit.svg b/src/icons/social/social-reddit.svg new file mode 100644 index 00000000..53bade5b --- /dev/null +++ b/src/icons/social/social-reddit.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/social/social-tw.svg b/src/icons/social/social-tw.svg new file mode 100644 index 00000000..084900b8 --- /dev/null +++ b/src/icons/social/social-tw.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/social/social-video.svg b/src/icons/social/social-video.svg new file mode 100644 index 00000000..d0756ed2 --- /dev/null +++ b/src/icons/social/social-video.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/icons/visa.svg b/src/icons/visa.svg new file mode 100644 index 00000000..0a97fb76 --- /dev/null +++ b/src/icons/visa.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/images/about-image1.jpg b/src/images/about-image1.jpg new file mode 100644 index 00000000..773eddb3 Binary files /dev/null and b/src/images/about-image1.jpg differ diff --git a/src/images/image1.png b/src/images/image1.png new file mode 100644 index 00000000..fb96ec11 Binary files /dev/null and b/src/images/image1.png differ diff --git a/src/images/image2.jpg b/src/images/image2.jpg new file mode 100644 index 00000000..46ecfce0 Binary files /dev/null and b/src/images/image2.jpg differ diff --git a/src/images/image3.jpg b/src/images/image3.jpg new file mode 100644 index 00000000..31bb570e Binary files /dev/null and b/src/images/image3.jpg differ diff --git a/src/images/image4.jpg b/src/images/image4.jpg new file mode 100644 index 00000000..0091382e Binary files /dev/null and b/src/images/image4.jpg differ diff --git a/src/images/image5..jpg b/src/images/image5..jpg new file mode 100644 index 00000000..0dd8fef1 Binary files /dev/null and b/src/images/image5..jpg differ diff --git a/src/images/img2.jpg b/src/images/img2.jpg new file mode 100644 index 00000000..c71e14f9 Binary files /dev/null and b/src/images/img2.jpg differ diff --git a/src/images/img5.jpg b/src/images/img5.jpg new file mode 100644 index 00000000..05c5be09 Binary files /dev/null and b/src/images/img5.jpg differ diff --git a/src/images/tech.png b/src/images/tech.png new file mode 100644 index 00000000..a5816011 Binary files /dev/null and b/src/images/tech.png differ diff --git a/src/index.html b/src/index.html index 8019b83e..daf98c72 100644 --- a/src/index.html +++ b/src/index.html @@ -6,14 +6,2496 @@ name="viewport" content="width=device-width, initial-scale=1.0" /> - Title + KatVR + + - -

Hello Mate Academy

+ + + +
+ + Buy Now + +
+ + + + + + + + + + + + + + + +
+
+
+

+ MORE THAN + GAMING! +

+ +

+ This also made for people who are interested in... +

+ +
+
+

EDUCATION

+

+ Create aducational simulations, trainings and much more with + unlimited virtual space and minimum physical space +

+
+ +
+

REAL ESTATE

+

+ Desighn architectural projects in a deeply realistic environment + allowing visitors to freely walk around, and feel their vibe +

+
+ +
+

FITNESS

+

+ Combine business with pleasure, and discover countless ways to + stay fit while playing your favorite VR Games! +

+
+ +
+

+ SOCIAL INTERACTIONS +

+

+ Hang out with your friends in the virtual world when you can’t + meet space requirements +

+
+
+
+
+ +
+
+
+
+
+
+
+

+ ABOUT + PRODUCT +

+ KAT Loco device on user + +

+ KAT loco is a foot-based VR locomotion system that gives + complete physical control over lower-body actions, + allowing you to freely walk, run, and carry out just any + other movement in virtual reality. +

+
+
+ +
+
+

+ ABOUT + PRODUCT +

+ VR Headset + +

+ 2KAT loco is a foot-based VR locomotion system that gives + complete physical control over lower-body actions, + allowing you to freely walk, run, and carry out just any + other movement in virtual reality. +

+
+
+ +
+
+

+ ABOUT + PRODUCT +

+ VR Headset + +

+ 3KAT loco is a foot-based VR locomotion system that gives + complete physical control over lower-body actions, + allowing you to freely walk, run, and carry out just any + other movement in virtual reality. +

+
+
+ +
+
+

+ ABOUT + PRODUCT +

+ VR Headset + +

+ 4KAT loco is a foot-based VR locomotion system that gives + complete physical control over lower-body actions, + allowing you to freely walk, run, and carry out just any + other movement in virtual reality. +

+
+
+ +
+
+

+ ABOUT + PRODUCT +

+ VR Headset + +

+ 5KAT loco is a foot-based VR locomotion system that gives + complete physical control over lower-body actions, + allowing you to freely walk, run, and carry out just any + other movement in virtual reality. +

+
+
+
+ +
+
+ + + + + +
+ +
+ 1/5 +
+
+ +
+
+
+
+
+
+
+ +
+ + + + +
+
+
+ +
+
+ Hello, + +

+ NICE TO MEET + YOU! +

+

+ KAT VR is an independent company dedicated to the research, + development, and sales of VR Locomotion products and solutions. + Founded in 2013, we have quickly grown to become one of the + world’s leading professional suppliers of VR games’ & + simulations’ equipment +

+
+ +
About us
+
+
+
+ +
+
+

+ TECH + SPECS +

+ +
+
+ Tech device +
+
+
+ +
+ + + + + +
+

SENSOR

+
    +
  • Weight: 35g/1.23oz each
  • +
  • Dimension: 50mm/1.97in
  • +
  • 24mm/0.94in
  • +
  • Light: LED lights
  • +
+
+
+ + +
+ + + + + + + +
+

BATTERRIES

+
    +
  • Type: Lithium-Ion polymer batteries
  • +
  • Capacity: 370mAh
  • +
  • + Battery life: 10% of continuous use 150 hours +
    + on standby +
  • +
  • Charging: Fast charging ~ 1 hour
  • +
  • Charging voltage and current: 5V = 0.5A
  • +
+
+
+ + +
+ + + + + + + +
+

CONNECTION

+
    +
  • Wireless: Bluetooth 4.2
  • +
  • Signal range: 5m
  • +
  • Receiver: USB 2.0 and above
  • +
+
+
+
+
+
+ +
+
+

+ Why + Kat loco? +

+ +
+
+

+ UNIVERSALLY COMPATIBLE +

+

+ KAT Loco offers universal compatibility across all major VR + headsets and platforms allowing you to play any VR game with + support for Free Locomotion +

+
+ +
+

+ VR/PC CONTROL PANEL +

+

+ Our Multifunctional Software allows for quick access to KAT + Loco’s control panel both from a computer desktop, and directly + from your VR headset. +

+
+ +
+

+ WIRELESS SENSORS +

+

+ What makes it even more advanced, KAT Loco is entirely wireless, + and comes with a complete system of algorithms, super durable + batteries and more! +

+
+
+
+
+ +
+
+

Have any questions?

+

+ GET IN + TOUCH +

+ +
+
+
+ + + Please, fill your name* +
+ +
+ + + Incorrect email format* +
+ +
+ + + Please, fill your phone* +
+ +
+ + +
+ + +
+
+ +

+ Our manager will reply you within 15 minutes +

+ + +
+
+ + +
+ + + + diff --git a/src/scripts/main.js b/src/scripts/main.js index ad9a93a7..e4019a15 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1 +1,1383 @@ -'use strict'; +// 'use strict'; + +// страны и города +document.addEventListener('DOMContentLoaded', () => { + const countrySelect = document.getElementById('country'); + const citySelect = document.getElementById('city'); + + // Объект с городами для каждой страны + const citiesByCountry = { + ukraine: [ + { value: 'kyiv', text: 'Kyiv' }, + { value: 'Zaporizhia', text: 'Zaporizhia' }, + { value: 'Kharkiv', text: 'Kharkiv' }, + { value: 'Odessa', text: 'Odessa' }, + { value: 'Dnipro', text: 'Dnipro' }, + { value: 'Donetsk', text: 'Donetsk' }, + { value: 'Mykolaiv', text: 'Mykolaiv' }, + ], + russia: [ + { value: 'moskov', text: 'Moskov' }, + { value: 'maykop', text: 'Maykop' }, + ], + france: [ + { value: 'parish', text: 'Parish' }, + { value: 'marsel', text: 'Marsel' }, + ], + spain: [ + { value: 'barselona', text: 'Barselona' }, + { value: 'kapella', text: 'Kapella' }, + ], + usa: [ + { value: 'mayami', text: 'Mayami' }, + { value: 'vashington', text: 'Vashington' }, + ], + china: [ + { value: 'pekin', text: 'Pekin' }, + { value: 'shanhay', text: 'Shanhay' }, + ], + italy: [ + { value: 'milan', text: 'Milan' }, + { value: 'palermo', text: 'Palermo' }, + ], + turkey: [ + { value: 'stambul', text: 'Stambul' }, + { value: 'ankara', text: 'Ankara' }, + ], + }; + + // Функция для обновления списка городов + function updateCities() { + const selectedCountry = countrySelect.value; + citySelect.innerHTML = ''; // Сбрасываем список + + if (selectedCountry && citiesByCountry[selectedCountry]) { + citiesByCountry[selectedCountry].forEach((city) => { + const option = document.createElement('option'); + option.value = city.value; + option.textContent = city.text; + citySelect.appendChild(option); + }); + } + } + + // Слушаем изменение страны + countrySelect.addEventListener('change', updateCities); +}); + +// блок цена +let currentQuantity = 1; // Значение по умолчанию +const basePrice = 1200; // Базовая цена за 1 единицу + +document.addEventListener('DOMContentLoaded', () => { + const quantitySelects = document.querySelectorAll('.quantity__select-option'); + const priceValues = document.querySelectorAll('.quantity__select-price'); + + // Функция для синхронизации количества и цены + function syncQuantityAndPrice(selectedQuantity) { + currentQuantity = parseInt(selectedQuantity); + + // Обновляем значение во всех select + quantitySelects.forEach((select) => { + select.value = currentQuantity; + }); + + // Обновляем цену во всех price-container + const totalPrice = basePrice * currentQuantity; + priceValues.forEach((priceValue) => { + priceValue.textContent = `${totalPrice}$`; + }); + } + + // Инициализация: устанавливаем начальное значение и цену + syncQuantityAndPrice(currentQuantity); + + // Привязываем обработчик события change ко всем элементам quantity__select-option + quantitySelects.forEach((select) => { + select.addEventListener('change', () => { + const selectedQuantity = parseInt(select.value); + syncQuantityAndPrice(selectedQuantity); + }); + }); +}); + +// Функция для ограничения ввода только цифр +function restrictToNumbers(event) { + const input = event.target; + input.value = input.value.replace(/[^0-9]/g, ''); +} + +// Функция для проверки количества цифр в полях номера карты +function checkCardNumberLength(input) { + const errorMessage = document.getElementById('card-number-error'); + const value = input.value; + + if (value.length < 4 && value.length > 0) { + errorMessage.textContent = 'Please enter exactly 4 digits in each field.'; + errorMessage.style.display = 'block'; + } else { + const allInputs = document.querySelectorAll( + '.payment-form__input--card-number', + ); + let allValid = true; + allInputs.forEach((inp) => { + if (inp.value.length > 0 && inp.value.length < 4) { + allValid = false; + } + }); + if (allValid) { + errorMessage.style.display = 'none'; + } + } + updatePurchaseButtonState(); // Проверяем состояние кнопки +} + +// Функция для проверки количества цифр в поле CVV +function checkCVVLength(input) { + const errorMessage = document.getElementById('cvv-error'); + const value = input.value; + + if (value.length < 3 && value.length > 0) { + errorMessage.textContent = 'Please enter exactly 3 digits.'; + errorMessage.style.display = 'block'; + } else { + errorMessage.style.display = 'none'; + } + updatePurchaseButtonState(); // Проверяем состояние кнопки +} + +// Функция для ограничения ввода только латинских букв и пробелов +function restrictToLettersAndSpaces(event) { + const input = event.target; + const errorMessage = document.getElementById('card-holder-error'); + const originalValue = input.value; + input.value = input.value.replace(/[^a-zA-Z\s]/g, ''); + + if (originalValue !== input.value) { + errorMessage.textContent = 'Please use only Latin letters and spaces.'; + errorMessage.style.display = 'block'; + } else { + errorMessage.style.display = 'none'; + } + updatePurchaseButtonState(); // Проверяем состояние кнопки +} + +// Функция для поля даты истечения (автоформатирование MM / YY с валидацией месяца) +function restrictToDateFormat(event) { + const input = event.target; + const errorMessage = document.getElementById('expiry-date-error'); + let value = input.value.replace(/[^0-9]/g, ''); + + if (value.length > 4) { + value = value.slice(0, 4); + } + + let monthValid = true; + if (value.length >= 2) { + const month = parseInt(value.slice(0, 2), 10); + if (month < 1 || month > 12) { + monthValid = false; + errorMessage.textContent = 'Month must be between 01 and 12.'; + errorMessage.style.display = 'block'; + value = value.slice(0, 2); + } else { + errorMessage.style.display = 'none'; + } + } else { + errorMessage.style.display = 'none'; + } + + let formattedValue = value; + if (value.length > 2 && monthValid) { + formattedValue = value.slice(0, 2) + ' / ' + value.slice(2, 4); + } + input.value = formattedValue; + updatePurchaseButtonState(); // Проверяем состояние кнопки +} + +// Функция для проверки валидности всех полей и обновления состояния кнопки +function updatePurchaseButtonState() { + const purchaseButton = document.querySelector('.buy__button-pay'); + const cardNumber1 = document.getElementById('card-number-1').value; + const cardNumber2 = document.getElementById('card-number-2').value; + const cardNumber3 = document.getElementById('card-number-3').value; + const cardNumber4 = document.getElementById('card-number-4').value; + const cardHolder = document.getElementById('card-holder').value; + const expiryDate = document.getElementById('expiry-date').value; + const cvv = document.getElementById('cvv').value; + + // Проверяем валидность всех полей + const isCardNumberValid = + /^\d{4}$/.test(cardNumber1) && + /^\d{4}$/.test(cardNumber2) && + /^\d{4}$/.test(cardNumber3) && + /^\d{4}$/.test(cardNumber4); + + const isCardHolderValid = + /^[a-zA-Z\s]+$/.test(cardHolder) && cardHolder.length > 0; + + const isExpiryDateValid = /^\d{2}\s\/\s\d{2}$/.test(expiryDate); + const month = parseInt(expiryDate.slice(0, 2), 10); + const isMonthValid = month >= 1 && month <= 12; + + const isCVVValid = /^\d{3}$/.test(cvv); + + // Включаем кнопку только если все поля валидны + if ( + isCardNumberValid && + isCardHolderValid && + isExpiryDateValid && + isMonthValid && + isCVVValid + ) { + purchaseButton.disabled = false; + } else { + purchaseButton.disabled = true; + } +} + +// Функция для перемещения фокуса на следующее поле при нажатии Enter +function handleEnterKey(event) { + if (event.key === 'Enter') { + event.preventDefault(); + const input = event.target; + const form = input.form; + const inputs = Array.from(form.querySelectorAll('input')); + const currentIndex = inputs.indexOf(input); + + if (input.classList.contains('payment-form__input--card-number')) { + if (input.value.length === 4) { + if (currentIndex < inputs.length - 1) { + inputs[currentIndex + 1].focus(); + } + } else { + const errorMessage = document.getElementById('card-number-error'); + errorMessage.textContent = + 'Please enter exactly 4 digits in each field.'; + errorMessage.style.display = 'block'; + } + } else if (input.id === 'cvv') { + if (input.value.length === 3) { + if (currentIndex < inputs.length - 1) { + inputs[currentIndex + 1].focus(); + } + } else { + const errorMessage = document.getElementById('cvv-error'); + errorMessage.textContent = 'Please enter exactly 3 digits.'; + errorMessage.style.display = 'block'; + } + } else { + if (currentIndex < inputs.length - 1) { + inputs[currentIndex + 1].focus(); + } + } + } +} + +// Применяем ограничения и проверки к полям номера карты +document + .querySelectorAll('.payment-form__input--card-number') + .forEach((input) => { + input.addEventListener('input', function (event) { + restrictToNumbers(event); + checkCardNumberLength(input); + }); + input.addEventListener('keydown', handleEnterKey); + }); + +// Применяем ограничения и проверки к полю CVV +document.getElementById('cvv').addEventListener('input', function (event) { + restrictToNumbers(event); + checkCVVLength(event.target); +}); +document.getElementById('cvv').addEventListener('keydown', handleEnterKey); + +// Применяем ограничения к другим полям +document + .getElementById('expiry-date') + .addEventListener('input', restrictToDateFormat); +document + .getElementById('expiry-date') + .addEventListener('keydown', handleEnterKey); + +document + .getElementById('card-holder') + .addEventListener('input', restrictToLettersAndSpaces); +document + .getElementById('card-holder') + .addEventListener('keydown', handleEnterKey); + +// Валидация при отправке формы +document + .getElementById('payment-form') + .addEventListener('submit', function (event) { + event.preventDefault(); + + const cardNumber1 = document.getElementById('card-number-1').value; + const cardNumber2 = document.getElementById('card-number-2').value; + const cardNumber3 = document.getElementById('card-number-3').value; + const cardNumber4 = document.getElementById('card-number-4').value; + const cardHolder = document.getElementById('card-holder').value; + const expiryDate = document.getElementById('expiry-date').value; + const cvv = document.getElementById('cvv').value; + + if ( + !/^\d{4}$/.test(cardNumber1) || + !/^\d{4}$/.test(cardNumber2) || + !/^\d{4}$/.test(cardNumber3) || + !/^\d{4}$/.test(cardNumber4) + ) { + alert('Each card number field must contain exactly 4 digits.'); + return; + } + + if (!/^[a-zA-Z\s]+$/.test(cardHolder)) { + alert('Card Holder Name must contain only Latin letters and spaces.'); + return; + } + + if (!/^\d{2}\s\/\s\d{2}$/.test(expiryDate)) { + alert('Expiration date must be in the format MM / YY (e.g., 12 / 25).'); + return; + } + + const month = parseInt(expiryDate.slice(0, 2), 10); + if (month < 1 || month > 12) { + alert('Month must be between 01 and 12.'); + return; + } + + if (!/^\d{3}$/.test(cvv)) { + alert('CVV must be exactly 3 digits.'); + return; + } + + console.log('Payment data:', { + cardNumber: `${cardNumber1} ${cardNumber2} ${cardNumber3} ${cardNumber4}`, + cardHolder, + expiryDate, + cvv, + }); + }); + +// Инициализируем состояние кнопки при загрузке страницы +document.addEventListener('DOMContentLoaded', () => { + updatePurchaseButtonState(); +}); + +// Управление шагами и модальными окнами +document.addEventListener('DOMContentLoaded', () => { + const menu = document.getElementById('menu'); + const menuButton = document.querySelector('.header__icon--menu'); + const menuCloseButton = document.querySelector('.menu--close'); + const modals = document.querySelectorAll('.buy'); + const steps = document.querySelectorAll('.step'); + const stepLinks = document.querySelectorAll('.buy__menu-item'); + const buyButton = document.querySelector('.buy-button'); + const orderForm = document.getElementById('order-form'); + const closeButtons = document.querySelectorAll('.buy__close'); + const purchaseButtons = document.querySelectorAll('.buy__button'); + + let currentStep = 1; + let isClosing = false; // Флаг для отслеживания закрытия + + // Функция для переключения шага + function setActiveStep(stepNumber) { + if (isClosing) return; // Не открываем модальное окно, если оно закрывается + + modals.forEach((modal) => { + modal.classList.remove('buy--open'); + }); + + const activeModal = document.getElementById( + stepNumber === 1 ? 'buy' : `step-${stepNumber}`, + ); + if (activeModal) { + activeModal.classList.add('buy--open'); + console.log(`Открываем модальное окно для шага ${stepNumber}`); + } else { + console.error(`Модальное окно для шага ${stepNumber} не найдено`); + } + + steps.forEach((step) => { + step.classList.remove('active'); + if (parseInt(step.dataset.step) === stepNumber) { + step.classList.add('active'); + } + }); + + currentStep = stepNumber; + window.location.hash = stepNumber === 1 ? 'buy' : `step-${stepNumber}`; + } + + // Функция для закрытия модального окна + function closeModal() { + isClosing = true; + modals.forEach((modal) => modal.classList.remove('buy--open')); + window.location.hash = ''; // Сбрасываем хэш + currentStep = 1; + isClosing = false; + } + + // Открытие модального окна при клике на "Buy Now" + if (buyButton) { + buyButton.addEventListener('click', (e) => { + e.preventDefault(); + console.log('Клик по кнопке Buy Now'); + setActiveStep(1); + }); + } else { + console.error('Кнопка Buy Now не найдена'); + } + + // Переключение шагов при клике на ссылки в меню + stepLinks.forEach((link) => { + link.addEventListener('click', (e) => { + e.preventDefault(); + const stepNumber = parseInt(link.parentElement.dataset.step); + console.log(`Клик по ссылке шага ${stepNumber}`); + setActiveStep(stepNumber); + }); + }); + + // Переход на следующий шаг при клике на "Purchase" или "End" + purchaseButtons.forEach((button, index) => { + button.addEventListener('click', (e) => { + e.preventDefault(); + console.log(`Клик по кнопке с индексом ${index}`); + if (index === 0) { + // Первый шаг (Place Order) + if (orderForm.checkValidity()) { + setActiveStep(2); + } else { + orderForm.reportValidity(); + } + } else if (index === 1) { + // Второй шаг (Pay) + setActiveStep(3); + } else if (index === 2) { + // Третий шаг (Complete) + console.log('Клик по кнопке End'); + closeModal(); + } + }); + }); + + // Закрытие модального окна + closeButtons.forEach((button) => { + button.addEventListener('click', (e) => { + e.preventDefault(); + closeModal(); + }); + }); + + // Проверка хэша при загрузке страницы + function checkHashOnLoad() { + const hash = window.location.hash.replace('#', ''); + if (hash === 'buy') { + setActiveStep(1); + } else if (hash === 'step-2') { + setActiveStep(2); + } else if (hash === 'step-3') { + setActiveStep(3); + } else if (hash === 'menu') { + openMenu(); + } else if (hash === 'help') { + openAsideModal('help'); + } else if (hash === 'faq') { + openAsideModal('faq'); + } else if (hash === 'lang') { + openAsideModal('lang'); + } else { + // Если хэш пустой, закрываем все модальные окна + modals.forEach((modal) => modal.classList.remove('buy--open')); + currentStep = 1; + } + } + + // Вызываем проверку хэша при загрузке страницы + checkHashOnLoad(); + + // Слушаем изменение хэша + window.addEventListener('hashchange', () => { + console.log('Хэш изменился:', window.location.hash); + if (isClosing) return; + + const hash = window.location.hash.replace('#', ''); + const navigationHashes = ['about', 'tech', 'benefits', 'contact']; + + if (hash === 'buy') { + setActiveStep(1); + } else if (hash === 'step-2') { + setActiveStep(2); + } else if (hash === 'step-3') { + setActiveStep(3); + } else if (hash === 'menu') { + openMenu(); + } else if (hash === 'help') { + openAsideModal('help'); + } else if (hash === 'faq') { + openAsideModal('faq'); + } else if (hash === 'lang') { + openAsideModal('lang'); + } else if (!navigationHashes.includes(hash)) { + closeModal(); + } + }); +}); + +// Управление меню +document.addEventListener('DOMContentLoaded', () => { + const menu = document.getElementById('menu'); + const menuButton = document.querySelector('.header__icon--menu'); + const menuCloseButton = document.querySelector('.menu--close'); + + // Функция для открытия меню + function openMenu() { + menu.classList.add('menu--open'); + window.location.hash = 'menu'; // Устанавливаем хэш + } + + // Функция для закрытия меню + function closeMenu() { + menu.classList.remove('menu--open'); + window.location.hash = ''; // Сбрасываем хэш + } +}); + +//main button. Появление при скроле +document.addEventListener('DOMContentLoaded', () => { + const mainButton = document.querySelector('.main-button'); + const header = document.querySelector('.header'); + + // Получаем высоту хедера динамически + const headerHeight = header.offsetHeight; + + window.addEventListener('scroll', () => { + // Текущее положение скролла + const scrollPosition = window.scrollY; + + if (scrollPosition > 50) { + // Показываем кнопку, если скролл больше 50px + mainButton.classList.add('visible'); + } else if (scrollPosition <= headerHeight) { + // Скрываем кнопку, если скролл вернулся к верху до высоты хедера + mainButton.classList.remove('visible'); + } + }); +}); + +//lang-switcher +// Выбираем все ссылки языков (для маленьких и больших экранов) +const langLinks = document.querySelectorAll('.lang__link'); +const langSwitcher = document.querySelector('.lang-switcher'); +const currentLangSpan = langSwitcher.querySelector( + '.lang-switcher__current span', +); + +// Объект с переводами для всех языков +const translations = { + en: { + title: + 'The New Start of
VR LOCOMOTION', + description: + 'Discover the most comprehensive VR Locomotion system, and unlock infinite motion in any games on any platforms!', + buyButton: 'Buy Now', + }, + ar: { + title: + 'بداية جديدة لـ
الحركة في الواقع الافتراضي', + description: + 'اكتشف نظام الحركة الأكثر شمولاً في الواقع الافتراضي، واطلق العنان للحركة اللانهائية في أي ألعاب على أي منصة!', + buyButton: 'اشترِ الآن', + }, + 'zh-s': { + title: 'VR运动的
新起点', + description: '发现最全面的VR运动系统,解锁任何平台上任何游戏中的无限运动!', + buyButton: '立即购买', + }, + 'zh-t': { + title: 'VR運動的
新起點', + description: '發現最全面的VR運動系統,解鎖任何平台上任何遊戲中的無限運動!', + buyButton: '立即購買', + }, + fr: { + title: + 'Le nouveau départ de la
locomotion VR', + description: + 'Découvrez le système de locomotion VR le plus complet et débloquez un mouvement infini dans tous les jeux sur toutes les plateformes !', + buyButton: 'Acheter maintenant', + }, + de: { + title: + 'Der Neue Start der
VR-Lokomotion', + description: + 'Entdecken Sie das umfassendste VR-Lokomotionssystem und schalten Sie unendliche Bewegung in allen Spielen auf allen Plattформах frei!', + buyButton: 'Jetzt Kaufen', + }, + it: { + title: + 'Il nuovo inizio della
locomozione VR', + description: + 'Scopri il sistema di locomozione VR più completo e sblocca un movimento infinito in qualsiasi gioco su qualsiasi piattaforma!', + buyButton: 'Acquista ora', + }, + pl: { + title: + 'Nowy początek
lokomocji VR', + description: + 'Odkryj najbardziej wszechstronny system lokomocji VR i odblokuj nieskończony ruch w dowolnych grach na dowolnych platformach!', + buyButton: 'Kup teraz', + }, + ru: { + title: + 'Новый старт
VR-локомоции', + description: + 'Откройте самую полную систему VR-локомоции и разблокируйте бесконечное движение в любых играх на любых платформах!', + buyButton: 'Купить сейчас', + }, + uk: { + title: + 'Новий Початок
VR Локомоції', + description: + 'Відкрийте найповнішу систему VR локомоції та розблокуйте безмежний рух у будь-яких іграх на будь-яких платформах!', + buyButton: 'Купити Зараз', + }, +}; + +// Функция для форматирования текста (первая буква заглавная, остальные строчные) +function formatLanguageDisplay(lang) { + return lang.charAt(0).toUpperCase() + lang.slice(1).toLowerCase(); // Например, "en" → "En", "zh-s" → "Zh-s" +} + +// Функция для установки языка +function setLanguage(lang) { + localStorage.setItem('language', lang); // Сохраняем выбранный язык + currentLangSpan.textContent = formatLanguageDisplay(lang); // Обновляем отображение + + // Обновляем текст на странице + document.querySelector('.header__title').innerHTML = translations[lang].title; // Используем innerHTML вместо textContent + document.querySelector('.header__text').textContent = + translations[lang].description; + document.querySelector('.main-button__link').textContent = + translations[lang].buyButton; + + // Закрываем меню после выбора языка + langSwitcher.classList.remove('is-open'); +} + +// Устанавливаем язык при загрузке страницы +const savedLang = localStorage.getItem('language') || 'en'; +setLanguage(savedLang); + +// Обработчик клика для открытия/закрытия меню +langSwitcher + .querySelector('.lang-switcher__current') + .addEventListener('click', () => { + langSwitcher.classList.toggle('is-open'); + }); + +// langLinks.querySelector('.lang__link').addEventListener('click', () => { +// window.location.href = 'http://localhost:8080/'; +// }); + +// Закрытие меню при клике вне его +document.addEventListener('click', (e) => { + if (!langSwitcher.contains(e.target)) { + langSwitcher.classList.remove('is-open'); + } +}); + +// Обработчик клика по языкам +langLinks.forEach((link) => { + link.addEventListener('click', (e) => { + e.preventDefault(); + const selectedLang = link.getAttribute('data-lang'); + setLanguage(selectedLang); + window.location.href = 'https://inhakr.github.io/layout_KateVR/'; + }); +}); + +//слайдер +document.addEventListener('DOMContentLoaded', () => { + const sliderItems = document.querySelectorAll('.slider__item'); + const prevButton = document.querySelector('.header__bottom-slider-but--prev'); + const currentButton = document.querySelector( + '.header__bottom-slider-but--current', + ); + const nextButton = document.querySelector('.header__bottom-slider-but--next'); + let currentIndex = 0; + let autoSlideInterval; + let lastClickedButton = null; // Переменная для отслеживания последней нажатой кнопки + + function updateSlider() { + // Убираем класс active у всех слайдов и кнопок + sliderItems.forEach((item) => item.classList.remove('active')); + prevButton.classList.remove('active'); + currentButton.classList.remove('active'); + nextButton.classList.remove('active'); + + // Добавляем класс active текущему слайду + sliderItems[currentIndex].classList.add('active'); + + // Если пользователь нажимал на кнопку, подчеркивание остается на ней + if (lastClickedButton) { + lastClickedButton.classList.add('active'); + } else { + // Иначе подчеркивание перемещается по заданному порядку + if (currentIndex === 0) { + currentButton.classList.add('active'); // Первый слайд — подчеркивание на центральной кнопке + } else if (currentIndex === 1) { + nextButton.classList.add('active'); // Второй слайд — подчеркивание на "Next" + } else if (currentIndex === 2) { + prevButton.classList.add('active'); // Третий слайд — подчеркивание на "Previous" + } + } + } + + // Функция для автоматической прокрутки + function startAutoSlide() { + autoSlideInterval = setInterval(() => { + currentIndex = (currentIndex + 1) % sliderItems.length; // Переключаем на следующий слайд + lastClickedButton = null; // Сбрасываем последнюю нажатую кнопку при автопрокрутке + updateSlider(); + }, 2000); // Каждые 2 секунды + } + + // Функция для остановки автоматической прокрутки + function stopAutoSlide() { + clearInterval(autoSlideInterval); + } + + // Функция для перезапуска автоматической прокрутки после паузы + function restartAutoSlide() { + stopAutoSlide(); + startAutoSlide(); + } + + // Обработчик для кнопки "Previous" + prevButton.addEventListener('click', () => { + stopAutoSlide(); + currentIndex = (currentIndex - 1 + sliderItems.length) % sliderItems.length; + lastClickedButton = prevButton; // Сохраняем, что была нажата кнопка "Previous" + updateSlider(); + setTimeout(restartAutoSlide, 5000); // Возобновляем автопрокрутку через 5 секунд + }); + + // Обработчик для кнопки "Next" + nextButton.addEventListener('click', () => { + stopAutoSlide(); + currentIndex = (currentIndex + 1) % sliderItems.length; + lastClickedButton = nextButton; // Сохраняем, что была нажата кнопка "Next" + updateSlider(); + setTimeout(restartAutoSlide, 5000); // Возобновляем автопрокрутку через 5 секунд + }); + + // Инициализация: показываем первый слайд и запускаем автопрокрутку + updateSlider(); + startAutoSlide(); +}); + +//троеточие в секции more +document.addEventListener('DOMContentLoaded', function () { + // Находим все блоки с классом more__block + const blocks = document.querySelectorAll('.section__text'); + + // Проходим по каждому блоку + blocks.forEach((block) => { + // Функция для проверки состояния блока + function updateEllipsis() { + const scrollTop = block.scrollTop; // Текущая позиция скролла + const scrollHeight = block.scrollHeight; // Полная высота содержимого + const clientHeight = block.clientHeight; // Видимая высота блока + + // Условие 1: Если пользователь начал прокрутку (scrollTop > 0) + // Условие 2: Если весь текст виден (scrollHeight <= clientHeight) + if (scrollTop > 0 || scrollHeight <= clientHeight) { + block.classList.add('hide-ellipsis'); + } else { + block.classList.remove('hide-ellipsis'); + } + } + + // Проверяем состояние при загрузке страницы + updateEllipsis(); + + // Проверяем состояние при прокрутке + block.addEventListener('scroll', updateEllipsis); + + // Проверяем состояние при изменении размера окна (например, если текст перераспределился) + window.addEventListener('resize', updateEllipsis); + }); +}); + +//кнопка видео kjlkjklj +let player1, player2; + +// Элементы для первого плеера (#vrVideo) +const playButton1 = document.querySelector( + '.play-button[data-video="vrVideo"]', +); +const closeButton1 = document.querySelector( + '.aside--close-video[data-video="vrVideo"]', +); +const videoFrame1 = document.getElementById('vrVideo'); +const headerVideo = document.querySelector('.header__video'); + +// Элементы для второго плеера (#vrVideo2) +const playButton2 = document.querySelector( + '.about__play-button[data-video="vrVideo2"]', +); +const closeButton2 = document.querySelector( + '.video--close-video[data-video="vrVideo2"]', +); +const videoFrame2 = document.getElementById('vrVideo2'); + +// Функция, которая вызывается, когда API YouTube готов +function onYouTubeIframeAPIReady() { + console.log('YouTube IFrame API ready'); + + // Инициализация первого плеера (#vrVideo) + if (videoFrame1) { + player1 = new YT.Player('vrVideo', { + events: { + onReady: onPlayer1Ready, + onError: function (event) { + console.error('YouTube Player 1 Error:', event.data); + }, + }, + }); + } + + // Инициализация второго плеера (#vrVideo2) + if (videoFrame2) { + player2 = new YT.Player('vrVideo2', { + events: { + onReady: onPlayer2Ready, + onError: function (event) { + console.error('YouTube Player 2 Error:', event.data); + }, + }, + }); + } +} + +// Обработчик готовности первого плеера +function onPlayer1Ready(event) { + console.log('Player 1 is ready'); + if (playButton1 && closeButton1) { + playButton1.addEventListener('click', function () { + console.log('Play button 1 clicked'); + if (player1 && player1.playVideo) { + player1.playVideo(); + playButton1.style.display = 'none'; + videoFrame1.style.display = 'block'; + closeButton1.style.display = 'block'; + headerVideo.classList.add('header__video--active'); + } else { + console.error('Player 1 is not initialized'); + } + }); + + closeButton1.addEventListener('click', function (event) { + event.preventDefault(); + console.log('Close button 1 clicked'); + if (player1 && player1.stopVideo) { + player1.stopVideo(); + playButton1.style.display = 'block'; + videoFrame1.style.display = 'none'; + closeButton1.style.display = 'none'; + headerVideo.classList.remove('header__video--active'); + } else { + console.error('Player 1 is not initialized'); + } + }); + } +} + +// Обработчик готовности второго плеера +function onPlayer2Ready(event) { + console.log('Player 2 is ready'); + if (playButton2 && closeButton2) { + playButton2.addEventListener('click', function () { + console.log('Play button 2 clicked'); + if (player2 && player2.playVideo) { + player2.playVideo(); + playButton2.style.display = 'none'; + videoFrame2.style.display = 'block'; + closeButton2.style.display = 'block'; + } else { + console.error('Player 2 is not initialized'); + } + }); + + closeButton2.addEventListener('click', function (event) { + event.preventDefault(); + console.log('Close button 2 clicked'); + if (player2 && player2.stopVideo) { + player2.stopVideo(); + playButton2.style.display = 'block'; + videoFrame2.style.display = 'none'; + closeButton2.style.display = 'none'; + } else { + console.error('Player 2 is not initialized'); + } + }); + } +} + +// Логика для нового слайдера в секции About +// document.addEventListener('DOMContentLoaded', () => { +// const aboutSlides = document.querySelectorAll('.about__slide'); +// const aboutPrevBtn = document.getElementById('aboutPrevBtn'); +// const aboutNextBtn = document.getElementById('aboutNextBtn'); + +// const aboutNothingvBtn = document.getElementById('aboutNothingvBtn'); + +// const aboutCounter = document.getElementById('aboutCounter'); +// const aboutDots = document.querySelectorAll('.about__slider-dot'); +// let aboutCurrentIndex = 0; +// let aboutAutoSlideInterval; +// let autoSlideStep = 0; // Счётчик шагов для автопрокрутки (определяет, какая кнопка подсвечивается) + +// function updateAboutSlider() { +// // Обновление видимости слайдов +// aboutSlides.forEach((slide, index) => { +// slide.style.display = index === aboutCurrentIndex ? 'block' : 'none'; +// }); + +// // Обновление счётчика +// aboutCounter.textContent = `${aboutCurrentIndex + 1}/${aboutSlides.length}`; + +// // Обновление точек +// aboutDots.forEach((dot, index) => { +// dot.classList.toggle('active', index === aboutCurrentIndex); +// }); + +// // Обновление состояния кнопок +// aboutPrevBtn.disabled = aboutCurrentIndex === 0; +// aboutNextBtn.disabled = aboutCurrentIndex === aboutSlides.length - 1; +// } + +// function startAboutAutoSlide() { +// aboutAutoSlideInterval = setInterval(() => { +// aboutCurrentIndex = (aboutCurrentIndex + 1) % aboutSlides.length; +// updateAboutSlider(); +// }, 2000); +// } + +// function stopAboutAutoSlide() { +// clearInterval(aboutAutoSlideInterval); +// } + +// function restartAboutAutoSlide() { +// stopAboutAutoSlide(); +// setTimeout(startAboutAutoSlide, 5000); +// } + +// // Обработчики событий для кнопок навигации +// aboutPrevBtn.addEventListener('click', () => { +// if (aboutCurrentIndex > 0) { +// aboutCurrentIndex--; +// updateAboutSlider(); +// restartAboutAutoSlide(); +// } +// }); + +// aboutNextBtn.addEventListener('click', () => { +// if (aboutCurrentIndex < aboutSlides.length - 1) { +// aboutCurrentIndex++; +// updateAboutSlider(); +// restartAboutAutoSlide(); +// } +// }); + +// // Обработчики событий для точек +// aboutDots.forEach((dot, index) => { +// dot.addEventListener('click', () => { +// aboutCurrentIndex = index; +// updateAboutSlider(); +// restartAboutAutoSlide(); +// }); +// }); + +// // Инициализация слайдера +// updateAboutSlider(); +// startAboutAutoSlide(); +// }); + +document.addEventListener('DOMContentLoaded', () => { + const aboutSlides = document.querySelectorAll('.about__slide'); + const aboutPrevBtn = document.getElementById('aboutPrevBtn'); + const aboutNextBtn = document.getElementById('aboutNextBtn'); + const aboutNothingvBtn = document.getElementById('aboutNothingvBtn'); + const aboutCounter = document.getElementById('aboutCounter'); + const aboutDots = document.querySelectorAll('.about__slider-dot'); + let aboutCurrentIndex = 0; + let aboutAutoSlideInterval; + let autoSlideStep = 0; // Счётчик шагов для автопрокрутки (определяет, какая кнопка подсвечивается) + + function updateAboutSlider(autoSlide = false) { + // Обновление видимости слайдов + aboutSlides.forEach((slide, index) => { + slide.style.display = index === aboutCurrentIndex ? 'block' : 'none'; + }); + + // Обновление точек + aboutDots.forEach((dot, index) => { + dot.classList.toggle('active', index === aboutCurrentIndex); + }); + + // Обновление счётчика + aboutCounter.textContent = `${aboutCurrentIndex + 1}/${aboutSlides.length}`; + + // Обновление состояния кнопок (disabled) + aboutPrevBtn.disabled = aboutCurrentIndex === 0; + aboutNextBtn.disabled = aboutCurrentIndex === aboutSlides.length - 1; + + // Управление подчеркиванием кнопок + if (autoSlide) { + // При автоматической прокрутке определяем, какую кнопку подсвечивать + const buttons = [aboutPrevBtn, aboutNothingvBtn, aboutNextBtn]; // Порядок кнопок + const currentButtonIndex = autoSlideStep % buttons.length; // Индекс текущей кнопки (0, 1, 2) + + // Убираем подсветку со всех кнопок + buttons.forEach((button) => button.classList.remove('active')); + + // Подсвечиваем текущую кнопку + buttons[currentButtonIndex].classList.add('active'); + + // Увеличиваем шаг автопрокрутки + autoSlideStep++; + } + } + + function startAboutAutoSlide() { + aboutAutoSlideInterval = setInterval(() => { + aboutCurrentIndex = (aboutCurrentIndex + 1) % aboutSlides.length; + updateAboutSlider(true); // Передаём true, чтобы указать, что это автопрокрутка + }, 2000); + } + + function stopAboutAutoSlide() { + clearInterval(aboutAutoSlideInterval); + } + + function restartAboutAutoSlide() { + stopAboutAutoSlide(); + autoSlideStep = 0; // Сбрасываем шаг автопрокрутки + setTimeout(startAboutAutoSlide, 5000); + } + + // Обработчики событий для кнопок навигации + aboutPrevBtn.addEventListener('click', () => { + if (aboutCurrentIndex > 0) { + aboutCurrentIndex--; + updateAboutSlider(); // Ручное переключение (не автопрокрутка) + restartAboutAutoSlide(); + + // Подсвечиваем Previous, убираем подсветку с остальных + aboutPrevBtn.classList.add('active'); + aboutNextBtn.classList.remove('active'); + aboutNothingvBtn.classList.remove('active'); + } + }); + + aboutNextBtn.addEventListener('click', () => { + if (aboutCurrentIndex < aboutSlides.length - 1) { + aboutCurrentIndex++; + updateAboutSlider(); // Ручное переключение (не автопрокрутка) + restartAboutAutoSlide(); + + // Подсвечиваем Next, убираем подсветку с остальных + aboutNextBtn.classList.add('active'); + aboutPrevBtn.classList.remove('active'); + aboutNothingvBtn.classList.remove('active'); + } + }); + + aboutNothingvBtn.addEventListener('click', () => { + // При клике на aboutNothingvBtn подсвечиваем её, убираем подсветку с остальных + updateAboutSlider(); // Ручное переключение (не автопрокрутка) + restartAboutAutoSlide(); + + aboutNothingvBtn.classList.add('active'); + aboutPrevBtn.classList.remove('active'); + aboutNextBtn.classList.remove('active'); + }); + + // Инициализация слайдера + updateAboutSlider(); + startAboutAutoSlide(); +}); + +//tech +// document.addEventListener('DOMContentLoaded', () => { +// const section = document.querySelector('.tech-specs'); +// const lines = document.querySelectorAll('.tech-specs__line'); +// const contents = document.querySelectorAll('.tech-specs__content'); + +// const observer = new IntersectionObserver( +// (entries) => { +// entries.forEach((entry) => { +// if (entry.isIntersecting) { +// lines.forEach((line) => (line.style.animationPlayState = 'running')); +// contents.forEach( +// (content) => (content.style.animationPlayState = 'running'), +// ); +// observer.unobserve(section); +// } +// }); +// }, +// { threshold: 0.5 }, +// ); + +// observer.observe(section); +// }); + +function updateSVG() { + const svg = document.querySelector('.tech-specs__line--batteries'); + // const svgConnect = document.querySelector('.tech-specs__line--connection'); + + const path = document.querySelector('.line-path'); + const pathConnect = document.querySelector('.path-connect'); + + // const startCircle = document.querySelector('.start-circle'); + + const endCircle = document.querySelector('.end-circle'); + const endCircleConnect = document.querySelector('.end-circle-connect'); + + const width = window.innerWidth; + + if (width >= 1920) { + // Для 1920px + svg.setAttribute('width', '750'); + // svg.setAttribute('height', '525'); + // svg.setAttribute('viewBox', '-300 0 600 450'); + path.setAttribute('d', 'M7.5,15 V215 H-285'); + pathConnect.setAttribute('d', 'M0,10 H100 V-70 H180'); + + // startCircle.setAttribute('cx', '8'); + // startCircle.setAttribute('cy', '12'); + // startCircle.setAttribute('r', '4.5'); + endCircle.setAttribute('cx', '-280'); + endCircleConnect.setAttribute('cx', '180'); + // endCircle.setAttribute('cy', '322.5'); + // endCircle.setAttribute('r', '4.5'); + } else { + // Для 1280px (или других разрешений) + // svg.setAttribute('width', '750'); + // svg.setAttribute('height', '350'); + // svg.setAttribute('viewBox', '-200 0 400 300'); + path.setAttribute('d', 'M5,10 V215 H-185'); + pathConnect.setAttribute('d', 'M0,10 H40 V-70 H95'); + // startCircle.setAttribute('r', '3'); + endCircle.setAttribute('cx', '-180'); + endCircleConnect.setAttribute('cx', '95'); + // endCircle.setAttribute('cy', '215'); + // endCircle.setAttribute('r', '3'); + } +} + +// Выполнять при загрузке страницы и изменении размера окна +window.addEventListener('resize', updateSVG); +window.addEventListener('load', updateSVG); +// startCircle.setAttribute('cx', '5'); +// startCircle.setAttribute('cy', '10'); + +// форма contact + +document.addEventListener('DOMContentLoaded', () => { + // Находим форму внутри section.contact + const form = document.querySelector('section.contact .contact-form'); + const emailInput = document.querySelector('section.contact #email'); + const nameInput = document.querySelector('section.contact #name'); + const phoneInput = document.querySelector('section.contact #phone'); + + // Проверяем, найдены ли элементы + if (!form) { + console.error( + 'Форма с классом .contact-form не найдена внутри section.contact!', + ); + return; + } + if (!emailInput) { + console.error('Поле email с id="email" не найдено внутри section.contact!'); + return; + } + if (!nameInput) { + console.error('Поле name с id="name" не найдено внутри section.contact!'); + return; + } + if (!phoneInput) { + console.error('Поле phone с id="phone" не найдено внутри section.contact!'); + return; + } else { + console.log('Элементы формы найдены корректно'); + } + + // Регулярное выражение для проверки email + const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; + + // Регулярное выражение для проверки телефона (+ и ровно 12 цифр) + const phoneRegex = /^\+[0-9]{12}$/; + + // Функция для проверки формата email + const validateEmail = (email) => emailRegex.test(email); + + // Функция для проверки формата телефона + const validatePhone = (phone) => phoneRegex.test(phone); + + // Функция для проверки заполненности имени + const validateName = (name) => name.trim().length > 0; + + // Функция для переключения состояния ошибки + const toggleError = (input, hasError) => { + const contactGroup = input.closest('.contact-group'); + if (!contactGroup) { + console.error('Контейнер .contact-group не найден для поля:', input); + return; + } + if (hasError) { + console.log('Добавляем класс contact-group--error для поля:', input); + contactGroup.classList.add('contact-group--error'); + } else { + console.log('Убираем класс contact-group--error для поля:', input); + contactGroup.classList.remove('contact-group--error'); + } + }; + + // Валидация имени при потере фокуса + nameInput.addEventListener('blur', () => { + const isValidName = validateName(nameInput.value); + console.log('Name:', nameInput.value, 'Валиден:', isValidName); + toggleError(nameInput, !isValidName); + }); + + // Валидация email при потере фокуса + emailInput.addEventListener('blur', () => { + const isValidEmail = validateEmail(emailInput.value); + console.log('Email:', emailInput.value, 'Валиден:', isValidEmail); + toggleError(emailInput, !isValidEmail); + }); + + // Ограничение ввода для телефона в реальном времени (без валидации) + phoneInput.addEventListener('input', (e) => { + let value = phoneInput.value; + + // Удаляем все, кроме символа + и цифр + value = value.replace(/[^0-9+]/g, ''); + + // Если символ + уже есть, не даем добавить еще один + if (value.indexOf('+') !== 0) { + value = '+' + value.replace(/\+/g, ''); + } else { + value = value.replace(/\+/g, (match, index) => (index === 0 ? '+' : '')); + } + + // Ограничиваем ввод: максимум 13 символов (+ и 12 цифр) + if (value.length > 13) { + value = value.slice(0, 13); + } + + // Устанавливаем новое значение поля + phoneInput.value = value; + }); + + // Валидация телефона при потере фокуса + phoneInput.addEventListener('blur', () => { + const isValidPhone = validatePhone(phoneInput.value); + console.log('Phone:', phoneInput.value, 'Валиден:', isValidPhone); + toggleError(phoneInput, !isValidPhone); + }); + + // Валидация при отправке формы + form.addEventListener('submit', (e) => { + e.preventDefault(); // Предотвращаем отправку формы + + let hasError = false; + + // Проверка имени + const isValidName = validateName(nameInput.value); + if (!isValidName) { + toggleError(nameInput, true); + hasError = true; + } else { + toggleError(nameInput, false); + } + + // Проверка email + const isValidEmail = validateEmail(emailInput.value); + if (!isValidEmail) { + toggleError(emailInput, true); + hasError = true; + } else { + toggleError(emailInput, false); + } + + // Проверка телефона + const isValidPhone = validatePhone(phoneInput.value); + if (!isValidPhone) { + toggleError(phoneInput, true); + hasError = true; + } else { + toggleError(phoneInput, false); + } + + if (!hasError) { + console.log('Форма валидна, готова к отправке!'); + console.log('Форма отправлена'); + form.reset(); + } + }); +}); + +//кнопка back-to-up +document.addEventListener('DOMContentLoaded', () => { + const backToTopButton = document.querySelector('.back-to-top'); + const header = document.querySelector('#header'); + + if (!backToTopButton) { + console.error('Кнопка back-to-top не найдена!'); + return; + } + if (!header) { + console.error('Хедер с id="header" не найден!'); + return; + } else { + console.log('Элементы back-to-top and header найдены корректно'); + } + + // Показ/скрытие кнопки при прокрутке + window.addEventListener('scroll', () => { + const headerHeight = header.offsetHeight; // Высота хедера + const scrollPosition = window.scrollY; // Текущая позиция прокрутки + + if (scrollPosition > headerHeight) { + backToTopButton.classList.add('visible'); // Показываем кнопку + } else { + backToTopButton.classList.remove('visible'); // Скрываем кнопку + } + }); + + // Обработчик для кнопки "Вернуться наверх" + backToTopButton.addEventListener('click', () => { + header.scrollIntoView({ behavior: 'smooth' }); // Плавная прокрутка к хедеру + }); +}); + +footerLinks.forEach((link) => { + link.addEventListener('click', (e) => { + e.preventDefault(); + const targetId = link.getAttribute('href'); + console.log('Target ID:', targetId); // Должно вывести "#tech" + const targetElement = document.querySelector(targetId); + console.log('Target Element:', targetElement); // Должно вывести элемент
+ + if (targetElement) { + targetElement.scrollIntoView({ behavior: 'smooth' }); + } else { + console.error(`Элемент с ID ${targetId} не найден!`); + } + }); +}); diff --git a/src/styles/_fonts.scss b/src/styles/_fonts.scss deleted file mode 100644 index 619b8c52..00000000 --- a/src/styles/_fonts.scss +++ /dev/null @@ -1,6 +0,0 @@ -@font-face { - font-family: Roboto, Arial, Helvetica, sans-serif; - src: url('../fonts/FontFont_FF.Mark.Pro.otf') format('otf'); - font-weight: normal; - font-style: normal; -} diff --git a/src/styles/_typography.scss b/src/styles/_typography.scss deleted file mode 100644 index 1837eb46..00000000 --- a/src/styles/_typography.scss +++ /dev/null @@ -1,3 +0,0 @@ -h1 { - @extend %h1; -} diff --git a/src/styles/_utils.scss b/src/styles/_utils.scss deleted file mode 100644 index 3280c3fe..00000000 --- a/src/styles/_utils.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import 'utils/vars'; -@import 'utils/mixins'; -@import 'utils/extends'; diff --git a/src/styles/about.scss b/src/styles/about.scss new file mode 100644 index 00000000..67c6e648 --- /dev/null +++ b/src/styles/about.scss @@ -0,0 +1,432 @@ +.about { + background: linear-gradient(to bottom, #191536, #000); + padding-block: 48px; + + &__top { + margin-bottom: 5px; + + &-text { + margin-bottom: 187px; + + @include on-tablet { + grid-column: 4 / 4; + grid-row: 1; + padding-top: 55px; + width: 340px; + } + + @include on-desktoplittle { + width: 332px; + grid-column: 6; + padding-top: 75px; + margin-right: 5px; + margin-bottom: 50px; + } + + @include on-desktopmiddle { + width: 435px; + padding-top: 100px; + } + } + + @include on-tablet { + display: flex; + justify-content: center; + margin-bottom: 10px; + } + + @include on-desktoplittle { + justify-content: end; + margin-bottom: 85px; + } + + @include on-desktopmiddle { + margin-bottom: 75px; + } + } + + &__img { + width: 280px; + height: 190px; + margin-bottom: 38px; + + @include on-tablet { + grid-column: span 3; + grid-row: 1; + width: 340px; + height: 270px; + } + + @include on-desktoplittle { + grid-column: 3; + width: 430px; + height: 290px; + margin-right: 55px; + margin-bottom: 10px; + } + + @include on-desktopmiddle { + width: 622px; + margin-bottom: 15px; + margin-top: 10px; + } + } + + &__video { + // position: relative; + width: 100%; + max-width: 768px; /* Пример ширины */ + margin: 0 auto; + } + + .video--close-video { + display: none; /* Изначально скрываем кнопку закрытия */ + position: absolute; + top: 50px; + right: 5px; + width: 15px; + height: 15px; + background: url('../icons/menu-close.svg') no-repeat center; + background-size: contain; + text-decoration: none; + + &:hover { + background-image: url(../icons/menu-closeBlue.svg); + } + + @include on-tablet { + top: -15px; + } + + @include on-desktoplittle { + top: -20px; + right: 0; + } + + @include on-desktopmiddle { + width: 30px; + height: 30px; + top: 10px; + right: -30px; + } + } + + &__video-iframe { + display: none; /* Изначально скрываем iframe */ + width: 100%; + height: 550px; /* Соотношение 16:9 для ширины 768px */ + position: absolute; + bottom: 12px; + + @include on-tablet { + height: 400px; + } + + @include on-desktoplittle { + height: 500px; + width: 115%; + bottom: -140px; + left: -130px; + } + } + + &__play-button { + position: absolute; + + // transform: translate(-30px, -160px); + + background: none; + border: none; + cursor: pointer; + + /* На мобильных (ширина < 768px) */ + bottom: 65px; /* Отступ снизу от текста */ + left: 40%; + transform: translateX(-50%); /* Центрируем по горизонтали */ + + &:hover { + background-color: transparent; + transform: scale(1.05) translate(-28%, 78%); + transition: + transform 0.5s ease, + color 0.5s ease; + } + + @include on-tablet { + width: 280px; + + /* На планшетах и шире (≥768px) */ + bottom: 105px; /* Тот же отступ снизу */ + left: calc( + 50% + 170px + ); /* Смещаем на половину ширины текста (340px / 2 = 170px) */ + + transform: translateX(-70%); /* Центрируем */ + } + + @include on-desktoplittle { + transform: translate(-28%, 78%); + } + + @include on-desktopmiddle { + transform: translate(-7%, 80%); + } + } + + &__video-iframe[style*='display: block'] + .video--close-video { + display: block; + } + + &__slider { + position: relative; + + &-title { + margin-bottom: 25px; + + @include on-tablet { + grid-column: 4 / 4; + grid-row: 1; + } + + @include on-desktoplittle { + grid-column: 6; + } + } + + &-controls { + display: none; + justify-content: space-between; + align-items: center; + + @include on-desktoplittle { + display: inline-block; + margin-left: 40px; + } + } + + &-dots { + position: absolute; + left: 118px; + top: 247px; + display: flex; + gap: 5px; + + @include on-tablet { + left: 150px; + top: 280px; + } + + @include on-desktoplittle { + display: none; + } + } + + &-dot { + width: 5px; + height: 5px; + background-color: #666; + border-radius: 50%; + cursor: pointer; + transition: background-color 0.3s; + + &.active { + background-color: #00d4ff; + } + } + + &-counter { + @include on-desktoplittle { + position: absolute; + font-size: 14px; + top: -10px; + left: -10px; + } + + @include on-desktopmiddle { + top: 5px; + left: 5px; + } + } + + &-nav { + @include on-desktoplittle { + width: 207px; + display: flex; + justify-content: space-between; + } + } + + @include on-desktoplittle { + margin-bottom: 145px; + } + } + + &__slide { + &-wrapper { + position: relative; + display: grid; + + @include on-tablet { + display: grid; + grid-template-columns: repeat (6, 1fr); + grid-template-rows: auto auto; + + // column-gap: 20px; + // row-gap: 20px; + + gap: 20px; + } + + @include on-desktoplittle { + row-gap: 0; + } + } + } + + &__bottom { + position: relative; + + &-title { + margin-bottom: 22px; + + @include on-tablet { + margin-bottom: 35px; + } + } + + &-pretitle { + display: block; + margin-bottom: 15px; + font-size: 14px; + line-height: 100%; + color: $main-title-color-accent; + + @include on-tablet { + margin-bottom: 12px; + } + + @include on-desktoplittle { + margin-bottom: 17px; + } + + @include on-desktopmiddle { + margin-bottom: 20px; + } + } + + &-text { + @include on-tablet { + width: 460px; + margin-bottom: 15px; + } + + @include on-desktopmiddle { + width: 532px; + } + } + + &-right { + display: none; + + @include on-tablet { + display: flex; /* Для центрирования текста */ + justify-content: center; + align-items: end; + position: absolute; + top: -10px; + + transform: rotate(-270deg) translateY(-195%); + transform-origin: center; + width: 257px; /* Ширина блока (до поворота) */ + height: 232px; /* Высота блока (до поворота) */ + color: #fff; + font-size: 48px; + font-weight: 900; + line-height: 130%; + text-transform: uppercase; + opacity: 1; + -webkit-text-stroke: 1px #00d4ff; + -webkit-text-fill-color: transparent; + + &::before { + content: 'ABOUT US'; + position: absolute; + width: 100%; + top: 25%; + left: -3%; + transform: rotate(180deg) translateY(-35%); + font-size: 48px; + font-weight: 900; + text-transform: uppercase; + -webkit-text-stroke: 1px #00d4ff; + -webkit-text-fill-color: transparent; + opacity: 0.4; + + @include on-desktoplittle { + width: 337px; + font-size: 64px; + top: 7%; + left: -2%; + } + } + + /* Вторая тень */ + &::after { + content: 'ABOUT US'; + position: absolute; + top: -13%; + left: 2%; + transform: rotate(0deg) translateY(50%); + font-size: 48px; + font-weight: 900; + text-transform: uppercase; + -webkit-text-stroke: 1px #00d4ff; + -webkit-text-fill-color: transparent; + opacity: 0.2; + + @include on-desktoplittle { + width: 337px; + font-size: 64px; + top: -40%; + } + } + } + + @include on-desktoplittle { + width: 337px; + font-size: 64px; + top: 10px; + transform: rotate(-270deg) translateY(-210%); + } + + @include on-desktopmiddle { + transform: rotate(-270deg) translateY(-250%); + } + } + + @include on-tablet { + width: 460px; + display: flex; + } + + &-slider-but { + padding: 0 0 10px; + } + + @include on-desktopmiddle { + padding-left: 100px; + } + } + + @include on-tablet { + padding-block: 70px; + } + + @include on-desktoplittle { + padding-block: 85px; + } + + @include on-desktopmiddle { + padding-top: 133px; + } +} diff --git a/src/styles/aside-complete.scss b/src/styles/aside-complete.scss new file mode 100644 index 00000000..c6f57b5b --- /dev/null +++ b/src/styles/aside-complete.scss @@ -0,0 +1,71 @@ +.buy__complete { + &-content { + grid-template-columns: repeat(2, 1fr); + column-gap: 20px; + display: grid; + margin: 0 10px 20px 0; + text-align: center; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + } + + @include on-desktopmiddle { + margin: 100px 10px 20px 0; + } + } + + &-title { + grid-column: span 2; + margin: 60px 0 16px; + font-size: 26px; + text-transform: uppercase; + + &--accent { + font-weight: 400; + color: $main-title-color-accent; + } + + @include on-tablet { + grid-column: span 6; + font-size: 46px; + margin: 140px 0 16px; + } + + @include on-desktoplittle { + margin: 140px 0 40px; + } + @include on-desktopmiddle { + margin-bottom: 50px; + } + } + + &-text { + grid-column: span 2; + margin-bottom: 20px; + line-height: 130%; + color: $main-title-color; + + @include on-tablet { + grid-column: span 6; + font-size: 18px; + } + } +} + +.button__complete { + grid-column: span 2; + + @include on-tablet { + grid-column: 2/-2; + } + + @include on-desktoplittle { + justify-self: center; + width: 218px; + } + + @include on-desktopmiddle { + margin-top: 50px; + } +} diff --git a/src/styles/aside.scss b/src/styles/aside.scss new file mode 100644 index 00000000..b098c12f --- /dev/null +++ b/src/styles/aside.scss @@ -0,0 +1,106 @@ +.aside { + position: fixed; + left: 0; + transform-origin: left center; /* Точка вращения — левый край */ + transform: perspective(1000px) rotateY(-90deg); /* Начальное состояние: "закрыто" */ + opacity: 0; + pointer-events: none; + transition: + transform 0.5s ease-in-out, + opacity 0.5s ease-in-out; /* Плавный переход */ + + z-index: 1000; + top: 0; + background-color: #191536; + width: 100%; + height: 100%; + overflow-y: auto; + + &:target, + &.aside--open { + opacity: 1; + transform: perspective(1000px) rotateY(0deg); /* "Открывается" как страница */ + // transform: translateX(0%); + pointer-events: all; + } + + &--close { + grid-column: 2 / -1; + justify-self: end; + background-image: url(../icons/menu-close.svg); + width: 17px; + height: 17px; + margin-top: 20px; + + &-video { + position: absolute; + top: 10px; + right: 10px; + display: none; + background-image: url(../icons/menu-close.svg); + width: 17px; + height: 17px; + + @include on-desktoplittle { + width: 20px; + height: 20px; + top: 15px; + right: 15px; + } + + &:hover { + background-image: url(../icons/menu-closeBlue.svg); + } + } + + &:hover { + background-image: url(../icons/menu-closeBlue.svg); + } + + @include on-tablet { + margin: 35px 0 20px; + } + } + + &__title { + font-weight: 900; + font-size: 21px; + line-height: 130%; + color: $main-title-color; + } + + &__title--accent { + font-weight: 500; + color: $main-title-color-accent; + } + + &__text { + grid-column: span 2; + + @include on-tablet { + grid-column: span 6; + } + + @include on-desktoplittle { + grid-column: 2/-1; + } + } + + &-help { + @include on-desktoplittle { + margin: 15px 25px 25px 0; + } + @include on-desktopmiddle { + margin: 30px 24px 25px 0; + } + } + + &-faq { + @include on-desktoplittle { + margin: 15px 15px 0 0; + } + @include on-desktopmiddle { + margin: 20px 25px 0 0; + } + } +} diff --git a/src/styles/back-to-up.scss b/src/styles/back-to-up.scss new file mode 100644 index 00000000..3e8e0f56 --- /dev/null +++ b/src/styles/back-to-up.scss @@ -0,0 +1,80 @@ +.back-to-top { + display: none; + + &.visible { + opacity: 1; + visibility: visible; + } + + &::before, + &::after { + content: ''; + position: absolute; + background-color: #00c4cc; /* Синяя стрелка по умолчанию */ + transition: background-color 0.3s ease; /* Плавное изменение цвета */ + } + + &::before { + width: 1px; /* Толщина линии стрелки */ + height: 12px; /* Длина линии */ + transform: rotate(45deg); /* Поворот для левой части стрелки */ + top: 16px; /* Позиционирование */ + left: 20px; /* Позиционирование */ + } + + &::after { + width: 1px; /* Толщина линии стрелки */ + height: 12px; /* Длина линии */ + transform: rotate(-45deg); /* Поворот для правой части стрелки */ + top: 16px; /* Позиционирование */ + left: 27px; /* Позиционирование */ + } + + /* При наведении на кнопку */ + &:hover { + background-color: #00c4cc; /* Синий фон */ + border-color: #00c4cc; /* Синяя окантовка */ + } + + /* При наведении стрелка становится белой */ + &:hover::before, + &:hover::after { + background-color: white; /* Белая стрелка */ + } + + @include on-tablet { + position: fixed; /* Фиксированная позиция */ + bottom: 240px; + right: 35px; + width: 50px; /* Размер кнопки */ + height: 50px; /* Размер кнопки */ + background-color: transparent; + border: 2px solid #00c4cc; /* Синяя окантовка */ + border-radius: 50%; /* Круглая форма */ + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + opacity: 0; /* Скрыта по умолчанию */ + visibility: hidden; /* Скрыта по умолчанию */ + transition: + background-color 0.3s ease, + border-color 0.3s ease, + opacity 0.3s ease, + visibility 0.3s ease; /* Плавное изменение */ + } + + @include on-desktoplittle { + bottom: 225px; + right: 110px; + } + + @include on-desktopmiddle { + bottom: 330px; + right: 235px; + } +} + +/* Показываем кнопку при прокрутке */ + +/* Стрелка вверх, нарисованная с помощью псевдоэлементов */ diff --git a/src/styles/benefits.scss b/src/styles/benefits.scss new file mode 100644 index 00000000..58051539 --- /dev/null +++ b/src/styles/benefits.scss @@ -0,0 +1,153 @@ +.benefits { + padding-block: 20px; + + &__title { + margin-bottom: 35px; + + @include on-tablet { + margin-bottom: 140px; + } + + @include on-desktoplittle { + text-align: center; + margin-bottom: 203px; + } + } + + &__wrapper { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 22px 20px; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + text-align: center; + } + + @include on-desktoplittle { + grid-template-columns: repeat(12, 1fr); + } + + @include on-desktopmiddle { + grid-template-columns: repeat(16, 1fr); + } + } + + &__block { + position: relative; + grid-column: span 2; + + @include on-tablet { + width: 222px; + } + + @include on-desktoplittle { + grid-column: span 4; + width: 340px; + } + + &::before { + @include on-tablet { + content: url(../icons/benefits-flow.svg); + width: 106px; + height: 81px; + display: block; + position: absolute; + top: 95%; + left: 48%; + transform: translate(-50%, -280%); + } + + @include on-desktoplittle { + top: 85%; + left: 50%; + } + } + + &-control { + @include on-desktopmiddle { + grid-column: 7/-6; + } + } + + &-sensors { + @include on-desktopmiddle { + grid-column: 13/-1; + } + } + + &-control::before { + @include on-tablet { + content: url('../icons/benefits-vr.svg'); + } + } + + &-sensors::before { + @include on-tablet { + content: url('../icons/benefits-sound.svg'); + } + } + } + + &__subtitle { + font-size: 16px; + margin-bottom: 15px; + + @include on-tablet { + margin-bottom: 35px; + } + + @include on-desktoplittle { + margin-bottom: 20px; + } + } + + &__text { + position: relative; + overflow-y: auto; + max-height: 75px; + + &::after { + content: '...'; + position: absolute; + width: 100px; + bottom: 0; + color: #fff; + font-size: 14px; + background: #05040b; + padding: 0 5px; + + @include on-tablet { + display: block; + padding: 0 3px; + width: 18px; + } + + @include on-desktoplittle { + display: none; + } + } + + @include on-tablet { + font-size: 17px; + text-align: center; + } + + @include on-desktoplittle { + max-height: 108px; + } + } + + @include on-tablet { + padding-block: 75px; + } + + @include on-desktoplittle { + margin-bottom: 165px; + } + + @include on-desktopmiddle { + padding-block: 100px; + margin-bottom: 75px; + } +} diff --git a/src/styles/buttons.scss b/src/styles/buttons.scss new file mode 100644 index 00000000..1e008e02 --- /dev/null +++ b/src/styles/buttons.scss @@ -0,0 +1,140 @@ +button { + width: 100%; + padding: 10px; + background-color: #05c2df; + border: none; + border-radius: 5px; + color: $main-title-color; + font-size: 16px; + cursor: pointer; + transition: background-color 0.3s; + + &:hover { + color: #05c2df; + background-color: $main-title-color; + } +} + +.buy__button { + font-weight: 500; + font-size: 14px; + line-height: 130%; + margin: 20px 0 37px; + + &-pay { + margin: 0; + } + &-pay:disabled { + cursor: not-allowed; + } + + @include on-tablet { + grid-column: 2/-2; + justify-self: center; + padding: 15px; + margin: 35px 0 37px; + font-size: 16px; + } + + @include on-desktoplittle { + width: 200px; + justify-self: start; + margin: 32px 0 0; + } + + @include on-desktopmiddle { + grid-column: 1 / -5; + justify-self: start; + width: 200px; + margin: 60px 0; + } +} + +.play-button { + font-weight: 500; + font-size: 16px; + padding: 15px 0 0; + background-color: $background-color; + border: 2px solid transparent; + cursor: pointer; + transition: + transform 0.5s ease, + opacity 0.2s ease; + + &:active { + transform: scale(0.95); + } + + @include hover(transform, scale(1.05)); + + &:hover { + background-color: $background-color; + } + + @include on-tablet { + padding: 22px 0 0; + } + + @include on-desktoplittle { + padding-left: 60px; + } + + @include on-desktopmiddle { + padding-top: 40px; + padding-left: 50px; + } +} + +.main-button { + position: fixed; + border-radius: 5px; + background-color: $main-title-color-accent; + width: 280px; + height: 40px; + text-align: center; + bottom: 20px; + left: 50%; + transform: translateX(-50%); + opacity: 0; + visibility: hidden; /* Убираем из потока */ + transition: opacity 0.3s ease; /* Плавное появление */ + z-index: 1; + + &__link { + display: block; + width: 100%; + font-weight: 500; + font-size: 14px; + line-height: 130%; + padding: 10px; + color: #fff; + + &:hover { + color: #05c2df; + background-color: $main-title-color; + } + + @include on-desktoplittle { + font-size: 16px; + padding: 13px; + } + } + + @include on-desktoplittle { + position: absolute; + top: 45px; + left: 84%; + opacity: 1; + visibility: visible; + width: 200px; + height: 48px; + } + @include on-desktopmiddle { + left: 83%; + } +} + +.main-button.visible { + opacity: 1; + visibility: visible; +} diff --git a/src/styles/buy-form.scss b/src/styles/buy-form.scss new file mode 100644 index 00000000..b46f9f14 --- /dev/null +++ b/src/styles/buy-form.scss @@ -0,0 +1,248 @@ +.buy { + &__wrapper-box { + @include on-desktoplittle { + margin-top: 10%; + padding-inline: 110px; + display: grid; + grid-template-columns: repeat(12, 1fr); + column-gap: 20px; + } + + @include on-desktopmiddle { + margin-top: 11%; + } + } + + &__img { + display: none; + text-align: center; + + @include on-tablet { + display: block; + } + + &-picture { + width: 524px; + height: 277px; + + @include on-desktoplittle { + margin-left: -15%; + } + + @include on-desktopmiddle { + margin-left: -11%; + width: 860px; + height: 445px; + } + } + + &-pay { + @include on-desktoplittle { + top: 30%; + left: 19%; + position: absolute; + } + + @include on-desktopmiddle { + top: 27%; + left: 14%; + } + } + } + + &__input { + width: 100%; + padding-bottom: 19px; + border: none; + border-bottom: 1px solid #2f2f2f; + color: #fff; + font-size: 18px; + line-height: 130%; + letter-spacing: 20%; + background-color: $background-color; + + &::placeholder { + color: #929292; + font-size: 14px; + line-height: 130%; + } + + &:hover { + border-bottom: 1px solid $main-title-color-accent; + + &::placeholder { + font-size: 16px; // Увеличиваем шрифт placeholder при наведении на input + } + } + + &:focus { + outline: none; /* Убираем стандартную оранжевую рамку */ + border-bottom: 1px solid $main-title-color-accent; + background-color: $background-color; + } + + // &:not(:placeholder-shown) { + // border-bottom: 1px solid #00c4cc; /* Синяя нижняя граница, когда поле заполнено */ + // &:hover { + // border-bottom: 1px solid #2f2f2f; + // } + // } + } + + &__select { + width: 100%; + height: 100%; + padding: 25px 0 15px 24px; + background-color: $background-color !important; + color: #fff !important; + border: none; + border-bottom: 1px solid #2f2f2f; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + transition: background-color 0.3s ease; + position: relative; + background-image: url('data:image/svg+xml;utf8,'); + background-repeat: no-repeat; + background-position: right 10px center; + + &:hover { + border-bottom: 1px solid $main-title-color-accent; + } + + &:focus-visible { + outline: none; + border-bottom: 1px solid $main-title-color-accent; + background-color: #191536 !important; + } + + &:-webkit-autofill { + background-color: $background-color !important; + -webkit-box-shadow: 0 0 0 30px $background-color inset !important; + color: #fff !important; + -webkit-text-fill-color: #fff !important; + } + + // Синее подчёркивание, когда поле заполнено + + &:valid { + border-bottom: 1px solid #2f2f2f; // Синяя нижняя граница + &:hover { + border-bottom: 1px solid $main-title-color-accent; + } + } + + &:-webkit-autofill:hover, + &:-webkit-autofill:focus, + &:-webkit-autofill:active { + background-color: $background-color !important; + -webkit-box-shadow: 0 0 0 30px $background-color inset !important; + color: #fff !important; + -webkit-text-fill-color: #fff !important; + } + + option { + background-color: $background-color; + color: #fff; + } + + @include on-desktoplittle { + width: 250px; + height: 47px; + margin-top: 13px; + margin-bottom: 10px; + padding: 15px 0 15px 15px; + } + + @include on-desktopmiddle { + width: 100%; + padding: 0 0 0 15px; + margin-top: 13px; + margin-bottom: 5px; + } + } + + &__order-form { + @include on-tablet { + display: grid; + column-gap: 20px; + grid-template-columns: repeat(6, 1fr); + } + + @include on-desktoplittle { + grid-template-columns: repeat(12, 1fr); + position: absolute; + width: 520px; + right: 12%; + top: 26%; + } + + @include on-desktopmiddle { + grid-template-columns: repeat(8, 1fr); + width: 716px; + top: 32%; + right: 12%; + } + } +} + +.form-group { + margin-bottom: 22px; + + label { + font-size: 14px; + line-height: 130%; + } + + &:hover { + label { + font-size: 16px; // Увеличиваем шрифт label при наведении на form-group + } + } + + @include on-tablet { + grid-column: span 3; + margin-bottom: 30px; + } + + @include on-desktoplittle { + margin-bottom: 33px; + } + + @include on-desktopmiddle { + grid-column: 5/-1; + } + + &:nth-child(2n + 1) { + @include on-desktoplittle { + grid-column: 2/-6; + } + + @include on-desktopmiddle { + grid-column: span 4; + } + } +} + +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +input:-webkit-autofill:active { + width: 100%; + padding-bottom: 19px; + border: none; + border-bottom: 1px solid #2f2f2f; + color: #fff; + font-size: 18px; + line-height: 130%; + letter-spacing: 20%; + box-shadow: 0 0 0 1000px #000 inset; + -webkit-text-fill-color: #fff !important; + -webkit-box-shadow: 0 0 0 30px $background-color inset !important; + background-color: $background-color !important; + transition: background-color 0.3s ease; +} + +input:-webkit-autofill:hover { + border-bottom: 1px solid $main-title-color-accent; +} diff --git a/src/styles/contact.scss b/src/styles/contact.scss new file mode 100644 index 00000000..831b7a10 --- /dev/null +++ b/src/styles/contact.scss @@ -0,0 +1,238 @@ +.contact { + // position: relative; + padding-top: 82px; + margin-bottom: 92px; + + &__uptitle { + font-size: 14px; + line-height: 100%; + margin-bottom: 15px; + color: $main-title-color-accent; + } + + &__title { + margin-bottom: 35px; + + @include on-tablet { + margin-bottom: 50px; + } + + @include on-desktoplittle { + margin-bottom: 35px; + } + } + + @include on-tablet { + padding-top: 70px; + margin-bottom: 245px; + } + + @include on-desktoplittle { + padding-top: 105px; + margin-bottom: 270px; + } + + @include on-desktopmiddle { + padding-top: 155px; + } + + @include on-desktopmiddle { + margin-bottom: 335px; + } +} + +.contact-container { + // max-width: 280px; + // width: 100%; + + margin-bottom: 25px; + + @include on-tablet { + position: absolute; + transform: translate(106%, -27%); + width: 340px; + } + + @include on-desktoplittle { + transform: translate(160%, -25%); + } + + @include on-desktopmiddle { + transform: translate(220%, -30%); + } +} + +/* Стили для формы */ +.contact-form { + display: flex; + flex-direction: column; + gap: 20px; +} + +/* Стили для группы полей */ +.contact-group { + position: relative; + display: flex; + flex-direction: column; + margin-bottom: 4px; +} + +.contact-group input { + height: 40px; +} + +.contact-group label { + position: absolute; + top: 0; + left: 0; + color: #fff; /* Белый цвет по умолчанию */ + font-size: 14px; + pointer-events: none; + transition: all 0.3s ease; +} + +/* Стили для полей ввода */ +.contact input, +.contact textarea { + background: none; + border: none; + border-bottom: 1px solid $main-text-color; + color: #fff; + font-size: 16px; + outline: none; + + @include on-tablet { + padding: 0; + padding-bottom: 20px; + } +} + +/* Делаем placeholder прозрачным */ +.contact input::placeholder, +.contact textarea::placeholder { + color: transparent; +} + +/* Стили для textarea */ +.contact-group textarea { + resize: none; + height: 88px; + padding-top: 60px; +} + +/* Стили для кнопки */ +.contact-button { + font-weight: 500; + margin-top: 7px; + + @include on-tablet { + width: 200px; + margin-top: 23px; + padding: 15px; + } + + @include on-desktoplittle { + margin-top: 65px; + } + + @include on-desktopmiddle { + margin-top: 30px; + } +} + +.contact-group--error input, +.contact-group--error textarea { + border-bottom: 1px solid red; +} + +/* Убираем подчёркивание при фокусе */ +.contact input:focus, +.contact textarea:focus { + border-bottom: 1px solid #00c4cc; +} + +.contact-group--error input:focus, +.contact-group--error textarea:focus { + border-bottom: 1px solid red; +} + +.contact input:-webkit-autofill { + color: #fff; + background: none; + border: none; + border-bottom: 1px solid #929292; + outline: none; + font-size: 16px; + padding-bottom: 0; +} + +.error-message { + display: none; +} + +.contact-group--error .error-message { + display: block; + color: red; + font-size: 14px; + line-height: 150%; + margin-top: -15px; +} + +.contact-group--error label { + color: var(--error-color); +} + +.contact-group--error .contact-group-label, +.contact-group--error .sr-only { + display: none; +} + +.contact-group input:focus + label, +.contact-group textarea:focus + label { + color: $main-title-color-accent; + top: -15px; +} + +// /* Стили для меток при заполнении поля (позиция, размер и голубой цвет) */ +.contact-group input:not(:placeholder-shown) + label, +.contact-group textarea:not(:placeholder-shown) + label { + top: -15px; + left: 0; + color: $main-title-color-accent; +} + +/* Стили для сообщения под кнопкой */ +.contact-message { + color: #b0b0b0; + font-size: 12px; + line-height: 150%; + + @include on-tablet { + font-size: 16px; + margin-bottom: 72px; + } +} + +.contact-info { + font-size: 13px; + line-height: 210%; + width: 130px; + position: absolute; + transform: translate(115%, 148%); + + @include on-tablet { + position: static; + width: 158px; + font-size: 16px; + line-height: 175%; + transform: translate(0); + } +} + +.contact-info a { + color: $main-text-color; + + &:hover { + color: $main-title-color; + } +} diff --git a/src/styles/faq.scss b/src/styles/faq.scss new file mode 100644 index 00000000..8d3bbb61 --- /dev/null +++ b/src/styles/faq.scss @@ -0,0 +1,160 @@ +.faq { + &__content { + grid-column: span 2; + + @include on-tablet { + grid-column: span 6; + margin-top: 30px; + } + + @include on-desktoplittle { + grid-column: 2/-2; + margin-top: 0; + } + } + + &__title { + width: 280px; + margin: 30px 0; + + @include on-tablet { + margin: 5px 0 20px; + } + + @include on-desktoplittle { + width: 520px; + font-size: 36px; + margin: 27px 0 55px; + } + + @include on-desktopmiddle { + width: 100%; + margin: 28px 0 50px; + } + } + + &__subtitle { + position: relative; + padding: 18px 12px; + color: $main-title-color-accent; + + @include on-tablet { + padding: 15px 12px; + } + } + + &__arrow { + position: absolute; + display: none; + right: 2%; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 9px solid $main-title-color-accent; + transform: rotate(-90deg); + transition: transform 0.3s ease; + + &:hover { + border-top: 10px solid $main-title-color; + cursor: pointer; + } + + @include on-desktoplittle { + display: inline-block; + bottom: 35%; + } + + @include on-desktopmiddle { + bottom: 27px; + right: 10px; + } + } + + .faq__arrow { + border-top-color: white; + } + + details[open] .faq__arrow { + transform: rotate(0deg); + } + + &__block { + min-height: 84px; + border: 1px solid $main-title-color-accent; + border-radius: 4px; + margin-bottom: 20px; + + &:hover { + transform: scale(1.05); + } + + @include on-tablet { + margin-bottom: 18px; + padding: 0 16px; + min-height: 54px; + } + @include on-desktoplittle { + padding: 0 26px; + } + @include on-desktopmiddle { + padding: 0 15px; + } + } + + &__text-wrapper { + padding: 0 11px; + + @include on-tablet { + padding: 3px 11px; + } + } + + &__text { + margin-bottom: 10px; + + @include on-tablet { + margin-bottom: 25px; + } + } + + &__data { + font-size: 12px; + color: #545454; + margin-bottom: 12px; + + @include on-desktoplittle { + font-size: 14px; + } + } + + &__bottom-more { + display: none; + + @include on-desktoplittle { + margin-top: 48px; + padding-left: 0; + display: block; + } + } + + @include on-desktoplittle { + width: 68%; + height: 74%; + top: 11%; + left: 16%; + } + + @include on-desktopmiddle { + width: 1083px; + height: 793px; + top: 13%; + left: 22%; + } +} + +summary::-webkit-details-marker { + display: none; +} + +summary { + list-style: none; +} diff --git a/src/styles/footer.scss b/src/styles/footer.scss new file mode 100644 index 00000000..3fa548c2 --- /dev/null +++ b/src/styles/footer.scss @@ -0,0 +1,88 @@ +/* Стили для футера */ +.footer { + margin-bottom: 60px; +} + +.footer__container { + @include on-tablet { + display: flex; + justify-content: space-between; + } +} + +.footer__logo { + margin-bottom: 5px; + + @include on-tablet { + display: inline-flex; + } +} + +.footer__logo-img { + width: 69px; + height: 14px; +} + +.footer__menu { + display: inline-block; + + @include on-tablet { + width: 306px; + margin-right: 15px; + margin-left: 112px; + } +} + +.footer__menu-list { + line-height: 195%; + + @include on-tablet { + display: flex; + justify-content: space-between; + line-height: 100%; + } +} + +// .footer__menu-item { +// @include on-tablet { +// margin-right: 10px; +// } +// } + +.footer__menu-link { + font-size: 13px; + color: $main-title-color; + + &:hover { + color: $main-title-color-accent; + } + + @include on-tablet { + padding: 10px 22px; + } +} + +/* Стили для блока с иконками соцсетей */ +.footer__social { + display: inline-flex; + column-gap: 18px; + margin-left: 95px; + + @include on-tablet { + column-gap: 10px; + } +} + +/* Стили для ссылок соцсетей */ +.footer__social-link { + width: 19px; + height: 18px; + display: inline-block; +} + +/* Стили для иконок соцсетей */ +.footer__social-icon { + // width: 18px; + // height: 18px; + transition: fill 0.3s ease; +} diff --git a/src/styles/header.scss b/src/styles/header.scss new file mode 100644 index 00000000..51c8bcc8 --- /dev/null +++ b/src/styles/header.scss @@ -0,0 +1,312 @@ +.header { + display: grid; + + &__top { + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 20px; + align-items: center; + padding-top: 12px; + + @include on-tablet { + padding-top: 25px; + } + + @include on-desktoplittle { + padding-top: 60px; + display: flex; + align-items: flex-end; + } + } + + &__logo-img { + width: 58px; + height: 12px; + + &:hover { + @include hover(transform, scale(1.2)); + } + + @include on-tablet { + width: 67px; + height: 14px; + } + + @include on-desktoplittle { + width: 78px; + height: 16px; + } + } + + &__icon--menu { + background-image: url(../icons/menu-burger.svg); + + justify-self: end; + + &:hover { + @include hover(transform, scale(1.2)); + } + + @include on-desktoplittle { + display: none; + } + } + + &__content { + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 20px; + margin-bottom: 25px; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + padding: 0 55px 0 0; + } + + @include on-desktoplittle { + grid-template-columns: repeat(12, 1fr); + margin-bottom: 0; + } + } + + &__info { + padding: 0 20px; + grid-column: span 2; + + @include on-tablet { + grid-column: 1/-4; + transform: translateY(-85%); + padding: 0 0 0 35px; + } + + @include on-desktoplittle { + position: absolute; + top: 410px; + left: 8%; + } + + @include on-desktopmiddle { + top: 590px; + left: 13%; + } + } + + &__title { + font-weight: 900; + font-size: 26px; + line-height: 135%; + color: #fff; + margin-bottom: 17px; + text-transform: uppercase; + + &--color { + font-weight: 400; + color: $main-title-color-accent; + } + + @include on-desktoplittle { + font-size: 46px; + margin-left: -30px; + } + + @include on-desktopmiddle { + font-size: 56px; + } + } + + &__text { + font-weight: 500; + margin-bottom: 8px; + + @include on-tablet { + margin-bottom: 15px; + } + + @include on-desktoplittle { + width: 336px; + margin-bottom: 20px; + margin-left: 15%; + } + @include on-desktopmiddle { + width: 439px; + margin-bottom: 30px; + margin-left: 12%; + font-size: 20px; + line-height: 150%; + } + } + + &__price { + display: grid; + justify-self: center; + font-weight: 500; + font-size: 18px; + line-height: 100%; + + @include on-tablet { + justify-self: start; + } + + @include on-desktoplittle { + margin-left: 15%; + } + + @include on-desktopmiddle { + margin-left: 12%; + font-size: 20px; + } + } + + &__video { + position: absolute; + + &-iframe { + display: none; + width: 100%; + height: 100%; + } + + &--active { + border: 1px solid #fff; + top: 50px; + left: 20px; + right: 20px; + height: 81%; + + @include on-tablet { + background-color: black; + padding-block: 20px; + padding-inline: 20px; + height: 300%; + width: 205%; + top: 0%; + } + + @include on-desktoplittle { + width: 235%; + height: 220%; + top: -25%; + left: 0; + } + + @include on-desktopmiddle { + width: 270%; + height: 270%; + padding-block: 30px; + padding-inline: 40px; + top: -130px; + left: -5%; + } + } + } + + &__bottom { + display: none; + + &-item { + display: block; + } + + &-list { + display: flex; + margin-right: 39px; + } + + &-link { + font-weight: 500; + font-size: 16px; + margin-right: 39px; + color: $main-title-color; + + &:hover { + color: $main-title-color-accent; + } + } + + &-more { + text-align: center; + padding-left: 25px; + + &-link { + font-weight: 500; + line-height: 150%; + color: $main-title-color; + + &:hover { + color: $main-title-color-accent; + } + } + + @include on-desktopmiddle { + padding-left: 55px; + } + } + + &-slider { + display: inline-block; + border-bottom: 1px solid $main-text-color; + } + + &-slider-but { + line-height: 150%; + font-weight: 500; + width: 69px; + + padding: 0 0 22px; + display: inline-block; + border-radius: 0; + border-bottom: 2px solid transparent; + background-color: transparent; + cursor: pointer; + + &:hover { + background-color: transparent; + } + + &.active { + border-bottom: 2px solid #00c4cc; + color: $main-text-color; + } + + &--current { + color: transparent; + + &.active { + color: transparent; + } + } + } + + @include on-desktoplittle { + display: flex; + justify-content: space-between; + margin-bottom: 84px; + margin-top: 16%; + } + + @include on-desktopmiddle { + margin-top: 33%; + } + } + + // @include on-desktopmiddle { + // margin-bottom: 165px; + // } +} + +.header__bottom-more:hover .header__bottom-more-link { + color: $main-title-color-accent; +} + +/* Изменение цвета стрелки при наведении на header__bottom-more */ +.header__bottom-more:hover .lang-switcher__arrow path { + fill: $main-title-color-accent; +} + +.play-button:hover svg .play-button-path { + fill: $main-title-color; +} + +.about__play-button:hover svg .play-button-path { + fill: $main-title-color; +} diff --git a/src/styles/help.scss b/src/styles/help.scss new file mode 100644 index 00000000..b3bda35e --- /dev/null +++ b/src/styles/help.scss @@ -0,0 +1,116 @@ +.help { + &__title { + margin: 30px 0; + grid-column: span 2; + + @include on-tablet { + grid-column: span 6; + } + + @include on-desktoplittle { + margin: 0 0 60px 10px; + font-size: 36px; + grid-column: 2/-1; + } + + @include on-desktopmiddle { + margin-left: 0; + } + } + + &__text { + margin-bottom: 27px; + grid-column: span 2; + + &--link { + color: $main-title-color-accent; + &:hover { + color: blue; + } + } + + @include on-tablet { + grid-column: span 6; + } + + @include on-desktoplittle { + grid-column: 2/-2; + padding: 0 5px; + } + } + + &__links { + grid-column: span 2; + margin: 10px 0 5px; + + @include on-tablet { + grid-column: 1/-4; + margin: 2px 0 5px; + } + @include on-desktoplittle { + padding-left: 10px; + grid-column: 2/-8; + } + @include on-desktopmiddle { + width: 205px; + padding-left: 0; + grid-column: 2/-9; + } + } + + &__link { + display: block; + color: $main-title-color-accent; + margin-bottom: 20px; + + &:hover { + font-size: 18px; + } + } + + &__contact { + display: grid; + gap: 5px; + grid-column: span 2; + margin-bottom: 73px; + + & a { + color: $main-text-color; + + &:hover { + color: $main-title-color; + font-size: 18px; + } + } + + @include on-tablet { + grid-column: 4/-1; + margin-bottom: 12px; + } + + @include on-desktoplittle { + grid-column: 6/-1; + margin-left: -20px; + } + + @include on-desktopmiddle { + width: 205px; + grid-column: 5/-1; + margin-left: -5px; + } + } + + @include on-desktoplittle { + width: 880px; + height: 550px; + top: 17%; + left: 16%; + } + + @include on-desktopmiddle { + width: 1083px; + height: 518px; + top: 26%; + left: 22%; + } +} diff --git a/src/styles/lang-switcher.scss b/src/styles/lang-switcher.scss new file mode 100644 index 00000000..65c2f137 --- /dev/null +++ b/src/styles/lang-switcher.scss @@ -0,0 +1,91 @@ +.lang-switcher { + display: none; + + @include on-desktoplittle { + display: inline-block; + } + + position: relative; + font-family: Arial, sans-serif; + + &__current { + display: flex; + align-items: baseline; + gap: 6px; + cursor: pointer; + padding: 8px 12px; + @include on-desktoplittle { + padding: 2px 12px; + } + } + + &__current span { + color: $main-title-color-accent; + font-size: 16px; + font-weight: 500; + } + + &__arrow { + transition: transform 0.3s ease; + } + + /* Стили для выпадающего меню */ + &__dropdown { + position: absolute; + scrollbar-width: thin; + scrollbar-color: $main-title-color-accent transparent; + max-height: 111px; + text-align: center; + max-width: 60px; + overflow-y: auto; + top: 100%; + left: -5px; + background-color: $background-color; + border-radius: 4px; + list-style: none; + padding: 0; + margin: 0; + z-index: 10; + opacity: 0; + transform: translateY(-10px); + visibility: hidden; + transition: + opacity 0.3s ease, + transform 0.3s ease, + visibility 0.3s ease; + + & li:last-child { + border-bottom: none; + } + + & a { + display: block; + padding: 10px; + color: $main-title-color-accent; + text-decoration: none; + font-size: 16px; + transition: + background-color 0.2s ease, + color 0.2s ease; + } + + & a:hover { + background-color: #00c4cc; + color: #1a1a1a; + } + + & li:first-child a { + color: $main-title-color; + } + } + + &.is-open .lang-switcher__arrow { + transform: rotate(180deg); + } + + &.is-open .lang-switcher__dropdown { + opacity: 1; + transform: translateY(10px); + visibility: visible; + } +} diff --git a/src/styles/lang.scss b/src/styles/lang.scss new file mode 100644 index 00000000..086be011 --- /dev/null +++ b/src/styles/lang.scss @@ -0,0 +1,53 @@ +.lang { + overflow-y: auto; + + &__wrapper { + margin-top: 20px; + + @include on-tablet { + margin-top: 30px; + } + } + + &--arrow { + padding: 20px 0 38px; + margin-bottom: 20px; + + &:hover path { + stroke: $main-title-color-accent; + } + + &:hover { + @include hover(transform, scale(1.2)); + } + + @include on-tablet { + padding: 30px 0 47px; + } + } + + &__link { + padding: 10px 25px; + display: block; + } + + &__bottom { + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 20px; + margin-top: 33px; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + margin-top: 47px; + } + } + + &__nav { + grid-column: 1 / -1; + + @include on-tablet { + grid-column: 2 / -1; + } + } +} diff --git a/src/styles/main.scss b/src/styles/main.scss index fb9195d1..6ae766b7 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -1,7 +1,25 @@ -@import 'utils'; -@import 'fonts'; -@import 'typography'; +@import './utils/variables'; +@import './utils/mixins'; -body { - background: $c-gray; -} +@import 'header'; +@import 'page'; +@import 'lang-switcher'; +@import 'menu'; +@import 'buttons'; +@import 'slider'; +@import 'aside'; +@import 'help'; +@import 'faq'; +@import 'lang'; +@import 'order'; +@import 'price-container'; +@import 'buy-form'; +@import 'pay'; +@import 'aside-complete'; +@import 'more'; +@import 'about'; +@import 'tech'; +@import 'benefits'; +@import 'contact'; +@import 'back-to-up'; +@import 'footer'; diff --git a/src/styles/menu.scss b/src/styles/menu.scss new file mode 100644 index 00000000..645440fa --- /dev/null +++ b/src/styles/menu.scss @@ -0,0 +1,210 @@ +.icon { + position: relative; + width: 20px; + height: 10px; + background-size: cover; + + @include on-tablet { + width: 28px; + height: 13px; + } + + &-close--menu { + @include on-desktoplittle { + display: none; + } + } + + &:hover { + color: $main-title-color-accent; + } +} + +.menu { + position: fixed; + left: 0; + transform-origin: left center; /* Точка вращения — левый край */ + transform: perspective(1000px) rotateY(-90deg); /* Начальное состояние: "закрыто" */ + opacity: 0; + pointer-events: none; + transition: + transform 0.5s ease-in-out, + opacity 0.5s ease-in-out; + z-index: 1000; + top: 0; + background-color: #191536; + width: 100%; + height: 100%; + + &:target, + &.menu--open { + opacity: 1; + transform: perspective(1000px) rotateY(0deg); + pointer-events: all; + } + + &__wrapper { + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 20px; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + } + @include on-desktoplittle { + grid-template-columns: repeat(12, 1fr); + } + } + + &-decktop { + @include on-desktoplittle { + // /* Делаем меню видимым на десктопе */ + transform: none; /* Убираем анимацию открытия */ + opacity: 5; /* Делаем видимым */ + pointer-events: all; /* Делаем кликабельным */ + background-color: transparent; /* Убираем фон */ + width: auto; /* Ширина по содержимому */ + height: auto; /* Высота по содержимому */ + display: flex; /* Располагаем элементы горизонтально */ + align-items: center; + position: absolute; + top: 60px; + left: 36%; + } + } + + &__bottom { + padding-block: 48px; + grid-column: span 2; + + @include on-tablet { + padding: 55px 0 139px; + grid-column: 2/-1; + } + + @include on-desktoplittle { + padding: 0; + } + + @include on-desktopmiddle { + padding-left: 156px; + } + } + + &__list { + display: grid; + row-gap: 22px; + + @include on-desktoplittle { + display: flex; + } + } + + &__item { + opacity: 0; + transform: translateX(-20px); + transition: + opacity 0.3s ease, + transform 0.3s ease; + + &-menu { + @include on-desktoplittle { + opacity: 1; /* Элементы сразу видны на десктопе */ + transform: none; /* Убираем анимацию появления */ + transition: none; /* Убираем анимацию */ + margin-right: 3px; + } + } + + &-lang, + &-faq, + &-help { + @include on-desktoplittle { + display: none; + } + } + } + + &:target .menu__item, + &.menu--open .menu__item { + opacity: 1; + transform: translateX(0); + } + + &:target .menu__item:nth-child(1), + &.menu--open .menu__item:nth-child(1) { + transition-delay: 0.3s; + } + &:target .menu__item:nth-child(2), + &.menu--open .menu__item:nth-child(2) { + transition-delay: 0.35s; + } + &:target .menu__item:nth-child(3), + &.menu--open .menu__item:nth-child(3) { + transition-delay: 0.4s; + } + &:target .menu__item:nth-child(4), + &.menu--open .menu__item:nth-child(4) { + transition-delay: 0.45s; + } + &:target .menu__item:nth-child(5), + &.menu--open .menu__item:nth-child(5) { + transition-delay: 0.5s; + } + &:target .menu__item:nth-child(6), + &.menu--open .menu__item:nth-child(6) { + transition-delay: 0.55s; + } + &:target .menu__item:nth-child(7), + &.menu--open .menu__item:nth-child(7) { + transition-delay: 0.6s; + } + &:target .menu__item:nth-child(8), + &.menu--open .menu__item:nth-child(8) { + transition-delay: 0.65s; + } + &:target .menu__item:nth-child(9), + &.menu--open .menu__item:nth-child(9) { + transition-delay: 0.7s; + } + &:target .menu__item:nth-child(10), + &.menu--open .menu__item:nth-child(10) { + transition-delay: 0.75s; + } + + &__link { + font-weight: 500; + font-size: 21px; + line-height: 130%; + padding: 11px 100% 11px 5px; + color: $main-title-color; + &:hover { + color: $main-title-color-accent; + background-color: #110e25; + + @include on-desktoplittle { + background-color: transparent; + } + } + + @include on-desktoplittle { + font-size: 16px; + padding: 11px 15px; + } + } + + &--close { + grid-column: 2 / -1; + justify-self: end; + background-image: url(../icons/menu-close.svg); + width: 17px; + height: 17px; + margin-top: 20px; + + @include hover(transform, scale(1.2)); + + @include on-tablet { + margin-top: 34px; + } + } +} diff --git a/src/styles/more.scss b/src/styles/more.scss new file mode 100644 index 00000000..d1e316dd --- /dev/null +++ b/src/styles/more.scss @@ -0,0 +1,207 @@ +.more { + padding-top: 160px; + padding-bottom: 50px; + + &__title { + margin-bottom: 12px; + + @include on-tablet { + grid-column: span 6; + text-align: center; + } + + @include on-desktoplittle { + margin-bottom: 25px; + } + } + + &__text { + font-size: 12px; + line-height: 100%; + margin-bottom: 48px; + color: $main-title-color-accent; + + @include on-tablet { + grid-column: span 6; + text-align: center; + margin-bottom: 165px; + } + + @include on-desktoplittle { + margin-bottom: 200px; + font-size: 14px; + } + + @include on-desktopmiddle { + margin-bottom: 185px; + } + } + + &__wrapper { + display: grid; + grid-template-columns: repeat (2, 1fr); + gap: 22px 20px; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + row-gap: 72px; + } + + @include on-desktoplittle { + grid-template-columns: repeat(12, 1fr); + row-gap: 0; + } + + @include on-desktopmiddle { + grid-template-columns: repeat(16, 1fr); + } + } + + &__block { + position: relative; + height: 82px; + grid-column: span 2; + padding-right: 30px; + + @include on-tablet { + height: 195px; + padding-right: 0; + grid-column: span 3; + text-align: center; + } + + @include on-desktoplittle { + // padding-top: 53%; + grid-column: span 3; + height: 267px; + } + + @include on-desktopmiddle { + grid-column: span 4; + height: 295px; + } + + &::before { + display: none; + + @include on-tablet { + content: url('../icons/more-cap.svg'); + display: block; + position: absolute; + width: 98px; + height: 81px; + top: 60%; + left: 50%; + transform: translate(-50%, -280%); + } + + @include on-desktoplittle { + top: 42%; + left: 50%; + transform: translate(-50%, -280%); + } + + @include on-desktopmiddle { + top: 37%; + left: 50%; + transform: translate(-50%, -280%); + } + } + + &-estate::before { + @include on-tablet { + content: url('../icons/more-building.svg'); + } + } + + &-fitness::before { + @include on-tablet { + content: url('../icons/more-circle.svg'); + } + } + + &-social::before { + @include on-tablet { + content: url('../icons/more-flow.svg'); + } + } + + &:hover::before { + content: url('../icons/more-cap1.svg'); + transition: all 0.5s; + } + + &-estate:hover::before { + content: url('../icons/more-building1.svg'); + transition: all 0.5s; + } + + &-fitness:hover::before { + content: url('../icons/more-circle1.svg'); + transition: all 0.5s; + } + + &-social:hover::before { + content: url('../icons/more-flow1.svg'); + transition: all 0.5s; + } + } + + &__subtitle { + margin-bottom: 15px; + + @include on-tablet { + margin-bottom: 20px; + } + } + + @include on-tablet { + padding-bottom: 0; + padding-top: 40px; + } + + @include on-desktoplittle { + padding-top: 90px; + } + + @include on-desktopmiddle { + padding-top: 165px; + } +} + +.section__text { + position: relative; + max-height: 52px; + overflow-y: auto; + + @include on-tablet { + max-height: 81px; + } + + @include on-desktoplittle { + max-height: 108px; + } + + @include on-desktopmiddle { + max-height: 81px; + } +} + +.section__text::after { + content: '...'; + position: absolute; + bottom: 0; + right: 0; + color: #fff; + font-size: 14px; + background: #05040b; /* Совпадает с фоном блока */ + padding: 0 5px; + + @include on-tablet { + display: none; + } +} + +.section__text.hide-ellipsis::after { + display: none; +} diff --git a/src/styles/order.scss b/src/styles/order.scss new file mode 100644 index 00000000..69c7c86c --- /dev/null +++ b/src/styles/order.scss @@ -0,0 +1,154 @@ +// мод окно + +.buy { + position: fixed; + left: 0; + transform-origin: left center; /* Точка вращения — левый край */ + transform: perspective(1000px) rotateY(-90deg); /* Начальное состояние: "закрыто" */ + opacity: 0; + pointer-events: none; + transition: + transform 0.5s ease-in-out, + opacity 0.5s ease-in-out; /* Плавный переход */ + + z-index: 1000; + top: 0; + background-color: $background-color; + width: 100%; + height: 100%; + overflow-y: auto; + + &__top { + margin: 15px 0 25px; + display: flex; + justify-content: space-between; + + @include on-tablet { + margin: 25px 0; + } + + @include on-desktoplittle { + margin: 0; + margin-top: 6%; + } + + @include on-desktopmiddle { + margin-top: 60px; + } + } + + &__close { + background-image: url(../icons/menu-close.svg); + width: 15px; + height: 15px; + @include hover(transform, scale(1.2)); + + @include on-desktoplittle { + display: none; + } + } + + &__menu { + display: flex; + justify-content: space-between; + min-height: 33px; + border-bottom: 1px solid #2f2f2f; + margin-bottom: 30px; + + &-item { + padding: 0 19px 17px; + font-weight: 500; + font-size: 12px; + line-height: 130%; + color: #545454; + + text-decoration: none; + border-bottom: 2px solid transparent; + transition: + color 0.3s, + border-bottom-color 0.3s; + + &:active { + color: $main-title-color-accent; + border-bottom: 1px solid main-title-color-accent; + } + &:hover { + color: $main-title-color-accent; + } + + @include on-tablet { + font-size: 14px; + } + } + + @include on-desktoplittle { + position: absolute; + border-bottom: none; + width: 57%; + left: 23%; + top: 65px; + } + + @include on-desktopmiddle { + top: 58px; + left: 24%; + } + } +} + +.buy--open { + opacity: 1; + transform: perspective(1000px) rotateY(0deg); + pointer-events: all; +} + +.step { + display: flex; + flex-direction: column; + align-items: center; + color: #888; + font-size: 14px; + flex: 1; +} + +.step.active { + border-bottom: 2px solid #00c4cc; + + @include on-desktoplittle { + border-bottom: 2px solid transparent; + } +} + +.step.active::after { + @include on-desktoplittle { + content: ''; + + position: absolute; + bottom: 10px; + + display: block; + background-color: $main-title-color-accent; + + width: 4px; + height: 4px; + border-radius: 50%; + } +} + +.step.active .buy__menu-item { + color: #00c4cc; +} + +select { + display: block; + width: 60px; + border: none; + color: #fff; + font-size: 16px; + appearance: none; + padding: 10px; + background: url('data:image/svg+xml;utf8,'); + background-color: #191536; + background-repeat: no-repeat; + background-position: right 10px center; +} diff --git a/src/styles/page.scss b/src/styles/page.scss new file mode 100644 index 00000000..0db3bb21 --- /dev/null +++ b/src/styles/page.scss @@ -0,0 +1,171 @@ +html { + box-sizing: border-box; + scroll-behavior: smooth; +} + +*, +*::before, +*::after { + box-sizing: inherit; +} + +body { + font-family: $font-family; + font-weight: $font-weight; + font-size: $font-size; + color: $main-text-color; + line-height: $line-height; + background-color: $background-color; +} + +html, +body, +div, +span, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +abbr, +address, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +samp, +small, +strong, +sub, +sup, +var, +b, +i, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + list-style: none; + vertical-align: baseline; +} + +a { + margin: 0; + padding: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent; + text-decoration: none; + list-style: none; +} + +input, +select { + vertical-align: middle; + border: none; +} + +.play-icon { + width: 30px; + height: 30px; + margin-right: 10px; +} + +.play-button span { + position: relative; + padding-right: 30px; +} + +.play-button span::after { + content: ''; + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); + width: 20px; + height: 2px; + background: repeating-linear-gradient( + to right, + #00c4ff, + #00c4ff 4px, + transparent 4px, + transparent 8px + ); +} + +.section__title { + font-weight: 900; + font-size: 21px; + line-height: 100%; + text-transform: uppercase; + color: $main-title-color; + + &--color { + font-weight: 400; + color: $main-title-color-accent; + } + + @include on-desktoplittle { + font-size: 36px; + } +} + +.section__subtitle { + font-weight: 900; + font-size: 18px; + line-height: 100%; + color: $main-title-color; +} + +.container__aside { + @include on-desktoplittle { + padding-inline: 0; + } +} diff --git a/src/styles/pay.scss b/src/styles/pay.scss new file mode 100644 index 00000000..ce24a02a --- /dev/null +++ b/src/styles/pay.scss @@ -0,0 +1,205 @@ +// .buy-pay__form { +// display: block; +// font-size: 14px; +// line-height: 130%; +// color: $main-text-color; +// } + +.buy-pay__form-date, +.buy-pay__form-cvv { + margin-bottom: 10px; +} + +.payment-form__group { + margin-bottom: 30px; + + @include on-tablet { + grid-column: 2/-2; + margin-bottom: 35px; + } + @include on-desktoplittle { + grid-column: 2/-1; + } + + @include on-desktopmiddle { + grid-column: 1/-1; + margin-bottom: 38px; + } +} + +// .buy-pay__form { +// font-size: 14px; +// line-height: 130%; +// color: $main-text-color; +// } + +.card-number-group { + display: flex; + gap: 10px; + align-items: end; + + @include on-desktopmiddle { + justify-content: space-between; + } +} + +.payment-form__input { + position: relative; + font-size: 18px; + line-height: 130%; + width: 100%; + letter-spacing: 5px; + padding-bottom: 0; + background-color: $background-color; + border: none; + border-bottom: 2px solid #2f2f2f; + color: $main-title-color; + + @include on-tablet { + padding-bottom: 14px; + } +} + +.payment-form__input:focus-visible { + outline: none; + border-bottom: 1px solid $main-title-color-accent; +} + +.buy-pay__form { + display: block; + font-size: 14px; + line-height: 130%; + color: $main-text-color; + transition: color 0.3s ease; + margin-bottom: 30px; + + @include on-desktoplittle { + margin-bottom: 38px; + } + @include on-desktopmiddle { + margin-bottom: 60px; + } + + &-label { + margin-bottom: 5px; + @include on-desktopmiddle { + margin-bottom: 17px; + } + } + + &-lab { + margin-bottom: -5px; + } +} + +.pay__visa { + display: none; + + @include on-tablet { + display: block; + height: 34px; + } +} + +/* Подсвечиваем label для card-number */ +.payment-form__group:has(.card-number-group .payment-form__input:focus-visible) + .buy-pay__form { + color: $main-title-color-accent; +} + +/* Подсвечиваем label только если его for соответствует id сфокусированного input */ +.payment-form__group + label.card-holder-label:has( + + .payment-form__input.card-holder-input:focus-visible + ) { + color: $main-title-color-accent; +} + +.payment-form__group + label.expiry-date-label:has( + + .payment-form__input.expiry-date-input:focus-visible + ) { + color: $main-title-color-accent; +} + +.payment-form__group + label.cvv-label:has(+ .payment-form__input.cvv-input:focus-visible) { + color: $main-title-color-accent; +} + +.payment-form__input::placeholder { + color: #2f2f2f; + letter-spacing: 20%; + font-size: 20px; +} + +.payment-form__input--card-number { + width: 25%; + padding: 10px 0; + + @include on-tablet { + width: 70px; + font-size: 20px; + margin-right: 22px; + } + + @include on-desktoplittle { + margin-right: 11px; + } +} + +.error-message { + position: absolute; + display: none; + color: red; + font-size: 10px; + margin-top: 5px; +} + +.row { + display: flex; + gap: 10px; + + @include on-desktopmiddle { + grid-column: span 4; + } +} + +.col { + flex: 1; +} + +.buy-pay__payment-form { + @include on-tablet { + display: grid; + grid-template-columns: repeat(6, 1fr); + column-gap: 20px; + } + + @include on-desktoplittle { + width: 430px; + position: absolute; + right: 21%; + top: 31%; + } + + @include on-desktopmiddle { + width: 533px; + right: 22%; + } +} + +.buy__button-pay { + @include on-tablet { + margin: 45px 0 0; + } + + @include on-desktoplittle { + margin-top: 20px; + margin-left: -5px; + } + @include on-desktopmiddle { + margin-top: 35px; + margin-left: 5px; + } +} diff --git a/src/styles/price-container.scss b/src/styles/price-container.scss new file mode 100644 index 00000000..d0142d24 --- /dev/null +++ b/src/styles/price-container.scss @@ -0,0 +1,112 @@ +.price-container { + display: flex; + justify-content: center; + margin-bottom: 51px; + + @include on-tablet { + justify-content: start; + margin: 5px 0 45px; + } + + @include on-desktoplittle { + position: absolute; + bottom: 55px; + left: 9%; + } + + @include on-desktopmiddle { + bottom: 225px; + left: 13%; + } + + &-pay { + @include on-tablet { + display: grid; + grid-template-columns: repeat(6, 1fr); + column-gap: 20px; + margin: 0 0 60px; + } + + @include on-desktoplittle { + margin: 0 0 45px; + } + } +} + +.quantity { + margin-right: 65px; + + @include on-tablet { + margin-right: 22%; + } + + @include on-desktoplittle { + margin-right: 50%; + } +} + +.quantity, +.price { + line-height: 130%; + text-align: center; +} + +.quantity-pay { + @include on-tablet { + text-align: start; + grid-column: 2/-4; + } + + @include on-desktoplittle { + margin-right: 65px; + grid-column: 1/-4; + } +} + +.price { + @include on-tablet { + text-align: start; + grid-column: 4/-1; + } +} + +.quantity__select-option { + text-align: center; + font-size: 20px; + line-height: 130%; + width: 90px; + margin-top: 8px; + padding: 8px 5px 8px 0; + + &:hover { + background-size: 30px 30px; + color: $main-title-color-accent; + } + + &:focus-visible { + outline: none; + } + + @include on-tablet { + margin-top: 25px; + } +} + +.quantity__label { + margin-right: 25px; +} + +.quantity__select-price { + margin-top: 15px; + display: block; + width: 80px; + font-size: 26px; + color: #00c4cc; + + @include on-tablet { + font-weight: 500; + font-size: 36px; + line-height: 100%; + margin-top: 28px; + } +} diff --git a/src/styles/slider.scss b/src/styles/slider.scss new file mode 100644 index 00000000..e079bace --- /dev/null +++ b/src/styles/slider.scss @@ -0,0 +1,76 @@ +.slider { + grid-column: span 2; + + &__img-static { + width: 320px; + + @include on-tablet { + width: 386px; + } + @include on-desktoplittle { + display: none; + } + } + + &__img { + width: 100%; + height: 100%; + object-fit: cover; + + @include on-desktoplittle { + width: 650px; + } + + @include on-desktopmiddle { + width: 100%; + } + } + + &__item { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + transition: opacity 0.5s ease; + display: none; + + @include on-desktoplittle { + display: block; + } + } + + @include on-tablet { + grid-column: 4/-1; + transform: translateY(45%); + } + + @include on-desktoplittle { + position: relative; + width: 100%; + height: 360px; /* Укажи нужную высоту слайдера */ + overflow: hidden; + grid-column: 7 / -1; + transform: translateX(-6%) translateY(30%); + } + + @include on-desktopmiddle { + height: 400px; + transform: translateX(-17%) translateY(75%); + } +} + +// .slider__item { +// position: absolute; +// top: 0; +// left: 0; +// width: 100%; +// height: 100%; +// opacity: 0; +// transition: opacity 0.5s ease; +// } + +.slider__item.active { + opacity: 1; +} diff --git a/src/styles/tech.scss b/src/styles/tech.scss new file mode 100644 index 00000000..846358d8 --- /dev/null +++ b/src/styles/tech.scss @@ -0,0 +1,312 @@ +.tech { + padding-block: 80px; + + @include on-desktoplittle { + padding-block: 130px; + } + + @include on-desktopmiddle { + padding-block: 220px; + } +} + +.tech__title { + margin-bottom: 48px; + + @include on-tablet { + margin-bottom: 60px; + } + + @include on-desktoplittle { + display: inline-block; + margin-bottom: 145px; + margin-left: 68%; + padding-top: 50px; + } + + @include on-desktopmiddle { + margin-left: 69%; + padding-top: 110px; + } +} + +/* Центральный круг */ +.tech__wrapper { + position: relative; + margin: 0 auto; + overflow: visible; + height: auto; + grid-template-columns: repeat(2, 1fr); + display: grid; + justify-items: center; + column-gap: 20px; + + @include on-desktoplittle { + grid-template-columns: repeat(12, 1fr); + width: 1055px; + } + + @include on-desktopmiddle { + width: 1175px; + } +} + +.tech__circle { + position: relative; + grid-column: span 2; + width: 197px; + height: 195px; + + @include on-tablet { + width: 358px; + height: 354px; + } + + @include on-desktoplittle { + width: 298px; + height: 294px; + grid-column: 5 / -6; + } +} + +.tech__small-circle, +.tech__small-circle::after, +.tech__small-circle::before { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + width: 34px; + height: 34px; + font-family: Arial, sans-serif; + font-size: 35px; + color: $main-title-color; + background-color: $main-title-color-accent; + line-height: 1; + transform: translate(-50%, -145%); + + @include on-tablet { + width: 62px; + height: 62px; + transform: translate(-95%, -140%); + } + + @include on-desktoplittle { + display: none; + } +} + +.tech__small-circle::after { + content: '+'; + top: -115px; + left: 95px; + + @include on-tablet { + top: -210px; + left: 180px; + } +} + +.tech__small-circle::before { + content: '+'; + top: -25px; + left: 167px; + + @include on-tablet { + top: -40px; + left: 365px; + } +} + +.tech__circle img { + width: 100%; + height: 100%; + object-fit: cover; +} + +/* Общие стили для блоков */ + +.tech-specs__block { + display: none; + + @include on-desktoplittle { + position: absolute; + text-transform: uppercase; + display: flex; + align-items: flex-start; + overflow: visible; /* Убедимся, что SVG не обрезается */ + } +} + +.tech-specs__content { + opacity: 0; /* Скрываем текст до анимации */ +} + +.tech-specs__subtitle { + font-weight: 900; + font-size: 18px; + margin-bottom: 21px; + color: $main-title-color; +} + +.tech-specs__list { + text-transform: capitalize; + list-style: none; + padding: 0; + font-size: 16px; +} + +// .tech-specs__list li { +// color: $main-text-color; +// } + +/* Позиционирование блоков */ +.tech-specs__block--sensor { + // top: -62px; + // left: 0; + // flex-direction: row; + top: -62px; + left: 0; + + @include on-desktopmiddle { + left: 55px; + } +} + +.tech-specs__block--batteries { + top: -60px; + right: -15px; + + @include on-desktoplittle { + right: -17px; + } + + @include on-desktopmiddle { + right: -70px; + } +} + +.tech-specs__block--connection { + bottom: 20px; + left: 90px; + flex-direction: row; + + @include on-desktoplittle { + left: 88px; + } + + @include on-desktopmiddle { + left: 0; + } + + @include on-desktopmiddle { + left: 55px; + } +} + +/* Линии */ +.tech-specs__line { + position: absolute; +} + +/* Линии для каждого блока */ +.tech-specs__line--sensor { + position: absolute; + top: 0; + left: 85px; +} + +.tech-specs__line--batteries { + position: absolute; + top: 0; + left: -250px; + + @include on-desktopmiddle { + left: -400px; + } +} + +.tech-specs__line--connection { + position: absolute; + top: -140px; + left: 25px; +} + +/* Стили для кружка */ +.tech-specs__line--sensor circle, +.tech-specs__line--batteries circle, +.tech-specs__line--connection circle { + opacity: 0; + animation: fade-in 0.5s forwards 2s infinite; /* Синхронизируем с началом анимации линии */ +} + +/* Анимация конечного кружка для CONNECTION */ +.tech-specs__line--connection .end-circle { + animation: fade-in 0.5s forwards 3s infinite; /* Появляется после линии (1s анимация + 2s задержка) */ +} + +/* Анимация SVG линии */ +.tech-specs__line--sensor path { + stroke-dasharray: 690; /* Длина пути (примерно H350 + V90) */ + stroke-dashoffset: 690; /* Начальное смещение для анимации */ + animation: draw-line 5s forwards 5s infinite; +} + +.tech-specs__line--batteries path { + stroke-dasharray: 385; /* Длина пути (примерно H350 + V90) */ + stroke-dashoffset: 385; /* Начальное смещение для анимации */ + animation: draw-line 5s forwards 5s infinite; + + @include on-desktopmiddle { + stroke-dasharray: 500; /* Длина пути (примерно H350 + V90) */ + stroke-dashoffset: 500; /* Начальное смещение для анимации */ + } +} + +.tech-specs__line--connection path { + stroke-dasharray: 190; /* Длина пути (примерно H350 + V90) */ + stroke-dashoffset: 190; /* Начальное смещение для анимации */ + animation: draw-line 5s forwards 5s infinite; + + @include on-desktopmiddle { + stroke-dasharray: 270; /* Длина пути (примерно H350 + V90) */ + stroke-dashoffset: 270; /* Начальное смещение для анимации */ + } +} + +@keyframes draw-line { + to { + stroke-dashoffset: 0; /* Линия полностью нарисована */ + } +} + +/* Анимация появления обводки кружка */ +@keyframes draw-circle-stroke { + to { + stroke-dashoffset: 0; + } +} + +/* Показ текста после анимации линии */ +.tech-specs__block--sensor .tech-specs__content { + animation: fade-in 0.5s forwards; +} + +.tech-specs__block--batteries .tech-specs__content { + animation: fade-in 0.5s forwards; +} + +.tech-specs__block--connection .tech-specs__content { + animation: fade-in 0.5s forwards; +} + +/* Анимация появления текста */ +@keyframes fade-in { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} diff --git a/src/styles/utils/_extends.scss b/src/styles/utils/_extends.scss deleted file mode 100644 index d7201e7b..00000000 --- a/src/styles/utils/_extends.scss +++ /dev/null @@ -1,4 +0,0 @@ -%h1 { - font-family: Roboto, sans-serif; - font-weight: 400; -} diff --git a/src/styles/utils/_mixins.scss b/src/styles/utils/_mixins.scss deleted file mode 100644 index 80c79780..00000000 --- a/src/styles/utils/_mixins.scss +++ /dev/null @@ -1,6 +0,0 @@ -@mixin hover($_property, $_toValue) { - transition: #{$_property} 0.3s; - &:hover { - #{$_property}: $_toValue; - } -} diff --git a/src/styles/utils/_vars.scss b/src/styles/utils/_vars.scss deleted file mode 100644 index aeb006ff..00000000 --- a/src/styles/utils/_vars.scss +++ /dev/null @@ -1 +0,0 @@ -$c-gray: #eee; diff --git a/src/styles/utils/mixins.scss b/src/styles/utils/mixins.scss new file mode 100644 index 00000000..e2359a88 --- /dev/null +++ b/src/styles/utils/mixins.scss @@ -0,0 +1,45 @@ +@mixin hover($property, $toValue) { + transition: #{$property} 0.5s; + + &:hover { + #{$property}: $toValue; + } +} + +@mixin on-tablet() { + @media (min-width: $tablet) { + @content; + } +} + +@mixin on-desktoplittle() { + @media (min-width: $desktop-little) { + @content; + } +} + +@mixin on-desktopmiddle() { + @media (min-width: $desktop-middle) { + @content; + } +} + +@mixin content-padding() { + padding-inline: 20px; + + @include on-tablet { + padding-inline: 33px; + } + + @include on-desktoplittle { + padding-inline: 110px; + } + + @include on-desktopmiddle { + padding-inline: 234px; + } +} + +.container { + @include content-padding; +} diff --git a/src/styles/utils/variables.scss b/src/styles/utils/variables.scss new file mode 100644 index 00000000..7a1e718b --- /dev/null +++ b/src/styles/utils/variables.scss @@ -0,0 +1,11 @@ +$tablet: 768px; +$desktop-little: 1280px; +$desktop-middle: 1920px; +$font-family: 'Inter', sans-serif; +$font-size: 16px; +$main-title-color: #fff; +$main-title-color-accent: #05c2df; +$main-text-color: #929292; +$line-height: 150%; +$font-weight: 400; +$background-color: #000;