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/index.html b/index.html index d339e6856..b0cb69979 100644 --- a/index.html +++ b/index.html @@ -1,19 +1,501 @@ - + - Title + NAMU + + + + -

Hello Mate Academy

- + +
+
+
+ 30 квітня - 30 листопада +
+ + + +
+ + UA- +
+
+ + +
+ +
+
+ 30 квітня – 30 листопада +

+ Мистецтво XIX – XX ст. +

+

+ Внесок українських митців у світову культуру до XXI +

+ + Купити квиток + +
+ 01 + / + 04 +
+
+
+ Мистецтво XIX-XX ст. +
+
+ +
+
+

Актуальні виставки

+ + Архів виставок → + +
+ +
+
+
+ Кураторська виставка "Ангели" +
+
+ 11.07 - 31.08 +

+ Кураторська виставка “Ангели” +

+

+ Виставковий проект «Ангели» — знакова подія для + української культури і широкої глядацької аудиторії + впродовж сімнадцяти. +

+ + Купити квиток + +
+
+ +
+
+ Мистецтво XX ст. – XXI ст. +
+
+ 06 листопад +

+ Мистецтво XX ст. – XXI ст. +

+

+ Знакові роботи Анни Горської, Миколи Самокиша, + Федора Кричевського та інших митців. +

+ + Купити квиток + +
+
+
+
+ +
+
+

Найближчі події

+ + Календар подій → + +
+ +
+
+
+ Кураторські екскурсії від Павла Гудімова +
+
+ 14/8 в 13:00 +

+ Кураторські екскурсії від Павла Гудімова +

+

+ Таємниця творчості, складний мистецький шлях — все це + та ні цього немає в нашій пропозиції — розпочинається + нова глава. +

+ + Зареєструватись + +
+
+ +
+ +
+
+ Майстер-клас «Подорож до Австралії» +
+
+ 20/8 в 15:00 +

+ Майстер-клас «Подорож до Австралії» +

+

+ Цей майстер-клас від нас арт-мандрівника можна + вважати останнім пунктом кругосвітньої подорожі — + тестів є. +

+ + Зареєструватись + +
+
+
+
+ +
+
+
+

+ Сплануйте візит до музею +

+

+ Оберіть зручний день, зареєструйтеся на той захід, що + цікавить вас, або просто завітайте до нас — ми завжди + раді допомогти вам насолодитися мистецтвом. +

+ + Почати + +
+
+ Сплануйте візит до музею +
+
+
+ +
+
+

Новини

+ + Усі новини → + +
+ +
+
+
+ Оголошення переможця +
+
+ 5 травня 2022 +

Оголошення переможця

+

+ Друга картина Поляці Поляця для А це більш обмежений + видатних успіхів що здобув перемогу розповсюджується. +

+
+
+ +
+
+ Міжнародний день котів +
+
+ 5 травня 2022 +

Міжнародний день котів

+

+ Музей у своєму розмаїтті простих вагань перетворює + Міжнародний день котів на нечувано яскраву подію. +

