diff --git a/README.md b/README.md index 302783df..8dda8802 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://Cumacea.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 d339e685..1af5a6aa 100644 --- a/index.html +++ b/index.html @@ -1,19 +1,1860 @@ - + - Title + KatVR + + - -

Hello Mate Academy

- + +
+
+
+
+ + + + +
+ +
    +
  • + En +
  • + +
  • + Ar +
  • + +
  • + Zh +
  • + +
  • + Fr +
  • + +
  • + De +
  • + +
  • + It +
  • + +
  • + Es +
  • + +
  • + Pl +
  • + +
  • + Ua +
  • +
+
+
+ + +
+
+ +
+ + + + VR Locomotion + +
+ +
+ VR Locomotion + + VR Locomotion + + VR Locomotion +
+ +
+

+ THE NEW START OF +
+ VR LOCOMOTION +

+ +

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

+ +

1200$

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

+ +
+
/5 +
+ +
+
+ VR Locomotion + + VR Locomotion + + VR Locomotion + + VR Locomotion + + VR Locomotion +
+ +
+
+
+
+
+
+
+
+ +
+ + + +
+ +
+
+
+
+
+ +
+

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

+ + +
+ +
+ +
+
+

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

+ +
+ + VR Locomotion + + +
+

+ SENSOR +

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

+ CONNECTION +

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

+ BATTERRIES +

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

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

+
+
+
+ + + +
+
+
+
+ + + + + +
+ +
+
+ Place Order +
+ +
+ Pay +
+ +
+ Complete + Order complete +
+
+
+ +
+
+
+ +
+
+
+
+
+ VR Locomotion +
+ +
+
+

Quantity

+ +
+ + +
    +
  • + 1 +
  • + +
  • + 2 +
  • + +
  • + 3 +
  • + +
  • + 4 +
  • +
+
+
+ +
+

Price

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

+ Country* +

+ +
+ + +
    +
  • + Ukraine +
  • + +
  • + United Kingdom +
  • + +
  • + Morocco +
  • + +
  • + China +
  • + +
  • + France +
  • + +
  • + Germany +
  • + +
  • + Italy +
  • + +
  • + Spain +
  • + +
  • + Poland +
  • +
+
+
+ +
+

+ City* +

+ +
+ + +
    +
  • + Kyiv +
  • + +
  • + Kharkiv +
  • + +
  • + Odesa +
  • + +
  • + Dnipro +
  • + +
  • + Zaporizhzhia +
  • + +
  • + Lviv +
  • + +
  • + Kryvyi Rih +
  • + +
  • + Mykolaiv +
  • + +
  • + Vinnytsia +
  • +
+
+
+ +
+ + +
+ +
+ + +
+ + +
+
+
+ +
+
+
+
+ VR Locomotion +
+ +
+
+

Quantity

+ +
+ + +
    +
  • + 1 +
  • + +
  • + 2 +
  • + +
  • + 3 +
  • + +
  • + 4 +
  • +
+
+
+ +
+

Price

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

+ THANK YOU FOR YOUR ORDER! +

+ +

+ Your order has been placed and is being processed. + You will recive an email with the order details +

+ + + Back to homepage + +
+
+
+
+
+ +
+
+ +
+ +
+ +

+ FREQUENTLY ASKED QUESTIONS +

+ +
+
+ + What makes KAT loco different from other systems? + + +

+ Despite being approached from many different angles, all traditional + VR Locomotion systems including roomscale, teleportation, and free locomotion + failed to provide an optimal solution capable of integrating high immersion with + convenience. KAT loco does all of that without repeating their flaws. Our system + offers a complete and versatile solution for an affordable price what makes it a + perfect choice for home-use. It is also 100% user friendly, wireless, universally + compatible, and more! It even offers decoupled head and body directions! +

+ +

+ Last updated: Wed, June 12 2019 7:07 PM UTC +03:00 +

+
+ +
+ + Will it decrease my motion sickness? + + +

+ Yes, using this device can significantly reduce motion sickness by resolving the + sensory conflict that typically occurs in VR. When your eyes perceive movement in + the virtual world while your body remains still, your brain experiences a disconnect + that causes nausea; by synchronizing your physical steps with your in-game character's + movement, this device aligns your vestibular system with your visual input. This + active physical engagement helps your brain process virtual locomotion as natural movement, + making your VR experience much more comfortable and immersive. +

+ +

+ Last updated: Wed, June 12 2019 7:07 PM UTC +03:00 +

+
+ +
+ + Which VR headsets is it compatible with? + + +

+ Our device is designed with universal compatibility in mind and works seamlessly with most + major VR headsets on the market. It fully supports standalone systems like Meta Quest 2 and 3, + as well as PC-powered setups such as Valve Index, HP Reverb G2, and the HTC Vive series. + Additionally, it is compatible with PlayStation VR (PSVR 1 & 2) via a dedicated adapter, ensuring + that whether you are gaming on a console, PC, or a mobile headset, you can enjoy a fully + immersive walking experience. +

+ +

+ Last updated: Wed, June 12 2019 7:07 PM UTC +03:00 +

+
+ +
+ + Is it compatible with Oculus Quest? + + +

+ Absolutely. Our device offers full native support for both Oculus Quest (Meta Quest 1 & 2) and the + latest Meta Quest 3. It connects effortlessly via Bluetooth, allowing you to enjoy a completely + wireless walking experience without the need for a PC. Whether you are playing standalone Quest games + or using Quest Link/Air Link to play SteamVR titles, our system synchronizes perfectly with your + movement to provide maximum immersion and freedom. +

+ +

+ Last updated: Wed, June 12 2019 7:07 PM UTC +03:00 +

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

+ HOW CAN WE HELP YOU? +

+ +
+

+ Welcome to our help center. Our goal is to make the process of getting acquainted and purchase + as easy and pleasant as possible. Need help with your KAT VR loco product? Many product questions + can be resolved by reviewing our Product Support + + FAQs + . +

+ +

+ Please also feel free to + + Contact Us + + directly should you need anything further. We’re happy to help. +

