# План реорганизации SCSS архитектуры **Дата:** 15 января 2026 **Статус:** 📋 План **Приоритет:** HIGH **Время выполнения:** 6-8 часов (с Bootstrap) / 40-60 часов (без Bootstrap) ## 🎯 Цель Преобразовать хаотичную структуру в чистую, поддерживаемую архитектуру с четкой категоризацией и переиспользуемыми компонентами. ### ⚠️ КРИТИЧЕСКОЕ РЕШЕНИЕ: Bootstrap или нет? **Пользователь запросил:** Полный отказ от Bootstrap в пользу собственных стилей. **Это означает:** - ❌ Удалить зависимость от Bootstrap (~301 KB CSS) - ✅ Написать свою систему: Grid, Buttons, Forms, Modals, Cards, Utilities - ⏱️ Увеличение времени реализации с 8 часов до **40-60 часов** - 🎨 Полный контроль над кодом и стилями - 📦 Уменьшение итогового размера бандла - 🔧 Необходимость поддержки своего UI Kit **См. раздел "БОНУСНЫЙ ЭТАП: Отказ от Bootstrap" в конце документа.** --- ## 📊 Целевая архитектура ### Feature-based структура (подходит под Django структуру): ``` scss/ ├── abstracts/ # ✅ Оставить как есть │ ├── _variables.scss # SCSS переменные │ ├── _css-variables.scss # CSS custom properties │ ├── _mixins.scss # Миксины │ └── _index.scss # Экспорт │ ├── core/ # ⭐ НОВАЯ ПАПКА - UI Kit │ ├── _buttons.scss # Кнопки │ ├── _forms.scss # Формы и инпуты │ ├── _badges.scss # Один badge компонент (объединить 2) │ ├── _cards.scss # Карточки │ ├── _lists.scss # ОДИН базовый список │ ├── _modals.scss # ОДИН modal (объединить 2) │ ├── _avatars.scss # Аватары │ ├── _search.scss # Поиск (вместо ios-search) │ └── _comments.scss # Комментарии │ ├── layout/ # Структура приложения │ ├── _grid.scss # App grid (из base-app.scss) │ ├── _header.scss # Navbar + page-header (объединить) │ ├── _sidebar.scss # ✅ Оставить │ └── _rightbar.scss # Rightbar + calendar (объединить) │ ├── features/ # ⭐ НОВАЯ ПАПКА - Feature-specific │ ├── feed/ │ │ ├── _layout.scss # Feed layout │ │ ├── _post-card.scss # Карточка поста │ │ └── _post-form.scss # ✅ Переместить │ ├── requests/ │ │ ├── _list.scss # Список заявок │ │ ├── _detail.scss # Детали заявки │ │ └── _picker.scss # Recipient picker │ ├── documents/ │ │ └── _list.scss # Список документов │ ├── employees/ │ │ ├── _controls.scss # Department controls │ │ └── _team-viz.scss # Team visualization (team-wheel) │ ├── notifications/ │ │ └── _center.scss # Notification center │ └── chat/ # ✅ Оставить подпапку │ └── ... # 10 файлов как есть │ └── utilities/ # Utility классы └── _spacing.scss # Объединить spacing-utils + layout-spacing ``` --- ## 📋 Этапы выполнения ### **Этап 0: Подготовка (30 мин)** #### 0.1 Создать backup ```bash cd backend/static cp -r scss scss_backup_$(date +%Y%m%d) git add -A git commit -m "backup: SCSS before reorganization" ``` #### 0.2 Создать новые папки ```bash cd scss mkdir -p core features utilities mkdir -p features/{feed,requests,documents,employees,notifications} ``` #### 0.3 Создать tracking файл ```bash # Создать файл для отслеживания прогресса touch REORGANIZATION_PROGRESS.md ``` --- ### **Этап 1: Аудит и группировка (1 час)** #### 1.1 Создать матрицу миграции Создать `MIGRATION_MATRIX.md`: ```markdown | Старый файл | Новое расположение | Статус | Требуется слияние | |-------------|-------------------|--------|-------------------| | _buttons.scss | core/_buttons.scss | ⏳ | Нет | | _badges-bem.scss | core/_badges.scss | ⏳ | Да (с telegram) | | _badges-telegram-style.scss | core/_badges.scss | ⏳ | Да (с bem) | | _ios-search.scss | core/_search.scss | ⏳ | Нет | | ... | ... | ... | ... | ``` #### 1.2 Проанализировать зависимости ```bash # Найти все импорты grep -r "@import" main.scss custom-bootstrap.scss # Найти использование классов в шаблонах grep -r "class=" templates/ | grep -E "(ios-|badge-|card-list)" ``` --- ### **Этап 2: Core UI Kit (2 часа)** #### 2.1 Простые перемещения (без изменений) ```bash # Buttons - просто переместить mv components/_buttons.scss core/_buttons.scss # Cards - переместить mv components/_cards.scss core/_cards.scss # Comments - переместить mv components/_comments.scss core/_comments.scss # Common - переместить mv components/_common.scss core/_common.scss ``` #### 2.2 Переименование файлов ```bash # iOS-search → search mv components/_ios-search.scss core/_search.scss # iOS-components разобрать на части или переименовать mv components/_ios-components.scss core/_ui-elements.scss ``` **Задача:** Открыть `_ios-components.scss`, посмотреть что там, возможно разбить на несколько файлов. #### 2.3 Объединение badges (ВАЖНО!) **Шаги:** 1. Открыть `_badges-bem.scss` и `_badges-telegram-style.scss` 2. Проанализировать что можно объединить 3. Создать единый `core/_badges.scss`: ```scss // core/_badges.scss // ===== BASE BADGE ===== .badge { // Общие стили } // ===== BEM VARIANT ===== .badge--bem { // BEM специфичные стили } // ===== TELEGRAM VARIANT ===== .badge--telegram { // Telegram специфичные стили } // ===== STATUS VARIANTS ===== .badge--success { } .badge--danger { } .badge--pending { } ``` 4. Удалить старые файлы 5. Обновить импорты #### 2.4 Объединение modals ```bash # Объединить modal-overrides в modals cat components/_modal-overrides.scss >> components/_modals.scss mv components/_modals.scss core/_modals.scss rm components/_modal-overrides.scss ``` **Почистить дубли** в объединенном файле! #### 2.5 Создать core/_lists.scss Проанализировать: - `_card-list.scss` - общие стили списков - `_list-view.scss` - view стили Объединить общее в `core/_lists.scss`: ```scss // core/_lists.scss // ===== BASE LIST ===== .list { // Базовые стили списка } // ===== LIST ITEM ===== .list__item { // Стили элемента списка } // ===== VARIANTS ===== .list--compact { } .list--cards { } ``` --- ### **Этап 3: Layout реорганизация (1.5 часа)** #### 3.1 Создать layout/_grid.scss ```bash # Переместить base-app mv layout/_base-app.scss layout/_grid.scss ``` Внутри файла переименовать классы: - `.app-layout` → `.app-grid` - Улучшить документацию #### 3.2 Объединить header компоненты **Анализ:** - `_navbar.scss` - навигация - `_page-header.scss` - заголовок страницы **Варианты:** **A) Объединить в один файл:** ```bash cat components/_navbar.scss components/_page-header.scss > layout/_header.scss ``` **B) Оставить раздельно но переименовать:** ```bash mv components/_navbar.scss layout/_navbar.scss mv components/_page-header.scss layout/_page-header.scss ``` **Рекомендация:** Вариант B (раздельно), но добавить комментарий что это части header'а. #### 3.3 Rightbar + Calendar ```bash # Переместить rightbar-calendar mv components/_rightbar-calendar.scss layout/_rightbar.scss ``` Внутри переименовать классы: - `.rightbar-card` → `.rightbar__card` - `.calendar-wrap` → `.rightbar__calendar` --- ### **Этап 4: Features организация (2 часа)** #### 4.1 Feed feature ```bash # Создать feed папку mkdir -p features/feed # Переместить компоненты mv components/_feed-specific.scss features/feed/_layout.scss mv components/_post-form.scss features/feed/_post-form.scss mv components/_join-scroller.scss features/feed/_members-scroller.scss # Если есть feed-header или подобное - тоже сюда ``` Создать `features/feed/_index.scss`: ```scss @forward 'layout'; @forward 'post-form'; @forward 'members-scroller'; ``` #### 4.2 Requests feature ```bash mkdir -p features/requests mv components/_request-list.scss features/requests/_list.scss mv components/_request-detail.scss features/requests/_detail.scss mv components/_recipientPicker.scss features/requests/_recipient-picker.scss ``` Создать `features/requests/_index.scss`: ```scss @forward 'list'; @forward 'detail'; @forward 'recipient-picker'; ``` #### 4.3 Documents feature ```bash mkdir -p features/documents mv components/_document-list.scss features/documents/_list.scss ``` Создать `features/documents/_index.scss`: ```scss @forward 'list'; ``` #### 4.4 Employees feature ```bash mkdir -p features/employees mv components/_department-controls.scss features/employees/_controls.scss mv components/_team-wheel.scss features/employees/_team-viz.scss ``` Переименовать внутри `_team-viz.scss`: - `.team-wheel` → `.team-viz` - Обновить комментарии Создать `features/employees/_index.scss`: ```scss @forward 'controls'; @forward 'team-viz'; ``` #### 4.5 Notifications feature ```bash mkdir -p features/notifications mv components/_notifications.scss features/notifications/_center.scss ``` Создать `features/notifications/_index.scss`: ```scss @forward 'center'; ``` #### 4.6 Chat feature (оставить как есть) ```bash # Chat уже в подпапке - оставить # features/chat/ уже существует как components/chat/ # Просто переместить папку целиком mv components/chat features/chat ``` #### 4.7 Logout modal (куда деть?) **Варианты:** 1. В `features/auth/_logout-modal.scss` 2. В `core/_modals.scss` (добавить специфичные стили) 3. Удалить если можно использовать общий modal **Рекомендация:** Вариант 2 - добавить `.modal--logout` в core модалы. ```bash # Слить с core/modals cat components/_logout-modal.scss >> core/_modals.scss rm components/_logout-modal.scss ``` --- ### **Этап 5: Utilities (30 мин)** #### 5.1 Объединить spacing ```bash # Объединить два spacing файла cat components/_layout-spacing.scss components/_spacing-utils.scss > utilities/_spacing.scss # Почистить дубли в объединенном файле # Удалить старые rm components/_layout-spacing.scss rm components/_spacing-utils.scss ``` #### 5.2 Проверить пустую utilities папку ```bash # Удалить старую пустую папку если осталась rmdir utilities/ 2>/dev/null || true ``` --- ### **Этап 6: Обновление импортов (1.5 часа)** #### 6.1 Создать новый main.scss Создать `main.scss.new`: ```scss // ============================================================================= // Main Application SCSS // ============================================================================= // Главный файл для сборки всех стилей приложения (кроме Bootstrap) // Компилируется в css/app.css // ============================================================================= // 1. ABSTRACTS - Переменные, миксины, функции // ============================================================================= @import 'abstracts/index'; // ============================================================================= // 2. CORE - UI Kit компоненты // ============================================================================= @import 'core/buttons'; @import 'core/forms'; @import 'core/badges'; @import 'core/cards'; @import 'core/lists'; @import 'core/modals'; @import 'core/avatars'; @import 'core/search'; @import 'core/comments'; @import 'core/common'; // ============================================================================= // 3. LAYOUT - Структура приложения // ============================================================================= @import 'layout/grid'; @import 'layout/navbar'; @import 'layout/page-header'; @import 'layout/sidebar'; @import 'layout/rightbar'; // ============================================================================= // 4. UTILITIES - Вспомогательные классы // ============================================================================= @import 'utilities/spacing'; // ============================================================================= // 5. FEATURES - Feature-specific стили // ============================================================================= // Feed @import 'features/feed/layout'; @import 'features/feed/post-form'; @import 'features/feed/members-scroller'; // Requests @import 'features/requests/list'; @import 'features/requests/detail'; @import 'features/requests/recipient-picker'; // Documents @import 'features/documents/list'; // Employees @import 'features/employees/controls'; @import 'features/employees/team-viz'; // Notifications @import 'features/notifications/center'; // Chat @import 'features/chat/message-inputs'; @import 'features/chat/chat-detail'; @import 'features/chat/chat-date-groups'; @import 'features/chat/chat-list-enhanced'; @import 'features/chat/chat-enhanced'; @import 'features/chat/chat-polls'; @import 'features/chat/chat-new-messages-indicator'; @import 'features/chat/message-selection'; @import 'features/chat/message-context-menu'; @import 'features/chat/message-reactions'; // ============================================================================= // ПРИМЕЧАНИЯ // ============================================================================= // - Bootstrap подключается отдельно через bootstrap-custom.css // - CSS переменные (--variable) определены в abstracts/_css-variables.scss // - SCSS переменные ($variable) определены в abstracts/_variables.scss // - Порядок импортов критичен для CSS каскада // - Core компоненты = переиспользуемые UI элементы // - Features = специфичные для конкретных функций приложения ``` #### 6.2 Очистить custom-bootstrap.scss Создать `custom-bootstrap.scss.new`: ```scss // ============================================================================= // Custom Bootstrap Configuration // ============================================================================= // Этот файл переопределяет переменные Bootstrap ДО его компиляции // ============================================================================= // 1. ПЕРЕОПРЕДЕЛЕНИЕ BOOTSTRAP ПЕРЕМЕННЫХ // ============================================================================= // Система отступов (8px grid) $spacer: 1rem !default; $spacers: ( 0: 0, 1: 0.25rem, // 4px 2: 0.5rem, // 8px 3: 0.75rem, // 12px 4: 1rem, // 16px 5: 1.5rem, // 24px ) !default; // Grid $grid-gutter-width: 0.5rem !default; // Cards $card-spacer-y: 1rem !default; $card-spacer-x: 1rem !default; $card-border-radius: 14px !default; // Buttons $btn-padding-y: 0.5rem !default; $btn-padding-x: 1rem !default; // Inputs $input-padding-y: 0.5rem !default; $input-padding-x: 1rem !default; // ============================================================================= // 2. ИМПОРТ ABSTRACTS // ============================================================================= @import "abstracts/variables"; @import "abstracts/mixins"; // ============================================================================= // 3. ИМПОРТ BOOTSTRAP // ============================================================================= @import "../node_modules/bootstrap/scss/bootstrap"; // ============================================================================= // 4. CSS ПЕРЕМЕННЫЕ (RUNTIME) // ============================================================================= @import "abstracts/css-variables"; // ============================================================================= // ВСЕ! Никаких компонентов здесь! // Все компоненты в main.scss → app.css // ============================================================================= ``` #### 6.3 Тестовая компиляция ```bash cd backend/static # Backup старых файлов mv scss/main.scss scss/main.scss.old mv scss/custom-bootstrap.scss scss/custom-bootstrap.scss.old # Применить новые mv scss/main.scss.new scss/main.scss mv scss/custom-bootstrap.scss.new scss/custom-bootstrap.scss # Попробовать собрать npm run build:app 2>&1 | tee build_errors.log # Если ошибки - смотреть build_errors.log ``` #### 6.4 Исправление ошибок импортов ```bash # Найти все missing imports grep -i "can't find" build_errors.log # Найти старые пути в файлах grep -r "@import.*components/" scss/ # Исправить пути ``` --- ### **Этап 7: Cleanup (30 мин)** #### 7.1 Удалить старую components папку ```bash # Проверить что components пуста ls -la scss/components/ # Если пусто - удалить rm -rf scss/components/ # Оставить только .gitkeep или удалить совсем ``` #### 7.2 Удалить BUTTONS_README.md из старого места ```bash # Переместить в новое место mv scss/components/BUTTONS_README.md docs/guides/BUTTONS_COMPONENT.md # Или в core папку mv scss/components/BUTTONS_README.md scss/core/README_BUTTONS.md ``` #### 7.3 Проверить дубликаты ```bash # Найти дублирующиеся селекторы grep -r "^\.badge" scss/ | sort | uniq -d # Найти дублирующиеся @import grep -r "@import" scss/main.scss scss/custom-bootstrap.scss | sort | uniq -d ``` --- ### **Этап 8: Тестирование (1 час)** #### 8.1 Сборка финальных CSS ```bash # Собрать все npm run build:app npm run build:bootstrap # Проверить размеры ls -lh css/app.css css/bootstrap-custom.css # Сравнить с backup ls -lh css_backup/app.css css_backup/bootstrap-custom.css ``` #### 8.2 Визуальное тестирование **Проверить страницы:** 1. Главная / feed 2. Список заявок 3. Детали заявки 4. Список документов 5. Список сотрудников 6. Уведомления 7. Чат 8. Logout modal 9. Search 10. Forms **Чек-лист для каждой страницы:** - [ ] Стили загружаются - [ ] Нет визуальных багов - [ ] Кнопки работают - [ ] Формы выглядят нормально - [ ] Responsive работает #### 8.3 Проверка консоли браузера ```javascript // В DevTools Console // Проверить нет ли 404 на CSS // Проверить размер загруженных CSS performance.getEntriesByType('resource') .filter(r => r.name.includes('.css')) ``` --- ### **Этап 9: Документация (30 мин)** #### 9.1 Создать scss/README.md ```markdown # SCSS Architecture ## Structure ### Core (UI Kit) Переиспользуемые UI компоненты: buttons, cards, badges, modals, etc. ### Layout Структура приложения: grid, header, sidebar, rightbar. ### Features Feature-specific стили, организованные по функциям приложения. ### Utilities Utility классы: spacing, helpers, etc. ## Build `npm run build:app` - компилирует main.scss → app.css `npm run build:bootstrap` - компилирует bootstrap-custom.scss → bootstrap-custom.css ## Adding New Components 1. Core component → `core/_component.scss` 2. Feature component → `features/feature/_component.scss` 3. Add import to `main.scss` 4. Run `npm run build:app` ``` #### 9.2 Обновить docs/guides/SCSS_QUICK_REFERENCE.md Обновить пути и структуру в quick reference. #### 9.3 Создать отчет о реорганизации `docs/reports/SCSS_REORGANIZATION_COMPLETE.md` с: - Что было изменено - Новая структура - Метрики (файлы, размеры, время) --- ### **Этап 10: Git commit (15 мин)** ```bash # Добавить все изменения git add -A # Коммит git commit -m "refactor: Complete SCSS architecture reorganization - Restructured 51 SCSS files into logical categories - Created core/ (UI Kit), layout/, features/, utilities/ folders - Merged duplicate components: badges (2→1), modals (2→1), spacing (2→1) - Renamed files: ios-search→search, team-wheel→team-viz, etc. - Cleaned custom-bootstrap.scss from component imports - Moved chat components from bootstrap to main.scss - Updated all imports in main.scss and custom-bootstrap.scss Structure: - core/ (9 files) - Reusable UI components - layout/ (5 files) - App structure - features/ (16 files in 6 folders) - Feature-specific styles - utilities/ (1 file) - Utility classes Benefits: - Clear categorization - No duplicate imports - Logical feature grouping - Easier maintenance - Clean architecture Breaking changes: None (CSS class names unchanged) " # Push git push ``` --- ## 📊 Метрики успеха ### До реорганизации: ``` components/ - 30 файлов (хаос) layout/ - 2 файла utilities/ - пуста Дублирующиеся импорты: 8 компонентов Странные названия: ios-, telegram-, -specific, team-wheel ``` ### После реорганизации: ``` core/ - 9-10 файлов (UI Kit) layout/ - 4-5 файлов (структура) features/ - 16 файлов в 6 папках (по функциям) utilities/ - 1 файл (spacing) Дублирующиеся импорты: 0 Понятные названия: search, badges, team-viz ``` ### Улучшения: - ✅ Четкая категоризация - ✅ Нет дубликатов - ✅ Логичная группировка - ✅ Легче найти нужный файл - ✅ Понятные названия - ✅ Масштабируемая структура --- ## ⚠️ Риски и как их минимизировать ### Риск 1: Сломать стили **Минимизация:** - Делать backup перед каждым этапом - Тестировать после каждого этапа - Не менять CSS классы, только структуру файлов - Использовать git для отката ### Риск 2: Забыть обновить импорт **Минимизация:** - Вести матрицу миграции - Проверять build errors - Grep поиск старых путей - Тестовая компиляция после каждого шага ### Риск 3: Потерять изменения **Минимизация:** - Git commit после каждого этапа - Backup папка - Документировать прогресс ### Риск 4: Слишком долго **Минимизация:** - Разбить на этапы - Можно делать частями (по 2-3 этапа в день) - Приоритет: сначала core, потом features --- ## 🎯 Альтернативный подход (если мало времени) ### Минимальный рефакторинг (2 часа): 1. **Убрать дубликаты из custom-bootstrap** (30 мин) 2. **Переместить chat в main.scss** (15 мин) 3. **Объединить badges** (20 мин) 4. **Объединить modals** (15 мин) 5. **Объединить spacing** (20 мин) 6. **Переименовать ios-* файлы** (20 мин) Остальное оставить как есть. Будет лучше но не идеально. --- ## 📚 Дополнительные ресурсы - [Sass Guidelines](https://sass-guidelin.es/) - best practices - [7-1 Pattern](https://sass-guidelin.es/#the-7-1-pattern) - архитектура - [ITCSS](https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/) - методология - [Atomic Design](https://atomicdesign.bradfrost.com/) - для вдохновения --- --- ## 🚨 БОНУСНЫЙ ЭТАП: Полный отказ от Bootstrap **⚠️ ВНИМАНИЕ:** Этот этап увеличивает время реализации в 5-7 раз! ### Зачем отказываться от Bootstrap? **Плюсы:** - ✅ Полный контроль над кодом - ✅ Уменьшение размера бандла (~300 KB → ~100 KB) - ✅ Нет неиспользуемого кода - ✅ Точная семантика под наше приложение - ✅ Легче кастомизация - ✅ Современный CSS (Grid, Custom Properties, Container Queries) **Минусы:** - ❌ Нужно написать свой UI Kit с нуля - ❌ Время: 40-60 часов вместо 8 часов - ❌ Нужно поддерживать свой код - ❌ Протестировать все компоненты - ❌ Обеспечить кроссбраузерность - ❌ Документировать систему ### Что нужно переписать? **Bootstrap предоставляет (~180 компонентов):** 1. **Grid System** - 12-колоночная сетка 2. **Typography** - заголовки, параграфы, списки 3. **Buttons** - 9 вариантов кнопок + sizes + states 4. **Forms** - inputs, selects, checkboxes, radio, validation 5. **Cards** - карточки с header/body/footer 6. **Modals** - модальные окна с backdrop 7. **Alerts** - уведомления 8. **Badges** - бейджи 9. **Breadcrumbs** - хлебные крошки 10. **Dropdowns** - выпадающие меню 11. **Navbar** - навигация 12. **Pagination** - пагинация 13. **Progress** - прогресс-бары 14. **Spinners** - загрузчики 15. **Tooltips** - подсказки 16. **Popovers** - всплывающие окна 17. **Utilities** - margin, padding, flex, display, colors... **Используется в проекте (по grep):** ```bash # Найти что реально используется grep -r "class=" templates/ | grep -oE '\.(btn|card|modal|form-|input-|alert|badge|nav|dropdown|pagination|container|row|col-|d-|m-|p-|text-|bg-|border-)' | sort | uniq -c ``` ### Этап 0: Аудит использования Bootstrap (4 часа) #### 0.1 Собрать статистику использования ```bash cd backend # Создать скрипт для анализа cat > analyze_bootstrap_usage.py << 'EOF' import re from pathlib import Path from collections import Counter # Bootstrap классы BS_PATTERNS = [ r'\bbtn-\w+', r'\bcard-\w+', r'\bmodal-\w+', r'\bform-\w+', r'\balert-\w+', r'\bbadge-\w+', r'\bnav-\w+', r'\bcol-\w+', r'\brow\b', r'\bcontainer\b', r'\bd-\w+', r'\bm[tblrxy]?-\d', r'\bp[tblrxy]?-\d', r'\btext-\w+', r'\bbg-\w+', r'\bborder-\w+' ] templates_dir = Path('templates') all_classes = Counter() for html_file in templates_dir.rglob('*.html'): content = html_file.read_text(encoding='utf-8') for pattern in BS_PATTERNS: matches = re.findall(pattern, content) all_classes.update(matches) print("=== TOP 50 BOOTSTRAP CLASSES ===") for cls, count in all_classes.most_common(50): print(f"{cls:30} - {count:4} uses") print(f"\n=== TOTAL: {len(all_classes)} unique Bootstrap classes ===") EOF .venv/Scripts/python analyze_bootstrap_usage.py > bootstrap_usage_report.txt ``` #### 0.2 Создать матрицу замены `BOOTSTRAP_REPLACEMENT_MATRIX.md`: ```markdown | Bootstrap класс | Использований | Наш класс | Статус | |-----------------|---------------|-----------|--------| | .btn-primary | 150 | .button--primary | ⏳ | | .card | 120 | .card | ⏳ | | .modal | 45 | .modal | ⏳ | | .form-control | 200 | .input | ⏳ | | .container | 80 | .container | ⏳ | | .row | 100 | .grid | ⏳ | | .col-* | 300 | .grid__col | ⏳ | ``` #### 0.3 Оценить объем работы ```bash # Посчитать templates с Bootstrap find templates/ -name "*.html" -exec grep -l "btn\|card\|modal\|form-control" {} \; | wc -l # Посчитать строк кода find templates/ -name "*.html" | xargs wc -l ``` ### Этап B1: Создать свою Grid систему (6 часов) #### B1.1 Создать core/_grid.scss ```scss // core/_grid.scss // ============================================================================= // GRID SYSTEM // ============================================================================= // Своя grid система на CSS Grid (не flexbox как Bootstrap) // Переменные $grid-columns: 12; $grid-gap: 1rem; $grid-container-max: 1200px; // Container .container { width: 100%; max-width: $grid-container-max; margin: 0 auto; padding: 0 1rem; } .container--fluid { max-width: 100%; } // Grid .grid { display: grid; grid-template-columns: repeat($grid-columns, 1fr); gap: $grid-gap; // Responsive gaps &--gap-sm { gap: 0.5rem; } &--gap-lg { gap: 2rem; } } // Grid columns @for $i from 1 through $grid-columns { .grid__col-#{$i} { grid-column: span $i; } } // Responsive @media (max-width: 768px) { .grid__col-12-mobile { grid-column: span 12; } } // Auto-fit grid .grid--auto { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); } ``` #### B1.2 Создать миграционный скрипт ```python # scripts/replace_bootstrap_grid.py import re from pathlib import Path def replace_bootstrap_grid(content): # .row → .grid content = re.sub(r'\brow\b', 'grid', content) # .col-{n} → .grid__col-{n} content = re.sub(r'\bcol-(\d+)', r'grid__col-\1', content) # .container → .container (оставить) return content templates_dir = Path('templates') for html_file in templates_dir.rglob('*.html'): content = html_file.read_text(encoding='utf-8') new_content = replace_bootstrap_grid(content) if content != new_content: html_file.write_text(new_content, encoding='utf-8') print(f"Updated: {html_file}") ``` ### Этап B2: Создать свою Button систему (4 часа) ```scss // core/_buttons.scss .button { // Base styles display: inline-flex; align-items: center; justify-content: center; padding: 0.5rem 1rem; border: none; border-radius: 0.375rem; font-size: 1rem; font-weight: 500; line-height: 1.5; cursor: pointer; transition: all 0.2s; &:hover { opacity: 0.85; } &:active { transform: scale(0.98); } &:disabled { opacity: 0.5; cursor: not-allowed; } // Variants &--primary { background: var(--color-primary); color: white; } &--secondary { background: var(--color-secondary); color: white; } &--success { background: var(--color-success); color: white; } &--danger { background: var(--color-danger); color: white; } &--outline { background: transparent; border: 1px solid currentColor; } // Sizes &--sm { padding: 0.25rem 0.5rem; font-size: 0.875rem; } &--lg { padding: 0.75rem 1.5rem; font-size: 1.125rem; } // Full width &--block { width: 100%; } } // Миграция: .btn-primary → .button.button--primary ``` ### Этап B3: Создать Form систему (8 часов) ```scss // core/_forms.scss .form-group { margin-bottom: 1rem; } .label { display: block; margin-bottom: 0.25rem; font-weight: 500; font-size: 0.875rem; } .input, .textarea, .select { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid var(--color-border); border-radius: 0.375rem; font-size: 1rem; transition: border-color 0.2s; &:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(var(--color-primary-rgb), 0.1); } &--error { border-color: var(--color-danger); } &:disabled { background: var(--color-gray-100); cursor: not-allowed; } } .textarea { resize: vertical; min-height: 100px; } .checkbox, .radio { // Кастомные checkbox/radio appearance: none; width: 1.25rem; height: 1.25rem; border: 2px solid var(--color-border); border-radius: 0.25rem; cursor: pointer; &:checked { background: var(--color-primary); border-color: var(--color-primary); } } .radio { border-radius: 50%; } ``` ### Этап B4: Utilities система (4 часа) ```scss // utilities/_spacing.scss // Margin и Padding генератор $spacers: ( 0: 0, 1: 0.25rem, 2: 0.5rem, 3: 0.75rem, 4: 1rem, 5: 1.5rem, 6: 2rem, ); @each $key, $value in $spacers { // Margin .m-#{$key} { margin: $value; } .mt-#{$key} { margin-top: $value; } .mb-#{$key} { margin-bottom: $value; } .ml-#{$key} { margin-left: $value; } .mr-#{$key} { margin-right: $value; } .mx-#{$key} { margin-left: $value; margin-right: $value; } .my-#{$key} { margin-top: $value; margin-bottom: $value; } // Padding .p-#{$key} { padding: $value; } .pt-#{$key} { padding-top: $value; } .pb-#{$key} { padding-bottom: $value; } .pl-#{$key} { padding-left: $value; } .pr-#{$key} { padding-right: $value; } .px-#{$key} { padding-left: $value; padding-right: $value; } .py-#{$key} { padding-top: $value; padding-bottom: $value; } } // Display utilities .d-none { display: none; } .d-block { display: block; } .d-flex { display: flex; } .d-grid { display: grid; } .d-inline { display: inline; } .d-inline-block { display: inline-block; } // Flexbox utilities .flex-row { flex-direction: row; } .flex-column { flex-direction: column; } .justify-center { justify-content: center; } .justify-between { justify-content: space-between; } .justify-end { justify-content: flex-end; } .align-center { align-items: center; } .align-start { align-items: flex-start; } .gap-1 { gap: 0.25rem; } .gap-2 { gap: 0.5rem; } .gap-3 { gap: 1rem; } // Text utilities .text-left { text-align: left; } .text-center { text-align: center; } .text-right { text-align: right; } .text-bold { font-weight: bold; } .text-sm { font-size: 0.875rem; } .text-lg { font-size: 1.125rem; } ``` ### Этап B5: Cards, Modals, Alerts (6 часов) Написать свои версии этих компонентов. ### Этап B6: Массовая замена в templates (12 часов) ```python # scripts/migrate_all_bootstrap_classes.py REPLACEMENTS = { # Buttons r'\bbtn\b': 'button', r'\bbtn-primary\b': 'button--primary', r'\bbtn-secondary\b': 'button--secondary', r'\bbtn-sm\b': 'button--sm', r'\bbtn-lg\b': 'button--lg', # Forms r'\bform-control\b': 'input', r'\bform-group\b': 'form-group', r'\bform-label\b': 'label', # Grid r'\brow\b': 'grid', r'\bcol-(\d+)': r'grid__col-\1', # Cards r'\bcard\b': 'card', r'\bcard-body\b': 'card__body', r'\bcard-header\b': 'card__header', # Utilities r'\bd-flex\b': 'd-flex', r'\bjustify-content-center\b': 'justify-center', # ... еще сотни замен } def migrate_template(filepath): content = filepath.read_text(encoding='utf-8') for old, new in REPLACEMENTS.items(): content = re.sub(old, new, content) filepath.write_text(content, encoding='utf-8') # Запустить на всех templates for html_file in Path('templates').rglob('*.html'): migrate_template(html_file) ``` ### Этап B7: Удаление Bootstrap (1 час) ```bash # Удалить из package.json npm uninstall bootstrap # Удалить custom-bootstrap.scss rm scss/custom-bootstrap.scss # Удалить из templates grep -r "bootstrap-custom.css" templates/ # Заменить на только app.css # Обновить build скрипты # Оставить только npm run build:app ``` ### Этап B8: Тестирование (8 часов) Протестировать каждую страницу: - Визуальная регрессия - Responsive - Кроссбраузерность - Формы работают - Модалы открываются - И т.д. --- ## 📊 Сравнение подходов ### Вариант А: С Bootstrap (рекомендуется сейчас) **Плюсы:** - ⏱️ Быстро: 6-8 часов - ✅ Проверенное решение - ✅ Хорошая документация - ✅ Обновления безопасности - ✅ Кроссбраузерность из коробки **Минусы:** - 📦 Размер бандла: ~300 KB - 🔧 Ограничения кастомизации - 📚 Неиспользуемый код **Итоговый размер:** - bootstrap-custom.css: ~280 KB - app.css: ~95 KB - **ИТОГО: ~375 KB** ### Вариант Б: Без Bootstrap (требует времени) **Плюсы:** - 📦 Размер бандла: ~100 KB (в 3 раза меньше!) - 🎨 Полный контроль - 🚀 Только нужный код - 💅 Современный CSS **Минусы:** - ⏱️ Долго: 40-60 часов - 🔧 Нужна поддержка - 🐛 Больше багов - 📚 Нужна документация **Итоговый размер:** - app.css: ~100 KB - **ИТОГО: ~100 KB** --- ## 🎯 Рекомендуемая стратегия ### Поэтапный отказ от Bootstrap: 1. **Этап 1-10 (6-8 часов):** Реорганизация SCSS с Bootstrap 2. **Использовать проект 2-3 месяца** 3. **Этап B (40-60 часов):** Постепенная замена Bootstrap своими стилями - Сначала Grid → готово за выходные - Потом Buttons → неделя - Потом Forms → неделя - Постепенно все остальное 4. **Тестирование на продакшене** 5. **Удаление Bootstrap когда все заменено** **Преимущества поэтапного подхода:** - ✅ Не ломаем текущий проект - ✅ Можно тестировать части - ✅ Откатиться легко - ✅ Меньше риска --- ## 🤔 Мое мнение **Для корпоративного Django приложения:** 👍 **ЗА отказ от Bootstrap:** - Полный контроль над кодом - Меньше размер - Современные CSS возможности - Нет jQuery зависимостей (если используете Bootstrap JS) 👎 **ПРОТИВ отказа от Bootstrap:** - Огромная работа (40-60 часов) - Нужно поддерживать свой код - Риск багов - Уже работает хорошо **Мой совет:** 1. Сейчас сделать реорганизацию С Bootstrap (8 часов) 2. Использовать 1-2 месяца 3. Если реально чувствуете ограничения - начать постепенно заменять 4. Если все работает нормально - оставить Bootstrap **Большинство крупных проектов используют Bootstrap/Tailwind/Foundation** - это нормально и правильно. --- **Готов начать? Какой вариант выбираем?** **A)** Реорганизация с Bootstrap (8 часов, безопасно) **Б)** Полный отказ от Bootstrap (60 часов, амбициозно) **В)** Поэтапная замена (8 часов сейчас + 40 часов потом)