+
+
+
+
+ +
+
+ + + +
+
+ + + + diff --git a/package-lock.json b/package-lock.json index 5d3b07d5a..6b9fd05c4 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 9e79dfff1..4cd3200dd 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/images/event-gudimov.jpg b/src/images/event-gudimov.jpg new file mode 100644 index 000000000..773ff0648 Binary files /dev/null and b/src/images/event-gudimov.jpg differ diff --git a/src/images/event-masterclass.jpg b/src/images/event-masterclass.jpg new file mode 100644 index 000000000..1a65f4685 Binary files /dev/null and b/src/images/event-masterclass.jpg differ diff --git a/src/images/exhibition-angels.jpg b/src/images/exhibition-angels.jpg new file mode 100644 index 000000000..4ed273a9d Binary files /dev/null and b/src/images/exhibition-angels.jpg differ diff --git a/src/images/exhibition-art.jpg b/src/images/exhibition-art.jpg new file mode 100644 index 000000000..e0f8c39ec Binary files /dev/null and b/src/images/exhibition-art.jpg differ diff --git a/src/images/facebook.svg b/src/images/facebook.svg new file mode 100644 index 000000000..ebf5c7794 --- /dev/null +++ b/src/images/facebook.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/hero-girl.svg b/src/images/hero-girl.svg new file mode 100644 index 000000000..b7632d0cb --- /dev/null +++ b/src/images/hero-girl.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/instagram.svg b/src/images/instagram.svg new file mode 100644 index 000000000..0050e7dfb --- /dev/null +++ b/src/images/instagram.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/logo.svg b/src/images/logo.svg new file mode 100644 index 000000000..feeec5150 --- /dev/null +++ b/src/images/logo.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/images/menu-portrait.jpg b/src/images/menu-portrait.jpg new file mode 100644 index 000000000..2cec940e9 Binary files /dev/null and b/src/images/menu-portrait.jpg differ diff --git a/src/images/menu.svg b/src/images/menu.svg new file mode 100644 index 000000000..c86f620af --- /dev/null +++ b/src/images/menu.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/news-cats.jpg b/src/images/news-cats.jpg new file mode 100644 index 000000000..589ff5b10 Binary files /dev/null and b/src/images/news-cats.jpg differ diff --git a/src/images/news-postcards.jpg b/src/images/news-postcards.jpg new file mode 100644 index 000000000..11381b22b Binary files /dev/null and b/src/images/news-postcards.jpg differ diff --git a/src/images/plan-bg.svg b/src/images/plan-bg.svg new file mode 100644 index 000000000..e2c5bc627 --- /dev/null +++ b/src/images/plan-bg.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/telegram.svg b/src/images/telegram.svg new file mode 100644 index 000000000..5c8590402 --- /dev/null +++ b/src/images/telegram.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/twitter.svg b/src/images/twitter.svg new file mode 100644 index 000000000..fc34953ad --- /dev/null +++ b/src/images/twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/youtube.svg b/src/images/youtube.svg new file mode 100644 index 000000000..a4583cbc0 --- /dev/null +++ b/src/images/youtube.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/scripts/main.js b/src/scripts/main.js index ad9a93a7c..7c3874426 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1 +1,187 @@ 'use strict'; + +const menuBtn = document.getElementById('menuBtn'); +const nav = document.getElementById('nav'); +const subscribeForm = document.getElementById('subscribeForm'); +const langBtn = document.querySelector('.header__lang'); + +const translations = { + ua: { + 'date': '30 квітня – 30 листопада', + 'hero-title': 'Мистецтво XIX – XX ст.', + 'hero-subtitle': 'Внесок українських митців у світову культуру до XXI', + 'btn-ticket': 'Купити квиток', + 'exhibitions-title': 'Актуальні виставки', + 'exhibitions-link': 'Архів виставок →', + 'card1-date': '11.07 - 31.08', + 'card1-title': 'Кураторська виставка «Ангели»', + 'card1-desc': 'Виставковий проект «Ангели» — знакова подія для української культури і широкої глядацької аудиторії впродовж сімнадцяти.', + 'card2-date': '06 листопад', + 'card2-title': 'Мистецтво XX ст. – XXI ст.', + 'card2-desc': 'Знакові роботи Анни Горської, Миколи Самокиша, Федора Кричевського та інших митців.', + 'events-title': 'Найближчі події', + 'events-link': 'Календар подій →', + 'event1-date': '14/8 в 13:00', + 'event1-title': 'Кураторські екскурсії від Павла Гудімова', + 'event1-desc': 'Таємниця творчості, складний мистецький шлях — все це та ні цього немає в нашій пропозиції — розпочинається нова глава.', + 'btn-register': 'Зареєструватись', + 'event2-date': '20/8 в 15:00', + 'event2-title': 'Майстер-клас «Подорож до Австралії»', + 'event2-desc': 'Цей майстер-клас від нас арт-мандрівника можна вважати останнім пунктом кругосвітньої подорожі — тестів є.', + 'plan-title': 'Сплануйте візит до музею', + 'plan-desc': 'Оберіть зручний день, зареєструйтеся на той захід, що цікавить вас, або просто завітайте до нас — ми завжди раді допомогти вам насолодитися мистецтвом.', + 'btn-start': 'Почати', + 'news-title': 'Новини', + 'news-link': 'Усі новини →', + 'news1-date': '5 травня 2022', + 'news1-title': 'Оголошення переможця', + 'news1-desc': 'Друга картина Поляці Поляця для А це більш обмежений видатних успіхів що здобув перемогу розповсюджується.', + 'news2-date': '5 травня 2022', + 'news2-title': 'Міжнародний день котів', + 'news2-desc': 'Музей у своєму розмаїтті простих вагань перетворює Міжнародний день котів на нечувано яскраву подію.', + 'subscribe-title': 'Підпишіться на дайджест', + 'subscribe-desc': 'Першими дізнавайтесь про нові новини та розробки, отримуйте запрошення подій та читайте статті від куратора.', + 'subscribe-placeholder': 'e-mail', + 'btn-subscribe': 'Підписатись', + 'footer-contacts': 'Контакти', + 'footer-address': 'Київ, вул. М. Грушевського 6', + 'footer-schedule': 'Розклад роботи', + 'footer-nav': 'Головна', + 'day-mon': 'Пн.', + 'day-tue': 'Вт.', + 'day-wed': 'Ср.', + 'day-thu': 'Чт.', + 'day-fri': 'Пт.', + 'day-sat': 'Сб.', + 'day-sun': 'Нд.', + 'day-off': 'виходний', + 'nav-exhibitions': 'Виставки', + 'nav-events': 'Події', + 'nav-news': 'Новини', + 'nav-visit': 'Відвідати', + 'footer-terms': 'Умови', + 'footer-tickets': 'Квитки', + }, + en: { + 'date': 'April 30 – November 30', + 'hero-title': 'Art of XIX – XX century', + 'hero-subtitle': 'The contribution of Ukrainian artists to world culture', + 'btn-ticket': 'Buy a ticket', + 'exhibitions-title': 'Current Exhibitions', + 'exhibitions-link': 'Archive of exhibitions →', + 'card1-date': '11.07 - 31.08', + 'card1-title': 'Curatorial exhibition «Angels»', + 'card1-desc': 'The exhibition project «Angels» is a landmark event for Ukrainian culture and a wide audience of viewers for seventeen years.', + 'card2-date': '06 November', + 'card2-title': 'Art of XX century – XXI century', + 'card2-desc': 'Iconic works by Anna Gorska, Mykola Samokysh, Fedir Krychevsky and other artists.', + 'events-title': 'Upcoming Events', + 'events-link': 'Events calendar →', + 'event1-date': '14/8 at 13:00', + 'event1-title': 'Curator tours by Pavlo Gudimov', + 'event1-desc': 'The mystery of creativity, a complex artistic path — all this and more awaits you in our proposal — a new chapter begins.', + 'btn-register': 'Register', + 'event2-date': '20/8 at 15:00', + 'event2-title': 'Master class «Journey to Australia»', + 'event2-desc': 'This master class from our art traveler can be considered the last stop of the world tour — full of discoveries.', + 'plan-title': 'Plan your museum visit', + 'plan-desc': 'Choose a convenient day, register for the event that interests you, or simply visit us — we are always glad to help you enjoy art.', + 'btn-start': 'Start', + 'news-title': 'News', + 'news-link': 'All news →', + 'news1-date': 'May 5, 2022', + 'news1-title': 'Winner announcement', + 'news1-desc': 'The second painting for A is a more limited achievement that won and is being distributed across the country.', + 'news2-date': 'May 5, 2022', + 'news2-title': 'International Cat Day', + 'news2-desc': 'The museum in all its variety turns International Cat Day into an incredibly vibrant and memorable event.', + 'subscribe-title': 'Subscribe to digest', + 'subscribe-desc': 'Be the first to know about new news and developments, receive event invitations and read articles from the curator.', + 'subscribe-placeholder': 'e-mail', + 'btn-subscribe': 'Subscribe', + 'footer-contacts': 'Contacts', + 'footer-address': 'Kyiv, M. Hrushevsky St. 6', + 'footer-schedule': 'Working hours', + 'footer-nav': 'Navigation', + 'day-mon': 'Mon.', + 'day-tue': 'Tue.', + 'day-wed': 'Wed.', + 'day-thu': 'Thu.', + 'day-fri': 'Fri.', + 'day-sat': 'Sat.', + 'day-sun': 'Sun.', + 'day-off': 'day off', + 'nav-exhibitions': 'Exhibitions', + 'nav-events': 'Events', + 'nav-news': 'News', + 'nav-visit': 'Visit', + 'footer-terms': 'Terms', + 'footer-tickets': 'Tickets', + }, +}; + +let currentLang = 'ua'; + +function applyTranslations(lang) { + const t = translations[lang]; + + document.querySelectorAll('[data-i18n]').forEach((el) => { + const key = el.dataset.i18n; + + if (t[key] !== undefined) { + el.textContent = t[key]; + } + }); + + document.querySelectorAll('[data-i18n-placeholder]').forEach((el) => { + const key = el.dataset.i18nPlaceholder; + + if (t[key] !== undefined) { + el.placeholder = t[key]; + } + }); + + document.documentElement.lang = lang === 'ua' ? 'uk' : 'en'; +} + +if (menuBtn && nav) { + menuBtn.addEventListener('click', () => { + const isOpen = nav.classList.toggle('is-open'); + + menuBtn.setAttribute('aria-expanded', isOpen.toString()); + nav.setAttribute('aria-hidden', (!isOpen).toString()); + }); + + document.querySelectorAll('.nav__link').forEach((link) => { + link.addEventListener('click', () => { + nav.classList.remove('is-open'); + menuBtn.setAttribute('aria-expanded', 'false'); + nav.setAttribute('aria-hidden', 'true'); + }); + }); +} + +if (langBtn) { + langBtn.addEventListener('click', () => { + currentLang = currentLang === 'ua' ? 'en' : 'ua'; + langBtn.textContent = currentLang === 'ua' ? 'UA-' : 'EN-'; + applyTranslations(currentLang); + }); +} + +if (subscribeForm) { + subscribeForm.addEventListener('submit', (e) => { + e.preventDefault(); + + const emailInput = subscribeForm.querySelector('input[type="email"]'); + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; + + if (!emailInput || !emailRegex.test(emailInput.value.trim())) { + emailInput.focus(); + + return; + } + + subscribeForm.reset(); + }); +} diff --git a/src/styles/_fonts.scss b/src/styles/_fonts.scss index 33c3ed2b3..77473a226 100644 --- a/src/styles/_fonts.scss +++ b/src/styles/_fonts.scss @@ -1 +1 @@ -// put fonts here +// Google Fonts loaded via in index.html diff --git a/src/styles/_typography.scss b/src/styles/_typography.scss index 1837eb46e..afd24e863 100644 --- a/src/styles/_typography.scss +++ b/src/styles/_typography.scss @@ -1,3 +1,32 @@ +h1, +h2, +h3 { + font-family: $font-heading; + font-weight: 700; + line-height: 1.2; + margin: 0; +} + h1 { @extend %h1; } + +p { + margin: 0; +} + +a { + color: inherit; + text-decoration: none; +} + +ul, +ol { + margin: 0; + padding: 0; + list-style: none; +} + +address { + font-style: normal; +} diff --git a/src/styles/blocks/_base.scss b/src/styles/blocks/_base.scss new file mode 100644 index 000000000..e5d4e7c1c --- /dev/null +++ b/src/styles/blocks/_base.scss @@ -0,0 +1,59 @@ +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: $font-body; + font-size: 16px; + line-height: 1.5; + color: $c-text; + background-color: $c-white; + margin: 0; + overflow-x: hidden; +} + +img { + display: block; + max-width: 100%; +} + +button { + cursor: pointer; + border: none; + background: none; + padding: 0; + font-family: inherit; +} + +.section-title { + font-family: $font-heading; + font-size: 28px; + font-weight: 700; + color: $c-text; + margin: 0; + + @include respond-to(tablet) { + font-size: 36px; + } +} + +.link-more { + font-family: $font-body; + font-size: 14px; + font-weight: 600; + color: $c-accent; + text-decoration: none; + white-space: nowrap; + transition: opacity $transition; + cursor: pointer; + + &:hover { + opacity: 0.75; + } +} diff --git a/src/styles/blocks/_button.scss b/src/styles/blocks/_button.scss new file mode 100644 index 000000000..d35e24438 --- /dev/null +++ b/src/styles/blocks/_button.scss @@ -0,0 +1,40 @@ +@use 'sass:color'; + +.button { + display: inline-block; + font-family: $font-body; + font-size: 14px; + font-weight: 600; + letter-spacing: 0.05em; + text-transform: uppercase; + text-decoration: none; + padding: 12px 28px; + border-radius: 2px; + cursor: pointer; + transition: + background-color $transition, + color $transition, + opacity $transition; + + &--primary { + background-color: $c-accent; + color: $c-white; + border: 2px solid $c-accent; + + &:hover { + background-color: color.adjust($c-accent, $lightness: -10%); + border-color: color.adjust($c-accent, $lightness: -10%); + } + } + + &--outline { + background-color: transparent; + color: $c-white; + border: 2px solid $c-white; + + &:hover { + background-color: $c-white; + color: $c-dark; + } + } +} diff --git a/src/styles/blocks/_events.scss b/src/styles/blocks/_events.scss new file mode 100644 index 000000000..3317968d5 --- /dev/null +++ b/src/styles/blocks/_events.scss @@ -0,0 +1,108 @@ +.events { + padding: 60px 20px; + background-color: $c-white; + border-top: 1px solid $c-border; + + @include respond-to(tablet) { + padding: 80px 40px; + } + + @include respond-to(desktop) { + padding: 100px 80px; + } + + &__header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 40px; + gap: 16px; + } + + &__list { + display: flex; + flex-direction: column; + gap: 0; + } + + &__divider { + border: none; + border-top: 1px solid rgba($c-dark, 0.12); + margin: 40px 0; + } +} + +.event-card { + display: flex; + flex-direction: column; + gap: 24px; + cursor: pointer; + + @include respond-to(tablet) { + flex-direction: row; + align-items: flex-start; + gap: 32px; + } + + &__image-wrap { + overflow: hidden; + border-radius: 2px; + flex-shrink: 0; + + @include respond-to(tablet) { + width: 280px; + } + + @include respond-to(desktop) { + width: 360px; + } + } + + &__image { + width: 100%; + height: 220px; + object-fit: cover; + transition: transform 0.5s ease; + cursor: pointer; + + .event-card:hover & { + transform: scale(1.05); + } + + @include respond-to(tablet) { + height: 260px; + } + } + + &__body { + display: flex; + flex-direction: column; + gap: 12px; + justify-content: center; + } + + &__date { + font-size: 12px; + font-weight: 600; + color: $c-text-muted; + text-transform: uppercase; + letter-spacing: 0.08em; + } + + &__title { + font-family: $font-heading; + font-size: 20px; + font-weight: 700; + color: $c-text; + + @include respond-to(tablet) { + font-size: 24px; + } + } + + &__desc { + font-size: 14px; + color: $c-text-muted; + line-height: 1.6; + } +} diff --git a/src/styles/blocks/_exhibitions.scss b/src/styles/blocks/_exhibitions.scss new file mode 100644 index 000000000..d414b2b23 --- /dev/null +++ b/src/styles/blocks/_exhibitions.scss @@ -0,0 +1,87 @@ +.exhibitions { + padding: 60px 20px; + background-color: $c-white; + + @include respond-to(tablet) { + padding: 80px 40px; + } + + @include respond-to(desktop) { + padding: 100px 80px; + } + + &__header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 40px; + gap: 16px; + } + + &__grid { + display: grid; + grid-template-columns: 1fr; + gap: 40px; + + @include respond-to(tablet) { + grid-template-columns: 1fr 1fr; + gap: 32px; + } + } +} + +.exhibition-card { + display: flex; + flex-direction: column; + cursor: pointer; + + &__image-wrap { + overflow: hidden; + border-radius: 2px; + margin-bottom: 24px; + } + + &__image { + width: 100%; + height: 320px; + object-fit: cover; + transition: transform 0.5s ease; + cursor: pointer; + + .exhibition-card:hover & { + transform: scale(1.05); + } + } + + &__body { + display: flex; + flex-direction: column; + gap: 12px; + } + + &__date { + font-size: 12px; + font-weight: 600; + color: $c-text-muted; + text-transform: uppercase; + letter-spacing: 0.08em; + } + + &__title { + font-family: $font-heading; + font-size: 22px; + font-weight: 700; + color: $c-text; + + @include respond-to(tablet) { + font-size: 24px; + } + } + + &__desc { + font-size: 14px; + color: $c-text-muted; + line-height: 1.6; + flex-grow: 1; + } +} diff --git a/src/styles/blocks/_footer.scss b/src/styles/blocks/_footer.scss new file mode 100644 index 000000000..e45a8db9e --- /dev/null +++ b/src/styles/blocks/_footer.scss @@ -0,0 +1,163 @@ +.footer { + background-color: $c-dark; + color: $c-light; + + &__inner { + display: grid; + grid-template-columns: 1fr; + gap: 40px; + padding: 60px 20px 40px; + + @include respond-to(tablet) { + grid-template-columns: 1fr 1fr 1fr; + gap: 32px; + padding: 80px 40px 60px; + } + + @include respond-to(desktop) { + padding: 80px 80px 60px; + } + } + + &__col { + display: flex; + flex-direction: column; + gap: 10px; + } + + &__heading { + font-family: $font-heading; + font-size: 18px; + font-weight: 700; + color: $c-light; + margin-bottom: 8px; + } + + &__address { + font-size: 13px; + color: rgba($c-light, 0.8); + line-height: 1.5; + } + + &__contact-link { + display: block; + font-size: 13px; + color: rgba($c-light, 0.8); + text-decoration: none; + transition: color $transition; + + &:hover { + color: $c-light; + } + } + + &__socials { + display: flex; + gap: 16px; + margin-top: 8px; + } + + &__social { + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + border: 1px solid rgba($c-light, 0.3); + border-radius: 50%; + color: $c-light; + transition: + background-color $transition, + border-color $transition; + cursor: pointer; + + &:hover { + background-color: rgba($c-light, 0.15); + border-color: $c-light; + } + } + + &__social-icon { + width: 16px; + height: 16px; + filter: brightness(0) invert(1); + } + + &__schedule { + display: flex; + flex-direction: column; + gap: 6px; + } + + &__schedule-item { + display: flex; + justify-content: space-between; + font-size: 13px; + color: rgba($c-light, 0.8); + gap: 16px; + } + + &__nav { + display: flex; + flex-direction: column; + gap: 8px; + } + + &__nav-link { + font-size: 14px; + color: rgba($c-light, 0.8); + text-decoration: none; + transition: color $transition; + cursor: pointer; + + &:hover { + color: $c-light; + } + } + + &__bottom { + display: flex; + align-items: center; + justify-content: space-between; + padding: 20px; + border-top: 1px solid rgba($c-light, 0.15); + + @include respond-to(tablet) { + padding: 20px 40px; + } + + @include respond-to(desktop) { + padding: 20px 80px; + } + } + + &__logo { + cursor: pointer; + transition: opacity $transition; + + &:hover { + opacity: 0.8; + } + } + + &__logo-img { + height: 18px; + filter: brightness(0) invert(1); + } + + &__links { + display: flex; + gap: 20px; + } + + &__link { + font-size: 12px; + color: rgba($c-light, 0.5); + text-decoration: none; + transition: color $transition; + + &:hover { + color: $c-light; + } + } +} diff --git a/src/styles/blocks/_header.scss b/src/styles/blocks/_header.scss new file mode 100644 index 000000000..12f2980ab --- /dev/null +++ b/src/styles/blocks/_header.scss @@ -0,0 +1,142 @@ +@use 'sass:color'; + +.header { + background-color: $c-dark; + color: $c-light; + position: sticky; + top: 0; + z-index: 100; + + &__inner { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 20px; + + @include respond-to(tablet) { + padding: 20px 40px; + } + } + + &__info { + font-size: 11px; + font-weight: 500; + letter-spacing: 0.05em; + color: rgba($c-light, 0.7); + display: none; + + @include respond-to(tablet) { + display: block; + font-size: 12px; + } + } + + &__date { + display: block; + } + + &__logo { + color: $c-light; + cursor: pointer; + transition: opacity $transition; + + &:hover { + opacity: 0.8; + } + } + + &__logo-img { + height: 20px; + filter: brightness(0) invert(1); + + @include respond-to(tablet) { + height: 26px; + } + } + + &__controls { + display: flex; + align-items: center; + gap: 16px; + } + + &__menu-btn { + display: flex; + align-items: center; + cursor: pointer; + transition: opacity $transition; + + &:hover { + opacity: 0.7; + } + } + + &__menu-icon { + width: 24px; + height: 24px; + filter: brightness(0) invert(1); + } + + &__lang { + font-size: 13px; + font-weight: 600; + color: $c-light; + cursor: pointer; + user-select: none; + transition: opacity $transition; + + &:hover { + opacity: 0.7; + } + } +} + +.nav { + background-color: color.adjust($c-dark, $lightness: -5%); + overflow: hidden; + max-height: 0; + transition: max-height 0.4s ease; + + &.is-open { + max-height: 300px; + } + + &__list { + display: flex; + flex-direction: column; + padding: 10px 20px 20px; + + @include respond-to(tablet) { + flex-direction: row; + padding: 10px 40px 20px; + gap: 32px; + } + } + + &__item { + border-bottom: 1px solid rgba($c-light, 0.1); + + &:last-child { + border-bottom: none; + } + + @include respond-to(tablet) { + border-bottom: none; + } + } + + &__link { + display: block; + padding: 12px 0; + font-family: $font-body; + font-size: 14px; + font-weight: 600; + color: $c-light; + text-decoration: none; + transition: color $transition; + + &:hover { + color: $c-accent; + } + } +} diff --git a/src/styles/blocks/_hero.scss b/src/styles/blocks/_hero.scss new file mode 100644 index 000000000..975027ca0 --- /dev/null +++ b/src/styles/blocks/_hero.scss @@ -0,0 +1,111 @@ +.hero { + background-color: $c-dark; + color: $c-light; + position: relative; + overflow: hidden; + min-height: 480px; + display: flex; + align-items: flex-end; + + @include respond-to(tablet) { + min-height: 560px; + } + + @include respond-to(desktop) { + min-height: 640px; + align-items: center; + } + + &__content { + position: relative; + z-index: 2; + padding: 40px 20px; + max-width: 560px; + + @include respond-to(tablet) { + padding: 60px 40px; + } + + @include respond-to(desktop) { + padding: 80px; + } + } + + &__date { + display: block; + font-size: 11px; + font-weight: 500; + letter-spacing: 0.05em; + color: rgba($c-light, 0.7); + margin-bottom: 16px; + + @include respond-to(tablet) { + display: none; + } + } + + &__title { + font-family: $font-heading; + font-size: 36px; + font-weight: 700; + color: $c-light; + margin-bottom: 16px; + line-height: 1.15; + + @include respond-to(tablet) { + font-size: 52px; + } + + @include respond-to(desktop) { + font-size: 64px; + } + } + + &__subtitle { + font-size: 14px; + color: rgba($c-light, 0.8); + margin-bottom: 32px; + max-width: 360px; + + @include respond-to(tablet) { + font-size: 16px; + } + } + + &__counter { + display: flex; + align-items: center; + gap: 4px; + margin-top: 40px; + font-size: 13px; + color: rgba($c-light, 0.6); + } + + &__counter-num { + font-weight: 700; + color: $c-light; + } + + &__image-wrap { + position: absolute; + right: 0; + bottom: 0; + height: 100%; + width: 50%; + display: flex; + align-items: flex-end; + justify-content: flex-end; + + @include respond-to(mobile-only) { + width: 60%; + opacity: 0.4; + } + } + + &__image { + height: 100%; + width: 100%; + object-fit: cover; + object-position: top center; + } +} diff --git a/src/styles/blocks/_news.scss b/src/styles/blocks/_news.scss new file mode 100644 index 000000000..66f47cbc6 --- /dev/null +++ b/src/styles/blocks/_news.scss @@ -0,0 +1,87 @@ +.news { + padding: 60px 20px; + background-color: $c-white; + + @include respond-to(tablet) { + padding: 80px 40px; + } + + @include respond-to(desktop) { + padding: 100px 80px; + } + + &__header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 40px; + gap: 16px; + } + + &__grid { + display: grid; + grid-template-columns: 1fr; + gap: 32px; + + @include respond-to(tablet) { + grid-template-columns: 1fr 1fr; + gap: 32px; + } + } +} + +.news-card { + cursor: pointer; + display: flex; + flex-direction: column; + + &__image-wrap { + overflow: hidden; + border-radius: 2px; + margin-bottom: 20px; + } + + &__image { + width: 100%; + height: 220px; + object-fit: cover; + transition: transform 0.5s ease; + cursor: pointer; + + .news-card:hover & { + transform: scale(1.05); + } + } + + &__body { + display: flex; + flex-direction: column; + gap: 10px; + } + + &__category { + font-size: 12px; + font-weight: 600; + color: $c-text-muted; + text-transform: uppercase; + letter-spacing: 0.08em; + } + + &__title { + font-family: $font-heading; + font-size: 20px; + font-weight: 700; + color: $c-text; + transition: color $transition; + + .news-card:hover & { + color: $c-accent; + } + } + + &__desc { + font-size: 14px; + color: $c-text-muted; + line-height: 1.6; + } +} diff --git a/src/styles/blocks/_plan.scss b/src/styles/blocks/_plan.scss new file mode 100644 index 000000000..deee89387 --- /dev/null +++ b/src/styles/blocks/_plan.scss @@ -0,0 +1,88 @@ +.plan { + background-color: $c-dark; + color: $c-light; + overflow: hidden; + + &__inner { + display: flex; + flex-direction: column; + position: relative; + + @include respond-to(tablet) { + flex-direction: row; + align-items: center; + min-height: 480px; + } + } + + &__content { + padding: 60px 20px; + position: relative; + z-index: 2; + + @include respond-to(tablet) { + padding: 80px 40px; + max-width: 50%; + margin-left: auto; + } + + @include respond-to(desktop) { + padding: 100px 80px; + max-width: 560px; + } + } + + &__title { + font-family: $font-heading; + font-size: 32px; + font-weight: 700; + color: $c-light; + margin-bottom: 20px; + + @include respond-to(tablet) { + font-size: 44px; + } + } + + &__desc { + font-size: 14px; + color: rgba($c-light, 0.8); + line-height: 1.7; + margin-bottom: 32px; + max-width: 400px; + + @include respond-to(tablet) { + font-size: 16px; + } + } + + &__image-wrap { + position: relative; + overflow: hidden; + + @include respond-to(tablet) { + position: absolute; + left: 0; + top: 0; + height: 100%; + width: 50%; + } + + @include respond-to(mobile-only) { + height: 280px; + } + } + + &__image { + width: 100%; + height: 100%; + object-fit: cover; + object-position: center top; + opacity: 0.7; + transition: transform 0.6s ease; + + .plan:hover & { + transform: scale(1.03); + } + } +} diff --git a/src/styles/blocks/_subscribe.scss b/src/styles/blocks/_subscribe.scss new file mode 100644 index 000000000..83fd55637 --- /dev/null +++ b/src/styles/blocks/_subscribe.scss @@ -0,0 +1,93 @@ +.subscribe { + padding: 60px 20px; + background-color: $c-white; + border-top: 1px solid $c-border; + + @include respond-to(tablet) { + padding: 80px 40px; + } + + @include respond-to(desktop) { + padding: 100px 80px; + } + + &__inner { + max-width: 600px; + } + + &__title { + font-family: $font-heading; + font-size: 28px; + font-weight: 700; + color: $c-text; + margin-bottom: 16px; + + @include respond-to(tablet) { + font-size: 36px; + } + } + + &__desc { + font-size: 14px; + color: $c-text-muted; + line-height: 1.7; + margin-bottom: 32px; + + @include respond-to(tablet) { + font-size: 16px; + } + } + + &__form { + display: flex; + flex-direction: column; + gap: 12px; + + @include respond-to(tablet) { + flex-direction: row; + gap: 0; + } + } + + &__input { + flex: 1; + font-family: $font-body; + font-size: 14px; + padding: 14px 20px; + border: 1px solid $c-border; + border-radius: 2px; + background-color: $c-white; + color: $c-text; + outline: none; + transition: border-color $transition; + + &::placeholder { + color: $c-text-muted; + } + + &:focus { + border-color: $c-dark; + } + + /* Override autocomplete styles */ + &:-webkit-autofill, + &:-webkit-autofill:hover, + &:-webkit-autofill:focus { + -webkit-text-fill-color: $c-text; + -webkit-box-shadow: 0 0 0 1000px $c-white inset; + transition: background-color 5000s ease-in-out 0s; + } + + @include respond-to(tablet) { + border-right: none; + border-radius: 2px 0 0 2px; + } + } + + &__form .button { + @include respond-to(tablet) { + border-radius: 0 2px 2px 0; + white-space: nowrap; + } + } +} diff --git a/src/styles/main.scss b/src/styles/main.scss index fb9195d12..4e8180e47 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -2,6 +2,13 @@ @import 'fonts'; @import 'typography'; -body { - background: $c-gray; -} +@import 'blocks/base'; +@import 'blocks/button'; +@import 'blocks/header'; +@import 'blocks/hero'; +@import 'blocks/exhibitions'; +@import 'blocks/events'; +@import 'blocks/plan'; +@import 'blocks/news'; +@import 'blocks/subscribe'; +@import 'blocks/footer'; 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/src/styles/utils/extends.scss b/src/styles/utils/extends.scss new file mode 100644 index 000000000..8900203f7 --- /dev/null +++ b/src/styles/utils/extends.scss @@ -0,0 +1,25 @@ +%h1 { + font-family: $font-heading; + font-weight: 700; +} + +%visually-hidden { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + overflow: hidden; + clip: rect(0 0 0 0); + clip-path: inset(50%); + white-space: nowrap; +} + +%container { + max-width: $bp-desktop; + margin: 0 auto; + padding: 0 20px; + + @include respond-to(tablet) { + padding: 0 40px; + } +} diff --git a/src/styles/utils/mixins.scss b/src/styles/utils/mixins.scss new file mode 100644 index 000000000..d4c0220de --- /dev/null +++ b/src/styles/utils/mixins.scss @@ -0,0 +1,29 @@ +@mixin hover($_property, $_toValue) { + transition: #{$_property} #{$transition}; + + &:hover { + #{$_property}: $_toValue; + } +} + +@mixin respond-to($bp) { + @if $bp == desktop { + @media (min-width: $bp-desktop) { + @content; + } + } @else if $bp == tablet { + @media (min-width: $bp-tablet) { + @content; + } + } @else if $bp == mobile-only { + @media (max-width: #{$bp-tablet - 1px}) { + @content; + } + } +} + +@mixin flex-center { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/src/styles/utils/vars.scss b/src/styles/utils/vars.scss new file mode 100644 index 000000000..416eb7e82 --- /dev/null +++ b/src/styles/utils/vars.scss @@ -0,0 +1,14 @@ +$c-dark: #3b5046; +$c-accent: #c9352a; +$c-light: #f1f5f4; +$c-white: #fff; +$c-text: #333; +$c-text-muted: #666; +$c-border: #e0e0e0; +$c-gray: #f5f5f5; +$font-heading: 'Playfair Display', serif; +$font-body: 'Raleway', sans-serif; +$transition: 0.3s ease; +$bp-desktop: 1280px; +$bp-tablet: 768px; +$bp-mobile: 480px;