+
+ + +
+
+ +
+
+
+ +
+
+
+
+ + 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/fonts/inter-v20-latin-500.woff2 b/src/fonts/inter-v20-latin-500.woff2 new file mode 100644 index 00000000..54f0a595 Binary files /dev/null and b/src/fonts/inter-v20-latin-500.woff2 differ diff --git a/src/fonts/inter-v20-latin-900.woff2 b/src/fonts/inter-v20-latin-900.woff2 new file mode 100644 index 00000000..4db8333c Binary files /dev/null and b/src/fonts/inter-v20-latin-900.woff2 differ diff --git a/src/fonts/inter-v20-latin-regular.woff2 b/src/fonts/inter-v20-latin-regular.woff2 new file mode 100644 index 00000000..f15b025d Binary files /dev/null and b/src/fonts/inter-v20-latin-regular.woff2 differ diff --git a/src/images/about/about-background.png b/src/images/about/about-background.png new file mode 100644 index 00000000..a22d85d0 Binary files /dev/null and b/src/images/about/about-background.png differ diff --git a/src/images/about/about-image-1.png b/src/images/about/about-image-1.png new file mode 100644 index 00000000..4d204adb Binary files /dev/null and b/src/images/about/about-image-1.png differ diff --git a/src/images/about/about-image-2.png b/src/images/about/about-image-2.png new file mode 100644 index 00000000..03669382 Binary files /dev/null and b/src/images/about/about-image-2.png differ diff --git a/src/images/about/about-image-3.png b/src/images/about/about-image-3.png new file mode 100644 index 00000000..4158e9fc Binary files /dev/null and b/src/images/about/about-image-3.png differ diff --git a/src/images/about/about-image-4.png b/src/images/about/about-image-4.png new file mode 100644 index 00000000..9c5832e9 Binary files /dev/null and b/src/images/about/about-image-4.png differ diff --git a/src/images/about/about-image-5.png b/src/images/about/about-image-5.png new file mode 100644 index 00000000..645b5ad5 Binary files /dev/null and b/src/images/about/about-image-5.png differ diff --git a/src/images/benefits/compatible.svg b/src/images/benefits/compatible.svg new file mode 100644 index 00000000..37e8765f --- /dev/null +++ b/src/images/benefits/compatible.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/benefits/control.svg b/src/images/benefits/control.svg new file mode 100644 index 00000000..6188346d --- /dev/null +++ b/src/images/benefits/control.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/benefits/sensors.svg b/src/images/benefits/sensors.svg new file mode 100644 index 00000000..68015352 --- /dev/null +++ b/src/images/benefits/sensors.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/images/button/footer-button-hover.svg b/src/images/button/footer-button-hover.svg new file mode 100644 index 00000000..40da6f4c --- /dev/null +++ b/src/images/button/footer-button-hover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/button/footer-button.svg b/src/images/button/footer-button.svg new file mode 100644 index 00000000..23aded6c --- /dev/null +++ b/src/images/button/footer-button.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/button/more-button-hover.svg b/src/images/button/more-button-hover.svg new file mode 100644 index 00000000..4c150067 --- /dev/null +++ b/src/images/button/more-button-hover.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/button/more-button.svg b/src/images/button/more-button.svg new file mode 100644 index 00000000..5cbb538d --- /dev/null +++ b/src/images/button/more-button.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/button/video-button-hover.svg b/src/images/button/video-button-hover.svg new file mode 100644 index 00000000..892aeaaf --- /dev/null +++ b/src/images/button/video-button-hover.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/button/video-button.svg b/src/images/button/video-button.svg new file mode 100644 index 00000000..ee34623f --- /dev/null +++ b/src/images/button/video-button.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/header/desktop-image-1.png b/src/images/header/desktop-image-1.png new file mode 100644 index 00000000..d47a3694 Binary files /dev/null and b/src/images/header/desktop-image-1.png differ diff --git a/src/images/header/desktop-image-2.png b/src/images/header/desktop-image-2.png new file mode 100644 index 00000000..d68b1b6a Binary files /dev/null and b/src/images/header/desktop-image-2.png differ diff --git a/src/images/header/desktop-image-3.png b/src/images/header/desktop-image-3.png new file mode 100644 index 00000000..bcd4af0d Binary files /dev/null and b/src/images/header/desktop-image-3.png differ diff --git a/src/images/header/mobile-image.png b/src/images/header/mobile-image.png new file mode 100644 index 00000000..c8cf5ac3 Binary files /dev/null and b/src/images/header/mobile-image.png differ diff --git a/src/images/header/tablet-image.png b/src/images/header/tablet-image.png new file mode 100644 index 00000000..47a655de Binary files /dev/null and b/src/images/header/tablet-image.png differ diff --git a/src/images/icons/back-icon.svg b/src/images/icons/back-icon.svg new file mode 100644 index 00000000..1a2fbd8a --- /dev/null +++ b/src/images/icons/back-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/close-hover-icon.svg b/src/images/icons/close-hover-icon.svg new file mode 100644 index 00000000..8308d009 --- /dev/null +++ b/src/images/icons/close-hover-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/icons/close-icon.svg b/src/images/icons/close-icon.svg new file mode 100644 index 00000000..5e35784f --- /dev/null +++ b/src/images/icons/close-icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/icons/mastercard-icon.svg b/src/images/icons/mastercard-icon.svg new file mode 100644 index 00000000..67e199b8 --- /dev/null +++ b/src/images/icons/mastercard-icon.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/icons/menu-icon.svg b/src/images/icons/menu-icon.svg new file mode 100644 index 00000000..a18a754d --- /dev/null +++ b/src/images/icons/menu-icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/icons/triangle-hover-icon.svg b/src/images/icons/triangle-hover-icon.svg new file mode 100644 index 00000000..87e174c5 --- /dev/null +++ b/src/images/icons/triangle-hover-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/triangle-icon.svg b/src/images/icons/triangle-icon.svg new file mode 100644 index 00000000..de53fb1b --- /dev/null +++ b/src/images/icons/triangle-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/visa-icon.svg b/src/images/icons/visa-icon.svg new file mode 100644 index 00000000..0a97fb76 --- /dev/null +++ b/src/images/icons/visa-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/images/logos/favicon.png b/src/images/logos/favicon.png new file mode 100644 index 00000000..5a6d50e7 Binary files /dev/null and b/src/images/logos/favicon.png differ diff --git a/src/images/logos/logo.svg b/src/images/logos/logo.svg new file mode 100644 index 00000000..b3435d9f --- /dev/null +++ b/src/images/logos/logo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/images/more/education.svg b/src/images/more/education.svg new file mode 100644 index 00000000..faa0bbff --- /dev/null +++ b/src/images/more/education.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/images/more/estate.svg b/src/images/more/estate.svg new file mode 100644 index 00000000..350421b9 --- /dev/null +++ b/src/images/more/estate.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/more/fitness.svg b/src/images/more/fitness.svg new file mode 100644 index 00000000..935fb574 --- /dev/null +++ b/src/images/more/fitness.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/images/more/interaction.svg b/src/images/more/interaction.svg new file mode 100644 index 00000000..09a32f51 --- /dev/null +++ b/src/images/more/interaction.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/social-media/facebook.svg b/src/images/social-media/facebook.svg new file mode 100644 index 00000000..1cb7bb4b --- /dev/null +++ b/src/images/social-media/facebook.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/social-media/reddit.svg b/src/images/social-media/reddit.svg new file mode 100644 index 00000000..2ec59738 --- /dev/null +++ b/src/images/social-media/reddit.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/social-media/x.svg b/src/images/social-media/x.svg new file mode 100644 index 00000000..b7142b7b --- /dev/null +++ b/src/images/social-media/x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/social-media/youtube.svg b/src/images/social-media/youtube.svg new file mode 100644 index 00000000..bd0387c5 --- /dev/null +++ b/src/images/social-media/youtube.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/tech/batterries-line-large.svg b/src/images/tech/batterries-line-large.svg new file mode 100644 index 00000000..fad6249e --- /dev/null +++ b/src/images/tech/batterries-line-large.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/tech/batterries-line.svg b/src/images/tech/batterries-line.svg new file mode 100644 index 00000000..c1533eae --- /dev/null +++ b/src/images/tech/batterries-line.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/tech/button-close.svg b/src/images/tech/button-close.svg new file mode 100644 index 00000000..f3e455cf --- /dev/null +++ b/src/images/tech/button-close.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/tech/button-open.svg b/src/images/tech/button-open.svg new file mode 100644 index 00000000..c1c91e51 --- /dev/null +++ b/src/images/tech/button-open.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/images/tech/connection-line-large.svg b/src/images/tech/connection-line-large.svg new file mode 100644 index 00000000..8183d536 --- /dev/null +++ b/src/images/tech/connection-line-large.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/tech/connection-line.svg b/src/images/tech/connection-line.svg new file mode 100644 index 00000000..e2961ab5 --- /dev/null +++ b/src/images/tech/connection-line.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/tech/eclipse.svg b/src/images/tech/eclipse.svg new file mode 100644 index 00000000..2d162854 --- /dev/null +++ b/src/images/tech/eclipse.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/tech/sensor-line-large.svg b/src/images/tech/sensor-line-large.svg new file mode 100644 index 00000000..ef522dfa --- /dev/null +++ b/src/images/tech/sensor-line-large.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/tech/sensor-line.svg b/src/images/tech/sensor-line.svg new file mode 100644 index 00000000..dfc56f6d --- /dev/null +++ b/src/images/tech/sensor-line.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/tech/tech-image.png b/src/images/tech/tech-image.png new file mode 100644 index 00000000..90974a17 Binary files /dev/null and b/src/images/tech/tech-image.png differ diff --git a/src/scripts/checkout.js b/src/scripts/checkout.js new file mode 100644 index 00000000..d4ad2887 --- /dev/null +++ b/src/scripts/checkout.js @@ -0,0 +1,31 @@ +export function initCheckoutToggle() { + const checkoutSection = document.getElementById('checkout'); + const buyButtons = document.querySelectorAll('.header__button, .top-bar__button'); + const closeButton = document.querySelector('.stepper__close'); + const pageBody = document.querySelector('.page__body'); + + if (!checkoutSection) return; + + const openCheckout = (e) => { + e.preventDefault(); + checkoutSection.classList.add('is-visible'); + pageBody.classList.add('no-scroll'); + }; + + const closeCheckout = (e) => { + e.preventDefault(); + checkoutSection.classList.remove('is-visible'); + pageBody.classList.remove('no-scroll'); + }; + + buyButtons.forEach(btn => { + btn.addEventListener('click', openCheckout); + }); + + closeButton?.addEventListener('click', closeCheckout); + + document.querySelector('.complete__button').addEventListener('click', () => { + window.location.href = window.location.origin + '#home'; + window.location.reload(); + }); +} diff --git a/src/scripts/country-select.js b/src/scripts/country-select.js new file mode 100644 index 00000000..c2afbabd --- /dev/null +++ b/src/scripts/country-select.js @@ -0,0 +1,50 @@ +const locationData = { + ukraine: ['Kyiv', 'Kharkiv', 'Odesa', 'Dnipro', 'Zaporizhzhia', 'Lviv', 'Kryvyi Rih', 'Mykolaiv', 'Vinnytsia'], + uk: ['London', 'Birmingham', 'Manchester', 'Glasgow', 'Leeds', 'Liverpool', 'Newcastle upon Tyne', 'Sheffield', 'Bristol'], + morocco: ['Casablanca', 'Rabat', 'Fes', 'Marrakesh', 'Tangier', 'Agadir', 'Meknes', 'Oujda', 'Kenitra'], + china: ['Shanghai', 'Beijing', 'Chongqing', 'Tianjin', 'Guangzhou', 'Shenzhen', 'Chengdu', 'Nanjing', 'Wuhan'], + france: ['Paris', 'Marseille', 'Lyon', 'Toulouse', 'Nice', 'Nantes', 'Strasbourg', 'Montpellier', 'Bordeaux'], + germany: ['Berlin', 'Hamburg', 'Munich', 'Cologne', 'Frankfurt', 'Stuttgart', 'Düsseldorf', 'Leipzig', 'Dortmund'], + italy: ['Rome', 'Milan', 'Naples', 'Turin', 'Palermo', 'Genoa', 'Bologna', 'Florence', 'Bari'], + spain: ['Madrid', 'Barcelona', 'Valencia', 'Seville', 'Zaragoza', 'Malaga', 'Murcia', 'Palma', 'Las Palmas'], + poland: ['Warsaw', 'Krakow', 'Lodz', 'Wroclaw', 'Poznan', 'Gdansk', 'Szczecin', 'Bydgoszcz', 'Lublin'], +}; + +export function initLocationSelects() { + const countrySelect = document.querySelector('#country-select'); + const citySelect = document.querySelector('#city-select'); + + if (!countrySelect || !citySelect) return; + + const countryItems = countrySelect.querySelectorAll('.select__item'); + const cityButton = citySelect.querySelector('.select__button'); + const cityList = citySelect.querySelector('.select__list'); + + countryItems.forEach(item => { + item.addEventListener('click', () => { + const selectedCountry = item.getAttribute('data-value'); + + cityList.innerHTML = ''; + + if (locationData[selectedCountry]) { + cityButton.textContent = locationData[selectedCountry][0]; + + locationData[selectedCountry].forEach(cityName => { + const li = document.createElement('li'); + li.className = 'form__item select__item'; + li.textContent = cityName; + li.setAttribute('data-value', cityName.toLowerCase()); + + li.addEventListener('click', (e) => { + e.stopPropagation(); + + cityButton.textContent = cityName; + citySelect.classList.remove('is-open'); + }); + + cityList.appendChild(li); + }); + } + }); + }); +} diff --git a/src/scripts/form.js b/src/scripts/form.js new file mode 100644 index 00000000..501c89e2 --- /dev/null +++ b/src/scripts/form.js @@ -0,0 +1,86 @@ +export function initForm(onSuccess) { + const forms = document.querySelectorAll('#footer-form, #order-form'); + + const validationRules = { + 'first-name': (value) => value.trim().length >= 2, + 'surname': (value) => value.trim().length >= 2, + 'name': (value) => value.trim().length >= 2, + 'email': (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value), + 'tel': (value) => /^[+]?[0-9]{10,15}$/.test(value.replace(/\s/g, '')), + 'address': (value) => value.trim().length >= 5, + }; + + function validateField(input) { + const name = input.name; + const value = input.value.trim(); + + if (!input.hasAttribute('required') && value === '') { + input.classList.remove('is-valid', 'is-invalid'); + + return true; + } + + let isValid = true; + if (input.hasAttribute('required') && value === '') { + isValid = false; + } else if (validationRules[name]) { + isValid = validationRules[name](value); + } + + if (isValid) { + input.classList.add('is-valid'); + input.classList.remove('is-invalid'); + } else { + input.classList.add('is-invalid'); + input.classList.remove('is-valid'); + } + + return isValid; + } + + forms.forEach(form => { + form.setAttribute('novalidate', ''); + + const inputs = form.querySelectorAll('.form__input'); + + inputs.forEach(input => { + input.addEventListener('blur', () => { + if (input.value.trim() !== '') validateField(input); + }); + + input.addEventListener('input', () => { + input.classList.remove('is-invalid'); + }); + }); + + form.addEventListener('submit', (e) => { + e.preventDefault(); + e.stopPropagation(); + + let isFormValid = true; + + inputs.forEach(input => { + if (input.hasAttribute('required')) { + const valid = validateField(input); + + if (!valid) isFormValid = false; + } + }); + + if (isFormValid) { + if (onSuccess && typeof onSuccess === 'function') { + onSuccess(form); + } + + form.reset(); + inputs.forEach(i => i.classList.remove('is-valid', 'is-invalid')); + + } else { + const firstError = form.querySelector('.is-invalid'); + + firstError?.focus(); + firstError?.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + }); + }); +} diff --git a/src/scripts/main.js b/src/scripts/main.js index ad9a93a7..105833cc 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1 +1,45 @@ 'use strict'; + +import '../styles/main.scss'; +import { initSlider } from './slider.js'; +import { initTechSpecs } from './tech.js'; +import { initMenu } from './menu.js'; +import { initScrollObserver } from './observer.js'; +import { initSelect } from './select.js'; +import { initStepper } from './stepper.js'; +import { initCheckoutToggle } from './checkout.js'; +import { initForm } from './form.js'; +import { initLocationSelects } from './country-select.js'; +import { initQuantityPrice } from './quantity.js'; +import { initPaymentForm } from './payment.js'; +import { initModals } from './modals.js'; +import { initVideoModal } from './video.js'; + +document.addEventListener('DOMContentLoaded', () => { + initSlider(); + initMenu(); + initScrollObserver(); + initSelect(); + initCheckoutToggle(); + initLocationSelects(); + initQuantityPrice(); + initTechSpecs(); + initModals(); + initVideoModal(); + + + const { updateStepper } = initStepper(); + + initForm((form) => { + if (form.classList.contains('order__form')) { + updateStepper(1); + } + }); + + initPaymentForm((form) => { + console.log('STEP 3 TRIGGER'); + if (form.classList.contains('pay__form')) { + updateStepper(2); + } + }); +}); diff --git a/src/scripts/menu.js b/src/scripts/menu.js new file mode 100644 index 00000000..34adbacd --- /dev/null +++ b/src/scripts/menu.js @@ -0,0 +1,55 @@ +export function initMenu() { + const pageBody = document.querySelector('.page__body'); + const burgerButton = document.querySelector('.top-bar__burger-menu'); + const closeButton = document.querySelector('.menu__close'); + const menuLinks = document.querySelectorAll('.menu__link'); + const menu = document.querySelector('.menu'); + + const languageButton = document.querySelector('.menu__language-button'); + const backButton = document.querySelector('.language-menu__back'); + const languageLink = document.querySelector('.language-menu__link--active'); + const languageMenu = document.querySelector('.language-menu'); + + if (!menu || !burgerButton) return; + + const closeAllMenus = () => { + menu.classList.remove('is-open'); + menu.classList.add('is-close'); + languageMenu?.classList.remove('is-open'); + languageMenu?.classList.add('is-close'); + pageBody.classList.remove('no-scroll'); + menu.style.overflow = 'auto'; + }; + + burgerButton.addEventListener('click', () => { + menu.classList.add('is-open'); + menu.classList.remove('is-close'); + pageBody.classList.add('no-scroll'); + }); + + closeButton?.addEventListener('click', closeAllMenus); + + menuLinks.forEach((link) => { + link.addEventListener('click', () => { + if (!link.classList.contains('menu__language-button')) { + closeAllMenus(); + } + }); + }); + + languageButton?.addEventListener('click', (e) => { + e.preventDefault(); + languageMenu?.classList.add('is-open'); + languageMenu?.classList.remove('is-close'); + menu.style.overflow = 'hidden'; + }); + + backButton?.addEventListener('click', (e) => { + e.preventDefault(); + languageMenu?.classList.remove('is-open'); + languageMenu?.classList.add('is-close'); + menu.style.overflow = 'auto'; + }); + + languageLink.addEventListener('click', closeAllMenus); +} diff --git a/src/scripts/modals.js b/src/scripts/modals.js new file mode 100644 index 00000000..50bba118 --- /dev/null +++ b/src/scripts/modals.js @@ -0,0 +1,52 @@ +export function initModals() { + const faqSection = document.getElementById('faq'); + const helpSection = document.getElementById('help'); + + const openFaqBtns = document.querySelectorAll('.header__faq, .menu__faq, .help__faq'); + const openHelpBtns = document.querySelectorAll('.header__help, .menu__help'); + + const closeFaqBtn = document.querySelector('.faq__close'); + const moreFaqBtn = document.querySelector('.faq__button'); + const closeHelpBtn = document.querySelector('.help__close'); + const contactHelpBtn = document.querySelector('.help__contact'); + + const toggleModal = (modal, action) => { + if (!modal) return; + + if (action === 'open') { + modal.classList.add('is-open'); + document.body.style.overflow = 'hidden'; + } else { + modal.classList.remove('is-open'); + + const anyOpen = document.querySelectorAll('.is-open').length > 0; + if (!anyOpen) { + document.body.style.overflow = ''; + } + } + }; + + openFaqBtns.forEach(btn => { + btn.addEventListener('click', (e) => { + e.preventDefault(); + + if (btn.classList.contains('help__faq')) { + toggleModal(helpSection, 'close'); + } + + toggleModal(faqSection, 'open'); + }); + }); + + openHelpBtns.forEach(btn => { + btn.addEventListener('click', (e) => { + e.preventDefault(); + toggleModal(helpSection, 'open'); + }); + }); + + closeFaqBtn?.addEventListener('click', () => toggleModal(faqSection, 'close')); + moreFaqBtn?.addEventListener('click', () => toggleModal(faqSection, 'close')); + closeHelpBtn?.addEventListener('click', () => toggleModal(helpSection, 'close')); + contactHelpBtn?.addEventListener('click', () => toggleModal(helpSection, 'close')); +} diff --git a/src/scripts/observer.js b/src/scripts/observer.js new file mode 100644 index 00000000..b6f9f380 --- /dev/null +++ b/src/scripts/observer.js @@ -0,0 +1,22 @@ +export function initScrollObserver() { + const footer = document.querySelector('.footer'); + const fixedButton = document.querySelector('.header__button'); + + if (!footer || !fixedButton) return; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + fixedButton.style.opacity = '0'; + fixedButton.style.pointerEvents = 'none'; + fixedButton.style.transform = 'translateY(20px)'; + } else { + fixedButton.style.opacity = '1'; + fixedButton.style.pointerEvents = 'auto'; + fixedButton.style.transform = 'translateY(0)'; + } + }); + }, { rootMargin: '0px 0px 20px 0px' }); + + observer.observe(footer); +} diff --git a/src/scripts/payment.js b/src/scripts/payment.js new file mode 100644 index 00000000..7098d06f --- /dev/null +++ b/src/scripts/payment.js @@ -0,0 +1,143 @@ +export function initPaymentForm(onSuccess) { + const form = document.getElementById('pay-form'); + + if (!form) return; + + const inputs = form.querySelectorAll('.pay__input, [data-card-part]'); + const cardFields = form.querySelectorAll('[data-card-part]'); + const hiddenCardInput = document.getElementById('card-number-full'); + const validationRules = { + 'card-number': (val) => val.length === 16, + 'holder-name': (val) => val.trim().split(' ').length >= 2, + 'cvv': (val) => /^\d{3}$/.test(val), + 'date': (val) => { + const clean = val.replace(/\D/g, ''); + + if (clean.length !== 4) return false; + + const mm = parseInt(clean.substring(0, 2)); + const yy = parseInt(clean.substring(2, 4)); + const curYear = new Date().getFullYear() % 100; + const curMonth = new Date().getMonth() + 1; + + if (mm < 1 || mm > 12) return false; + + if (yy < 26 || yy > 50) return false; + + if (yy < curYear || (yy === curYear && mm < curMonth)) return false; + + return true; + } + }; + const visaIcon = form.querySelector('.pay__form-visa'); + const mastercardIcon = form.querySelector('.pay__form-mastercard'); + + function validateField(input) { + const name = input.name; + const value = input.value.trim(); + const container = input.closest('.pay__card-number, .pay__form-date, .pay__form-cvv, .form__field'); + let isValid = true; + + if (input.hasAttribute('required') && (value === '' || (name === 'card-number' && value.length < 16))) { + isValid = false; + } else if (validationRules[name]) { + isValid = validationRules[name](value); + } + + if (isValid) { + container?.classList.remove('is-invalid'); + container?.classList.add('is-valid'); + input.classList.add('is-valid'); + input.classList.remove('is-invalid'); + } else { + container?.classList.add('is-invalid'); + container?.classList.remove('is-valid'); + input.classList.add('is-invalid'); + input.classList.remove('is-valid'); + } + + return isValid; + } + + inputs.forEach(input => { + input.addEventListener('focus', () => { + const container = input.closest('.pay__card-number, .pay__form-date, .pay__form-cvv'); + + container?.classList.remove('is-invalid'); + }); + }); + + const dateInput = document.getElementById('date'); + + dateInput.addEventListener('input', (e) => { + let v = e.target.value.replace(/\D/g, ''); + + if (v.length >= 2) v = v.substring(0, 2) + ' / ' + v.substring(2, 4); + + e.target.value = v; + }); + + cardFields.forEach((field, index) => { + field.addEventListener('input', () => { + field.value = field.value.replace(/\D/g, ''); + + if (index === 0) { + const firstDigit = field.value.substring(0, 1); + + visaIcon?.classList.remove('is-active'); + mastercardIcon?.classList.remove('is-active'); + + if (firstDigit > 0 && firstDigit <= 4) { + visaIcon?.classList.add('is-active'); + } else if (firstDigit >= 5 && firstDigit <= 9) { + mastercardIcon?.classList.add('is-active'); + } + } + + if (field.value.length === 4 && index < 3) cardFields[index + 1].focus(); + + const full = Array.from(cardFields).map(f => f.value).join(''); + + hiddenCardInput.value = full; + + field.closest('.pay__card-number').classList.remove('is-invalid'); + }); + }); + + + form.addEventListener('submit', (e) => { + e.preventDefault(); + + let isFormValid = true; + + inputs.forEach(input => { + if (input.name) { + const valid = validateField(input); + + if (!valid) isFormValid = false; + } + }); + + const cardNumber = hiddenCardInput.value; + + if (cardNumber.length !== 16) { + isFormValid = false; + form.querySelector('.pay__card-number')?.classList.add('is-invalid'); + } else { + form.querySelector('.pay__card-number')?.classList.remove('is-invalid'); + form.querySelector('.pay__card-number')?.classList.add('is-valid'); + } + + if (isFormValid) { + if (onSuccess && typeof onSuccess === 'function') { + onSuccess(form); + } + + form.reset(); + + document.querySelectorAll('.is-valid, .is-invalid').forEach(el => + el.classList.remove('is-valid', 'is-invalid') + ); + } +}); +} diff --git a/src/scripts/quantity.js b/src/scripts/quantity.js new file mode 100644 index 00000000..bd9da129 --- /dev/null +++ b/src/scripts/quantity.js @@ -0,0 +1,40 @@ +export function initQuantityPrice() { + const quantitySelects = document.querySelectorAll('.quantity__select'); + const priceDisplays = document.querySelectorAll('.quantity__value'); + const allQuantityButtons = document.querySelectorAll('.quantity__button'); + + if (quantitySelects.length === 0) return; + + const UNIT_PRICE = 1200; + + const updateAllPrices = (amount) => { + priceDisplays.forEach((display) => { + display.textContent = `${amount}$`; + }); + }; + + const updateAllButtons = (count) => { + allQuantityButtons.forEach((btn) => { + btn.textContent = count; + }); + }; + + updateAllPrices(UNIT_PRICE); + updateAllButtons(1); + + quantitySelects.forEach((quantitySelect) => { + const items = quantitySelect.querySelectorAll('.select__item'); + + items.forEach(item => { + item.addEventListener('click', () => { + const count = parseInt(item.getAttribute('data-value')) || 1; + const totalPrice = count * UNIT_PRICE; + + updateAllPrices(totalPrice); + updateAllButtons(count); + + quantitySelect.classList.remove('is-open'); + }); + }); + }); +} diff --git a/src/scripts/select.js b/src/scripts/select.js new file mode 100644 index 00000000..9bae0bfd --- /dev/null +++ b/src/scripts/select.js @@ -0,0 +1,41 @@ +export function initSelect() { + const selects = document.querySelectorAll('.select'); + + selects.forEach((select) => { + const button = select.querySelector('.select__button'); + const items = select.querySelectorAll('.select__item'); + + if (!button) return; + + button.addEventListener('click', (e) => { + e.stopPropagation(); + + document.querySelectorAll('.select.is-open').forEach(openSelect => { + if (openSelect !== select) openSelect.classList.remove('is-open'); + }); + + select.classList.toggle('is-open'); + }); + + items.forEach((item) => { + item.addEventListener('click', (e) => { + e.stopPropagation(); + + if (item.classList.contains('select__item--disabled')) return; + + button.textContent = item.textContent; + select.classList.remove('is-open'); + + const changeEvent = new Event('change'); + button.dispatchEvent(changeEvent); + }); + }); + }); + + document.addEventListener('click', () => { + document.querySelectorAll('.select.is-open').forEach(select => { + select.classList.remove('is-open'); + }); + }); +} + diff --git a/src/scripts/slider.js b/src/scripts/slider.js new file mode 100644 index 00000000..dfa40fc7 --- /dev/null +++ b/src/scripts/slider.js @@ -0,0 +1,113 @@ +export function initSlider() { + const sliders = document.querySelectorAll('[data-slider]'); + const value = document.querySelector('.product__value'); + + if (!sliders.length) return; + + sliders.forEach(sliderElement => { + const sliderId = sliderElement.dataset.slider; + const controls = document.querySelector(`[data-slider-controls="${sliderId}"]`); + + if (!controls) return; + + const images = sliderElement.querySelectorAll('.slider__image'); + const leftButton = controls.querySelector('.slider__button--left'); + const rightButton = controls.querySelector('.slider__button--right'); + const progressLine = controls.querySelector('.slider__line'); + const pagination = controls.querySelector('.slider__pagination'); + const dots = pagination?.querySelectorAll('.slider__dot'); + + if (!leftButton || !rightButton || !images.length) return; + + let currentStep = 1; + const totalSteps = images.length; + + const updateSlider = () => { + images.forEach((img, index) => { + img.classList.toggle('slider__image--active', index === currentStep - 1); + + if (sliderId === 'product') { + value.textContent = currentStep; + } + }); + + leftButton.classList.toggle('slider__button--disabled', currentStep === 1); + leftButton.classList.toggle('slider__button--active', currentStep !== 1); + + rightButton.classList.toggle('slider__button--disabled', currentStep === totalSteps); + rightButton.classList.toggle('slider__button--active', currentStep !== totalSteps); + + if (progressLine) { + progressLine.style.transform = `translateX(${(currentStep - 1) * 100}%)`; + } + + if (dots && dots.length) { + dots.forEach((dot, index) => { + dot.classList.toggle('slider__dot--active', index === currentStep - 1); + }); + } + }; + + rightButton.addEventListener('click', () => { + if (currentStep < totalSteps) { + currentStep++; + updateSlider(); + } + }); + + leftButton.addEventListener('click', () => { + if (currentStep > 1) { + currentStep--; + updateSlider(); + } + }); + + if (dots && dots.length) { + dots.forEach((dot, index) => { + dot.addEventListener('click', () => { + currentStep = index + 1; + updateSlider(); + }); + }); + } + + let touchStartX = 0; + let touchEndX = 0; + + sliderElement.addEventListener('touchstart', (e) => { + touchStartX = e.changedTouches[0].screenX; + }, { passive: true }); + + sliderElement.addEventListener('touchend', (e) => { + touchEndX = e.changedTouches[0].screenX; + handleSwipe(); + }, { passive: true }); + + const handleSwipe = () => { + const swipeThreshold = 50; + const diff = touchStartX - touchEndX; + + if (Math.abs(diff) > swipeThreshold) { + if (diff > 0 && currentStep < totalSteps) { + currentStep++; + updateSlider(); + } else if (diff < 0 && currentStep > 1) { + currentStep--; + updateSlider(); + } + } + }; + + document.addEventListener('keydown', (e) => { + if (e.key === 'ArrowLeft' && currentStep > 1) { + currentStep--; + updateSlider(); + } else if (e.key === 'ArrowRight' && currentStep < totalSteps) { + currentStep++; + updateSlider(); + } + }); + + updateSlider(); + }); +} diff --git a/src/scripts/stepper.js b/src/scripts/stepper.js new file mode 100644 index 00000000..8d3a2d6f --- /dev/null +++ b/src/scripts/stepper.js @@ -0,0 +1,33 @@ +export function initStepper() { + const steps = document.querySelectorAll('.stepper__step'); + const panels = document.querySelectorAll('.panel'); + const progressLine = document.querySelector('.stepper__line'); + + if (!steps.length || !panels.length) return { updateStepper: () => {} }; + + const updateStepper = (stepIndex) => { + steps.forEach((step, index) => { + if (index === stepIndex) { + step.classList.add('stepper__step--active'); + + if (progressLine) { + progressLine.style.transform = `translateX(${(index) * 100}%)`; + } + } else { + step.classList.remove('stepper__step--active'); + } + }); + + panels.forEach((panel, index) => { + if (index === stepIndex) { + panel.classList.add('panel--active'); + } else { + panel.classList.remove('panel--active'); + } + }); + + window.scrollTo({ top: 0, behavior: 'smooth' }); + }; + + return { updateStepper }; +} diff --git a/src/scripts/tech.js b/src/scripts/tech.js new file mode 100644 index 00000000..9847743c --- /dev/null +++ b/src/scripts/tech.js @@ -0,0 +1,31 @@ +export function initTechSpecs() { + const triggers = document.querySelectorAll('.tech__trigger'); + const blocks = document.querySelectorAll('.tech__info-block'); + + triggers.forEach(trigger => { + trigger.addEventListener('click', (e) => { + e.stopPropagation(); + + const targetId = trigger.getAttribute('data-target'); + const targetBlock = document.getElementById(targetId); + const isActive = targetBlock.classList.contains('is-visible'); + + blocks.forEach(block => block.classList.remove('is-visible')); + triggers.forEach(t => t.classList.remove('is-active')); + + if (!isActive) { + targetBlock.classList.add('is-visible'); + trigger.classList.add('is-active'); + } + }); + }); + + document.addEventListener('click', () => { + blocks.forEach(block => block.classList.remove('is-visible')); + triggers.forEach(t => t.classList.remove('is-active')); + }); + + blocks.forEach(block => { + block.addEventListener('click', (e) => e.stopPropagation()); + }); +} diff --git a/src/scripts/video.js b/src/scripts/video.js new file mode 100644 index 00000000..30844e8a --- /dev/null +++ b/src/scripts/video.js @@ -0,0 +1,35 @@ +export function initVideoModal() { + const videoModal = document.getElementById('video-modal'); + const closeBtn = document.getElementById('close-video'); + const playerContainer = document.getElementById('video-iframe-container'); + const videoButtons = document.querySelectorAll('.header__video-button, .product__video-button'); + const youtubeId = "SvTbB19bvIw"; + const videoSrc = `https://www.youtube.com/embed/${youtubeId}?autoplay=1&rel=0&wmode=opaque`; + + const openModal = (e) => { + e.preventDefault(); + + playerContainer.innerHTML = ` + `; + + videoModal.classList.add('is-open'); + document.body.style.overflow = 'hidden'; + }; + + const closeModal = () => { + videoModal.classList.remove('is-open'); + playerContainer.innerHTML = ''; + document.body.style.overflow = ''; + }; + + videoButtons.forEach(btn => btn.addEventListener('click', openModal)); + closeBtn?.addEventListener('click', closeModal); + + videoModal?.addEventListener('click', (e) => { + if (e.target === videoModal) closeModal(); + }); +} diff --git a/src/styles/_fonts.scss b/src/styles/_fonts.scss index 619b8c52..fb7bba67 100644 --- a/src/styles/_fonts.scss +++ b/src/styles/_fonts.scss @@ -1,6 +1,23 @@ @font-face { - font-family: Roboto, Arial, Helvetica, sans-serif; - src: url('../fonts/FontFont_FF.Mark.Pro.otf') format('otf'); - font-weight: normal; + font-family: Inter; + font-weight: 400; font-style: normal; + font-display: swap; + src: url('../fonts/inter-v20-latin-regular.woff2') format('woff2'); +} + +@font-face { + font-family: Inter; + font-weight: 500; + font-style: normal; + font-display: swap; + src: url('../fonts/inter-v20-latin-500.woff2') format('woff2'); +} + +@font-face { + font-family: Inter; + font-weight: 900; + font-style: normal; + font-display: swap; + src: url('../fonts/inter-v20-latin-900.woff2') format('woff2'); } diff --git a/src/styles/_typography.scss b/src/styles/_typography.scss index 1837eb46..2a56910d 100644 --- a/src/styles/_typography.scss +++ b/src/styles/_typography.scss @@ -1,3 +1,32 @@ h1 { @extend %h1; } + +h2 { + @extend %h2; +} + +h3 { + @extend %h3; +} + +button, +a, +li { + @extend %button-links; +} + +p, +summary { + @extend %p; +} + +input, +textarea, +label { + @extend %input; +} + +div { + @extend %div; +} diff --git a/src/styles/_utils.scss b/src/styles/_utils.scss index 3280c3fe..f044aad2 100644 --- a/src/styles/_utils.scss +++ b/src/styles/_utils.scss @@ -1,3 +1,4 @@ @import 'utils/vars'; @import 'utils/mixins'; @import 'utils/extends'; +@import 'utils/reset'; diff --git a/src/styles/blocks/about.scss b/src/styles/blocks/about.scss new file mode 100644 index 00000000..6c1cfe19 --- /dev/null +++ b/src/styles/blocks/about.scss @@ -0,0 +1,26 @@ +.about { + display: flex; + flex-direction: column; + gap: 79px; + + padding-block: 50px; + + background: $main-background; + + @include on-tablet { + gap: 83px; + padding-block: 70px 50px; + } + + @include on-desktop { + gap: 183px; + padding-block: 100px; + } + + @include on-large-desktop { + gap: 175px; + padding-block: 147px 156px; + } + + @include container-padding; +} diff --git a/src/styles/blocks/address.scss b/src/styles/blocks/address.scss new file mode 100644 index 00000000..c3835590 --- /dev/null +++ b/src/styles/blocks/address.scss @@ -0,0 +1,21 @@ +.address { + &__list { + display: flex; + flex-direction: column; + gap: 11px; + align-items: start; + + list-style: none; + } + + &__item { + width: fit-content; + color: inherit; + text-decoration: none; + transition: color 0.3s ease; + + &:hover { + color: $main-color; + } + } +} diff --git a/src/styles/blocks/benefits.scss b/src/styles/blocks/benefits.scss new file mode 100644 index 00000000..3ba9dd82 --- /dev/null +++ b/src/styles/blocks/benefits.scss @@ -0,0 +1,107 @@ +.benefits { + display: grid; + gap: 20px; + padding-block: 50px; + background: $main-background; + + @include container-padding; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + gap: 30px 20px; + padding-block: 70px; + } + + @include on-desktop { + gap: 20px; + padding-block: 100px 240px; + } + + @include on-large-desktop { + gap: 20px 205px; + padding-block: 158px; + } + + &__title { + margin-bottom: 10px; + + @include on-tablet { + grid-column: 1 / -1; + } + + @include on-desktop { + margin-bottom: 64px; + text-align: center; + } + } + + &__subtitle { + color: $title-color; + + @include on-tablet { + text-align: center; + } + } + + &__block { + display: flex; + flex-direction: column; + gap: 10px; + + @include on-tablet { + grid-column: span 2; + gap: 22px; + align-items: center; + } + + @include on-desktop { + grid-column: span 2; + gap: 30px; + } + + @include on-large-desktop { + gap: 84px; + } + } + + &__text { + @include on-tablet { + text-align: center; + } + } + + &__compatible { + font-size: 16px; + } + + &__image { + @include on-tablet { + background-repeat: no-repeat; + background-position: center; + background-size: contain; + transition: transform 0.3s ease; + + &--compatible { + width: 80px; + height: 79px; + background-image: url('../images/benefits/compatible.svg'); + } + + &--control { + width: 89px; + height: 81px; + background-image: url('../images/benefits/control.svg'); + } + + &--sensor { + width: 105px; + height: 79px; + background-image: url('../images/benefits/sensors.svg'); + } + + &:hover { + transform: scale(1.2); + } + } + } +} diff --git a/src/styles/blocks/bottom-bar.scss b/src/styles/blocks/bottom-bar.scss new file mode 100644 index 00000000..5e9f6cc3 --- /dev/null +++ b/src/styles/blocks/bottom-bar.scss @@ -0,0 +1,97 @@ +.bottom-bar { + display: grid; + grid-template-columns: repeat(2, 1fr); + justify-items: start; + + padding-block: 45px 50px; + + background-color: $footer-background; + + @include on-tablet { + display: flex; + grid-column: 1 / -1; + justify-content: space-between; + padding-block: 25px; + } + + @include on-desktop { + padding-block: 43px; + } + + &__link { + grid-column: 1 / -1; + margin-bottom: 15px; + } + + &__logo { + grid-column: 1 / -1; + width: 70px; + height: 14px; + transition: transform 0.3s ease; + + &:hover { + transform: scale(1.1); + } + } + + &__list { + display: flex; + flex-direction: column; + gap: 12px; + + @include on-tablet { + flex-direction: row; + gap: 40px; + } + } + + &__social { + display: flex; + flex-direction: column; + gap: 20px; + } + + &__social-media { + display: flex; + gap: 20px; + } + + &__social-icon { + cursor: pointer; + + width: 18px; + height: 18px; + + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + transition: transform 0.3s ease; + + &--facebook { + background-image: url('../images/social-media/facebook.svg'); + } + + &--x { + background-image: url('../images/social-media/x.svg'); + } + + &--youtube { + background-image: url('../images/social-media/youtube.svg'); + } + + &--reddit { + background-image: url('../images/social-media/reddit.svg'); + } + + &:hover { + transform: scale(1.2); + } + } + + &__address { + @include on-tablet { + display: none; + } + } +} diff --git a/src/styles/blocks/button.scss b/src/styles/blocks/button.scss new file mode 100644 index 00000000..abfdf0f4 --- /dev/null +++ b/src/styles/blocks/button.scss @@ -0,0 +1,32 @@ +.button { + width: 100%; + padding-block: 13px; + border: none; + border-radius: 4px; + + font-size: 14px; + color: $title-color; + text-align: center; + text-decoration: none; + + background-color: $main-color; + + transition: + color 0.3s ease, + background-color 0.3s ease; + + &:hover { + color: $main-color; + background-color: $title-color; + } + + @include on-tablet { + width: 458px; + padding-block: 16px; + font-size: 16px; + } + + @include on-desktop { + width: 200px; + } +} diff --git a/src/styles/blocks/checkout.scss b/src/styles/blocks/checkout.scss new file mode 100644 index 00000000..d0fd3310 --- /dev/null +++ b/src/styles/blocks/checkout.scss @@ -0,0 +1,27 @@ +.checkout { + pointer-events: none; + + position: fixed; + z-index: 100; + top: 0; + left: 0; + + overflow-y: auto; + display: none; + + box-sizing: border-box; + width: 100%; + height: 100%; + + opacity: 0; + background: $main-background; + + transition: opacity 0.3s ease-in-out; + + &.is-visible { + pointer-events: all; + display: flex; + flex-direction: column; + opacity: 1; + } +} diff --git a/src/styles/blocks/complete.scss b/src/styles/blocks/complete.scss new file mode 100644 index 00000000..f3360ece --- /dev/null +++ b/src/styles/blocks/complete.scss @@ -0,0 +1,38 @@ +.complete { + display: flex; + flex-direction: column; + gap: 16px; + + margin-block: 90px 185px; + + text-align: center; + + @include on-tablet { + gap: 20px; + margin-block: 180px 453px; + } + + @include on-desktop { + gap: 36px; + margin-block: 140px 270px; + } + + @include on-large-desktop { + gap: 56px; + margin-block: 236px 500px; + } + + &__button { + margin-top: 14px; + + @include on-tablet { + align-self: center; + margin-top: 30px; + } + + @include on-desktop { + width: 218px; + margin-top: 14px; + } + } +} diff --git a/src/styles/blocks/faq.scss b/src/styles/blocks/faq.scss new file mode 100644 index 00000000..daa9664f --- /dev/null +++ b/src/styles/blocks/faq.scss @@ -0,0 +1,166 @@ +.faq { + position: fixed; + z-index: 100; + top: 0; + left: 0; + + overflow-y: auto; + display: none; + + box-sizing: border-box; + width: 100%; + height: 100%; + + background-color: $menu-background; + + @include container-padding; + + &.is-open { + display: block; + animation: fade-in 0.3s ease-out; + } + + @include on-desktop { + display: none; + align-items: center; + justify-content: center; + background: radial-gradient( + circle, + transparent 20%, + rgba(0, 0, 0, 0.8) 100% + ); + + &.is-open { + display: flex; + } + } + + &__top { + display: flex; + justify-content: end; + padding-block: 20px; + + @include on-tablet { + padding-block: 34px; + } + } + + &__container { + z-index: 101; + width: 100%; + background: $menu-background; + + @include on-desktop { + scrollbar-width: none; + + overflow-y: auto; + + box-sizing: border-box; + width: 880px; + height: 550px; + padding-inline: 90px; + border-radius: 4px; + + -ms-overflow-style: none; + + &::-webkit-scrollbar { + display: none; + } + } + + @include on-large-desktop { + width: 1083px; + padding-inline: 95px; + } + } + + &__content { + display: flex; + flex-direction: column; + gap: 13px; + margin-block: 30px 15px; + + @include on-tablet { + margin-top: 30px; + } + } + + &__item { + padding-inline: 12px; + border: 1px solid $main-color; + border-radius: 4px; + } + + &__question { + cursor: pointer; + padding-block: 20px; + color: $main-color; + list-style: none; + } + + &__description { + padding-block: 25px 12px; + font-size: 12px; + color: $faq-bottom-color; + } + + &__close { + cursor: pointer; + + display: block; + + width: 20px; + height: 20px; + border: none; + + background: $main-background; + background-image: url('../images/icons/close-icon.svg'); + background-repeat: no-repeat; + background-position: center; + + transition: background-image 0.3s ease; + + &:hover { + background-image: url('../images/icons/close-hover-icon.svg'); + } + } + + &__button { + display: block; + + width: 40px; + height: 37px; + margin-top: 50px; + margin-inline: auto; + + background-image: url('../images/button/more-button.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + transition: background-image 0.3s ease; + + @include on-desktop { + margin-bottom: 50px; + } + + &:hover { + background-image: url('../images/button/more-button-hover.svg'); + } + } + + summary::-webkit-details-marker { + display: none; + } +} + +@keyframes fade-in { + from { + transform: scale(0.95); + opacity: 0; + } + to { + transform: scale(1); + opacity: 1; + } +} diff --git a/src/styles/blocks/footer.scss b/src/styles/blocks/footer.scss new file mode 100644 index 00000000..a74381ba --- /dev/null +++ b/src/styles/blocks/footer.scss @@ -0,0 +1,126 @@ +.footer { + padding-top: 50px; + background-color: $secondary-background; + + @include container-padding; + + @include on-tablet { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 22px; + padding-top: 70px; + } + + @include on-desktop { + padding-top: 103px; + } + + @include on-large-desktop { + padding-top: 156px; + } + + &__text { + margin-bottom: 32px; + + @include on-tablet { + grid-column: 1 / 4; + grid-row: 1; + } + } + + &__subtitle { + margin-bottom: 11px; + font-size: 14px; + color: $main-color; + } + + &__reply { + display: none; + + @include on-tablet { + display: flex; + flex-direction: column; + gap: 11px; + align-items: start; + } + } + + &__description { + font-size: 16px; + + @include on-tablet { + padding-block: 50px 76px; + } + } + + &__reply-mobile { + padding-block: 30px 50px; + font-size: 12px; + + @include on-tablet { + display: none; + } + } + + &__form { + display: flex; + flex-direction: column; + gap: 24px; + + @include on-tablet { + grid-column: 4 / -1; + margin-bottom: 130px; + } + + @include on-desktop { + margin-bottom: 100px; + } + + @include on-large-desktop { + margin-bottom: 205px; + } + } + + &__buttons { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 30px; + + @include on-tablet { + margin-top: 48px; + } + + @include on-desktop { + margin-top: 90px; + } + + @include on-large-desktop { + margin-top: 50px; + } + } + + &__button { + @include on-tablet { + width: 200px; + } + } + + &__top-button { + @include on-tablet { + width: 48px; + height: 48px; + + background-image: url('../images/button/footer-button.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + transition: background-image 0.3s ease; + + &:hover { + background-image: url('../images/button/footer-button-hover.svg'); + } + } + } +} diff --git a/src/styles/blocks/form.scss b/src/styles/blocks/form.scss new file mode 100644 index 00000000..610ebad0 --- /dev/null +++ b/src/styles/blocks/form.scss @@ -0,0 +1,136 @@ +.form { + &__field { + position: relative; + display: flex; + flex-direction: column; + } + + &__label { + pointer-events: none; + + position: absolute; + top: 16px; + left: 0; + + width: 100%; + + transition: all 0.3s ease; + } + + &__name { + position: absolute; + top: 0; + left: 0; + transition: + top 0.3s ease, + font-size 0.3s ease, + color 0.3s ease, + opacity 0.3s ease, + visibility 0.3s ease; + } + + &__error { + position: absolute; + top: 0; + left: 0; + + color: $error-color; + + visibility: hidden; + opacity: 0; + + transition: + opacity 0.3s ease, + visibility 0.3s ease; + } + + &__input { + box-sizing: border-box; + width: 100%; + padding: 16px 0 8px; + border: none; + border-bottom: 1px solid $input-bottom; + + color: $title-color; + + background: transparent; + outline: none; + caret-color: $main-color; + + transition: border-color 0.3s ease; + + &--textarea { + resize: none; + padding-bottom: 67px; + } + + &:focus { + border-bottom-color: $main-color; + + ~ .form__label { + .form__name { + top: -20px; + color: $main-color; + } + } + } + + &:not(:placeholder-shown) { + ~ .form__label { + .form__name { + top: -20px; + } + } + } + + &.is-invalid { + border-bottom-color: $error-color; + + ~ .form__label { + top: -2px; + color: $error-color; + + .form__name { + visibility: hidden; + opacity: 0; + } + + .form__error { + visibility: visible; + opacity: 1; + } + } + } + + &.is-valid { + border-bottom-color: $main-color; + + ~ .form__label { + color: $main-color; + } + } + } + + &__select-name { + margin-bottom: 13px; + font-size: 14px; + } + + &__select-button { + padding: 13px 16px 13px 24px; + border-radius: 4px; + color: $title-color; + background-color: $menu-background; + } + + &__select-list { + overflow-y: auto; + height: 308px; + margin-top: 3px; + border-radius: 4px; + } + + &__item { + padding-left: 24px; + } +} diff --git a/src/styles/blocks/header.scss b/src/styles/blocks/header.scss new file mode 100644 index 00000000..5db0cbd0 --- /dev/null +++ b/src/styles/blocks/header.scss @@ -0,0 +1,214 @@ +.header { + @include container-padding; + + display: grid; + grid-template-columns: repeat(2, 1fr); + background: $main-background; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + gap: 20px; + } + + @include on-desktop { + grid-template-columns: repeat(16, 1fr); + } + + &__top { + grid-column: 1 / -1; + } + + &__picture { + display: flex; + grid-column: 1 / -1; + align-items: center; + justify-content: center; + + @include on-tablet { + overflow: hidden; + grid-column: span 3; + height: 320px; + } + + @include on-desktop { + display: none; + } + } + + &__image { + transform: scale(1.3); + max-width: 100%; + height: 100%; + object-fit: cover; + + @include on-tablet { + transform: scale(1.3) translateX(-30px); + } + + @include on-desktop { + display: none; + } + } + + &__slider { + display: none; + + @include on-desktop { + display: flex; + grid-column: 7 / -1; + + width: 100%; + height: 500px; + margin-block: 100px 84px; + } + } + + &__content { + grid-column: 1 / -1; + margin-bottom: 46px; + + @include on-tablet { + grid-column: span 3; + grid-row: 2; + margin-block: 55px 61px; + } + + @include on-desktop { + display: grid; + grid-column: 1 / 7; + grid-template-columns: repeat(6, 1fr); + margin-block: 196px 84px; + } + } + + &__title { + margin-bottom: 17px; + + @include on-desktop { + grid-column: 1 / -1; + margin-bottom: 20px; + } + } + + &__description { + margin-bottom: 10px; + font-weight: 500; + + @include on-desktop { + grid-column: 2 / -1; + margin-bottom: 20px; + } + } + + &__price { + margin-bottom: 15px; + + font-size: 18px; + line-height: 100%; + color: $title-color; + text-align: center; + + @include on-tablet { + margin-bottom: 24px; + text-align: start; + } + + @include on-desktop { + grid-column: 2 / -1; + } + } + + &__video-button { + display: block; + + width: 247px; + height: 66px; + + background-image: url('../images/button/video-button.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + transition: background-image 0.3s ease; + + @include on-desktop { + grid-column: 2 / -1; + justify-self: start; + } + + &:hover { + background-image: url('../images/button/video-button-hover.svg'); + } + } + + &__button { + position: fixed; + z-index: 50; + right: 20px; + bottom: 20px; + left: 20px; + + width: auto; + + transition: + opacity 0.3s ease, + transform 0.3s ease; + + @include on-tablet { + justify-self: center; + width: 458px; + } + + @include on-desktop { + display: none; + } + } + + &__bottom { + display: none; + + @include on-desktop { + display: flex; + grid-column: 1 / -1; + align-items: center; + justify-content: space-between; + + margin-bottom: 84px; + } + + @include on-large-desktop { + margin-bottom: 100px; + } + } + + &__nav { + @include on-desktop { + display: flex; + gap: 40px; + } + } + + &__more-button { + @include on-desktop { + display: block; + + width: 40px; + height: 37px; + + background-image: url('../images/button/more-button.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + transition: background-image 0.3s ease; + + &:hover { + background-image: url('../images/button/more-button-hover.svg'); + } + } + } + + &__line { + width: 33%; + } +} diff --git a/src/styles/blocks/help.scss b/src/styles/blocks/help.scss new file mode 100644 index 00000000..d695f955 --- /dev/null +++ b/src/styles/blocks/help.scss @@ -0,0 +1,153 @@ +.help { + position: fixed; + z-index: 100; + top: 0; + left: 0; + + display: none; + + box-sizing: border-box; + width: 100%; + height: 100%; + + background-color: $menu-background; + + &.is-open { + display: block; + animation: fade-in 0.3s ease-out; + } + + @include on-tablet { + background-color: rgba(0, 0, 0, 0.7); + } + + @include on-desktop { + align-items: center; + justify-content: center; + background: radial-gradient( + circle, + transparent 20%, + rgba(0, 0, 0, 0.8) 100% + ); + + &.is-open { + display: flex; + } + } + + &__top { + display: flex; + justify-content: end; + padding-block: 20px; + + @include on-tablet { + padding-block: 34px; + } + } + + &__container { + @include container-padding; + + z-index: 101; + + box-sizing: border-box; + width: 100%; + height: 596px; + + background: $menu-background; + + @include on-desktop { + box-sizing: border-box; + width: 880px; + height: 550px; + padding-inline: 90px; + border-radius: 4px; + } + + @include on-large-desktop { + width: 1083px; + padding-inline: 95px; + } + } + + &__content { + display: flex; + flex-direction: column; + gap: 32px; + margin-block: 30px; + + @include on-tablet { + margin-top: 30px; + } + } + + &__link { + color: $main-color; + text-decoration: none; + transition: color 0.3s ease; + + &:hover { + color: $title-color; + } + } + + &__links { + display: flex; + flex-direction: column; + gap: 30px; + + @include on-tablet { + flex-direction: row; + gap: 152px; + } + } + + &__disabled { + cursor: not-allowed; + } + + &__support { + display: flex; + flex-direction: column; + gap: 20px; + align-items: start; + } + + &__address { + @include on-tablet { + gap: 20px; + } + } + + &__close { + cursor: pointer; + + display: block; + + width: 20px; + height: 20px; + border: none; + + background: $main-background; + background-image: url('../images/icons/close-icon.svg'); + background-repeat: no-repeat; + background-position: center; + + transition: background-image 0.3s ease; + + &:hover { + background-image: url('../images/icons/close-hover-icon.svg'); + } + } +} + +@keyframes fade-in { + from { + transform: scale(0.95); + opacity: 0; + } + to { + transform: scale(1); + opacity: 1; + } +} diff --git a/src/styles/blocks/language-menu.scss b/src/styles/blocks/language-menu.scss new file mode 100644 index 00000000..13004827 --- /dev/null +++ b/src/styles/blocks/language-menu.scss @@ -0,0 +1,122 @@ +.language-menu { + pointer-events: none; + + position: fixed; + top: 0; + left: 0; + transform: translateX(-100%); + + overflow: hidden; + display: flex; + flex-direction: column; + + box-sizing: border-box; + width: 100%; + height: 100%; + + opacity: 0; + + transition: + opacity 0.5s ease-in-out, + transform 0.5s ease-in-out; + + &.is-open { + pointer-events: all; + transform: translateX(0); + opacity: 1; + } + + &.is-close { + pointer-events: none; + transform: translateX(-100%); + opacity: 0; + } + + &__content { + height: 100%; + background-color: $menu-background; + + @include on-tablet { + flex-shrink: 0; + height: 620px; + } + } + + &__top { + display: flex; + justify-content: start; + padding: 20px; + + @include on-tablet { + padding: 34px; + } + } + + &__back { + cursor: pointer; + + display: block; + + width: 20px; + height: 20px; + + background-image: url('../images/icons/back-icon.svg'); + background-repeat: no-repeat; + background-position: center; + + transition: transform 0.3s ease; + + &:hover { + transform: scale(1.1); + } + } + + &__nav { + display: flex; + flex-direction: column; + } + + &__link { + cursor: not-allowed; + + display: block; + + box-sizing: border-box; + width: 100%; + padding: 10px 0 10px 22px; + border: none; + + text-align: start; + + background-color: $menu-background; + + transition: background-color 0.3s ease; + + @include on-tablet { + padding: 10px 0 10px 150px; + } + + &:hover { + background-color: $menu-background-hover; + } + + &--active { + cursor: pointer; + } + } + + &__item { + font-size: 21px; + } + + &__bottom { + display: none; + + @include on-tablet { + flex-grow: 1; + width: 100%; + height: auto; + background-color: #19153650; + } + } +} diff --git a/src/styles/blocks/meeting.scss b/src/styles/blocks/meeting.scss new file mode 100644 index 00000000..532d6496 --- /dev/null +++ b/src/styles/blocks/meeting.scss @@ -0,0 +1,84 @@ +.meeting { + @include on-tablet { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 11px; + } + + @include on-desktop { + grid-template-columns: repeat(12, 1fr); + } + + @include on-large-desktop { + grid-template-columns: repeat(16, 1fr); + } + + &__hello { + font-size: 14px; + color: $main-color; + } + + &__title { + margin-block: 11px 22px; + + @include on-tablet { + margin-bottom: 32px; + } + + @include on-desktop { + margin-top: 15px; + } + } + + &__content { + @include on-tablet { + grid-column: 1 / 5; + align-self: center; + } + + @include on-desktop { + grid-column: 1 / 5; + } + + @include on-large-desktop { + grid-column: 2 / 7; + } + } + + &__background { + display: none; + + @include on-tablet { + overflow-x: hidden; + display: block; + grid-column: 5 / -1; + height: 276px; + } + + @include on-desktop { + grid-column: 7 / -1; + height: 342px; + } + + @include on-large-desktop { + grid-column: 9 / -1; + height: 349px; + } + } + + &__image { + @include on-tablet { + width: 100%; + height: 100%; + + background-image: url('../images/about/about-background.png'); + background-repeat: no-repeat; + background-position: left; + background-size: cover; + } + + @include on-desktop { + background-size: contain; + } + } +} diff --git a/src/styles/blocks/menu.scss b/src/styles/blocks/menu.scss new file mode 100644 index 00000000..e2e3aa7f --- /dev/null +++ b/src/styles/blocks/menu.scss @@ -0,0 +1,107 @@ +.menu { + pointer-events: none; + + position: fixed; + top: 0; + left: 0; + transform: translateX(-100%); + + display: flex; + flex-direction: column; + + box-sizing: border-box; + width: 100%; + height: 100%; + + opacity: 0; + + transition: + opacity 0.5s ease-in-out, + transform 0.5s ease-in-out; + + &.is-open { + pointer-events: all; + transform: translateX(0); + opacity: 1; + } + + &.is-close { + pointer-events: none; + transform: translateX(-100%); + opacity: 0; + } + + &__content { + height: 100%; + background-color: $menu-background; + + @include on-tablet { + flex-shrink: 0; + height: 568px; + } + } + + &__top { + display: flex; + justify-content: end; + padding: 20px; + + @include on-tablet { + padding: 34px; + } + } + + &__close { + cursor: pointer; + + display: block; + + width: 20px; + height: 20px; + + background-image: url('../images/icons/close-icon.svg'); + background-repeat: no-repeat; + background-position: center; + + transition: background-image 0.3s ease; + + &:hover { + background-image: url('../images/icons/close-hover-icon.svg'); + } + } + + &__nav { + display: flex; + flex-direction: column; + } + + &__link { + display: block; + width: 100%; + padding: 10px 0 10px 22px; + transition: background-color 0.3s ease; + + @include on-tablet { + padding: 10px 0 10px 150px; + } + + &:hover { + background-color: $menu-background-hover; + } + } + + &__item { + font-size: 21px; + } + + &__bottom { + display: none; + + @include on-tablet { + flex-grow: 1; + width: 100%; + height: auto; + background-color: #19153650; + } + } +} diff --git a/src/styles/blocks/more.scss b/src/styles/blocks/more.scss new file mode 100644 index 00000000..197062f3 --- /dev/null +++ b/src/styles/blocks/more.scss @@ -0,0 +1,113 @@ +.more { + display: grid; + gap: 20px; + padding-block: 50px; + background-color: $secondary-background; + + @include container-padding; + + @include on-tablet { + grid-template-columns: repeat(6, 1fr); + gap: 30px 20px; + padding-block: 70px; + } + + @include on-desktop { + grid-template-columns: repeat(12, 1fr); + gap: 20px; + padding-block: 100px; + } + + @include on-large-desktop { + padding-block: 158px; + } + + &__description { + display: flex; + flex-direction: column; + gap: 12px; + padding-bottom: 10px; + + @include on-tablet { + grid-column: 1 / -1; + text-align: center; + } + + @include on-desktop { + padding-bottom: 83px; + } + } + + &__title { + color: $title-color; + } + + &__subtitle { + font-size: 12px; + color: $main-color; + + @include on-desktop { + font-size: 14px; + } + } + + &__block { + display: flex; + flex-direction: column; + gap: 10px; + + @include on-tablet { + grid-column: span 3; + gap: 22px; + align-items: center; + } + + @include on-desktop { + grid-column: span 3; + gap: 30px; + } + } + + &__text { + @include on-tablet { + text-align: center; + } + } + + &__image { + @include on-tablet { + background-repeat: no-repeat; + background-position: center; + background-size: contain; + transition: transform 0.3s ease; + + &--education { + width: 98px; + height: 81px; + background-image: url('../images/more/education.svg'); + } + + &--estate { + width: 84px; + height: 84px; + background-image: url('../images/more/estate.svg'); + } + + &--fitness { + width: 113px; + height: 83px; + background-image: url('../images/more/fitness.svg'); + } + + &--interactions { + width: 83px; + height: 83px; + background-image: url('../images/more/interaction.svg'); + } + + &:hover { + transform: scale(1.2); + } + } + } +} diff --git a/src/styles/blocks/nav.scss b/src/styles/blocks/nav.scss new file mode 100644 index 00000000..4bfce8d1 --- /dev/null +++ b/src/styles/blocks/nav.scss @@ -0,0 +1,20 @@ +.nav { + &__list { + list-style: none; + } + + &__item { + display: block; + + width: fit-content; + + color: $title-color; + text-decoration: none; + + transition: color 0.3s ease; + + &:hover { + color: $main-color; + } + } +} diff --git a/src/styles/blocks/order.scss b/src/styles/blocks/order.scss new file mode 100644 index 00000000..04ef441d --- /dev/null +++ b/src/styles/blocks/order.scss @@ -0,0 +1,39 @@ +.order { + @include on-desktop { + display: grid; + grid-template-columns: repeat(2, 1fr); + margin-block: 102px 97px; + } + + &__form { + display: flex; + flex-direction: column; + gap: 30px; + + @include on-tablet { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 40px; + } + } + + &__input { + background: transparent; + } + + &__button { + margin-top: 40px; + + @include on-tablet { + grid-column: 1 / -1; + justify-self: center; + margin-top: 58px; + } + + @include on-desktop { + place-self: center; + justify-self: left; + margin-top: 68px; + } + } +} diff --git a/src/styles/blocks/page.scss b/src/styles/blocks/page.scss new file mode 100644 index 00000000..0b2f8d3f --- /dev/null +++ b/src/styles/blocks/page.scss @@ -0,0 +1,10 @@ +.page { + scroll-behavior: smooth; + color: $text-color; + + &__body { + &.no-scroll { + overflow: hidden; + } + } +} diff --git a/src/styles/blocks/panel.scss b/src/styles/blocks/panel.scss new file mode 100644 index 00000000..15066f40 --- /dev/null +++ b/src/styles/blocks/panel.scss @@ -0,0 +1,8 @@ +.panel { + display: none; + + &--active { + display: block; + animation: fadeIn 0.4s ease-in-out; + } +} diff --git a/src/styles/blocks/pay.scss b/src/styles/blocks/pay.scss new file mode 100644 index 00000000..95870388 --- /dev/null +++ b/src/styles/blocks/pay.scss @@ -0,0 +1,233 @@ +.pay { + @include on-tablet { + display: grid; + grid-template-columns: repeat(12, 1fr); + + &__form-visa { + width: 54px; + height: 34px; + + background-image: url('../images/icons/visa-icon.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + } + + &__form-mastercard { + width: 54px; + height: 34px; + + background-image: url('../images/icons/mastercard-icon.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + } + + &__form-visa, + &__form-mastercard { + display: none; + transition: transform 0.3s ease; + } + + &__form-visa.is-active, + &__form-mastercard.is-active { + display: inline-block; + } + } + + @include on-desktop { + grid-template-columns: repeat(2, 1fr); + margin-block: 102px 97px; + } + + &__quantity { + margin-bottom: 53px; + + @include on-tablet { + grid-column: 1 / -1; + } + + @include on-desktop { + grid-column: 1; + } + } + + &__quantity-content { + @include on-tablet { + display: grid; + grid-column: 1 / -1; + grid-template-columns: repeat(12, 1fr); + } + + @include on-desktop { + display: flex; + gap: 86px; + justify-content: left; + } + } + + &__count { + @include on-tablet { + grid-column: 2; + } + } + + &__price { + @include on-tablet { + grid-column: 7; + } + } + + &__button { + margin-block: 40px; + + @include on-tablet { + grid-column: 1 / -1; + margin-inline: auto; + } + + @include on-desktop { + justify-self: left; + margin-top: 128px; + margin-inline: 0; + } + } + + &__form { + display: flex; + flex-direction: column; + gap: 16px; + + @include on-tablet { + grid-column: 2 / 12; + } + + @include on-desktop { + grid-column: 2; + margin-top: 80px; + } + } + + &__form-label { + position: relative; + display: block; + margin-bottom: 17px; + } + + &__form-wrapper { + display: flex; + gap: 21px; + justify-content: start; + } + + &__form-field { + flex: 1; + + max-width: 60px; + padding-bottom: 9px; + border: none; + border-bottom: 1px solid $input-bottom; + + font-size: 18px; + color: $title-color; + text-align: center; + letter-spacing: 20%; + + background: transparent; + outline: none; + + transition: border-color 0.3s ease; + + &::placeholder { + color: $input-bottom; + } + } + + &__form-error { + position: absolute; + top: 0; + left: 0; + + color: $error-color; + + visibility: hidden; + opacity: 0; + + transition: all 0.3s ease; + } + + &__form-name { + visibility: visible; + opacity: 1; + transition: all 0.3s ease; + } + + &__card-number, + &__form-date, + &__form-cvv { + position: relative; + + &:focus-within { + .pay__form-name { + color: $main-color; + } + + input { + border-color: $main-color; + } + } + + &.is-invalid { + .pay__form-name { + visibility: hidden; + opacity: 0; + } + + .pay__form-error { + display: block; + visibility: visible; + opacity: 1; + } + + input { + border-color: $error-color; + } + } + + &.is-valid { + input { + border-color: $main-color; + } + + .pay__form-name { + color: $main-color; + } + } + } + + &__form-back { + display: flex; + gap: 50px; + margin-block: 15px 40px; + } + + &__input-date { + width: 90px; + font-size: 18px; + text-align: center; + + &::placeholder { + color: $input-bottom; + } + } + + &__input-cvv { + width: 41px; + font-size: 18px; + text-align: center; + + &::placeholder { + color: $input-bottom; + } + } +} diff --git a/src/styles/blocks/product.scss b/src/styles/blocks/product.scss new file mode 100644 index 00000000..c6c7d5d4 --- /dev/null +++ b/src/styles/blocks/product.scss @@ -0,0 +1,149 @@ +.product { + @include on-tablet { + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 20px; + } + + @include on-desktop { + grid-template-columns: repeat(12, 1fr); + gap: 23px; + } + + @include on-large-desktop { + grid-template-columns: repeat(16, 1fr); + gap: 23px; + } + + &__pictures { + @include on-tablet { + grid-column: 1 / 4; + grid-row: 1; + } + + @include on-desktop { + grid-column: 3 / 8; + } + + @include on-large-desktop { + grid-column: 5 / 11; + } + } + + &__image { + aspect-ratio: 280 / 189; + + @include on-tablet { + aspect-ratio: 340 / 270; + } + + @include on-desktop { + aspect-ratio: 430 / 290; + } + + @include on-large-desktop { + aspect-ratio: 622 / 290; + } + } + + &__control { + display: none; + + @include on-desktop { + display: flex; + } + } + + &__progress { + display: none; + + @include on-desktop { + display: flex; + } + } + + &__line { + width: 20%; + } + + &__title { + margin-bottom: 20px; + + @include on-tablet { + grid-column: 4 / -1; + grid-row: 1; + margin-bottom: 0; + } + + @include on-desktop { + grid-column: 9 / -1; + } + + @include on-large-desktop { + grid-column: 12 / -1; + } + } + + &__count { + display: none; + + @include on-desktop { + display: flex; + grid-column: 2; + justify-self: right; + + font-size: 14px; + font-weight: 400; + color: $main-color; + } + + @include on-large-desktop { + grid-column: 3; + } + } + + &__content { + @include on-tablet { + grid-column: 4 / -1; + grid-row: 1; + } + + @include on-desktop { + grid-column: 9 / -1; + } + + @include on-large-desktop { + grid-column: 12 / -1; + } + } + + &__description { + margin-block: 20px 25px; + + @include on-tablet { + margin-block: 60px 20px; + } + + @include on-large-desktop { + margin-block: 70px 20px; + } + } + + &__video-button { + display: block; + + width: 247px; + height: 66px; + + background-image: url('../images/button/video-button.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + transition: background-image 0.3s ease; + + &:hover { + background-image: url('../images/button/video-button-hover.svg'); + } + } +} diff --git a/src/styles/blocks/quantity.scss b/src/styles/blocks/quantity.scss new file mode 100644 index 00000000..ed4332e6 --- /dev/null +++ b/src/styles/blocks/quantity.scss @@ -0,0 +1,111 @@ +.quantity { + @include on-tablet { + display: grid; + grid-template-columns: repeat(2, 1fr); + column-gap: 40px; + } + + &__picture { + @include on-tablet { + overflow: hidden; + display: flex; + grid-column: 1 / -1; + align-items: center; + justify-content: center; + + width: 100%; + max-height: 460px; + } + } + + &__image { + display: none; + + @include on-tablet { + transform: scale(1.2) translateX(-30px); + + display: block; + + width: 100%; + height: 100%; + + object-fit: cover; + } + + @include on-desktop { + transform: scale(1.4) translateX(-30px) translateY(-40px); + } + } + + &__content { + display: flex; + justify-content: space-evenly; + padding-block: 30px; + + @include on-tablet { + grid-column: 1 / 2; + justify-content: space-between; + padding-block: 0 48px; + } + + @include on-desktop { + padding-block: 32px 0; + } + } + + &__count { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; + + @include on-tablet { + align-items: start; + } + } + + &__price { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; + + @include on-tablet { + align-items: start; + } + } + + &__value { + font-size: 26px; + font-weight: 500; + color: $main-color; + } + + &__select { + width: 90px; + } + + &__button { + padding: 8px 11px 8px 39px; + border-radius: 4px; + + font-size: 20px; + color: $title-color; + + background-color: $menu-background; + } + + &__select-list { + overflow-y: auto; + + height: 144px; + margin-top: 3px; + border-radius: 4px; + + text-align: center; + } + + &__item { + font-size: 20px; + } +} diff --git a/src/styles/blocks/select.scss b/src/styles/blocks/select.scss new file mode 100644 index 00000000..84d4ad0c --- /dev/null +++ b/src/styles/blocks/select.scss @@ -0,0 +1,101 @@ +.select { + position: relative; + + &__button { + cursor: pointer; + + display: flex; + align-items: center; + justify-content: space-between; + + width: 100%; + border: none; + + text-align: left; + + &::after { + content: ''; + + display: block; + + width: 9px; + height: 6px; + + background-image: url('../images/icons/triangle-icon.svg'); + background-repeat: no-repeat; + background-position: center; + + transition: transform 0.3s; + } + } + + &__list { + position: absolute; + z-index: 10; + top: 100%; + left: 0; + transform: translateY(-10px); + + width: 100%; + margin: 0; + padding: 0; + + list-style: none; + + visibility: hidden; + opacity: 0; + background: $menu-background; + + transition: all 0.3s; + + @supports not selector(::-webkit-scrollbar) { + scrollbar-color: $main-color transparent; + scrollbar-width: thin; + } + + @supports selector(::-webkit-scrollbar) { + &::-webkit-scrollbar { + width: 1px; + } + + &::-webkit-scrollbar-thumb { + cursor: pointer; + background-color: $main-color; + } + + &::-webkit-scrollbar-track { + background: transparent; + } + } + } + + &__item { + cursor: pointer; + padding: 10px; + color: $title-color; + transition: + color 0.3s ease, + background-color 0.3s ease; + + &--disabled { + cursor: not-allowed; + } + + &:hover { + color: $main-color; + background-color: $menu-background-hover; + } + } + + &.is-open { + .select__list { + transform: translateY(0); + visibility: visible; + opacity: 1; + } + + .select__button::after { + transform: rotate(180deg); + } + } +} diff --git a/src/styles/blocks/slider.scss b/src/styles/blocks/slider.scss new file mode 100644 index 00000000..1a155bdf --- /dev/null +++ b/src/styles/blocks/slider.scss @@ -0,0 +1,113 @@ +.slider { + position: relative; + overflow: hidden; + + &__image { + position: absolute; + bottom: 0; + left: 0; + + width: 100%; + height: 100%; + + opacity: 0; + object-fit: cover; + object-position: center; + + transition: + opacity 0.6s ease-in-out, + transform 0.6s ease-in-out; + + &--1 { + transform: scale(1.4); + } + + &--active { + position: relative; + opacity: 1; + } + } + + &__interaction { + width: 100%; + + @include on-desktop { + width: 207px; + } + } + + &__control { + display: flex; + justify-content: space-between; + margin-bottom: 10px; + } + + &__button { + border: none; + color: $title-color; + background: transparent; + + &--disabled { + cursor: not-allowed; + color: $text-color; + } + + &--active { + cursor: pointer; + + &:hover { + color: $main-color; + } + } + } + + &__progress { + position: relative; + + overflow: hidden; + + width: 100%; + height: 1px; + + background-color: $progress-color; + } + + &__line { + height: 100%; + background-color: $main-color; + transition: transform 0.3s ease-in-out; + } + + &__pagination { + display: flex; + gap: 6px; + justify-content: center; + margin-top: 14px; + + @include on-desktop { + display: none; + } + } + + &__dot { + cursor: pointer; + + display: block; + + width: 4px; + height: 4px; + border-radius: 50%; + + background-color: $pagination; + + transition: transform 0.3s ease; + + &--active { + background-color: $pagination-active; + } + + &:hover { + transform: scale(1.6); + } + } +} diff --git a/src/styles/blocks/stepper.scss b/src/styles/blocks/stepper.scss new file mode 100644 index 00000000..d1a69258 --- /dev/null +++ b/src/styles/blocks/stepper.scss @@ -0,0 +1,164 @@ +.stepper { + &__top { + @include container-padding; + + margin-block: 20px 15px; + + @include on-tablet { + margin-block: 30px 10px; + } + + @include on-desktop { + display: grid; + grid-template-columns: repeat(4, 1fr); + margin-block: 64px 0; + } + } + + &__header { + display: flex; + justify-content: space-between; + + @include on-desktop { + grid-column: 1; + justify-content: start; + } + } + + &__logo { + width: 70px; + height: 14px; + transition: transform 0.3s ease; + + @include on-desktop { + width: 77px; + height: 16px; + } + + &:hover { + transform: scale(1.1); + } + } + + &__close { + cursor: pointer; + + display: block; + + width: 20px; + height: 20px; + border: none; + + background: $main-background; + background-image: url('../images/icons/close-icon.svg'); + background-repeat: no-repeat; + background-position: center; + + transition: background-image 0.3s ease; + + &:hover { + background-image: url('../images/icons/close-hover-icon.svg'); + } + + @include on-desktop { + display: none; + } + } + + &__steps { + display: flex; + justify-content: space-between; + margin-top: 30px; + + @include on-tablet { + justify-content: space-around; + } + + @include on-desktop { + display: grid; + grid-column: 2 / span 3; + grid-template-columns: repeat(3, 1fr); + margin-top: 0; + } + } + + &__step { + @include on-desktop { + position: relative; + width: fit-content; + } + } + + &__step--active { + color: $main-color; + + @include on-desktop { + &::after { + content: ''; + + position: absolute; + bottom: -7px; + left: 50%; + transform: translateX(-100%); + + display: block; + + width: 4px; + height: 4px; + border-radius: 50%; + + background: $main-color; + } + } + } + + &__desktop-step { + display: none; + + @include on-desktop { + display: block; + } + } + + &__mobile-step { + @include on-desktop { + display: none; + } + } + + &__status { + position: relative; + + width: 100%; + height: 1px; + margin-bottom: 30px; + + background-color: $input-bottom; + + @include on-desktop { + display: none; + } + } + + &__line { + width: 33%; + height: 100%; + background-color: $main-color; + transition: transform 0.3s ease-in-out; + } + + &__content { + @include container-padding; + } +} + +@keyframes fade-in { + from { + transform: translateY(10px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} diff --git a/src/styles/blocks/tech.scss b/src/styles/blocks/tech.scss new file mode 100644 index 00000000..5d6456ff --- /dev/null +++ b/src/styles/blocks/tech.scss @@ -0,0 +1,369 @@ +.tech { + @include container-padding; + + padding-block: 50px; + background-color: $secondary-background; + + @include on-desktop { + padding-block: 100px; + } + + @include on-large-desktop { + padding-block: 160px; + } + + &__title { + margin-bottom: 41px; + + @include on-tablet { + margin-bottom: 57px; + } + + @include on-desktop { + display: flex; + justify-content: end; + margin-right: 185px; + margin-bottom: 80px; + } + + @include on-large-desktop { + margin-right: 410px; + } + } + + &__content { + position: relative; + width: 197px; + height: 194px; + margin-inline: auto; + + @include on-tablet { + width: 358px; + height: 354px; + } + + @include on-desktop { + width: 1055px; + height: 355px; + } + + @include on-large-desktop { + width: 1175px; + } + } + + &__image { + position: absolute; + z-index: 1; + right: 0; + bottom: 0; + + width: 100%; + height: 100%; + + @include on-desktop { + left: 357px; + width: 297px; + height: 294px; + } + + @include on-large-desktop { + left: 375px; + } + } + + &__subtitle { + display: none; + + @include on-desktop { + display: block; + margin-bottom: 21px; + color: $title-color; + } + } + + &__description { + list-style: none; + } + + &__item { + font-size: 12px; + font-weight: 400; + + @include on-desktop { + font-size: 16px; + } + } + + &__trigger { + cursor: pointer; + + position: absolute; + z-index: 3; + + width: 34px; + height: 34px; + + background-image: url('../images/tech/button-open.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + transition: + transform 0.3s ease, + background-image 0.3s ease; + + &.is-active { + background-image: url('../images/tech/button-close.svg'); + } + + @include on-tablet { + width: 62px; + height: 62px; + } + + @include on-desktop { + display: none; + } + + &:hover { + transform: scale(1.1) rotate(180deg); + } + } + + &__sensor-button { + top: -11px; + left: 60px; + + @include on-tablet { + top: -27px; + left: 65px; + } + } + + &__connection-button { + bottom: 8px; + left: -17px; + + @include on-tablet { + bottom: 20px; + left: -58px; + } + } + + &__batterries-button { + top: 80px; + right: 29px; + + @include on-tablet { + top: 145px; + right: 49px; + } + } + + &__info-block { + position: absolute; + z-index: 10; + transform: translateY(-10px); + + display: block; + + width: 168px; + padding: 17px 10px 22px; + border: none; + border-radius: 4px; + + visibility: hidden; + opacity: 0; + background: $menu-background; + + transition: + opacity 0.4s ease, + transform 0.4s ease; + + @include on-desktop { + transform: none; + + padding: 0; + + visibility: visible; + opacity: 1; + background: transparent; + } + + &.is-visible { + transform: translateY(0); + visibility: visible; + opacity: 1; + } + } + + &__sensor-block { + position: absolute; + top: 28px; + left: 55px; + + @include on-tablet { + top: 41px; + } + + @include on-desktop { + top: 5px; + left: 0; + width: 250px; + height: 143px; + } + } + + &__connection-block { + position: absolute; + bottom: 47px; + left: -15px; + + @include on-tablet { + bottom: 17px; + left: 11px; + } + + @include on-desktop { + bottom: 15px; + left: 86px; + width: 241px; + height: 124px; + } + + @include on-large-desktop { + left: 0; + } + } + + &__batterries-block { + position: absolute; + top: 50px; + right: 69px; + + @include on-tablet { + top: 147px; + right: 117px; + } + + @include on-desktop { + top: 5px; + right: 0; + width: 338px; + height: 207px; + } + + @include on-large-desktop { + width: 344px; + } + } + + &__sensor-line { + display: none; + + @include on-desktop { + position: absolute; + z-index: 2; + top: 9px; + left: 101px; + + display: block; + + width: 403px; + height: 72px; + + background-image: url('../images/tech/sensor-line.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + } + + @include on-large-desktop { + left: 91px; + width: 431px; + background-image: url('../images/tech/sensor-line-large.svg'); + } + } + + &__connection-line { + display: none; + + @include on-desktop { + position: absolute; + z-index: 2; + top: 115px; + left: 226px; + + display: block; + + width: 134px; + height: 113px; + + background-image: url('../images/tech/connection-line.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + } + + @include on-large-desktop { + top: 118px; + left: 137px; + width: 241px; + background-image: url('../images/tech/connection-line-large.svg'); + } + } + + &__batterries-line { + display: none; + + @include on-desktop { + position: absolute; + z-index: 2; + top: 9px; + right: 355px; + + display: block; + + width: 192px; + height: 245px; + + background-image: url('../images/tech/batterries-line.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + } + + @include on-large-desktop { + top: 9px; + right: 365px; + width: 283px; + background-image: url('../images/tech/batterries-line-large.svg'); + } + } + + &__eclipse { + display: none; + + @include on-desktop { + position: absolute; + z-index: 2; + bottom: 54px; + left: 342px; + + display: block; + + width: 50px; + height: 201px; + + background-image: url('../images/tech/eclipse.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + } + + @include on-large-desktop { + left: 360px; + } + } +} diff --git a/src/styles/blocks/title.scss b/src/styles/blocks/title.scss new file mode 100644 index 00000000..1352418c --- /dev/null +++ b/src/styles/blocks/title.scss @@ -0,0 +1,8 @@ +.title { + color: $title-color; + + &__span { + font-weight: 400; + color: $main-color; + } +} diff --git a/src/styles/blocks/top-bar.scss b/src/styles/blocks/top-bar.scss new file mode 100644 index 00000000..df276604 --- /dev/null +++ b/src/styles/blocks/top-bar.scss @@ -0,0 +1,116 @@ +.top-bar { + display: flex; + align-items: center; + justify-content: space-between; + padding-block: 20px; + + @include on-tablet { + padding-block: 30px; + } + + @include on-desktop { + @include container-padding; + + position: fixed; + z-index: 90; + top: 0; + right: 0; + left: 0; + + background: linear-gradient( + 180deg, + #191536 0%, + rgba(25, 21, 54, 0.83) 70.31%, + rgba(25, 21, 54, 0) 100% + ); + } + + &__logo { + width: 70px; + height: 14px; + transition: transform 0.3s ease; + + @include on-desktop { + width: 77px; + height: 16px; + } + + &:hover { + transform: scale(1.1); + } + } + + &__select { + display: none; + + @include on-desktop { + display: block; + width: 46px; + } + } + + &__select-button { + color: $main-color; + background: transparent; + transition: transform 0.3s ease; + + &:hover { + transform: scale(1.1); + } + } + + &__select-list { + overflow-y: auto; + height: 132px; + border-radius: 4px; + } + + &__block { + @include on-desktop { + display: flex; + gap: 37px; + align-items: center; + } + } + + &__nav { + display: none; + + @include on-desktop { + display: flex; + gap: 37px; + } + } + + &__button { + display: none; + + @include on-desktop { + display: block; + } + } + + &__burger-menu { + cursor: pointer; + + display: block; + + width: 30px; + height: 13px; + + background-image: url('../images/icons/menu-icon.svg'); + background-repeat: no-repeat; + background-position: center; + background-size: contain; + + transition: transform 0.3s ease; + + @include on-desktop { + display: none; + } + + &:hover { + transform: scale(1.1); + } + } +} diff --git a/src/styles/blocks/video-modal.scss b/src/styles/blocks/video-modal.scss new file mode 100644 index 00000000..65b02603 --- /dev/null +++ b/src/styles/blocks/video-modal.scss @@ -0,0 +1,72 @@ +.video-modal { + position: fixed; + z-index: 500; + top: 0; + left: 0; + + display: none; + align-items: center; + justify-content: center; + + width: 100vw; + height: 100vh; + + background: radial-gradient(circle, transparent 20%, rgba(0, 0, 0, 0.9) 100%); + + &.is-open { + display: flex; + animation: fadeIn 0.3s ease-out; + } + + &__container { + position: relative; + width: 90%; + max-width: 900px; + } + + &__wrapper { + position: relative; + height: 0; + padding-bottom: 56.25%; + border-radius: 4px; + + iframe { + position: absolute; + z-index: 1; + top: 0; + left: 0; + + width: 100%; + height: 100%; + border: none; + border-radius: 4px; + + box-shadow: 0 0 30px rgba(0, 0, 0, 0.5); + } + } + + &__close { + cursor: pointer; + + position: absolute; + z-index: 99; + top: 15px; + right: 15px; + + display: block; + + width: 17px; + height: 17px; + border: none; + + background: transparent url('../images/icons/close-icon.svg') no-repeat + center; + background-size: contain; + + transition: background-image 0.3s ease; + + &:hover { + background-image: url('../images/icons/close-hover-icon.svg'); + } + } +} diff --git a/src/styles/main.scss b/src/styles/main.scss index fb9195d1..d7c9965a 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -1,7 +1,33 @@ @import 'utils'; @import 'fonts'; @import 'typography'; - -body { - background: $c-gray; -} +@import 'blocks/page'; +@import 'blocks/nav'; +@import 'blocks/address'; +@import 'blocks/button'; +@import 'blocks/select'; +@import 'blocks/form'; +@import 'blocks/title'; +@import 'blocks/header'; +@import 'blocks/slider'; +@import 'blocks/top-bar'; +@import 'blocks/menu'; +@import 'blocks/language-menu'; +@import 'blocks/more'; +@import 'blocks/about'; +@import 'blocks/product'; +@import 'blocks/meeting'; +@import 'blocks/tech'; +@import 'blocks/benefits'; +@import 'blocks/faq'; +@import 'blocks/help'; +@import 'blocks/checkout'; +@import 'blocks/panel'; +@import 'blocks/stepper'; +@import 'blocks/quantity'; +@import 'blocks/order'; +@import 'blocks/pay'; +@import 'blocks/complete'; +@import 'blocks/video-modal'; +@import 'blocks/footer'; +@import 'blocks/bottom-bar'; diff --git a/src/styles/utils/_extends.scss b/src/styles/utils/_extends.scss index d7201e7b..9ffbb64a 100644 --- a/src/styles/utils/_extends.scss +++ b/src/styles/utils/_extends.scss @@ -1,4 +1,65 @@ %h1 { - font-family: Roboto, sans-serif; + font-family: Inter, sans-serif; + font-size: 26px; + font-weight: 900; + line-height: 130%; + + @include on-desktop { + font-size: 46px; + } +} + +%h2 { + font-family: Inter, sans-serif; + font-size: 21px; + font-weight: 900; + line-height: 130%; + + @include on-desktop { + font-size: 36px; + line-height: 100%; + } +} + +%h3 { + font-family: Inter, sans-serif; + font-size: 18px; + font-weight: 900; + line-height: 100%; + + @include on-desktop { + font-size: 18px; + } +} + +%button-links { + font-family: Inter, sans-serif; + font-size: 16px; + font-weight: 500; + line-height: 150%; +} + +%p { + font-family: Inter, sans-serif; + font-size: 16px; font-weight: 400; + line-height: 150%; +} + +%input { + font-family: Inter, sans-serif; + font-size: 14px; + font-weight: 400; + line-height: 130%; +} + +%div { + font-family: Inter, sans-serif; + font-size: 12px; + font-weight: 500; + line-height: 130%; + + @include on-tablet { + font-size: 14px; + } } diff --git a/src/styles/utils/_mixins.scss b/src/styles/utils/_mixins.scss index 80c79780..154aad81 100644 --- a/src/styles/utils/_mixins.scss +++ b/src/styles/utils/_mixins.scss @@ -1,6 +1,39 @@ -@mixin hover($_property, $_toValue) { - transition: #{$_property} 0.3s; - &:hover { - #{$_property}: $_toValue; +@mixin on-mobile { + @media screen and (min-width: 320px) { + @content; + } +} + +@mixin on-tablet { + @media screen and (min-width: 640px) { + @content; + } +} + +@mixin on-desktop { + @media screen and (min-width: 1280px) { + @content; + } +} + +@mixin on-large-desktop { + @media screen and (min-width: 1920px) { + @content; + } +} + +@mixin container-padding { + padding-inline: 20px; + + @include on-tablet { + padding-inline: 34px; + } + + @include on-desktop { + padding-inline: 110px; + } + + @include on-large-desktop { + padding-inline: 254px; } } diff --git a/src/styles/utils/_reset.scss b/src/styles/utils/_reset.scss new file mode 100644 index 00000000..47fffec3 --- /dev/null +++ b/src/styles/utils/_reset.scss @@ -0,0 +1,32 @@ +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +input:-webkit-autofill:active, +textarea:-webkit-autofill, +textarea:-webkit-autofill:hover, +textarea:-webkit-autofill:focus, +textarea:-webkit-autofill:active { + -webkit-box-shadow: 0 0 0 50px transparent inset !important; + transition: background-color 999999s ease-in-out 0s; + + -webkit-text-fill-color: $title-color !important; +} + +input:-webkit-autofill:focus, +input:-webkit-autofill:active, +textarea:-webkit-autofill:focus, +textarea:-webkit-autofill:active { + border-bottom: 1px solid $main-color !important; +} + +body, +html, +ul, +p, +h1, +h2, +h3, +h4 { + margin: 0; + padding: 0; +} diff --git a/src/styles/utils/_vars.scss b/src/styles/utils/_vars.scss index aeb006ff..53dad5ee 100644 --- a/src/styles/utils/_vars.scss +++ b/src/styles/utils/_vars.scss @@ -1 +1,14 @@ -$c-gray: #eee; +$main-background: linear-gradient(107.56deg, #191536 0%, #000 100%); +$secondary-background: #05040b; +$footer-background: #000; +$menu-background: #191536; +$menu-background-hover: #110e25; +$text-color: #929292; +$title-color: #fff; +$main-color: #05c2df; +$input-bottom: #2f2f2f; +$progress-color: #212121; +$error-color: #860404; +$pagination: #484848; +$pagination-active: #ababab; +$faq-bottom-color: #545454;