diff --git a/.github/workflows/test.yml-template b/.github/workflows/test.yml-template new file mode 100644 index 000000000..8b5743ecb --- /dev/null +++ b/.github/workflows/test.yml-template @@ -0,0 +1,29 @@ +name: Test + +on: + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test + - name: Upload HTML report(backstop data) + if: ${{ always() }} + uses: actions/upload-artifact@v2 + with: + name: report + path: backstop_data diff --git a/README.md b/README.md index 302783df5..f6ff6e3d0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # KateVR landing page (HARD) -**⚠️ Attention: this is a hard landing page for development. We highly recommend choosing this landing page only if you didn't have a lot of troubles with previous homework tasks and if you sent all homework in time (didn't miss deadlines).** +**⚠️ Attention: this is a hard landing page for development. We highly recommend choosing this landing page only if you didn't have a lot of troubles with previous homework tasks and if you sent all homework in time (didn't miss deadlines).** Implement landing page according to [Figma design](https://www.figma.com/file/Blpg4iapsI7fRqJeSp6DvK/KatVR?node-id=1%3A370) - Use BEM and SCSS @@ -25,7 +25,7 @@ Implement landing page according to [Figma design](https://www.figma.com/file/Bl 11. `git push origin develop` - to send you code for PR. 12. Create a Pull Request (PR) from your branch `develop` to branch `master` of original repo. 13. Replace `` with your Github username in the - [DEMO LINK](https://.github.io/layout_KateVR/). + [DEMO LINK](https://tvoypervy.github.io/layout_KateVR/). 14. Copy `DEMO LINK` to the PR description. > To update you PR repeat steps 7-11. diff --git a/index.html b/index.html index d339e6856..273d57aac 100644 --- a/index.html +++ b/index.html @@ -1,19 +1,1449 @@ - + - Title + KATVR + + + + + - -

Hello Mate Academy

- + +
+
+
+
+ +
+ + +
+ + + + Buy Now + +
+ +
+
+
+
+ VR system +
+
+ VR system +
+
+ VR system +
+
+
+

+ THE NEW START OF +
+ VR LOCOMOTION +

+
+

+ Discover the most comprehensive VR Locomotion system, and unlock + infinite motion in any games on any platforms! +

+

1200$

+ + Play Video + +
+
+ +
+ + + More + +
+
+
Previous
+
Next
+
+
+
+
+
+
+
+ + + + + + + + + + + + + +
+
+
+
+
+

+ MORE THAN + GAMING! +

+

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

+
+
+ education +

EDUCATION

+

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

+
+
+ estate +

REAL ESTATE

+

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

+
+
+ fitness +

FITNESS

+

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

+
+
+ social +

SOCIAL INTERACTIONS

+

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

+
+
+
+
+
+
+
+
+

+ ABOUT + PRODUCT +

+
+
+
+
+
+
+ image in slider +
+
+
+
+ image in slider +
+
+
+
+ image in slider +
+
+
+
+ image in slider +
+
+
+
+ image in slider +
+
+ ... +
+
+
+
+
Previous
+
Next
+
+
+
+ +
+

+ ABOUT + PRODUCT +

+

+ 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. +

+ + Play Video + +
+
+

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 +

+
+
+
+
+
+
+
+
+

+ TECH + SPECS +

+
+

SENSOR

+

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

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

BATTERIES

+

+ Type: Lthium-lon polymer batteries +
+ Capacity: 370mAh +
+ Battery life: 10h of continuous use 150 hours on stand by +
+ 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 +
+

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 +
+

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 +
+

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! +

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

Have any questions?

+

+ GET IN + TOUCH +

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

+ Our manager will reply you within 15 minutes +

