diff --git a/.github/workflows/test.yml-template b/.github/workflows/test.yml-template new file mode 100644 index 000000000..8b5743ecb --- /dev/null +++ b/.github/workflows/test.yml-template @@ -0,0 +1,29 @@ +name: Test + +on: + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm test + - name: Upload HTML report(backstop data) + if: ${{ always() }} + uses: actions/upload-artifact@v2 + with: + name: report + path: backstop_data diff --git a/README.md b/README.md index a95e97afe..e7aa8fd30 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Kickstarter 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/Ujp7bCFuvuJlkn8TSbQPSZ/%E2%84%9611-(kickstarter)?node-id=19655%3A33) - Use BEM and SCSS - The design 1440px @@ -34,7 +34,7 @@ Implement landing page according to [Figma design](https://www.figma.com/file/Uj 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/Kickstarter/) + [DEMO LINK](https://FedorLey.github.io/Kickstarter/) 14. Copy `DEMO LINK` to the PR description > To update you PR repeat steps 7-11 diff --git a/index-uk.html b/index-uk.html new file mode 100644 index 000000000..13af409b3 --- /dev/null +++ b/index-uk.html @@ -0,0 +1,383 @@ + + + + + + Luna | Футуристичний бездротовий динамік + + + + + + + + + + + +
+
+ + +
+ + + + +
+
+
+ + + + +
+ +
+
+ + + + Crazybaby Hero + + +
+

Футуристична бездротова колонка

+

Звучання Luna збалансоване та плавне у всіх діапазонах частот, що робить музику природно приємною та значно більш багатогранною.

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

Футуристичний дизайн

+

Щоб надати Luna справді бездоганного вигляду, ми спеціально обрали авіаційний алюміній як матеріал і застосували як технологію тривимірного розтягування та згинання, так і техніку високоточного холодного кування.

+
+ +
+ +

Високочастотні динаміки

+

Щоб забезпечити більш багатогранне звучання, краще за один широкосмуговий динамік, наша команда оснастила Luna ще одним високочастотним динаміком (твітером), який незалежно відповідає за високі частоти.

+
+ +
+ +

Мультирум система

+

Luna від самого початку сумісна з вашим домашнім Wi-Fi. Налаштуйте кілька колонок у різних кімнатах, щоб поширити музичний досвід на весь будинок.

+
+ +
+ +

Інтуїтивна система освітлення

+

Інтуїтивно зрозумілий інтерфейс користувача дозволяє налаштувати відтінок і насиченість кольору освітлення, що відповідає будь-якому настрою та ситуації.

+
+
+
+
+ + +
+
+ + + + Presentation Image + +
+
+ + +
+
+
+ + + + Future Design + + +
+

Створено для майбутнього

+

У 2014 році група захоплених промислових дизайнерів, ветеранів інженерії та експертів з акустики заснувала crazybaby. Це компанія пристрасних людей, достатньо божевільних, щоб думати, що вони можуть кинути виклик індустрії революційними аудіопродуктами.

+ +
+
+
+
+ + +
+
+
+ + + + Future Design + + +
+

Luna Eye

+

Luna Eye — це суть цієї інноваційної світлової та аудіосистеми. Вона складається з незалежного високочастотного динаміка, світловодного компонента, купола та кільцевого орнаменту.

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

+ “Чесно кажучи, мене справді здивувало таке повне та красиве звучання з такого маленького компактного пристрою...” +

+
+ +
+ Garrett Martin + Гарретт Мартін + Креативний директор +
+
+
+
+ + +
+
+

Особливості

+ +
+
+
+

Звук і музика

+
    +
  • Потужний бас, що відчувається тілом
  • +
  • Цифрова передача аудіо без втрат
  • +
  • Просте та стабільне стерео-з'єднання
  • +
  • Чітке та чисте звучання на високих частотах
  • +
  • Потокове відтворення з хмарних сервісів та локальної бібліотеки
  • +
  • Автоматичне відтворення з останньої зупиненої пісні
  • +
+
+ +
+

Підключення

+
    +
  • Бездротове аудіо без допомоги рук
  • +
  • Bluetooth 4.0 LE
  • +
  • Wi-Fi 2.4 ГГц (802.11 b/g/n)
  • +
  • Розумне налаштування мультирум системи
  • +
  • Режим вечірки для 6 і більше пристроїв
  • +
  • Мережа кількох колонок MESHNET
  • +
+
+ +
+

Функції програми

+
    +
  • Налаштування розкладу музики
  • +
  • Пробудження з улюбленими піснями
  • +
  • Автоматичне пробудження при виявленні вдома
  • +
  • Колірне колесо
  • +
+
+
+ + + + + + Speaker components + +
+
+
+ + +
+
+

Маєте запитання?

+ +
+
+ + +
+ + +
+
+
+
+ + +
+ +
+ + diff --git a/index.html b/index.html index d339e6856..c0b27334c 100644 --- a/index.html +++ b/index.html @@ -1,19 +1,407 @@ - + - + - Title + > + Luna | Futuristic Wireless Speaker + + href="src/styles/index.scss" + > + + + + + - -

Hello Mate Academy

- + + + +
+
+ + +
+ + + + +
+
+
+ + + + +
+ +
+
+ + + + Crazybaby Hero + + +
+

Futuristic Wireless Speaker

+

Luna’s performance is balanced and smooth in all frequency ranges which makes the music both naturally pleasant and distinctly more layered.

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

Futuristic Design

+

To give Luna a truly flawless look, we specifically picked aircraft grade aluminum as its material and adopted both three-dimensional stretch-bending technology and a high precision cold forging technique.

+
+ +
+ +

Tweeter Speaker System

+

To deliver a more layered sound performance better than a sole full-range speaker, our team equipped Luna with one more tweeter speaker responsible for high-frequency sound independently.

+
+ +
+ +

Multiroom System

+

Luna is natively compatible with your home Wi-Fi. Set up multiple speakers in different rooms to expand your music experience into the entire house.

+
+ +
+ +

Intuitive Lighting System

+

An intuitive user interface allows you to adjust the hue and saturation of color for lighting that fits any mood and situation.

+
+
+
+
+ + +
+
+ + + + Presentation Image + +
+
+ + +
+
+
+ + + + Future Design + + +
+

Designed for the future

+

In 2014, a group of geeky industrial designers, engineering veterans and acoustic experts formed crazybaby. This is a bunch of passionate people who are crazy enough to think they can challenge the industry with disruptive audio products.

+ +
+
+
+
+ + +
+
+
+ + + + Future Design + + +
+

Luna Eye

+

Luna Eye is to the essence of this innovative light and audio system. It comprises an independent tweeter speaker, a light guiding component, a dome and a ring ornament.

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

+ “It really took me by surprise honestly to have such full beautiful sound that coming out of this small compact device...” +

+
+ +
+ Garrett Martin + Garrett Martin + Creative Director +
+
+
+
+ + +
+
+

Features

+ +
+
+
+

Sound & Music

+
    +
  • Feel-in-chest Base Power
  • +
  • Lossless Digital Audio Transmission
  • +
  • Easy & Stable Stereo Pairing
  • +
  • Crisp and Clear High Frequency Sound
  • +
  • Streams from Cloud Music and Local Library
  • +
  • Auto Music from Last Song Stopped
  • +
+
+ +
+

Connectivity

+
    +
  • Hands Free Wireless Audio
  • +
  • Bluetooth 4.0 LE
  • +
  • Wi-Fi 2.4 GHz (802.11 b/g/n)
  • +
  • Smart Multiroom System Set Up
  • +
  • Party Mode with 6.0 Units and above
  • +
  • MESHNET Multi Speaker Network
  • +
+
+ +
+

App Features

+
    +
  • Customize Music Schedule
  • +
  • Wake Up with Favorite Songs
  • +
  • Home Detection Auto Wake Up
  • +
  • Color Wheel
  • +
+
+
+ + + + + + Speaker components + +
+
+
+ + +
+
+

Do you have any questions?

+ +
+
+ + +
+ + +
+
+
+
+ + +
+ +
diff --git a/package-lock.json b/package-lock.json index ace1ce6c0..aaa6d39c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@mate-academy/eslint-config": "latest", "@mate-academy/jest-mochawesome-reporter": "^1.0.0", "@mate-academy/linthtml-config": "latest", - "@mate-academy/scripts": "^2.1.1", + "@mate-academy/scripts": "^2.1.3", "@mate-academy/stylelint-config": "latest", "cypress": "^13.13.0", "eslint": "^8.57.0", @@ -1875,10 +1875,11 @@ "dev": true }, "node_modules/@mate-academy/scripts": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-2.1.2.tgz", - "integrity": "sha512-gUXFdqqOfYzF9R3RSx2pCa5GLdOkxB9bFbF+dpUpzucdgGAANqOGdqpmNnMj+e3xA9YHraUWq3xo9cwe5vD9pQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-2.1.3.tgz", + "integrity": "sha512-a07wHTj/1QUK2Aac5zHad+sGw4rIvcNl5lJmJpAD7OxeSbnCdyI6RXUHwXhjF5MaVo9YHrJ0xVahyERS2IIyBQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/rest": "^17.11.2", "@types/get-port": "^4.2.0", diff --git a/package.json b/package.json index 19d2ac56e..cd8f44768 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "@mate-academy/eslint-config": "latest", "@mate-academy/jest-mochawesome-reporter": "^1.0.0", "@mate-academy/linthtml-config": "latest", - "@mate-academy/scripts": "^2.1.1", + "@mate-academy/scripts": "^2.1.3", "@mate-academy/stylelint-config": "latest", "cypress": "^13.13.0", "eslint": "^8.57.0", diff --git a/src/fonts/.gitkeep b/src/fonts/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/fonts/DINPro.woff2 b/src/fonts/DINPro.woff2 new file mode 100644 index 000000000..79f9a4c04 Binary files /dev/null and b/src/fonts/DINPro.woff2 differ diff --git a/src/fonts/Roboto-Regular-webfont.woff b/src/fonts/Roboto-Regular-webfont.woff deleted file mode 100755 index 8aa07d731..000000000 Binary files a/src/fonts/Roboto-Regular-webfont.woff and /dev/null differ diff --git a/src/images/.gitkeep b/src/images/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/images/avatar.jpg b/src/images/avatar.jpg new file mode 100644 index 000000000..0651fa867 Binary files /dev/null and b/src/images/avatar.jpg differ diff --git a/src/images/card1-desktop.jpg b/src/images/card1-desktop.jpg new file mode 100644 index 000000000..bb11ff9fe Binary files /dev/null and b/src/images/card1-desktop.jpg differ diff --git a/src/images/card1-mobile.jpg b/src/images/card1-mobile.jpg new file mode 100644 index 000000000..b0ab39ad8 Binary files /dev/null and b/src/images/card1-mobile.jpg differ diff --git a/src/images/card1-tablet.jpg b/src/images/card1-tablet.jpg new file mode 100644 index 000000000..87084a03f Binary files /dev/null and b/src/images/card1-tablet.jpg differ diff --git a/src/images/card2-desktop.jpg b/src/images/card2-desktop.jpg new file mode 100644 index 000000000..866bb90f8 Binary files /dev/null and b/src/images/card2-desktop.jpg differ diff --git a/src/images/card2-mobile.jpg b/src/images/card2-mobile.jpg new file mode 100644 index 000000000..a4ae61d1f Binary files /dev/null and b/src/images/card2-mobile.jpg differ diff --git a/src/images/card2-tablet.jpg b/src/images/card2-tablet.jpg new file mode 100644 index 000000000..75f377bb4 Binary files /dev/null and b/src/images/card2-tablet.jpg differ diff --git a/src/images/favicon.png b/src/images/favicon.png new file mode 100644 index 000000000..fc0a8cac1 Binary files /dev/null and b/src/images/favicon.png differ diff --git a/src/images/features-desktop.jpg b/src/images/features-desktop.jpg new file mode 100644 index 000000000..48030f8e2 Binary files /dev/null and b/src/images/features-desktop.jpg differ diff --git a/src/images/features.jpg b/src/images/features.jpg new file mode 100644 index 000000000..1b06c487e Binary files /dev/null and b/src/images/features.jpg differ diff --git a/src/images/hero-desktop.jpg b/src/images/hero-desktop.jpg new file mode 100644 index 000000000..8a3ed1108 Binary files /dev/null and b/src/images/hero-desktop.jpg differ diff --git a/src/images/hero-mobile.jpg b/src/images/hero-mobile.jpg new file mode 100644 index 000000000..a118cc356 Binary files /dev/null and b/src/images/hero-mobile.jpg differ diff --git a/src/images/hero-tablet.jpg b/src/images/hero-tablet.jpg new file mode 100644 index 000000000..36e779ee8 Binary files /dev/null and b/src/images/hero-tablet.jpg differ diff --git a/src/images/icons/compass.svg b/src/images/icons/compass.svg new file mode 100644 index 000000000..ffa680dba --- /dev/null +++ b/src/images/icons/compass.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/cross.svg b/src/images/icons/cross.svg new file mode 100644 index 000000000..df1397add --- /dev/null +++ b/src/images/icons/cross.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/facebook.svg b/src/images/icons/facebook.svg new file mode 100644 index 000000000..2f5d0bec2 --- /dev/null +++ b/src/images/icons/facebook.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/instagram.svg b/src/images/icons/instagram.svg new file mode 100644 index 000000000..acc91ab7f --- /dev/null +++ b/src/images/icons/instagram.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/light.svg b/src/images/icons/light.svg new file mode 100644 index 000000000..df0cb9b4c --- /dev/null +++ b/src/images/icons/light.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/images/icons/menu.svg b/src/images/icons/menu.svg new file mode 100644 index 000000000..4df42c36f --- /dev/null +++ b/src/images/icons/menu.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/images/icons/next.svg b/src/images/icons/next.svg new file mode 100644 index 000000000..bf3bd358a --- /dev/null +++ b/src/images/icons/next.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/icons/prev.svg b/src/images/icons/prev.svg new file mode 100644 index 000000000..cfab7d543 --- /dev/null +++ b/src/images/icons/prev.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/icons/speaker.svg b/src/images/icons/speaker.svg new file mode 100644 index 000000000..fd4b7550f --- /dev/null +++ b/src/images/icons/speaker.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/twitter.svg b/src/images/icons/twitter.svg new file mode 100644 index 000000000..1d928f615 --- /dev/null +++ b/src/images/icons/twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/up.svg b/src/images/icons/up.svg new file mode 100644 index 000000000..0bfb2174c --- /dev/null +++ b/src/images/icons/up.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/icons/wifi.svg b/src/images/icons/wifi.svg new file mode 100644 index 000000000..203f2f68d --- /dev/null +++ b/src/images/icons/wifi.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/logo.png b/src/images/logo.png new file mode 100644 index 000000000..2928bf4d0 Binary files /dev/null and b/src/images/logo.png differ diff --git a/src/images/presentation-desktop.jpg b/src/images/presentation-desktop.jpg new file mode 100644 index 000000000..32be892d8 Binary files /dev/null and b/src/images/presentation-desktop.jpg differ diff --git a/src/images/presentation-mobile.jpg b/src/images/presentation-mobile.jpg new file mode 100644 index 000000000..5728b859d Binary files /dev/null and b/src/images/presentation-mobile.jpg differ diff --git a/src/images/presentation-tablet.jpg b/src/images/presentation-tablet.jpg new file mode 100644 index 000000000..8a3133634 Binary files /dev/null and b/src/images/presentation-tablet.jpg differ diff --git a/src/images/quote.png b/src/images/quote.png new file mode 100644 index 000000000..dd522ddaa Binary files /dev/null and b/src/images/quote.png differ diff --git a/src/scripts/index.js b/src/scripts/index.js new file mode 100644 index 000000000..e4a924650 --- /dev/null +++ b/src/scripts/index.js @@ -0,0 +1,7 @@ +import { initSlider } from './modules/slider'; +import { initLanguage } from './modules/language'; + +document.addEventListener('DOMContentLoaded', () => { + initSlider(); + initLanguage(); +}); diff --git a/src/scripts/lib/.gitkeep b/src/scripts/lib/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/scripts/main.js b/src/scripts/main.js deleted file mode 100644 index ad9a93a7c..000000000 --- a/src/scripts/main.js +++ /dev/null @@ -1 +0,0 @@ -'use strict'; diff --git a/src/scripts/modules/language.js b/src/scripts/modules/language.js new file mode 100644 index 000000000..a7c1be994 --- /dev/null +++ b/src/scripts/modules/language.js @@ -0,0 +1,32 @@ +export const initLanguage = () => { + const currentLang = document.documentElement.lang; + const savedLang = window.localStorage.getItem('siteLang'); + + if (savedLang && savedLang !== currentLang) { + const isUkPage = window.location.href.includes('index-uk.html'); + + if (savedLang === 'uk' && !isUkPage) { + window.location.replace('index-uk.html'); + } else if (savedLang === 'en' && isUkPage) { + window.location.replace('index.html'); + } + } + + const langLinks = document.querySelectorAll('.navbar__item--language a'); + + langLinks.forEach((link) => { + link.addEventListener('click', (e) => { + e.preventDefault(); + + const targetHref = link.getAttribute('href'); + const selectedLang = targetHref.includes('index-uk.html') ? 'uk' : 'en'; + + window.localStorage.setItem('siteLang', selectedLang); + document.body.classList.add('page__body--fade-out'); + + setTimeout(() => { + window.location.href = targetHref; + }, 300); + }); + }); +}; diff --git a/src/scripts/modules/slider.js b/src/scripts/modules/slider.js new file mode 100644 index 000000000..b4e690d82 --- /dev/null +++ b/src/scripts/modules/slider.js @@ -0,0 +1,57 @@ +export const initSlider = () => { + const section = document.querySelector('.features'); + + if (!section) { + return; + } + + const track = section.querySelector('.features__track'); + const slides = section.querySelectorAll('.features__slide'); + const btnPrev = section.querySelector('.icon--prev'); + const btnNext = section.querySelector('.icon--next'); + const currentEl = section.querySelector('.pagination__active'); + const totalEl = section.querySelector('.pagination__total'); + + if (slides.length === 0) { + return; + } + + if (totalEl) { + totalEl.textContent = String(slides.length).padStart(2, '0'); + } + + const scrollToSlide = (direction) => { + const currentIndex = Math.round(track.scrollLeft / track.clientWidth); + let targetIndex = currentIndex + direction; + + if (targetIndex < 0) { + targetIndex = 0; + } + + if (targetIndex >= slides.length) { + targetIndex = slides.length - 1; + } + + track.scrollTo({ + left: track.clientWidth * targetIndex, + behavior: 'smooth', + }); + }; + + btnNext?.addEventListener('click', () => scrollToSlide(1)); + btnPrev?.addEventListener('click', () => scrollToSlide(-1)); + + track.addEventListener( + 'scroll', + () => { + let index = Math.round(track.scrollLeft / track.clientWidth); + + index = Math.max(0, Math.min(index, slides.length - 1)); + + if (currentEl) { + currentEl.textContent = String(index + 1).padStart(2, '0'); + } + }, + { passive: true }, + ); +}; diff --git a/src/styles/_fonts.scss b/src/styles/_fonts.scss deleted file mode 100644 index 45cdd5400..000000000 --- a/src/styles/_fonts.scss +++ /dev/null @@ -1,6 +0,0 @@ -@font-face { - font-family: Roboto, Arial, Helvetica, sans-serif; - src: url('../fonts/Roboto-Regular-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; -} diff --git a/src/styles/_typography.scss b/src/styles/_typography.scss deleted file mode 100644 index 1837eb46e..000000000 --- a/src/styles/_typography.scss +++ /dev/null @@ -1,3 +0,0 @@ -h1 { - @extend %h1; -} diff --git a/src/styles/_utils.scss b/src/styles/_utils.scss deleted file mode 100644 index 3280c3fe1..000000000 --- a/src/styles/_utils.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import 'utils/vars'; -@import 'utils/mixins'; -@import 'utils/extends'; diff --git a/src/styles/index.scss b/src/styles/index.scss new file mode 100644 index 000000000..543f18881 --- /dev/null +++ b/src/styles/index.scss @@ -0,0 +1,29 @@ +// --- Utilities --- // +@use './utility/normalize'; +@use './utility/variables'; +@use './utility/mixins'; +@use './utility/fonts'; +@use './utility/animations'; + +// --- Modules --- // +@use './modules/page'; +@use './modules/main'; +@use './modules/icon'; +@use './modules/button'; +@use './modules/header'; +@use './modules/logo'; +@use './modules/navbar'; +@use './modules/menu'; +@use './modules/navigation'; +@use './modules/card'; +@use './modules/form'; +@use './modules/pagination'; + +// --- Blocks --- // +@use './modules/hero'; +@use './modules/benefits'; +@use './modules/presentation'; +@use './modules/testimonials'; +@use './modules/features'; +@use './modules/questions'; +@use './modules/footer'; diff --git a/src/styles/main.scss b/src/styles/main.scss deleted file mode 100644 index fb9195d12..000000000 --- a/src/styles/main.scss +++ /dev/null @@ -1,7 +0,0 @@ -@import 'utils'; -@import 'fonts'; -@import 'typography'; - -body { - background: $c-gray; -} diff --git a/src/styles/modules/_benefits.scss b/src/styles/modules/_benefits.scss new file mode 100644 index 000000000..c68a8794c --- /dev/null +++ b/src/styles/modules/_benefits.scss @@ -0,0 +1,81 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.benefits { + &__navigation { + display: none; + + @include desktop { + display: flex; + justify-self: center; + margin-bottom: 90px; + } + } + + &__items { + @include grid; + + align-items: stretch; + + @include tablet { + row-gap: 65px; + } + } + + // --- Benefit --- // + &__item { + display: flex; + grid-column: 1 / -1; + flex-direction: column; + align-items: center; + + height: 100%; + + text-align: center; + + @include tablet { + grid-column: span 4; + } + + @include desktop { + grid-column: span 3; + } + + &:not(:first-child) { + display: none; + + @include tablet { + display: flex; + } + } + } + + &__icon { + margin-bottom: 40px; + + @include tablet { + margin-bottom: 50px; + } + + @include desktop { + margin-bottom: 30px; + } + } + + &__title { + min-height: 2.4em; + margin-bottom: 20px; + + @include text(h4); + + @include desktop { + margin-bottom: 24px; + } + } + + &__description { + @include text(secondary); + + color: $gray-400; + } +} diff --git a/src/styles/modules/_button.scss b/src/styles/modules/_button.scss new file mode 100644 index 000000000..5190947be --- /dev/null +++ b/src/styles/modules/_button.scss @@ -0,0 +1,90 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.button { + width: 150px; + height: 48px; + + @include text(button); + + text-transform: uppercase; + + @include transition(color, background-color); + + &--primary-gray { + color: #fff; + background-color: $gray-600; + + @include hover { + background-color: $gray-700; + } + + @include disabled { + background-color: $gray-200; + } + } + + &--primary-cyan { + color: #fff; + background-color: $cyan-300; + + @include hover { + background-color: $cyan-500; + } + + @include disabled { + background-color: $cyan-200; + } + } + + &--secondary-gray { + border: 1px solid $gray-600; + color: $gray-600; + + @include hover { + color: #fff; + background-color: $gray-600; + } + } + + &--secondary-cyan { + border: 1px solid $cyan-400; + color: $cyan-400; + + @include hover { + color: #fff; + background-color: $cyan-400; + } + } + + &--secondary-underline { + position: relative; + + width: unset; + height: unset; + padding-bottom: 6px; + + color: $cyan-400; + + &::after { + content: ''; + + position: absolute; + bottom: 0; + left: 0; + + width: 40%; + height: 1px; + + background-color: currentColor; + + @include transition(width); + } + + @include hover { + &::after { + width: 100%; + } + } + } +} diff --git a/src/styles/modules/_card.scss b/src/styles/modules/_card.scss new file mode 100644 index 000000000..93116936b --- /dev/null +++ b/src/styles/modules/_card.scss @@ -0,0 +1,120 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.card { + display: flex; + flex-direction: column; + + @include tablet { + flex-direction: row; + column-gap: $gap-tablet; + } + + @include desktop { + column-gap: $gap-desktop; + } + + @include hover { + .card__image { + transform: scale(1.05); + } + } + + // --- Image--- // + &__picture { + overflow: hidden; + order: 2; + margin-bottom: 30px; + + @include tablet { + flex: 1; + order: unset; + margin-bottom: 0; + margin-left: -$padding-tablet; + } + + @include desktop { + margin-left: 0; + } + } + + &__image { + aspect-ratio: 5 / 4; + width: 100%; + object-fit: cover; + + @include transition(transform); + + @include tablet { + aspect-ratio: 4 / 5; + } + + @include desktop { + aspect-ratio: 3 / 2; + } + } + + // --- Content--- // + &__content { + display: contents; + + @include tablet { + display: flex; + flex: 1; + flex-direction: column; + } + } + + &__title { + order: 1; + + @include text(h2); + + margin-bottom: 20px; + + @include tablet { + order: unset; + margin-bottom: 30px; + } + } + + &__description { + order: 3; + margin-bottom: 30px; + color: $gray-400; + + @include text(secondary); + + @include tablet { + order: unset; + margin-bottom: 60px; + } + } + + &__button { + order: 4; + width: fit-content; + + @include tablet { + order: unset; + } + } + + // --- REVERSE LOGIC --- // + &--reverse { + @include tablet { + flex-direction: row-reverse; + } + + .card__picture { + @include tablet { + margin-right: -$padding-tablet; + margin-left: 0; + } + + @include desktop { + margin-right: 0; + } + } + } +} diff --git a/src/styles/modules/_features.scss b/src/styles/modules/_features.scss new file mode 100644 index 000000000..746ebcc1d --- /dev/null +++ b/src/styles/modules/_features.scss @@ -0,0 +1,190 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.features { + &__container { + display: flex; + flex-direction: column; + row-gap: 30px; + } + + &__title { + @include text(h2); + } + + // --- Content --- // + &__content { + position: relative; + z-index: 1; + + @include grid; + + padding-top: 30px; + + @include desktop { + overflow: hidden; + + @include hover { + .features__image { + transform: scale(1.05); + } + } + } + + &::before { + content: ''; + + position: absolute; + z-index: -1; + inset: 0 (-$padding-mobile); + + background-color: #d6ecec; + + @include tablet { + right: 0; + left: 0; + } + } + + @include tablet { + padding-block: 60px 120px; + } + + @include desktop { + row-gap: 60px; + padding-block: 60px; + } + } + + &__track { + scroll-behavior: smooth; + scrollbar-width: none; + scroll-snap-type: x mandatory; + + overflow-x: auto; + display: flex; + grid-column: 1 / -1; + &::-webkit-scrollbar { + display: none; + } + + @include tablet { + grid-column: 2 / 5; + } + + @include desktop { + display: contents; + } + } + + // --- Slide --- // + &__slide { + scroll-snap-align: start; + + display: flex; + flex-direction: column; + row-gap: 20px; + + min-width: 100%; + + @include desktop { + row-gap: 30px; + min-width: auto; + + &--sound { + grid-column: 2 / 6; + grid-row: 2; + } + + &--connect { + grid-column: 2 / 7; + grid-row: 1; + } + + &--features { + grid-column: 7 / 11; + grid-row: 1; + } + } + } + + &__subtitle { + @include text(h3); + + color: $cyan-500; + } + + &__list { + display: flex; + flex-direction: column; + row-gap: 10px; + } + + &__item { + position: relative; + padding-left: 16px; + + @include text(main); + + &::before { + content: ''; + + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + + width: 6px; + height: 6px; + border-radius: $radius-round; + + background-color: $gray-600; + } + } + + // --- Pagination --- // + &__pagination { + grid-column: 1 / -1; + align-self: center; + padding-top: 50px; + + @include tablet { + grid-column: 2; + align-self: start; + } + + @include desktop { + display: none; + } + } + + // --- Image --- // + &__picture { + grid-column: 1 / -1; + margin-inline: -$padding-mobile; + + @include tablet { + position: absolute; + right: 0; + bottom: 0; + + grid-column: 4 / -1; + + margin-inline: 0; + } + + @include desktop { + grid-column: 7 / -1; + grid-row: 2; + } + } + + &__image { + width: 100%; + height: 100%; + object-fit: cover; + mix-blend-mode: darken; + + @include transition(transform); + } +} diff --git a/src/styles/modules/_footer.scss b/src/styles/modules/_footer.scss new file mode 100644 index 000000000..e336a2adc --- /dev/null +++ b/src/styles/modules/_footer.scss @@ -0,0 +1,59 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.footer { + padding-bottom: 20px; + + @include tablet { + padding-bottom: 30px; + } + + &__container { + position: relative; + + display: flex; + flex-direction: column; + row-gap: 30px; + align-items: center; + + text-align: center; + + @include tablet { + row-gap: 60px; + } + } + + &__icons { + display: flex; + column-gap: 40px; + + @include tablet { + column-gap: 50px; + } + + @include desktop { + column-gap: 40px; + } + } + + &__copyright { + @include text(secondary); + + color: $gray-300; + } + + &__up { + display: none; + + @include tablet { + position: absolute; + top: 0; + right: $padding-tablet; + display: block; + } + + @include desktop { + right: $padding-desktop; + } + } +} diff --git a/src/styles/modules/_form.scss b/src/styles/modules/_form.scss new file mode 100644 index 000000000..0d1b2a57f --- /dev/null +++ b/src/styles/modules/_form.scss @@ -0,0 +1,56 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.form { + &__inputs { + display: flex; + flex-direction: column; + row-gap: 20px; + margin-bottom: 30px; + } + + &__input { + width: 100%; + padding: 12px 20px; + border: 1px solid $gray-400; + + color: $gray-600; + + outline: 0; + + @include text(main); + @include transition(color, border-color); + + &::placeholder { + color: $gray-300; + + @include transition(color); + } + + @include hover { + border-color: $cyan-500; + + &::placeholder { + color: $cyan-500; + } + } + + &:focus { + border-color: $cyan-500; + } + + &--textarea { + resize: vertical; + min-height: 128px; + } + } + + &__button { + width: 100px; + height: 40px; + + @include desktop { + width: 140px; + } + } +} diff --git a/src/styles/modules/_header.scss b/src/styles/modules/_header.scss new file mode 100644 index 000000000..64471a950 --- /dev/null +++ b/src/styles/modules/_header.scss @@ -0,0 +1,54 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.header { + flex-shrink: 0; + height: 80px; + + @include flex-center; + + &__container { + display: flex; + align-items: center; + justify-content: space-between; + } + + // --- Items --- // + &__items { + display: flex; + align-items: center; + + @include tablet { + column-gap: 30px; + } + + @include desktop { + column-gap: 50px; + } + } + + // --- Navbar --- // + &__navbar { + display: none; + + @include tablet { + display: flex; + } + } + + // --- Button --- // + &__button { + display: none; + + @include tablet { + display: block; + width: 100px; + } + } + + &__burger { + @include desktop { + display: none; + } + } +} diff --git a/src/styles/modules/_hero.scss b/src/styles/modules/_hero.scss new file mode 100644 index 000000000..48bc78db8 --- /dev/null +++ b/src/styles/modules/_hero.scss @@ -0,0 +1,64 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.hero { + &__container { + @include grid; + + row-gap: 40px; + align-items: end; + } + + // --- Image --- // + &__picture { + grid-column: 1 / -1; + margin-inline: -$padding-mobile; + + @include tablet { + grid-column: 4 / -1; + grid-row: 1; + margin-inline: 0; + } + + @include desktop { + grid-column: 5 / -1; + margin-left: -$gap-desktop; + } + } + + &__image { + width: 100%; + height: 100%; + object-fit: cover; + } + + // --- Content --- // + &__content { + display: grid; + grid-column: 1 / 5; + grid-template-columns: subgrid; + row-gap: 20px; + align-items: end; + + @include tablet { + grid-row: 1; + row-gap: 30px; + } + } + + &__title { + grid-column: 1 / -1; + + @include text(h1); + } + + &__description { + grid-column: 1 / -1; + + @include text(main); + + @include tablet { + grid-column: 1 / 4; + } + } +} diff --git a/src/styles/modules/_icon.scss b/src/styles/modules/_icon.scss new file mode 100644 index 000000000..8efbe41e5 --- /dev/null +++ b/src/styles/modules/_icon.scss @@ -0,0 +1,155 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.icon { + display: inline-block; + width: 24px; + height: 24px; + background-color: currentColor; + + @include transition(background-color); + + &--menu { + width: 32px; + height: 32px; + + @include mask-contain('/src/images/icons/menu.svg'); + + @include hover { + background-color: $cyan-500; + } + } + + &--cross { + @include mask-contain('/src/images/icons/cross.svg'); + + width: 32px; + height: 32px; + + -webkit-mask-size: 24px; + mask-size: 24px; + + @include hover { + background-color: $cyan-500; + } + } + + &--compass { + width: 50px; + height: 40px; + + @include mask-contain('/src/images/icons/compass.svg'); + + @include desktop { + width: 70px; + height: 50px; + } + } + + &--speaker { + width: 50px; + height: 40px; + + @include mask-contain('/src/images/icons/speaker.svg'); + + @include desktop { + width: 70px; + height: 50px; + } + } + + &--wifi { + width: 50px; + height: 40px; + + @include mask-contain('/src/images/icons/wifi.svg'); + + @include desktop { + width: 70px; + height: 50px; + } + } + + &--light { + width: 50px; + height: 40px; + + @include mask-contain('/src/images/icons/light.svg'); + + @include desktop { + width: 70px; + height: 50px; + } + } + + &--prev { + width: 48px; + height: 13px; + + @include mask-contain('/src/images/icons/prev.svg'); + + background-color: $gray-300; + + @include hover { + background-color: $cyan-500; + } + } + + &--next { + width: 48px; + height: 13px; + + @include mask-contain('/src/images/icons/next.svg'); + + background-color: $gray-600; + + @include hover { + background-color: $cyan-500; + } + } + + &--facebook { + @include mask-contain('/src/images/icons/facebook.svg'); + + @include hover { + background-color: $cyan-500; + } + } + + &--twitter { + @include mask-contain('/src/images/icons/twitter.svg'); + + @include hover { + background-color: $cyan-500; + } + } + + &--instagram { + @include mask-contain('/src/images/icons/instagram.svg'); + + @include hover { + background-color: $cyan-500; + } + } + + &--up { + @include mask-contain('/src/images/icons/up.svg'); + + -webkit-mask-size: 24px; + mask-size: 24px; + + @include tablet { + width: 50px; + height: 50px; + } + + @include desktop { + width: 24px; + height: 24px; + } + + @include hover { + background-color: $cyan-500; + } + } +} diff --git a/src/styles/modules/_logo.scss b/src/styles/modules/_logo.scss new file mode 100644 index 000000000..73e944630 --- /dev/null +++ b/src/styles/modules/_logo.scss @@ -0,0 +1,9 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.logo { + &__image { + width: 160px; + height: auto; + } +} diff --git a/src/styles/modules/_main.scss b/src/styles/modules/_main.scss new file mode 100644 index 000000000..05ada5c04 --- /dev/null +++ b/src/styles/modules/_main.scss @@ -0,0 +1,17 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.main { + display: flex; + flex-direction: column; + flex-grow: 1; + row-gap: $sections-gap-mobile; + + @include tablet { + row-gap: $sections-gap-tablet; + } + + @include desktop { + row-gap: $sections-gap-desktop; + } +} diff --git a/src/styles/modules/_menu.scss b/src/styles/modules/_menu.scss new file mode 100644 index 000000000..359c1df58 --- /dev/null +++ b/src/styles/modules/_menu.scss @@ -0,0 +1,54 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.menu { + pointer-events: none; + + z-index: $z-header; + + display: flex; + flex-direction: column; + row-gap: 30px; + + height: 100vh; + + opacity: 0; + background-color: #f9f9f9; + + @include transition(opacity); + + @include tablet { + row-gap: 40px; + } + + @include desktop { + display: none; + } + + &--open { + pointer-events: auto; + opacity: 1; + } + + &__container { + display: flex; + flex-direction: column; + row-gap: 50px; + height: 100%; + } + + &__navbar { + @include tablet { + display: none; + } + } + + &__button { + width: 100%; + margin-block: auto 30px; + + @include tablet { + display: none; + } + } +} diff --git a/src/styles/modules/_navbar.scss b/src/styles/modules/_navbar.scss new file mode 100644 index 000000000..fb6ba83c2 --- /dev/null +++ b/src/styles/modules/_navbar.scss @@ -0,0 +1,37 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.navbar { + &__items { + display: flex; + column-gap: 20px; + } + + &__item { + &--language { + color: $gray-600; + } + } + + &__link { + font-size: 14px; + font-weight: 400; + line-height: 20px; + color: $gray-500; + text-transform: uppercase; + + @include transition(color); + + &--active { + pointer-events: none; + } + + &--unactive { + color: $gray-300; + } + + @include hover { + color: $cyan-500; + } + } +} diff --git a/src/styles/modules/_navigation.scss b/src/styles/modules/_navigation.scss new file mode 100644 index 000000000..7f693de59 --- /dev/null +++ b/src/styles/modules/_navigation.scss @@ -0,0 +1,48 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.navigation { + &__items { + display: flex; + flex-direction: column; + row-gap: 25px; + + @include tablet { + row-gap: 40px; + } + + @include desktop { + flex-direction: row; + column-gap: 80px; + } + } + + &__link { + font-size: 14px; + font-weight: 400; + line-height: 20px; + text-transform: uppercase; + + @include transition(color); + + @include tablet { + font-size: 22px; + line-height: 28px; + } + + @include desktop { + font-size: 14px; + line-height: 20px; + } + + @include hover { + color: $cyan-500; + } + + &--active { + pointer-events: none; + font-weight: 700; + color: $gray-700; + } + } +} diff --git a/src/styles/modules/_page.scss b/src/styles/modules/_page.scss new file mode 100644 index 000000000..3f632448c --- /dev/null +++ b/src/styles/modules/_page.scss @@ -0,0 +1,48 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.page { + scroll-behavior: smooth; + height: 100%; + + &__body { + display: flex; + flex-direction: column; + + min-width: 320px; + min-height: 100%; + + font-family: $font-main; + color: $gray-600; + + background-color: $gray-100; + + @include animation(fade-in); + @include transition(opacity); + + &--fade-out { + opacity: 0; + } + + &--no-scroll { + overflow: hidden; + } + } + + &__menu { + position: fixed; + inset: 0; + } + + &__main { + margin-bottom: $sections-gap-mobile; + + @include tablet { + margin-bottom: $sections-gap-tablet; + } + + @include desktop { + margin-bottom: $sections-gap-desktop; + } + } +} diff --git a/src/styles/modules/_pagination.scss b/src/styles/modules/_pagination.scss new file mode 100644 index 000000000..baddfbf6b --- /dev/null +++ b/src/styles/modules/_pagination.scss @@ -0,0 +1,27 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.pagination { + display: flex; + flex-direction: column; + row-gap: 8px; + align-items: center; + + &__arrows { + display: flex; + column-gap: -2px; + } + + &__page { + font-family: 'DIN Pro', sans-serif; + font-size: 11px; + font-weight: 400; + line-height: 100%; + color: $gray-300; + } + + &__active { + font-size: 16px; + color: $gray-600; + } +} diff --git a/src/styles/modules/_presentation.scss b/src/styles/modules/_presentation.scss new file mode 100644 index 000000000..8fbe8cde1 --- /dev/null +++ b/src/styles/modules/_presentation.scss @@ -0,0 +1,35 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.presentation { + &__container { + @include grid; + } + + &__picture { + grid-column: 1 / -1; + margin-inline: -$padding-mobile / 2; + + @include tablet { + margin-inline: 0; + } + + @include desktop { + grid-column: 3 / 11; + margin-inline: -$gap-desktop; + } + } + + &__image { + width: 100%; + height: 100%; + object-fit: cover; + mix-blend-mode: darken; + + @include transition(transform); + + @include hover { + transform: scale(1.05); + } + } +} diff --git a/src/styles/modules/_questions.scss b/src/styles/modules/_questions.scss new file mode 100644 index 000000000..1cb31345a --- /dev/null +++ b/src/styles/modules/_questions.scss @@ -0,0 +1,31 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.questions { + &__container { + display: flex; + flex-direction: column; + row-gap: 30px; + + @include tablet { + flex-direction: row; + gap: 0 $gap-tablet; + } + + @include desktop { + column-gap: $gap-desktop; + } + } + + &__title { + flex: 1; + + @include text(h2); + } + + &__form { + display: flex; + flex: 1; + flex-direction: column; + } +} diff --git a/src/styles/modules/_testimonials.scss b/src/styles/modules/_testimonials.scss new file mode 100644 index 000000000..45323d16f --- /dev/null +++ b/src/styles/modules/_testimonials.scss @@ -0,0 +1,85 @@ +@use '../utility/variables' as *; +@use '../utility/mixins' as *; + +.testimonials { + &__container { + @include grid; + } + + &__testimonial { + display: flex; + grid-column: 1 / -1; + flex-direction: column; + row-gap: 30px; + + text-align: center; + + @include tablet { + row-gap: 40px; + } + + @include desktop { + grid-column: 3 / 11; + row-gap: 30px; + } + } + + &__quote { + position: relative; + display: grid; + place-items: end center; + + @include desktop { + place-items: center; + } + + &::before { + pointer-events: none; + content: ''; + + z-index: -1; + + grid-area: 1 / 1; + + width: 208px; + height: 170px; + + @include image-contain('/src/images/quote.png'); + } + } + + &__text { + grid-area: 1 / 1; + + @include text(quote); + } + + &__author { + display: flex; + flex-direction: column; + align-items: center; + } + + &__avatar { + aspect-ratio: 1 / 1; + width: 64px; + margin-bottom: 10px; + border-radius: $radius-round; + + object-fit: cover; + + @include tablet { + margin-bottom: 20px; + } + } + + &__name { + @include text(h5); + + margin-bottom: 5px; + } + + &__position { + @include text(secondary); + } +} diff --git a/src/styles/utility/_animations.scss b/src/styles/utility/_animations.scss new file mode 100644 index 000000000..c33ac4a3b --- /dev/null +++ b/src/styles/utility/_animations.scss @@ -0,0 +1,8 @@ +@keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } +} diff --git a/src/styles/utility/_fonts.scss b/src/styles/utility/_fonts.scss new file mode 100644 index 000000000..fd3989aaa --- /dev/null +++ b/src/styles/utility/_fonts.scss @@ -0,0 +1,7 @@ +@font-face { + font-family: 'DIN Pro'; + font-weight: 400; + font-style: normal; + font-display: swap; + src: url('../fonts/DINPro.woff2') format('woff2'); +} diff --git a/src/styles/utility/_mixins.scss b/src/styles/utility/_mixins.scss new file mode 100644 index 000000000..33c5a25a1 --- /dev/null +++ b/src/styles/utility/_mixins.scss @@ -0,0 +1,172 @@ +@use './variables.scss' as *; +@use 'sass:list'; +@use 'sass:map'; + +// --- Responsive --- // +@mixin tablet { + @media (min-width: $bp-tablet) { + @content; + } +} + +@mixin desktop { + @media (min-width: $bp-desktop) { + @content; + } +} + +// --- Layout --- // +@mixin content-padding { + width: 100%; + margin-inline: auto; + padding-inline: $padding-mobile; + + @include tablet { + padding-inline: $padding-tablet; + } + + @include desktop { + padding-inline: $padding-desktop; + } +} + +.container { + @include content-padding; + + @include desktop { + max-width: $bp-desktop; + } +} + +// --- Grid & Flex --- // +@mixin grid($row-gap: false) { + --columns: #{$cols-mobile}; + + display: grid; + grid-template-columns: repeat(var(--columns), 1fr); + + @if $row-gap { + row-gap: $gap-mobile; + } + + column-gap: $gap-mobile; + + @include tablet { + --columns: #{$cols-tablet}; + + @if $row-gap { + row-gap: $gap-tablet; + } + + column-gap: $gap-tablet; + } + + @include desktop { + --columns: #{$cols-desktop}; + + @if $row-gap { + row-gap: $gap-desktop; + } + + column-gap: $gap-desktop; + } +} + +@mixin flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +// --- Typography --- // +@mixin text($level) { + $config: map.get($type-scale, $level); + $desktop-size: list.nth($config, 1); + $tablet-size: list.nth($config, 2); + $mobile-size: list.nth($config, 3); + $desktop-lh: list.nth($config, 4); + $tablet-lh: list.nth($config, 5); + $mobile-lh: list.nth($config, 6); + $weight: list.nth($config, 7); + $family: list.nth($config, 8); + $transform: list.nth($config, 9); + + font-family: $family; + font-size: $mobile-size; + font-weight: $weight; + line-height: $mobile-lh; + text-transform: $transform; + + @include tablet { + font-size: $tablet-size; + line-height: $tablet-lh; + } + + @include desktop { + font-size: $desktop-size; + line-height: $desktop-lh; + } +} + +@mixin line-clamp($lines: 2) { + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: $lines; +} + +// --- Interactions --- // +@mixin transition($property...) { + transition-timing-function: $transition-function; + transition-duration: $transition-speed; + transition-property: $property; +} + +@mixin animation($name) { + animation-name: $name; + animation-duration: $transition-speed; + animation-timing-function: $transition-function; +} + +@mixin hover { + @media (hover: hover) { + &:hover { + @content; + } + } +} + +@mixin pressed { + &:active { + @content; + } +} + +@mixin disabled { + &:disabled, + &.disabled { + pointer-events: none; + cursor: not-allowed; + @content; + } +} + +// --- Visuals --- // +@mixin image-cover($path) { + background-image: url($path); + background-repeat: no-repeat; + background-position: center; + background-size: cover; +} + +@mixin image-contain($path) { + background-image: url($path); + background-repeat: no-repeat; + background-position: center; + background-size: contain; +} + +@mixin mask-contain($url) { + -webkit-mask: url($url) no-repeat center / contain; + mask: url($url) no-repeat center / contain; +} diff --git a/src/styles/utility/_normalize.scss b/src/styles/utility/_normalize.scss new file mode 100644 index 000000000..4523b01a7 --- /dev/null +++ b/src/styles/utility/_normalize.scss @@ -0,0 +1,152 @@ +//////////////////// +// --- Global --- // +//////////////////// + +*, +::after, +::before, +::backdrop, +::file-selector-button { + box-sizing: border-box; + margin: 0; + padding: 0; + border: 0 solid; +} + +////////////////// +// --- Page --- // +////////////////// + +html { + scrollbar-gutter: stable; + font-family: sans-serif; + -webkit-text-size-adjust: 100%; +} + +body { + -webkit-font-smoothing: antialiased; + line-height: inherit; +} + +///////////////////////// +// --- Typographic --- // +///////////////////////// + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +ol, +ul, +menu { + list-style: none; +} + +a { + color: inherit; + text-decoration: none; +} + +cite { + font-style: normal; +} + +hr { + width: 100%; + height: 1px; + background-color: white; +} + +address { + font-style: normal; +} + +/////////////////// +// --- Media --- // +/////////////////// + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object, +details { + display: block; +} + +img, +video { + max-width: 100%; + height: auto; +} + +/////////////////// +// --- Table --- // +/////////////////// + +table { + border-spacing: 0; + border-collapse: collapse; + border-color: inherit; + text-indent: 0; +} + +///////////////////////////// +// --- Forms & Buttons --- // +///////////////////////////// + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + font-size: 100%; + line-height: inherit; + color: inherit; + + appearance: none; + background-color: transparent; +} + + +button, +[type='button'], +[type='reset'], +[type='submit'] { + cursor: pointer; +} + +textarea { + resize: vertical; +} + +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 { + transition: background-color 9999s ease-in-out 0s; + + -webkit-text-fill-color: inherit; +} + +///////////////////// +// --- Utility --- // +///////////////////// + +[hidden]:where(:not([hidden='until-found'])) { + display: none !important; +} diff --git a/src/styles/utility/_variables.scss b/src/styles/utility/_variables.scss new file mode 100644 index 000000000..f4c85af64 --- /dev/null +++ b/src/styles/utility/_variables.scss @@ -0,0 +1,71 @@ +// --- Fonts --- // +$font-title: 'Inter', sans-serif; +$font-main: 'Inter', sans-serif; + +// --- Colors --- // +// Cyan group +$cyan-500: #0c797a; +$cyan-400: #0db2b3; +$cyan-300: #39bebf; +$cyan-200: #cfeff0; +$cyan-100: #eefafa; + +// Gray group +$gray-700: #131313; +$gray-600: #333; +$gray-500: #4f4f4f; +$gray-400: #7c7c7c; +$gray-300: #bdbdbd; +$gray-200: #d0d0d0; +$gray-100: #f7f7f7; + +// --- Breakpoints --- // +$bp-tablet: 744px; +$bp-desktop: 1440px; + +// --- Layout --- // +$padding-mobile: 30px; +$padding-tablet: 34px; +$padding-desktop: 123px; +$gap-mobile: 20px; +$gap-tablet: 20px; +$gap-desktop: 30px; +$sections-gap-mobile: 110px; +$sections-gap-tablet: 140px; +$sections-gap-desktop: 170px; +$cols-mobile: 4; +$cols-tablet: 8; +$cols-desktop: 12; + +// --- UI --- // +$z-under: -1; +$z-base: 0; +$z-above: 1; +$z-dropdown: 50; +$z-header: 100; +$z-modal: 1000; +$radius-sm: 4px; +$radius-md: 8px; +$radius-lg: 16px; +$radius-round: 50%; +$shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05); +$shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1); +$shadow-lg: 0 12px 24px rgba(0, 0, 0, 0.15); +$transition-speed: 0.3s; +$transition-function: ease-out; + +// --- Typography --- // +$type-scale: ( + // Level: (D-size, T-size, M-size, D-lh, T-lh, M-lh, weight, family, transform) + h1: (64px, 48px, 40px, 78px, 62px, 52px, 700, $font-title, uppercase), + h2: (56px, 36px, 30px, 70px, 46px, 40px, 700, $font-title, uppercase), + h3: (34px, 24px, 18px, 42px, 30px, 22px, 700, $font-title, uppercase), + h4: (22px, 22px, 22px, 28px, 28px, 28px, 700, $font-title, uppercase), + h5: (16px, 16px, 16px, 22px, 22px, 22px, 700, $font-title, none), + h6: (14px, 14px, 14px, 20px, 20px, 20px, 700, $font-title, uppercase), + button: (12px, 12px, 12px, 14px, 14px, 14px, 500, $font-main, uppercase), + main: (16px, 16px, 16px, 24px, 24px, 24px, 400, $font-main, none), + secondary: (14px, 14px, 14px, 21px, 21px, 21px, 400, $font-main, none), + thirdary: (14px, 14px, 14px, 21px, 21px, 21px, 400, $font-main, uppercase), + quote: (24px, 24px, 14px, 36px, 36px, 20px, 700, $font-main, none) +); diff --git a/src/styles/utils/_extends.scss b/src/styles/utils/_extends.scss deleted file mode 100644 index d7201e7b3..000000000 --- a/src/styles/utils/_extends.scss +++ /dev/null @@ -1,4 +0,0 @@ -%h1 { - font-family: Roboto, sans-serif; - font-weight: 400; -} diff --git a/src/styles/utils/_mixins.scss b/src/styles/utils/_mixins.scss deleted file mode 100644 index 80c79780d..000000000 --- a/src/styles/utils/_mixins.scss +++ /dev/null @@ -1,6 +0,0 @@ -@mixin hover($_property, $_toValue) { - transition: #{$_property} 0.3s; - &:hover { - #{$_property}: $_toValue; - } -} diff --git a/src/styles/utils/_vars.scss b/src/styles/utils/_vars.scss deleted file mode 100644 index aeb006ffb..000000000 --- a/src/styles/utils/_vars.scss +++ /dev/null @@ -1 +0,0 @@ -$c-gray: #eee; diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 000000000..65fbb333d --- /dev/null +++ b/vite.config.js @@ -0,0 +1,13 @@ +import { defineConfig } from 'vite'; + +export default defineConfig({ + base: '/Kickstarter/', + build: { + rollupOptions: { + input: { + main: './index.html', + uk: './index-uk.html', + }, + }, + }, +});