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/src/images/events/event-1.png b/src/images/events/event-1.png new file mode 100644 index 000000000..ce1ebd81c Binary files /dev/null and b/src/images/events/event-1.png differ diff --git a/src/images/events/event-2.png b/src/images/events/event-2.png new file mode 100644 index 000000000..ce9a82e2f Binary files /dev/null and b/src/images/events/event-2.png differ diff --git a/src/images/gallery/gallery-pic-1.png b/src/images/gallery/gallery-pic-1.png new file mode 100644 index 000000000..2cbc94659 Binary files /dev/null and b/src/images/gallery/gallery-pic-1.png differ diff --git a/src/images/gallery/gallery-pic-2.png b/src/images/gallery/gallery-pic-2.png new file mode 100644 index 000000000..c6ce628ab Binary files /dev/null and b/src/images/gallery/gallery-pic-2.png differ diff --git a/src/images/gallery/gallery-pic-3.png b/src/images/gallery/gallery-pic-3.png new file mode 100644 index 000000000..dea36b4c9 Binary files /dev/null and b/src/images/gallery/gallery-pic-3.png differ diff --git a/src/images/gallery/gallery-pic-4.png b/src/images/gallery/gallery-pic-4.png new file mode 100644 index 000000000..39f051241 Binary files /dev/null and b/src/images/gallery/gallery-pic-4.png differ diff --git a/src/images/gallery/gallery-pic-sm-1.png b/src/images/gallery/gallery-pic-sm-1.png new file mode 100644 index 000000000..f289f715f Binary files /dev/null and b/src/images/gallery/gallery-pic-sm-1.png differ diff --git a/src/images/i-spohady-i-mrii.png b/src/images/i-spohady-i-mrii.png new file mode 100644 index 000000000..90c9c60be Binary files /dev/null and b/src/images/i-spohady-i-mrii.png differ diff --git a/src/images/icons/arrow-black.png b/src/images/icons/arrow-black.png new file mode 100644 index 000000000..752daf893 Binary files /dev/null and b/src/images/icons/arrow-black.png differ diff --git a/src/images/icons/arrow.png b/src/images/icons/arrow.png new file mode 100644 index 000000000..e6877f79e Binary files /dev/null and b/src/images/icons/arrow.png differ diff --git a/src/images/icons/facebook.png b/src/images/icons/facebook.png new file mode 100644 index 000000000..9de271df8 Binary files /dev/null and b/src/images/icons/facebook.png differ diff --git a/src/images/icons/icon-burger-menu-hover.png b/src/images/icons/icon-burger-menu-hover.png new file mode 100644 index 000000000..883807f5e Binary files /dev/null and b/src/images/icons/icon-burger-menu-hover.png differ diff --git a/src/images/icons/instagram.png b/src/images/icons/instagram.png new file mode 100644 index 000000000..e130a2414 Binary files /dev/null and b/src/images/icons/instagram.png differ diff --git a/src/images/icons/menu.png b/src/images/icons/menu.png new file mode 100644 index 000000000..e535eab4b Binary files /dev/null and b/src/images/icons/menu.png differ diff --git a/src/images/icons/menu.svg b/src/images/icons/menu.svg new file mode 100644 index 000000000..f08cc7c6a --- /dev/null +++ b/src/images/icons/menu.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/images/icons/rectangle.png b/src/images/icons/rectangle.png new file mode 100644 index 000000000..0b1f91cb0 Binary files /dev/null and b/src/images/icons/rectangle.png differ diff --git a/src/images/idu-i-povertaus.png b/src/images/idu-i-povertaus.png new file mode 100644 index 000000000..49232dfa8 Binary files /dev/null and b/src/images/idu-i-povertaus.png differ diff --git a/src/images/lectures/lecture-1.png b/src/images/lectures/lecture-1.png new file mode 100644 index 000000000..81800f043 Binary files /dev/null and b/src/images/lectures/lecture-1.png differ diff --git a/src/images/logo-xl.png b/src/images/logo-xl.png new file mode 100644 index 000000000..739b53fb3 Binary files /dev/null and b/src/images/logo-xl.png differ diff --git a/src/images/logo-xl.svg b/src/images/logo-xl.svg new file mode 100644 index 000000000..21275e7da --- /dev/null +++ b/src/images/logo-xl.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/images/logo.png b/src/images/logo.png new file mode 100644 index 000000000..9d20119c8 Binary files /dev/null and b/src/images/logo.png differ diff --git "a/src/images/museum-1800\321\2051200.png" "b/src/images/museum-1800\321\2051200.png" new file mode 100644 index 000000000..5a0b8a083 Binary files /dev/null and "b/src/images/museum-1800\321\2051200.png" differ diff --git a/src/images/pidpyska.png b/src/images/pidpyska.png new file mode 100644 index 000000000..c8d2e3639 Binary files /dev/null and b/src/images/pidpyska.png differ diff --git a/src/images/subscribe-bg.jpg b/src/images/subscribe-bg.jpg new file mode 100644 index 000000000..c8d2e3639 Binary files /dev/null and b/src/images/subscribe-bg.jpg differ diff --git a/src/index.html b/src/index.html index 8019b83ec..4ee3cf216 100644 --- a/src/index.html +++ b/src/index.html @@ -1,19 +1,516 @@ - + - Title + Художній музей - Головна сторінка + + + + + - -

Hello Mate Academy

+ + + + +
+ + +
+ +
+
+ Зовнішній вигляд художнього музею +
+

+ ХУДОЖНІЙ +
+ МУЗЕЙ +

+ + КВИТКИ + +
+ Квитки +
+
+
+ + ПОДІЇ + +
+
+
+

Актуальні події

+
+
+ І спогади і мрії +
+
+

ВИСТАВКА

+

26.08-29.11.2019

+
+

І спогади і мрії

+

+ Національний художній музей України до 100 річчя від дня + народження видатної української художниці Тетяни Яблонської + відкриває ретроспективну ювілейну виставку «І спогади і мрії». +

