Compare commits
6 Commits
feature/mi
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48c8f7b1cf | ||
|
|
338e8b233b | ||
|
|
999da5fef4 | ||
|
|
d3816b0952 | ||
|
|
d3343f1f7b | ||
|
|
7c94fa8ffe |
302
README.md
302
README.md
@@ -1,6 +1,286 @@
|
||||
# Only Task
|
||||
# GSAP Carousel
|
||||
|
||||
Тестовое задание для only.digital
|
||||
---
|
||||
|
||||
[🌐 English](#english) | [🇷🇺 Русский](#russian)
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
<a id="english"></a>
|
||||
|
||||
---
|
||||
|
||||
[🌍 Scroll to top](#) | [🇷🇺 Русский](#russian)
|
||||
|
||||
---
|
||||
|
||||
# GSAP Carousel
|
||||
|
||||
React-based UI component developed to explore advanced animation patterns using GSAP. This project focuses on synchronizing complex circular transitions with a dynamic content carousel.
|
||||
|
||||
## Technical Highlights
|
||||
|
||||
- **GSAP Integration**: Implementation of smooth, high-performance animations for state transitions
|
||||
- **Circular Data Visualization**: An interactive timeline with selectable time periods
|
||||
- **Adaptive Layout**: Fully responsive architecture supporting mobile, tablet, and desktop viewports
|
||||
- **Custom Navigation**: Bespoke UI controls for seamless event browsing
|
||||
|
||||
## 🚀 Technologies
|
||||
|
||||
- **React 19** - User interface library
|
||||
- **TypeScript 5** - Typed JavaScript
|
||||
- **GSAP** - Smooth animation library
|
||||
- **Swiper** - Modern carousel library
|
||||
- **Webpack 5** - Module bundler
|
||||
- **SCSS** - CSS preprocessor with modules
|
||||
- **Jest** - Testing framework
|
||||
- **ESLint + Prettier** - Code linting and formatting
|
||||
|
||||
## 📋 Requirements
|
||||
|
||||
- **Node.js** >= 18.0.0
|
||||
- **pnpm** >= 8.0.0
|
||||
|
||||
## 🛠️ Installation
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd gsap-carousel
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
## 🎯 Available Commands
|
||||
|
||||
### Development
|
||||
|
||||
```bash
|
||||
# Start dev-server on port 3000
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
The application will be available at: http://localhost:3000
|
||||
|
||||
### Build
|
||||
|
||||
```bash
|
||||
# Production build
|
||||
pnpm build:prod
|
||||
|
||||
# Development build
|
||||
pnpm build:dev
|
||||
```
|
||||
|
||||
The build result will be in the `dist/` folder
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
# Run all unit tests
|
||||
pnpm test:unit
|
||||
|
||||
# Check TypeScript types
|
||||
pnpm type-check
|
||||
```
|
||||
|
||||
### Linting
|
||||
|
||||
```bash
|
||||
# Check JavaScript/TypeScript code
|
||||
pnpm lint
|
||||
|
||||
# Auto-fix errors
|
||||
pnpm lint --fix
|
||||
|
||||
# Check styles (SCSS)
|
||||
pnpm lint:styles
|
||||
|
||||
# Auto-fix styles
|
||||
pnpm lint:styles --fix
|
||||
```
|
||||
|
||||
### Storybook
|
||||
|
||||
```bash
|
||||
# Run Storybook for component development
|
||||
pnpm storybook
|
||||
|
||||
# Build static version of Storybook
|
||||
pnpm build-storybook
|
||||
```
|
||||
|
||||
### Pre-push Checks
|
||||
|
||||
```bash
|
||||
# Run all checks before push
|
||||
pnpm pre-push
|
||||
```
|
||||
|
||||
This command runs:
|
||||
|
||||
- ✅ TypeScript type checking
|
||||
- ✅ Code linting
|
||||
- ✅ Style linting
|
||||
- ✅ Unit tests
|
||||
- ✅ Production build
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
gsap-carousel/
|
||||
├── config/ # Build configuration
|
||||
│ ├── build/ # Webpack configuration
|
||||
│ ├── jest/ # Jest configuration
|
||||
│ └── storybook/ # Storybook configuration
|
||||
├── dist/ # Production build (generated)
|
||||
├── src/ # Source code
|
||||
│ ├── app/ # Root application component
|
||||
│ ├── entities/ # Business entities (data types)
|
||||
│ ├── shared/ # Reusable components and utilities
|
||||
│ │ ├── assets/ # Static resources (SVG, images)
|
||||
│ │ └── ui/ # UI components (Button, Card)
|
||||
│ └── widgets/ # Complex components (TimeFrameSlider)
|
||||
├── .husky/ # Git hooks
|
||||
├── package.json # Dependencies and scripts
|
||||
└── tsconfig.json # TypeScript configuration
|
||||
```
|
||||
|
||||
## 🎨 Main Components
|
||||
|
||||
### TimeFrameSlider
|
||||
|
||||
The main application widget combining a circular timeline and an events carousel.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Interactive circular chart with periods
|
||||
- Smooth GSAP animations during transitions
|
||||
- Responsive design for mobile, tablet, and desktop
|
||||
- Custom navigation
|
||||
|
||||
### CircleTimeline
|
||||
|
||||
A circular timeline with period points.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Auto-rotation to the active period
|
||||
- Click on points to switch periods
|
||||
- Period title animations
|
||||
|
||||
### EventsCarousel
|
||||
|
||||
Historical events carousel using Swiper.
|
||||
|
||||
**Features:**
|
||||
|
||||
- Adaptive number of slides
|
||||
- Custom navigation
|
||||
- Smooth appearance/disappearance animation
|
||||
|
||||
## ⚡ Performance Optimization
|
||||
|
||||
The project is optimized for production:
|
||||
|
||||
- ✅ **Code splitting** - chunk separation (vendors, runtime, main)
|
||||
- ✅ **Tree shaking** - removal of unused code
|
||||
- ✅ **Gzip compression** - file compression (~68% size reduction)
|
||||
- ✅ **Minification** - JS and CSS minification
|
||||
- ✅ **CSS Modules** - isolated component styles
|
||||
- ✅ **Babel caching** - caching for fast rebuilds
|
||||
|
||||
**Bundle size:**
|
||||
|
||||
- Uncompressed: ~371 KiB
|
||||
- Gzipped: ~117 KiB
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
The project is covered by unit tests:
|
||||
|
||||
- ✅ Component tests (Button, Card, CircleTimeline, TimeFrameSlider, EventsCarousel)
|
||||
- ✅ Utility tests (calculateCoordinates)
|
||||
- ✅ Mocks for GSAP and Swiper
|
||||
- ✅ 39 tests, 100% successful
|
||||
|
||||
## 📱 Responsiveness
|
||||
|
||||
The application is adapted for all devices:
|
||||
|
||||
- **Desktop** (>1440px) - Full version with circular chart
|
||||
- **Tablet** (768px - 1024px) - Optimized version
|
||||
- **Mobile** (<768px) - Simplified version with bottom navigation
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
### Webpack
|
||||
|
||||
- Babel for transpilation (faster than ts-loader)
|
||||
- CSS Modules for style isolation
|
||||
- SVGR for importing SVG as React components
|
||||
- Hot Module Replacement for development
|
||||
- Bundle Analyzer for size analysis
|
||||
|
||||
### TypeScript
|
||||
|
||||
- Strict mode enabled
|
||||
- Path aliases (`@/*` → `src/*`)
|
||||
- Type checking separate from build
|
||||
|
||||
### ESLint
|
||||
|
||||
- Rules for React, TypeScript, Jest
|
||||
- Prettier integration
|
||||
- Import sorting
|
||||
|
||||
## 🤝 Git Hooks
|
||||
|
||||
Pre-push hook automatically runs:
|
||||
|
||||
1. Type checking
|
||||
2. ESLint
|
||||
3. Stylelint
|
||||
4. Unit tests
|
||||
5. Production build
|
||||
|
||||
This ensures that only working code enters the repository.
|
||||
|
||||
## 📝 License
|
||||
|
||||
ISC
|
||||
|
||||
**Happy coding! 🚀**
|
||||
|
||||
---
|
||||
|
||||
<a id="russian"></a>
|
||||
|
||||
---
|
||||
|
||||
[🌍 Scroll to top](#) | [🌐 English](#english)
|
||||
|
||||
---
|
||||
|
||||
# GSAP Carousel
|
||||
|
||||
React-компонент UI для изучения продвинутых паттернов анимации с использованием GSAP. Проект фокусируется на синхронизации сложных круговых переходов с динамической каруселью контента.
|
||||
|
||||
## Технические особенности
|
||||
|
||||
- **Интеграция GSAP**: Реализация плавных высокопроизводительных анимаций для переходов между состояниями
|
||||
- **Круговая визуализация данных**: Интерактивная временная шкала с выбираемыми периодами
|
||||
- **Адаптивный макет**: Полностью адаптивная архитектура, поддерживающая мобильные устройства, планшеты и десктопы
|
||||
- **Кастомная навигация**: Собственные элементы управления UI для удобного просмотра событий
|
||||
|
||||
## 🚀 Технологии
|
||||
|
||||
@@ -21,12 +301,14 @@
|
||||
## 🛠️ Установка
|
||||
|
||||
1. Клонируйте репозиторий:
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd only-task
|
||||
cd gsap-carousel
|
||||
```
|
||||
|
||||
2. Установите зависимости:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
@@ -98,6 +380,7 @@ pnpm pre-push
|
||||
```
|
||||
|
||||
Эта команда выполняет:
|
||||
|
||||
- ✅ Проверку типов TypeScript
|
||||
- ✅ Линтинг кода
|
||||
- ✅ Линтинг стилей
|
||||
@@ -107,7 +390,7 @@ pnpm pre-push
|
||||
## 📁 Структура проекта
|
||||
|
||||
```
|
||||
only-task/
|
||||
gsap-carousel/
|
||||
├── config/ # Конфигурация сборки
|
||||
│ ├── build/ # Webpack конфигурация
|
||||
│ ├── jest/ # Jest конфигурация
|
||||
@@ -128,26 +411,32 @@ only-task/
|
||||
## 🎨 Основные компоненты
|
||||
|
||||
### TimeFrameSlider
|
||||
|
||||
Главный виджет приложения, объединяющий круговую временную шкалу и карусель событий.
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Интерактивная круговая диаграмма с периодами
|
||||
- Плавные GSAP анимации при переключении
|
||||
- Адаптивный дизайн для мобильных, планшетов и десктопа
|
||||
- Кастомная навигация
|
||||
|
||||
### CircleTimeline
|
||||
|
||||
Круговая временная шкала с точками периодов.
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Автоматический поворот к активному периоду
|
||||
- Клик по точкам для переключения
|
||||
- Анимация заголовков периодов
|
||||
|
||||
### EventsCarousel
|
||||
|
||||
Карусель исторических событий с использованием Swiper.
|
||||
|
||||
**Особенности:**
|
||||
|
||||
- Адаптивное количество слайдов
|
||||
- Кастомная навигация
|
||||
- Плавная анимация появления/исчезновения
|
||||
@@ -164,6 +453,7 @@ only-task/
|
||||
- ✅ **Babel caching** - кеширование для быстрой пересборки
|
||||
|
||||
**Размер бандла:**
|
||||
|
||||
- Uncompressed: ~371 KiB
|
||||
- Gzipped: ~117 KiB
|
||||
|
||||
@@ -187,6 +477,7 @@ only-task/
|
||||
## 🔧 Конфигурация
|
||||
|
||||
### Webpack
|
||||
|
||||
- Babel для транспиляции (быстрее ts-loader)
|
||||
- CSS Modules для изоляции стилей
|
||||
- SVGR для импорта SVG как React компонентов
|
||||
@@ -194,11 +485,13 @@ only-task/
|
||||
- Bundle Analyzer для анализа размера
|
||||
|
||||
### TypeScript
|
||||
|
||||
- Strict mode включен
|
||||
- Path aliases (`@/*` → `src/*`)
|
||||
- Проверка типов отдельно от сборки
|
||||
|
||||
### ESLint
|
||||
|
||||
- Правила для React, TypeScript, Jest
|
||||
- Prettier интеграция
|
||||
- Import sorting
|
||||
@@ -206,6 +499,7 @@ only-task/
|
||||
## 🤝 Git Hooks
|
||||
|
||||
Pre-push hook автоматически запускает:
|
||||
|
||||
1. Type checking
|
||||
2. ESLint
|
||||
3. Stylelint
|
||||
|
||||
BIN
assets/gsap-carousel.gif
Normal file
BIN
assets/gsap-carousel.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
@@ -40,6 +40,7 @@
|
||||
"@storybook/addon-webpack5-compiler-babel": "^4.0.0",
|
||||
"@storybook/react": "^8.6.14",
|
||||
"@storybook/react-webpack5": "^8.6.14",
|
||||
"@stylistic/stylelint-plugin": "^4.0.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
|
||||
25
pnpm-lock.yaml
generated
25
pnpm-lock.yaml
generated
@@ -63,6 +63,9 @@ importers:
|
||||
'@storybook/react-webpack5':
|
||||
specifier: ^8.6.14
|
||||
version: 8.6.14(@storybook/test@8.6.14(storybook@8.6.14(prettier@3.6.2)))(esbuild@0.25.12)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(storybook@8.6.14(prettier@3.6.2))(typescript@5.9.3)(webpack-cli@5.1.4)
|
||||
'@stylistic/stylelint-plugin':
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0(stylelint@16.25.0(typescript@5.9.3))
|
||||
'@svgr/webpack':
|
||||
specifier: ^8.1.0
|
||||
version: 8.1.0(typescript@5.9.3)
|
||||
@@ -1664,6 +1667,12 @@ packages:
|
||||
peerDependencies:
|
||||
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
|
||||
|
||||
'@stylistic/stylelint-plugin@4.0.0':
|
||||
resolution: {integrity: sha512-CFwt3K4Y/7bygNCLCQ8Sy4Hzgbhxq3BsNW0FIuYxl17HD3ywptm54ocyeiLVRrk5jtz1Zwks7Xr9eiZt8SWHAw==}
|
||||
engines: {node: ^18.12 || >=20.9}
|
||||
peerDependencies:
|
||||
stylelint: ^16.22.0
|
||||
|
||||
'@svgr/babel-plugin-add-jsx-attribute@8.0.0':
|
||||
resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -5224,6 +5233,9 @@ packages:
|
||||
peerDependencies:
|
||||
webpack: ^5.27.0
|
||||
|
||||
style-search@0.1.0:
|
||||
resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==}
|
||||
|
||||
stylelint-config-recommended-scss@14.1.0:
|
||||
resolution: {integrity: sha512-bhaMhh1u5dQqSsf6ri2GVWWQW5iUjBYgcHkh7SgDDn92ijoItC/cfO/W+fpXshgTQWhwFkP1rVcewcv4jaftRg==}
|
||||
engines: {node: '>=18.12.0'}
|
||||
@@ -7531,6 +7543,17 @@ snapshots:
|
||||
dependencies:
|
||||
storybook: 8.6.14(prettier@3.6.2)
|
||||
|
||||
'@stylistic/stylelint-plugin@4.0.0(stylelint@16.25.0(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
||||
'@csstools/css-tokenizer': 3.0.4
|
||||
'@csstools/media-query-list-parser': 4.0.3(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
|
||||
postcss: 8.5.6
|
||||
postcss-selector-parser: 7.1.0
|
||||
postcss-value-parser: 4.2.0
|
||||
style-search: 0.1.0
|
||||
stylelint: 16.25.0(typescript@5.9.3)
|
||||
|
||||
'@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
@@ -11617,6 +11640,8 @@ snapshots:
|
||||
dependencies:
|
||||
webpack: 5.103.0(esbuild@0.25.12)(webpack-cli@5.1.4)
|
||||
|
||||
style-search@0.1.0: {}
|
||||
|
||||
stylelint-config-recommended-scss@14.1.0(postcss@8.5.6)(stylelint@16.25.0(typescript@5.9.3)):
|
||||
dependencies:
|
||||
postcss-scss: 4.0.9(postcss@8.5.6)
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-family-main);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-family-main);
|
||||
|
||||
background-color: var(--color-bg);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
background-color: var(--color-bg);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: inherit;
|
||||
font-family: inherit;
|
||||
|
||||
border: none;
|
||||
border: none;
|
||||
|
||||
background: none;
|
||||
background: none;
|
||||
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
list-style: none;
|
||||
list-style: none;
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
:root {
|
||||
// Цвета
|
||||
--color-primary: #42567A;
|
||||
--color-accent: #EF5DA8;
|
||||
--color-text: #42567A;
|
||||
--color-bg: #F4F5F9;
|
||||
--color-border: rgb(66 86 122 / 10%);
|
||||
--color-blue: #3877EE;
|
||||
--color-white: #FFF;
|
||||
// Цвета
|
||||
--color-primary: #42567A;
|
||||
--color-accent: #EF5DA8;
|
||||
--color-text: #42567A;
|
||||
--color-bg: #F4F5F9;
|
||||
--color-border: rgb(66 86 122 / 10%);
|
||||
--color-blue: #3877EE;
|
||||
--color-white: #FFF;
|
||||
|
||||
// Градиенты
|
||||
--gradient-primary: linear-gradient(to bottom, #3877EE, #EF5DA8);
|
||||
// Градиенты
|
||||
--gradient-primary: linear-gradient(to bottom, #3877EE, #EF5DA8);
|
||||
|
||||
// Типографика
|
||||
--font-family-main: 'PT Sans', sans-serif;
|
||||
--font-size-h1: 56px;
|
||||
--font-size-h2: 32px;
|
||||
--font-size-h3: 20px;
|
||||
--font-size-body: 16px;
|
||||
--font-size-small: 14px;
|
||||
--line-height-h1: 120%;
|
||||
--line-height-body: 150%;
|
||||
// Типографика
|
||||
--font-family-main: 'PT Sans', sans-serif;
|
||||
--font-size-h1: 56px;
|
||||
--font-size-h2: 32px;
|
||||
--font-size-h3: 20px;
|
||||
--font-size-body: 16px;
|
||||
--font-size-small: 14px;
|
||||
--line-height-h1: 120%;
|
||||
--line-height-body: 150%;
|
||||
}
|
||||
@@ -1,108 +1,108 @@
|
||||
.button {
|
||||
display: inline-flex;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
padding: 0;
|
||||
|
||||
font-family: var(--font-family-main);
|
||||
|
||||
border: none;
|
||||
|
||||
background: transparent;
|
||||
|
||||
outline: none;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
// Variants
|
||||
&.round {
|
||||
border-radius: 50%;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
&.regular {
|
||||
padding: 0.5em 1em;
|
||||
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
// Sizes
|
||||
&.small {
|
||||
height: 40px;
|
||||
|
||||
font-size: 14px;
|
||||
|
||||
@media (width <=768px) {
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&.medium {
|
||||
height: 50px;
|
||||
|
||||
font-size: 18px;
|
||||
|
||||
@media (width <=768px) {
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
height: 60px;
|
||||
|
||||
font-size: 24px;
|
||||
|
||||
@media (width <=768px) {
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
// Color Schemes
|
||||
&.primary {
|
||||
$color-primary: var(--color-primary);
|
||||
color: $color-primary;
|
||||
|
||||
border: 1px solid $color-primary;
|
||||
|
||||
background-color: transparent;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: var(--color-white);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
$color-blue: var(--color-blue);
|
||||
color: $color-blue;
|
||||
|
||||
background-color: var(--color-white);
|
||||
|
||||
box-shadow: 0 0 15px rgb($color-blue / 10%);
|
||||
}
|
||||
|
||||
// Icon handling
|
||||
.icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
font-family: var(--font-family-main);
|
||||
svg {
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
|
||||
border: none;
|
||||
|
||||
background: transparent;
|
||||
|
||||
outline: none;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
// Variants
|
||||
&.round {
|
||||
border-radius: 50%;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
|
||||
&.regular {
|
||||
padding: 0.5em 1em;
|
||||
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
// Sizes
|
||||
&.small {
|
||||
height: 40px;
|
||||
|
||||
font-size: 14px;
|
||||
|
||||
@media (width <=768px) {
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&.medium {
|
||||
height: 50px;
|
||||
|
||||
font-size: 18px;
|
||||
|
||||
@media (width <=768px) {
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
height: 60px;
|
||||
|
||||
font-size: 24px;
|
||||
|
||||
@media (width <=768px) {
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
// Color Schemes
|
||||
&.primary {
|
||||
$color-primary: var(--color-primary);
|
||||
color: $color-primary;
|
||||
|
||||
border: 1px solid $color-primary;
|
||||
|
||||
background-color: transparent;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
background-color: var(--color-white);
|
||||
}
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
$color-blue: var(--color-blue);
|
||||
color: $color-blue;
|
||||
|
||||
background-color: var(--color-white);
|
||||
|
||||
box-shadow: 0 0 15px rgb($color-blue / 10%);
|
||||
}
|
||||
|
||||
// Icon handling
|
||||
.icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
svg {
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
|
||||
object-fit: contain;
|
||||
}
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,27 @@
|
||||
.card {
|
||||
padding: 20px 0;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-bottom: 15px;
|
||||
margin-bottom: 15px;
|
||||
|
||||
color: var(--color-blue);
|
||||
font-weight: 400;
|
||||
font-size: 25px;
|
||||
line-height: 120%;
|
||||
color: var(--color-blue);
|
||||
font-weight: 400;
|
||||
font-size: 25px;
|
||||
line-height: 120%;
|
||||
|
||||
@media (width <=768px) {
|
||||
font-size: 16px;
|
||||
}
|
||||
@media (width <=768px) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
color: var(--color-text);
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
line-height: 145%;
|
||||
color: var(--color-text);
|
||||
font-weight: 400;
|
||||
font-size: 20px;
|
||||
line-height: 145%;
|
||||
|
||||
@media (width <=768px) {
|
||||
font-size: 14px;
|
||||
}
|
||||
@media (width <=768px) {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +1,76 @@
|
||||
.circleContainer {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
|
||||
width: calc(var(--circle-radius, 265px) * 2);
|
||||
height: calc(var(--circle-radius, 265px) * 2);
|
||||
width: calc(var(--circle-radius, 265px) * 2);
|
||||
height: calc(var(--circle-radius, 265px) * 2);
|
||||
|
||||
border: 1px solid rgba(#42567A, 0.2);
|
||||
border-radius: 50%;
|
||||
border: 1px solid rgba(#42567A, 0.2);
|
||||
border-radius: 50%;
|
||||
|
||||
transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.point {
|
||||
position: absolute;
|
||||
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin-top: -28px;
|
||||
margin-left: -28px;
|
||||
|
||||
border: 25px solid transparent;
|
||||
border-radius: 50%;
|
||||
|
||||
background: var(--color-text);
|
||||
background-clip: content-box;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
transform-origin: center;
|
||||
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
z-index: 10;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
border: 1px solid rgba(#303E58, 0.5);
|
||||
|
||||
background: #F4F5F9;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
&:hover .number,
|
||||
&.active .number {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.number {
|
||||
display: none;
|
||||
|
||||
color: var(--color-text);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin-top: -28px;
|
||||
margin-left: -28px;
|
||||
margin-left: 20px;
|
||||
|
||||
border: 25px solid transparent;
|
||||
border-radius: 50%;
|
||||
color: var(--color-text);
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
white-space: nowrap;
|
||||
|
||||
background: var(--color-text);
|
||||
background-clip: content-box;
|
||||
visibility: hidden;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
transform-origin: center;
|
||||
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
z-index: 10;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
border: 1px solid rgba(#303E58, 0.5);
|
||||
|
||||
background: #F4F5F9;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
&:hover .number,
|
||||
&.active .number {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.number {
|
||||
display: none;
|
||||
|
||||
color: var(--color-text);
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
left: 100%;
|
||||
|
||||
margin-left: 20px;
|
||||
|
||||
color: var(--color-text);
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
white-space: nowrap;
|
||||
|
||||
visibility: hidden;
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +1,51 @@
|
||||
.container {
|
||||
position: relative;
|
||||
position: relative;
|
||||
|
||||
opacity: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.prevButtonWrapper {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -60px;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -60px;
|
||||
z-index: 10;
|
||||
|
||||
transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
|
||||
transition: opacity 0.3s ease;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.nextButtonWrapper {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: -60px;
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: -60px;
|
||||
z-index: 10;
|
||||
|
||||
transform: translateY(-50%) rotate(180deg);
|
||||
transform: translateY(-50%) rotate(180deg);
|
||||
|
||||
transition: opacity 0.3s ease;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
opacity: 0;
|
||||
opacity: 0;
|
||||
|
||||
pointer-events: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
:global(.swiper) {
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
padding: 0 40px;
|
||||
}
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
padding: 0 40px;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.swiper-slide-visible) {
|
||||
transition: opacity 0.3s ease;
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
@container timeframe-slider (width < 768px) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
@container timeframe-slider (width < 768px) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.swiper-slide-fully-visible) {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
@@ -1,303 +1,303 @@
|
||||
/* Wrapper для container queries - должен быть родителем контейнера */
|
||||
.wrapper {
|
||||
/* Включаем container queries для адаптивности виджета */
|
||||
container-type: inline-size;
|
||||
container-name: timeframe-slider;
|
||||
/* Включаем container queries для адаптивности виджета */
|
||||
container-type: inline-size;
|
||||
container-name: timeframe-slider;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
position: relative;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
width: 100%;
|
||||
max-width: 1440px;
|
||||
min-height: 100vh;
|
||||
margin: 0 auto;
|
||||
padding-top: 180px;
|
||||
width: 100%;
|
||||
max-width: 1440px;
|
||||
min-height: 100vh;
|
||||
margin: 0 auto;
|
||||
padding-top: 180px;
|
||||
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-family-main);
|
||||
color: var(--color-text);
|
||||
font-family: var(--font-family-main);
|
||||
|
||||
border-right: 1px solid var(--color-border);
|
||||
border-left: 1px solid var(--color-border);
|
||||
border-right: 1px solid var(--color-border);
|
||||
border-left: 1px solid var(--color-border);
|
||||
|
||||
background-image: linear-gradient(to right, rgba(#42567A, 0.1) 1px, transparent 1px);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center top;
|
||||
background-size: 1px 100%;
|
||||
background-image: linear-gradient(to right, rgba(#42567A, 0.1) 1px, transparent 1px);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center top;
|
||||
background-size: 1px 100%;
|
||||
|
||||
overflow: hidden;
|
||||
overflow: hidden;
|
||||
|
||||
@container timeframe-slider (width <= 1024px) {
|
||||
padding-top: 100px;
|
||||
}
|
||||
@container timeframe-slider (width <= 1024px) {
|
||||
padding-top: 100px;
|
||||
}
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
padding: 60px 20px 20px;
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
padding: 60px 20px 20px;
|
||||
|
||||
background-image: unset;
|
||||
}
|
||||
background-image: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
top: 170px;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
top: 170px;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
|
||||
max-width: 15ch;
|
||||
padding-left: 75px;
|
||||
max-width: 15ch;
|
||||
padding-left: 75px;
|
||||
|
||||
font-weight: 700;
|
||||
font-size: 56px;
|
||||
line-height: 120%;
|
||||
font-weight: 700;
|
||||
font-size: 56px;
|
||||
line-height: 120%;
|
||||
|
||||
border-left: 5px solid transparent;
|
||||
border-image: var(--gradient-primary) 1;
|
||||
border-left: 5px solid transparent;
|
||||
border-image: var(--gradient-primary) 1;
|
||||
|
||||
|
||||
@container timeframe-slider (width <= 1024px) {
|
||||
top: 80px;
|
||||
@container timeframe-slider (width <= 1024px) {
|
||||
top: 80px;
|
||||
|
||||
font-size: 40px;
|
||||
}
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
padding-left: 20px;
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
padding-left: 20px;
|
||||
|
||||
font-size: 34px;
|
||||
}
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
position: relative;
|
||||
inset: unset;
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
position: relative;
|
||||
inset: unset;
|
||||
|
||||
margin-bottom: 20px;
|
||||
padding-left: 0;
|
||||
margin-bottom: 20px;
|
||||
padding-left: 0;
|
||||
|
||||
|
||||
border: none;
|
||||
}
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
position: relative;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
width: calc(100% + 40px);
|
||||
height: 600px;
|
||||
margin: 0 -20px;
|
||||
width: calc(100% + 40px);
|
||||
height: 600px;
|
||||
margin: 0 -20px;
|
||||
|
||||
background-image: linear-gradient(to bottom, rgba(#42567A, 0.1) 1px, transparent 1px);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 100% 1px;
|
||||
background-image: linear-gradient(to bottom, rgba(#42567A, 0.1) 1px, transparent 1px);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 100% 1px;
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
position: unset;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
|
||||
background-image: unset;
|
||||
}
|
||||
}
|
||||
|
||||
.controls {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
position: unset;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
transform-origin: left;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
|
||||
@container timeframe-slider (width <= 1024px) {
|
||||
left: 100px;
|
||||
bottom: 40px;
|
||||
}
|
||||
background-image: unset;
|
||||
}
|
||||
}
|
||||
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
left: 40px;
|
||||
.controls {
|
||||
position: absolute;
|
||||
left: 100px;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
|
||||
gap: 10px;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
left: 20px;
|
||||
bottom: 13px;
|
||||
transform-origin: left;
|
||||
|
||||
order: 2;
|
||||
@container timeframe-slider (width <= 1024px) {
|
||||
left: 100px;
|
||||
bottom: 40px;
|
||||
}
|
||||
|
||||
margin-top: 20px;
|
||||
padding: 0;
|
||||
}
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
left: 40px;
|
||||
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
left: 20px;
|
||||
bottom: 13px;
|
||||
|
||||
order: 2;
|
||||
|
||||
margin-top: 20px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination {
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
gap: 8px;
|
||||
}
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.chevronIcon {
|
||||
width: 9px;
|
||||
height: 14px;
|
||||
width: 9px;
|
||||
height: 14px;
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
width: 6px;
|
||||
height: 11.5px;
|
||||
}
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
width: 6px;
|
||||
height: 11.5px;
|
||||
}
|
||||
}
|
||||
|
||||
.dots {
|
||||
display: none;
|
||||
display: none;
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 32px;
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 32px;
|
||||
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
|
||||
.dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
padding: 0;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
padding: 0;
|
||||
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
|
||||
background-color: var(--color-primary);
|
||||
background-color: var(--color-primary);
|
||||
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
|
||||
opacity: 0.4;
|
||||
opacity: 0.4;
|
||||
|
||||
transition: opacity 0.3s ease;
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
&.activeDot {
|
||||
opacity: 1;
|
||||
}
|
||||
&.activeDot {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.rotated {
|
||||
transform: rotate(180deg);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.centerDate {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 0;
|
||||
|
||||
display: flex;
|
||||
gap: 60px;
|
||||
display: flex;
|
||||
gap: 60px;
|
||||
|
||||
color: var(--color-text);
|
||||
font-weight: 700;
|
||||
font-size: 200px;
|
||||
line-height: 160px;
|
||||
color: var(--color-text);
|
||||
font-weight: 700;
|
||||
font-size: 200px;
|
||||
line-height: 160px;
|
||||
|
||||
transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
pointer-events: none;
|
||||
pointer-events: none;
|
||||
|
||||
@container timeframe-slider (width <= 1024px) {
|
||||
gap: 40px;
|
||||
@container timeframe-slider (width <= 1024px) {
|
||||
gap: 40px;
|
||||
|
||||
font-size: 140px;
|
||||
line-height: 120px;
|
||||
}
|
||||
font-size: 140px;
|
||||
line-height: 120px;
|
||||
}
|
||||
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
font-size: 100px;
|
||||
line-height: 80px;
|
||||
}
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
font-size: 100px;
|
||||
line-height: 80px;
|
||||
}
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
position: static;
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
position: static;
|
||||
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
|
||||
margin-bottom: 40px;
|
||||
margin-bottom: 40px;
|
||||
|
||||
font-size: 56px;
|
||||
font-size: 56px;
|
||||
|
||||
transform: none;
|
||||
}
|
||||
transform: none;
|
||||
}
|
||||
|
||||
span:first-child {
|
||||
color: #5d5fef;
|
||||
}
|
||||
span:first-child {
|
||||
color: #5d5fef;
|
||||
}
|
||||
|
||||
span:last-child {
|
||||
color: #ef5da8;
|
||||
}
|
||||
span:last-child {
|
||||
color: #ef5da8;
|
||||
}
|
||||
}
|
||||
|
||||
.periodLabel {
|
||||
display: none;
|
||||
display: none;
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
order: 1;
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
order: 1;
|
||||
|
||||
display: block;
|
||||
display: block;
|
||||
|
||||
padding-bottom: 20px;
|
||||
padding-bottom: 20px;
|
||||
|
||||
color: var(--color-text);
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
color: var(--color-text);
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
|
||||
border-bottom: 1px solid #C7CDD9;
|
||||
}
|
||||
border-bottom: 1px solid #C7CDD9;
|
||||
}
|
||||
}
|
||||
|
||||
.circleContainer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
display: none;
|
||||
}
|
||||
@container timeframe-slider (width <= 576px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.carouselContainer {
|
||||
padding: 55px 80px 105px;
|
||||
padding: 55px 80px 105px;
|
||||
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
width: calc(100% + 40px);
|
||||
margin: 0 -20px;
|
||||
padding: 0;
|
||||
}
|
||||
@container timeframe-slider (width <= 768px) {
|
||||
width: calc(100% + 40px);
|
||||
margin: 0 -20px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
@@ -46,8 +46,12 @@ const {
|
||||
|
||||
module.exports = {
|
||||
extends: 'stylelint-config-standard-scss',
|
||||
plugins: ['stylelint-order'],
|
||||
plugins: [
|
||||
'stylelint-order',
|
||||
'@stylistic/stylelint-plugin',
|
||||
],
|
||||
rules: {
|
||||
'@stylistic/indentation': 2,
|
||||
'selector-class-pattern': null,
|
||||
'order/order': selectorOrdering,
|
||||
'order/properties-order': propertyOrdering,
|
||||
|
||||
Reference in New Issue
Block a user