+ +
+
+
+ +
+ + diff --git a/package-lock.json b/package-lock.json index 87fcefd81..3fb897d39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,14 @@ "version": "1.0.0", "hasInstallScript": true, "license": "GPL-3.0", + "dependencies": { + "swiper": "^12.1.2" + }, "devDependencies": { "@linthtml/linthtml": "^0.9.6", "@mate-academy/bemlint": "latest", "@mate-academy/linthtml-config": "latest", - "@mate-academy/scripts": "^2.1.2", + "@mate-academy/scripts": "^2.1.3", "@mate-academy/stylelint-config": "latest", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", @@ -1510,10 +1513,11 @@ "dev": true }, "node_modules/@mate-academy/scripts": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-2.1.2.tgz", - "integrity": "sha512-gUXFdqqOfYzF9R3RSx2pCa5GLdOkxB9bFbF+dpUpzucdgGAANqOGdqpmNnMj+e3xA9YHraUWq3xo9cwe5vD9pQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-2.1.3.tgz", + "integrity": "sha512-a07wHTj/1QUK2Aac5zHad+sGw4rIvcNl5lJmJpAD7OxeSbnCdyI6RXUHwXhjF5MaVo9YHrJ0xVahyERS2IIyBQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/rest": "^17.11.2", "@types/get-port": "^4.2.0", @@ -7986,6 +7990,25 @@ "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, + "node_modules/swiper": { + "version": "12.1.2", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-12.1.2.tgz", + "integrity": "sha512-4gILrI3vXZqoZh71I1PALqukCFgk+gpOwe1tOvz5uE9kHtl2gTDzmYflYCwWvR4LOvCrJi6UEEU+gnuW5BtkgQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "license": "MIT", + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", diff --git a/package.json b/package.json index 7149ff15d..3195a0dee 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@linthtml/linthtml": "^0.9.6", "@mate-academy/bemlint": "latest", "@mate-academy/linthtml-config": "latest", - "@mate-academy/scripts": "^2.1.2", + "@mate-academy/scripts": "^2.1.3", "@mate-academy/stylelint-config": "latest", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", @@ -42,5 +42,8 @@ "tests": { "backstop": false } + }, + "dependencies": { + "swiper": "^12.1.2" } } diff --git a/src/images/about/about-style.png b/src/images/about/about-style.png new file mode 100644 index 000000000..5e7e5332c Binary files /dev/null and b/src/images/about/about-style.png differ diff --git a/src/images/about/ellipse-select.svg b/src/images/about/ellipse-select.svg new file mode 100644 index 000000000..8ce25b68c --- /dev/null +++ b/src/images/about/ellipse-select.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/about/ellipse.svg b/src/images/about/ellipse.svg new file mode 100644 index 000000000..6564bb55a --- /dev/null +++ b/src/images/about/ellipse.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/about/slider/about1.svg b/src/images/about/slider/about1.svg new file mode 100644 index 000000000..61bce041d --- /dev/null +++ b/src/images/about/slider/about1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/about/slider/about4.svg b/src/images/about/slider/about4.svg new file mode 100644 index 000000000..55817bc54 --- /dev/null +++ b/src/images/about/slider/about4.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/images/benefits/benefits1.svg b/src/images/benefits/benefits1.svg new file mode 100644 index 000000000..3d64d90f8 --- /dev/null +++ b/src/images/benefits/benefits1.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/benefits/benefits2.svg b/src/images/benefits/benefits2.svg new file mode 100644 index 000000000..b0ae17628 --- /dev/null +++ b/src/images/benefits/benefits2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/benefits/benefits3.svg b/src/images/benefits/benefits3.svg new file mode 100644 index 000000000..1b62826b1 --- /dev/null +++ b/src/images/benefits/benefits3.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/images/favicon.svg b/src/images/favicon.svg new file mode 100644 index 000000000..a42594520 --- /dev/null +++ b/src/images/favicon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/footer/facebook.svg b/src/images/footer/facebook.svg new file mode 100644 index 000000000..e4de883e6 --- /dev/null +++ b/src/images/footer/facebook.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/footer/reddit.svg b/src/images/footer/reddit.svg new file mode 100644 index 000000000..53bade5b8 --- /dev/null +++ b/src/images/footer/reddit.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/footer/x.svg b/src/images/footer/x.svg new file mode 100644 index 000000000..084900b8e --- /dev/null +++ b/src/images/footer/x.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/footer/youtube.svg b/src/images/footer/youtube.svg new file mode 100644 index 000000000..59b97532e --- /dev/null +++ b/src/images/footer/youtube.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/header/header.svg b/src/images/header/header.svg new file mode 100644 index 000000000..f6fd02646 --- /dev/null +++ b/src/images/header/header.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/header/polygon-accent.svg b/src/images/header/polygon-accent.svg new file mode 100644 index 000000000..1782f2a77 --- /dev/null +++ b/src/images/header/polygon-accent.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/header/polygon-white.svg b/src/images/header/polygon-white.svg new file mode 100644 index 000000000..a750c32e3 --- /dev/null +++ b/src/images/header/polygon-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/back.svg b/src/images/icons/back.svg new file mode 100644 index 000000000..6d4ea0730 --- /dev/null +++ b/src/images/icons/back.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/burger.svg b/src/images/icons/burger.svg new file mode 100644 index 000000000..8506fd7fc --- /dev/null +++ b/src/images/icons/burger.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/icons/close-accent.svg b/src/images/icons/close-accent.svg new file mode 100644 index 000000000..b5e212800 --- /dev/null +++ b/src/images/icons/close-accent.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/icons/close.svg b/src/images/icons/close.svg new file mode 100644 index 000000000..1e31cd1da --- /dev/null +++ b/src/images/icons/close.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/logo-katvr.svg b/src/images/logo-katvr.svg new file mode 100644 index 000000000..8f90be78b --- /dev/null +++ b/src/images/logo-katvr.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/more/more1.svg b/src/images/more/more1.svg new file mode 100644 index 000000000..62adf3e20 --- /dev/null +++ b/src/images/more/more1.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/images/more/more2.svg b/src/images/more/more2.svg new file mode 100644 index 000000000..dca2e94bf --- /dev/null +++ b/src/images/more/more2.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/more/more3.svg b/src/images/more/more3.svg new file mode 100644 index 000000000..104fb3db5 --- /dev/null +++ b/src/images/more/more3.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/images/more/more4.svg b/src/images/more/more4.svg new file mode 100644 index 000000000..5c9f3da71 --- /dev/null +++ b/src/images/more/more4.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/pay/visA.png b/src/images/pay/visA.png new file mode 100644 index 000000000..5cbc06f68 Binary files /dev/null and b/src/images/pay/visA.png differ diff --git a/src/images/play-video/play-video.svg b/src/images/play-video/play-video.svg new file mode 100644 index 000000000..d50af8dc1 --- /dev/null +++ b/src/images/play-video/play-video.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/scroll-up/scroll-up-hover.svg b/src/images/scroll-up/scroll-up-hover.svg new file mode 100644 index 000000000..38bdbf705 --- /dev/null +++ b/src/images/scroll-up/scroll-up-hover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/scroll-up/scroll-up.svg b/src/images/scroll-up/scroll-up.svg new file mode 100644 index 000000000..f246f3acc --- /dev/null +++ b/src/images/scroll-up/scroll-up.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/tech/circle-close.svg b/src/images/tech/circle-close.svg new file mode 100644 index 000000000..8d2f4fd2a --- /dev/null +++ b/src/images/tech/circle-close.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/images/tech/circle-open.svg b/src/images/tech/circle-open.svg new file mode 100644 index 000000000..6fee4ce3b --- /dev/null +++ b/src/images/tech/circle-open.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/tech/line1.svg b/src/images/tech/line1.svg new file mode 100644 index 000000000..0a169d2c3 --- /dev/null +++ b/src/images/tech/line1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/tech/line2.svg b/src/images/tech/line2.svg new file mode 100644 index 000000000..58bbd07a0 --- /dev/null +++ b/src/images/tech/line2.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/tech/line3.svg b/src/images/tech/line3.svg new file mode 100644 index 000000000..69725c29e --- /dev/null +++ b/src/images/tech/line3.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/tech/semicircle-line.svg b/src/images/tech/semicircle-line.svg new file mode 100644 index 000000000..2c6c31541 --- /dev/null +++ b/src/images/tech/semicircle-line.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/tech/tech.svg b/src/images/tech/tech.svg new file mode 100644 index 000000000..bb6bd2a9e --- /dev/null +++ b/src/images/tech/tech.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/scripts/components/changeLang.js b/src/scripts/components/changeLang.js new file mode 100644 index 000000000..1bda5cb82 --- /dev/null +++ b/src/scripts/components/changeLang.js @@ -0,0 +1,37 @@ +export function changeLang() { + const langItems = document.querySelectorAll('.lang__item'); + const languageItems = document.querySelectorAll('.language__item'); + const langButton = document.querySelector('.lang__button'); + + // Додамо лог, щоб побачити, чи знаходить JS елементи + console.log('Lang items found:', langItems.length, languageItems.length); + + const allNodes = [...langItems, ...languageItems]; + + allNodes.forEach((node) => { + node.addEventListener('click', (e) => { + // Якщо це посилання всередині
  • , зупиняємо перехід + if (e.target.tagName === 'A') e.preventDefault(); + + const selectedLang = node.dataset.lang; + console.log('Selected:', selectedLang); + + if (langButton) langButton.textContent = selectedLang; + + // Оновлюємо класи для ВСІХ знайдених елементів + allNodes.forEach(item => { + const isActive = item.dataset.lang === selectedLang; + // Визначаємо правильний префікс класу (lang або language) + const baseClass = item.classList.contains('lang__item') ? 'lang__item' : 'language__item'; + + item.classList.toggle(`${baseClass}--active`, isActive); + + // Оновлюємо посилання всередині, якщо воно є + const link = item.querySelector('a'); + if (link) { + link.classList.toggle('language__link--active', isActive); + } + }); + }); + }); +} diff --git a/src/scripts/components/chooseSelect.js b/src/scripts/components/chooseSelect.js new file mode 100644 index 000000000..28319f00c --- /dev/null +++ b/src/scripts/components/chooseSelect.js @@ -0,0 +1,66 @@ +const order = document.querySelector('.order'); + +const countSelect = document.querySelector('.count__select'); +const countList = document.querySelector('.count__list'); +const countItems = document.querySelectorAll('.count__item'); +const amount = document.querySelector('.order__amount'); + +const countriesSelect = document.querySelector('.countries__select'); +const countriesList = document.querySelector('.countries__list'); +const countriesItems = document.querySelectorAll('.countries__item'); + +const citiesSelect = document.querySelector('.cities__select'); +const citiesList = document.querySelector('.cities__list'); +const citiesItems = document.querySelectorAll('.cities__item'); + +export function closeDropdown() { + order.addEventListener('click', (e) => { + if (e.target !== countSelect) { + countList.classList.remove('count__list--active'); + } + + if (e.target !== countriesSelect) { + countriesList.classList.remove('countries__list--active'); + } + + if (e.target !== citiesSelect) { + citiesList.classList.remove('cities__list--active'); + } + }); +} + +export function chooseSelect() { + countItems.forEach((countItem) => + countItem.addEventListener('click', () => { + chooseSelectHandler(countItem, 'count', countSelect, countList); + + amount.textContent = `${+countItem.textContent * 1200}$`; + }), + ); + + countriesItems.forEach((countriesItem) => + countriesItem.addEventListener('click', () => { + chooseSelectHandler( + countriesItem, + 'countries', + countriesSelect, + countriesList, + ); + }), + ); + + citiesItems.forEach((citiesItem) => + citiesItem.addEventListener('click', () => { + chooseSelectHandler(citiesItem, 'cities', citiesSelect, citiesList); + }), + ); +} + +export function chooseSelectHandler(chosenItem, className, select, list) { + const itemActive = document.querySelector(`.${className}__item--active`); + + itemActive.classList.remove(`${className}__item--active`); + chosenItem.classList.add(`${className}__item--active`); + select.textContent = chosenItem.textContent; + list.classList.remove(`${className}__list--active`); +} diff --git a/src/scripts/components/closeOrder.js b/src/scripts/components/closeOrder.js new file mode 100644 index 000000000..fdc675c83 --- /dev/null +++ b/src/scripts/components/closeOrder.js @@ -0,0 +1,29 @@ +const orderStages = document.querySelectorAll('.order__item'); +const orderImage = document.querySelector('.order__image'); +const orderInfo = document.querySelector('.order__info'); +const orderForm = document.querySelector('.order__form'); +const payForm = document.querySelector('.order__pay'); +const complete = document.querySelector('.order__complete'); + +const orderLogo = document.querySelector('.order__logo'); +const orderIconClose = document.querySelector('.order__icon'); +const completeButton = document.querySelector('.complete__button'); +const placeOrder = document.querySelector('.order__item--place-order'); + +export function closeOrder() { + orderLogo.addEventListener('click', closeOrderHandler); + orderIconClose.addEventListener('click', closeOrderHandler); + completeButton.addEventListener('click', closeOrderHandler); + placeOrder.addEventListener('click', closeOrderHandler); +} + +function closeOrderHandler() { + orderForm.classList.add('order__form--active'); + payForm.classList.remove('order__pay--active'); + complete.classList.remove('order__complete--active'); + orderStages[0].classList.add('order__item--active'); + orderStages[1].classList.remove('order__item--active'); + orderStages[2].classList.remove('order__item--active'); + orderImage.classList.remove('order__image--complete'); + orderInfo.classList.remove('order__info--complete'); +} diff --git a/src/scripts/components/formValidation.js b/src/scripts/components/formValidation.js new file mode 100644 index 000000000..2386f9b36 --- /dev/null +++ b/src/scripts/components/formValidation.js @@ -0,0 +1,201 @@ +import { chooseSelectHandler } from "./chooseSelect"; + +export function formValidation() { + const contactForm = document.querySelector('.contact__form'); + const contactInputs = document.querySelectorAll('.contact__input'); + + const orderForm = document.querySelector('.order__form'); + const orderInputs = document.querySelectorAll('.order__input'); + const requiredOrderInputs = [...orderInputs].filter((input) => { + return input.hasAttribute('required'); + }); + const orderStages = document.querySelectorAll('.order__item'); + const orderImage = document.querySelector('.order__image'); + const orderInfo = document.querySelector('.order__info'); + + const payForm = document.querySelector('.order__pay'); + const payInputs = document.querySelectorAll('.pay__input'); + + const countSelect = document.querySelector('.count__select'); + const countList = document.querySelector('.count__list'); + const countItem = document.querySelectorAll('.count__item')[0]; + const amount = document.querySelector('.order__amount'); + + const complete = document.querySelector('.order__complete'); + + let error = false; + + function errorAction(input, label) { + error = true; + input.classList.add('form__input--error'); + label.classList.add('form__label--error'); + } + + function inputValidation(input) { + const field = input.closest('.form__field'); + const label = field.querySelector('.form__label'); + + if (!input.value.trim()) { + errorAction(input, label); + label.textContent = `Please, fill your ${normalizeName(input.name)}*`; + + return; + } else { + error = false; + label.textContent = `${input.name[0].toUpperCase()}${normalizeName(input.name).slice(1)}*`; + input.classList.remove('form__input--error'); + label.classList.remove('form__label--error'); + } + + if (input.name === 'email' && input.value.indexOf('@') === -1) { + errorAction(input, label); + label.textContent = `Incorrect format of ${input.name}*`; + } + + if (input.name === 'phone') { + const phoneSymbols = '+()- 0123456789'; + + for (const char of input.value) { + if (!phoneSymbols.includes(char)) { + errorAction(input, label); + label.textContent = `Incorrect format of ${input.name}*`; + break; + } + } + } + + if (input.name === 'cardNumber') { + if (input.value.length < 16) { + errorAction(input, label); + label.textContent = `Incorrect format of ${input.name}*`; + } + const cardSymbols = ' 0123456789'; + + for (const char of input.value) { + if (!cardSymbols.includes(char)) { + errorAction(input, label); + label.textContent = `Incorrect format of ${normalizeName(input.name)}*`; + break; + } + } + } + + if (input.name === 'expirationDate') { + if (input.value.length !== 5) { + errorAction(input, label); + label.textContent = `Incorrect format of ${input.name}*`; + } + + const expirationDateSymbols = '/0123456789'; + + for (const char of input.value) { + if (!expirationDateSymbols.includes(char)) { + errorAction(input, label); + label.textContent = `Incorrect format of ${normalizeName(input.name)}*`; + break; + } + } + } + + if (input.name === 'cvv') { + if (input.value.length !== 3) { + errorAction(input, label); + label.textContent = `Incorrect format of ${input.name}*`; + } + + const cvvSymbols = '0123456789'; + + for (const char of input.value) { + if (!cvvSymbols.includes(char)) { + errorAction(input, label); + label.textContent = `Incorrect format of ${input.name}*`; + break; + } + } + } + } + + contactInputs.forEach((input) => { + input.addEventListener('blur', () => { + inputValidation(input); + }); + }); + + requiredOrderInputs.forEach((input) => { + input.addEventListener('blur', () => { + inputValidation(input); + }); + }); + + payInputs.forEach((input) => { + input.addEventListener('blur', () => { + inputValidation(input); + }); + }); + + function onSubmitContactForm(eventSubmit) { + eventSubmit.preventDefault(); + contactInputs.forEach((input) => { + inputValidation(input); + }); + if (error) { + return; + } + contactForm.reset(); + } + + function onSubmitOrderForm(eventSubmit) { + eventSubmit.preventDefault(); + requiredOrderInputs.forEach((input) => { + inputValidation(input); + }); + if (error) { + return; + } + + orderForm.classList.remove('order__form--active'); + payForm.classList.add('order__pay--active'); + orderStages[0].classList.remove('order__item--active'); + orderStages[1].classList.add('order__item--active'); + } + + function onSubmitPayForm(eventSubmit) { + eventSubmit.preventDefault(); + payInputs.forEach((input) => { + inputValidation(input); + }); + if (error) { + return; + } + payForm.classList.remove('order__pay--active'); + complete.classList.add('order__complete--active'); + orderStages[1].classList.remove('order__item--active'); + orderStages[2].classList.add('order__item--active'); + orderImage.classList.add('order__image--complete'); + orderInfo.classList.add('order__info--complete'); + + chooseSelectHandler(countItem, 'count', countSelect, countList); + amount.textContent = '1200$'; + + orderForm.reset(); + payForm.reset(); + } + + contactForm.addEventListener('submit', onSubmitContactForm); + orderForm.addEventListener('submit', onSubmitOrderForm); + payForm.addEventListener('submit', onSubmitPayForm); +} + +function normalizeName(inputId) { + let normalizedName = ''; + + for (const char of inputId) { + if (char === char.toUpperCase()) { + normalizedName += ' ' + char.toLowerCase(); + } else { + normalizedName += char; + } + } + + return normalizedName; +} diff --git a/src/scripts/components/openDetails.js b/src/scripts/components/openDetails.js new file mode 100644 index 000000000..144de487d --- /dev/null +++ b/src/scripts/components/openDetails.js @@ -0,0 +1,44 @@ +const circles = document.querySelectorAll('.tech__circle'); +const firstCircle = document.querySelector('.tech__circle--1'); +const secondCircle = document.querySelector('.tech__circle--2'); +const thirdCircle = document.querySelector('.tech__circle--3'); + +const firstDetails = document.querySelector('.tech__details--1'); +const secondDetails = document.querySelector('.tech__details--2'); +const thirdDetails = document.querySelector('.tech__details--3'); + +function findSelectedDetails(circle) { + if (circle === firstCircle) { + return firstDetails; + } + if (circle === secondCircle) { + return secondDetails; + } + if (circle === thirdCircle) { + return thirdDetails; + } +} + +export function openDetails() { + circles.forEach((circle) => { + circle.addEventListener('click', () => { + const selectedDatails = findSelectedDetails(circle); + + if (circle.classList.contains('tech__circle--active')) { + circle.classList.remove('tech__circle--active'); + selectedDatails.classList.remove('tech__details--active'); + } else { + const activeCircle = document.querySelector('.tech__circle--active'); + if (activeCircle) { + activeCircle.classList.remove('tech__circle--active'); + + const activeDetails = findSelectedDetails(activeCircle); + activeDetails.classList.remove('tech__details--active'); + } + + circle.classList.add('tech__circle--active'); + selectedDatails.classList.add('tech__details--active'); + } + }); + }); +} diff --git a/src/scripts/components/openQuestion.js b/src/scripts/components/openQuestion.js new file mode 100644 index 000000000..12da023a5 --- /dev/null +++ b/src/scripts/components/openQuestion.js @@ -0,0 +1,27 @@ +const questions = document.querySelectorAll('.faq__question'); +const iconClose = document.querySelector('.faq__icon'); + +export function openQuestion() { + questions.forEach((question) => { + question.addEventListener('click', () => { + const wrapper = question.querySelector('.faq__info'); + + if (wrapper.classList.contains('faq__info--active')) { + wrapper.classList.remove('faq__info--active'); + } else { + closeActiveQuestion(); + + wrapper.classList.add('faq__info--active'); + } + }); + }); + + iconClose.addEventListener('click', closeActiveQuestion); +} + +function closeActiveQuestion() { + const activeQuestion = document.querySelector('.faq__info--active'); + if (activeQuestion) { + activeQuestion.classList.remove('faq__info--active'); + } +} diff --git a/src/scripts/components/playVideo.js b/src/scripts/components/playVideo.js new file mode 100644 index 000000000..bb2f3379d --- /dev/null +++ b/src/scripts/components/playVideo.js @@ -0,0 +1,19 @@ +export function playVideo() { + const video = document.querySelector('.video'); + const playVideo = document.querySelectorAll('.play-video'); + const videoClose = document.querySelector('.video__close'); + + playVideo.forEach((buttonPlayVideo) => { + buttonPlayVideo.addEventListener('click', () => { + video.classList.add('video--active'); + }); + }); + + videoClose.addEventListener('click', () => { + video.classList.remove('video--active'); + }); + + video.addEventListener('click', () => { + video.classList.remove('video--active'); + }); +} diff --git a/src/scripts/components/scrollUp.js b/src/scripts/components/scrollUp.js new file mode 100644 index 000000000..32781e095 --- /dev/null +++ b/src/scripts/components/scrollUp.js @@ -0,0 +1,11 @@ +export function scrollUp() { + const scrollUpButton = document.querySelector('.scroll-up'); + + window.addEventListener('scroll', () => { + if (window.scrollY > 100) { + scrollUpButton.classList.add('scroll-up--active'); + } else { + scrollUpButton.classList.remove('scroll-up--active'); + } + }); +} diff --git a/src/scripts/components/swiper.js b/src/scripts/components/swiper.js new file mode 100644 index 000000000..8cfdac291 --- /dev/null +++ b/src/scripts/components/swiper.js @@ -0,0 +1,50 @@ +import Swiper from 'swiper'; +import { Navigation, Pagination, Scrollbar, Autoplay, Controller} from 'swiper/modules'; +import 'swiper/css'; +import 'swiper/css/navigation'; +import 'swiper/css/pagination'; +import 'swiper/css/scrollbar'; + +export const headerSlider = new Swiper('.header__slider', { + modules: [Navigation, Scrollbar, Autoplay], + autoHeight: true, + grabCursor: true, + navigation: { + nextEl: ".swiper-button-next-header", + prevEl: ".swiper-button-prev-header", + }, + scrollbar: { + el: ".swiper-scrollbar-header", + }, + autoplay: { + delay: 2500, + disableOnInteraction: false, + }, +}); + +export const slider = new Swiper('.slider', { + modules: [Navigation, Pagination, Scrollbar, Controller], + autoHeight: true, + grabCursor: true, + pagination: { + el: ".swiper-pagination", + clickable: true, + }, + navigation: { + nextEl: ".swiper-button-next-out", + prevEl: ".swiper-button-prev-out", + }, + scrollbar: { + el: ".swiper-scrollbar", + }, +}); + +export const sliderFraction = new Swiper('.slider', { + modules: [Pagination], + pagination: { + el: ".swiper-pagination--fraction", + type: "fraction", + }, +}); + +slider.controller.control = sliderFraction; diff --git a/src/scripts/components/toggleList.js b/src/scripts/components/toggleList.js new file mode 100644 index 000000000..bffaee6a7 --- /dev/null +++ b/src/scripts/components/toggleList.js @@ -0,0 +1,23 @@ + +const langButton = document.querySelector('.lang__button'); +const langList = document.querySelector('.lang__list'); +const countList = document.querySelector('.count__list'); +const countButton = document.querySelector('.count__select'); +const countriesButton = document.querySelector('.countries__select'); +const countriesList = document.querySelector('.countries__list'); +const citiesButton = document.querySelector('.cities__select'); +const citiesList = document.querySelector('.cities__list'); + + +export function toggleList() { + toggleListHandler(langButton, langList, 'lang__list--active'); + toggleListHandler(countButton, countList, 'count__list--active'); + toggleListHandler(countriesButton, countriesList, 'countries__list--active'); + toggleListHandler(citiesButton, citiesList, 'cities__list--active'); +} + +function toggleListHandler(elementClick, elementList, activeClass) { + elementClick.addEventListener('click', () => { + elementList.classList.toggle(activeClass); + }); +} diff --git a/src/scripts/main.js b/src/scripts/main.js index ad9a93a7c..60c5088fe 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1 +1,28 @@ 'use strict'; + +import { scrollUp } from './components/scrollUp.js'; +import { playVideo } from './components/playVideo.js'; +import { changeLang } from './components/changeLang.js'; +import { openDetails } from './components/openDetails.js'; +import { formValidation } from './components/formValidation.js'; +import { openQuestion } from './components/openQuestion.js'; +import { slider, sliderFraction, headerSlider } from './components/swiper.js'; +import { toggleList } from './components/toggleList.js'; +import { closeDropdown } from './components/chooseSelect.js'; +import { chooseSelect } from './components/chooseSelect.js'; +import { closeOrder } from './components/closeOrder.js'; + + + +document.addEventListener('DOMContentLoaded', () => { + scrollUp(); + playVideo(); + changeLang(); + openQuestion(); + openDetails(); + toggleList(); + closeDropdown(); + formValidation(); + chooseSelect(); + closeOrder(); +}); diff --git a/src/styles/_fonts.scss b/src/styles/_fonts.scss index 619b8c52b..e54998b6e 100644 --- a/src/styles/_fonts.scss +++ b/src/styles/_fonts.scss @@ -1,6 +1,6 @@ @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; + src: url('../fonts/FontFont_FF.Mark.Pro.otf') format('otf'); } diff --git a/src/styles/blocks/about.scss b/src/styles/blocks/about.scss new file mode 100644 index 000000000..e6a32eb06 --- /dev/null +++ b/src/styles/blocks/about.scss @@ -0,0 +1,231 @@ +.about { + background: $color-gradient; + + &__container { + padding-block: 50px; + + @include on-tablet { + @include page-grid; + + overflow: hidden; + row-gap: 84px; + padding-block: 70px; + } + + @include on-desktop { + row-gap: 226px; + padding-block: 100px; + } + + @include on-design { + row-gap: 220px; + padding-block: 150px; + } + } + + &__slider { + position: relative; + margin-bottom: 20px; + + @include on-tablet { + grid-column: span 3; + } + + @include on-desktop { + grid-column: 3/8; + } + + @include on-design { + grid-column: 4/11; + } + } + + &__img { + display: block; + width: 100%; + margin-bottom: 14px; + object-fit: contain; + + @include on-tablet { + aspect-ratio: 1 / 0.85; + object-fit: cover; + } + + @include on-desktop { + aspect-ratio: auto; + } + + @include on-design { + aspect-ratio: 3 / 1.3; + } + } + + &__boolets { + @include on-desktop { + display: none; + } + } + + &__navigation { + display: none; + + @include on-desktop { + display: flex; + justify-content: space-between; + width: 50%; + margin-bottom: 10px; + } + } + + &__scrollbar { + display: none; + + @include on-desktop { + display: block; + } + } + + &__switch { + display: flex; + gap: 6px; + justify-content: center; + + @include on-desktop { + display: none; + } + } + + &__main { + @include on-tablet { + grid-column: span 3; + } + + @include on-desktop { + grid-column: 9/-1; + } + + @include on-design { + grid-column: 12/-1; + } + } + + &__title { + margin-bottom: 20px; + + &--before { + @include on-tablet { + display: none; + } + } + + &--after { + display: none; + + @include on-tablet { + display: block; + margin-bottom: 30px; + } + } + } + + &__text { + padding-bottom: 24px; + } + + &__play-video { + margin-top: 14px; + margin-bottom: 107px; + + @include on-tablet { + margin-top: 20px; + margin-bottom: 0; + } + } + + &__additional { + @include on-tablet { + grid-column: span 4; + } + + @include on-desktop { + grid-column: span 5; + } + + @include on-design { + grid-column: 2/8; + } + } + + &__hello { + margin-bottom: 11px; + font-size: 14px; + line-height: 130%; + color: $color-accent; + } + + &__subtitle { + margin-bottom: 22px; + } + + &__picture-style { + display: none; + + @include on-tablet { + display: block; + grid-column: span 2; + + background-image: url(../images/about/about-style.png); + background-repeat: no-repeat; + background-size: auto 100%; + } + + @include on-desktop { + transform: scale(1, 1.2); + grid-column: 7/-1; + } + + @include on-design { + grid-column: 9/-1; + } + } + + .swiper-pagination { + --swiper-pagination-bullet-size: 4px; + --swiper-pagination-color: #ababab; + --swiper-pagination-bullet-inactive-color: #484848; + --swiper-pagination-bullet-inactive-opacity: 1; + --swiper-pagination-bottom: 0; + + font-size: 4px; + line-height: 1; + } + + .swiper-pagination-fraction { + --swiper-pagination-bottom: 1; + + transform: translate(calc(-55% - 20px)); + font-size: 14px; + line-height: 1.21; + color: $color-accent; + } + + .swiper-scrollbar { + --swiper-scrollbar-bg-color: #212121; + --swiper-scrollbar-size: 2px; + --swiper-scrollbar-bottom: 0; + --swiper-scrollbar-sides-offset: 25%; + + transform: translate(-50%); + } + + .swiper-button-next-out, + .swiper-button-prev-out { + cursor: pointer; + color: $color-white; + } + + .swiper-button-disabled { + cursor: no-drop; + color: $color-text; + } +} diff --git a/src/styles/blocks/accent-title.scss b/src/styles/blocks/accent-title.scss new file mode 100644 index 000000000..645700e5a --- /dev/null +++ b/src/styles/blocks/accent-title.scss @@ -0,0 +1,4 @@ +.accent-title { + font-weight: 400; + color: $color-accent; +} diff --git a/src/styles/blocks/benefits.scss b/src/styles/blocks/benefits.scss new file mode 100644 index 000000000..fa23859ba --- /dev/null +++ b/src/styles/blocks/benefits.scss @@ -0,0 +1,141 @@ +.benefits { + background: $color-gradient; + + &__content { + padding-block: 50px; + + @include on-tablet { + padding-block: 70px; + } + + @include on-desktop { + padding-block: 100px; + } + + @include on-design { + padding-block: 160px; + } + } + + &__title { + margin-bottom: 32px; + + @include on-desktop { + margin-bottom: 84px; + text-align: center; + } + + @include on-design { + margin-bottom: 82px; + } + } + + &__container { + @include page-grid; + + row-gap: 20px; + + @include on-design { + justify-content: space-between; + } + } + + &__benefit { + grid-column: 1/-1; + padding: 5px; + border: solid 1px transparent; + border-radius: 4px; + + @include hover(border, solid 1px $color-accent); + @include hover(box-shadow, 0 0 10px 5px $color-accent); + + @include on-tablet { + grid-column: span 2; + } + + @include on-desktop { + grid-column: span 4; + } + + &:first-child { + @include on-design { + grid-column: 1 / span 4; + } + } + + &:nth-child(2) { + @include on-design { + grid-column: 7 / span 4; + } + } + + &:nth-child(3) { + @include on-design { + grid-column: 13 / span 4; + } + } + } + + // &__picture { + // display: block; + // width: 100%; + // } + + &__image { + display: none; + + @include on-tablet { + display: block; + + // margin-bottom: 26px; + // object-position: center; + margin: auto; + margin-bottom: 26px; + } + + @include on-desktop { + margin-bottom: 30px; + } + } + + &__description { + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 4; + line-clamp: 4; + + text-overflow: ellipsis; + + @include hover(display, block); + + @include on-desktop { + display: block; + } + } + + &__subtitle { + margin-bottom: 11px; + + font-size: 18px; + font-weight: 900; + line-height: 105%; + color: $color-white; + + @include on-tablet { + font-size: 16px; + line-height: 120%; + text-align: center; + } + + @include on-desktop { + margin-bottom: 16px; + } + } + + &__text { + @include on-tablet { + text-align: center; + } + } +} diff --git a/src/styles/blocks/button.scss b/src/styles/blocks/button.scss new file mode 100644 index 000000000..8ee23012e --- /dev/null +++ b/src/styles/blocks/button.scss @@ -0,0 +1,32 @@ +.button { + z-index: 3; + + display: block; + + width: 100%; + max-width: 280px; + padding-block: 11px; + border-radius: 4px; + + font-size: 14px; + font-weight: 500; + line-height: 130%; + color: $color-white; + text-align: center; + text-decoration: none; + + background-color: $color-accent; + + @include hover(box-shadow, 0 0 10px 5px $color-accent); + + @include on-tablet { + max-width: 458px; + padding-block: 13px; + font-size: 16px; + } + + &:active { + color: $color-accent; + background-color: $color-white; + } +} diff --git a/src/styles/blocks/cities.scss b/src/styles/blocks/cities.scss new file mode 100644 index 000000000..77b472e24 --- /dev/null +++ b/src/styles/blocks/cities.scss @@ -0,0 +1,18 @@ +.cities { + &__list { + display: none; + + &--active { + display: block; + } + } + + &__item { + padding-left: 24px; + padding-block: 5px; + + &--active { + display: none; + } + } +} diff --git a/src/styles/blocks/complete.scss b/src/styles/blocks/complete.scss new file mode 100644 index 000000000..c188b05c8 --- /dev/null +++ b/src/styles/blocks/complete.scss @@ -0,0 +1,19 @@ +.complete { + color: $color-white; + text-align: center; + + &__title { + margin-top: 90px; + margin-bottom: 16px; + font-size: 26px; + text-transform: uppercase; + } + + &__text { + margin-bottom: 30px; + } + + &__button { + margin: auto; + } +} diff --git a/src/styles/blocks/contact.scss b/src/styles/blocks/contact.scss new file mode 100644 index 000000000..56e1a7fac --- /dev/null +++ b/src/styles/blocks/contact.scss @@ -0,0 +1,118 @@ +.contact { + background-color: $color-black; + + &__container { + @include page-grid; + + padding-block: 50px; + + @include on-tablet { + padding-top: 70px; + padding-bottom: 130px; + } + + @include on-desktop { + padding-block: 100px; + } + + @include on-design { + padding-top: 160px; + padding-bottom: 205px; + } + } + + &__title { + grid-column: 1/-1; + margin-bottom: 32px; + + @include on-tablet { + grid-column: 1/4; + margin-bottom: 50px; + } + + @include on-desktop { + grid-column: span 6; + margin-bottom: 26px; + } + + @include on-design { + grid-column: span 8; + } + } + + &__subtitle { + // grid-column: 1/-1; + margin-bottom: 11px; + font-size: 14px; + color: $color-accent; + + @include on-desktop { + margin-bottom: 13px; + } + } + + &__form { + margin-bottom: 30px; + + @include on-tablet { + grid-column: 4/-1; + grid-row: span 4; + margin-bottom: 0; + } + + @include on-desktop { + grid-column: span 6; + } + + @include on-design { + grid-column: span 8; + } + } + + &__button { + @include on-tablet { + width: 200px; + margin-top: 24px; + } + + @include on-desktop { + margin-top: 66px; + } + + @include on-desktop { + margin-top: 26px; + } + } + + &__text { + grid-column: 1/-1; + font-size: 12px; + + @include on-tablet { + grid-column: 1/4; + margin-bottom: 76px; + } + + @include on-desktop { + grid-column: span 6; + } + } + + &__contacts { + display: none; + + @include on-tablet { + display: flex; + grid-column: 1/4; + flex-direction: column; + gap: 8px; + } + } + + &__link { + color: inherit; + text-decoration: none; + + @include hover(color, $color-accent); + } +} diff --git a/src/styles/blocks/container.scss b/src/styles/blocks/container.scss new file mode 100644 index 000000000..244ccc355 --- /dev/null +++ b/src/styles/blocks/container.scss @@ -0,0 +1,3 @@ +.container { + @include content-padding-inline; +} diff --git a/src/styles/blocks/count.scss b/src/styles/blocks/count.scss new file mode 100644 index 000000000..20622dd69 --- /dev/null +++ b/src/styles/blocks/count.scss @@ -0,0 +1,15 @@ +.count { + &__list { + display: none; + + &--active { + display: block; + } + } + + &__item { + &--active { + background-color: $color-hover-background; + } + } +} diff --git a/src/styles/blocks/countries.scss b/src/styles/blocks/countries.scss new file mode 100644 index 000000000..3b1982d17 --- /dev/null +++ b/src/styles/blocks/countries.scss @@ -0,0 +1,17 @@ +.countries { + &__list { + display: none; + + &--active { + display: block; + } + } + + &__item { + padding-left: 24px; + padding-block: 5px; + &--active { + display: none; + } + } +} diff --git a/src/styles/blocks/dropdown.scss b/src/styles/blocks/dropdown.scss new file mode 100644 index 000000000..a9e19dee2 --- /dev/null +++ b/src/styles/blocks/dropdown.scss @@ -0,0 +1,18 @@ +.dropdown { + border: solid 1px $color-accent; + border-radius: 4px; + + list-style: none; + + background-color: $color-background; + box-shadow: 0 0 10px 2px $color-accent; + + &__item { + cursor: pointer; + border-radius: 4px; + color: $color-white; + + @include hover(color, $color-accent); + @include hover(background-color, $color-hover-background); + } +} diff --git a/src/styles/blocks/faq.scss b/src/styles/blocks/faq.scss new file mode 100644 index 000000000..e9c6eb0cf --- /dev/null +++ b/src/styles/blocks/faq.scss @@ -0,0 +1,108 @@ +.faq { + z-index: 4; + overflow: scroll; + + &__wrapper { + background-color: $color-background; + + @include on-desktop { + width: 880px; + margin-top: 7%; + margin-inline: auto; + } + + @include on-design { + width: 1280px; + } + } + + &__content { + position: relative; + height: 100vh; + padding-bottom: 60px; + + @include on-desktop { + height: fit-content; + } + } + + &__icon { + position: absolute; + right: 0; + + display: block; + + width: 17px; + height: 17px; + margin-top: 20px; + + background-image: url(../../images/icons/close.svg); + background-size: cover; + + @include hover(transform, scale($scale-size)); + } + + &__title { + margin-bottom: 30px; + padding-top: 68px; + + font-size: 21px; + font-weight: 900; + line-height: 130%; + color: $color-white; + + @include on-desktop { + font-size: 36px; + } + } + + &__questions { + display: flex; + flex-direction: column; + gap: 13px; + + @include on-tablet { + margin-bottom: 50px; + } + } + + &__question { + cursor: pointer; + padding: 20px 12px 12px; + border: solid 1px $color-accent; + border-radius: 4px; + } + + &__subtitle { + margin-bottom: 18px; + color: $color-accent; + } + + &__info { + display: none; + + &--active { + display: block; + } + } + + &__answer { + margin-bottom: 10px; + padding-bottom: 24px; + } + + &__update { + padding-left: 2px; + font-size: 12px; + color: #545454; + } + + &__more { + display: none; + + @include on-tablet { + display: block; + text-align: center; + } + } +} diff --git a/src/styles/blocks/footer.scss b/src/styles/blocks/footer.scss new file mode 100644 index 000000000..797508e04 --- /dev/null +++ b/src/styles/blocks/footer.scss @@ -0,0 +1,110 @@ +.footer { + background-color: #000; + + &__content { + @include page-grid; + + padding-top: 45px; + padding-bottom: 50px; + + @include on-tablet { + display: flex; + align-items: baseline; + justify-content: space-between; + } + } + + &__logo { + grid-column: 1/-1; + margin-bottom: 15px; + } + + &__nav { + grid-column: 1; + grid-row: 2/4; + } + + &__list { + display: flex; + flex-direction: column; + gap: 12px; + list-style: none; + + @include on-tablet { + flex-direction: row; + gap: 40px; + } + } + + &__link { + font-size: 13px; + color: $color-white; + text-decoration: none; + + @include hover(color, $color-accent); + + @include on-tablet { + font-size: 14px; + } + } + + &__contacts { + display: flex; + grid-column: 2; + flex-direction: column; + gap: 12px; + + margin-bottom: 22px; + + @include on-tablet { + display: none; + } + } + + &__contact { + font-size: 13px; + color: inherit; + text-decoration: none; + + @include hover(color, $color-accent); + } + + &__social-medias { + display: flex; + grid-column: 2; + gap: 18px; + + @include on-design { + gap: 28px; + } + } + + &__icon { + display: block; + + width: 20px; + height: 20px; + + background-repeat: no-repeat; + background-position: bottom; + background-size: contain; + + @include hover(transform, scale($scale-size)); + } + + &__icon--facebook { + background-image: url(../images/footer/facebook.svg); + } + + &__icon--x { + background-image: url(../images/footer/x.svg); + } + + &__icon--youtube { + background-image: url(../images/footer/youtube.svg); + } + + &__icon--reddit { + background-image: url(../images/footer/reddit.svg); + } +} diff --git a/src/styles/blocks/form.scss b/src/styles/blocks/form.scss new file mode 100644 index 000000000..ffb2f1f3a --- /dev/null +++ b/src/styles/blocks/form.scss @@ -0,0 +1,96 @@ +.form { + display: flex; + grid-column: 1/-1; + flex-direction: column; + gap: 24px; + + &__label { + font-size: 14px; + + &--error { + color: $color-error; + } + } + + &__field { + display: flex; + flex-direction: column; + + &:focus-within .form__label { + color: $color-accent; + } + } + + &__input { + resize: none; + + width: 100%; + border: none; + border-bottom: solid 1px $color-gray; + + font-size: 18px; + color: $color-white; + + background-color: inherit; + outline: none; + caret-color: $color-accent; + + @include on-tablet { + font-size: 20px; + } + + &:focus { + border-bottom: solid 1px $color-accent; + } + + &--error { + border-bottom: solid 1px $color-error; + } + } + + &__select { + position: relative; + } + + &__select-input { + padding-left: 24px; + padding-block: 13px; + } + + &__dropdown { + position: absolute; + z-index: 4; + top: 56px; + width: 100%; + } + + &__button { + cursor: pointer; + border: none; + } +} + +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +textarea:-webkit-autofill, +textarea:-webkit-autofill:hover, +textarea:-webkit-autofill:focus, +select:-webkit-autofill, +select:-webkit-autofill:hover, +select:-webkit-autofill:focus { + border: none; + border-bottom: solid 1px $color-gray; + + color-scheme: dark; + background-color: inherit; + -webkit-box-shadow: none; + + transition: background-color 5000s ease-in-out 0s; + + -webkit-text-fill-color: $color-white; + + &:focus { + border-bottom: solid 1px $color-accent; + } +} diff --git a/src/styles/blocks/header.scss b/src/styles/blocks/header.scss new file mode 100644 index 000000000..f72c91777 --- /dev/null +++ b/src/styles/blocks/header.scss @@ -0,0 +1,171 @@ +.header { + background: $color-gradient; + + &__content { + padding-bottom: 46px; + + @include on-desktop { + padding-bottom: 84px; + } + + @include on-design { + padding-bottom: 107px; + } + } + + &__top { + @include on-tablet { + margin-bottom: 25px; + } + } + + &__container { + @include on-tablet { + @include page-grid; + + grid-template-rows: auto; + } + + @include on-desktop { + margin-bottom: 84px; + } + } + + &__slider { + display: flex; + padding-block: 10px; + + @include on-tablet { + overflow: hidden; + display: flex; + grid-column: 4/-1; + grid-row: span 2; + order: 1; + } + + @include on-desktop { + grid-column: 7/-1; + } + } + + &__image { + transform: scale(1.1); + display: block; + width: 100%; + object-fit: contain; + } + + &__title { + margin-bottom: 17px; + + font-size: 26px; + font-weight: 900; + line-height: 130%; + color: $color-white; + + @include on-tablet { + grid-column: 1/4; + order: 0; + } + + @include on-desktop { + grid-column: 1/7; + font-size: 46px; + } + } + + &__info { + @include on-tablet { + grid-column: 1/4; + order: 2; + } + + @include on-desktop { + grid-column: 2/6; + } + } + + &__description { + margin-bottom: 8px; + font-weight: 500; + + @include on-tablet { + margin-bottom: 10px; + } + } + + &__price { + margin-bottom: 16px; + + font-size: 18px; + font-weight: 500; + color: $color-white; + text-align: center; + + @include on-tablet { + margin-bottom: 24px; + } + + @include on-desktop { + margin-bottom: 20px; + text-align: left; + } + } + + &__bottom { + display: none; + font-weight: 500; + color: $color-white; + + @include on-desktop { + display: flex; + justify-content: space-between; + } + } + + &__qa { + display: flex; + gap: 40px; + } + + &__link { + color: inherit; + text-decoration: none; + + @include hover(color, $color-accent); + } + + &__navigation { + display: flex; + flex-direction: column; + gap: 10px; + } + + &__switch-photo { + position: relative; + display: flex; + gap: 103px; + } + + &__scrollbar { + height: 1px; + } + + .swiper-button-next-header, + .swiper-button-prev-header { + cursor: pointer; + color: $color-white; + } + + .swiper-button-disabled { + cursor: no-drop; + color: $color-text; + } + + .swiper-scrollbar-header { + --swiper-scrollbar-size: 2px; + --swiper-scrollbar-bottom: 0; + + background-color: #212121; + } +} diff --git a/src/styles/blocks/help.scss b/src/styles/blocks/help.scss new file mode 100644 index 000000000..47a4cd249 --- /dev/null +++ b/src/styles/blocks/help.scss @@ -0,0 +1,110 @@ +.help { + z-index: 4; + + &__wrapper { + background-color: $color-background; + + @include on-desktop { + width: 880px; + margin-top: 10%; + margin-inline: auto; + } + + @include on-design { + width: 1280px; + } + } + + &__content { + position: relative; + + display: flex; + flex-direction: column; + gap: 30px; + + height: 100vh; + + @include on-desktop { + height: fit-content; + } + } + + &__icon { + position: absolute; + right: 0; + + display: block; + + width: 17px; + height: 17px; + margin-top: 20px; + + background-image: url(../images/icons/close.svg); + background-size: cover; + + @include hover(transform, scale($scale-size)); + } + + &__title { + padding-top: 68px; + + font-size: 21px; + font-weight: 900; + line-height: 130%; + color: $color-white; + } + + &__description { + display: flex; + flex-direction: column; + gap: 24px; + } + + &__bottom { + display: flex; + flex-direction: column; + gap: 30px; + + @include on-tablet { + flex-direction: row; + gap: 152px; + margin-bottom: 80px; + } + + @include on-desktop { + gap: 70px; + } + } + + &__list { + display: flex; + flex-direction: column; + gap: 20px; + list-style: none; + } + + &__link { + color: $color-accent; + text-decoration: none; + + @include hover(color, $color-white); + } + + &__contacts { + display: flex; + flex-direction: column; + gap: 11px; + + @include on-tablet { + gap: 25px; + } + } + + &__contact { + line-height: 1.19; + color: inherit; + text-decoration: none; + + @include hover(color, $color-white); + } +} diff --git a/src/styles/blocks/lang.scss b/src/styles/blocks/lang.scss new file mode 100644 index 000000000..5018dc9a3 --- /dev/null +++ b/src/styles/blocks/lang.scss @@ -0,0 +1,68 @@ +.lang { + &__button { + cursor: pointer; + + padding: 0 10px 0 0; + border: none; + + font-size: 16px; + + background-color: inherit; + + @include on-desktop { + position: relative; + color: $color-accent; + + @include hover(color, $color-white); + + &::after { + content: ''; + + position: absolute; + right: -15px; + bottom: 4px; + + display: block; + + width: 100%; + height: 6px; + + background-image: url(../images/header/polygon-accent.svg); + background-repeat: no-repeat; + background-position: center; + } + + &:hover::after { + background-image: url(../images/header/polygon-white.svg); + } + } + } + + &__list { + pointer-events: none; + + position: absolute; + transform: translateY(-15px); + + width: max-content; + + opacity: 0; + + transition: all $effect-duration ease-out; + + &--active { + pointer-events: all; + transform: translateY(0); + opacity: 1; + transition: all $effect-duration ease-out; + } + } + + &__item { + padding: 5px 10px; + + &--active { + background-color: $color-hover-background; + } + } +} diff --git a/src/styles/blocks/language.scss b/src/styles/blocks/language.scss new file mode 100644 index 000000000..dc65c6edd --- /dev/null +++ b/src/styles/blocks/language.scss @@ -0,0 +1,70 @@ +.language { + z-index: 4; + background-color: $color-background; + + &__content { + position: relative; + height: 100vh; + + @include page-grid; + } + + &__icon { + position: absolute; + + display: block; + + width: 8px; + height: 17px; + margin-top: 20px; + + background-image: url(../images/icons/back.svg); + background-size: cover; + + @include hover(transform, scale($scale-size)); + + @include on-tablet { + margin-top: 33px; + } + } + + &__nav { + @include on-tablet { + grid-column: 2/-1; + } + } + + &__list { + display: flex; + flex-direction: column; + padding-top: 86px; + list-style: none; + } + + &__item { + cursor: pointer; + + width: 200vw; + margin-left: -25vw; + padding-left: 25vw; + padding-block: 11px; + + font-size: 21px; + font-weight: 500; + line-height: 130%; + color: $color-white; + + @include hover(color, $color-accent); + @include hover(background-color, $color-hover-background); + + &--active { + background-color: $color-hover-background; + } + } + + &__link { + width: 100%; + color: inherit; + text-decoration: none; + } +} diff --git a/src/styles/blocks/logo.scss b/src/styles/blocks/logo.scss new file mode 100644 index 000000000..16dc977d5 --- /dev/null +++ b/src/styles/blocks/logo.scss @@ -0,0 +1,16 @@ +.logo { + display: flex; + width: fit-content; + + &__img { + width: 68px; + height: 14px; + + @include hover(transform, scale($scale-size)); + + @include on-desktop { + width: 78px; + height: 16px; + } + } +} diff --git a/src/styles/blocks/main.scss b/src/styles/blocks/main.scss new file mode 100644 index 000000000..e63e74044 --- /dev/null +++ b/src/styles/blocks/main.scss @@ -0,0 +1,25 @@ +.main { + &__wrapper { + background-color: $color-black; + + @include on-desktop { + padding-bottom: 90px; + } + } + + &__button { + position: sticky; + // bottom: 10px; + display: block; + margin: 50px auto; + + @include on-desktop { + // display: block; + position: relative; + bottom: 0; + + // margin: auto; + width: 200px; + } + } +} diff --git a/src/styles/blocks/menu.scss b/src/styles/blocks/menu.scss new file mode 100644 index 000000000..4129e7987 --- /dev/null +++ b/src/styles/blocks/menu.scss @@ -0,0 +1,66 @@ +.menu { + z-index: 4; + background-color: $color-background; + + &__content { + position: relative; + height: 100vh; + + @include page-grid; + } + + &__icon { + position: absolute; + right: 0; + + display: block; + + width: 17px; + height: 17px; + margin-top: 20px; + + background-image: url(../images/icons/close.svg); + background-size: cover; + + @include hover(transform, scale($scale-size)); + + @include on-tablet { + margin-top: 34px; + } + } + + &__nav { + @include on-tablet { + grid-column: 2/-1; + } + } + + &__list { + display: flex; + flex-direction: column; + padding-top: 86px; + list-style: none; + + @include on-tablet { + padding-top: 108px; + } + } + + &__link { + display: block; + + width: 200vw; + margin-left: -25vw; + padding-left: 25vw; + padding-block: 11px; + + font-size: 21px; + font-weight: 500; + line-height: 130%; + color: $color-white; + text-decoration: none; + + @include hover(color, $color-accent); + @include hover(background-color, $color-hover-background); + } +} diff --git a/src/styles/blocks/more-link.scss b/src/styles/blocks/more-link.scss new file mode 100644 index 000000000..45415a51f --- /dev/null +++ b/src/styles/blocks/more-link.scss @@ -0,0 +1,27 @@ +.more-link { + position: relative; + color: $color-accent; + text-decoration: none; + + @include hover(color, $color-white); + + &::after { + content: ''; + + position: absolute; + bottom: -14px; + + display: block; + + width: 100%; + height: 6px; + + background-image: url(../images/header/polygon-accent.svg); + background-repeat: no-repeat; + background-position: center; + } + + &:hover::after { + background-image: url(../images/header/polygon-white.svg); + } +} diff --git a/src/styles/blocks/more.scss b/src/styles/blocks/more.scss new file mode 100644 index 000000000..ce2ea2fa4 --- /dev/null +++ b/src/styles/blocks/more.scss @@ -0,0 +1,125 @@ +.more { + background-color: $color-black; + + &__content { + display: flex; + flex-direction: column; + padding-block: 50px; + + @include on-tablet { + align-items: center; + padding-block: 70px; + } + + @include on-desktop { + padding-block: 100px; + } + + @include on-design { + padding-block: 158px; + } + } + + &__title { + margin-bottom: 12px; + + @include on-desktop { + margin-bottom: 16px; + } + } + + &__text { + margin-bottom: 30px; + font-size: 12px; + color: $color-accent; + + @include on-desktop { + margin-bottom: 83px; + font-size: 14px; + } + + @include on-design { + margin-bottom: 70px; + } + } + + &__container { + @include page-grid; + + row-gap: 20px; + + @include on-tablet { + row-gap: 40px; + } + } + + &__interest { + overflow: hidden; + display: -webkit-box; + grid-column: 1/-1; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + line-clamp: 3; + + padding: 5px; + border: solid 1px transparent; + border-radius: 4px; + + text-overflow: ellipsis; + + @include hover(border, solid 1px $color-accent); + @include hover(box-shadow, 0 0 10px 5px $color-accent); + @include hover(display, block); + + @include on-tablet { + display: flex; + grid-column: span 3; + flex-direction: column; + align-items: center; + + @include hover(display, flex); + } + + @include on-design { + grid-column: span 4; + } + } + + &__image { + display: none; + margin-bottom: 22px; + + @include on-tablet { + display: block; + } + + @include on-desktop { + margin-bottom: 30px; + } + + @include on-design { + margin-bottom: 20px; + } + } + + &__subtitle { + margin-bottom: 11px; + font-size: 16px; + font-weight: 900; + color: $color-white; + + @include on-tablet { + margin-bottom: 20px; + } + + @include on-design { + font-size: 18px; + } + } + + &__description { + @include on-tablet { + text-align: center; + } + } +} diff --git a/src/styles/blocks/order.scss b/src/styles/blocks/order.scss new file mode 100644 index 000000000..5017a1f6f --- /dev/null +++ b/src/styles/blocks/order.scss @@ -0,0 +1,243 @@ +.order { + z-index: 4; + overflow: scroll; + background: $color-gradient; + + &__content { + position: relative; + + @include on-tablet { + @include page-grid; + } + } + + &__top { + grid-column: 1/-1; + align-items: baseline; + + @include on-desktop { + grid-column: 1/2; + } + } + + &__icon { + width: 17px; + height: 17px; + + @include on-desktop { + display: none; + } + } + + &__stages { + grid-column: 1/-1; + margin-bottom: 30px; + + @include on-desktop { + grid-column: 2/-1; + margin: 0; + padding-block: 30px; + } + } + + &__list { + display: flex; + list-style: none; + } + + &__item { + flex: 1 0 33.33%; + padding-block: 16px; + border-bottom: 1px solid $color-text; + text-align: center; + + @include on-desktop { + padding-block: 0; + border: none; + } + + &--place-order { + cursor: pointer; + + &:hover { + color: $color-accent; + } + } + + &--active { + border-color: $color-accent; + color: $color-accent; + + &::after { + @include on-desktop { + content: ''; + + display: block; + + width: 4px; + height: 4px; + margin: auto; + border-radius: 50%; + + background-color: $color-accent; + } + } + } + } + + &__image { + display: none; + + @include on-tablet { + display: block; + grid-column: 2/-2; + width: 100%; + } + + @include on-desktop { + grid-column: 1/7; + margin-top: 200px; + } + + @include on-design { + grid-column: 1/9; + } + + &--complete { + display: none; + } + } + + &__info { + display: flex; + justify-content: space-around; + margin-bottom: 30px; + + @include on-tablet { + grid-column: 2/5; + justify-content: space-between; + } + + @include on-desktop { + grid-column: 1/5; + order: 1; + } + + &--complete { + display: none; + } + } + + &__quantity { + text-align: center; + } + + &__select { + position: relative; + font-size: 20px; + line-height: 130%; + } + + &__dropdown { + position: absolute; + z-index: 4; + top: 46px; + width: 100%; + } + + &__count { + margin-top: 10px; + padding: 8px 40px; + } + + &__price { + text-align: center; + } + + &__amount { + margin-top: 10px; + font-size: 26px; + color: $color-accent; + + @include on-tablet { + font-size: 36px; + } + } + + &__form { + display: none; + + @include on-tablet { + grid-column: 1/-1; + grid-template-columns: 1fr 1fr; + gap: 20px; + } + + @include on-desktop { + grid-column: 7/-1; + grid-row: 2/4; + margin-top: 200px; + } + + @include on-design { + grid-column: 9/-1; + } + + &--active { + display: grid; + } + } + + &__button { + margin: auto; + margin-top: 10px; + + @include on-tablet { + grid-column: 1/-1; + } + } + + &__pay { + display: none; + + @include on-tablet { + grid-column: 2/-2; + } + + @include on-desktop { + grid-column: 7/-3; + grid-row: 2/4; + margin-top: 200px; + } + + @include on-design { + grid-column: 9/-3; + } + + &--active { + display: grid; + } + } + + &__complete { + display: none; + grid-column: 1/-1; + margin-top: 90px; + + @include on-tablet { + margin-top: 180px; + } + + @include on-desktop { + margin-top: 140px; + } + + @include on-desktop { + margin-top: 250px; + } + + &--active { + display: block; + } + } +} diff --git a/src/styles/blocks/page.scss b/src/styles/blocks/page.scss new file mode 100644 index 000000000..b807a25a4 --- /dev/null +++ b/src/styles/blocks/page.scss @@ -0,0 +1,52 @@ +* { + box-sizing: border-box; +} + +body, +p, +ul, +h1, +h2, +h3 { + margin: 0; + padding: 0; +} + +.page { + scroll-behavior: smooth; + + min-width: 320px; + + font-family: Inter, serif; + font-size: 16px; + line-height: 150%; + color: #929292; + + &:has(.page__menu:target), + &:has(.page__help:target), + &:has(.page__faq:target), + &:has(.page__order:target), + &:has(.page__language:target) { + overflow: hidden; + } + + &__aside { + position: fixed; + top: 0; + right: 0; + left: 0; + transform: translateY(-100%); + + overflow: hidden; + + height: 100%; + + background-color: rgba(0, 0, 0, 0.7); + + transition: transform $effect-duration; + + &:target { + transform: translateY(0); + } + } +} diff --git a/src/styles/blocks/pay.scss b/src/styles/blocks/pay.scss new file mode 100644 index 000000000..eac7069f6 --- /dev/null +++ b/src/styles/blocks/pay.scss @@ -0,0 +1,28 @@ +.pay { + &__card { + display: flex; + gap: 7%; + justify-content: space-between; + } + + &__visa { + display: none; + + @include on-tablet { + display: block; + width: 54px; + height: 34px; + } + } + + &__wrapper { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 20px; + } + + &__button { + margin: auto; + margin-top: 10px; + } +} diff --git a/src/styles/blocks/play-video.scss b/src/styles/blocks/play-video.scss new file mode 100644 index 000000000..ee415c8a6 --- /dev/null +++ b/src/styles/blocks/play-video.scss @@ -0,0 +1,19 @@ +.play-video { + display: block; + + width: 209px; + height: 66px; + padding: 22px 0 22px 105px; + + font-weight: 500; + line-height: 130%; + color: $color-white; + text-decoration: none; + + background-image: url(../images/play-video/play-video.svg); + background-repeat: no-repeat; + background-size: cover; + + @include hover(color, $color-accent); + @include hover(transform, scale($scale-size)); +} diff --git a/src/styles/blocks/scroll-up.scss b/src/styles/blocks/scroll-up.scss new file mode 100644 index 000000000..19ad477aa --- /dev/null +++ b/src/styles/blocks/scroll-up.scss @@ -0,0 +1,31 @@ +.scroll-up { + position: fixed; + z-index: 3; + right: 20px; + bottom: 200px; + + display: none; + + width: 48px; + height: 48px; + border-radius: 50%; + + background-image: url(../images/scroll-up/scroll-up.svg); + background-size: cover; + box-shadow: + 0 0 15px 4px $color-accent, + inset 0 0 15px 4px $color-accent; + + @include hover( + background-image, + url(../images/scroll-up/scroll-up-hover.svg) + ); + @include hover( + box-shadow, + (0 0 15px 4px $color-white, inset 0 0 15px 4px $color-white) + ); + + &--active { + display: block; + } +} diff --git a/src/styles/blocks/section-title.scss b/src/styles/blocks/section-title.scss new file mode 100644 index 000000000..8e6af0118 --- /dev/null +++ b/src/styles/blocks/section-title.scss @@ -0,0 +1,9 @@ +.section-title { + font-size: 21px; + font-weight: 900; + color: $color-white; + + @include on-desktop { + font-size: 36px; + } +} diff --git a/src/styles/blocks/select.scss b/src/styles/blocks/select.scss new file mode 100644 index 000000000..c37fa6dc5 --- /dev/null +++ b/src/styles/blocks/select.scss @@ -0,0 +1,28 @@ +.select { + cursor: pointer; + + position: relative; + + border-radius: 4px; + + color: $color-white; + + background-color: $color-background; + + &::after { + content: ''; + + position: absolute; + right: 10px; + bottom: 40%; + + display: block; + + width: 100%; + height: 6px; + + background-image: url(../images/header/polygon-accent.svg); + background-repeat: no-repeat; + background-position: right; + } +} diff --git a/src/styles/blocks/swiper.scss b/src/styles/blocks/swiper.scss new file mode 100644 index 000000000..4e5390669 --- /dev/null +++ b/src/styles/blocks/swiper.scss @@ -0,0 +1,24 @@ +.swiper { + --swiper-navigation-color: #fff; + + width: 100%; + height: auto; + + &-slide { + display: flex; + align-items: center; + justify-content: center; + text-align: center; + } + + &-slide img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; + } + + &-scrollbar-drag { + --swiper-scrollbar-drag-bg-color: #05c2df; + } +} diff --git a/src/styles/blocks/tech.scss b/src/styles/blocks/tech.scss new file mode 100644 index 000000000..18adf2ada --- /dev/null +++ b/src/styles/blocks/tech.scss @@ -0,0 +1,347 @@ +.tech { + background-color: $color-black; + + &__content { + @include page-grid; + + position: relative; + grid-template-rows: auto; + justify-content: center; + padding-block: 50px; + + @include on-tablet { + padding-block: 80px; + } + + @include on-desktop { + padding-block: 100px; + } + + @include on-design { + padding-block: 160px; + } + } + + &__title { + grid-column: 1; + + // justify-self: start; + + margin-bottom: 30px; + + @include on-tablet { + grid-column: span 2; + margin-bottom: 58px; + } + + @include on-desktop { + grid-column: 9/-1; + margin-bottom: 80px; + } + + @include on-design { + grid-column: 12/-1; + } + } + + &__container { + position: relative; + + grid-column: span 2; + justify-self: center; + + width: 200px; + height: 200px; + + background-image: url(../images/tech/tech.svg); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + @include on-tablet { + grid-column: span 6; + width: 350px; + height: 350px; + } + + @include on-desktop { + grid-column: 5/9; + + // @include page-grid; + grid-row: 2/4; + + width: 300px; + height: 300px; + margin-top: 52px; + } + + @include on-design { + grid-column: 7/11; + margin-top: 60px; + } + } + + &__semiline { + @include on-desktop { + position: absolute; + top: 44px; + left: -10px; + + width: 40px; + height: 200px; + + background-image: url(../images/tech/semicircle-line.svg); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + animation-name: semiline; + animation-duration: 3000ms; + animation-fill-mode: backwards; + animation-iteration-count: infinite; + } + } + + &__circle { + position: absolute; + + width: 34px; + height: 34px; + border-radius: 50%; + + background-image: url(../images/tech/circle-close.svg); + background-repeat: no-repeat; + background-position: center; + background-size: 100%; + + @include hover(box-shadow, 0 0 10px 5px $color-accent); + + &--active { + background-image: url(../images/tech/circle-open.svg); + + @include hover(box-shadow, 0 0 10px 5px #07798b); + } + + @include on-tablet { + width: 62px; + height: 62px; + } + + @include on-desktop { + display: none; + } + + &--1 { + top: -10px; + left: 62px; + + @include on-tablet { + top: -25px; + left: 66px; + } + } + + &--2 { + top: 160px; + left: -18px; + + @include on-tablet { + top: 270px; + left: -60px; + } + } + + &--3 { + top: 80px; + left: 136px; + + @include on-tablet { + top: 140px; + left: 240px; + } + } + } + + &__line { + display: none; + + @include on-desktop { + position: absolute; + + display: block; + + background-repeat: no-repeat; + background-position: center; + background-size: 100%; + } + + &--1 { + @include on-desktop { + top: -46px; + left: -254px; + + width: 403px; + height: 72px; + + background-image: url(../images/tech/line1.svg); + } + + @include on-design { + top: -48px; + left: -214px; + width: 362px; + } + } + + &--2 { + @include on-desktop { + top: 85px; + left: -150px; + + width: 134px; + height: 113px; + + background-image: url(../images/tech/line2.svg); + } + + @include on-design { + top: 80px; + left: -160px; + width: 144px; + } + } + + &--3 { + @include on-desktop { + top: -85px; + left: 150px; + + width: 182px; + height: 245px; + + background-image: url(../images/tech/line3.svg); + } + + @include on-design { + top: -70px; + width: 220px; + } + } + } + + &__details { + position: absolute; + z-index: 3; + + display: none; + + padding: 20px 10px; + border-radius: 10px; + + font-size: 12px; + + background-color: $color-background; + + &--active { + display: block; + } + + @include on-tablet { + font-size: 16px; + } + + @include on-desktop { + position: static; + top: 0; + left: 0; + + display: block; + + padding: 0; + + background-color: transparent; + } + + &--1 { + top: 130px; + left: 25%; + + @include on-tablet { + top: 210px; + } + + @include on-desktop { + grid-column: span 3; + } + + @include on-design { + grid-column: 3/7; + } + } + + &--2 { + top: 75px; + left: 20%; + + @include on-tablet { + top: 260px; + } + + @include on-desktop { + grid-column: 9/-1; + } + + @include on-design { + grid-column: 12/-1; + } + } + + &--3 { + top: 225px; + left: 25%; + + @include on-tablet { + top: 180px; + left: 40%; + } + + @include on-desktop { + grid-column: 2 / span 3; + } + + @include on-design { + grid-column: 3/6; + } + } + } + + &__subtitle { + display: none; + + margin-bottom: 21px; + + font-size: 18px; + font-weight: 900; + color: $color-white; + + @include on-desktop { + display: block; + } + } +} + +@keyframes semiline { + 0% { + top: 44px; + left: -10px; + } + 50% { + top: 26px; + left: -8px; + transform: rotate(0.02turn); + } + 100% { + top: 44px; + left: -10px; + } +} diff --git a/src/styles/blocks/top-bar.scss b/src/styles/blocks/top-bar.scss new file mode 100644 index 000000000..d0e40cee2 --- /dev/null +++ b/src/styles/blocks/top-bar.scss @@ -0,0 +1,80 @@ +.top-bar { + display: flex; + align-items: center; + justify-content: space-between; + padding: 18px 0 14px; + + @include on-tablet { + padding-block: 30px; + } + + &__lang { + display: none; + + @include on-desktop { + position: relative; + display: block; + margin-left: 34px; + } + } + + &__nav { + display: none; + + @include on-desktop { + display: flex; + justify-content: flex-end; + width: 100%; + margin-right: 37px; + } + } + + &__list { + display: flex; + gap: 36px; + list-style: none; + } + + &__link { + font-weight: 500; + line-height: 130%; + color: $color-white; + text-decoration: none; + + @include hover(color, $color-accent); + } + + &__icon { + display: block; + width: 20px; + height: 20px; + background-size: cover; + + @include hover(transform, scale($scale-size)); + + @include on-tablet { + width: 30px; + height: 30px; + } + + &--burger { + background-image: url(../images/icons/burger.svg); + + @include on-desktop { + display: none; + } + } + &--close { + background-image: url(../images/icons/close.svg); + } + } + + &__button { + display: none; + + @include on-desktop { + display: block; + width: 200px; + } + } +} diff --git a/src/styles/blocks/video.scss b/src/styles/blocks/video.scss new file mode 100644 index 000000000..22191bd18 --- /dev/null +++ b/src/styles/blocks/video.scss @@ -0,0 +1,45 @@ +.video { + display: none; + + &--active { + position: fixed; + z-index: 55; + top: 0; + right: 0; + left: 0; + + display: flex; + align-items: center; + justify-content: center; + + height: 100%; + + background-color: rgba(0, 0, 0, 0.7); + } + + &__content { + position: relative; + aspect-ratio: 16/9; + width: 80%; + margin: auto; + } + + &__close { + position: absolute; + top: 15px; + right: 13px; + + width: 20px; + height: 20px; + + background-image: url(../images/icons/close.svg); + + @include hover(background-image, url(../images/icons/close-accent.svg)); + @include hover(transform, scale($scale-size)); + } + + &__iframe { + width: 100%; + height: 100%; + } +} diff --git a/src/styles/main.scss b/src/styles/main.scss index fb9195d12..3aacd3f79 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -2,6 +2,37 @@ @import 'fonts'; @import 'typography'; -body { - background: $c-gray; -} +@import 'blocks/page'; +@import 'blocks/header'; +@import 'blocks/footer'; +@import 'blocks/container'; +@import 'blocks/form'; +@import 'blocks/button'; +@import 'blocks/top-bar'; +@import 'blocks/swiper'; +@import 'blocks/logo'; +@import 'blocks/menu'; +@import 'blocks/more-link'; +@import 'blocks/play-video'; +@import 'blocks/select'; +@import 'blocks/accent-title'; +@import 'blocks/faq'; +@import 'blocks/help'; +@import 'blocks/order'; +@import 'blocks/pay'; +@import 'blocks/complete'; +@import 'blocks/count'; +@import 'blocks/countries'; +@import 'blocks/cities'; +@import 'blocks/main'; +@import 'blocks/more'; +@import 'blocks/section-title'; +@import 'blocks/about'; +@import 'blocks/tech'; +@import 'blocks/benefits'; +@import 'blocks/contact'; +@import 'blocks/scroll-up'; +@import 'blocks/video'; +@import 'blocks/dropdown'; +@import 'blocks/language'; +@import 'blocks/lang'; diff --git a/src/styles/utils/_mixins.scss b/src/styles/utils/_mixins.scss index 80c79780d..91fe6969c 100644 --- a/src/styles/utils/_mixins.scss +++ b/src/styles/utils/_mixins.scss @@ -1,6 +1,62 @@ +@mixin on-tablet { + @media (min-width: $tablet-width) { + @content; + } +} + +@mixin on-desktop { + @media (min-width: $desktop-width) { + @content; + } +} + +@mixin on-design { + @media (min-width: $design-width) { + @content; + } +} + @mixin hover($_property, $_toValue) { - transition: #{$_property} 0.3s; + transition: #{$_property} $effect-duration; &:hover { #{$_property}: $_toValue; } } + +@mixin content-padding-inline { + padding-inline: $content-padding-inline-mobile; + + @include on-tablet { + padding-inline: $content-padding-inline-tablet; + } + + @include on-desktop { + padding-inline: 110px; + } + + @include on-design { + max-width: 1920px; + margin-inline: auto; + padding-inline: 234px; + } +} + +@mixin page-grid { + --columns: 2; + + display: grid; + grid-template-columns: repeat(var(--columns), 1fr); + column-gap: 20px; + + @include on-tablet { + --columns: 6; + } + + @include on-desktop { + --columns: 12; + } + + @include on-design { + --columns: 16; + } +} diff --git a/src/styles/utils/_vars.scss b/src/styles/utils/_vars.scss index aeb006ffb..adcac726d 100644 --- a/src/styles/utils/_vars.scss +++ b/src/styles/utils/_vars.scss @@ -1 +1,16 @@ -$c-gray: #eee; +$tablet-width: 640px; +$desktop-width: 1280px; +$design-width: 1440px; +$color-accent: #05c2df; +$color-black: #05040b; +$color-background: #191536; +$color-hover-background: #110e25; +$color-gray: #2f2f2f; +$color-text: #929292; +$color-white: #fff; +$color-error: #860404; +$color-gradient: linear-gradient(100.83deg, #191536 0.67%, #000 100%); +$scale-size: 1.2; +$effect-duration: 0.3s; +$content-padding-inline-mobile: 20px; +$content-padding-inline-tablet: 34px;