+
+
+
+ Йду і повертаюсь +
+
+

ВИСТАВКА

+

26.08-29.11.2019

+
+

Йду і повертаюсь

+

+ Національний Художній Музей України презентує унікальну + частину колекції Градобанку - українське мистецтво другої + половини 1980-1995 років. +

+
+
+
+
+
+
+
+ Лекція 1 +
+
+
+

Лекція

+

26/08/2019 - 11:00

+
+

Від класицизму до романтизму

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

Графік роботи

+
+
+ 12:00 — 20:00 + середа +
+
+ 12:00 — 20:00 + четвер +
+
+ 12:00 — 20:00 + п'ятниця +
+
+ 11:00 — 19:00 + субота +
+
+ 11:00 — 19:00 + неділя +
+
+

Вихідні: понеділок, вівторок

+

+ Каса припиняє роботу за 1 годину до закриття музею +

+
+
+
+ +
+

Контакти

+ +
+ +
+ + Про Нас + +
Контакти
+
+
+
+ +
+ +
+
diff --git a/src/styles/_fonts.scss b/src/styles/_fonts.scss index 45cdd5400..35f297cc2 100644 --- a/src/styles/_fonts.scss +++ b/src/styles/_fonts.scss @@ -1,6 +1,16 @@ -@font-face { - font-family: Roboto, Arial, Helvetica, sans-serif; - src: url('../fonts/Roboto-Regular-webfont.woff') format('woff'); - font-weight: normal; - font-style: normal; +// Google Fonts are loaded in HTML head section +// IBM Plex Sans: Primary font for body text and general content +// Montserrat: Secondary font for headings and emphasis + +body { + font-family: $font-primary; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: $font-secondary; } diff --git a/src/styles/_typography.scss b/src/styles/_typography.scss index 1837eb46e..8edb4e7e7 100644 --- a/src/styles/_typography.scss +++ b/src/styles/_typography.scss @@ -1,3 +1,126 @@ +// Typography system based on Figma design tokens + +// Headings h1 { - @extend %h1; + @include montserrat-hero-desktop; + + margin: 0; + color: $color-primary; + + @include on-tablet { + @include montserrat-hero-medium; + } + + @media (max-width: #{$tablet-breakpoint - 1px}) { + @include montserrat-hero-large; + } +} + +h2 { + @include montserrat-gallery-title; + + margin: 0; + color: $color-primary; + + @include on-tablet { + @include montserrat-hero-large; + } + + @media (max-width: #{$tablet-breakpoint - 1px}) { + @include montserrat-hero-title; + } +} + +h3 { + @include montserrat-hero-title; + + margin: 0; + color: $color-primary; + + @media (max-width: #{$tablet-breakpoint - 1px}) { + @include montserrat-event-title; + } +} + +h4 { + @include montserrat-event-title; + + margin: 0; + color: $color-primary; + + @media (max-width: #{$tablet-breakpoint - 1px}) { + @include ibm-gallery-nav; + } +} + +// Body text +p { + @include ibm-description; + + margin: 0; + color: $color-secondary; + + &.large { + @include ibm-subscribe; + } +} + +// Utility classes +.text-title { + @include ibm-title; +} + +.text-button { + @include ibm-button; +} + +.text-copyright { + @include ibm-copyright; +} + +.text-events { + @include ibm-events; +} + +.text-lecture { + @include ibm-lecture; +} + +.text-date { + @include ibm-date; +} + +.text-summary { + @include ibm-summary; +} + +.text-logo { + @include montserrat-logo; + + @media (max-width: #{$tablet-breakpoint - 1px}) { + @include montserrat-logo-small; + } +} + +.text-input { + @include montserrat-input; +} + +// Links +a { + @include ibm-title; + + color: $color-primary; + text-decoration: none; + + @include hover(color, $color-accent); +} + +// Buttons +button { + @include ibm-button; + + background: none; + border: none; + cursor: pointer; } diff --git a/src/styles/components/_about.scss b/src/styles/components/_about.scss new file mode 100644 index 000000000..830e48b84 --- /dev/null +++ b/src/styles/components/_about.scss @@ -0,0 +1,39 @@ +.about { + padding: 60px 0; + background-color: $color-bg-light; + + @include on-tablet { + padding: 80px 0; + } + + @include on-desktop { + padding: 100px 0; + } + + &__content { + max-width: 800px; + margin: 0 auto; + text-align: center; + } + + &__title { + @extend %section-title; + + margin-bottom: 30px; + color: $color-primary; + + @include on-tablet { + margin-bottom: 40px; + } + } + + &__text { + font-size: 16px; + line-height: 1.6; + color: $color-secondary; + + @include on-tablet { + font-size: 18px; + } + } +} diff --git a/src/styles/components/_aside-menu.scss b/src/styles/components/_aside-menu.scss new file mode 100644 index 000000000..7687162f5 --- /dev/null +++ b/src/styles/components/_aside-menu.scss @@ -0,0 +1,277 @@ +.aside-menu { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: auto; + min-height: 100vh; + z-index: 1000; + visibility: hidden; + opacity: 0; + transform: translateY(-100%); + transition: all 0.3s ease; + + // Коли меню відкрите через :target + &:target { + visibility: visible; + opacity: 1; + transform: translateY(0); + } + + &__overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100vh; + background-color: $color-overlay; + backdrop-filter: blur(4px); + } + + &__content { + position: relative; + width: 100%; + height: auto; + background-color: $color-success; + padding: 60px 20px 40px; + box-sizing: border-box; + + @include on-tablet { + padding: 80px 39px 60px; + } + + @include on-desktop { + padding: 100px 120px 80px; + } + } + + &__grid { + display: grid; + gap: 20px; + row-gap: 30px; + + // Мобільний: перший стовпець мінімальний розмір для кнопки, решта рівномірно + grid-template-columns: min-content 1fr 1fr; + + @include on-tablet { + // Планшет: перший стовпець min-content, навігація 1fr+1fr, дільник auto, schedule більший простір + grid-template-columns: min-content 1fr 1fr auto 2fr 1fr; + gap: 30px; + align-items: start; + } + + @include on-desktop { + // Десктоп: той же лейаут що планшет, але збільшені відступи + gap: 60px; + } + } + + &__close { + @extend %smooth-transition; + + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + font-size: 30px; + font-weight: 300; + color: $color-white; + text-decoration: none; + background-color: transparent; + cursor: pointer; + + // Позиціонування в grid + grid-column: 1; + grid-row: 1; + place-self: start start; + + &:hover { + color: $color-primary; + } + + @include on-tablet { + width: 50px; + height: 50px; + font-size: 36px; + } + } + + &__nav-column { + display: flex; + flex-direction: column; + gap: 30px; + + &--left { + // Мобільний: ряд 1, стовпець 2 + grid-column: 2; + grid-row: 1; + + @include on-tablet { + // Планшет: стовпець 2 + grid-column: 2; + grid-row: 1; + } + } + + &--right { + // Мобільний: ряд 1, стовпець 3 + grid-column: 3; + grid-row: 1; + + @include on-tablet { + // Планшет: стовпець 3 + grid-column: 3; + grid-row: 1; + } + } + } + + &__item { + @extend %smooth-transition; + + font-size: 16px; + line-height: 150%; + color: $color-white; + text-decoration: none; + padding: 8px 0; + border-bottom: 1px solid transparent; + display: inline-block; + width: auto; + + &:hover { + color: $color-white; + border-bottom-color: $color-white; + opacity: 0.8; + } + + @include on-tablet { + font-size: 18px; + padding: 12px 0; + } + } + + &__divider { + background-color: $color-white; + + // Мобільний: горизонтальний делівер на ряду 2, всі стовпці + grid-column: 1 / -1; + grid-row: 2; + height: 1px; + width: 100%; + margin: 20px 0; + + @include on-tablet { + // Планшет і десктоп: вертикальний делівер на стовпці 4 + grid-column: 4; + grid-row: 1; + width: 1px; + height: 100%; + margin: 0; + justify-self: center; + min-height: 200px; + } + + @include on-desktop { + min-height: 250px; + } + } + + &__schedule { + // Мобільний: весь блок schedule займає стовпці 2-3, ряд 3 + grid-column: 2 / -1; + grid-row: 3; + + @include on-tablet { + // Планшет: schedule block на стовпці 5, ряд 1 + grid-column: 5; + grid-row: 1; + } + } + + &__note { + // Мобільний: нотатка після графіку роботи + grid-column: 2 / -1; // Від другого стовпця до кінця (пропускаємо кнопку) + grid-row: 4; + + @include on-tablet { + // Планшет/десктоп: показуємо в стовпці 6 після графіку + display: block; + grid-column: 6; + grid-row: 1; + } + } + + &__day-off { + font-size: 14px; + margin-bottom: 8px; + font-weight: 500; + line-height: 1.4; + color: $color-white; + } + + &__notice { + font-size: 14px; + color: $color-white; + line-height: 1.5; + margin: 0; + } + + &__title { + @extend %section-title; + + font-size: 24px; + margin-bottom: 30px; + color: $color-white; + + @include on-tablet { + font-size: 32px; + margin-bottom: 40px; + } + } +} + +// Schedule стилі для aside-menu (в одному стовпці) +.aside-menu .schedule { + // Завжди в один стовпець + display: block; + + // Контейнер для днів роботи + &__items { + display: flex; + flex-direction: column; + } + + &__item { + display: flex; + flex-wrap: wrap; + column-gap: 4px; + align-items: center; + margin-bottom: 8px; + } + + &__day { + @extend %metadata-text; + + color: $color-white; + text-transform: capitalize; + } + + &__time { + font-size: 14px; + line-height: 150%; + color: $color-white; + font-weight: bold; + } +} + +// Запобігання прокрутки body коли меню відкрите +.page__body:has(.aside-menu:target) { + overflow: hidden; +} + +// Fallback для браузерів без :has +.aside-menu:target ~ .page-content { + position: fixed; + width: 100%; +} diff --git a/src/styles/components/_common.scss b/src/styles/components/_common.scss new file mode 100644 index 000000000..f0791b246 --- /dev/null +++ b/src/styles/components/_common.scss @@ -0,0 +1,62 @@ +.button { + font-family: inherit; + font-weight: bold; + text-transform: uppercase; + border-radius: 0; + outline: none; + + &:focus { + box-shadow: 0 0 0 2px $color-accent; + } +} + +.container { + @include section-padding; + + width: 100%; + + max-width: $max-content-width; + margin: 0 auto; +} + +// Глобальне обмеження ширини для всіх секцій +.section { + margin: 0 auto; + width: 100%; + overflow-x: hidden; + + // Застосовуємо вертикальні відступи тільки до секцій з контентом + &--with-padding { + @include content-spacing; + } +} + +// Клас для повноширинних секцій (як hero з background) +.section--full-width { + max-width: none; + overflow-x: hidden; + + .section__content { + max-width: $max-content-width; + margin: 0 auto; + width: 100%; + overflow-x: hidden; + + @include section-padding; + } +} // Утилітарні класи для відступів +.spacing-section { + @include content-spacing; +} + +.spacing-margin { + @include section-margin; +} + +.spacing-padding { + @include section-padding; +} + +.spacing-gap { + @include section-gap; +} diff --git a/src/styles/components/_copyright.scss b/src/styles/components/_copyright.scss new file mode 100644 index 000000000..56b9bcaee --- /dev/null +++ b/src/styles/components/_copyright.scss @@ -0,0 +1,31 @@ +.copyright { + @include page-grid; + + text-align: center; + padding-bottom: 56px; + + &__content { + grid-column: 1 / -1; + display: flex; + flex-direction: column; + gap: 8px; + + @include on-tablet { + padding-bottom: 36px; + flex-direction: row; + justify-content: space-between; + align-items: center; + } + } + + &__text { + font-size: 12px; + color: $color-secondary; + margin: 0; + line-height: 1.4; + + @include on-tablet { + font-size: 14px; + } + } +} diff --git a/src/styles/components/_events.scss b/src/styles/components/_events.scss new file mode 100644 index 000000000..c6f02a0db --- /dev/null +++ b/src/styles/components/_events.scss @@ -0,0 +1,130 @@ +.events { + @extend %flex-column; + @include content-spacing; + + &__title { + @extend %section-title; + + font-size: 36px; + + @include section-margin; + + text-align: center; + + @include on-tablet { + font-size: 48px; + } + } + + &__list { + @extend %flex-column; + @include section-gap; + + @include on-tablet { + gap: 64px; + } + + @include on-desktop { + gap: 104px; + } + } +} + +.event { + @include page-grid; + + box-sizing: border-box; + overflow: hidden; + max-width: 100%; + + &__image { + @extend %full-image; + + height: auto; + transition: transform 0.3s ease; + overflow: hidden; + grid-column: 1 / -1; // мобільний: повні 2 колонки + + &:hover { + transform: scale(1.05); + } + + @include on-tablet { + grid-column: 1 / -1; // планшет: всі 6 колонок + height: 400px; + } + + @include on-desktop { + grid-column: 1 / 8; // десктоп: колонки 1-7 + height: 520px; + } + } + + &__info { + @extend %flex-column; + + justify-content: space-between; + grid-column: 1 / -1; // мобільний: повні 2 колонки + padding-top: 20px; + + @include on-tablet { + grid-column: 1 / 5; // планшет: перші 4 колонки + padding-top: 30px; + } + + @include on-desktop { + grid-column: 9 / -1; // десктоп: колонки 9-12 + height: 202px; + padding-top: 0; + align-self: center; + } + } + + &__wrap { + display: flex; + justify-content: space-between; + margin-bottom: 10px; + } + + &__type { + @extend %metadata-text; + + color: $color-secondary; + } + + &__date { + @extend %metadata-text; + + color: $color-success; + font-weight: bold; + } + + &__title { + font-size: 18px; + font-weight: bold; + color: $color-primary; + margin-bottom: 10px; + display: inline-flex; + align-items: center; + gap: 12px; + + &::after { + content: ''; + display: inline-block; + width: 10px; + height: 10px; + background-color: $color-warning; + } + + @include on-tablet { + font-size: 20px; + } + } + + &__description { + font-size: 16px; + line-height: 1.6; + color: $color-secondary; + margin: 0; + } +} diff --git a/src/styles/components/_footer.scss b/src/styles/components/_footer.scss new file mode 100644 index 000000000..dc85c0b79 --- /dev/null +++ b/src/styles/components/_footer.scss @@ -0,0 +1,5 @@ +.footer { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 30px; +} diff --git a/src/styles/components/_gallery.scss b/src/styles/components/_gallery.scss new file mode 100644 index 000000000..7ec69210f --- /dev/null +++ b/src/styles/components/_gallery.scss @@ -0,0 +1,177 @@ +.gallery-wrapper { + width: 100%; + max-width: 100%; + overflow: hidden; /* запобігає розтягуванню сторінки */ + + @include section-padding; + + @include on-desktop { + max-width: $max-content-width; + } + + // Мобільний (320px+) + .gallery { + display: grid; + grid-auto-flow: column; + grid-auto-columns: calc(100% - 56px); /* 100% - 40px (20+20) - 16px (gap) */ + gap: 16px; + overflow: auto hidden; + scroll-snap-type: x mandatory; + scroll-behavior: smooth; + -webkit-overflow-scrolling: touch; + padding: 0; + box-sizing: content-box; + -ms-overflow-style: none; + scrollbar-width: none; + max-width: 100%; + + &::-webkit-scrollbar { + display: none; + } + + &__title { + @extend %section-title; + + font-size: 36px; + + @include section-margin; + + text-align: center; + + @include on-tablet { + font-size: 48px; + } + } + } + + .slide { + scroll-snap-align: start; + height: 410px; + overflow: hidden; + background: $color-dark; + display: block; + outline: none; + flex-shrink: 0; + + img { + width: 100%; + height: 100%; + object-fit: cover; + display: block; + transition: transform 0.3s ease; + } + + &:hover img { + transform: scale(1.05); + } + } + + .gallery-dots { + display: flex; + justify-content: center; + gap: 8px; + margin-top: 12px; + + a { + width: 10px; + height: 10px; + border-radius: 50%; + background: $color-light-gray; + display: inline-block; + text-indent: -9999px; + transition: + transform 0.18s ease, + background 0.18s ease; + box-shadow: none; + + &:focus { + outline: 2px solid $color-success; + outline-offset: 3px; + } + + &:hover { + transform: scale(1.1); + } + + &:active, + &:focus-visible { + background: $color-success; + transform: scale(1.25); + } + } + } + + // Планшет (640px+) + @include on-tablet { + .gallery { + grid-auto-columns: calc( + 50% - 39px + ); /* 2 слайди, відступи враховуються в section-padding, 16px gap */ + + padding: 0; + } + + .slide { + height: 543px; + } + } + + // Десктоп (1280px+) - грід без навігації + @include on-desktop { + @include page-grid; + + .gallery { + display: grid; + grid-template-columns: repeat(12, 1fr); + grid-template-rows: 600px 360px; + gap: 24px; + padding: 0; + overflow: visible; + scroll-snap-type: none; + grid-column: 1 / -1; + } + + .slide { + scroll-snap-align: none; + + &:nth-child(1) { + grid-column: 1 / 5; // стовпці 1-4 + grid-row: 1; + height: 600px; + } + + &:nth-child(2) { + grid-column: 5 / -1; // стовпці 5-12 + grid-row: 1; + height: 600px; + } + + &:nth-child(3) { + grid-column: 1 / 9; // стовпці 1-8 + grid-row: 2; + height: 360px; + } + + &:nth-child(4) { + grid-column: 9 / -1; // стовпці 9-12 + grid-row: 2; + height: 360px; + } + } + + .gallery-dots { + display: none; /* прибираємо навігацію на десктопі */ + } + } +} + +/* активна крапка через :has + :target (працює в сучасних браузерах) */ +/* stylelint-disable selector-max-id */ +.gallery-wrapper:has(#slide1:target) .gallery-dots a[href='#slide1'], +.gallery-wrapper:has(#slide2:target) .gallery-dots a[href='#slide2'], +.gallery-wrapper:has(#slide3:target) .gallery-dots a[href='#slide3'], +.gallery-wrapper:has(#slide4:target) .gallery-dots a[href='#slide4'] { + background: $color-success; + transform: scale(1.25); +} +/* stylelint-enable selector-max-id */ diff --git a/src/styles/components/_header.scss b/src/styles/components/_header.scss new file mode 100644 index 000000000..416caf4d5 --- /dev/null +++ b/src/styles/components/_header.scss @@ -0,0 +1,54 @@ +.header { + position: absolute; + top: 8px; + left: 50%; + transform: translateX(-50%); + width: 100%; + max-width: $max-content-width; + height: 60px; + z-index: 10; + display: flex; + align-items: center; + justify-content: center; + + &__navigation { + position: absolute; + left: 32px; + height: 100%; + display: flex; + align-items: center; + } + + &__menu-button { + width: 24px; + height: 24px; + background-image: url('../images/icons/menu.svg'); + background-size: contain; + background-repeat: no-repeat; + background-position: center; + border: none; + cursor: pointer; + text-decoration: none; + + &:hover { + @include hover(transform, scale(1.2)); + + background-image: url('../images/icons/icon-burger-menu-hover.png'); + } + } + + &__logo { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + height: 100%; + + img { + height: 100%; + object-fit: contain; + + @include hover(transform, scale(1.2)); + } + } +} diff --git a/src/styles/components/_hero.scss b/src/styles/components/_hero.scss new file mode 100644 index 000000000..81de8dd53 --- /dev/null +++ b/src/styles/components/_hero.scss @@ -0,0 +1,160 @@ +.hero { + @extend %flex-column; + + gap: 16px; + max-width: $max-content-width; + margin: 0 auto; + width: 100%; + overflow-x: hidden; + + @media (min-width: 600px) { + flex-direction: row-reverse; + } + + @include on-desktop { + @include page-grid; + + position: relative; + display: grid; + grid-template-rows: 1fr; + padding-inline: 30px; + } + + &__image { + @extend %full-image; + + height: 300px; + + @include on-tablet { + height: 384px; + flex: 1; + } + + @include on-desktop { + height: 655px; + grid-column: 7 / -1; + grid-row: 1; + flex: none; + } + } + + &__content { + @extend %flex-column; + + justify-content: center; + align-items: center; + row-gap: 20px; + grid-column: 1 / -1; + + @include section-padding; + + @include on-tablet { + flex: 1; + align-items: flex-start; + row-gap: 38px; + } + + @include on-desktop { + row-gap: 89px; + align-items: flex-start; + padding-inline: 0; + grid-column: 1 / 7; + grid-row: 1; + flex: none; + } + } + + &__title { + @extend %section-title; + + font-size: 45px; + text-align: center; + + @include on-tablet { + font-size: 54px; + text-align: left; + } + + @include on-desktop { + font-size: 72px; + text-align: left; + } + } + + &__events { + display: none; + text-decoration: none; + color: $color-accent; + + @include on-desktop { + display: flex; + justify-content: center; + align-items: center; + position: absolute; + bottom: 80px; + left: 30px; + font-size: 14px; + font-weight: bold; + color: $color-accent; + text-transform: uppercase; + transform: rotate(-90deg); + transform-origin: left bottom; + white-space: nowrap; + transition: color 0.3s ease; + + &:hover { + color: $color-primary; + } + + &::before { + content: ''; + display: inline-block; + width: 70px; + height: 1px; + background-color: $color-success; + margin-right: 20px; + } + } + } + + &__button { + @extend %flex-center; + @extend %smooth-transition; + + width: 100%; + background-color: $color-white; + border: 1px solid $color-success; + overflow: hidden; + cursor: pointer; + padding: 0; + text-decoration: none; + display: flex; + + @include on-desktop { + align-self: flex-end; + } + + &-text { + flex: 1; + text-align: center; + font-size: 16px; + font-weight: 600; + color: $color-dark-gray; + background-color: white; + } + + &-ico { + @extend %flex-center; + + width: 50px; + height: 50px; + background-color: $color-success; + margin: 0; + padding: 0; + } + + @include on-tablet { + width: 270px; + } + } +} diff --git a/src/styles/components/_info.scss b/src/styles/components/_info.scss new file mode 100644 index 000000000..cc20023d6 --- /dev/null +++ b/src/styles/components/_info.scss @@ -0,0 +1,243 @@ +.info { + @include page-grid; + @include section-margin; + + position: relative; + + @include on-desktop { + &::before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + grid-column: 2; + justify-self: center; + width: 1px; + background-color: $color-success; + } + } + + @include on-tablet { + flex-direction: row; + } + + @include on-desktop { + // gap: 80px; + } + + &__left { + grid-column: 1 / 1; + + @include on-tablet { + grid-column: 2 / 4; + } + + @include on-desktop { + grid-column: 8 / 10; + } + } + &__right { + grid-column: 2 / -1; + + @include on-tablet { + grid-column: span 2; + } + + @include on-desktop { + grid-column: span 2; + } + } + + &__schedule { + grid-column: 1 / 1; + + @include on-tablet { + grid-column: span 2; + } + + @include on-desktop { + grid-column: 3 / 5; + } + } + &__contacts { + grid-column: 2 / -1; + + @include on-tablet { + grid-column: span 2; + } + + @include on-desktop { + grid-column: 5 / 7; + } + } + + &__title { + font-size: 14px; + margin-bottom: 20px; + color: $color-primary; + line-height: 140.6%; + + @include on-tablet { + margin-bottom: 20px; + } + } + &__social { + grid-column: 1 / -1; + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 30px; + + @include on-tablet { + grid-column: span 1; + flex-direction: column; + align-items: flex-start; + justify-content: flex-start; + gap: 62px; + } + + @include on-desktop { + grid-column: span 1; + } + } + + &__logo { + img { + height: 48px; + width: auto; + } + } + + &__item { + font-size: 14px; + line-height: 150%; + color: $color-primary; + margin-bottom: 12px; + text-decoration: none; + transition: color 0.3s ease; + + &:hover { + color: $color-accent; + } + + &:last-child { + margin-bottom: 0; + } + } + + &__social-icons { + display: flex; + gap: 16px; + } + + &__social-link { + @extend %smooth-transition; + + display: block; + width: 24px; + height: 24px; + + &:hover { + opacity: 0.7; + } + + img { + @extend %full-image; + + height: 100%; + object-fit: contain; + } + } +} + +.schedule { + &__item { + display: flex; + flex-wrap: wrap; + column-gap: 4px; + align-items: center; + } + + &__day { + @extend %metadata-text; + + color: $color-secondary; + text-transform: capitalize; + } + + &__time { + font-size: 14px; + line-height: 150%; + color: $color-primary; + font-weight: bold; + } + + &__note { + margin-top: 16px; + padding-top: 16px; + } + + &__day-off { + font-size: 14px; + margin-bottom: 8px; + font-weight: 500; + line-height: 1.4; + } + + &__notice { + font-size: 14px; + color: $color-secondary; + line-height: 1.5; + margin-bottom: 60px; + } +} + +.contacts { + &__item { + @extend %flex-column; + + margin-bottom: 16px; + + @include on-tablet { + flex-direction: row; + align-items: flex-start; + } + + &:last-child { + margin-bottom: 0; + } + } + + &__label { + font-size: 14px; + color: $color-secondary; + margin-bottom: 4px; + font-weight: 500; + min-width: 80px; + + @include on-tablet { + margin-bottom: 0; + margin-right: 12px; + } + } + + &__value { + @extend %metadata-text; + + color: $color-primary; + line-height: 1.4; + text-transform: none; + + a { + @extend %smooth-transition; + + color: $color-primary; + text-decoration: none; + + &:hover { + color: $color-accent; + text-decoration: underline; + } + } + } +} diff --git a/src/styles/components/_lecture.scss b/src/styles/components/_lecture.scss new file mode 100644 index 000000000..d1df8d452 --- /dev/null +++ b/src/styles/components/_lecture.scss @@ -0,0 +1,122 @@ +.lecture { + position: relative; + + @include section-margin; + @include page-grid; + + padding-bottom: 40px; // Ще більше зменшуємо + overflow: visible; // Дозволяємо вільний потік контенту + + @include on-tablet { + padding-bottom: 50px; + } + + @include on-desktop { + padding-bottom: 60px; + } + + &__img { + grid-column: 1 / -1; + } + + &__image { + width: 100%; + object-fit: cover; + display: block; + + height: 210px; + + @include on-tablet { + height: 390px; + } + + @include on-desktop { + height: 550px; + } + } + + &__info { + @extend %flex-column; + @extend %flex-center; + @extend %smooth-transition; + + min-height: 140px; + position: absolute; + bottom: 0; + left: 20px; + right: 20px; + transform: translateY(15%); // Ще більше зменшуємо + background: white; + padding: 20px 15px; + box-shadow: 0 2px 0 rgba(26, 90, 76, 0.25); + + &:hover { + box-shadow: 0 6px 16px rgba($color-accent, 0.25); + } + + @include on-tablet { + grid-column: 2 / 6; + padding: 25px 20px; + transform: translateY(20%); // Ще більше зменшуємо + } + + @include on-desktop { + min-height: 204px; + grid-column: 4 / 10; + padding: 30px 25px; + transform: translateY(25%); // Ще більше зменшуємо + } + } + + &__wrap { + width: 100%; + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 15px; + + @include on-tablet { + margin-bottom: 20px; + } + } + + &__type { + @extend %metadata-text; + + font-size: 14px; + color: $color-secondary; + letter-spacing: 1px; + + @include on-tablet { + font-size: 16px; + } + } + + &__date { + @extend %metadata-text; + + font-size: 14px; + color: $color-success; + font-weight: bold; + + @include on-tablet { + font-size: 16px; + } + } + + &__name { + @include montserrat-hero-title; // використовуємо готовий міксін + + margin: 0; + text-align: center; + line-height: 1.3; + + @include on-tablet { + font-size: 28px; + } + + @include on-desktop { + font-size: 36px; + } + } +} diff --git a/src/styles/components/_subscribe.scss b/src/styles/components/_subscribe.scss new file mode 100644 index 000000000..03edb23d0 --- /dev/null +++ b/src/styles/components/_subscribe.scss @@ -0,0 +1,155 @@ +.subscribe { + padding-block: 88px; + background-image: url('../images/subscribe-bg.jpg'); + background-size: cover; + background-repeat: no-repeat; + background-position: center; + width: 100%; + + @include on-tablet { + padding-block: 82px; + } + + @include on-desktop { + padding-block: 163px; + } + + .section__content { + @include page-grid; + } + + &__content { + @extend %flex-column; + @extend %flex-center; + + box-sizing: border-box; + grid-column: 1 / -1; + padding-inline: 20px; + + @include on-tablet { + grid-column: 2 / -2; + padding-inline: 0; + } + + @include on-desktop { + grid-column: 4 / -4; + padding-inline: 0; + } + } + + &__title { + @extend %section-title; + + font-size: 36px; + margin-bottom: 20px; + color: $color-white; + + @include on-tablet { + font-size: 48px; + margin-bottom: 16px; + } + } + + &__text { + font-family: $font-primary; + font-size: 18px; + line-height: 150%; + margin-bottom: 50px; + text-align: center; + color: $color-white; + + @include on-tablet { + line-height: 100%; + font-weight: bold; + margin-bottom: 64px; + } + } + + &__form { + display: flex; + height: 50px; + width: 100%; + + @include on-tablet { + height: 70px; + gap: 16px; + } + + @include on-desktop { + height: 70px; + gap: $grid-gutter-desktop; + } + } + + &__input { + @extend %smooth-transition; + + flex: 1; + padding: 12px 16px; + font-size: 16px; + border: none; + + &:focus { + outline: none; + border-color: $color-primary; + } + } + + &__button { + @extend %smooth-transition; + + width: 50px; + height: 50px; + flex-shrink: 0; + padding: 0; + background-color: $color-warning; + border: none; + cursor: pointer; + + background-image: url(../images/icons/arrow-black.png); + background-repeat: no-repeat; + background-position: center; + background-size: 24px 24px; + + @include on-tablet { + width: 70px; + height: 70px; + } + + @include on-desktop { + width: 70px; + height: 70px; + } + + &:hover { + background-color: $color-warning-dark; + } + + &:active { + transform: scale(0.95); + background-color: $color-success; + } + } + + // Анімація після успішної відправки + &__form:target &__button, + &__form[data-submitted='true'] &__button { + background-color: $color-success; + animation: submit-success 2s ease-in-out; + } + + @keyframes submit-success { + 0% { + background-color: $color-warning; + transform: scale(1); + } + 50% { + background-color: $color-success; + transform: scale(1.1); + } + 100% { + background-color: $color-warning; + transform: scale(1); + } + } +} diff --git a/src/styles/main.scss b/src/styles/main.scss index fb9195d12..1285084a7 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss @@ -1,7 +1,66 @@ -@import 'utils'; +@import 'utils/vars'; +@import 'utils/mixins'; +@import 'utils/extends'; @import 'fonts'; -@import 'typography'; + +// Загальні стилі +html { + scroll-behavior: smooth; + overflow: hidden auto; // Дозволяємо тільки природний вертикальний скрол +} body { - background: $c-gray; + overflow: hidden auto; // Дозволяємо тільки природний вертикальний скрол +} + +h1, +h2, +h3, +p { + margin: 0; + color: $color-primary; } + +.content { + padding-inline: 20px; +} + +$hero-section-height: 300px; + +* { + box-sizing: border-box; +} + +.page { + &__body { + font-family: Arial, sans-serif; + line-height: 1.6; + padding: 0; + min-width: 320px; + overflow-x: hidden; + margin: 0 auto; + } +} + +.main { + display: flex; + flex-direction: column; + margin: 0 auto; + width: 100%; + overflow-x: hidden; + + @include section-gap; +} + +// Імпорт компонентів +@import 'components/common'; +@import 'components/aside-menu'; +@import 'components/header'; +@import 'components/hero'; +@import 'components/events'; +@import 'components/lecture'; +@import 'components/gallery'; +@import 'components/subscribe'; +@import 'components/info'; +@import 'components/copyright'; +@import 'components/footer'; diff --git a/src/styles/utils/_extends.scss b/src/styles/utils/_extends.scss index d7201e7b3..10ed824a7 100644 --- a/src/styles/utils/_extends.scss +++ b/src/styles/utils/_extends.scss @@ -1,4 +1,41 @@ -%h1 { - font-family: Roboto, sans-serif; - font-weight: 400; +// Заголовки +%section-title { + font-family: $font-secondary; + font-weight: bold; + margin: 0; + color: $color-primary; + letter-spacing: 2px; +} + +// Flex контейнери +%flex-center { + display: flex; + align-items: center; + justify-content: center; +} + +%flex-column { + display: flex; + flex-direction: column; +} + +// Повнорозмірні зображення +%full-image { + width: 100%; + object-fit: cover; + display: block; +} + +// Метадані (дата, тип) +%metadata-text { + font-family: $font-primary; + font-size: 16px; + line-height: 150%; + font-weight: 500; + text-transform: uppercase; +} + +// Плавні переходи +%smooth-transition { + transition: all 0.3s ease; } diff --git a/src/styles/utils/_mixins.scss b/src/styles/utils/_mixins.scss index 80c79780d..be28b0381 100644 --- a/src/styles/utils/_mixins.scss +++ b/src/styles/utils/_mixins.scss @@ -4,3 +4,279 @@ #{$_property}: $_toValue; } } + +@mixin flex-center { + display: flex; + justify-content: center; + align-items: center; +} + +@mixin on-tablet() { + @media (min-width: $tablet-breakpoint) { + @content; + } +} + +@mixin on-desktop() { + @media (min-width: $desktop-breakpoint) { + @content; + } +} + +@mixin page-grid { + --columns-count: 2; + + column-gap: $grid-gutter-mobile; + display: grid; + grid-template-columns: repeat(var(--columns-count), 1fr); + + @include on-tablet { + --columns-count: 6; + + column-gap: $grid-gutter-tablet; + } + + @include on-desktop { + --columns-count: 12; + + column-gap: $grid-gutter-desktop; + } +} + +// Міксіни для вертикальних відступів +@mixin section-padding() { + padding-inline: 20px; + + @include on-tablet { + padding-inline: 39px; + } + + @include on-desktop { + padding-inline: 55px; + } +} + +@mixin section-margin() { + margin-bottom: 20px; + + @include on-tablet { + margin-bottom: 39px; + } + + @include on-desktop { + margin-bottom: 55px; + } +} + +@mixin section-gap() { + gap: 20px; + + @include on-tablet { + gap: 39px; + } + + @include on-desktop { + gap: 55px; + } +} + +// Міксін для контенту з вертикальними відступами +@mixin content-spacing() { + padding-block: 20px; + + @include on-tablet { + padding-block: 39px; + } + + @include on-desktop { + padding-block: 55px; + } +} + +// Typography mixins +@mixin font-preset( + $family, + $size, + $weight, + $line-height: $line-height-normal, + $letter-spacing: 0 +) { + font-family: $family; + font-size: $size; + font-weight: $weight; + line-height: $line-height; + letter-spacing: $letter-spacing; +} + +// IBM Plex Sans presets (з Figma) +@mixin ibm-title() { + @include font-preset( + $font-primary, + $font-size-sm, + $font-weight-regular, + $line-height-relaxed + ); +} + +@mixin ibm-button() { + @include font-preset( + $font-primary, + $font-size-base, + $font-weight-medium, + $line-height-tight + ); +} + +@mixin ibm-copyright() { + @include font-preset( + $font-primary, + $font-size-xs, + $font-weight-light, + $line-height-relaxed + ); +} + +@mixin ibm-events() { + @include font-preset( + $font-primary, + $font-size-sm, + $font-weight-bold, + $line-height-tight + ); +} + +@mixin ibm-lecture() { + @include font-preset( + $font-primary, + $font-size-sm, + $font-weight-medium, + $line-height-tight + ); +} + +@mixin ibm-description() { + @include font-preset( + $font-primary, + $font-size-base, + $font-weight-light, + $line-height-loose + ); +} + +@mixin ibm-date() { + @include font-preset( + $font-primary, + $font-size-base, + $font-weight-bold, + $line-height-loose + ); +} + +@mixin ibm-subscribe() { + @include font-preset( + $font-primary, + $font-size-lg, + $font-weight-regular, + $line-height-tight + ); +} + +@mixin ibm-gallery-nav() { + @include font-preset( + $font-primary, + $font-size-xl, + $font-weight-medium, + $line-height-tight + ); +} + +@mixin ibm-summary() { + @include font-preset( + $font-primary, + $font-size-sm, + $font-weight-semibold, + $line-height-loose + ); +} + +// Montserrat presets (з Figma) +@mixin montserrat-logo() { + @include font-preset( + $font-secondary, + $font-size-3xl, + $font-weight-bold, + $line-height-tight + ); +} + +@mixin montserrat-logo-small() { + @include font-preset( + $font-secondary, + 30px, + $font-weight-bold, + $line-height-tight + ); +} + +@mixin montserrat-hero-title() { + @include font-preset( + $font-secondary, + $font-size-3xl, + $font-weight-regular, + $line-height-tight + ); +} + +@mixin montserrat-event-title() { + @include font-preset( + $font-secondary, + $font-size-2xl, + $font-weight-regular, + $line-height-tight + ); +} + +@mixin montserrat-gallery-title() { + @include font-preset( + $font-secondary, + $font-size-5xl, + $font-weight-bold, + $line-height-tight + ); +} + +@mixin montserrat-hero-large() { + @include font-preset( + $font-secondary, + $font-size-4xl, + $font-weight-bold, + $line-height-tight + ); +} + +@mixin montserrat-hero-medium() { + @include font-preset( + $font-secondary, + $font-size-6xl, + $font-weight-bold, + $line-height-normal + ); +} + +@mixin montserrat-hero-desktop() { + @include font-preset( + $font-secondary, + $font-size-7xl, + $font-weight-bold, + $line-height-normal + ); +} + +@mixin montserrat-input() { + @include font-preset( + $font-secondary, + $font-size-sm, + $font-weight-regular, + $line-height-tight + ); +} diff --git a/src/styles/utils/_vars.scss b/src/styles/utils/_vars.scss index aeb006ffb..afa45f5d4 100644 --- a/src/styles/utils/_vars.scss +++ b/src/styles/utils/_vars.scss @@ -1 +1,64 @@ +// Colors $c-gray: #eee; +$color-primary: #0f0e08; +$color-secondary: #4e4e4e; +$color-accent: #687480; +$color-success: #1a5a4c; +$color-warning: #f14a27; +$color-error: #f44336; +$color-info: #2196f3; + +// Additional colors from design +$color-white: #fff; +$color-black: #000; +$color-dark: #111; +$color-dark-gray: #333; +$color-light-gray: #e0e0e0; +$color-bg-light: #f9f9f9; +$color-warning-dark: #d63e1e; +$color-overlay: rgba(0, 0, 0, 0.5); + +// Fonts +$font-primary: 'IBM Plex Sans', Arial, sans-serif; +$font-secondary: 'Montserrat', Arial, sans-serif; +$font-fallback: Arial, Helvetica, sans-serif; + +// Font weights +$font-weight-light: 300; +$font-weight-regular: 400; +$font-weight-medium: 500; +$font-weight-semibold: 600; +$font-weight-bold: 700; + +// Font sizes +$font-size-xs: 12px; +$font-size-sm: 14px; +$font-size-base: 16px; +$font-size-lg: 18px; +$font-size-xl: 22px; +$font-size-2xl: 28px; +$font-size-3xl: 36px; +$font-size-4xl: 45px; +$font-size-5xl: 48px; +$font-size-6xl: 54px; +$font-size-7xl: 72px; + +// Line heights +$line-height-tight: 100%; +$line-height-normal: 120%; +$line-height-relaxed: 140.63%; +$line-height-loose: 150%; + +// Breakpoints +$mobile-breakpoint: 320px; +$tablet-breakpoint: 640px; +$desktop-breakpoint: 1280px; +$design-breakpoint: 1440px; + +// Layout constraints +$max-content-width: 1280px; + +// grid gutter +$grid-gutter-mobile: 20px; +$grid-gutter-tablet: 30px; +$grid-gutter-desktop: 30px;