commit 5f18505943b84827deade696b587f575340c1cc9 Author: root Date: Fri Jul 24 20:20:51 2026 +0200 sync: full site from notebook (source of truth) + missing media diff --git a/.cursor/commands/apply-edits.md b/.cursor/commands/apply-edits.md new file mode 100644 index 0000000..67f071e --- /dev/null +++ b/.cursor/commands/apply-edits.md @@ -0,0 +1,27 @@ +# Apply content edits + +Примени правки из режима content-edit на localhost. + +## Обязательно + +1. Прочитай и выполни **`.cursor/rules/content-edit-apply.mdc`**. +2. Прочитай **`texts/content-edits/pending.json`**. +3. Если `items` пуст — кратко сообщи, что очередь пуста, и остановись. +4. Иначе для каждого пункта с непустым `instruction` (по возрастанию `n`): + - правь только **`src/pages/…`** (не `public/`); + - основной блок: `target.selector` → `target.content` / `snippet` → `anchorId`; + - дополнительные блоки из `refs[]` — тот же порядок; метки `«…»` в instruction ↔ `refs[].label`; + - выполни `instruction`. +5. Русский текст после правок — скилл **`humanizer-ru`**. +6. Запусти **`npm run build:pages`**. +7. **`pending.json` не очищать** — очередь остаётся для проверки; пользователь сам удаляет пункты в dock или правит instruction и снова вызывает apply. По желанию обнови только `lastAppliedAt` (ISO). + +## Не делать + +- Не очищать `items` в `pending.json` после apply. +- Не править `public/cases/*.html` вручную (только через сборку). +- Не путать с режимом «правь в public» — см. `case-content-edit-in-public.mdc`. + +Если в сообщении указана страница (slug или путь) — примени только её `item.page`. + +В ответе пользователю — одна короткая строка или «готово», без списка правок, если он не просил отчёт. diff --git a/.deploy-manifest.json b/.deploy-manifest.json new file mode 100644 index 0000000..8502c33 --- /dev/null +++ b/.deploy-manifest.json @@ -0,0 +1,1586 @@ +{ + "assets/ai-platform-primo-rpa/.gitkeep": { + "mtime": 1777548036560.4653, + "size": 2 + }, + "assets/ai-platform-primo-rpa/cover.png": { + "mtime": 1779377996031.643, + "size": 159015 + }, + "assets/ai-platform-primo-rpa/cover.webp": { + "mtime": 1779377996032.6443, + "size": 30364 + }, + "assets/ai-platform-primo-rpa/dataset-editor-old.png": { + "mtime": 1777636422809.364, + "size": 888287 + }, + "assets/ai-platform-primo-rpa/dataset-editor-old.webp": { + "mtime": 1779295491001, + "size": 280160 + }, + "assets/ai-platform-primo-rpa/dataset-editor-small-screen.png": { + "mtime": 1779377996036.6465, + "size": 404244 + }, + "assets/ai-platform-primo-rpa/dataset-editor-small-screen.webp": { + "mtime": 1779377996037.6458, + "size": 88614 + }, + "assets/ai-platform-primo-rpa/dataset-editor.png": { + "mtime": 1779377996046.131, + "size": 819234 + }, + "assets/ai-platform-primo-rpa/dataset-editor.webp": { + "mtime": 1779377996048.131, + "size": 153230 + }, + "assets/ai-platform-primo-rpa/dataset-lerning.png": { + "mtime": 1778061201695.4707, + "size": 178506 + }, + "assets/ai-platform-primo-rpa/dataset-lerning.webp": { + "mtime": 1779295491358, + "size": 76082 + }, + "assets/ai-platform-primo-rpa/dataset-quality.png": { + "mtime": 1778061201699.9893, + "size": 256076 + }, + "assets/ai-platform-primo-rpa/dataset-quality.webp": { + "mtime": 1779295491507, + "size": 101230 + }, + "assets/ai-platform-primo-rpa/dataset_editor-main_toolbar.png": { + "mtime": 1779377996049.637, + "size": 15031 + }, + "assets/ai-platform-primo-rpa/dataset_editor-main_toolbar.webp": { + "mtime": 1779377996050.6484, + "size": 6034 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-default_mode.png": { + "mtime": 1779377996050.6484, + "size": 47547 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-default_mode.webp": { + "mtime": 1779377996051.6475, + "size": 38664 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode-both_panels.png": { + "mtime": 1779377996053.8552, + "size": 56585 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode-both_panels.webp": { + "mtime": 1779377996054.8564, + "size": 44568 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode-left_panel.png": { + "mtime": 1779377996056.8555, + "size": 59824 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode-left_panel.webp": { + "mtime": 1779377996057.8606, + "size": 55050 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode-right_panel.png": { + "mtime": 1779377996058.8574, + "size": 60884 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode-right_panel.webp": { + "mtime": 1779377996059.86, + "size": 55078 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode.png": { + "mtime": 1779377996060.891, + "size": 64220 + }, + "assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode.webp": { + "mtime": 1779377996062.934, + "size": 63640 + }, + "assets/ai-platform-primo-rpa/fields-maping.mp4": { + "mtime": 1778061201754.2502, + "size": 12663587 + }, + "assets/ai-platform-primo-rpa/fields-maping.webm": { + "mtime": 1778061201761.628, + "size": 811806 + }, + "assets/ai-platform-primo-rpa/fields-maping.webp": { + "mtime": 1778061201763.6267, + "size": 86646 + }, + "assets/ai-platform-primo-rpa/full-screen-mode-with-panels.png": { + "mtime": 1778061201769.9807, + "size": 555909 + }, + "assets/ai-platform-primo-rpa/full-screen-mode-with-panels.webp": { + "mtime": 1779295492433, + "size": 110334 + }, + "assets/ai-platform-primo-rpa/full-screen-mode-zen.png": { + "mtime": 1778061201774.9817, + "size": 502027 + }, + "assets/ai-platform-primo-rpa/full-screen-mode-zen.webp": { + "mtime": 1779295492517, + "size": 94372 + }, + "assets/ai-platform-primo-rpa/fullscreen_modal-import_dataset.png": { + "mtime": 1779377996064.941, + "size": 72399 + }, + "assets/ai-platform-primo-rpa/fullscreen_modal-import_dataset.webp": { + "mtime": 1779377996066.941, + "size": 26252 + }, + "assets/ai-platform-primo-rpa/fullscreen_modal-in_project-import_dataset.png": { + "mtime": 1779377996069.4497, + "size": 130169 + }, + "assets/ai-platform-primo-rpa/fullscreen_modal-in_project-import_dataset.webp": { + "mtime": 1779377996071.4585, + "size": 30506 + }, + "assets/ai-platform-primo-rpa/in_project-learn-card-learning_process.png": { + "mtime": 1779377996073.4573, + "size": 113156 + }, + "assets/ai-platform-primo-rpa/in_project-learn-card-learning_process.webp": { + "mtime": 1779377996075.4573, + "size": 67896 + }, + "assets/ai-platform-primo-rpa/in_project-learn-card-learning_process_wireframe.png": { + "mtime": 1779377996076.4575, + "size": 8462 + }, + "assets/ai-platform-primo-rpa/in_project-learn-card-learning_process_wireframe.webp": { + "mtime": 1779377996077.4592, + "size": 4008 + }, + "assets/ai-platform-primo-rpa/in_project-learn-card-new.png": { + "mtime": 1779377996079.963, + "size": 109260 + }, + "assets/ai-platform-primo-rpa/in_project-learn-card-new.webp": { + "mtime": 1779377996081.969, + "size": 77098 + }, + "assets/ai-platform-primo-rpa/in_project-learn-card-сollapsed.png": { + "mtime": 1779377996082.9697, + "size": 6342 + }, + "assets/ai-platform-primo-rpa/in_project-learn-card-сollapsed.webp": { + "mtime": 1779377996085.1777, + "size": 4868 + }, + "assets/ai-platform-primo-rpa/in_project-learn-overview.png": { + "mtime": 1779377996088.1775, + "size": 147934 + }, + "assets/ai-platform-primo-rpa/in_project-learn-overview.webp": { + "mtime": 1779377996089.6838, + "size": 28904 + }, + "assets/ai-platform-primo-rpa/main-new.png": { + "mtime": 1779377996092.691, + "size": 191708 + }, + "assets/ai-platform-primo-rpa/main-new.webp": { + "mtime": 1779377996093.6912, + "size": 56804 + }, + "assets/ai-platform-primo-rpa/main.png": { + "mtime": 1779377996099.692, + "size": 430951 + }, + "assets/ai-platform-primo-rpa/main.webp": { + "mtime": 1779377996101.8147, + "size": 108008 + }, + "assets/ai-platform-primo-rpa/nav-project-nlp.png": { + "mtime": 1779377996103.8135, + "size": 109931 + }, + "assets/ai-platform-primo-rpa/nav-project-nlp.webp": { + "mtime": 1779377996104.8171, + "size": 18854 + }, + "assets/ai-platform-primo-rpa/nav-project-ocr.png": { + "mtime": 1779377996106.8132, + "size": 116365 + }, + "assets/ai-platform-primo-rpa/nav-project-ocr.webp": { + "mtime": 1779377996107.8135, + "size": 24166 + }, + "assets/ai-platform-primo-rpa/nav-secondary-detail_view.png": { + "mtime": 1779377996108.8142, + "size": 17770 + }, + "assets/ai-platform-primo-rpa/nav-secondary-detail_view.webp": { + "mtime": 1779377996108.8142, + "size": 5266 + }, + "assets/favicon/android-chrome-192x192.png": { + "mtime": 1780513420000, + "size": 45462 + }, + "assets/favicon/android-chrome-512x512.png": { + "mtime": 1780513420000, + "size": 259917 + }, + "assets/favicon/apple-touch-icon.png": { + "mtime": 1780513420000, + "size": 41086 + }, + "assets/favicon/favicon-16x16.png": { + "mtime": 1780513420000, + "size": 776 + }, + "assets/favicon/favicon-32x32.png": { + "mtime": 1780513420000, + "size": 2166 + }, + "assets/favicon/favicon.ico": { + "mtime": 1780513420000, + "size": 15406 + }, + "assets/favicon/favicon.png": { + "mtime": 1780520464204.617, + "size": 778312 + }, + "assets/favicon/favicon_bg.png": { + "mtime": 1780520601264.4983, + "size": 791215 + }, + "assets/favicon/site.webmanifest": { + "mtime": 1780513420000, + "size": 263 + }, + "assets/fonts/files/alice-cyrillic-400-normal.woff2": { + "mtime": 1779377996112.3274, + "size": 17784 + }, + "assets/fonts/files/alice-cyrillic-ext-400-normal.woff2": { + "mtime": 1779377996113.3308, + "size": 15748 + }, + "assets/fonts/files/alice-latin-400-normal.woff2": { + "mtime": 1779377996114.3271, + "size": 25788 + }, + "assets/fonts/files/alice-latin-ext-400-normal.woff2": { + "mtime": 1779377996115.328, + "size": 4880 + }, + "assets/fonts/files/geologica-cyrillic-ext-wght-normal.woff2": { + "mtime": 1779377996117.3262, + "size": 11488 + }, + "assets/fonts/files/geologica-cyrillic-wght-normal.woff2": { + "mtime": 1779377996118.3267, + "size": 16428 + }, + "assets/fonts/files/geologica-greek-wght-normal.woff2": { + "mtime": 1779377996118.3267, + "size": 10928 + }, + "assets/fonts/files/geologica-latin-ext-wght-normal.woff2": { + "mtime": 1779377996119.833, + "size": 22404 + }, + "assets/fonts/files/geologica-latin-wght-normal.woff2": { + "mtime": 1779377996120.8398, + "size": 24944 + }, + "assets/fonts/files/geologica-vietnamese-wght-normal.woff2": { + "mtime": 1779377996121.8386, + "size": 8328 + }, + "assets/fonts/files/merriweather-cyrillic-400-normal.woff2": { + "mtime": 1779377996122.839, + "size": 25484 + }, + "assets/fonts/files/merriweather-cyrillic-700-normal.woff2": { + "mtime": 1779377996123.8394, + "size": 25492 + }, + "assets/fonts/files/merriweather-cyrillic-ext-400-normal.woff2": { + "mtime": 1779377996124.9783, + "size": 18600 + }, + "assets/fonts/files/merriweather-cyrillic-ext-700-normal.woff2": { + "mtime": 1779377996125.9778, + "size": 18560 + }, + "assets/fonts/files/merriweather-latin-400-normal.woff2": { + "mtime": 1779377996126.9783, + "size": 49168 + }, + "assets/fonts/files/merriweather-latin-700-normal.woff2": { + "mtime": 1779377996127.9773, + "size": 48660 + }, + "assets/fonts/files/merriweather-latin-ext-400-normal.woff2": { + "mtime": 1779377996129.4827, + "size": 42952 + }, + "assets/fonts/files/merriweather-latin-ext-700-normal.woff2": { + "mtime": 1779377996130.4888, + "size": 42880 + }, + "assets/fonts/files/merriweather-vietnamese-400-normal.woff2": { + "mtime": 1779377996131.49, + "size": 6664 + }, + "assets/fonts/files/merriweather-vietnamese-700-normal.woff2": { + "mtime": 1779377996133.4978, + "size": 6660 + }, + "assets/fonts/files/pt-mono-cyrillic-400-normal.woff2": { + "mtime": 1779377996134.4993, + "size": 15356 + }, + "assets/fonts/files/pt-mono-cyrillic-ext-400-normal.woff2": { + "mtime": 1779377996135.4956, + "size": 22028 + }, + "assets/fonts/files/pt-mono-latin-400-normal.woff2": { + "mtime": 1779377996136.4954, + "size": 27436 + }, + "assets/fonts/files/pt-mono-latin-ext-400-normal.woff2": { + "mtime": 1779377996137.4963, + "size": 16072 + }, + "assets/fonts/files/pt-sans-cyrillic-400-normal.woff2": { + "mtime": 1779377996138.4968, + "size": 28548 + }, + "assets/fonts/files/pt-sans-cyrillic-700-normal.woff2": { + "mtime": 1779377996139.4963, + "size": 30164 + }, + "assets/fonts/files/pt-sans-cyrillic-ext-400-normal.woff2": { + "mtime": 1779377996140.0027, + "size": 42680 + }, + "assets/fonts/files/pt-sans-cyrillic-ext-700-normal.woff2": { + "mtime": 1779377996142.004, + "size": 39584 + }, + "assets/fonts/files/pt-sans-latin-400-normal.woff2": { + "mtime": 1779377996143.0056, + "size": 45532 + }, + "assets/fonts/files/pt-sans-latin-700-normal.woff2": { + "mtime": 1779377996144.0051, + "size": 47180 + }, + "assets/fonts/files/pt-sans-latin-ext-400-normal.woff2": { + "mtime": 1779377996145.0054, + "size": 26812 + }, + "assets/fonts/files/pt-sans-latin-ext-700-normal.woff2": { + "mtime": 1779377996147.0066, + "size": 29624 + }, + "assets/fonts/files/source-code-pro-cyrillic-400-normal.woff2": { + "mtime": 1779377996147.0066, + "size": 6788 + }, + "assets/fonts/files/source-code-pro-cyrillic-500-normal.woff2": { + "mtime": 1779377996148.0044, + "size": 6836 + }, + "assets/fonts/files/source-code-pro-cyrillic-600-normal.woff2": { + "mtime": 1779377996149.5103, + "size": 6796 + }, + "assets/fonts/files/source-code-pro-cyrillic-700-normal.woff2": { + "mtime": 1779377996150.517, + "size": 6800 + }, + "assets/fonts/files/source-code-pro-cyrillic-ext-400-normal.woff2": { + "mtime": 1779377996150.517, + "size": 4516 + }, + "assets/fonts/files/source-code-pro-cyrillic-ext-500-normal.woff2": { + "mtime": 1779377996151.5173, + "size": 4556 + }, + "assets/fonts/files/source-code-pro-cyrillic-ext-600-normal.woff2": { + "mtime": 1779377996152.5176, + "size": 4520 + }, + "assets/fonts/files/source-code-pro-cyrillic-ext-700-normal.woff2": { + "mtime": 1779377996153.5164, + "size": 4480 + }, + "assets/fonts/files/source-code-pro-greek-400-normal.woff2": { + "mtime": 1779377996154.5195, + "size": 5528 + }, + "assets/fonts/files/source-code-pro-greek-500-normal.woff2": { + "mtime": 1779377996155.5168, + "size": 5584 + }, + "assets/fonts/files/source-code-pro-greek-600-normal.woff2": { + "mtime": 1779377996155.5168, + "size": 5532 + }, + "assets/fonts/files/source-code-pro-greek-700-normal.woff2": { + "mtime": 1779377996156.5166, + "size": 5528 + }, + "assets/fonts/files/source-code-pro-greek-ext-400-normal.woff2": { + "mtime": 1779377996157.5166, + "size": 1852 + }, + "assets/fonts/files/source-code-pro-greek-ext-500-normal.woff2": { + "mtime": 1779377996158.5164, + "size": 1856 + }, + "assets/fonts/files/source-code-pro-greek-ext-600-normal.woff2": { + "mtime": 1779377996159.5183, + "size": 1868 + }, + "assets/fonts/files/source-code-pro-greek-ext-700-normal.woff2": { + "mtime": 1779377996160.6191, + "size": 1824 + }, + "assets/fonts/files/source-code-pro-latin-400-normal.woff2": { + "mtime": 1779377996160.6191, + "size": 11656 + }, + "assets/fonts/files/source-code-pro-latin-500-normal.woff2": { + "mtime": 1779377996161.619, + "size": 11604 + }, + "assets/fonts/files/source-code-pro-latin-600-normal.woff2": { + "mtime": 1779377996163.6172, + "size": 11628 + }, + "assets/fonts/files/source-code-pro-latin-700-normal.woff2": { + "mtime": 1779377996163.6172, + "size": 11540 + }, + "assets/fonts/files/source-code-pro-latin-ext-400-normal.woff2": { + "mtime": 1779377996165.6191, + "size": 17748 + }, + "assets/fonts/files/source-code-pro-latin-ext-500-normal.woff2": { + "mtime": 1779377996166.6196, + "size": 17752 + }, + "assets/fonts/files/source-code-pro-latin-ext-600-normal.woff2": { + "mtime": 1779377996167.6196, + "size": 17640 + }, + "assets/fonts/files/source-code-pro-latin-ext-700-normal.woff2": { + "mtime": 1779377996168.6196, + "size": 17644 + }, + "assets/fonts/files/source-code-pro-vietnamese-400-normal.woff2": { + "mtime": 1779377996169.619, + "size": 4752 + }, + "assets/fonts/files/source-code-pro-vietnamese-500-normal.woff2": { + "mtime": 1779377996170.1245, + "size": 4804 + }, + "assets/fonts/files/source-code-pro-vietnamese-600-normal.woff2": { + "mtime": 1779377996171.1304, + "size": 4704 + }, + "assets/fonts/files/source-code-pro-vietnamese-700-normal.woff2": { + "mtime": 1779377996172.1353, + "size": 4748 + }, + "assets/fonts/geologica.css": { + "mtime": 1779377996172.1353, + "size": 5047 + }, + "assets/fonts/merriweather.css": { + "mtime": 1779377996173.1355, + "size": 5119 + }, + "assets/fonts/mono.css": { + "mtime": 1779377996174.135, + "size": 11463 + }, + "assets/index/ava-bg-1.png": { + "mtime": 1776187876634.7048, + "size": 1279764 + }, + "assets/index/ava-bg-1.webp": { + "mtime": 1777054556943, + "size": 81378 + }, + "assets/index/me-transparentBG-1.png": { + "mtime": 1776189627628.54, + "size": 1011694 + }, + "assets/index/me-transparentBG-1.webp": { + "mtime": 1777054557058, + "size": 141834 + }, + "assets/index/me_motion.mp4": { + "mtime": 1777636422897.9202, + "size": 311169 + }, + "assets/index/me_motion.webm": { + "mtime": 1777636422899.8853, + "size": 215347 + }, + "assets/index/me_motion.webp": { + "mtime": 1777636422902.3997, + "size": 79376 + }, + "assets/index/me_static.png": { + "mtime": 1777636422916.1433, + "size": 1592317 + }, + "assets/index/me_static.webp": { + "mtime": 1777636422917.152, + "size": 141572 + }, + "assets/lunacy/.gitkeep": { + "mtime": 1779377996175.1355, + "size": 2 + }, + "assets/lunacy/blob_settings_on_canvas.png": { + "mtime": 1779377996193.6858, + "size": 185060 + }, + "assets/lunacy/blob_settings_on_canvas.webp": { + "mtime": 1779377996194.6858, + "size": 48762 + }, + "assets/lunacy/blob_settings_panel_v1.png": { + "mtime": 1779377996195.6848, + "size": 16000 + }, + "assets/lunacy/blob_settings_panel_v1.webp": { + "mtime": 1779377996196.6843, + "size": 6868 + }, + "assets/lunacy/blob_settings_panel_v2.png": { + "mtime": 1779377996196.6843, + "size": 13903 + }, + "assets/lunacy/blob_settings_panel_v2.webp": { + "mtime": 1779377996197.6863, + "size": 4308 + }, + "assets/lunacy/blob_settings_panel_v3.png": { + "mtime": 1779377996197.6863, + "size": 20852 + }, + "assets/lunacy/blob_settings_panel_v3.webp": { + "mtime": 1779377996198.6855, + "size": 9948 + }, + "assets/lunacy/blob_settings_panel_v4.png": { + "mtime": 1779377996198.6855, + "size": 15539 + }, + "assets/lunacy/blob_settings_panel_v4.webp": { + "mtime": 1779377996199.6868, + "size": 3930 + }, + "assets/lunacy/blob_settings_panel_v5.png": { + "mtime": 1779377996200.7917, + "size": 14378 + }, + "assets/lunacy/blob_settings_panel_v5.webp": { + "mtime": 1779377996200.7917, + "size": 3864 + }, + "assets/lunacy/blob_settings_panel_v6.png": { + "mtime": 1779377996201.7903, + "size": 14869 + }, + "assets/lunacy/blob_settings_panel_v6.webp": { + "mtime": 1779377996202.7896, + "size": 4080 + }, + "assets/lunacy/blob_settings_panel_v7.png": { + "mtime": 1779377996202.7896, + "size": 23381 + }, + "assets/lunacy/blob_settings_panel_v7.webp": { + "mtime": 1779377996203.7908, + "size": 7690 + }, + "assets/lunacy/blob_settings_panel_v8.png": { + "mtime": 1779377996204.7915, + "size": 15387 + }, + "assets/lunacy/blob_settings_panel_v8.webp": { + "mtime": 1779377996204.7915, + "size": 4542 + }, + "assets/lunacy/blob_settings_panel_v9.png": { + "mtime": 1779377996205.7905, + "size": 18344 + }, + "assets/lunacy/blob_settings_panel_v9.webp": { + "mtime": 1779377996206.7903, + "size": 8820 + }, + "assets/lunacy/compare_components_modal_window.png": { + "mtime": 1779377996207.7922, + "size": 103262 + }, + "assets/lunacy/compare_components_modal_window.webp": { + "mtime": 1779377996208.7913, + "size": 23548 + }, + "assets/lunacy/components_update_indicator_location_panel.png": { + "mtime": 1779377996210.2961, + "size": 75843 + }, + "assets/lunacy/components_update_indicator_location_panel.webp": { + "mtime": 1779377996211.3025, + "size": 24570 + }, + "assets/lunacy/cover.webp": { + "mtime": 1779377996212.307, + "size": 198532 + }, + "assets/lunacy/Lunacy_app_overview.png": { + "mtime": 1779377996188.6538, + "size": 1304403 + }, + "assets/lunacy/Lunacy_app_overview.webp": { + "mtime": 1779377996191.6865, + "size": 198532 + }, + "assets/lunacy/modal_window_for_prototype_create_on_canvas.png": { + "mtime": 1779377996218.308, + "size": 699587 + }, + "assets/lunacy/modal_window_for_prototype_create_on_canvas.webp": { + "mtime": 1779377996219.8125, + "size": 114986 + }, + "assets/lunacy/modal_window_for_prototype_panel_states.png": { + "mtime": 1779377996221.818, + "size": 163537 + }, + "assets/lunacy/modal_window_for_prototype_panel_states.webp": { + "mtime": 1779377996222.8186, + "size": 67292 + }, + "assets/lunacy/shadow_pro_settings_ideas.png": { + "mtime": 1779377996224.3208, + "size": 150278 + }, + "assets/lunacy/shadow_pro_settings_ideas.webp": { + "mtime": 1779377996225.3252, + "size": 41824 + }, + "assets/lunacy/shadow_pro_settings_modal_auto-off.png": { + "mtime": 1779377996227.3298, + "size": 149676 + }, + "assets/lunacy/shadow_pro_settings_modal_auto-off.webp": { + "mtime": 1779377996228.329, + "size": 20878 + }, + "assets/lunacy/shadow_pro_settings_modal_auto_on.png": { + "mtime": 1779377996229.8337, + "size": 133884 + }, + "assets/lunacy/shadow_pro_settings_modal_auto_on.webp": { + "mtime": 1779377996230.84, + "size": 20552 + }, + "assets/lunacy/shadow_pro_settings_panel.png": { + "mtime": 1779377996232.8403, + "size": 175508 + }, + "assets/lunacy/shadow_pro_settings_panel.webp": { + "mtime": 1779377996233.8416, + "size": 64304 + }, + "assets/lunacy/sliders_all_set.png": { + "mtime": 1779377996260.5515, + "size": 653520 + }, + "assets/lunacy/sliders_all_set.webp": { + "mtime": 1779377996261.5532, + "size": 82004 + }, + "assets/lunacy/slider_14.png": { + "mtime": 1779377996233.8416, + "size": 15296 + }, + "assets/lunacy/slider_14.webp": { + "mtime": 1779377996234.8418, + "size": 6104 + }, + "assets/lunacy/slider_v1.png": { + "mtime": 1779377996235.8403, + "size": 11997 + }, + "assets/lunacy/slider_v1.webp": { + "mtime": 1779377996235.8403, + "size": 4894 + }, + "assets/lunacy/slider_v10.png": { + "mtime": 1779377996236.8413, + "size": 16438 + }, + "assets/lunacy/slider_v10.webp": { + "mtime": 1779377996237.8428, + "size": 5316 + }, + "assets/lunacy/slider_v11.png": { + "mtime": 1779377996237.8428, + "size": 15713 + }, + "assets/lunacy/slider_v11.webp": { + "mtime": 1779377996238.8408, + "size": 5264 + }, + "assets/lunacy/slider_v12.png": { + "mtime": 1779377996239.8408, + "size": 16355 + }, + "assets/lunacy/slider_v12.webp": { + "mtime": 1779377996239.8408, + "size": 5236 + }, + "assets/lunacy/slider_v13.png": { + "mtime": 1779377996240.93, + "size": 16412 + }, + "assets/lunacy/slider_v13.webp": { + "mtime": 1779377996240.93, + "size": 4780 + }, + "assets/lunacy/slider_v15.png": { + "mtime": 1779377996241.9312, + "size": 16438 + }, + "assets/lunacy/slider_v15.webp": { + "mtime": 1779377996241.9312, + "size": 5316 + }, + "assets/lunacy/slider_v16.png": { + "mtime": 1779377996242.932, + "size": 16992 + }, + "assets/lunacy/slider_v16.webp": { + "mtime": 1779377996242.932, + "size": 5042 + }, + "assets/lunacy/slider_v17.png": { + "mtime": 1779377996243.93, + "size": 14273 + }, + "assets/lunacy/slider_v17.webp": { + "mtime": 1779377996244.9321, + "size": 4370 + }, + "assets/lunacy/slider_v18.png": { + "mtime": 1779377996244.9321, + "size": 15153 + }, + "assets/lunacy/slider_v18.webp": { + "mtime": 1779377996245.9304, + "size": 5138 + }, + "assets/lunacy/slider_v2.png": { + "mtime": 1779377996245.9304, + "size": 12918 + }, + "assets/lunacy/slider_v2.webp": { + "mtime": 1779377996246.9302, + "size": 5676 + }, + "assets/lunacy/slider_v3.png": { + "mtime": 1779377996247.9326, + "size": 24683 + }, + "assets/lunacy/slider_v3.webp": { + "mtime": 1779377996247.9326, + "size": 6056 + }, + "assets/lunacy/slider_v4.png": { + "mtime": 1779377996249.4392, + "size": 21075 + }, + "assets/lunacy/slider_v4.webp": { + "mtime": 1779377996250.448, + "size": 5806 + }, + "assets/lunacy/slider_v5.png": { + "mtime": 1779377996251.4482, + "size": 13119 + }, + "assets/lunacy/slider_v5.webp": { + "mtime": 1779377996251.4482, + "size": 5512 + }, + "assets/lunacy/slider_v6.png": { + "mtime": 1779377996252.4485, + "size": 15467 + }, + "assets/lunacy/slider_v6.webp": { + "mtime": 1779377996252.4485, + "size": 4526 + }, + "assets/lunacy/slider_v7.png": { + "mtime": 1779377996253.4475, + "size": 15261 + }, + "assets/lunacy/slider_v7.webp": { + "mtime": 1779377996254.446, + "size": 5300 + }, + "assets/lunacy/slider_v8.png": { + "mtime": 1779377996254.446, + "size": 15432 + }, + "assets/lunacy/slider_v8.webp": { + "mtime": 1779377996255.4485, + "size": 4910 + }, + "assets/lunacy/slider_v9.png": { + "mtime": 1779377996256.447, + "size": 17093 + }, + "assets/lunacy/slider_v9.webp": { + "mtime": 1779377996256.447, + "size": 5676 + }, + "assets/mamadaevv_resume.pdf": { + "mtime": 1780575571973.1184, + "size": 160205 + }, + "assets/manu-game-maker/.gitkeep": { + "mtime": 1779377996263.5508, + "size": 2 + }, + "assets/manu-game-maker/cover.png": { + "mtime": 1779377996266.5527, + "size": 483251 + }, + "assets/manu-game-maker/cover.webp": { + "mtime": 1779377996268.5513, + "size": 94600 + }, + "assets/misc/dribbble_logo.png": { + "mtime": 1780407662552.718, + "size": 794904 + }, + "assets/misc/dribbble_logo.webp": { + "mtime": 1780407662555.7188, + "size": 16768 + }, + "assets/misc/figma_logo.jpg": { + "mtime": 1780407662557.7192, + "size": 10883 + }, + "assets/misc/figma_logo.webp": { + "mtime": 1780407662559.719, + "size": 5108 + }, + "assets/misc/tg-channel-logo-design_not_pizza.jpg": { + "mtime": 1780407662562.7192, + "size": 48308 + }, + "assets/misc/tg-channel-logo-design_not_pizza.webp": { + "mtime": 1780407662564.7183, + "size": 23598 + }, + "assets/mobile-clinic-app/.gitkeep": { + "mtime": 1779377996270.7036, + "size": 2 + }, + "assets/mobile-clinic-app/cover.png": { + "mtime": 1779377996275.6907, + "size": 626518 + }, + "assets/mobile-clinic-app/cover.webp": { + "mtime": 1779377996277.6917, + "size": 121088 + }, + "assets/obsidian-plugin-columns-view/filter use.mp4": { + "mtime": 1782054448519.579, + "size": 36000629 + }, + "assets/obsidian-plugin-columns-view/filter use.webm": { + "mtime": 1782054874042.0066, + "size": 4117727 + }, + "assets/obsidian-plugin-columns-view/filter use.webp": { + "mtime": 1782054874401.6035, + "size": 82876 + }, + "assets/obsidian-plugin-columns-view/overview.png": { + "mtime": 1782055820170.6465, + "size": 358265 + }, + "assets/obsidian-plugin-columns-view/overview.webp": { + "mtime": 1782057055802, + "size": 199104 + }, + "assets/obsidian-plugin-columns-view/view configure.mp4": { + "mtime": 1782054318526.4917, + "size": 41097403 + }, + "assets/obsidian-plugin-columns-view/view configure.webm": { + "mtime": 1782054960161.7544, + "size": 2104173 + }, + "assets/obsidian-plugin-columns-view/view configure.webp": { + "mtime": 1782054960408.1843, + "size": 69110 + }, + "assets/orc-primo-rpa/cover.webp": { + "mtime": 1780407662568.7195, + "size": 42848 + }, + "assets/orc-primo-rpa/projects--table-new.png": { + "mtime": 1780407662571.719, + "size": 86822 + }, + "assets/orc-primo-rpa/projects--table-new.webp": { + "mtime": 1780407662572.718, + "size": 42848 + }, + "assets/orc-primo-rpa/projects--table-old.png": { + "mtime": 1780407662575.226, + "size": 139826 + }, + "assets/orc-primo-rpa/projects--table-old.webp": { + "mtime": 1780407662577.2327, + "size": 78910 + }, + "assets/README.md": { + "mtime": 1779377996027.13, + "size": 843 + }, + "assets/shared/icons/arrow_upright.svg": { + "mtime": 1776362143026.8838, + "size": 1215 + }, + "assets/shared/icons/chat_start.svg": { + "mtime": 1776193642521.755, + "size": 3485 + }, + "assets/shared/icons/checkmark.svg": { + "mtime": 1776422601550.154, + "size": 767 + }, + "assets/shared/icons/close.svg": { + "mtime": 1776857552773.9846, + "size": 407 + }, + "assets/shared/icons/copy.svg": { + "mtime": 1776352846992.719, + "size": 1418 + }, + "assets/shared/icons/cv.svg": { + "mtime": 1776514945920.6653, + "size": 2492 + }, + "assets/shared/icons/delete.svg": { + "mtime": 1779377996278.6897, + "size": 1486 + }, + "assets/shared/icons/design_edit.svg": { + "mtime": 1776193642520.2417, + "size": 5473 + }, + "assets/shared/icons/email.svg": { + "mtime": 1776362122606.4749, + "size": 1589 + }, + "assets/shared/icons/link_url.svg": { + "mtime": 1780407662580.2358, + "size": 1525 + }, + "assets/shared/icons/moon.svg": { + "mtime": 1776193642519.029, + "size": 1090 + }, + "assets/shared/icons/original_size.svg": { + "mtime": 1776857547534.4807, + "size": 2382 + }, + "assets/shared/icons/portfolio.svg": { + "mtime": 1776515141309.182, + "size": 1352 + }, + "assets/shared/icons/shevron-down.svg": { + "mtime": 1777636422918.6008, + "size": 1222 + }, + "assets/shared/icons/shevron-left.svg": { + "mtime": 1777636422919.6145, + "size": 1207 + }, + "assets/shared/icons/shevron-right.svg": { + "mtime": 1777636422919.6145, + "size": 1209 + }, + "assets/shared/icons/shevron-up.svg": { + "mtime": 1777636422921.079, + "size": 1208 + }, + "assets/shared/icons/sun.svg": { + "mtime": 1776193642517.9954, + "size": 4326 + }, + "assets/shared/icons/system.svg": { + "mtime": 1776193642519.029, + "size": 2249 + }, + "assets/shared/icons/tg.svg": { + "mtime": 1776362122602.7698, + "size": 1373 + }, + "assets/shared/icons/vk.svg": { + "mtime": 1776362122605.4763, + "size": 615 + }, + "assets/shared/icons/write_me.svg": { + "mtime": 1777030666208.4812, + "size": 3077 + }, + "assets/shared/icons/yandex_telemost.svg": { + "mtime": 1776362122604.4692, + "size": 572 + }, + "assets/shared/icons/zoom_in.svg": { + "mtime": 1776856548780.6626, + "size": 1953 + }, + "assets/shared/icons/zoom_out.svg": { + "mtime": 1776856548780.6626, + "size": 1592 + }, + "assets/shared/icons/zoom_to_fit.svg": { + "mtime": 1779377996280.203, + "size": 1248 + }, + "assets/shared/icons/сookie.svg": { + "mtime": 1776607984487.0112, + "size": 3508 + }, + "assets/shared/placeholder.jpg": { + "mtime": 1777053044955.2012, + "size": 34829 + }, + "assets/shared/placeholder.webp": { + "mtime": 1780407662581.2354, + "size": 240 + }, + "assets/task-distribution-concept/.gitkeep": { + "mtime": 1779377996281.21, + "size": 2 + }, + "assets/task-distribution-concept/cover.png": { + "mtime": 1779377996284.209, + "size": 197021 + }, + "assets/task-distribution-concept/cover.webp": { + "mtime": 1779377996286.2097, + "size": 81646 + }, + "assets/task-tracker/actions_for_page.png": { + "mtime": 1724892346000, + "size": 25027 + }, + "assets/task-tracker/actions_for_page.webp": { + "mtime": 1777119492700, + "size": 23404 + }, + "assets/task-tracker/cover.webp": { + "mtime": 1779377996288.2092, + "size": 151720 + }, + "assets/task-tracker/dark_theme.png": { + "mtime": 1724892366000, + "size": 291518 + }, + "assets/task-tracker/dark_theme.webp": { + "mtime": 1777119492957, + "size": 147348 + }, + "assets/task-tracker/drag-drop-action_example.mp4": { + "mtime": 1776793076285.7869, + "size": 2095990 + }, + "assets/task-tracker/drag-drop-action_example.webm": { + "mtime": 1777118933364.2495, + "size": 147445 + }, + "assets/task-tracker/drag-drop-action_example.webp": { + "mtime": 1777118933542.3682, + "size": 3604 + }, + "assets/task-tracker/drag-drop-item_board-view.mp4": { + "mtime": 1724892358000, + "size": 1784143 + }, + "assets/task-tracker/drag-drop-item_board-view.webm": { + "mtime": 1777118939415.8855, + "size": 232186 + }, + "assets/task-tracker/drag-drop-item_board-view.webp": { + "mtime": 1777118939601.6213, + "size": 27548 + }, + "assets/task-tracker/drag-drop-item_list-view.mp4": { + "mtime": 1724892360000, + "size": 2886192 + }, + "assets/task-tracker/drag-drop-item_list-view.webm": { + "mtime": 1777118960260.8003, + "size": 331393 + }, + "assets/task-tracker/drag-drop-item_list-view.webp": { + "mtime": 1777118960514.3586, + "size": 27766 + }, + "assets/task-tracker/dropdown_menu_for_views.png": { + "mtime": 1724892346000, + "size": 75360 + }, + "assets/task-tracker/dropdown_menu_for_views.webp": { + "mtime": 1777119493007, + "size": 64398 + }, + "assets/task-tracker/expand-collapse_group.mp4": { + "mtime": 1724892356000, + "size": 1663390 + }, + "assets/task-tracker/expand-collapse_group.webm": { + "mtime": 1777118977581.77, + "size": 196247 + }, + "assets/task-tracker/expand-collapse_group.webp": { + "mtime": 1777118977813.5178, + "size": 27750 + }, + "assets/task-tracker/full_preview.mp4": { + "mtime": 1776877975221.4644, + "size": 2480939 + }, + "assets/task-tracker/full_preview.webm": { + "mtime": 1777119206780.3667, + "size": 1852963 + }, + "assets/task-tracker/full_preview.webp": { + "mtime": 1777119207226.3965, + "size": 31316 + }, + "assets/task-tracker/light_theme_color.png": { + "mtime": 1724892364000, + "size": 555991 + }, + "assets/task-tracker/light_theme_color.webp": { + "mtime": 1777119493297, + "size": 164962 + }, + "assets/task-tracker/refs.png": { + "mtime": 1776792419154.0342, + "size": 1779282 + }, + "assets/task-tracker/refs.webp": { + "mtime": 1777119493506, + "size": 225610 + }, + "assets/task-tracker/tabs.mp4": { + "mtime": 1776792488669.555, + "size": 4908318 + }, + "assets/task-tracker/tabs.webm": { + "mtime": 1777119316281.4424, + "size": 804022 + }, + "assets/task-tracker/tabs.webp": { + "mtime": 1777119316704.9702, + "size": 31082 + }, + "assets/task-tracker/tab_all-tasks.png": { + "mtime": 1724892344000, + "size": 285868 + }, + "assets/task-tracker/tab_all-tasks.webp": { + "mtime": 1777119493851, + "size": 151720 + }, + "assets/task-tracker/tab_my-tasks.png": { + "mtime": 1724892344000, + "size": 232690 + }, + "assets/task-tracker/tab_my-tasks.webp": { + "mtime": 1777119494176, + "size": 118694 + }, + "assets/task-tracker/tab_tasks-by-assign.png": { + "mtime": 1724892344000, + "size": 283151 + }, + "assets/task-tracker/tab_tasks-by-assign.webp": { + "mtime": 1777119494494, + "size": 147370 + }, + "assets/task-tracker/views.mp4": { + "mtime": 1776792546358.3933, + "size": 3655835 + }, + "assets/task-tracker/views.webm": { + "mtime": 1777119348131.017, + "size": 588868 + }, + "assets/task-tracker/views.webp": { + "mtime": 1777119348524.0642, + "size": 30412 + }, + "assets/task-tracker/view_board.png": { + "mtime": 1724892346000, + "size": 285868 + }, + "assets/task-tracker/view_board.webp": { + "mtime": 1777119494790, + "size": 151720 + }, + "assets/task-tracker/view_list.png": { + "mtime": 1724892350000, + "size": 281726 + }, + "assets/task-tracker/view_list.webp": { + "mtime": 1777119495084, + "size": 153030 + }, + "assets/task-tracker/view_table.png": { + "mtime": 1724892354000, + "size": 306629 + }, + "assets/task-tracker/view_table.webp": { + "mtime": 1777119495385, + "size": 159062 + }, + "assets/template-elements-demo/hello.gif": { + "mtime": 1713970676235.8618, + "size": 1445905 + }, + "assets/template-elements-demo/img-long.png": { + "mtime": 1779377996303.2358, + "size": 1430322 + }, + "assets/template-elements-demo/img-long.webp": { + "mtime": 1779377996305.2405, + "size": 134456 + }, + "assets/template-elements-demo/small-image-1.png": { + "mtime": 1779377996307.2373, + "size": 127198 + }, + "assets/template-elements-demo/small-image-1.webp": { + "mtime": 1779377996307.2373, + "size": 6676 + }, + "assets/template-elements-demo/small-image-2.png": { + "mtime": 1779377996309.7412, + "size": 220181 + }, + "assets/template-elements-demo/small-image-2.webp": { + "mtime": 1779377996309.7412, + "size": 9214 + }, + "assets/template-elements-demo/small-image-3.png": { + "mtime": 1779377996312.7493, + "size": 330973 + }, + "assets/template-elements-demo/small-image-3.webp": { + "mtime": 1779377996313.7478, + "size": 19430 + }, + "assets/template-elements-demo/small-image-4.png": { + "mtime": 1779377996314.7488, + "size": 211288 + }, + "assets/template-elements-demo/small-image-4.webp": { + "mtime": 1779377996315.7507, + "size": 11306 + }, + "assets/template-elements-demo/small-image-5.png": { + "mtime": 1779377996317.748, + "size": 249941 + }, + "assets/template-elements-demo/small-image-5.webp": { + "mtime": 1779377996318.7485, + "size": 15056 + }, + "assets/template-elements-demo/small-image-6.png": { + "mtime": 1779377996319.7495, + "size": 161762 + }, + "assets/template-elements-demo/small-image-6.webp": { + "mtime": 1779377996320.861, + "size": 8470 + }, + "assets/template-elements-demo/small-image-7.png": { + "mtime": 1779377996322.8584, + "size": 196080 + }, + "assets/template-elements-demo/small-image-7.webp": { + "mtime": 1779377996323.8606, + "size": 7832 + }, + "assets/template-elements-demo/video-1.mp4": { + "mtime": 1774365295973.9094, + "size": 3676034 + }, + "assets/template-elements-demo/video-1.webm": { + "mtime": 1777119460084.1753, + "size": 3490147 + }, + "assets/template-elements-demo/video-1.webp": { + "mtime": 1777119460340.927, + "size": 112702 + }, + "assets/template-elements-demo/wallpaper-1.jpg": { + "mtime": 1770206903718.8467, + "size": 1011262 + }, + "assets/template-elements-demo/wallpaper-1.webp": { + "mtime": 1777119432828, + "size": 795944 + }, + "cases/ai-platform-primo-rpa-2.html": { + "mtime": 1782245252136.977, + "size": 56010 + }, + "cases/ai-platform-primo-rpa.html": { + "mtime": 1782245252138.9834, + "size": 65300 + }, + "cases/design-system.html": { + "mtime": 1782245252140.9756, + "size": 51499 + }, + "cases/lunacy.html": { + "mtime": 1782245252140.9756, + "size": 51520 + }, + "cases/manu-game-maker.html": { + "mtime": 1782245252142.1548, + "size": 33426 + }, + "cases/mini-projects-showcase.html": { + "mtime": 1782245252144.1592, + "size": 45596 + }, + "cases/mobile-clinic-app.html": { + "mtime": 1782245252145.1597, + "size": 33340 + }, + "cases/obsidian-plugin-columns-view.html": { + "mtime": 1782245252145.1597, + "size": 34314 + }, + "cases/orc-automation-panel.html": { + "mtime": 1782245252146.161, + "size": 48044 + }, + "cases/task-distribution-concept.html": { + "mtime": 1782245252147.1592, + "size": 33330 + }, + "cases/task-tracker.html": { + "mtime": 1782245252149.1597, + "size": 66746 + }, + "cases/template-elements-demo.html": { + "mtime": 1782245252150.16, + "size": 47480 + }, + "cookie-policy.html": { + "mtime": 1782245252151.1606, + "size": 20265 + }, + "css/main.css": { + "mtime": 1782122516629.0486, + "size": 129130 + }, + "index.html": { + "mtime": 1782245252151.1606, + "size": 69045 + }, + "js/main.js": { + "mtime": 1780407662602.799, + "size": 2804 + }, + "js/modules/cases/image-viewer.js": { + "mtime": 1780407662603.8, + "size": 13683 + }, + "js/modules/cases/natural-image-size.js": { + "mtime": 1777287125125.0857, + "size": 625 + }, + "js/modules/cases/sequential-images.js": { + "mtime": 1779377996345.018, + "size": 1224 + }, + "js/modules/cases/tall-media-expand.js": { + "mtime": 1779377996345.018, + "size": 1861 + }, + "js/modules/cases/video-player.js": { + "mtime": 1779377996347.0156, + "size": 1095 + }, + "js/modules/experience/expand.js": { + "mtime": 1777287125125.0857, + "size": 3993 + }, + "js/modules/experience/hover-glow.js": { + "mtime": 1777636422925.3562, + "size": 912 + }, + "js/modules/experience/masonry.js": { + "mtime": 1780407662605.8008, + "size": 2916 + }, + "js/modules/header/header-scroll.js": { + "mtime": 1779377996348.017, + "size": 4328 + }, + "js/modules/header/nav-overflow.js": { + "mtime": 1777287125117.0547, + "size": 5621 + }, + "js/modules/mini-projects/expand.js": { + "mtime": 1780407662607.4187, + "size": 4418 + }, + "js/modules/mini-projects/masonry.js": { + "mtime": 1782122516632.0474, + "size": 5036 + }, + "js/modules/shared/dom.js": { + "mtime": 1777287125128.091, + "size": 221 + }, + "js/modules/shared/image-src.js": { + "mtime": 1780407662612.4294, + "size": 214 + }, + "js/modules/shared/math.js": { + "mtime": 1777287125125.0857, + "size": 161 + }, + "js/modules/shared/media.js": { + "mtime": 1777287125117.0547, + "size": 645 + }, + "js/modules/shared/schedule-idle.js": { + "mtime": 1779377996348.017, + "size": 457 + }, + "js/modules/theme/theme-controls.js": { + "mtime": 1779377996349.5276, + "size": 6205 + }, + "js/modules/theme/theme-core.js": { + "mtime": 1782122516625.0393, + "size": 4885 + }, + "js/modules/theme/theme-fonts.js": { + "mtime": 1779377996352.5422, + "size": 1147 + }, + "js/modules/ui/contact-copy.js": { + "mtime": 1777287125128.091, + "size": 1793 + }, + "js/modules/ui/content-edit/content-edit-dock.js": { + "mtime": 1779377996353.5432, + "size": 9560 + }, + "js/modules/ui/content-edit/content-edit-mode.js": { + "mtime": 1779377996355.5415, + "size": 11767 + }, + "js/modules/ui/content-edit/content-edit-storage.js": { + "mtime": 1779377996355.5415, + "size": 868 + }, + "js/modules/ui/content-edit/content-edit-target.js": { + "mtime": 1779377996357.5415, + "size": 9573 + }, + "js/modules/ui/cookie-notice.js": { + "mtime": 1779377996357.5415, + "size": 923 + }, + "js/modules/ui/deferred-media.js": { + "mtime": 1779377996358.5417, + "size": 470 + }, + "js/modules/ui/hero-motion-video.js": { + "mtime": 1782244713466.1138, + "size": 1004 + }, + "js/modules/ui/hero-word-slot.js": { + "mtime": 1777287125117.0547, + "size": 3717 + }, + "js/modules/ui/image-load-placeholder.js": { + "mtime": 1780407662613.426, + "size": 2435 + }, + "js/modules/ui/mesh-panel.js": { + "mtime": 1779377996360.0525, + "size": 859 + }, + "js/modules/ui/page-mesh-bg.js": { + "mtime": 1779377996361.0547, + "size": 3216 + }, + "js/modules/ui/primary-button-shine.js": { + "mtime": 1777287125118.0613, + "size": 952 + }, + "js/modules/ui/projects-carousel.js": { + "mtime": 1779377996362.0613, + "size": 6390 + }, + "js/modules/ui/skills-accordion.js": { + "mtime": 1778061201791.5735, + "size": 5099 + }, + "js/modules/ui/skills-intro.js": { + "mtime": 1780407662615.4253, + "size": 1983 + }, + "js/skill-connectors.js": { + "mtime": 1776439133838.0786, + "size": 12132 + }, + "README.md": { + "mtime": 1777051804851.6003, + "size": 1363 + }, + "vendor/plyr/plyr.css": { + "mtime": 1779377996364.0625, + "size": 32455 + }, + "vendor/plyr/plyr.min.mjs": { + "mtime": 1779377996366.0618, + "size": 121675 + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..784bae0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Dependencies +node_modules/ + +# Build outputs +dist/ +build/ +coverage/ +.cache/ + +# IDE/editor local files (команды — в репо, см. .cursor/commands/) +.cursor/* +!.cursor/commands/ +!.cursor/commands/** +.vscode/ +gitverse/ + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# OS files +.DS_Store +Thumbs.db diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..170afb3 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,62 @@ +# Подсказки для агента (Cursor) + +## GitVerse / деплой статики + +Полный чеклист: **`docs/gitverse-sync.md`** → раздел **«Инструкция для агента (Cursor)»**. + +Деплой на VPS: **`docs/vps-deploy.md`**. + +Кратко по запросу пользователя «выложить на GitVerse», «синк gitverse», «задеплоить»: + +1. При правках `src/pages/**` или `src/partials/**` — `npm run build:pages`; при смене шрифтов/Plyr или `package.json` — `npm run build` (включает `vendor:copy`). +2. Затем `npm run sync-gitverse` (разрешения **network** и **git_write**). +3. Не запускать синк без явного запроса пользователя. + +По запросу «задеплой в Coolify», «задеплой на VPS»: + +1. При правках в `public/` — `npm run deploy:vps` (разрешения **all**). +2. По запросу «задеплой везде» — `npm run deploy` (VPS + GitVerse). + +Не запускать деплой на VPS без явного запроса: скрипт перезаписывает `/data/static-site` на сервере. + +## Git: корневой репозиторий + +Этот репозиторий в корне проекта **только локальный** (рабочая копия, история коммитов для себя). **Не добавлять `origin` и не пушить** в удалённый репозиторий из агента, если пользователь явно не попросил настроить remote и не дал URL. Выгрузка наружу — отдельный сценарий через **`npm run sync-gitverse`** в папку `gitverse` (см. выше), а не `git push` из корня. + +### Влить в `master`, оставаясь на текущей ветке + +Запрос «влить в мастер» **не означает** `git checkout master`, если пользователь не просил переключиться. + +- **Fast-forward** (ветка впереди `master`): на текущей ветке — `git branch -f master HEAD` или `git push . HEAD:master`. +- **Нужен merge-коммит** (`master` ушёл вперёд): `git checkout master` → `git merge <ветка>` → `git checkout -` (вернуться на прежнюю ветку). +- После влития **не меняй** активную ветку в IDE без запроса; при необходимости уточни, на какой ветке продолжать работу. + +## Design System + +Страница-каталог: **`src/pages/cases/design-system.html`** → после сборки `public/cases/design-system.html`. + +При **глобальных** правках стилей (токены в `public/css/main.css`, компоненты главной, блоки лонгрида кейса) **обновляй Design System**: живой пример и краткое описание в соответствующей секции, при необходимости — `docs/case-page-blocks.md`. + +## Контент кейса в public (по запросу) + +Обычный путь: `src/pages/cases/` → `npm run build:pages`. Если пользователь явно просит править **собранную** страницу под `npm run serve`, см. **`.cursor/rules/case-content-edit-in-public.mdc`**: правки в `.case-article` в `public/cases/`, синхронизация в `src` по запросу. + +## Русские тексты (humanizer-ru) + +При генерации и правке **русскоязычного контента** для сайта (кейсы, главная, `texts/**`, callout, meta) — читать скилл **`humanizer-ru`** и вычитывать текст по нему перед отдачей пользователю. Подробности: **`.cursor/rules/humanizer-ru-text.mdc`**. + +## Правки контента (content-edits, localhost) + +Режим на странице при `npm run serve` → очередь в **`texts/content-edits/pending.json`**. Apply по запросу **«примени правки»**: читать этот файл, править **`src/pages/`**, **humanizer-ru**, **`npm run build:pages`**; **`pending.json` не очищать** (пользователь удаляет пункты сам). Подробности: **`docs/content-edit-mode.md`**, **`.cursor/rules/content-edit-apply.mdc`**. + +## Vendor (шрифты, Plyr) + +Локально в `public/`, без CDN. Обновление: **`docs/vendor-assets.md`**, команда `npm run vendor:copy`. + +## Медиа на сайте (WebP / WebM) + +По запросу «добавить/обновить картинку или видео» в разметке только **WebP** (изображения, постеры) и **WebM** (видео); исходник конвертировать скриптами, не ждать отдельного уточнения. Подробности: **`.cursor/rules/media-webp-webm-only.mdc`**, `docs/image-optimization.md`, `docs/video-conversion.md`. + +## Остальное + +Правила и таблица доков: **`.cursor/rules/read-docs-before-feature-dev.mdc`** (локально; папка `.cursor/` может быть в `.gitignore`). diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..124bfd7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM nginx:latest + +# Fix mjs MIME type — without this plyr.min.mjs fails to load as ES module +RUN sed -i 's|application/javascript *js;|application/javascript js mjs;|' /etc/nginx/mime.types + +COPY ./public /usr/share/nginx/html +RUN chown -R nginx:nginx /usr/share/nginx/html diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 0000000..8d0edb5 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +set -e + +HOST="root@155.212.186.39" +SSH_KEY="$HOME/.ssh/beget" +SRC_DIR="$(cd "$(dirname "$0")" && pwd)/public/" + +echo "📦 Deploy mamadaevv.site..." +echo "Src: $SRC_DIR" + +REMOTE_INFO=$(ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no "$HOST" ' + CONTAINER=$(docker ps --format "{{.Names}}" | grep "s9mrcps8xw02r1dak0fsznix" | head -1) + VOLUME_PATH=$(docker inspect "$CONTAINER" 2>/dev/null | python3 -c " +import sys,json +mounts=json.load(sys.stdin)[0].get(\"Mounts\",[]) +print([m[\"Source\"] for m in mounts if m[\"Destination\"]==\"/usr/share/nginx/html\"][0]) +") + echo "$CONTAINER|$VOLUME_PATH" +') + +IFS='|' read -r CONTAINER VOLUME_PATH <<< "$REMOTE_INFO" +echo "Container: $CONTAINER" +echo "Volume: $VOLUME_PATH" + +# Копируем файлы +cd "$SRC_DIR" +tar cf - . | ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no "$HOST" \ + "tar xf - -C $VOLUME_PATH" + +# Фикс MIME для .mjs (plyr.min.mjs модуль) +ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no "$HOST" \ + "docker exec $CONTAINER sh -c \" + if ! grep -q 'application/javascript mjs' /etc/nginx/mime.types 2>/dev/null; then + sed -i 's|application/wasm|application/javascript mjs;\\n application/wasm|' /etc/nginx/mime.types + nginx -s reload && echo 'MIME fix applied' + fi + \"" 2>/dev/null || true + +echo "" +echo "✅ Done! https://mamadaevv.site" diff --git a/docs/case-page-blocks.md b/docs/case-page-blocks.md new file mode 100644 index 0000000..3c7237b --- /dev/null +++ b/docs/case-page-blocks.md @@ -0,0 +1,199 @@ +# Страница кейса: каркас и блоки контента + +Инструкция завязана на эталон **`src/pages/cases/template-elements-demo.html`**: оттуда копируются готовые куски разметки. Текстовый дубль структуры для редактуры — `texts/cases/template-elements-demo.md`. + +## Где править + +| Что | Путь | +|-----|------| +| Разметка кейса | `src/pages/cases/<имя>.html` | +| Общие вставки (шапка кейса, футер, скрипты) | `src/partials/*.html` | +| Сборка в статику | `npm run build:pages` → `public/cases/<имя>.html` | + +**`public/cases/*.html` не редактировать вручную** — они перезаписываются сборкой. + +Локальные инструкции агенту без правки HTML в браузере: режим правок при `npm run serve` → [`docs/content-edit-mode.md`](content-edit-mode.md) → `texts/content-edits/*.json` → apply в `src` по запросу в чате. + +## Каркас `body` (как в template) + +Порядок важен для единообразия с остальными кейсами: + +1. `{{> header-case}}` — шапка с ссылкой на главную (внутри partial используется `{{assetPrefix}}`). +2. `{{> fab-stack}}` — плавающие кнопки темы и т.п. +3. `
` → внутри `
` — **весь уникальный контент кейса**. +4. Нижние секции как на главной: `{{> projects-section}}`, `{{> contact-section}}`, `{{> footer-spacer}}`, `{{> footer}}`, `{{> cookie-notice}}`, `{{> nav-more-floating}}`. +5. Скрипты подключаются в `` через `{{> head-links}}` (preload + `main.js`, `skill-connectors.js`). + +`head` у кейсов: `meta`, `viewport`, `description`, `title`, затем `{{> head-links}}` (preconnect/preload шрифтов и CSS/JS, стили, скрипты с `defer`), при необходимости локальный ` + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Product Design · AI

+

Разработка интерфейса для Primo RPA AI Server

+

+ Платформа интеллектуальной обработки документов
+ и оркестрации ИИ-агентов +

+ +
+

Обзор

+

+ Внутри компании появился сервис, который заметно улучшил работу с моделями для распознавания текста на документах: загрузка датасета из документов компании, разметка полей, обучение модели и дальнейшее использование модели в других продуктах. Такой подход давал более высокое качество распознавания и соответствовал требованиям безопасности — данные оставались внутри контура компании. Уже в ходе работы в продукте появился функционал дообучения (fine-tuning) базовых нейросетей под задачи компании и работы со скилами: суммаризация, извлечение, генерация и другие сценарии. +

+

+ В проект меня пригласили как UX/UI дизайнера: интерфейс до этого собирали разработчики своими силами. В результате работы у сервиса снизился порог входа — продуктом могли пользоваться существенно больше людей без специальной подготовки в области ИИ и OCR. +

+ +
+ +
+

Было и стало

+

+ Сервис был собран на Ant Design под React с визуальной темой Hope UI для Bootstrap. У компании уже было несколько веб-продуктов с задачей унифицировать и освежить интерфейс, поэтому в разработке опирались на компоненты этих систем. +

+ +

+ Я погрузился в продукт и вместе с командой детально разобрал весь функционал. +

+ +

+ По текущим сценариям собрал юзерфлоу: они показали команде, где в интерфейсе и в маршрутах пользователя возникает путаница. На этой основе переработали сами процессы настройки: часть функций автоматизировали и спрятали, чтобы снизить риск ошибок и убрать лишнюю рутину. +

+

+ Новый подход изменил и восприятие продукта, и процесс настройки. Интерфейс ведёт по этапам настройки, при этом не ломает привычные сценарии: полностью линейный визард здесь невозможен — пользователю всё равно нужно возвращаться назад и уточнять параметры ради качества результата. +

+

Вопросы к команде по текущему состоянию

+

Ответы помогут зафиксировать эффект от внедрения в цифрах и фактах.

+
    +
  • Сократилось ли количество обращений в поддержку.
  • +
  • Получается ли у пользователей самостоятельно пройти настройку проекта от начала до конца.
  • +
  • Позволяет ли новый интерфейс заводить новые типы проектов, опираясь на уже заложенные паттерны.
  • +
+
+ +
+

Паттерны интерфейса

+

+ Ниже — ключевые зоны продукта: как они поддерживают сценарии обучения и работы с моделью и чем отличаются от прежнего подхода. +

+ +

Сопоставление полей (маппинг)

+

+ Маппинг связывает поля документа с целевой структурой данных. Важно было сделать связь наглядной и обратимой, чтобы пользователь не терял контекст при правках. +

+
+
+ +
+
Сопоставление полей в интерфейсе
+
+ +

Датасет, обучение и контроль качества

+

+ Редактор датасета, запуск обучения и экраны качества образуют один ментальный путь: подготовка данных → обучение → проверка результата. +

+ +
+ Редактор датасета — текущая версия интерфейса +
Редактор датасета — текущая версия
+
+
+ Редактор датасета — предыдущая версия для сравнения +
Предыдущая версия редактора
+
+
+ Экран обучения модели по датасету +
Обучение по датасету
+
+
+ Контроль качества модели после обучения +
Качество и проверка результата
+
+ +

Inference в проекте

+

+ Отдельный фокус — запуск и контроль модели внутри проекта: пользователь должен понимать состояние прогона и не терять связь с остальными настройками. +

+
+ Интерфейс inference модели внутри проекта +
Inference в проекте
+
+
+
+
+ Inference в проекте — полный экран интерфейса + +
+
+ +
+
+
Полный вертикальный кадр экрана inference
+
+
+ Предыдущая версия экрана inference в проекте +
Предыдущая версия inference
+
+ + + +

Полноэкранный режим и импорт

+

+ Речь не о «длинных задачах», а о процессах в отдельном контексте: одни до завершения блокируют работу с проектом, другие идут параллельно в отдельном окне, и при этом можно продолжать настраивать параметры проекта. Функционал вынесли в отдельное окно, потому что точек входа в такие задачи было несколько, а обычной модалки было недостаточно — нужно было пройти отдельный процесс в стороне и затем вернуться к настройкам проекта. Такой подход сократил объём разработки и тестирования. +

+

+ Ниже — три варианта полноэкранного холста: импорт в отдельном окне, режим с панелями и минималистичный «zen». +

+
+ Модальное окно импорта датасета на отдельном экране +
Импорт в модальном окне
+
+
+ Полноэкранный режим с боковыми панелями +
Полноэкранный режим с панелями
+
+
+ Полноэкранный режим без отвлекающих панелей +
Минимальный режим без лишнего chrome
+
+ +

Дальнейшее развитие

+

+ В дорожной карте оставались отдельные крупные куски: сценарии вокруг LLM (списки, статусы, действия), пошаговый мастер обучения с прогрессом и отменой, а также полноценный контур OCR с разметкой регионов и превью качества на странице. Они не входили в минимальный набор для первого промышленного релиза интерфейса, но заложенные паттерны должны их принять без ломки навигации. +

+
+ +
+

Процесс и передача

+

+ Работа шла через регулярные синхронизации с разработкой: макеты, спецификации и поэтапный handoff во фронт. После моего выхода из проекта команда искала следующего дизайнера и выстраивала онбординг по уже оформленным артефактам и правилам компоновки. +

+ +

Вопросы следующему дизайнеру

+
    +
  • Что оказалось неочевидным в первые две недели в проекте.
  • +
  • Какие артефакты и правила передачи пригодились больше всего.
  • +
  • Что пришлось пересобрать и по какой причине.
  • +
  • Как в трёх предложениях описать текущее состояние UX.
  • +
+
+ +
+

Итог

+

+ Интерфейс AI Server в Primo RPA перевели от «инженерного интерфейса разработчиков» к продукту с понятной логикой настройки и сопровождения пользователя. Упор на юзерфлоу и автоматизацию рутины снял часть нагрузки с внедрения и открыл дорогу к более широкому использованию внутри компании и у клиентов. +

+
+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + diff --git a/public/cases/ai-platform-primo-rpa.html b/public/cases/ai-platform-primo-rpa.html new file mode 100644 index 0000000..1e9c811 --- /dev/null +++ b/public/cases/ai-platform-primo-rpa.html @@ -0,0 +1,1138 @@ + + + + + + + AI Server в Primo RPA — кейс + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Product Design · AI

+

Разработка интерфейса для Primo RPA AI Server

+

+ Платформа интеллектуальной обработки документов
+ и оркестрации ИИ-агентов +

+ +
+

Обзор

+

+ Продукт AI Server разворачивается на внутренних серверах клиентов. Он позволяет использовать нейросети во внутреннем контуре компании и настраивается через веб-интерфейс. +

+

+ Меня пригласили на проект как UX/UI-дизайнера. Продукт был в активной стадии тестирования; по обратной связи от клиентов стало ясно, что настройка слишком сложна: с ней справляются только эксперты и команда внедрения Primo RPA. Сложная настройка снижала привлекательность продукта и тормозила масштабирование. +

+

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

+ +

+ Ниже — погружение в продукт, примеры выполненных задач и паттерны интерфейса. +

+
+ +
+

Погружение

+

+ Работу начал со знакомства с командой: кто за продукт, кто за внедрение, как всё устроено сейчас. Пообщался с экспертами по настройке, разделил ключевые и вспомогательные сценарии, собрал визуализацию поведения пользователя. Плотно работал с разработкой и искал, где интерфейс можно упростить и ускорить настройку. +

+ +

+ Продукт уже использовали клиенты, поэтому нельзя было остановить разработку и пересобрать интерфейс целиком. Пришлось решать, в каком порядке и какие части трогать в редизайне. Самые крупные изменения встраивал в текущий план разработки, без отрыва от релизов. +

+

+ Прорабатывать изменения в интерфейсе нужно было с учётом используемого фреймворка. На тот момент это был + Ant Design под React со стилизацией под + Hope UI. +

+

+ Новые компоненты приходилось придумывать только в крайних случаях, в приоритете было переиспользовать уже существующую библиотеку. По итоговым экранам это видно: интерфейс в основном собран из готовых блоков, а не с нуля. +

+
+ +
+

Выполненные задачи

+

+ Фрагменты интерфейса, которые я переработал или собрал почти с нуля. Ниже — отдельные задачи из проекта, которые хотелось показать в портфолио, а не обзор всего продукта. +

+ +

Главная навигация сервиса

+

+ В сервисе стояла привычная для админок схема: слева боковое меню, справа контент. На скриншоте видно, что такая структура страницы неэффективно использовала доступное рабочее пространство на экране. Если открыть проект, слева окажется навигация по разделам проекта — вперемешку с главной, и это путает пользователя. Эту ситуацию нужно было исправить. +

+
+ Предыдущая главная навигация сервиса AI Server +
Предыдущая навигация
+
+
+ Обновлённая главная навигация сервиса AI Server +
Обновлённая навигация
+
+

+ Обновлённая навигация стала компактной и всё так же привычна большинству пользователей. Для контентной части пространства стало значительно больше. Как будет видно дальше, у проектов внутри появится отдельная навигация, которая не будет перекрывать главную. При этом улучшилась эстетическая составляющая дизайна сервиса. +

+

Навигация внутри конкретного проекта

+

+ У пользователя остаётся доступ и к навигации внутри проекта, и к главной навигации сервиса. Разные типы проекта содержат разное количество пунктов, и такое решение позволяет удачно их разместить. +

+
+ Навигация внутри NLP-проекта и главная навигация сервиса +
NLP-проект
+
+
+ Навигация внутри OCR-проекта и главная навигация сервиса +
OCR-проект
+
+

+ Отдельно отмечу идею с формой пунктов навигации. По виду она мягко подсказывает, что настройку удобнее проходить по шагам, но разделы по-прежнему работают как обычные табы: можно переключаться в любом порядке. +

+
+ Вторичная навигация проекта со стрелочной формой пунктов +
Форма пунктов навигации
+
+

Редактор разметки датасета

+

+ На этом экране проводят больше всего времени. Разметка полей на сотнях изображений — монотонная работа, но от неё зависит, насколько качественными будут данные для обучения модели. Прежний редактор сильно выбивался из общего стиля сервиса: выглядел перегруженно и местами сбивал с толку, особенно в работе с полями. +

+
+ Редактор датасета — предыдущая версия для сравнения +
Предыдущая версия редактора датасета
+
+

+ Я разобрал редактор на микросценарии, выстроил их по приоритету и связке между собой. С командой обсудили, как сделать поведение пользователя плавнее и понятнее. В новой структуре страницы заложил место под новый функционал и те же паттерны, что в остальном сервисе. Дизайн редактора привёл к общей стилистике. +

+
+ Редактор датасета — текущая версия интерфейса +
Обновлённая версия редактора датасета
+
+

+ На схематическом наброске видно, что страница стала симметричной: почти всё пространство уходит на размечаемое изображение. Действия сгруппированы по панелям — нужную функцию проще найти. +

+
+ Вайрфрейм редактора датасета — режим по умолчанию +
Каркас: режим по умолчанию
+
+

+ Добавил режим «Во весь экран». Продвинутые пользователи обычно прячут лишние панели и работают с разметкой через горячие клавиши и нижнюю панель. Боковые панели можно свернуть, когда нужно больше места под изображение — на небольших мониторах это особенно имеет значение. +

+ + +

+ Нижняя панель позволяет переключаться между изображениями и выполнять быстрые действия. +

+
+ Главная панель инструментов редактора датасета +
Нижняя панель инструментов
+
+ +

Карточки настройки обучения модели

+

+ После разметки датасета модель можно дообучить (fine-tuning). Мы с командой, как обычно, разобрали все действия пользователя для этой задачи. Сделали несколько вариантов компоновки этой страницы; самым удачным оказался вариант с лентой из карточек. +

+
+ Обзор карточек настройки обучения в проекте +
Вид раздела обучения моделей
+
+

+ В начале ленты у пользователя карточка с настройкой обучения: через неё видно результат разметки активного датасета, задают параметры и запускают fine-tuning. +

+
+ Карточка настройки обучения +
Карточка настройки обучения
+
+

+ В карточке отдельный блок с оценкой качества разметки датасета и блок с параметрами перед запуском обучения. +

+ +

+ Под каждый запущенный процесс ниже появится отдельная карточка. Можно завести несколько процессов с разными параметрами и потом сравнить, какая конфигурация сработала лучше. +

+
+ Карточка процесса обучения модели +
Карточка процесса обучения
+
+

+ Внутри карточки информация и действия разнесены по логическим блокам. Мы рассматривали разные варианты компоновки и в итоге зафиксировали схему, которая оказалась удобнее остальных. +

+
+ Вайрфрейм карточки процесса обучения +
Вайрфрейм карточки процесса обучения
+
+

+ Карточки могут быть свёрнуты. Для удобства в шапку вынесены название и статус. +

+
+ Свёрнутая карточка настройки обучения +
Свёрнутая карточка
+
+

+ После проработки этих карточек появились паттерны, которые потом использовались в других разделах продукта. Так проще держать интерфейс в едином стиле. +

+ +

Настройка параметров полей

+

+ На одной из страниц раздела проекта нужно было дать возможность настроить уникальные параметры полей для датасета. Редактору требовалась большая область под изображение (скан документа), могло быть десятки полей, у каждого — свои зависимые параметры и типы. +

+

+ На видео — работа прототипа готового решения. +

+
+
+ +
+
Сопоставление полей в интерфейсе
+
+

+ Интерфейс получился компактным и лаконичным. Механика не считывается с первого взгляда, но после короткого обучения пользователю в нём комфортно. +

+

+ Редактор для меня оказался интересной и сложной задачей: было много черновиков и вариантов поведения. В финале остался вариант, который закрывал все требования, которые мы с командой сформулировали. +

+ +

Модальные окна на отдельном экране

+

+ В сервисе часть задач нужно выполнять параллельно с остальной работой. Для таких сценариев сделали так: модальное окно открывается на отдельной странице. +

+
+ Модальное окно импорта датасета на отдельном экране +
Импорт датасета в модальном окне
+
+

+ На странице проекта отображается заглушка: процесс идёт, рядом кнопка перехода к нему. +

+
+ Импорт датасета внутри проекта +
Импорт датасета внутри проекта
+
+

+ Такие заглушки есть в нескольких разделах проекта — в зависимости от того, можно ли с ним работать, пока задача активна. +

+ +

+ Такой вариант оказался технически проще, чем точечно блокировать кнопки на отдельных страницах. +

+ +
+ +
+

Передача в разработку

+

+ Раз в неделю команда собиралась на обсуждение дизайна. Созвоны были длительными, но продуктивными. На неделю формировали список задач для дизайна, приоритеты и сроки подстраивали под планы релизов. +

+

+ Я делал дизайн в Figma, в разработку передавал ссылки на готовые юзерфлоу. Отдельную дизайн-систему или UI-kit не заводили: в продукте уже был готовый фреймворк. +

+

+ Время от времени созванивался с верстальщиком тет-а-тет, если нужно уточнить детали по макетам или объяснить поведение интерфейса. После вёрстки давал фидбэк на правки, чтобы результат не отличался от задуманного поведения и вида интерфейса. +

+
+ +
+

Смена дизайнера

+

+ Проект вёл параллельно с другими, нагрузку приходилось распределять. В компанию наняли нового дизайнера — моя задача была ввести её в курс дела и курировать результат по задачам. После адаптации работа над проектом полностью перешла под её ответственность. +

+
+ +
+

Итог

+

+ Интерфейс Primo RPA AI Server стал выглядеть консистентно. С ним могут работать пользователи, которые ещё не эксперты в области ИИ. Для будущих изменений в интерфейсе заложена возможность наращивать функционал без больших переделок. +

+
+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + diff --git a/public/cases/design-system.html b/public/cases/design-system.html new file mode 100644 index 0000000..933ea8a --- /dev/null +++ b/public/cases/design-system.html @@ -0,0 +1,1046 @@ + + + + + + + Design System — портфолио + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Документация · UI

+

Design System

+

Токены, типографика, сетка, компоненты и блоки лонгрида кейса

+

+ Переключайте тему, акцент и шрифт через плавающую панель справа. При глобальных правках стилей (токены, + компоненты, блоки лонгрида) обновляйте и эту страницу — живой каталог UI проекта. +

+ + + +

Цвета

+

+ Акцент и «холод/тепло» всего UI задаются тремя числами в модели HSL (Hue — оттенок, + Saturation — насыщенность, Lightness — светлота) на <html>. Из них собирается + --accent и производные токены; нейтральные фоны слегка подмешивают тот же оттенок + (--neutral-accent-tint). Светлая/тёмная тема — data-theme, mesh — + data-mesh-bg. Меняется в FAB справа. +

+

Что такое --theme-h, --theme-s, --theme-l

+
    +
  • + --theme-h — оттенок (Hue), позиция на цветовом круге 0–360°. Сдвиг hue + перекрашивает кнопки, ссылки, mesh-градиент и квадратные акценты (--accent-square-2 … + 4), не трогая вручную каждый hex. +
  • +
  • + --theme-s — насыщенность: насколько «чистый» цвет, а не серый. +
  • +
  • + --theme-l — светлота акцента: темнее или ярче основной фирменный тон + (в панели обычно ограничен диапазоном, чтобы кнопки оставались читаемыми). +
  • +
+

+ В CSS это выглядит так: + --accent: hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)). + Значения пишутся в localStorage (siteThemeV1) и подставляются inline-скриптом в + head, чтобы не было вспышки «чужого» цвета при загрузке. +

+
+
+
+ --bg +
+
+
+ --bg-elevated +
+
+
+ --surface +
+
+
+ --text +
+
+
+ --text-muted +
+
+
+ --line +
+
+
+ --accent +
+
+
+ --accent-text +
+
+
+ --accent-soft +
+
+

+ Дополнительно: квадратичные оттенки mesh — --accent-square-2 … 4; они зависят от hue. +

+ +

Шрифты

+

+ Пара шрифтов — data-font на <html> (FAB «Типографика»): задаёт + --font-accent (заголовки) и --font (проза). Шкала в таблицах: класс, пример, назначение. +

+

Семейства

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
data-fontСтекГде
merriweatherMerriweather + AliceПара по умолчанию; Alice — основной текст, Merriweather — акцентные заголовки
monoSource Code Pro + PT MonoМоноширинная пара
geologicaGeologica + PT SansГротеск + нейтральная проза
+
+ +

Типографическая шкала

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
КлассПримерНазначение
.hero__eyebrow

Подпись секции

Hero, ввод кейса
.hero__title +

+ Display заголовок +

+
H1 главной; на DS уменьшен для колонки
.section__title

Секция

«Навыки», «Портфолио», контакты; основной шрифт, без капса
.case-page__h1

Заголовок страницы

H1 кейса / Design System
.case-page__sub

Лид под заголовком

Подзаголовок под H1
.section__prose

Основной текст абзаца.

Проза, списки, ссылки в статье
h2 в .case-article

Подсекция H2

Разделы лонгрида (как «Цвета»)
h3 в .case-article

Подсекция H3

Подразделы внутри H2; отступы в main.css: сверху 3.25rem, снизу 1.5rem, после figure 4rem, h3+h3 3.5rem
+
+ +

Ритм и код

+

Пример ритма:

+
    +
  • маркированный список;
  • +
  • акцент и ссылка;
  • +
+
    +
  1. нумерованный пункт;
  2. +
+

Инлайн code и блок:

+
--font: "Alice", system-ui, serif;
+--font-accent: "Merriweather", var(--font);
+

+ Заголовки используют clamp() — масштаб от вьюпорта; подробнее в разделе «Сетка». +

+ +

Сетка и адаптив

+

+ Отдельной 12-колоночной сетки нет: full-bleed layout с боковыми полями + --space и локальными CSS Grid внутри секций. Контентная колонка DS и кейсов — + .case-article (max-width 48rem). +

+ +

Базовый каркас

+
    +
  • --space: clamp(1rem, 4vw, 2.75rem) — горизонтальные поля + safe-area-inset.
  • +
  • --max: none — без фиксированной «коробки» 1200px; ширина = вьюпорт минус padding.
  • +
  • .section — вертикальные отступы через clamp(); .section__inner центрирует блок.
  • +
  • .section--tight — компактнее по вертикали (кейсы, эта страница).
  • +
+ +

Брейкпоинты

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОтЧто меняется
860px.hero__grid → 2 колонки 1.15fr 0.85fr
760px / 1180px.projects-carousel: --projects-visible 1 → 2 → 3 карточки
720px.skills-category__grid → 2 колонки
1024pxНавыки: 6-колоночная мозаика (grid-column: span …)
560px / 1024px.contact-grid → 2 → 4 колонки
48rem / 28remГалерея кейса: ≤2 col → 1 col
640pxcase-media-gallery--wide схлопывается в ширину колонки
+
+ +

Hero: одна → две колонки

+

Схема .hero__grid (сжато до 860px):

+ + +

Контакты: 1 → 2 → 4

+

Демо .contact-grid (плейсхолдеры, без переходов):

+ +

+ Навыки: мозаика на широком экране — см. + главную, #skills. Портфолио: карусель на + 100vw с --projects-card-width и JS-прокруткой — на главной + #projects. +

+ +

Wide в кейсах

+

+ .case-media--wide, .case-media-gallery--wide и .case-callout шире + колонки статьи: min(100vw − 2×padding, content + 8rem), с полями --space. На узком + экране (до 640px) wide схлопывается в ширину колонки. Кадры с data-image-viewer — обводка и hover + как у .case-video-shell (живые примеры — демо элементов кейса). Подпись под видео — + figcaption по центру колонки. +

+ +

Типографика и motion

+

+ Fluid type: clamp() на .hero__title, .section__title, + .case-page__h1. Скругления (data-radius) сетку не меняют. Для длинных скринов и + анимаций учитывается prefers-reduced-motion: reduce. +

+ +

Компоненты

+

Живые примеры; оболочка (шапка, FAB, футер, cookie) уже подключена на этой странице.

+ +

Кнопки

+ +

.btn .btn--primary | secondary | ghost · .btn--flat | raised · .btn__icon

+ +

Теги

+
    +
  • hero__tag
  • +
  • UX/UI
  • +
+

.hero__tags / .hero__tag

+
    +
  • portfolio-card__tag
  • +
  • Web App
  • +
+

.portfolio-card__tags / .portfolio-card__tag

+ +

Карточка портфолио

+ +

.portfolio-card и дочерние BEM-классы

+ +

Заглушка при загрузке изображений

+

+ Пока img ещё не загрузился, initImageLoadPlaceholder вешает + .is-img-loading на картинку и .has-img-loading на обёртку. Слой фона — + ::before, один блеск слева направо — ::after (img-ph-shine-sweep). + Иконки, SVG и мелкие картинки до 40px пропускаются; + отключить точечно: data-no-img-placeholder. Ниже — зафиксированное демо (на сайте классы снимаются + после load). +

+ +

.has-img-loading · .is-img-loading · .img-ph-demo (демо заглушки)

+ +

Карточка навыка

+
+

skill-task-card__task — формулировка задачи от бизнеса.

+
+

skill-task-card__solution — первый подход к решению.

+

Второй пункт в зоне решений.

+
+
+

.skill-task-card__task · __solutions · __solution

+ +

Callout

+

+ Акцентный блок лонгрида: шире колонки (как wide-медиа), текст в .case-callout__content чуть + крупнее основного абзаца. +

+ +

.case-callout · .case-callout__emoji · .case-callout__emoji--pulse · .case-callout__content

+ +

Контактные карточки

+

+ На главной в сетке четыре карточки (1→2→4 колонки). Здесь два примера — сетка принудительно в две колонки. +

+ +

.contact-card--link · --action · --brand-*

+ +

Секция с фоном

+

+ На главной полоса .section--surface визуально читается через mesh; в кейсах фон страницы + ровный — ниже компактное демо с background: var(--surface). +

+
+
+

section__title

+

Фрагмент .section.section--surface + .section__inner

+
+
+

.section · .section--surface · .section--tight · .section__inner

+ +

Блоки

+
+

+ Разметка лонгрида кейса: медиа и галереи, карточки ссылок, видео, callout, wide-блоки и прочие partials. + Живой эталон со всеми вариантами — на отдельной странице; оттуда копируют куски при сборке нового кейса. +

+

+ Демо элементов кейса +

+
+ +

Активность

+
+

+ На главной в секции #mini-projects карточки mp-card в masonry-сетке. Типы, клетки и живая + раскладка вынесены на отдельную страницу. +

+

+ Каталог карточек активности +

+
+
+
+ + + + + + + + + + + + diff --git a/public/cases/lunacy.html b/public/cases/lunacy.html new file mode 100644 index 0000000..2a42de1 --- /dev/null +++ b/public/cases/lunacy.html @@ -0,0 +1,926 @@ + + + + + + + Lunacy — кейс + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Icons8 · desktop

+

Графический редактор Lunacy

+

+ Работа над интерфейсом Lunacy в команде Icons8: user flow, прототипы сложных сценариев, доработка функциональности и + визуальной логики. Ниже — фрагменты экранов из процесса (порядок кадров ориентирован на имена файлов). +

+

+ Продукт: icons8.com/lunacy +

+ +

Обзор

+

Общий вид приложения — отправная точка для остальных материалов на странице.

+
+ Обзор приложения Lunacy +
Обзор окна Lunacy.
+
+

Дальше — отдельные сценарии и итерации интерфейса в том порядке, в каком удобнее читать по смыслу и по именам файлов.

+ +

Blob: настройки на холсте

+

Работа с blob в контексте холста — отдельный сценарий до разборов панели по версиям.

+
+ Настройки blob на холсте +
blob_settings_on_canvas
+
+

Панель настроек для тех же задач развивалась серией макетов v1–v9 — они собраны в сетку ниже.

+ +

Компоненты и сравнение

+

Сравнение компонентов и индикатор обновлений в панели.

+
+ Модальное окно сравнения компонентов +
compare_components_modal_window
+
+
+ Индикатор обновления компонентов в панели +
components_update_indicator_location_panel
+
+

Два связанных экрана: поиск расхождений и отображение статуса обновлений рядом с навигацией по панели.

+ +

Прототип в панели

+

Создание прототипа на холсте и состояния панели для режима прототипа.

+
+ Модальное окно: создать прототип на холсте +
modal_window_for_prototype_create_on_canvas
+
+
+ Модальное окно: состояния панели прототипа +
modal_window_for_prototype_panel_states
+
+

Оба кадра — про увязку прототипа с холстом и с набором состояний панели.

+ +

Shadow Pro: настройки

+

Блок Shadow Pro: панель, идеи, модалки с авто-включением и выключением.

+
+ Shadow Pro: панель настроек +
shadow_pro_settings_panel
+
+
+ Shadow Pro: идеи +
shadow_pro_settings_ideas
+
+
+ Shadow Pro: модалка, авто включено +
shadow_pro_settings_modal_auto_on
+
+
+ Shadow Pro: модалка, авто выключено +
shadow_pro_settings_modal_auto-off
+
+

Четыре кадра подряд показывают развитие одного подпроекта: от панели и набросков к уточнению поведения в модалках.

+ +

Панель настроек blob: версии v1–v9

+

+ Итерации панели по именам файлов blob_settings_panel_v1 … v9. Сетка на ширине текста, три колонки на + широком экране; при сужении окна число колонок уменьшается автоматически. +

+ +

Сетка удобна для сравнения шага к шагу; для деталей клик по ячейке открывает полноэкранный просмотр.

+ +

Слайдер: версии v1–v18 и кадр 14

+

+ Порядок по именам: slider_v1 … slider_v13, затем slider_14 (в ассете без суффикса v), + затем slider_v15 … slider_v18. +

+ +

Такой ряд полезен при разборе эволюции контрола: от ранних раскладок до финальных состояний.

+ +

Слайдеры: общий кадр

+

Сводный экран по слайдерам — после ряда по версиям.

+
+ Все слайдеры: общий вид +
sliders_all_set
+
+

Завершает блок про слайдеры: контекст, как несколько контролов сосуществуют на одном экране.

+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + diff --git a/public/cases/manu-game-maker.html b/public/cases/manu-game-maker.html new file mode 100644 index 0000000..8855b2e --- /dev/null +++ b/public/cases/manu-game-maker.html @@ -0,0 +1,668 @@ + + + + + + + Игровой движок MANU — кейс + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Product Design · Desktop App

+

Игровой движок MANU

+

+ Редизайн и развитие интерфейса: новая концепция работы, обновлённая визуальная система и сотни проработанных пользовательских сценариев. +

+

+ Работа велась вокруг десктопного редактора и связанных панелей: нужно было удержать целостность визуального языка при росте функциональности и не потерять опытные сценарии силовых пользователей. +

+

+ Развёрнутый лонгрид кейса появится на этой странице позже; ниже — обложка для навигации из портфолио. +

+

Обложка

+
+ Интерфейс игрового движка MANU — обложка кейса +
Текущее превью для карточки портфолио
+
+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + diff --git a/public/cases/mini-projects-showcase.html b/public/cases/mini-projects-showcase.html new file mode 100644 index 0000000..38d809b --- /dev/null +++ b/public/cases/mini-projects-showcase.html @@ -0,0 +1,973 @@ + + + + + + + Активность — каталог карточек + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+
+
+

Design System · Активность

+

Карточки активности

+

Все типы карточек и живая сетка для подбора раскладки на главной

+

+ Страница для верстки и контента: здесь те же классы и скрипты, что в секции на главной. Меняйте шрифт и тему в панели + справа, сужайте окно — сетка пересчитается. Подписи в заголовках карточек — подсказки, в проде их убрать. +

+ + + +

Как пользоваться

+

+ Сначала выберите тип (stack, horizontal, compact, decor), затем data-mp-cells (1–3) и + порядок li в списке. Карточки с data-mp-extra не влияют на высоту списка до кнопки «Показать все». + Подробности — в docs/mini-projects-cards.md. +

+ +

Типы карточек

+

+ Слева пример карточки с текстом, справа название типа и пояснение по классам. +

+
+
+ +
+

+ Stack со ссылкой. Превью на всю ширину, текст снизу. Для внешней ссылки: + mp-card--link и mp-card__ext в заголовке (как в блоке опыта). +

+
+
+ +
+
+

mp-card--stack без ссылки

+
+ +
+

Stack без ссылки

+
    +
  • заметка
  • +
+

+ Связка баз и rollup для недельного обзора, только для личного пользования. +

+
+
+
+
+

+ Stack без ссылки. Тот же вид. Обёртка div или article, без + mp-card--link. +

+
+
+ +
+ +
+

+ Horizontal со ссылкой. Миниатюра слева, текст справа. На узком экране карточка + складывается в столбик. +

+
+
+ +
+
+

mp-card--horizontal без ссылки

+
+ +
+

Horizontal без ссылки

+
    +
  • шаблон
  • +
+

+ Статический сайт с расписанием и формой заявки на отдельном сервисе. +

+
+
+
+
+

+ Horizontal без ссылки. Тот же расклад, карточка не ведёт на внешний URL. +

+
+
+ +
+ +
+

+ Compact со ссылкой. Только текст, без mp-card__media. В сетке часто с + data-mp-cells="1". +

+
+
+ +
+
+

mp-card--compact без ссылки

+
+
+

Compact без ссылки

+
    +
  • документ
  • +
+

+ Markdown-список проверок перед релизом мелких правок в интерфейсе. +

+
+
+
+
+

+ Compact без ссылки. Короткая заметка или чеклист без внешней ссылки. +

+
+
+ +
+
+

mp-card--decor

+ +
+
+

+ Декоративная ячейка. Заглушка в сетке, без проекта и ссылки. Внутри + span.mp-card__decor-pattern. +

+
+
+
+ + +

Ширина в клетках

+

+ Атрибут data-mp-cells на li.mini-projects-grid__item задаёт желаемую ширину от 1 до 3 клеток. + Скрипт не даст карточке быть шире текущего ряда. +

+
+ +

Ряд из 6 клеток (широкий экран)

+
+
3
+
3
+
+
+
2
+
2
+
2
+
+
+
1
+
2
+
3
+
+
+ Цифра в блоке = значение data-mp-cells. Карточка занимает столько клеток подряд в одном ряду. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Ширина спискаКлеток в ряду
≥ 1180px6
≥ 880px4
≥ 520px2
уже1 (вся строка)
+

+ На шести клетках пара 3 + 3 или тройка 2 + 2 + 2 обычно смотрится ровнее случайного набора. + Декор (mp-card--decor) заполняет пустоты в сетке. +

+
+
+
+ +
+
+

Живая сетка masonry

+

+ Демо блока «Активность» с главной: здесь все типы карточек в одной живой сетке. В подписях у каждой — тип + раскладки и data-mp-cells. Меняйте ширину окна и шрифт в панели темы, смотрите, как сетка + перестраивается, и переносите удачный порядок на главную. +

+
    +
  1. + + +
    +

    + [2] stack · ссылка + +

    +
      +
    • веб-сайт
    • +
    +

    Базовая пара в ряду из шести клеток.

    +
    +
    +
  2. +
  3. +
    + +
    +

    [2] stack

    +
      +
    • заметка
    • +
    +

    Stack без внешней ссылки.

    +
    +
    +
  4. +
  5. +
    + +
    +

    [2] horizontal

    +
      +
    • утилита
    • +
    +

    Horizontal на две клетки, без ссылки.

    +
    +
    +
  6. +
  7. +
    +
    +

    [2] compact

    +
      +
    • шаблон
    • +
    +

    Текстовая карточка на две клетки.

    +
    +
    +
  8. +
  9. + +
    +

    + [1] compact · ссылка + +

    +
      +
    • cli
    • +
    +

    Узкая колонка со ссылкой.

    +
    +
    +
  10. +
  11. +
    +
    +

    [1] compact

    +
      +
    • документ
    • +
    +

    Compact на одну клетку.

    +
    +
    +
  12. +
  13. + +
  14. +
  15. + + +
    +

    + [3] stack · ссылка + +

    +
      +
    • приложение
    • +
    +

    + Половина шестиклеточной строки. Длиннее описание, чтобы проверить перенос и высоту после смены шрифта. +

    +
    +
    +
  16. +
  17. + + +
    +

    + [3] horizontal · ссылка + +

    +
      +
    • плагин
    • +
    +

    Широкий horizontal: превью и текст в одной полосе.

    +
    +
    +
  18. +
  19. +
    + +
    +

    [3] horizontal

    +
      +
    • виджет
    • +
    +

    Horizontal на три клетки, без ссылки.

    +
    +
    +
  20. +
+ +
+
+
+ + + + + + + + + + + diff --git a/public/cases/mobile-clinic-app.html b/public/cases/mobile-clinic-app.html new file mode 100644 index 0000000..38ff7cc --- /dev/null +++ b/public/cases/mobile-clinic-app.html @@ -0,0 +1,668 @@ + + + + + + + Мобильное приложение для сети клиник — кейс + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

UX/UI · Mobile App

+

Мобильное приложение для сети клиник

+

+ Запись к врачам и работа с медицинскими услугами: простой путь пользователя, понятная навигация и быстрый доступ к действиям. +

+

+ Фокус проекта — снять тревожность и лишние шаги у пациента: ясные статусы записи, предсказуемые формы и опора на привычные паттерны мобильных приложений. +

+

+ Полный разбор кейса будет опубликован здесь; пока страница служит точкой входа из блока портфолио на главной. +

+

Обложка

+
+ Мобильное приложение для сети клиник — обложка кейса +
Текущее превью для карточки портфолио
+
+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + diff --git a/public/cases/obsidian-plugin-columns-view.html b/public/cases/obsidian-plugin-columns-view.html new file mode 100644 index 0000000..b97cbb7 --- /dev/null +++ b/public/cases/obsidian-plugin-columns-view.html @@ -0,0 +1,702 @@ + + + + + + + Колоночный вид для Obsidian — кейс + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Obsidian · Plugin

+

Колоночный вид — плагин для Obsidian

+

Дизайн и разработка интерфейса для многоколоночной работы с заметками

+ +

+ +

+ +

Контекст

+

+ +

+ +

Задача

+

+ +

+ +

Решение

+

+ +

+ +

Фильтр использования

+
+
+ +
+
Фильтрация заметок в колоночном виде.
+
+ +

Конфигурация отображения

+
+
+ +
+
Настройка колонок и отображения.
+
+ +

Результат

+

+ +

+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + diff --git a/public/cases/orc-automation-panel.html b/public/cases/orc-automation-panel.html new file mode 100644 index 0000000..9f53dee --- /dev/null +++ b/public/cases/orc-automation-panel.html @@ -0,0 +1,806 @@ + + + + + + + Веб-панель для оркестрации автоматизаций — кейс + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Primo RPA · UX/UI · Web App

+

Веб-панель для оркестрации автоматизаций

+

+ Оркестратор Primo RPA: запуск роботов, проекты и контроль процессов в веб-кабинете для админов и разработчиков автоматизаций. +

+ +
+

Контекст

+

+ В стеке Primo RPA оркестратор отвечает за расписание, очередь и статусы RPA-роботов на инфраструктуре клиента. С ним работают не только из студии разработки, но и из браузера: смотрят проекты, перезапускают задания, разбирают сбои. +

+

+ К тому моменту продукт уже был в эксплуатации, но интерфейс заметно устарел: пользователи сталкивались с неудобствами в навигации, визуальным шумом в таблицах и неочевидными сценариями в некоторых разделах. Задача стояла освежить вид интерфейса, сделать его современным и исправить накопившиеся UX-проблемы. +

+
+ +
+

Роль и подход

+

+ Моя роль в этом проекте была скорее кураторской — я не делал дизайн самостоятельно, а выстраивал процесс так, чтобы команда дизайна и разработки работала слаженно. +

+ +

+ Параллельно я искал дизайнера, который взял бы на себя основную визуальную работу. Отбор прошла Елизавета — среди более чем 150 заявок она лучше всего подходила под предстоящий фронт работ. +

+

+ В течение трёх месяцев я погружал новую сотрудницу в детали проекта: ставил задачи, давал обратную связь по создаваемым макетам, делился контекстом по пользовательским сценариям. Вместе с командой разработки мы планировали порядок обновления дизайна сервиса — меняли экраны по приоритету, вкладывая изменения в текущие релизы, без «остановить всё и перерисовать». +

+
+ +
+

Технический стек и инструменты

+

+ В качестве фреймворка для интерфейса был выбран Ant Design последней версии. Он уже использовался в проекте, и его свежий релиз предлагал Theme Editor — возможность настраивать внешний вид компонентов через дизайн-токены без переопределения стилей вручную. Это давало и дизайнерам, и разработчикам единый язык описания интерфейса. +

+

+ Единым источником правды и мостом между дизайном и разработкой стал Storybook. В нём компоненты были не просто задокументированы, а реально работали в изолированной среде — это позволяло дизайнерам видеть реализацию элементов вживую, а разработчикам — быстрее интегрировать компоненты в панель. +

+
+ +
+

Дизайн-система и синхронизация

+

+ Для удобства работы мы синхронизировали токены из Ant Design с токенами в Figma — цвета, отступы, типографика и радиусы скругления были приведены к единым значениям. Работало это так: если в Figma токены обновлялись, их можно было выгрузить в JSON и без проблем сразу загрузить в код — вместо того, чтобы разработчик вручную искал изменения и правил каждый токен индивидуально. Такой подход также позволил смотреть на дизайн более системно. +

+ +

+ Компоненты в Figma создавались с нуля — по референсам Ant Design, но без использования готовых библиотек. Отказ от готовых решений был осознанным: нам нужна была полная настройка под наш стиль работы и возможность использовать новые функции Figma, которые не поддерживались в библиотеках из сообщества Figma. +

+

+ Для Storybook мы отобрали и настроили плагины, которые были уместны для наших задач — контроль доступности, просмотр состояний компонентов, переключение тем и локалей. Это сделало Storybook не просто витриной компонентов, а полноценным инструментом дизайн-ревью. +

+
+ +
+

Рабочая среда дизайнера

+

+ Мы настроили среду так, чтобы дизайнер мог видеть реализацию компонентов вживую у себя на компьютере, используя локальный Storybook и Git. Это позволяло точнее контролировать, как задуманный дизайн воплощается в коде, и оперативно замечать расхождения на ранних этапах. +

+

+ Обсуждался также шаг ускорить поддержку Storybook тем, чтобы дизайнер сам мог описывать JSX для реализованного компонента — это сокращало путь от макета до документированного компонента в сторибуке. +

+

+ Мы отладили рабочий процесс по передаче иконок в библиотеку. Особенность заключалась в том, чтобы иконки можно было отобразить в Storybook с фильтрацией и сортировкой. При этом дизайнер мог обновлять иконки без привлечения разработчика — просто пушил новые файлы в репозиторий. +

+

+ Увидеть обновлённую иконку сразу в браузере позволяло лучше её оптимизировать и убрать косяки отображения при использовании булевых операций. +

+

+ Для Figma также был разработан подход и правила, которые не только ограничивали дизайнера, но и позволяли гарантированно делать консистентные и рабочие иконки. +

+
+ +
+

UX-улучшения

+

+ За время обновления интерфейса Елизавета предложила ещё и ряд улучшений пользовательского опыта. Часть из них была успешно внедрена — например, более понятная группировка элементов в сложных формах и переработанные состояния загрузки. Но в приоритете было не ломать старый UX, к которому привыкли пользователи, поэтому многие идеи сохранились в бэклог для следующей итерации. +

+
+ +
+

Список проектов

+

+ Таблица проектов — один из самых частых экранов. На старой версии много колонок, плотная сетка и мелкий текст: статус и имя проекта читаются с трудом, особенно на ноутбуке. +

+

В новой версии:

+
    +
  • колонки свели к тому, что нужно для ежедневной работы;
  • +
  • статусы и действия вынесли в предсказуемые зоны строки;
  • +
  • отступы и типографику подтянули под остальную панель на Ant Design.
  • +
+ +

Было

+
+ Список проектов в оркестраторе — предыдущая версия таблицы +
+ +

Стало

+
+ Список проектов в оркестраторе — обновлённая таблица +
+
+ +
+

Результаты и рефлексия

+

+ Экран проектов стал проще сканировать: меньше визуального шума, быстрее находить нужный проект и его состояние. После раскатывания нового дизайна среди нескольких клиентов мы получили положительные отзывы и множество идей для дальнейших улучшений. +

+

+ Я оставил проект, когда Елизавета уже уверенно чувствовала себя в нём и могла самостоятельно вести дизайнерские задачи. Периодически я отвечал на точечные вопросы, но в целом передача прошла гладко. +

+

+ Спустя год с небольшим процессы в команде заметно изменились. По словам ребят, в создании и передаче дизайна теперь активное участие принимают инструменты с нейросетями — такие как Claude Design. То, что мы начинали выстраивать вручную через токены, Storybook и синхронизацию сред, сейчас в какой-то мере автоматизируется. +

+

+ Считаю, что проделанная работа была выполнена достаточно оперативно и качественно — в условиях постоянных изменений на рынке и внутри компании нам удалось не просто обновить интерфейс, но и выстроить устойчивый процесс, который продолжил работать уже без моего участия. +

+
+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + diff --git a/public/cases/task-distribution-concept.html b/public/cases/task-distribution-concept.html new file mode 100644 index 0000000..bfdec40 --- /dev/null +++ b/public/cases/task-distribution-concept.html @@ -0,0 +1,668 @@ + + + + + + + Концепт сервиса распределения задач — кейс + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

UX/UI · Analytics

+

Концепт сервиса распределения задач

+

+ Продуктовый концепт: постановка, распределение и отслеживание задач с акцентом на прозрачность процессов и удобство командной работы. +

+

+ Задача концепта — показать, как команда видит поток работ без «чёрных ящиков»: кто что взял, где узкие места и какие статусы критичны для следующего шага. +

+

+ Детальный кейс появится здесь позже; страница уже связана с карточкой в портфолио на сайте. +

+

Обложка

+
+ Концепт сервиса распределения задач — обложка кейса +
Текущее превью для карточки портфолио
+
+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + diff --git a/public/cases/task-tracker.html b/public/cases/task-tracker.html new file mode 100644 index 0000000..f6c8a30 --- /dev/null +++ b/public/cases/task-tracker.html @@ -0,0 +1,1099 @@ + + + + + + + Таск-трекер для бек-офис системы — кейс + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Тестовое задание · back-office

+

Таск-трекер для внутренней бек-офис системы

+

Задание

+

+ Реализовать интерфейс для планирования и распределения задач между сотрудниками операционного отдела, работающими в некой бек-офис системе. Существует большое количество разноплановых задач, которые можно сгруппировать: Тип-1, Тип-2, Тип-3, Тип-4, Тип-5, Тип-6, Тип-7. У каждой задачи есть свой, выставляемый автоматически, приоритет. Пользователю доступны только задачи из определенных категорий. +

+

Нужно реализовать:

+
    +
  • + Общий экран: +
      +
    • где пользователь может посмотреть все открытые общие задачи и взять какие-то себе.
    • +
    • персональный ToDo лист, где отображаются как взятые вручную задачи, так и автоматически назначенные.
    • +
    • у взятой задачи есть возможность передать ее другому сотруднику или вернуть в общий список.
    • +
    +
  • +
  • Экран, где можно посмотреть, что у кого в работе.
  • +
+ +

Введение

+

+ Так как у меня лично есть обширный опыт работы с таск-трекерами, то я опираюсь на свой опыт и опыт моих коллег с учётом требований задания. +

+ +

Референсы

+
+ Референсы +
+
    +
  • Таск-трекеры (Trello, Monday, YouTrack и др.)
  • +
  • Сервисы для визуальной работы с базами данных (Notion, Airtable и др.)
  • +
+ +

Решение

+ +

Скринкаст

+
+
+ +
+
+ + + +

Вкладки (Tabs)

+

На вкладке All tasks сотрудник может ознакомиться со всеми доступными задачами.

+
+ Untitled +
+

+ На вкладке My tasks отображаются только те задачи, что закреплены за текущим сотрудником. Группировка идёт по статусам задач (статус в карточке задачи скрыт). +

+
+ Untitled +
+

На вкладке Task by assign отображены все задачи c разбивкой по исполнителю.

+
+ Untitled +
+

В правой части имеются опции для текущей вкладки.

+
+ Untitled +
+

+ Все изменения сохраняются после ухода с вкладки и после закрытия всей страницы Tasks. Эти настройки индивидуальны и каждый сотрудник может настроить страницу как ему удобно. +

+
    +
  • Group - позволяет создать дополнительную группировку по свойству таски (категория, приоритет, исполнитель, статус, дата создания, дата изменения).
  • +
  • View - позволяет изменить отображение текущих задач на другой вид: доска, список, таблица.
  • +
  • Filter - позволяет скрывать задачи по свойствам.
  • +
  • + Sort - позволяет определять порядок отображения задач по свойствам. Если включена сортировка по статусу High, Medium, Low то можно выбрать либо по алфавиту, либо в обратном порядке, а также можно создать свой порядок. С датами и цифрами работает принцип по возрастанию/убыванию. +
  • +
  • + Search on page - позволяет отобразить только те задачи, в названии или описании которых есть поисковое слово или фраза. (Можно улучшить функционал поиска, добавив поисковые операторы, если исследования докажут эту необходимость) +
  • +
+

+ На странице работает постепенная подгрузка задач. По мере скрола вниз, будут подгружаться новые задачи. Кол-во задач указывается в заголовках, это может быть полезно, чтобы оценить как далеко надо скролить, чтобы все посмотреть. Задач может быть очень много и тогда возможно имеет смысл добавить ещё и переход по страницам. +

+ +

Варианты отображения (Views)

+

+ Разные виды отображения одних и тех же задач могут быть полезны для разных контекстов использования страницы Tasks и также в угоду личным предпочтениям сотрудника, что повышает его эффективность. Сотрудник, которого не раздражает интерфейс работает продуктивнее и приносит больше пользы. +

+
+ Untitled +
+ +

+ Вид Board позволяет удобнее работать с функцией Drag&Drop (см. ниже). Также визуально легче определить кол-во задач в категории, подразумеваю что это может быть полезно. В случае использования группировки задач по статусам выполнения, перемещение карточек слева направо создаёт естественное горизонтальное течение задач из точки А в точку Б. +

+
+ Untitled +
+

+ Вид List позволяет увидеть больше информации на меньшей площади экрана. При этом этот вид визуально и функционально легче табличного вида, а значит меньше когнитивной нагрузки на пользователя. Также здесь все заголовки задач начинаются в крайнем левом положении, поэтому становится легко пробежаться глазами по списку. +

+
+ Untitled +
+

+ Вид Table позволяет сразу же работать со всеми полями задачи, без раскрытия её в модальном окне или отдельной странице. Таблица подразумевает пользовательскую настройку ширины и порядка столбцов, что может быть удобно в некоторых кейсах использования. +

+
+ Untitled +
+ +
+
+ +
+
+ + +

Drag&Drop

+

+ Во всех видах можно перетаскивать элементы (карточки/элементы списка/строки и столбцы таблицы). Это способствует более продуктивной работе и выглядит естественным для пользователя. Например, если требуется раскидать задачи между сотрудниками (для админа или менеджера), поменять статус для нескольких задач разом или в короткий отрезок времени. +

+

Board view

+
+
+ +
+
+ +

List view

+
+
+ +
+
+ +

Продвинутый интерактивный прототип в ProtoPie

+

+ Схематичное представление того как работает Drag&Drop. Такой прототип помогает дизайнеру лучше понять какие нюансы нужно учесть в юзерфлоу, а также и при подготовке спецификации для разработчика. Также попробовав данный прототип можно прийти к тому, что функционал должен работать совсем иначе и переделать его сразу. Это экономит общее время разработки. +

+
+
+ +
+
+ +

+ В прототипе можно перемещать только голубую карточку и не все положения работают корректно. Можно посмотреть запись, которая доступна на той же странице прототипа. +

+ +

Стиль

+

+ Визуальный стиль может быть любым, не меняя самого каркаса. Например, чуть более красочным и с более выразительными шрифтами. +

+

Светлая цветная тема

+
+ Светлая цветная тема +
+ +

Нейтральная тёмная тема

+
+ Нейтральная тёмная тема +
+ + +

Исследования

+

+ На этапе прототипов Figma можно провести интервью с несколькими сотрудниками, например 5 человек. Предварительно в прототип нужно добавить реальные задачи из текущей системы, порядка 20 должно хватить. Далее можно созвониться по видеосвязи с шэрингом экрана респондента или встретиться лично и задать несколько заданий и вопросов. Во время сессии респондент может тыкать в прототип, но если что-то не сработает интервьюер может зафиксировать попытку и объяснить, что этот функционал пока не работает, а также поинтересоваться что респондент ожидает увидеть дальше. +

+

Задания

+
    +
  1. Найти свои актуальные задачи со страницы Tasks вкладки All tasks
  2. +
  3. Назначить себе задачи, чтобы взять в работу
  4. +
  5. Найти задачу про что-то конкретное (интервьюер приводит пример), которую он уже выполнил ранее
  6. +
  7. Показать задачи, которые относятся только к определённой категории и должны быть сделаны до конца недели
  8. +
  9. Попросить поменять приоритет у нескольких задач одновременно
  10. +
  11. Оценить визуальную привлекательность интерфейса по шкале от 1 до 10
  12. +
  13. Оценить общее впечатление от предложенного концепта по шкале от 1 до 10
  14. +
  15. Предложить ещё функции, которые были бы полезны
  16. +
+

Аналитика

+

Для оценки актуальности реализованного функционала необходимо собирать следующие показатели.

+
    +
  • + Кол-во просмотров страницы Tasks page_views_tasks с возможностью разбиения +
      +
    • + по вкладкам +
        +
      • All tasks all_tasks_tab
      • +
      • My tasks my_tasks_tab
      • +
      • Tasks by assign tasks_by_assign
      • +
      +
    • +
    • + по ролям +
        +
      • Admin admin
      • +
      • Manager manager
      • +
      • User user
      • +
      +
    • +
    • + по попыткам поиска +
        +
      • Search Used search used
      • +
      +
    • +
    +
  • +
  • + Кол-во включённых пользовательских настроек Custom Settings custom_settings с возможностью разбиения +
      +
    • + по вкладкам +
        +
      • All tasks all_tasks_tab
      • +
      • My tasks my_tasks_tab
      • +
      • Tasks by assign tasks_by_assign
      • +
      +
    • +
    • + по ролям +
        +
      • Admin admin
      • +
      • Manager manager
      • +
      • User user
      • +
      +
    • +
    • + по типам +
        +
      • Group group
      • +
      • Filter filter
      • +
      • Sort sort
      • +
      +
    • +
    +
  • +
  • + Кол-во включенных видов View Used view_used с возможностью разбиения +
      +
    • + по вкладкам +
        +
      • All tasks all_tasks_tab
      • +
      • My tasks my_tasks_tab
      • +
      • Tasks by assign tasks_by_assign
      • +
      +
    • +
    • + по ролям +
        +
      • Admin admin
      • +
      • Manager manager
      • +
      • User user
      • +
      +
    • +
    +
  • +
+

+ Далее в течение полугода (может и раньше, в зависимости от активности пользователей) можно будет увидеть результат и провести исследование (в виде интервью) по функциям, которые используются реже всего и тем на которые есть жалобы, чтобы получить качественные данные и составить полную картину происходящего. +

+ +

Дополнительные детали

+

+ При создании мокапов в Figma были использованы: возможности автолэаутов; интерактивные компоненты, плагины (Iconify, Fitter, Protofly, Shadow Maker, Dark Side и др.), файл Community (+40 Types of Cursor). Слои названы и организованы для более удобной работы где-то на 60%. Используется сетка 8pt + есть размеры 2pt, 4pt. Имеются цветовые стили для светлой и тёмной темы. Присутствует адаптивность под изменяющиеся размеры окна (мобильной версии нет). +

+ +
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + + + + diff --git a/public/cases/template-elements-demo.html b/public/cases/template-elements-demo.html new file mode 100644 index 0000000..6340dc0 --- /dev/null +++ b/public/cases/template-elements-demo.html @@ -0,0 +1,858 @@ + + + + + + + Демо элементов кейса — template + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+
+

Демо · template

+

Пример кейса: демо элементов

+

Рыба-текст и блоки для быстрой сборки лонгрида

+

Медиа для демо лежат в public/assets/ (сборка страниц их не копирует). См. public/assets/README.md.

+ +

Контекст

+

+ Этот раздел показывает пример рыбы для вступления. Здесь можно коротко описать продукт, аудиторию и ограничения проекта. + Текст нейтральный: цель — быстро набросать структуру и проверить визуальный ритм страницы. +

+ +

Задача

+

+ Нужно собрать демонстрационный лонгрид с основными UI-элементами: карточками ссылок, медиа-блоками и примерами оформления контента. + Дополнительно важно проверить, как блоки ведут себя на узких и широких экранах. +

+ +

Решение

+

Ниже собраны готовые примеры, которые можно копировать в реальные кейсы.

+ +

Карточки ссылок

+ + +

Картинка: 50% от оригинала (без превью)

+
+ Демо GIF в натуральном размере +
Изображение в уменьшенном натуральном размере, по центру.
+
+ +

Картинка: по ширине контента (с превью)

+
+ Демо изображения по ширине контента +
Изображение по ширине контента. Клик открывает viewer.
+
+ +

Картинка: чуть шире контента (с превью)

+
+ Демо изображения шире контента +
Изображение немного выходит за пределы контентной колонки.
+
+ +

Длинный скрин: свёрнутая высота и кнопка внутри превью

+

+ Блок data-case-tall-media: ширина задаётся атрибутом data-case-tall-width="wide" (как «широкая» картинка) или content (по колонке). В свёрнутом виде видна верхняя часть кадра, внизу превью — плотный «туман». Кнопка «Развернуть» / «Свернуть» с иконкой-шевроном поверх нижней части кадра, внутри рамки; после раскрытия туман скрывается, после сворачивания страница прокручивается к превью. Высоту превью — на .case-media-tall__clip через --case-tall-max (по умолчанию min(70vh, 32rem)). +

+
+
+
+ Демо: длинный вертикальный скрин интерфейса + +
+
+ +
+
+
Длинное изображение img-long.webp (исходник PNG рядом в public/assets/template-elements-demo/).
+
+ +

Галерея: сетка по ширине контента

+

+ Колонок на широком экране задаётся на figure: атрибут style="--case-gallery-cols: 3". Ниже порогов сетка схлопывается до двух и одной колонки. Клик по миниатюре открывает общий viewer кейса. +

+ + +

Галерея: сетка на ширину страницы с боковыми отступами

+

+ Класс case-media-gallery--wide — та же логика выхода за колонку, что у одиночного case-media--wide. Здесь две колонки на широком экране (--case-gallery-cols: 2). +

+ + +

Callout: важный абзац с эмоджи

+ + +

Видео: карточка с тенью и фиксированными малыми углами

+
+
+ +
+
Пример видео-карточки в стиле кейса.
+
+ +

Результат

+

+ Шаблон готов для копирования в новый кейс: остаётся заменить рыбу на фактический текст, подставить реальные ссылки и медиа проекта. +

+
+
+ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
+ + + + + + + + + + + + + + + + + diff --git a/public/cookie-policy.html b/public/cookie-policy.html new file mode 100644 index 0000000..50bf814 --- /dev/null +++ b/public/cookie-policy.html @@ -0,0 +1,320 @@ + + + + + + + Политика cookie — Николай Мамадаев + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+ +
+ + + + + + + + + diff --git a/public/css/main.css b/public/css/main.css new file mode 100644 index 0000000..aa6ca2e --- /dev/null +++ b/public/css/main.css @@ -0,0 +1,5063 @@ +/* Базовые числа темы (переопределяются из localStorage и пикера) */ +html { + --theme-h: 210; + --theme-s: 90; + --theme-l: 40; + --mesh-a-x: 2%; + --mesh-a-y: 2%; + --mesh-b-x: 50%; + --mesh-b-y: 2%; + --mesh-c-x: 98%; + --mesh-c-y: 2%; + --mesh-a-mult: 1; + --mesh-b-mult: 1; + --mesh-c-mult: 1; + --mesh-size-mult: 1.5; + --mesh-opacity-max: 1; + --mesh-opacity-min: 0; + --mesh-opacity-current: 1; + --neutral-accent-tint: 4%; + --accent: hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)); + --accent-square-2-h: calc((var(--theme-h) + 90) * 1deg); + --accent-square-3-h: calc((var(--theme-h) + 180) * 1deg); + --accent-square-4-h: calc((var(--theme-h) + 270) * 1deg); + --accent-square-2: hsl(var(--accent-square-2-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)); + --accent-square-3: hsl(var(--accent-square-3-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)); + --accent-square-4: hsl(var(--accent-square-4-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)); + --accent-text: var(--accent); + --accent-btn-radial-core: color-mix( + in hsl, + hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc((var(--theme-l) + 8) * 1%)), + white 6% + ); + --accent-btn-radial-mid: color-mix(in hsl, var(--accent-analog), hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)) 45%); + --accent-btn-radial-edge: color-mix(in hsl, var(--accent-analog), black 15%); + /* Базовая шкала скруглений; карточки и кнопки используют один уровень */ + --radius-sm: 8px; + --radius-md: 12px; + --radius-card: 14px; + --radius-btn: 14px; + --space: clamp(1rem, 4vw, 2.75rem); + /* Контент на всю ширину экрана, поля только от --space и safe area */ + --max: none; + --font: "Alice", system-ui, -apple-system, serif; + --font-accent: "Merriweather", var(--font); + --neutral-s: 5%; + /* Иконки UI: фиксированный размер по типу элемента */ + --icon-fab: 1.25rem; + --icon-nav-overflow: 1.125rem; + --icon-contact: 1.5rem; + --icon-contact-meta: 1.125rem; +} + +html[data-theme="dark"] { + color-scheme: dark; + --bg: color-mix(in hsl, hsl(var(--theme-h), 6%, 10%), var(--accent) var(--neutral-accent-tint)); + --bg-elevated: color-mix(in hsl, hsl(var(--theme-h), 6%, 13%), var(--accent) var(--neutral-accent-tint)); + --surface: color-mix(in hsl, hsl(var(--theme-h), 6%, 17%), var(--accent) var(--neutral-accent-tint)); + --accent-text: color-mix(in hsl, var(--accent), white 10%); + --page-bg: + radial-gradient( + calc(48% * var(--mesh-size-mult)) calc(56% * var(--mesh-size-mult)) at var(--mesh-a-x) var(--mesh-a-y), + color-mix(in srgb, var(--accent-square-3) calc(52% * var(--mesh-a-mult)), var(--bg)) 0%, + transparent 62% + ), + radial-gradient( + calc(48% * var(--mesh-size-mult)) calc(56% * var(--mesh-size-mult)) at var(--mesh-b-x) var(--mesh-b-y), + color-mix(in srgb, var(--accent-square-2) calc(44% * var(--mesh-b-mult)), var(--bg)) 0%, + transparent 64% + ), + radial-gradient( + calc(52% * var(--mesh-size-mult)) calc(60% * var(--mesh-size-mult)) at var(--mesh-c-x) var(--mesh-c-y), + color-mix(in srgb, var(--accent-square-4) calc(36% * var(--mesh-c-mult)), var(--bg)) 0%, + transparent 68% + ); + --text: hsl(var(--theme-h), 4%, 92%); + --text-muted: color-mix(in hsl, hsl(var(--theme-h), 5%, 58%), var(--accent) 6%); + --line: color-mix(in hsl, hsla(var(--theme-h), 8%, 48%, 0.18), var(--accent) 5%); + --accent-hover: color-mix(in hsl, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)), white 18%); + --accent-soft: color-mix(in hsl, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)), transparent 82%); + --shadow-strong: 0 24px 60px hsla(0, 0%, 0%, 0.45); + /* Карточки навыков: зона решений */ + --skill-solutions-bg: color-mix(in srgb, var(--bg-elevated) 55%, var(--surface)); + --skill-solutions-top-border: var(--line); + --skill-solution-separator: color-mix(in srgb, var(--line) 92%, var(--text-muted)); + --img-ph-shine-peak: color-mix(in srgb, var(--text) 25%, var(--surface) 75%); + /* Кнопки primary: радиальный акцент + стекло (общие с .fab--primary) */ + --btn-primary-border: color-mix( + in srgb, + hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)) 55%, + hsla(0, 0%, 100%, 0.12) + ); + --btn-primary-bg: radial-gradient( + circle at 0% 0%, + color-mix(in hsl, var(--accent), white 10%) 0%, + var(--accent) 100% + ); + --btn-primary-hover-bg: radial-gradient( + circle at 0% 0%, + color-mix(in hsl, var(--accent), white 14%) 0%, + var(--accent) 100% + ); + /* flat: без «парения» и фаски — только обводка (--btn-primary-border) */ + --btn-primary-shadow-flat: none; + --btn-primary-shadow-raised: + 0 14px 34px color-mix(in srgb, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)) 22%, hsla(0, 0%, 0%, 0.5)), + inset 0 1px 0 hsla(0, 0%, 100%, 0.14), + inset 0 -1px 0 color-mix(in srgb, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)) 22%, transparent); + --btn-primary-shadow-hover: + 0 16px 40px color-mix(in srgb, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)) 28%, hsla(0, 0%, 0%, 0.48)), + inset 0 1px 0 hsla(0, 0%, 100%, 0.18), + inset 0 -1px 0 color-mix(in srgb, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)) 18%, transparent); + --btn-primary-backdrop: blur(16px) saturate(135%); + --btn-primary-backdrop-hover: blur(18px) saturate(140%); + --btn-primary-sheen: linear-gradient( + 155deg, + hsla(0, 0%, 100%, 0.1) 0%, + hsla(0, 0%, 100%, 0.03) 50%, + color-mix(in srgb, var(--accent-soft) 32%, transparent) 100% + ); +} + +html[data-radius="soft"] { + --radius-sm: 4px; + --radius-md: 6px; + --radius-card: 4px; + --radius-btn: 4px; +} + +html[data-radius="strong"] { + --radius-sm: 11px; + --radius-md: 16px; + --radius-card: 20px; + --radius-btn: 20px; +} + +html[data-font="merriweather"] { + --font: "Alice", system-ui, -apple-system, serif; + --font-accent: "Merriweather", var(--font); +} + +html[data-font="geologica"] { + --font: "PT Sans", system-ui, -apple-system, sans-serif; + --font-accent: "Geologica", var(--font); +} + +html[data-font="mono"] { + --font: "PT Mono", ui-monospace, "Cascadia Code", "Consolas", monospace; + --font-accent: "Source Code Pro", var(--font); +} + +html[data-theme="light"] { + color-scheme: light; + --bg: color-mix(in hsl, hsl(var(--theme-h), 6%, 97%), var(--accent) var(--neutral-accent-tint)); + --bg-elevated: color-mix(in hsl, hsl(var(--theme-h), 5%, 94%), var(--accent) var(--neutral-accent-tint)); + --surface: color-mix(in hsl, hsl(var(--theme-h), 6%, 100%), var(--accent) var(--neutral-accent-tint)); + --accent-text: color-mix(in hsl, var(--accent), black 14%); + --page-bg: + radial-gradient( + calc(48% * var(--mesh-size-mult)) calc(56% * var(--mesh-size-mult)) at var(--mesh-a-x) var(--mesh-a-y), + color-mix(in srgb, var(--accent-square-3) calc(38% * var(--mesh-a-mult)), var(--bg)) 0%, + transparent 62% + ), + radial-gradient( + calc(48% * var(--mesh-size-mult)) calc(56% * var(--mesh-size-mult)) at var(--mesh-b-x) var(--mesh-b-y), + color-mix(in srgb, var(--accent-square-2) calc(32% * var(--mesh-b-mult)), var(--bg)) 0%, + transparent 64% + ), + radial-gradient( + calc(52% * var(--mesh-size-mult)) calc(60% * var(--mesh-size-mult)) at var(--mesh-c-x) var(--mesh-c-y), + color-mix(in srgb, var(--accent-square-4) calc(26% * var(--mesh-c-mult)), var(--bg)) 0%, + transparent 68% + ); + --text: hsl(var(--theme-h), 8%, 14%); + --text-muted: color-mix(in hsl, hsl(var(--theme-h), 7%, 40%), var(--accent) 7%); + --line: color-mix(in hsl, hsla(var(--theme-h), 10%, 38%, 0.16), var(--accent) 6%); + --accent-hover: color-mix(in hsl, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)), black 14%); + --accent-soft: color-mix(in hsl, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)), transparent 88%); + --shadow-strong: 0 20px 48px hsla(var(--theme-h), 20%, 20%, 0.08); + /* Зона решений: светлее чем --bg-elevated (~#efeff0), ближе к странице/белому */ + --skill-solutions-bg: color-mix(in srgb, var(--surface) 82%, var(--bg) 18%); + --skill-solutions-top-border: color-mix(in srgb, var(--line), var(--text) 7%); + --skill-solution-separator: color-mix(in srgb, var(--line), var(--text) 11%); + --img-ph-shine-peak: color-mix(in srgb, var(--text) 15%, var(--surface) 85%); + --btn-primary-border: color-mix(in srgb, var(--accent) 48%, hsl(0 0% 0% / 0.16)); + --btn-primary-bg: radial-gradient( + circle at 0% 0%, + color-mix(in hsl, var(--accent), white 10%) 0%, + var(--accent) 100% + ); + --btn-primary-hover-bg: radial-gradient( + circle at 0% 0%, + color-mix(in hsl, var(--accent), white 14%) 0%, + var(--accent) 100% + ); + --btn-primary-shadow-flat: none; + --btn-primary-shadow-raised: + 0 14px 28px color-mix(in srgb, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)) 24%, hsla(0, 0%, 0%, 0.18)), + inset 0 1px 0 color-mix(in srgb, var(--accent) 40%, hsl(0 0% 100%) 60%), + inset 0 -1px 0 color-mix(in srgb, var(--accent) 35%, hsl(0 0% 0%) 65%); + --btn-primary-shadow-hover: + 0 16px 34px color-mix(in srgb, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)) 28%, hsla(0, 0%, 0%, 0.2)), + inset 0 1px 0 color-mix(in srgb, var(--accent) 35%, hsl(0 0% 100%) 65%), + inset 0 -1px 0 color-mix(in srgb, var(--accent) 32%, hsl(0 0% 0%) 68%); + --btn-primary-backdrop: blur(10px) saturate(142%); + --btn-primary-backdrop-hover: blur(11px) saturate(148%); + --btn-primary-sheen: linear-gradient( + 155deg, + color-mix(in srgb, var(--accent) 55%, hsl(0 0% 100%) 45%) 0%, + transparent 52%, + color-mix(in srgb, var(--accent) 70%, hsl(0 0% 0%) 30%) 100% + ); +} + +/* Фон и цвет на корне: без этого просвечивает белый фон документа и «хвосты» светлой темы */ +html[data-theme="dark"], +html[data-theme="light"] { + min-height: 100%; + background-color: var(--bg); + color: var(--text); +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; + /* запас под sticky header; точнее задаётся --header-offset из JS */ + scroll-padding-top: var(--header-offset, 4.25rem); +} + +body { + margin: 0; + min-height: 100dvh; + font-family: var(--font); + font-size: 1rem; + line-height: 1.55; + color: var(--text); + background-color: transparent; + position: relative; + -webkit-font-smoothing: antialiased; +} + +.page-mesh-bg { + position: fixed; + inset: 0; + z-index: -1; + pointer-events: none; + overflow: hidden; +} + +html[data-mesh-bg="off"] .page-mesh-bg { + visibility: hidden; +} + +.page-mesh-bg::before { + content: ""; + position: absolute; + inset: 0; + background-image: var(--page-bg); + background-repeat: no-repeat; + background-size: 100% 100dvh; + background-position: top center; + background-blend-mode: normal; + opacity: var(--mesh-opacity-current); +} + +.mesh-panel { + position: fixed; + left: max(0.75rem, env(safe-area-inset-left, 0px)); + bottom: max(0.75rem, env(safe-area-inset-bottom, 0px)); + z-index: 120; + width: min(230px, calc(100vw - 1.5rem)); + padding: 0.65rem 0.7rem; + border-radius: var(--radius-md); + border: 1px solid var(--line); +} + +.mesh-panel__title { + margin: 0 0 0.5rem; + font-size: 0.72rem; + line-height: 1.2; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--text-muted); +} + +.mesh-panel__row { + display: grid; + grid-template-columns: 5.2rem minmax(0, 1fr) 2.3rem; + align-items: center; + gap: 0.45rem; +} + +.mesh-panel__row + .mesh-panel__row { + margin-top: 0.35rem; +} + +.mesh-panel__row--toggle { + grid-template-columns: 5.2rem auto; +} + +.mesh-panel__label { + font-size: 0.72rem; + line-height: 1.25; + color: var(--text-muted); +} + +.mesh-panel__value { + font-size: 0.68rem; + line-height: 1; + color: var(--text-muted); + text-align: right; + font-variant-numeric: tabular-nums; +} + +.mesh-panel input[type="checkbox"] { + width: 1rem; + height: 1rem; + margin: 0; + accent-color: var(--accent-text); +} + +.mesh-panel input[type="range"] { + width: 100%; + margin: 0; + accent-color: var(--accent-text); +} + +#main { + color: var(--text); + background-color: transparent; + margin-top: 0; +} + +.header--scrolled ~ #main { + margin-top: 3.75rem; +} + +img { + max-width: 100%; + height: auto; + display: block; +} + +/* Заглушка: ::before — статичный фон, ::after — один бегущий блеск */ +.has-img-loading { + position: relative; + overflow: hidden; + background-color: transparent; +} + +.has-img-loading::before { + content: ""; + position: absolute; + inset: 0; + z-index: 0; + pointer-events: none; + background-color: color-mix(in srgb, var(--text-muted) 11%, var(--surface)); +} + +/* У обёрток со своим фоном — не дублируем серый слой */ +.mp-card__media.has-img-loading::before, +.case-media-gallery__item.has-img-loading::before { + content: none; +} + +.has-img-loading::after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 260%; + height: 100%; + z-index: 1; + pointer-events: none; + /* Узкая полоса блеска; слой шире тайла — без обрезки краёв градиента */ + background-image: linear-gradient( + 105deg, + transparent 0%, + transparent 40%, + var(--img-ph-shine-peak) 50%, + transparent 60%, + transparent 100% + ); + background-repeat: no-repeat; + background-size: 100% 100%; + background-position: 50% 50%; + transform: translateX(-100%); + animation: img-ph-shine-sweep 3.4s linear infinite; +} + +.has-img-loading img.is-img-loading { + opacity: 0; +} + +.has-img-loading img:not(.is-img-loading) { + opacity: 1; + transition: opacity 0.28s ease; +} + +@keyframes img-ph-shine-sweep { + 0% { + transform: translateX(-100%); + } + 100% { + transform: translateX(38.5%); + } +} + +@media (prefers-reduced-motion: reduce) { + .has-img-loading::after { + content: none; + } +} + +.img-ph-demo { + max-width: 18rem; + aspect-ratio: 16 / 9; + margin: 0.85rem 0 1.2rem; +} + +a { + color: var(--accent-text); + text-decoration-thickness: 1px; + text-underline-offset: 0.2em; +} + +a:hover { + color: var(--accent-hover); +} + +/* Только «текстовые» ссылки: .btn / .fab / .logo задают цвет сами, иначе :visited перебивает --on-accent */ +a:visited:not(.btn):not(.fab):not(.logo):not(.skip-link) { + color: color-mix(in hsl, var(--accent) 10%, var(--text) 90%); +} + +a:visited:not(.btn):not(.fab):not(.logo):not(.skip-link):hover { + color: color-mix(in hsl, var(--accent-hover) 14%, var(--text) 86%); +} + +::selection { + background: var(--accent-soft); + color: var(--text); +} + +.skip-link { + position: absolute; + left: -9999px; + top: auto; + width: 1px; + height: 1px; + overflow: hidden; +} + +.skip-link:focus { + position: fixed; + left: var(--space); + top: var(--space); + z-index: 100; + width: auto; + height: auto; + padding: 0.75rem 1rem; + background: var(--accent); + color: var(--on-accent); + font-weight: 600; + border-radius: var(--radius-md); +} + +.header { + position: relative; + top: 0; + z-index: 50; + background: transparent; + transition: background 0.25s ease; +} + +.header--scrolled { + background: transparent; + height: 0; + overflow: visible; +} + +.header__inner { + max-width: var(--max); + width: 100%; + margin: 0 auto; + padding: 0.8rem max(var(--space), env(safe-area-inset-right, 0px), env(safe-area-inset-left, 0px)); + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; + flex-wrap: nowrap; +} + +.header--scrolled .header__inner { + position: fixed; + top: max(0.42rem, env(safe-area-inset-top, 0px)); + left: auto; + right: max(var(--space), env(safe-area-inset-right, 0px)); + width: fit-content; + max-width: min( + 980px, + calc( + 100% - max(var(--space), env(safe-area-inset-left, 0px)) - + max(var(--space), env(safe-area-inset-right, 0px)) + ) + ); + margin-left: 0; + margin-right: 0; + margin-top: 0; + margin-bottom: 0; + padding: 0.8rem; + border: 1px solid var(--line); + border-radius: calc(var(--radius-card) * 0.7); + background: var(--bg-elevated); + box-shadow: 0 16px 38px hsla(0, 0%, 0%, 0.2); + animation: header-float-in 0.24s cubic-bezier(0.22, 0.8, 0.24, 1); + justify-content: flex-start; + gap: 0.75rem; +} + +@keyframes header-float-in { + from { + transform: translateY(-118%); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} + +.header--scrolled .logo { + width: 2.15rem; + height: 2.15rem; + font-size: 0.75rem; +} + +.header--scrolled .nav { + font-size: 0.84rem; + gap: 0.45rem 0.72rem; +} + +.header--scrolled .nav-more__btn { + width: 32px; + height: 32px; +} + +.header--scrolled .header__cluster { + flex: 0 1 auto; + margin-left: 0; +} + +.header__cluster { + display: flex; + flex-wrap: nowrap; + align-items: center; + justify-content: flex-end; + gap: 0.5rem; + margin-left: auto; + flex: 1 1 auto; + min-width: 0; + /* overflow не hidden: иначе обрезается .nav-more__menu (position:absolute снизу) */ + overflow: visible; +} + +.logo { + display: grid; + flex-shrink: 0; + place-items: center; + width: 2.5rem; + height: 2.5rem; + border-radius: var(--radius-sm); + background: var(--accent-soft); + color: var(--accent-text); + font-weight: 700; + font-size: 0.85rem; + letter-spacing: 0.02em; + text-decoration: none; +} + +.logo:hover { + color: var(--accent-hover); +} + +.logo:visited { + color: var(--accent-text); +} + +.nav { + display: flex; + flex-wrap: nowrap; + justify-content: flex-end; + gap: 0.65rem 0.95rem; + font-size: 0.9rem; + flex: 1 1 auto; + min-width: 0; + overflow: hidden; +} + +.nav a { + color: var(--text-muted); + text-decoration: none; + font-weight: 600; + letter-spacing: 0.02em; + white-space: nowrap; +} + +.nav a:visited { + color: var(--text-muted); +} + +.nav a:hover { + color: var(--text); +} + +/* --- Overflow навигации + панель темы --- */ +.nav-more { + position: relative; + flex-shrink: 0; +} + +.nav-more__btn { + display: grid; + place-items: center; + width: 36px; + height: 36px; + border: 1px solid var(--line); + border-radius: var(--radius-sm); + background: var(--surface); + color: var(--text-muted); + cursor: pointer; +} + +.nav-more__btn:hover { + color: var(--text); + background: var(--accent-soft); +} + +.nav-more__btn svg { + width: var(--icon-nav-overflow); + height: var(--icon-nav-overflow); + display: block; + flex-shrink: 0; +} + +.nav-more__btn[aria-expanded="true"] { + color: var(--accent-text); +} + +/* Два отдельных контейнера: док (шапка) и плавающий (body). Общая сетка ссылок — без общего класса «menu». */ +.nav-more__dock, +.nav-more__floating { + min-width: 12rem; + padding: 0.35rem; + border-radius: var(--radius-md); + border: 1px solid var(--line); + box-shadow: var(--shadow-strong); +} + +.nav-more__dock { + position: absolute; + top: calc(100% + 6px); + right: 0; + z-index: 90; + background: var(--bg-elevated); +} + +/* Плавающая панель: fixed + координаты из JS; фон — токены v12-glass внизу файла */ +#nav-more-menu-floating.nav-more__floating { + position: fixed; + top: var(--nav-more-menu-top, 0px); + left: var(--nav-more-menu-left, 0px); + right: auto; + z-index: 140; + margin: 0; +} + +.nav-more__dock a, +.nav-more__floating a { + display: block; + padding: 0.5rem 0.6rem; + border-radius: var(--radius-sm); + color: var(--text-muted); + text-decoration: none; + font-weight: 500; +} + +.nav-more__dock a:hover, +.nav-more__floating a:hover { + color: var(--text); + background: var(--accent-soft); +} + +.fab[data-theme-panel-btn] { + display: grid; + place-items: center; +} + +.theme-panel-fab__icon { + grid-area: 1 / 1; + line-height: 1; + color: inherit; + pointer-events: none; +} + +.theme-panel-fab__icon--close { + display: block; + width: var(--icon-fab); + height: var(--icon-fab); +} + +.theme-panel-fab__icon--open-hide { + display: block; + flex-shrink: 0; + width: var(--icon-fab); + height: var(--icon-fab); + background: currentColor; + mask-image: url("../assets/shared/icons/design_edit.svg"); + -webkit-mask-image: url("../assets/shared/icons/design_edit.svg"); + mask-size: contain; + mask-repeat: no-repeat; + mask-position: center; + -webkit-mask-size: contain; + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; +} + +.theme-mode-seg .theme-mode-seg__ico { + display: block; + width: var(--icon-fab); + height: var(--icon-fab); + background: currentColor; + mask-size: contain; + mask-repeat: no-repeat; + mask-position: center; + -webkit-mask-size: contain; + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; +} + +.theme-mode-seg__ico--system { + mask-image: url("../assets/shared/icons/system.svg"); + -webkit-mask-image: url("../assets/shared/icons/system.svg"); +} + +.theme-mode-seg__ico--light { + mask-image: url("../assets/shared/icons/sun.svg"); + -webkit-mask-image: url("../assets/shared/icons/sun.svg"); +} + +.theme-mode-seg__ico--dark { + mask-image: url("../assets/shared/icons/moon.svg"); + -webkit-mask-image: url("../assets/shared/icons/moon.svg"); +} + +.fab-primary__ico { + display: block; + width: var(--icon-fab); + height: var(--icon-fab); + background: currentColor; + mask-image: url("../assets/shared/icons/chat_start.svg"); + -webkit-mask-image: url("../assets/shared/icons/chat_start.svg"); + mask-size: contain; + mask-repeat: no-repeat; + mask-position: center; + -webkit-mask-size: contain; + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; +} + +[data-theme-panel-btn][aria-expanded="true"] .theme-panel-fab__icon--open-hide { + display: none; +} + +[data-theme-panel-btn][aria-expanded="false"] .theme-panel-fab__icon--close { + display: none; +} + +/* Панель темы привязана к FAB настроек: абсолют внутри .theme-panel-fab-wrap */ +.theme-panel-fab-wrap { + position: relative; + display: flex; + flex-direction: column; + align-items: flex-end; +} + +.theme-picker__panel { + position: absolute; + right: 0; + bottom: calc(100% + 0.5rem); + width: min(calc(320px + 2.2rem), calc(100vw - 2 * var(--space))); + max-height: min(85vh, calc(100dvh - 5rem)); + overflow-y: auto; + -webkit-overflow-scrolling: touch; + padding: 1rem 1.1rem; + border-radius: var(--radius-md); + border: 1px solid var(--line); + background: var(--bg-elevated); + box-shadow: var(--shadow-strong); + z-index: 1; +} + +.theme-picker__panel[hidden] { + display: none !important; +} + +.fab-stack { + position: fixed; + right: max(var(--space), env(safe-area-inset-right, 0px)); + bottom: max(1rem, env(safe-area-inset-bottom, 0px)); + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 0.6rem; + z-index: 92; +} + +.fab { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 3rem; + min-height: 3rem; + padding: 0.7rem 1rem; + border-radius: 999px; + border: 1px solid var(--line); + text-decoration: none; + color: var(--text); + background: var(--surface); + box-shadow: var(--shadow-strong); + cursor: pointer; + transition: + background-color 0.15s ease, + color 0.15s ease, + border-color 0.15s ease, + box-shadow 0.15s ease; +} + +.fab--primary { + position: relative; + isolation: isolate; + overflow: hidden; + width: 3rem; + min-width: 3rem; + min-height: 3rem; + padding: 0; + border: 1px solid var(--btn-primary-border); + background: var(--btn-primary-bg); + backdrop-filter: var(--btn-primary-backdrop); + -webkit-backdrop-filter: var(--btn-primary-backdrop); + box-shadow: var(--btn-primary-shadow-raised); + color: var(--on-accent); + font-weight: 600; + transition: + background 0.2s ease, + color 0.15s ease, + border-color 0.15s ease, + box-shadow 0.2s ease, + backdrop-filter 0.2s ease; +} + +.fab--primary::after { + content: ""; + position: absolute; + inset: 0; + border-radius: inherit; + pointer-events: none; + z-index: 0; + background: var(--btn-primary-sheen); +} + +html[data-theme="light"] .fab--primary::after { + opacity: 0.42; +} + +.fab--primary::before { + content: ""; + position: absolute; + inset: 0; + border-radius: inherit; + background: radial-gradient( + circle 3rem at var(--btn-shine-x, 50%) var(--btn-shine-y, 50%), + color-mix(in hsl, hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)), white 52%) 0%, + transparent 55% + ); + opacity: 0; + transition: opacity 0.2s ease; + pointer-events: none; + z-index: 2; + mix-blend-mode: soft-light; +} + +.fab--primary:hover::before { + opacity: 0.58; +} + +a.fab--primary:visited { + color: var(--on-accent); + background: var(--btn-primary-bg); +} + +.fab--primary > * { + position: relative; + z-index: 3; +} + +.fab--primary:hover { + color: var(--on-accent); + border-color: var(--btn-primary-border); + background: var(--btn-primary-hover-bg); + backdrop-filter: var(--btn-primary-backdrop-hover); + -webkit-backdrop-filter: var(--btn-primary-backdrop-hover); + box-shadow: var(--btn-primary-shadow-hover); +} + +.fab--primary:focus-visible { + color: var(--on-accent); + border-color: var(--btn-primary-border); + background: var(--btn-primary-hover-bg); + backdrop-filter: var(--btn-primary-backdrop-hover); + -webkit-backdrop-filter: var(--btn-primary-backdrop-hover); + box-shadow: var(--btn-primary-shadow-hover); + outline: 2px solid color-mix(in hsl, var(--accent) 65%, var(--text)); + outline-offset: 2px; +} + +.fab--secondary { + width: 3rem; + padding: 0; + color: var(--text-muted); +} + +a.fab--secondary:visited { + color: var(--text-muted); +} + +.fab--secondary:hover { + color: var(--accent-text); + background: var(--bg-elevated); + border-color: color-mix(in hsl, var(--accent) 38%, var(--line)); + box-shadow: var(--shadow-strong); +} + +.fab--secondary:focus-visible { + color: var(--accent-text); + background: var(--bg-elevated); + border-color: color-mix(in hsl, var(--accent) 45%, var(--line)); + outline: 2px solid color-mix(in hsl, var(--accent) 50%, var(--line)); + outline-offset: 2px; +} + +.theme-picker__stack { + display: flex; + flex-direction: column; + gap: 1.1rem; +} + +.theme-picker__section { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.theme-picker__section-title { + margin: 0; + font-size: 0.68rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.07em; + color: var(--text-muted); +} + +/* Segmented: слабое / среднее / сильное скругление */ +.radius-seg { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 0.4rem; + padding: 0; + border: none; + background: transparent; +} + +.radius-seg--two { + grid-template-columns: repeat(2, 1fr); +} + +.radius-seg__btn { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-width: 0; + padding: 0.5rem 0.25rem; + border: 1px solid var(--line); + border-radius: var(--radius-sm); + background: transparent; + color: var(--text-muted); + cursor: pointer; + font-family: inherit; + transition: + background 0.15s ease, + color 0.15s ease, + border-color 0.15s ease, + box-shadow 0.15s ease; +} + +.radius-seg__btn:hover { + color: var(--text); + border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); +} + +.radius-seg__btn[aria-checked="true"] { + background: var(--accent-soft); + color: var(--accent-text); + border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); + box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent); +} + +.theme-font-seg__btn { + min-height: 44px; + padding: 0.5rem 0.25rem; +} + +.theme-font-seg__label { + display: block; + font-size: 0.78rem; + line-height: 1.15; + letter-spacing: 0.01em; +} + +.theme-font-seg__btn[data-font-option="merriweather"] .theme-font-seg__label { + font-family: "Merriweather", serif; +} + +.theme-font-seg__btn[data-font-option="mono"] .theme-font-seg__label { + font-family: "Source Code Pro", monospace; +} + +.theme-font-seg__btn[data-font-option="geologica"] .theme-font-seg__label { + font-family: "Geologica", sans-serif; +} + +.theme-mesh-bg-seg__btn { + min-height: 44px; + padding: 0.5rem 0.35rem; +} + +.theme-mesh-bg-seg__label { + display: block; + font-size: 0.78rem; + line-height: 1.15; + font-weight: 600; + letter-spacing: 0.01em; +} + +.radius-seg__viz { + display: grid; + place-items: center; + flex-shrink: 0; + width: 44px; + height: 44px; +} + +.radius-seg__arc { + display: block; + width: 28px; + height: 28px; + box-sizing: border-box; + border-left: 2px solid currentColor; + border-top: 2px solid currentColor; + opacity: 0.88; +} + +.radius-seg__arc--soft { + border-top-left-radius: 4px; +} + +.radius-seg__arc--medium { + border-top-left-radius: 14px; +} + +.radius-seg__arc--strong { + border-top-left-radius: 26px; +} + +/* Colorpicker: S/L 16:9 + горизонтальный оттенок, общая ширина блоков */ +.colorpicker { + display: flex; + flex-direction: column; + gap: 0.75rem; + width: min(100%, 320px); + margin-inline: auto; +} + +.colorpicker__plane-box { + position: relative; + width: 100%; + aspect-ratio: 16 / 9; + border-radius: var(--radius-md); + overflow: hidden; + border: 1px solid var(--line); + touch-action: none; +} + +.colorpicker__plane { + display: block; + width: 100%; + height: 100%; + cursor: crosshair; + vertical-align: middle; +} + +.colorpicker__knob { + position: absolute; + width: 20px; + height: 20px; + margin: -10px 0 0 -10px; + border: 1px solid hsla(0, 0%, 0%, 0.32); + border-radius: 50%; + background: #fff; + box-shadow: inset 0 0 0 1px hsla(0, 0%, 100%, 0.45); + pointer-events: none; +} + +.colorpicker__hue-sr { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + clip-path: inset(50%); + white-space: nowrap; + border: 0; +} + +.colorpicker__hue-wrap { + position: relative; + width: 100%; + box-sizing: border-box; + padding: 0; + line-height: 0; +} + +.colorpicker__hue { + -webkit-appearance: none; + appearance: none; + display: block; + width: 100%; + /* Высота ≈ thumb (20px), без лишней «полки» под трек */ + height: 22px; + margin: 0; + padding: 0; + cursor: pointer; + background: transparent; + touch-action: manipulation; + -webkit-tap-highlight-color: transparent; +} + +.colorpicker__hue::-webkit-slider-runnable-track { + height: 14px; + border-radius: 7px; + border: 1px solid var(--line); + background: linear-gradient( + to right, + hsl(0 100% 50%), + hsl(60 100% 45%), + hsl(120 100% 40%), + hsl(180 100% 40%), + hsl(240 100% 52%), + hsl(300 100% 50%), + hsl(360 100% 50%) + ); +} + +.colorpicker__hue::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 20px; + height: 20px; + margin-top: -4px; + border-radius: 50%; + border: 1px solid hsla(0, 0%, 0%, 0.32); + background: #fff; + box-shadow: inset 0 0 0 1px hsla(0, 0%, 100%, 0.45); +} + +.colorpicker__hue::-moz-range-track { + height: 14px; + border-radius: 7px; + border: 1px solid var(--line); + background: linear-gradient( + to right, + hsl(0 100% 50%), + hsl(60 100% 45%), + hsl(120 100% 40%), + hsl(180 100% 40%), + hsl(240 100% 52%), + hsl(300 100% 50%), + hsl(360 100% 50%) + ); +} + +.colorpicker__hue::-moz-range-thumb { + width: 20px; + height: 20px; + border-radius: 50%; + border: 1px solid hsla(0, 0%, 0%, 0.32); + background: #fff; + box-shadow: inset 0 0 0 1px hsla(0, 0%, 100%, 0.45); +} + +.hero { + padding: calc(2 * clamp(2.5rem, 6vw, 4.5rem)) calc(2 * max(var(--space), env(safe-area-inset-right, 0px))) calc(2 * clamp(2rem, 5vw, 3.5rem)) calc(2 * max(var(--space), env(safe-area-inset-left, 0px))); +} + +.hero__grid { + max-width: var(--max); + margin: 0 auto; + display: grid; + grid-template-columns: 1fr; + gap: clamp(2rem, 5vw, 3rem); + align-items: center; +} + +@media (min-width: 860px) { + .hero__grid { + grid-template-columns: 1.15fr 0.85fr; + } +} + +.hero__eyebrow { + margin: 0 0 0.5rem; + font-size: 0.78rem; + font-weight: 700; + color: var(--text-muted); + letter-spacing: 0.14em; + text-transform: uppercase; +} + +.hero__title { + margin: 0 0 1rem; + font-family: var(--font-accent); + font-size: clamp(3.1rem, 7.2vw, 4.85rem); + font-weight: 700; + line-height: 1.2; + letter-spacing: -0.02em; + color: var(--text); +} + +html[data-font="geologica"] .hero__title { + line-height: 1; +} + +html[data-font="mono"] .hero__title { + line-height: 1; +} + +.hero-rotator { + position: relative; + display: inline-flex; + align-items: baseline; + vertical-align: baseline; + min-width: 8.5ch; + min-height: 0.92em; +} + +.hero-rotator__word { + display: inline-block; + min-width: 100%; + white-space: pre; + color: var(--accent-text); + letter-spacing: var(--hero-slot-spacing, 0); + transition: letter-spacing 0.26s ease; +} + +.hero-rotator__char { + display: inline-block; + transition: color 0.12s linear; +} + +/* Превью кейса: pages/cases/*.html (без полной оболочки главной) */ +.case-page__h1 { + margin: 0 0 0.5rem; + font-family: var(--font-accent); + font-size: clamp(1.35rem, 2.6vw, 1.95rem); + font-weight: 700; + line-height: 1.2; + color: var(--text); + text-transform: none; + letter-spacing: -0.02em; +} + +.case-article h2:not(.section__title), +.case-article h3:not(.section__title):not(.mp-card__title) { + font-family: var(--font-accent); +} + +.case-article h3:not(.section__title):not(.mp-card__title) { + margin: 3.25rem 0 1.5rem; +} + +.case-article h2 + h3:not(.section__title):not(.mp-card__title) { + margin-top: 2.25rem; +} + +.case-article h3 + h3:not(.section__title):not(.mp-card__title) { + margin-top: 3.5rem; +} + +.case-article figure + h3:not(.section__title):not(.mp-card__title) { + margin-top: 4rem; +} + +.case-page__sub { + margin: 0 0 1.25rem; + font-size: clamp(1rem, 1.35vw, 1.1rem); + color: var(--text-muted); + font-weight: 500; +} + +.case-page__code { + font-size: 0.88rem; + word-break: break-all; +} + +/* Inline-код в лонгридах кейса (`metric_name` и т.п.) */ +.case-article code { + font-family: ui-monospace, "Cascadia Code", "Consolas", "Courier New", monospace; + font-size: 0.86em; + font-weight: 400; + padding: 0.1em 0.4em; + border-radius: 6px; + vertical-align: 0.04em; + color: var(--accent-text); + background: color-mix(in srgb, var(--bg) 42%, var(--surface) 58%); + border: 1px solid color-mix(in srgb, var(--line) 65%, transparent); + box-decoration-break: clone; + -webkit-box-decoration-break: clone; + word-break: break-word; +} + +.case-article pre { + max-width: 100%; + overflow: auto; + padding: 0.9rem 1rem; + border-radius: var(--radius-sm); + background: color-mix(in srgb, var(--bg) 32%, var(--surface) 68%); + border: 1px solid var(--line); +} + +.case-article pre code { + padding: 0; + border: none; + background: none; + font-size: inherit; + font-weight: inherit; + vertical-align: baseline; + word-break: normal; + white-space: pre; + color: inherit; +} + +/* Внутренние страницы: быстрый флаг скрытия хедера (легко вернуть, убрав класс). */ +body.case-page--hide-header .header { + display: none; +} + +.case-links-grid { + display: grid; + gap: 0.75rem; + margin: 0.85rem 0 1.15rem; +} + +.case-link-card { + display: grid; + grid-template-columns: 96px minmax(0, 1fr); + gap: 1rem; + align-items: center; + padding: 1rem 1.1rem; + border-radius: var(--radius-md); + border: 1px solid var(--line); + background: color-mix(in srgb, var(--surface) 82%, transparent); + text-decoration: none; + color: inherit; + transition: + border-color 0.2s ease, + box-shadow 0.2s ease, + transform 0.2s ease; +} + +.case-link-card:hover, +.case-link-card:focus-visible { + border-color: var(--accent); + box-shadow: 0 8px 24px color-mix(in srgb, var(--accent) 18%, transparent); + transform: translateY(-1px); +} + +.case-link-card:focus-visible { + outline: 2px solid color-mix(in srgb, var(--accent) 44%, transparent); + outline-offset: 2px; +} + +.case-link-card__media { + display: block; + width: 96px; + height: 72px; + border-radius: calc(var(--radius-md) - 4px); + overflow: hidden; + border: 1px solid var(--line); + background: color-mix(in srgb, var(--surface-soft) 70%, transparent); +} + +.case-link-card__media img { + display: block; + width: 100%; + height: 100%; + margin: 0; + object-fit: cover; +} + +.case-link-card__body { + min-width: 0; + display: grid; + gap: 0.2rem; +} + +.case-link-card__title { + font-weight: 700; + font-size: 0.98rem; + line-height: 1.2; + color: var(--text); +} + +.case-link-card__meta { + font-size: 0.88rem; + line-height: 1.35; + color: var(--text-muted); +} + +.case-link-card__url { + font-size: 0.78rem; + line-height: 1.2; + color: color-mix(in srgb, var(--accent) 72%, var(--text)); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.case-link-card--favicon { + grid-template-columns: 24px minmax(0, 1fr); + align-items: center; +} + +.case-link-card--favicon .case-link-card__media { + display: flex; + align-items: center; + justify-content: center; + width: 24px; + height: 24px; + min-width: 24px; + min-height: 24px; + border-radius: 6px; + padding: 0; + background: color-mix(in srgb, var(--surface) 64%, var(--accent) 7%); + overflow: hidden; + flex-shrink: 0; + line-height: 0; + box-sizing: border-box; +} + +.case-link-card--favicon .case-link-card__media img { + display: block; + width: 100%; + height: 100%; + max-width: none; + max-height: none; + margin: 0; + object-fit: contain; + object-position: center; +} + +/* Картинки в кейсах: 3 ширины + fullscreen viewer */ +.case-media { + margin: 0.85rem 0 1.2rem; +} + +.case-media img { + display: block; + height: auto; +} + +.case-media .plyr { + border-radius: 0; + overflow: hidden; + --plyr-color-main: var(--accent); + --plyr-video-range-track-background: color-mix(in srgb, var(--text-muted) 36%, var(--surface)); + --plyr-control-spacing: 0.75rem; + --plyr-control-icon-size: 14px; + --plyr-video-control-color: var(--text-muted); + --plyr-video-control-color-hover: var(--accent); + --plyr-control-radius: 999px; + --plyr-menu-color: var(--text); + --plyr-menu-background: color-mix(in srgb, var(--surface) 92%, var(--bg) 8%); + --plyr-tooltip-background: color-mix(in srgb, var(--surface) 92%, var(--bg) 8%); + --plyr-tooltip-color: var(--text); + --plyr-video-controls-background: linear-gradient( + to top, + color-mix(in srgb, var(--bg) 72%, transparent) 0%, + color-mix(in srgb, var(--bg) 40%, transparent) 42%, + transparent 100% + ); +} + +.case-media .plyr--video .plyr__controls { + margin: 0; + padding: 0; + min-height: 3rem; + width: 100%; + border-radius: 0; + border: 0; + border-top: 1px solid color-mix(in srgb, var(--line) 92%, transparent); + background: color-mix(in srgb, var(--surface) 84%, var(--bg) 16%); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + align-items: center; +} + +.case-media .plyr--video .plyr__controls .plyr__control { + height: calc(3rem - 2px); + min-height: calc(3rem - 2px); + width: calc(3rem - 2px); + min-width: calc(3rem - 2px); + border-radius: 0; + padding: 0; + display: inline-flex; + align-items: center; + justify-content: center; +} + +.case-media .plyr--video .plyr__controls .plyr__progress__container { + height: auto; + display: flex; + align-items: center; + min-width: 0; + flex: 1 1 auto; +} + +.case-media .plyr--video .plyr__controls .plyr__progress { + flex: 1 1 auto; + min-width: 0; +} + +.case-media .plyr--video .plyr__controls .plyr__progress input[type="range"] { + width: 100%; + min-width: 0; +} + +.case-media .case-video-shell { + border-radius: var(--radius-md); + overflow: hidden; + box-sizing: border-box; + border: 1px solid var(--line); + box-shadow: none; + transition: + border-color 0.2s ease, + box-shadow 0.2s ease; +} + +.case-media .case-video-shell:hover, +.case-media .case-video-shell:focus-within { + border-color: var(--accent); + box-shadow: 0 8px 24px color-mix(in srgb, var(--accent) 18%, transparent); +} + +.case-media .case-plyr video, +.case-media .plyr video { + width: 100% !important; + height: auto !important; + max-height: none; + object-fit: contain; + object-position: center; + border-radius: 0 !important; +} + +/* Fullscreen (API и fallback Plyr): кадр целиком, без cover по ширине */ +.plyr--fullscreen-active, +.plyr--fullscreen-fallback, +.plyr:fullscreen, +.plyr:-webkit-full-screen { + background: #000; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.plyr--fullscreen-active .plyr__video-wrapper, +.plyr--fullscreen-fallback .plyr__video-wrapper, +.plyr:fullscreen .plyr__video-wrapper, +.plyr:-webkit-full-screen .plyr__video-wrapper { + display: flex; + align-items: center; + justify-content: center; + flex: 1 1 auto; + width: 100%; + height: 100%; + max-height: none; +} + +.case-plyr.case-plyr--fullscreen video, +.case-plyr--fullscreen-fallback video, +.case-plyr.plyr--fullscreen-fallback video, +.plyr--fullscreen-active video, +.plyr--fullscreen-active .plyr__video-wrapper video, +.plyr--fullscreen-fallback video, +.plyr--fullscreen-fallback .plyr__video-wrapper video, +.plyr:fullscreen video, +.plyr:-webkit-full-screen video, +video:fullscreen, +video:-webkit-full-screen { + width: auto !important; + height: auto !important; + max-width: 100% !important; + max-height: 100% !important; + object-fit: contain !important; + object-position: center; + margin: auto; +} + +.case-media .plyr__video-wrapper, +.case-media .plyr__poster, +.case-media .plyr__video-embed { + border-radius: 0 !important; + border: 0 !important; + box-shadow: none !important; +} + +.case-media .plyr__control { + color: var(--text-muted); +} + +.case-media .plyr__control:hover, +.case-media .plyr__control:focus-visible { + color: var(--accent-text); + background: var(--bg-elevated); + border-color: color-mix(in hsl, var(--accent) 38%, var(--line)); +} + +.case-media .plyr__control--overlaid { + background: color-mix(in srgb, var(--surface) 88%, var(--bg) 12%); + border: 1px solid color-mix(in srgb, var(--line) 92%, transparent); + color: var(--text-muted); +} + +.case-media .plyr__control--overlaid:hover { + background: var(--bg-elevated); + color: var(--accent-text); + border-color: color-mix(in hsl, var(--accent) 38%, var(--line)); +} + +.case-media figcaption { + margin-top: 0.3rem; + font-size: 0.86rem; + line-height: 1.35; + color: var(--text-muted); +} + +.case-media:has(.case-video-shell) { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.35rem; +} + +.case-media:has(.case-video-shell) > .case-video-shell { + width: 100%; +} + +.case-media:has(.case-video-shell) > figcaption { + width: 100%; + margin-top: 0; + text-align: center; +} + +.case-media--natural img { + width: auto; + max-width: 100%; + margin-inline: auto; +} + +.case-media--natural { + display: flex; + flex-direction: column; + align-items: center; +} + +.case-media--content img { + width: 100%; + max-width: 100%; +} + +.case-media--wide { + width: min(calc(100vw - (max(var(--space), env(safe-area-inset-left)) + max(var(--space), env(safe-area-inset-right)))), calc(100% + 8rem)); + margin-left: 50%; + transform: translateX(-50%); +} + +.case-media--wide img { + width: 100%; + max-width: 100%; + margin-inline: auto; +} + +/* Длинный скрин: ширина по колонке (content) или «широкая» (wide), см. data-case-tall-width */ +.case-media[data-case-tall-media][data-case-tall-width="wide"]:not(.case-media--wide) { + width: min(calc(100vw - (max(var(--space), env(safe-area-inset-left)) + max(var(--space), env(safe-area-inset-right)))), calc(100% + 8rem)); + margin-left: 50%; + transform: translateX(-50%); +} + +.case-media[data-case-tall-media][data-case-tall-width="wide"] .case-media-tall__clip > img, +.case-media.case-media--wide[data-case-tall-media] .case-media-tall__clip > img { + width: 100%; + max-width: 100%; + margin-inline: auto; +} + +.case-media[data-case-tall-media][data-case-tall-width="wide"] .case-media-tall, +.case-media.case-media--wide[data-case-tall-media] .case-media-tall { + width: 100%; +} + +/* Длинный скрин: обрезка по высоте, туман и кнопка внутри рамки превью */ +.case-media-tall { + position: relative; + box-sizing: border-box; + border: 0; + background: none; +} + +.case-media-tall__clip { + position: relative; + max-height: var(--case-tall-max, min(70vh, 32rem)); + overflow: hidden; + transition: max-height 0.38s ease; +} + +.case-media-tall--expanded .case-media-tall__clip { + max-height: none; + overflow: visible; +} + +.case-media-tall--reduced-motion .case-media-tall__clip { + transition: none; +} + +.case-media-tall__clip > img { + width: 100%; + max-width: 100%; + height: auto; + display: block; +} + +.case-media-tall__fog { + position: absolute; + left: 0; + right: 0; + bottom: 0; + z-index: 1; + height: min(58%, 15rem); + min-height: 5.5rem; + pointer-events: none; + visibility: visible; + opacity: 1; + background: linear-gradient( + to top, + color-mix(in srgb, var(--bg) 99.5%, transparent) 0%, + color-mix(in srgb, var(--bg) 96%, transparent) 12%, + color-mix(in srgb, var(--bg) 78%, transparent) 38%, + color-mix(in srgb, var(--bg) 38%, transparent) 68%, + transparent 100% + ); + transition: opacity 0.22s ease, visibility 0.22s ease; +} + +.case-media-tall--expanded .case-media-tall__fog { + opacity: 0; + visibility: hidden; +} + +.case-media-tall__actions { + position: absolute; + left: 0; + right: 0; + bottom: 0; + z-index: 2; + display: flex; + justify-content: center; + align-items: center; + padding: 0.65rem 0.5rem 0.75rem; + border: 0; + background: none; + pointer-events: none; +} + +.case-media-tall__actions .case-media-tall__btn { + pointer-events: auto; +} + +.case-media-tall__btn.btn.btn--ghost { + gap: 0.45rem; + min-width: unset; + padding: 0.45rem 0.65rem; + color: var(--accent-text); + border-color: transparent !important; + background: transparent !important; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; + box-shadow: none !important; +} + +.case-media-tall__btn.btn.btn--ghost:hover, +.case-media-tall__btn.btn.btn--ghost:focus-visible { + color: var(--accent-hover); + border-color: transparent !important; + background: color-mix(in srgb, var(--accent) 10%, transparent) !important; + backdrop-filter: none !important; + -webkit-backdrop-filter: none !important; +} + +.case-media-tall__btn-chev { + display: block; + width: 1rem; + height: 1rem; + flex-shrink: 0; + background: currentColor; + mask-image: url("../assets/shared/icons/shevron-down.svg"); + -webkit-mask-image: url("../assets/shared/icons/shevron-down.svg"); + mask-size: contain; + mask-repeat: no-repeat; + mask-position: center; + -webkit-mask-size: contain; + -webkit-mask-repeat: no-repeat; + -webkit-mask-position: center; +} + +.case-media-tall--expanded .case-media-tall__btn .case-media-tall__btn-chev { + mask-image: url("../assets/shared/icons/shevron-up.svg"); + -webkit-mask-image: url("../assets/shared/icons/shevron-up.svg"); +} + +@media (prefers-reduced-motion: reduce) { + .case-media-tall__clip { + transition: none; + } + + .case-media-tall__fog { + transition: none; + } +} + +/* Галерея изображений сеткой: число колонок на широком экране — CSS-переменная --case-gallery-cols на figure */ +.case-media-gallery { + --case-gallery-cols: 3; +} + +.case-media-gallery > figcaption { + width: 100%; + text-align: center; +} + +.case-media-gallery__grid { + display: grid; + gap: 0.65rem; + grid-template-columns: repeat(var(--case-gallery-cols), minmax(0, 1fr)); +} + +@media (max-width: 48rem) { + .case-media-gallery__grid { + grid-template-columns: repeat(min(2, var(--case-gallery-cols)), minmax(0, 1fr)); + } +} + +@media (max-width: 28rem) { + .case-media-gallery__grid { + grid-template-columns: 1fr; + } +} + +.case-media-gallery__item { + min-width: 0; + border-radius: var(--radius-md); + overflow: hidden; + border: 1px solid var(--line); + background: color-mix(in srgb, var(--surface) 60%, var(--bg) 40%); + transition: + border-color 0.2s ease, + box-shadow 0.2s ease; +} + +.case-media-gallery__item:has(> img[data-image-viewer]:not([data-src])):not(.has-img-loading) { + padding: 0; + border: none; + background: none; + overflow: visible; +} + +/* Заглушка: клип по тайлу (viewer снимает overflow только после load) */ +.case-media-gallery__item.has-img-loading { + overflow: hidden; + border: 1px solid var(--line); +} + + +.case-media-gallery__item img { + width: 100%; + height: auto; + display: block; +} + +.case-media-gallery--wide { + width: min(calc(100vw - (max(var(--space), env(safe-area-inset-left)) + max(var(--space), env(safe-area-inset-right)))), calc(100% + 8rem)); + margin-left: 50%; + transform: translateX(-50%); +} + +.case-callout { + width: min(calc(100vw - (max(var(--space), env(safe-area-inset-left)) + max(var(--space), env(safe-area-inset-right)))), calc(100% + 8rem)); + margin: 1.8rem 0 2.4rem; + margin-left: 50%; + padding: 0.95rem 1.1rem; + display: grid; + grid-template-columns: auto 1fr; + align-items: start; + gap: 0.72rem; + border-radius: var(--radius-md); + transform: translateX(-50%); + background: color-mix(in srgb, var(--surface) 84%, var(--bg) 16%); +} + +.case-callout__emoji { + display: inline-grid; + place-items: center; + min-width: 1.65rem; + min-height: 1.65rem; + font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", emoji, sans-serif; + font-size: clamp(1.05rem, 1.75vw, 1.3rem); + line-height: 1; + font-style: normal; + font-variant-emoji: emoji; + color: unset; + -webkit-text-fill-color: unset; + transform-origin: center; +} + +.case-callout__emoji--pulse { + animation: case-callout-emoji-pulse 0.6s ease-in-out infinite; +} + +.case-callout__content { + min-width: 0; + font-size: clamp(1.05rem, 1.45vw, 1.125rem); + line-height: 1.6; + color: var(--text); +} + +.case-callout__content > :first-child { + margin-top: 0; +} + +.case-callout__content > :last-child { + margin-bottom: 0; +} + +.case-callout:has(.case-callout__content > p:only-child), +.case-callout:has(.case-callout__content > :only-child) { + align-items: center; +} + +@keyframes case-callout-emoji-pulse { + 0%, + 100% { + transform: scale(1); + filter: saturate(1); + } + 50% { + transform: scale(1.12); + filter: saturate(1.15); + } +} + +/* Кликабельные кадры (viewer): рамка на кадре, figcaption снаружи и по центру под картинкой */ +.case-media:has(> img[data-image-viewer]:not([data-src])), +.case-media:has(.case-media-tall__clip > img[data-image-viewer]:not([data-src])) { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.35rem; +} + +/* Перебивает margin у `.case-article img` в локальных + + + + {{> header-case}} +{{> fab-stack}} +
+
+

Product Design · AI

+

Разработка интерфейса для Primo RPA AI Server

+

+ Платформа интеллектуальной обработки документов
+ и оркестрации ИИ-агентов +

+ +
+

Обзор

+

+ Внутри компании появился сервис, который заметно улучшил работу с моделями для распознавания текста на документах: загрузка датасета из документов компании, разметка полей, обучение модели и дальнейшее использование модели в других продуктах. Такой подход давал более высокое качество распознавания и соответствовал требованиям безопасности — данные оставались внутри контура компании. Уже в ходе работы в продукте появился функционал дообучения (fine-tuning) базовых нейросетей под задачи компании и работы со скилами: суммаризация, извлечение, генерация и другие сценарии. +

+

+ В проект меня пригласили как UX/UI дизайнера: интерфейс до этого собирали разработчики своими силами. В результате работы у сервиса снизился порог входа — продуктом могли пользоваться существенно больше людей без специальной подготовки в области ИИ и OCR. +

+ +
+ +
+

Было и стало

+

+ Сервис был собран на Ant Design под React с визуальной темой Hope UI для Bootstrap. У компании уже было несколько веб-продуктов с задачей унифицировать и освежить интерфейс, поэтому в разработке опирались на компоненты этих систем. +

+ +

+ Я погрузился в продукт и вместе с командой детально разобрал весь функционал. +

+ +

+ По текущим сценариям собрал юзерфлоу: они показали команде, где в интерфейсе и в маршрутах пользователя возникает путаница. На этой основе переработали сами процессы настройки: часть функций автоматизировали и спрятали, чтобы снизить риск ошибок и убрать лишнюю рутину. +

+

+ Новый подход изменил и восприятие продукта, и процесс настройки. Интерфейс ведёт по этапам настройки, при этом не ломает привычные сценарии: полностью линейный визард здесь невозможен — пользователю всё равно нужно возвращаться назад и уточнять параметры ради качества результата. +

+

Вопросы к команде по текущему состоянию

+

Ответы помогут зафиксировать эффект от внедрения в цифрах и фактах.

+
    +
  • Сократилось ли количество обращений в поддержку.
  • +
  • Получается ли у пользователей самостоятельно пройти настройку проекта от начала до конца.
  • +
  • Позволяет ли новый интерфейс заводить новые типы проектов, опираясь на уже заложенные паттерны.
  • +
+
+ +
+

Паттерны интерфейса

+

+ Ниже — ключевые зоны продукта: как они поддерживают сценарии обучения и работы с моделью и чем отличаются от прежнего подхода. +

+ +

Сопоставление полей (маппинг)

+

+ Маппинг связывает поля документа с целевой структурой данных. Важно было сделать связь наглядной и обратимой, чтобы пользователь не терял контекст при правках. +

+
+
+ +
+
Сопоставление полей в интерфейсе
+
+ +

Датасет, обучение и контроль качества

+

+ Редактор датасета, запуск обучения и экраны качества образуют один ментальный путь: подготовка данных → обучение → проверка результата. +

+ +
+ Редактор датасета — текущая версия интерфейса +
Редактор датасета — текущая версия
+
+
+ Редактор датасета — предыдущая версия для сравнения +
Предыдущая версия редактора
+
+
+ Экран обучения модели по датасету +
Обучение по датасету
+
+
+ Контроль качества модели после обучения +
Качество и проверка результата
+
+ +

Inference в проекте

+

+ Отдельный фокус — запуск и контроль модели внутри проекта: пользователь должен понимать состояние прогона и не терять связь с остальными настройками. +

+
+ Интерфейс inference модели внутри проекта +
Inference в проекте
+
+
+
+
+ Inference в проекте — полный экран интерфейса + +
+
+ +
+
+
Полный вертикальный кадр экрана inference
+
+
+ Предыдущая версия экрана inference в проекте +
Предыдущая версия inference
+
+ + + +

Полноэкранный режим и импорт

+

+ Речь не о «длинных задачах», а о процессах в отдельном контексте: одни до завершения блокируют работу с проектом, другие идут параллельно в отдельном окне, и при этом можно продолжать настраивать параметры проекта. Функционал вынесли в отдельное окно, потому что точек входа в такие задачи было несколько, а обычной модалки было недостаточно — нужно было пройти отдельный процесс в стороне и затем вернуться к настройкам проекта. Такой подход сократил объём разработки и тестирования. +

+

+ Ниже — три варианта полноэкранного холста: импорт в отдельном окне, режим с панелями и минималистичный «zen». +

+
+ Модальное окно импорта датасета на отдельном экране +
Импорт в модальном окне
+
+
+ Полноэкранный режим с боковыми панелями +
Полноэкранный режим с панелями
+
+
+ Полноэкранный режим без отвлекающих панелей +
Минимальный режим без лишнего chrome
+
+ +

Дальнейшее развитие

+

+ В дорожной карте оставались отдельные крупные куски: сценарии вокруг LLM (списки, статусы, действия), пошаговый мастер обучения с прогрессом и отменой, а также полноценный контур OCR с разметкой регионов и превью качества на странице. Они не входили в минимальный набор для первого промышленного релиза интерфейса, но заложенные паттерны должны их принять без ломки навигации. +

+
+ +
+

Процесс и передача

+

+ Работа шла через регулярные синхронизации с разработкой: макеты, спецификации и поэтапный handoff во фронт. После моего выхода из проекта команда искала следующего дизайнера и выстраивала онбординг по уже оформленным артефактам и правилам компоновки. +

+ +

Вопросы следующему дизайнеру

+
    +
  • Что оказалось неочевидным в первые две недели в проекте.
  • +
  • Какие артефакты и правила передачи пригодились больше всего.
  • +
  • Что пришлось пересобрать и по какой причине.
  • +
  • Как в трёх предложениях описать текущее состояние UX.
  • +
+
+ +
+

Итог

+

+ Интерфейс AI Server в Primo RPA перевели от «инженерного интерфейса разработчиков» к продукту с понятной логикой настройки и сопровождения пользователя. Упор на юзерфлоу и автоматизацию рутины снял часть нагрузки с внедрения и открыл дорогу к более широкому использованию внутри компании и у клиентов. +

+
+
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + diff --git a/src/pages/cases/ai-platform-primo-rpa.html b/src/pages/cases/ai-platform-primo-rpa.html new file mode 100644 index 0000000..5ac3f8d --- /dev/null +++ b/src/pages/cases/ai-platform-primo-rpa.html @@ -0,0 +1,587 @@ + + + + + + + AI Server в Primo RPA — кейс + {{> head-links}} + {{> head-plyr}} + + + + + {{> header-case}} +{{> fab-stack}} +
+
+

Product Design · AI

+

Разработка интерфейса для Primo RPA AI Server

+

+ Платформа интеллектуальной обработки документов
+ и оркестрации ИИ-агентов +

+ +
+

Обзор

+

+ Продукт AI Server разворачивается на внутренних серверах клиентов. Он позволяет использовать нейросети во внутреннем контуре компании и настраивается через веб-интерфейс. +

+

+ Меня пригласили на проект как UX/UI-дизайнера. Продукт был в активной стадии тестирования; по обратной связи от клиентов стало ясно, что настройка слишком сложна: с ней справляются только эксперты и команда внедрения Primo RPA. Сложная настройка снижала привлекательность продукта и тормозила масштабирование. +

+

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

+ +

+ Ниже — погружение в продукт, примеры выполненных задач и паттерны интерфейса. +

+
+ +
+

Погружение

+

+ Работу начал со знакомства с командой: кто за продукт, кто за внедрение, как всё устроено сейчас. Пообщался с экспертами по настройке, разделил ключевые и вспомогательные сценарии, собрал визуализацию поведения пользователя. Плотно работал с разработкой и искал, где интерфейс можно упростить и ускорить настройку. +

+ +

+ Продукт уже использовали клиенты, поэтому нельзя было остановить разработку и пересобрать интерфейс целиком. Пришлось решать, в каком порядке и какие части трогать в редизайне. Самые крупные изменения встраивал в текущий план разработки, без отрыва от релизов. +

+

+ Прорабатывать изменения в интерфейсе нужно было с учётом используемого фреймворка. На тот момент это был + Ant Design под React со стилизацией под + Hope UI. +

+

+ Новые компоненты приходилось придумывать только в крайних случаях, в приоритете было переиспользовать уже существующую библиотеку. По итоговым экранам это видно: интерфейс в основном собран из готовых блоков, а не с нуля. +

+
+ +
+

Выполненные задачи

+

+ Фрагменты интерфейса, которые я переработал или собрал почти с нуля. Ниже — отдельные задачи из проекта, которые хотелось показать в портфолио, а не обзор всего продукта. +

+ +

Главная навигация сервиса

+

+ В сервисе стояла привычная для админок схема: слева боковое меню, справа контент. На скриншоте видно, что такая структура страницы неэффективно использовала доступное рабочее пространство на экране. Если открыть проект, слева окажется навигация по разделам проекта — вперемешку с главной, и это путает пользователя. Эту ситуацию нужно было исправить. +

+
+ Предыдущая главная навигация сервиса AI Server +
Предыдущая навигация
+
+
+ Обновлённая главная навигация сервиса AI Server +
Обновлённая навигация
+
+

+ Обновлённая навигация стала компактной и всё так же привычна большинству пользователей. Для контентной части пространства стало значительно больше. Как будет видно дальше, у проектов внутри появится отдельная навигация, которая не будет перекрывать главную. При этом улучшилась эстетическая составляющая дизайна сервиса. +

+

Навигация внутри конкретного проекта

+

+ У пользователя остаётся доступ и к навигации внутри проекта, и к главной навигации сервиса. Разные типы проекта содержат разное количество пунктов, и такое решение позволяет удачно их разместить. +

+
+ Навигация внутри NLP-проекта и главная навигация сервиса +
NLP-проект
+
+
+ Навигация внутри OCR-проекта и главная навигация сервиса +
OCR-проект
+
+

+ Отдельно отмечу идею с формой пунктов навигации. По виду она мягко подсказывает, что настройку удобнее проходить по шагам, но разделы по-прежнему работают как обычные табы: можно переключаться в любом порядке. +

+
+ Вторичная навигация проекта со стрелочной формой пунктов +
Форма пунктов навигации
+
+

Редактор разметки датасета

+

+ На этом экране проводят больше всего времени. Разметка полей на сотнях изображений — монотонная работа, но от неё зависит, насколько качественными будут данные для обучения модели. Прежний редактор сильно выбивался из общего стиля сервиса: выглядел перегруженно и местами сбивал с толку, особенно в работе с полями. +

+
+ Редактор датасета — предыдущая версия для сравнения +
Предыдущая версия редактора датасета
+
+

+ Я разобрал редактор на микросценарии, выстроил их по приоритету и связке между собой. С командой обсудили, как сделать поведение пользователя плавнее и понятнее. В новой структуре страницы заложил место под новый функционал и те же паттерны, что в остальном сервисе. Дизайн редактора привёл к общей стилистике. +

+
+ Редактор датасета — текущая версия интерфейса +
Обновлённая версия редактора датасета
+
+

+ На схематическом наброске видно, что страница стала симметричной: почти всё пространство уходит на размечаемое изображение. Действия сгруппированы по панелям — нужную функцию проще найти. +

+
+ Вайрфрейм редактора датасета — режим по умолчанию +
Каркас: режим по умолчанию
+
+

+ Добавил режим «Во весь экран». Продвинутые пользователи обычно прячут лишние панели и работают с разметкой через горячие клавиши и нижнюю панель. Боковые панели можно свернуть, когда нужно больше места под изображение — на небольших мониторах это особенно имеет значение. +

+ + +

+ Нижняя панель позволяет переключаться между изображениями и выполнять быстрые действия. +

+
+ Главная панель инструментов редактора датасета +
Нижняя панель инструментов
+
+ +

Карточки настройки обучения модели

+

+ После разметки датасета модель можно дообучить (fine-tuning). Мы с командой, как обычно, разобрали все действия пользователя для этой задачи. Сделали несколько вариантов компоновки этой страницы; самым удачным оказался вариант с лентой из карточек. +

+
+ Обзор карточек настройки обучения в проекте +
Вид раздела обучения моделей
+
+

+ В начале ленты у пользователя карточка с настройкой обучения: через неё видно результат разметки активного датасета, задают параметры и запускают fine-tuning. +

+
+ Карточка настройки обучения +
Карточка настройки обучения
+
+

+ В карточке отдельный блок с оценкой качества разметки датасета и блок с параметрами перед запуском обучения. +

+ +

+ Под каждый запущенный процесс ниже появится отдельная карточка. Можно завести несколько процессов с разными параметрами и потом сравнить, какая конфигурация сработала лучше. +

+
+ Карточка процесса обучения модели +
Карточка процесса обучения
+
+

+ Внутри карточки информация и действия разнесены по логическим блокам. Мы рассматривали разные варианты компоновки и в итоге зафиксировали схему, которая оказалась удобнее остальных. +

+
+ Вайрфрейм карточки процесса обучения +
Вайрфрейм карточки процесса обучения
+
+

+ Карточки могут быть свёрнуты. Для удобства в шапку вынесены название и статус. +

+
+ Свёрнутая карточка настройки обучения +
Свёрнутая карточка
+
+

+ После проработки этих карточек появились паттерны, которые потом использовались в других разделах продукта. Так проще держать интерфейс в едином стиле. +

+ +

Настройка параметров полей

+

+ На одной из страниц раздела проекта нужно было дать возможность настроить уникальные параметры полей для датасета. Редактору требовалась большая область под изображение (скан документа), могло быть десятки полей, у каждого — свои зависимые параметры и типы. +

+

+ На видео — работа прототипа готового решения. +

+
+
+ +
+
Сопоставление полей в интерфейсе
+
+

+ Интерфейс получился компактным и лаконичным. Механика не считывается с первого взгляда, но после короткого обучения пользователю в нём комфортно. +

+

+ Редактор для меня оказался интересной и сложной задачей: было много черновиков и вариантов поведения. В финале остался вариант, который закрывал все требования, которые мы с командой сформулировали. +

+ +

Модальные окна на отдельном экране

+

+ В сервисе часть задач нужно выполнять параллельно с остальной работой. Для таких сценариев сделали так: модальное окно открывается на отдельной странице. +

+
+ Модальное окно импорта датасета на отдельном экране +
Импорт датасета в модальном окне
+
+

+ На странице проекта отображается заглушка: процесс идёт, рядом кнопка перехода к нему. +

+
+ Импорт датасета внутри проекта +
Импорт датасета внутри проекта
+
+

+ Такие заглушки есть в нескольких разделах проекта — в зависимости от того, можно ли с ним работать, пока задача активна. +

+ +

+ Такой вариант оказался технически проще, чем точечно блокировать кнопки на отдельных страницах. +

+ +
+ +
+

Передача в разработку

+

+ Раз в неделю команда собиралась на обсуждение дизайна. Созвоны были длительными, но продуктивными. На неделю формировали список задач для дизайна, приоритеты и сроки подстраивали под планы релизов. +

+

+ Я делал дизайн в Figma, в разработку передавал ссылки на готовые юзерфлоу. Отдельную дизайн-систему или UI-kit не заводили: в продукте уже был готовый фреймворк. +

+

+ Время от времени созванивался с верстальщиком тет-а-тет, если нужно уточнить детали по макетам или объяснить поведение интерфейса. После вёрстки давал фидбэк на правки, чтобы результат не отличался от задуманного поведения и вида интерфейса. +

+
+ +
+

Смена дизайнера

+

+ Проект вёл параллельно с другими, нагрузку приходилось распределять. В компанию наняли нового дизайнера — моя задача была ввести её в курс дела и курировать результат по задачам. После адаптации работа над проектом полностью перешла под её ответственность. +

+
+ +
+

Итог

+

+ Интерфейс Primo RPA AI Server стал выглядеть консистентно. С ним могут работать пользователи, которые ещё не эксперты в области ИИ. Для будущих изменений в интерфейсе заложена возможность наращивать функционал без больших переделок. +

+
+
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + diff --git a/src/pages/cases/design-system.html b/src/pages/cases/design-system.html new file mode 100644 index 0000000..0af2800 --- /dev/null +++ b/src/pages/cases/design-system.html @@ -0,0 +1,859 @@ + + + + + + + Design System — портфолио + {{> head-links}} + + + + + {{> header-minimal}} +{{> fab-stack-home-contact}} +
+
+

Документация · UI

+

Design System

+

Токены, типографика, сетка, компоненты и блоки лонгрида кейса

+

+ Переключайте тему, акцент и шрифт через плавающую панель справа. При глобальных правках стилей (токены, + компоненты, блоки лонгрида) обновляйте и эту страницу — живой каталог UI проекта. +

+ + + +

Цвета

+

+ Акцент и «холод/тепло» всего UI задаются тремя числами в модели HSL (Hue — оттенок, + Saturation — насыщенность, Lightness — светлота) на <html>. Из них собирается + --accent и производные токены; нейтральные фоны слегка подмешивают тот же оттенок + (--neutral-accent-tint). Светлая/тёмная тема — data-theme, mesh — + data-mesh-bg. Меняется в FAB справа. +

+

Что такое --theme-h, --theme-s, --theme-l

+
    +
  • + --theme-h — оттенок (Hue), позиция на цветовом круге 0–360°. Сдвиг hue + перекрашивает кнопки, ссылки, mesh-градиент и квадратные акценты (--accent-square-2 … + 4), не трогая вручную каждый hex. +
  • +
  • + --theme-s — насыщенность: насколько «чистый» цвет, а не серый. +
  • +
  • + --theme-l — светлота акцента: темнее или ярче основной фирменный тон + (в панели обычно ограничен диапазоном, чтобы кнопки оставались читаемыми). +
  • +
+

+ В CSS это выглядит так: + --accent: hsl(var(--theme-h) calc(var(--theme-s) * 1%) calc(var(--theme-l) * 1%)). + Значения пишутся в localStorage (siteThemeV1) и подставляются inline-скриптом в + head, чтобы не было вспышки «чужого» цвета при загрузке. +

+
+
+
+ --bg +
+
+
+ --bg-elevated +
+
+
+ --surface +
+
+
+ --text +
+
+
+ --text-muted +
+
+
+ --line +
+
+
+ --accent +
+
+
+ --accent-text +
+
+
+ --accent-soft +
+
+

+ Дополнительно: квадратичные оттенки mesh — --accent-square-2 … 4; они зависят от hue. +

+ +

Шрифты

+

+ Пара шрифтов — data-font на <html> (FAB «Типографика»): задаёт + --font-accent (заголовки) и --font (проза). Шкала в таблицах: класс, пример, назначение. +

+

Семейства

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
data-fontСтекГде
merriweatherMerriweather + AliceПара по умолчанию; Alice — основной текст, Merriweather — акцентные заголовки
monoSource Code Pro + PT MonoМоноширинная пара
geologicaGeologica + PT SansГротеск + нейтральная проза
+
+ +

Типографическая шкала

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
КлассПримерНазначение
.hero__eyebrow

Подпись секции

Hero, ввод кейса
.hero__title +

+ Display заголовок +

+
H1 главной; на DS уменьшен для колонки
.section__title

Секция

«Навыки», «Портфолио», контакты; основной шрифт, без капса
.case-page__h1

Заголовок страницы

H1 кейса / Design System
.case-page__sub

Лид под заголовком

Подзаголовок под H1
.section__prose

Основной текст абзаца.

Проза, списки, ссылки в статье
h2 в .case-article

Подсекция H2

Разделы лонгрида (как «Цвета»)
h3 в .case-article

Подсекция H3

Подразделы внутри H2; отступы в main.css: сверху 3.25rem, снизу 1.5rem, после figure 4rem, h3+h3 3.5rem
+
+ +

Ритм и код

+

Пример ритма:

+
    +
  • маркированный список;
  • +
  • акцент и ссылка;
  • +
+
    +
  1. нумерованный пункт;
  2. +
+

Инлайн code и блок:

+
--font: "Alice", system-ui, serif;
+--font-accent: "Merriweather", var(--font);
+

+ Заголовки используют clamp() — масштаб от вьюпорта; подробнее в разделе «Сетка». +

+ +

Сетка и адаптив

+

+ Отдельной 12-колоночной сетки нет: full-bleed layout с боковыми полями + --space и локальными CSS Grid внутри секций. Контентная колонка DS и кейсов — + .case-article (max-width 48rem). +

+ +

Базовый каркас

+
    +
  • --space: clamp(1rem, 4vw, 2.75rem) — горизонтальные поля + safe-area-inset.
  • +
  • --max: none — без фиксированной «коробки» 1200px; ширина = вьюпорт минус padding.
  • +
  • .section — вертикальные отступы через clamp(); .section__inner центрирует блок.
  • +
  • .section--tight — компактнее по вертикали (кейсы, эта страница).
  • +
+ +

Брейкпоинты

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ОтЧто меняется
860px.hero__grid → 2 колонки 1.15fr 0.85fr
760px / 1180px.projects-carousel: --projects-visible 1 → 2 → 3 карточки
720px.skills-category__grid → 2 колонки
1024pxНавыки: 6-колоночная мозаика (grid-column: span …)
560px / 1024px.contact-grid → 2 → 4 колонки
48rem / 28remГалерея кейса: ≤2 col → 1 col
640pxcase-media-gallery--wide схлопывается в ширину колонки
+
+ +

Hero: одна → две колонки

+

Схема .hero__grid (сжато до 860px):

+ + +

Контакты: 1 → 2 → 4

+

Демо .contact-grid (плейсхолдеры, без переходов):

+ +

+ Навыки: мозаика на широком экране — см. + главную, #skills. Портфолио: карусель на + 100vw с --projects-card-width и JS-прокруткой — на главной + #projects. +

+ +

Wide в кейсах

+

+ .case-media--wide, .case-media-gallery--wide и .case-callout шире + колонки статьи: min(100vw − 2×padding, content + 8rem), с полями --space. На узком + экране (до 640px) wide схлопывается в ширину колонки. Кадры с data-image-viewer — обводка и hover + как у .case-video-shell (живые примеры — демо элементов кейса). Подпись под видео — + figcaption по центру колонки. +

+ +

Типографика и motion

+

+ Fluid type: clamp() на .hero__title, .section__title, + .case-page__h1. Скругления (data-radius) сетку не меняют. Для длинных скринов и + анимаций учитывается prefers-reduced-motion: reduce. +

+ +

Компоненты

+

Живые примеры; оболочка (шапка, FAB, футер, cookie) уже подключена на этой странице.

+ +

Кнопки

+ +

.btn .btn--primary | secondary | ghost · .btn--flat | raised · .btn__icon

+ +

Теги

+
    +
  • hero__tag
  • +
  • UX/UI
  • +
+

.hero__tags / .hero__tag

+
    +
  • portfolio-card__tag
  • +
  • Web App
  • +
+

.portfolio-card__tags / .portfolio-card__tag

+ +

Карточка портфолио

+ +

.portfolio-card и дочерние BEM-классы

+ +

Заглушка при загрузке изображений

+

+ Пока img ещё не загрузился, initImageLoadPlaceholder вешает + .is-img-loading на картинку и .has-img-loading на обёртку. Слой фона — + ::before, один блеск слева направо — ::after (img-ph-shine-sweep). + Иконки, SVG и мелкие картинки до 40px пропускаются; + отключить точечно: data-no-img-placeholder. Ниже — зафиксированное демо (на сайте классы снимаются + после load). +

+ +

.has-img-loading · .is-img-loading · .img-ph-demo (демо заглушки)

+ +

Карточка навыка

+
+

skill-task-card__task — формулировка задачи от бизнеса.

+
+

skill-task-card__solution — первый подход к решению.

+

Второй пункт в зоне решений.

+
+
+

.skill-task-card__task · __solutions · __solution

+ +

Callout

+

+ Акцентный блок лонгрида: шире колонки (как wide-медиа), текст в .case-callout__content чуть + крупнее основного абзаца. +

+ +

.case-callout · .case-callout__emoji · .case-callout__emoji--pulse · .case-callout__content

+ +

Контактные карточки

+

+ На главной в сетке четыре карточки (1→2→4 колонки). Здесь два примера — сетка принудительно в две колонки. +

+ +

.contact-card--link · --action · --brand-*

+ +

Секция с фоном

+

+ На главной полоса .section--surface визуально читается через mesh; в кейсах фон страницы + ровный — ниже компактное демо с background: var(--surface). +

+
+
+

section__title

+

Фрагмент .section.section--surface + .section__inner

+
+
+

.section · .section--surface · .section--tight · .section__inner

+ +

Блоки

+
+

+ Разметка лонгрида кейса: медиа и галереи, карточки ссылок, видео, callout, wide-блоки и прочие partials. + Живой эталон со всеми вариантами — на отдельной странице; оттуда копируют куски при сборке нового кейса. +

+

+ Демо элементов кейса +

+
+ +

Активность

+
+

+ На главной в секции #mini-projects карточки mp-card в masonry-сетке. Типы, клетки и живая + раскладка вынесены на отдельную страницу. +

+

+ Каталог карточек активности +

+
+
+
+ + {{> footer-spacer}} + {{> footer}} + {{> cookie-notice}} + {{> nav-more-floating}} + + + diff --git a/src/pages/cases/lunacy.html b/src/pages/cases/lunacy.html new file mode 100644 index 0000000..8bf6274 --- /dev/null +++ b/src/pages/cases/lunacy.html @@ -0,0 +1,376 @@ + + + + + + + Lunacy — кейс + {{> head-links}} + + + + + {{> header-case}} +{{> fab-stack}} +
+
+

Icons8 · desktop

+

Графический редактор Lunacy

+

+ Работа над интерфейсом Lunacy в команде Icons8: user flow, прототипы сложных сценариев, доработка функциональности и + визуальной логики. Ниже — фрагменты экранов из процесса (порядок кадров ориентирован на имена файлов). +

+

+ Продукт: icons8.com/lunacy +

+ +

Обзор

+

Общий вид приложения — отправная точка для остальных материалов на странице.

+
+ Обзор приложения Lunacy +
Обзор окна Lunacy.
+
+

Дальше — отдельные сценарии и итерации интерфейса в том порядке, в каком удобнее читать по смыслу и по именам файлов.

+ +

Blob: настройки на холсте

+

Работа с blob в контексте холста — отдельный сценарий до разборов панели по версиям.

+
+ Настройки blob на холсте +
blob_settings_on_canvas
+
+

Панель настроек для тех же задач развивалась серией макетов v1–v9 — они собраны в сетку ниже.

+ +

Компоненты и сравнение

+

Сравнение компонентов и индикатор обновлений в панели.

+
+ Модальное окно сравнения компонентов +
compare_components_modal_window
+
+
+ Индикатор обновления компонентов в панели +
components_update_indicator_location_panel
+
+

Два связанных экрана: поиск расхождений и отображение статуса обновлений рядом с навигацией по панели.

+ +

Прототип в панели

+

Создание прототипа на холсте и состояния панели для режима прототипа.

+
+ Модальное окно: создать прототип на холсте +
modal_window_for_prototype_create_on_canvas
+
+
+ Модальное окно: состояния панели прототипа +
modal_window_for_prototype_panel_states
+
+

Оба кадра — про увязку прототипа с холстом и с набором состояний панели.

+ +

Shadow Pro: настройки

+

Блок Shadow Pro: панель, идеи, модалки с авто-включением и выключением.

+
+ Shadow Pro: панель настроек +
shadow_pro_settings_panel
+
+
+ Shadow Pro: идеи +
shadow_pro_settings_ideas
+
+
+ Shadow Pro: модалка, авто включено +
shadow_pro_settings_modal_auto_on
+
+
+ Shadow Pro: модалка, авто выключено +
shadow_pro_settings_modal_auto-off
+
+

Четыре кадра подряд показывают развитие одного подпроекта: от панели и набросков к уточнению поведения в модалках.

+ +

Панель настроек blob: версии v1–v9

+

+ Итерации панели по именам файлов blob_settings_panel_v1 … v9. Сетка на ширине текста, три колонки на + широком экране; при сужении окна число колонок уменьшается автоматически. +

+ +

Сетка удобна для сравнения шага к шагу; для деталей клик по ячейке открывает полноэкранный просмотр.

+ +

Слайдер: версии v1–v18 и кадр 14

+

+ Порядок по именам: slider_v1 … slider_v13, затем slider_14 (в ассете без суффикса v), + затем slider_v15 … slider_v18. +

+ +

Такой ряд полезен при разборе эволюции контрола: от ранних раскладок до финальных состояний.

+ +

Слайдеры: общий кадр

+

Сводный экран по слайдерам — после ряда по версиям.

+
+ Все слайдеры: общий вид +
sliders_all_set
+
+

Завершает блок про слайдеры: контекст, как несколько контролов сосуществуют на одном экране.

+
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + diff --git a/src/pages/cases/manu-game-maker.html b/src/pages/cases/manu-game-maker.html new file mode 100644 index 0000000..b793fc6 --- /dev/null +++ b/src/pages/cases/manu-game-maker.html @@ -0,0 +1,118 @@ + + + + + + + Игровой движок MANU — кейс + {{> head-links}} + + + + + {{> header-case}} +{{> fab-stack}} +
+
+

Product Design · Desktop App

+

Игровой движок MANU

+

+ Редизайн и развитие интерфейса: новая концепция работы, обновлённая визуальная система и сотни проработанных пользовательских сценариев. +

+

+ Работа велась вокруг десктопного редактора и связанных панелей: нужно было удержать целостность визуального языка при росте функциональности и не потерять опытные сценарии силовых пользователей. +

+

+ Развёрнутый лонгрид кейса появится на этой странице позже; ниже — обложка для навигации из портфолио. +

+

Обложка

+
+ Интерфейс игрового движка MANU — обложка кейса +
Текущее превью для карточки портфолио
+
+
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + diff --git a/src/pages/cases/mini-projects-showcase.html b/src/pages/cases/mini-projects-showcase.html new file mode 100644 index 0000000..a37d11f --- /dev/null +++ b/src/pages/cases/mini-projects-showcase.html @@ -0,0 +1,379 @@ + + + + + + + Активность — каталог карточек + {{> head-links}} + + + + + {{> header-minimal}} + {{> fab-stack-home-contact}} +
+
+
+
+

Design System · Активность

+

Карточки активности

+

Все типы карточек и живая сетка для подбора раскладки на главной

+

+ Страница для верстки и контента: здесь те же классы и скрипты, что в секции на главной. Меняйте шрифт и тему в панели + справа, сужайте окно — сетка пересчитается. Подписи в заголовках карточек — подсказки, в проде их убрать. +

+ + + +

Как пользоваться

+

+ Сначала выберите тип (stack, horizontal, compact, decor), затем data-mp-cells (1–3) и + порядок li в списке. Карточки с data-mp-extra не влияют на высоту списка до кнопки «Показать все». + Подробности — в docs/mini-projects-cards.md. +

+ +

Типы карточек

+

+ Слева пример карточки с текстом, справа название типа и пояснение по классам. +

+ {{> mini-projects-showcase-specimens}} + +

Ширина в клетках

+

+ Атрибут data-mp-cells на li.mini-projects-grid__item задаёт желаемую ширину от 1 до 3 клеток. + Скрипт не даст карточке быть шире текущего ряда. +

+
+ +

Ряд из 6 клеток (широкий экран)

+
+
3
+
3
+
+
+
2
+
2
+
2
+
+
+
1
+
2
+
3
+
+
+ Цифра в блоке = значение data-mp-cells. Карточка занимает столько клеток подряд в одном ряду. +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Ширина спискаКлеток в ряду
≥ 1180px6
≥ 880px4
≥ 520px2
уже1 (вся строка)
+

+ На шести клетках пара 3 + 3 или тройка 2 + 2 + 2 обычно смотрится ровнее случайного набора. + Декор (mp-card--decor) заполняет пустоты в сетке. +

+
+
+
+ +
+
+

Живая сетка masonry

+

+ Демо блока «Активность» с главной: здесь все типы карточек в одной живой сетке. В подписях у каждой — тип + раскладки и data-mp-cells. Меняйте ширину окна и шрифт в панели темы, смотрите, как сетка + перестраивается, и переносите удачный порядок на главную. +

+ {{> mini-projects-showcase-grid}} +
+
+
+ + {{> footer-spacer}} + {{> footer}} + {{> cookie-notice}} + {{> nav-more-floating}} + + diff --git a/src/pages/cases/mobile-clinic-app.html b/src/pages/cases/mobile-clinic-app.html new file mode 100644 index 0000000..f700974 --- /dev/null +++ b/src/pages/cases/mobile-clinic-app.html @@ -0,0 +1,118 @@ + + + + + + + Мобильное приложение для сети клиник — кейс + {{> head-links}} + + + + + {{> header-case}} +{{> fab-stack}} +
+
+

UX/UI · Mobile App

+

Мобильное приложение для сети клиник

+

+ Запись к врачам и работа с медицинскими услугами: простой путь пользователя, понятная навигация и быстрый доступ к действиям. +

+

+ Фокус проекта — снять тревожность и лишние шаги у пациента: ясные статусы записи, предсказуемые формы и опора на привычные паттерны мобильных приложений. +

+

+ Полный разбор кейса будет опубликован здесь; пока страница служит точкой входа из блока портфолио на главной. +

+

Обложка

+
+ Мобильное приложение для сети клиник — обложка кейса +
Текущее превью для карточки портфолио
+
+
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + diff --git a/src/pages/cases/obsidian-plugin-columns-view.html b/src/pages/cases/obsidian-plugin-columns-view.html new file mode 100644 index 0000000..a14abc8 --- /dev/null +++ b/src/pages/cases/obsidian-plugin-columns-view.html @@ -0,0 +1,151 @@ + + + + + + + Колоночный вид для Obsidian — кейс + {{> head-links}} + {{> head-plyr}} + + + + + {{> header-case}} +{{> fab-stack}} +
+
+

Obsidian · Plugin

+

Колоночный вид — плагин для Obsidian

+

Дизайн и разработка интерфейса для многоколоночной работы с заметками

+ +

+ +

+ +

Контекст

+

+ +

+ +

Задача

+

+ +

+ +

Решение

+

+ +

+ +

Фильтр использования

+
+
+ +
+
Фильтрация заметок в колоночном виде.
+
+ +

Конфигурация отображения

+
+
+ +
+
Настройка колонок и отображения.
+
+ +

Результат

+

+ +

+
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + diff --git a/src/pages/cases/orc-automation-panel.html b/src/pages/cases/orc-automation-panel.html new file mode 100644 index 0000000..8e0b617 --- /dev/null +++ b/src/pages/cases/orc-automation-panel.html @@ -0,0 +1,256 @@ + + + + + + + Веб-панель для оркестрации автоматизаций — кейс + {{> head-links}} + + + + + {{> header-case}} + {{> fab-stack}} +
+
+

Primo RPA · UX/UI · Web App

+

Веб-панель для оркестрации автоматизаций

+

+ Оркестратор Primo RPA: запуск роботов, проекты и контроль процессов в веб-кабинете для админов и разработчиков автоматизаций. +

+ +
+

Контекст

+

+ В стеке Primo RPA оркестратор отвечает за расписание, очередь и статусы RPA-роботов на инфраструктуре клиента. С ним работают не только из студии разработки, но и из браузера: смотрят проекты, перезапускают задания, разбирают сбои. +

+

+ К тому моменту продукт уже был в эксплуатации, но интерфейс заметно устарел: пользователи сталкивались с неудобствами в навигации, визуальным шумом в таблицах и неочевидными сценариями в некоторых разделах. Задача стояла освежить вид интерфейса, сделать его современным и исправить накопившиеся UX-проблемы. +

+
+ +
+

Роль и подход

+

+ Моя роль в этом проекте была скорее кураторской — я не делал дизайн самостоятельно, а выстраивал процесс так, чтобы команда дизайна и разработки работала слаженно. +

+ +

+ Параллельно я искал дизайнера, который взял бы на себя основную визуальную работу. Отбор прошла Елизавета — среди более чем 150 заявок она лучше всего подходила под предстоящий фронт работ. +

+

+ В течение трёх месяцев я погружал новую сотрудницу в детали проекта: ставил задачи, давал обратную связь по создаваемым макетам, делился контекстом по пользовательским сценариям. Вместе с командой разработки мы планировали порядок обновления дизайна сервиса — меняли экраны по приоритету, вкладывая изменения в текущие релизы, без «остановить всё и перерисовать». +

+
+ +
+

Технический стек и инструменты

+

+ В качестве фреймворка для интерфейса был выбран Ant Design последней версии. Он уже использовался в проекте, и его свежий релиз предлагал Theme Editor — возможность настраивать внешний вид компонентов через дизайн-токены без переопределения стилей вручную. Это давало и дизайнерам, и разработчикам единый язык описания интерфейса. +

+

+ Единым источником правды и мостом между дизайном и разработкой стал Storybook. В нём компоненты были не просто задокументированы, а реально работали в изолированной среде — это позволяло дизайнерам видеть реализацию элементов вживую, а разработчикам — быстрее интегрировать компоненты в панель. +

+
+ +
+

Дизайн-система и синхронизация

+

+ Для удобства работы мы синхронизировали токены из Ant Design с токенами в Figma — цвета, отступы, типографика и радиусы скругления были приведены к единым значениям. Работало это так: если в Figma токены обновлялись, их можно было выгрузить в JSON и без проблем сразу загрузить в код — вместо того, чтобы разработчик вручную искал изменения и правил каждый токен индивидуально. Такой подход также позволил смотреть на дизайн более системно. +

+ +

+ Компоненты в Figma создавались с нуля — по референсам Ant Design, но без использования готовых библиотек. Отказ от готовых решений был осознанным: нам нужна была полная настройка под наш стиль работы и возможность использовать новые функции Figma, которые не поддерживались в библиотеках из сообщества Figma. +

+

+ Для Storybook мы отобрали и настроили плагины, которые были уместны для наших задач — контроль доступности, просмотр состояний компонентов, переключение тем и локалей. Это сделало Storybook не просто витриной компонентов, а полноценным инструментом дизайн-ревью. +

+
+ +
+

Рабочая среда дизайнера

+

+ Мы настроили среду так, чтобы дизайнер мог видеть реализацию компонентов вживую у себя на компьютере, используя локальный Storybook и Git. Это позволяло точнее контролировать, как задуманный дизайн воплощается в коде, и оперативно замечать расхождения на ранних этапах. +

+

+ Обсуждался также шаг ускорить поддержку Storybook тем, чтобы дизайнер сам мог описывать JSX для реализованного компонента — это сокращало путь от макета до документированного компонента в сторибуке. +

+

+ Мы отладили рабочий процесс по передаче иконок в библиотеку. Особенность заключалась в том, чтобы иконки можно было отобразить в Storybook с фильтрацией и сортировкой. При этом дизайнер мог обновлять иконки без привлечения разработчика — просто пушил новые файлы в репозиторий. +

+

+ Увидеть обновлённую иконку сразу в браузере позволяло лучше её оптимизировать и убрать косяки отображения при использовании булевых операций. +

+

+ Для Figma также был разработан подход и правила, которые не только ограничивали дизайнера, но и позволяли гарантированно делать консистентные и рабочие иконки. +

+
+ +
+

UX-улучшения

+

+ За время обновления интерфейса Елизавета предложила ещё и ряд улучшений пользовательского опыта. Часть из них была успешно внедрена — например, более понятная группировка элементов в сложных формах и переработанные состояния загрузки. Но в приоритете было не ломать старый UX, к которому привыкли пользователи, поэтому многие идеи сохранились в бэклог для следующей итерации. +

+
+ +
+

Список проектов

+

+ Таблица проектов — один из самых частых экранов. На старой версии много колонок, плотная сетка и мелкий текст: статус и имя проекта читаются с трудом, особенно на ноутбуке. +

+

В новой версии:

+
    +
  • колонки свели к тому, что нужно для ежедневной работы;
  • +
  • статусы и действия вынесли в предсказуемые зоны строки;
  • +
  • отступы и типографику подтянули под остальную панель на Ant Design.
  • +
+ +

Было

+
+ Список проектов в оркестраторе — предыдущая версия таблицы +
+ +

Стало

+
+ Список проектов в оркестраторе — обновлённая таблица +
+
+ +
+

Результаты и рефлексия

+

+ Экран проектов стал проще сканировать: меньше визуального шума, быстрее находить нужный проект и его состояние. После раскатывания нового дизайна среди нескольких клиентов мы получили положительные отзывы и множество идей для дальнейших улучшений. +

+

+ Я оставил проект, когда Елизавета уже уверенно чувствовала себя в нём и могла самостоятельно вести дизайнерские задачи. Периодически я отвечал на точечные вопросы, но в целом передача прошла гладко. +

+

+ Спустя год с небольшим процессы в команде заметно изменились. По словам ребят, в создании и передаче дизайна теперь активное участие принимают инструменты с нейросетями — такие как Claude Design. То, что мы начинали выстраивать вручную через токены, Storybook и синхронизацию сред, сейчас в какой-то мере автоматизируется. +

+

+ Считаю, что проделанная работа была выполнена достаточно оперативно и качественно — в условиях постоянных изменений на рынке и внутри компании нам удалось не просто обновить интерфейс, но и выстроить устойчивый процесс, который продолжил работать уже без моего участия. +

+
+
+
+ + {{> projects-section-mp}}{{> projects-section}} + {{> contact-section}} + {{> footer-spacer}} + {{> footer}} + {{> cookie-notice}} + {{> nav-more-floating}} + + diff --git a/src/pages/cases/task-distribution-concept.html b/src/pages/cases/task-distribution-concept.html new file mode 100644 index 0000000..1895489 --- /dev/null +++ b/src/pages/cases/task-distribution-concept.html @@ -0,0 +1,118 @@ + + + + + + + Концепт сервиса распределения задач — кейс + {{> head-links}} + + + + + {{> header-case}} +{{> fab-stack}} +
+
+

UX/UI · Analytics

+

Концепт сервиса распределения задач

+

+ Продуктовый концепт: постановка, распределение и отслеживание задач с акцентом на прозрачность процессов и удобство командной работы. +

+

+ Задача концепта — показать, как команда видит поток работ без «чёрных ящиков»: кто что взял, где узкие места и какие статусы критичны для следующего шага. +

+

+ Детальный кейс появится здесь позже; страница уже связана с карточкой в портфолио на сайте. +

+

Обложка

+
+ Концепт сервиса распределения задач — обложка кейса +
Текущее превью для карточки портфолио
+
+
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + diff --git a/src/pages/cases/task-tracker.html b/src/pages/cases/task-tracker.html new file mode 100644 index 0000000..a695927 --- /dev/null +++ b/src/pages/cases/task-tracker.html @@ -0,0 +1,548 @@ + + + + + + + Таск-трекер для бек-офис системы — кейс + {{> head-links}} + {{> head-plyr}} + + + + + {{> header-case}} +{{> fab-stack}} +
+
+

Тестовое задание · back-office

+

Таск-трекер для внутренней бек-офис системы

+

Задание

+

+ Реализовать интерфейс для планирования и распределения задач между сотрудниками операционного отдела, работающими в некой бек-офис системе. Существует большое количество разноплановых задач, которые можно сгруппировать: Тип-1, Тип-2, Тип-3, Тип-4, Тип-5, Тип-6, Тип-7. У каждой задачи есть свой, выставляемый автоматически, приоритет. Пользователю доступны только задачи из определенных категорий. +

+

Нужно реализовать:

+
    +
  • + Общий экран: +
      +
    • где пользователь может посмотреть все открытые общие задачи и взять какие-то себе.
    • +
    • персональный ToDo лист, где отображаются как взятые вручную задачи, так и автоматически назначенные.
    • +
    • у взятой задачи есть возможность передать ее другому сотруднику или вернуть в общий список.
    • +
    +
  • +
  • Экран, где можно посмотреть, что у кого в работе.
  • +
+ +

Введение

+

+ Так как у меня лично есть обширный опыт работы с таск-трекерами, то я опираюсь на свой опыт и опыт моих коллег с учётом требований задания. +

+ +

Референсы

+
+ Референсы +
+
    +
  • Таск-трекеры (Trello, Monday, YouTrack и др.)
  • +
  • Сервисы для визуальной работы с базами данных (Notion, Airtable и др.)
  • +
+ +

Решение

+ +

Скринкаст

+
+
+ +
+
+ + + +

Вкладки (Tabs)

+

На вкладке All tasks сотрудник может ознакомиться со всеми доступными задачами.

+
+ Untitled +
+

+ На вкладке My tasks отображаются только те задачи, что закреплены за текущим сотрудником. Группировка идёт по статусам задач (статус в карточке задачи скрыт). +

+
+ Untitled +
+

На вкладке Task by assign отображены все задачи c разбивкой по исполнителю.

+
+ Untitled +
+

В правой части имеются опции для текущей вкладки.

+
+ Untitled +
+

+ Все изменения сохраняются после ухода с вкладки и после закрытия всей страницы Tasks. Эти настройки индивидуальны и каждый сотрудник может настроить страницу как ему удобно. +

+
    +
  • Group - позволяет создать дополнительную группировку по свойству таски (категория, приоритет, исполнитель, статус, дата создания, дата изменения).
  • +
  • View - позволяет изменить отображение текущих задач на другой вид: доска, список, таблица.
  • +
  • Filter - позволяет скрывать задачи по свойствам.
  • +
  • + Sort - позволяет определять порядок отображения задач по свойствам. Если включена сортировка по статусу High, Medium, Low то можно выбрать либо по алфавиту, либо в обратном порядке, а также можно создать свой порядок. С датами и цифрами работает принцип по возрастанию/убыванию. +
  • +
  • + Search on page - позволяет отобразить только те задачи, в названии или описании которых есть поисковое слово или фраза. (Можно улучшить функционал поиска, добавив поисковые операторы, если исследования докажут эту необходимость) +
  • +
+

+ На странице работает постепенная подгрузка задач. По мере скрола вниз, будут подгружаться новые задачи. Кол-во задач указывается в заголовках, это может быть полезно, чтобы оценить как далеко надо скролить, чтобы все посмотреть. Задач может быть очень много и тогда возможно имеет смысл добавить ещё и переход по страницам. +

+ +

Варианты отображения (Views)

+

+ Разные виды отображения одних и тех же задач могут быть полезны для разных контекстов использования страницы Tasks и также в угоду личным предпочтениям сотрудника, что повышает его эффективность. Сотрудник, которого не раздражает интерфейс работает продуктивнее и приносит больше пользы. +

+
+ Untitled +
+ +

+ Вид Board позволяет удобнее работать с функцией Drag&Drop (см. ниже). Также визуально легче определить кол-во задач в категории, подразумеваю что это может быть полезно. В случае использования группировки задач по статусам выполнения, перемещение карточек слева направо создаёт естественное горизонтальное течение задач из точки А в точку Б. +

+
+ Untitled +
+

+ Вид List позволяет увидеть больше информации на меньшей площади экрана. При этом этот вид визуально и функционально легче табличного вида, а значит меньше когнитивной нагрузки на пользователя. Также здесь все заголовки задач начинаются в крайнем левом положении, поэтому становится легко пробежаться глазами по списку. +

+
+ Untitled +
+

+ Вид Table позволяет сразу же работать со всеми полями задачи, без раскрытия её в модальном окне или отдельной странице. Таблица подразумевает пользовательскую настройку ширины и порядка столбцов, что может быть удобно в некоторых кейсах использования. +

+
+ Untitled +
+ +
+
+ +
+
+ + +

Drag&Drop

+

+ Во всех видах можно перетаскивать элементы (карточки/элементы списка/строки и столбцы таблицы). Это способствует более продуктивной работе и выглядит естественным для пользователя. Например, если требуется раскидать задачи между сотрудниками (для админа или менеджера), поменять статус для нескольких задач разом или в короткий отрезок времени. +

+

Board view

+
+
+ +
+
+ +

List view

+
+
+ +
+
+ +

Продвинутый интерактивный прототип в ProtoPie

+

+ Схематичное представление того как работает Drag&Drop. Такой прототип помогает дизайнеру лучше понять какие нюансы нужно учесть в юзерфлоу, а также и при подготовке спецификации для разработчика. Также попробовав данный прототип можно прийти к тому, что функционал должен работать совсем иначе и переделать его сразу. Это экономит общее время разработки. +

+
+
+ +
+
+ +

+ В прототипе можно перемещать только голубую карточку и не все положения работают корректно. Можно посмотреть запись, которая доступна на той же странице прототипа. +

+ +

Стиль

+

+ Визуальный стиль может быть любым, не меняя самого каркаса. Например, чуть более красочным и с более выразительными шрифтами. +

+

Светлая цветная тема

+
+ Светлая цветная тема +
+ +

Нейтральная тёмная тема

+
+ Нейтральная тёмная тема +
+ + +

Исследования

+

+ На этапе прототипов Figma можно провести интервью с несколькими сотрудниками, например 5 человек. Предварительно в прототип нужно добавить реальные задачи из текущей системы, порядка 20 должно хватить. Далее можно созвониться по видеосвязи с шэрингом экрана респондента или встретиться лично и задать несколько заданий и вопросов. Во время сессии респондент может тыкать в прототип, но если что-то не сработает интервьюер может зафиксировать попытку и объяснить, что этот функционал пока не работает, а также поинтересоваться что респондент ожидает увидеть дальше. +

+

Задания

+
    +
  1. Найти свои актуальные задачи со страницы Tasks вкладки All tasks
  2. +
  3. Назначить себе задачи, чтобы взять в работу
  4. +
  5. Найти задачу про что-то конкретное (интервьюер приводит пример), которую он уже выполнил ранее
  6. +
  7. Показать задачи, которые относятся только к определённой категории и должны быть сделаны до конца недели
  8. +
  9. Попросить поменять приоритет у нескольких задач одновременно
  10. +
  11. Оценить визуальную привлекательность интерфейса по шкале от 1 до 10
  12. +
  13. Оценить общее впечатление от предложенного концепта по шкале от 1 до 10
  14. +
  15. Предложить ещё функции, которые были бы полезны
  16. +
+

Аналитика

+

Для оценки актуальности реализованного функционала необходимо собирать следующие показатели.

+
    +
  • + Кол-во просмотров страницы Tasks page_views_tasks с возможностью разбиения +
      +
    • + по вкладкам +
        +
      • All tasks all_tasks_tab
      • +
      • My tasks my_tasks_tab
      • +
      • Tasks by assign tasks_by_assign
      • +
      +
    • +
    • + по ролям +
        +
      • Admin admin
      • +
      • Manager manager
      • +
      • User user
      • +
      +
    • +
    • + по попыткам поиска +
        +
      • Search Used search used
      • +
      +
    • +
    +
  • +
  • + Кол-во включённых пользовательских настроек Custom Settings custom_settings с возможностью разбиения +
      +
    • + по вкладкам +
        +
      • All tasks all_tasks_tab
      • +
      • My tasks my_tasks_tab
      • +
      • Tasks by assign tasks_by_assign
      • +
      +
    • +
    • + по ролям +
        +
      • Admin admin
      • +
      • Manager manager
      • +
      • User user
      • +
      +
    • +
    • + по типам +
        +
      • Group group
      • +
      • Filter filter
      • +
      • Sort sort
      • +
      +
    • +
    +
  • +
  • + Кол-во включенных видов View Used view_used с возможностью разбиения +
      +
    • + по вкладкам +
        +
      • All tasks all_tasks_tab
      • +
      • My tasks my_tasks_tab
      • +
      • Tasks by assign tasks_by_assign
      • +
      +
    • +
    • + по ролям +
        +
      • Admin admin
      • +
      • Manager manager
      • +
      • User user
      • +
      +
    • +
    +
  • +
+

+ Далее в течение полугода (может и раньше, в зависимости от активности пользователей) можно будет увидеть результат и провести исследование (в виде интервью) по функциям, которые используются реже всего и тем на которые есть жалобы, чтобы получить качественные данные и составить полную картину происходящего. +

+ +

Дополнительные детали

+

+ При создании мокапов в Figma были использованы: возможности автолэаутов; интерактивные компоненты, плагины (Iconify, Fitter, Protofly, Shadow Maker, Dark Side и др.), файл Community (+40 Types of Cursor). Слои названы и организованы для более удобной работы где-то на 60%. Используется сетка 8pt + есть размеры 2pt, 4pt. Имеются цветовые стили для светлой и тёмной темы. Присутствует адаптивность под изменяющиеся размеры окна (мобильной версии нет). +

+ +
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + + + + diff --git a/src/pages/cases/template-elements-demo.html b/src/pages/cases/template-elements-demo.html new file mode 100644 index 0000000..6d8fe3a --- /dev/null +++ b/src/pages/cases/template-elements-demo.html @@ -0,0 +1,282 @@ + + + + + + + Демо элементов кейса — template + {{> head-links}} + {{> head-plyr}} + + + + + {{> header-minimal}} +{{> fab-stack-home-contact}} +
+
+

Демо · template

+

Пример кейса: демо элементов

+

Рыба-текст и блоки для быстрой сборки лонгрида

+

Медиа для демо лежат в public/assets/ (сборка страниц их не копирует). См. public/assets/README.md.

+ +

Контекст

+

+ Этот раздел показывает пример рыбы для вступления. Здесь можно коротко описать продукт, аудиторию и ограничения проекта. + Текст нейтральный: цель — быстро набросать структуру и проверить визуальный ритм страницы. +

+ +

Задача

+

+ Нужно собрать демонстрационный лонгрид с основными UI-элементами: карточками ссылок, медиа-блоками и примерами оформления контента. + Дополнительно важно проверить, как блоки ведут себя на узких и широких экранах. +

+ +

Решение

+

Ниже собраны готовые примеры, которые можно копировать в реальные кейсы.

+ +

Карточки ссылок

+ + +

Картинка: 50% от оригинала (без превью)

+
+ Демо GIF в натуральном размере +
Изображение в уменьшенном натуральном размере, по центру.
+
+ +

Картинка: по ширине контента (с превью)

+
+ Демо изображения по ширине контента +
Изображение по ширине контента. Клик открывает viewer.
+
+ +

Картинка: чуть шире контента (с превью)

+
+ Демо изображения шире контента +
Изображение немного выходит за пределы контентной колонки.
+
+ +

Длинный скрин: свёрнутая высота и кнопка внутри превью

+

+ Блок data-case-tall-media: ширина задаётся атрибутом data-case-tall-width="wide" (как «широкая» картинка) или content (по колонке). В свёрнутом виде видна верхняя часть кадра, внизу превью — плотный «туман». Кнопка «Развернуть» / «Свернуть» с иконкой-шевроном поверх нижней части кадра, внутри рамки; после раскрытия туман скрывается, после сворачивания страница прокручивается к превью. Высоту превью — на .case-media-tall__clip через --case-tall-max (по умолчанию min(70vh, 32rem)). +

+
+
+
+ Демо: длинный вертикальный скрин интерфейса + +
+
+ +
+
+
Длинное изображение img-long.webp (исходник PNG рядом в public/assets/template-elements-demo/).
+
+ +

Галерея: сетка по ширине контента

+

+ Колонок на широком экране задаётся на figure: атрибут style="--case-gallery-cols: 3". Ниже порогов сетка схлопывается до двух и одной колонки. Клик по миниатюре открывает общий viewer кейса. +

+ + +

Галерея: сетка на ширину страницы с боковыми отступами

+

+ Класс case-media-gallery--wide — та же логика выхода за колонку, что у одиночного case-media--wide. Здесь две колонки на широком экране (--case-gallery-cols: 2). +

+ + +

Callout: важный абзац с эмоджи

+ + +

Видео: карточка с тенью и фиксированными малыми углами

+
+
+ +
+
Пример видео-карточки в стиле кейса.
+
+ +

Результат

+

+ Шаблон готов для копирования в новый кейс: остаётся заменить рыбу на фактический текст, подставить реальные ссылки и медиа проекта. +

+
+
+ + {{> projects-section-mp}}{{> projects-section}} +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + + + + diff --git a/src/pages/cookie-policy.html b/src/pages/cookie-policy.html new file mode 100644 index 0000000..3a3dd52 --- /dev/null +++ b/src/pages/cookie-policy.html @@ -0,0 +1,137 @@ + + + + + + + Политика cookie — Николай Мамадаев + {{> head-links}} + + + + + {{> header-minimal}} +{{> fab-stack-home-contact}} +
+ +
+ + {{> footer}} +{{> cookie-notice}} + + + + diff --git a/src/pages/index.html b/src/pages/index.html new file mode 100644 index 0000000..3209913 --- /dev/null +++ b/src/pages/index.html @@ -0,0 +1,545 @@ + + + + + + + Николай Мамадаев — продуктовый дизайнер + {{> head-links}} + + + + {{> header-home}} +{{> fab-stack}} +
+
+
+
+

Николай Мамадаев

+

+ Создаю интерфейсы для продуктов + + web + +

+
    +
  • UX/UI
  • +
  • 10+ лет опыта
  • +
  • Продуктовое мышление
  • +
  • Дизайн-системы
  • +
  • Менторство и наставничество
  • +
  • AI инструменты и вайбкодинг
  • +
+ +
+ +
+
+ + {{> projects-section-mp}}{{> projects-section}} + {{> mini-projects-section}} + +
+
+

Навыки

+
+
+
+

Николай М:

+

+ В моём опыте есть и запуск первых версий продукта с нуля, и развитие уже зрелых решений, где важно не + сломать привычный сценарий, а аккуратно улучшить его. +

+ +
+
+
+
+

+ Ниже я собрал примеры задач от бизнеса и то, как я их решал +

+ +
+
+
+ +
+
+
+

+ +

+ +
+
+ +
+
+

+ +

+ +
+
+ +
+
+

+ +

+ +
+
+ +
+
+

+ +

+ +
+
+ +
+
+
+ +
+
+

Опыт работы

+
    +
  1. + +
    + Февраль 2023 — Ноябрь 2025 + + 2 года 10 месяцев +
    +

    + Primo RPA + +

    +

    + Платформа для автоматизации бизнес‑процессов с комплексом продуктов: студией для создания роботов, оркестратором для их управления, Idea Hub для отбора процессов и AI‑серверами для работы с моделями и распознаванием данных. +

    +
    +
  2. +
  3. + +
    + Июль 2022 — Январь 2023 + + 7 месяцев +
    +

    + Icons8 (Lunacy) + +

    +

    + Векторный редактор для UI/UX и веб‑дизайна с поддержкой Sketch‑файлов, встроенной библиотекой иконок/фото/иллюстраций и набором AI‑инструментов для ускорения рутинных задач. +

    +
    +
  4. +
  5. + +
    + Январь 2019 — Декабрь 2021 + + 3 года +
    +

    + MANU Video Game Maker + +

    +

    + No-code/low-code платформа для создания 2D и 3D игр без необходимости писать код. +

    +
    +
  6. + + + +
+
+ +
+
+
+ +{{> contact-section}} +{{> footer-spacer}} +{{> footer}} +{{> cookie-notice}} +{{> nav-more-floating}} + + + + diff --git a/src/partials/contact-section.html b/src/partials/contact-section.html new file mode 100644 index 0000000..34b76d0 --- /dev/null +++ b/src/partials/contact-section.html @@ -0,0 +1,11 @@ + diff --git a/src/partials/content-edit-fab-stack.html b/src/partials/content-edit-fab-stack.html new file mode 100644 index 0000000..8f392a0 --- /dev/null +++ b/src/partials/content-edit-fab-stack.html @@ -0,0 +1,21 @@ +
+ +
diff --git a/src/partials/cookie-notice.html b/src/partials/cookie-notice.html new file mode 100644 index 0000000..dc058f6 --- /dev/null +++ b/src/partials/cookie-notice.html @@ -0,0 +1,12 @@ + diff --git a/src/partials/fab-stack-home-contact.html b/src/partials/fab-stack-home-contact.html new file mode 100644 index 0000000..7d3ef02 --- /dev/null +++ b/src/partials/fab-stack-home-contact.html @@ -0,0 +1,62 @@ +
+
+ + +
+ + + +
+{{> content-edit-fab-stack}} diff --git a/src/partials/fab-stack.html b/src/partials/fab-stack.html new file mode 100644 index 0000000..cc255a0 --- /dev/null +++ b/src/partials/fab-stack.html @@ -0,0 +1,62 @@ +
+
+ + +
+ + + +
+{{> content-edit-fab-stack}} diff --git a/src/partials/footer-spacer.html b/src/partials/footer-spacer.html new file mode 100644 index 0000000..95d1a74 --- /dev/null +++ b/src/partials/footer-spacer.html @@ -0,0 +1,3 @@ + diff --git a/src/partials/footer.html b/src/partials/footer.html new file mode 100644 index 0000000..5c617de --- /dev/null +++ b/src/partials/footer.html @@ -0,0 +1,7 @@ + diff --git a/src/partials/head-links.html b/src/partials/head-links.html new file mode 100644 index 0000000..c1a886a --- /dev/null +++ b/src/partials/head-links.html @@ -0,0 +1,11 @@ +{{> theme-init-script}} + + + + + + + + + + {{> head-scripts}} diff --git a/src/partials/head-plyr.html b/src/partials/head-plyr.html new file mode 100644 index 0000000..52057be --- /dev/null +++ b/src/partials/head-plyr.html @@ -0,0 +1 @@ + diff --git a/src/partials/head-scripts.html b/src/partials/head-scripts.html new file mode 100644 index 0000000..f379195 --- /dev/null +++ b/src/partials/head-scripts.html @@ -0,0 +1,2 @@ + + diff --git a/src/partials/header-case.html b/src/partials/header-case.html new file mode 100644 index 0000000..3571e0e --- /dev/null +++ b/src/partials/header-case.html @@ -0,0 +1,12 @@ + +
+ +
diff --git a/src/partials/header-home.html b/src/partials/header-home.html new file mode 100644 index 0000000..e5f53e7 --- /dev/null +++ b/src/partials/header-home.html @@ -0,0 +1,25 @@ + + + +
+ +
diff --git a/src/partials/header-minimal.html b/src/partials/header-minimal.html new file mode 100644 index 0000000..dd47c4c --- /dev/null +++ b/src/partials/header-minimal.html @@ -0,0 +1,12 @@ + + +
+
+ + +
+
diff --git a/src/partials/mini-projects-section.html b/src/partials/mini-projects-section.html new file mode 100644 index 0000000..df2317e --- /dev/null +++ b/src/partials/mini-projects-section.html @@ -0,0 +1,113 @@ +
+ +
diff --git a/src/partials/mini-projects-showcase-grid.html b/src/partials/mini-projects-showcase-grid.html new file mode 100644 index 0000000..11a6d65 --- /dev/null +++ b/src/partials/mini-projects-showcase-grid.html @@ -0,0 +1,190 @@ +
    +
  1. + + +
    +

    + [2] stack · ссылка + +

    +
      +
    • веб-сайт
    • +
    +

    Базовая пара в ряду из шести клеток.

    +
    +
    +
  2. +
  3. +
    + +
    +

    [2] stack

    +
      +
    • заметка
    • +
    +

    Stack без внешней ссылки.

    +
    +
    +
  4. +
  5. +
    + +
    +

    [2] horizontal

    +
      +
    • утилита
    • +
    +

    Horizontal на две клетки, без ссылки.

    +
    +
    +
  6. +
  7. +
    +
    +

    [2] compact

    +
      +
    • шаблон
    • +
    +

    Текстовая карточка на две клетки.

    +
    +
    +
  8. +
  9. + +
    +

    + [1] compact · ссылка + +

    +
      +
    • cli
    • +
    +

    Узкая колонка со ссылкой.

    +
    +
    +
  10. +
  11. +
    +
    +

    [1] compact

    +
      +
    • документ
    • +
    +

    Compact на одну клетку.

    +
    +
    +
  12. +
  13. + +
  14. +
  15. + + +
    +

    + [3] stack · ссылка + +

    +
      +
    • приложение
    • +
    +

    + Половина шестиклеточной строки. Длиннее описание, чтобы проверить перенос и высоту после смены шрифта. +

    +
    +
    +
  16. +
  17. + + +
    +

    + [3] horizontal · ссылка + +

    +
      +
    • плагин
    • +
    +

    Широкий horizontal: превью и текст в одной полосе.

    +
    +
    +
  18. +
  19. +
    + +
    +

    [3] horizontal

    +
      +
    • виджет
    • +
    +

    Horizontal на три клетки, без ссылки.

    +
    +
    +
  20. +
diff --git a/src/partials/mini-projects-showcase-specimens.html b/src/partials/mini-projects-showcase-specimens.html new file mode 100644 index 0000000..452d7fa --- /dev/null +++ b/src/partials/mini-projects-showcase-specimens.html @@ -0,0 +1,217 @@ +
+
+ +
+

+ Stack со ссылкой. Превью на всю ширину, текст снизу. Для внешней ссылки: + mp-card--link и mp-card__ext в заголовке (как в блоке опыта). +

+
+
+ +
+
+

mp-card--stack без ссылки

+
+ +
+

Stack без ссылки

+
    +
  • заметка
  • +
+

+ Связка баз и rollup для недельного обзора, только для личного пользования. +

+
+
+
+
+

+ Stack без ссылки. Тот же вид. Обёртка div или article, без + mp-card--link. +

+
+
+ +
+ +
+

+ Horizontal со ссылкой. Миниатюра слева, текст справа. На узком экране карточка + складывается в столбик. +

+
+
+ +
+
+

mp-card--horizontal без ссылки

+
+ +
+

Horizontal без ссылки

+
    +
  • шаблон
  • +
+

+ Статический сайт с расписанием и формой заявки на отдельном сервисе. +

+
+
+
+
+

+ Horizontal без ссылки. Тот же расклад, карточка не ведёт на внешний URL. +

+
+
+ +
+ +
+

+ Compact со ссылкой. Только текст, без mp-card__media. В сетке часто с + data-mp-cells="1". +

+
+
+ +
+
+

mp-card--compact без ссылки

+
+
+

Compact без ссылки

+
    +
  • документ
  • +
+

+ Markdown-список проверок перед релизом мелких правок в интерфейсе. +

+
+
+
+
+

+ Compact без ссылки. Короткая заметка или чеклист без внешней ссылки. +

+
+
+ +
+
+

mp-card--decor

+ +
+
+

+ Декоративная ячейка. Заглушка в сетке, без проекта и ссылки. Внутри + span.mp-card__decor-pattern. +

+
+
+
diff --git a/src/partials/nav-more-floating.html b/src/partials/nav-more-floating.html new file mode 100644 index 0000000..45282dc --- /dev/null +++ b/src/partials/nav-more-floating.html @@ -0,0 +1 @@ + diff --git a/src/partials/page-scripts.html b/src/partials/page-scripts.html new file mode 100644 index 0000000..f379195 --- /dev/null +++ b/src/partials/page-scripts.html @@ -0,0 +1,2 @@ + + diff --git a/src/partials/projects-section-mp.html b/src/partials/projects-section-mp.html new file mode 100644 index 0000000..362dbb5 --- /dev/null +++ b/src/partials/projects-section-mp.html @@ -0,0 +1,135 @@ +
+
+

Портфолио

+
    +
  1. + + +
    +

    Платформа для работы с AI

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.

    +
    +
    +
  2. +
  3. + + +
    +

    Графический редактор Lunacy

    +
      +
    • UX/UI
    • +
    • Desktop App
    • +
    +

    Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.

    +
    +
    +
  4. +
  5. + + +
    +

    Игровой движок MANU

    +
      +
    • Product Design
    • +
    • Desktop App
    • +
    +

    Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.

    +
    +
    +
  6. +
  7. + + +
    +

    Мобильное приложение для сети клиник

    +
      +
    • UX/UI
    • +
    • Mobile App
    • +
    +

    Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.

    +
    +
    +
  8. +
  9. + +
    +

    Веб-панель для оркестрации автоматизаций

    +
      +
    • UX/UI
    • +
    • Web App
    • +
    +

    Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.

    +
    +
    +
  10. +
  11. + +
    +

    Концепт сервиса распределения задач

    +
      +
    • UX/UI
    • +
    • Analytics
    • +
    +

    Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.

    +
    +
    +
  12. +
  13. + +
    +

    Таск-трекер для бек-офис системы

    +
      +
    • Product Design
    • +
    • Web App
    • +
    +

    Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.

    +
    +
    +
  14. +
+
+
\ No newline at end of file diff --git a/src/partials/projects-section.html b/src/partials/projects-section.html new file mode 100644 index 0000000..19839f8 --- /dev/null +++ b/src/partials/projects-section.html @@ -0,0 +1,243 @@ + diff --git a/src/partials/theme-init-script.html b/src/partials/theme-init-script.html new file mode 100644 index 0000000..21340f4 --- /dev/null +++ b/src/partials/theme-init-script.html @@ -0,0 +1,56 @@ + diff --git a/texts/cases/ai-platform-primo-rpa.md b/texts/cases/ai-platform-primo-rpa.md new file mode 100644 index 0000000..c8c99a1 --- /dev/null +++ b/texts/cases/ai-platform-primo-rpa.md @@ -0,0 +1,57 @@ +# Разработка интерфейса для Primo RPA AI Server + +- **Источник:** `src/pages/cases/ai-platform-primo-rpa.html` (сборка → `public/cases/ai-platform-primo-rpa.html`) +- **eyebrow:** Product Design · AI +- **meta description:** Кейс по разработке интерфейса для AI Server в Primo RPA: структура, процесс и ключевые UX/UI-решения. + +--- + +## Обзор (`#obzor`) + +- Что это был за продукт и зачем тебя позвали. + - Внутри компании разработали новый продукт, который позволял сильно улучшить работу с моделями для распознавания текстов на документах. Можно было загрузить датасет из документов компании разметить там поля и обучить модель. После этого обученная модель уже использовалась в других продуктах компании. Качество распознавания при таком подходе был существенно выше и также соответствовал требованиям безопасности по хранению данных только внутри контура компании. Уже при мне в сервисе появился функционал, который позволял обучать любую базовую нейросеть под конкретные задачи компании. Это был файнтюнинг и работа со скилами: суммаризация, извлечение, генарация и прочие. +- Роль, сроки, главный итог в двух абзацах. + - Меня пригласили в проект как UX/UI дизайнера, потому что проект делали только разработчики своими силами. В резуальтате моей работы у сервиса существенно снизился порог входа и пользоваться продуктом уже могли гараздо больший круг лиц, даже не имея специальных знаний в области ии и OCR. +- Подсказки в HTML: задача бизнеса, главное достижение, что намеренно не освещаешь. + - не понимаю что в этом блоке , напиши сам, я поправлю + +## Было и стало (`#bylo-stalo`) + +- Как выглядел сервис «до», типовые проблемы. + - Сервис был собран на фрэймворке Ant Design под React и использовал визуальную стилизацию от Hope UI (тема для Bootstrap). На тот момент у компании было уже несколько веб-продуктов и была цель унифицировать и освежить интерфейс продуктов. Поэтому в разработке интерфейса применялись компоненты из этих фрэймворков. + - Основная проблема сервиса, которую надо было решить это то что настройка проекта крайне сложная задача с большим количеством шагов и мелких задач. А ещё на платформе было три типа проектов и каждый тип настраивался по своему. Таким образом от момента создания проекта и его реального использования проходило много времени и требовалась помощь специалистов самой компании, отдела внедрения. Запутанная навигация внутри проекта и дублирование функцинала существенно снижали продуктивность работы отдела внедрения и не позволяли масштабировать продукт. Также невозможно было продвигать продукт на широкую аудиторию. +- Что переделано и как это сняло боли. + - Я погрузился в продукт. Очень много и подробно обсуждая с командой весь функционал. Мои знания в области ИИ и работы со схожими веб-платформами хорошо мне в этом помогали. + - Составил юзерфлоу по тому как выполняются сценарии в текущем продукте и они помогли подсветить команде где есть путаница в интерфейсе и пути пользователя. Также благодаря этой скурпулёзной работе удалось переработать и сами процессы настроек проектов. Часть функций была также автоматизирована и спрятана от пользователя, чтобы уменьшить шанс совершения ошибок и не заставлять пользователя выполнять рутинные дейтсвия. + - Новый подход полностью изменил и восприятие продукта и процесс настройки проектов. Теперь интерфейс плавно вёл пользователя по этапам настройки, но в том же время не ломал старые сценарии. Так как тут не получается сделать типичный визард из последовательных шагов и пользователю всё равно надо возвращаться назад и править что-то для улучшения результата. +- **Вопросы команде:** текущее состояние, живые паттерны, метрики, backlog, что сделали бы иначе. + - Сократилось ли кол-во запросов к поддержке + - Получается ли у пользователей самостоятельно настроить проект от начала и до конца + - Позволяет ли новый интерфейс создавать новые типы проектов придерживаясь уже заложенных паттернов +- Слот под медиа: скрин/видео «как было». + +## Паттерны (`#patterns`) + +- Для каждого паттерна: зачем, сценарий, отличие от старого подхода. +- Уже вставлены: маппинг полей (видео), датасет/обучение/качество, inference, полноэкранный режим. +- **Слоты «Медиа позже»:** LLM список/статусы, мастер обучения, OCR/разметка. + +## Процесс и передача (`#process`) + +- Синки, макеты, спека, handoff во фронт. +- Поиск и собеседование следующего дизайнера, онбординг. +- **Вопросы следующему дизайнеру:** первые две недели, полезные артефакты, что пересобрали, UX в трёх предложениях. +- Слот под медиа: Notion/Figma/timeline. + +## Заключение (`#zaklyuchenie`) + +- Итог для читателя в сжатом виде. + +## Чеклист (`#cheklist`) + +- Пользователи, ограничения, сценарии LLM/OCR, исследования, метрики. + +## Ассеты (`#media`) + +- `public/assets/ai-platform-primo-rpa/` — обложка `cover.webp` и прочие файлы; основные кадры встроены в раздел «Паттерны». + diff --git a/texts/cases/lunacy.md b/texts/cases/lunacy.md new file mode 100644 index 0000000..be97f1d --- /dev/null +++ b/texts/cases/lunacy.md @@ -0,0 +1,59 @@ +# Графический редактор Lunacy + +- **Источник (разметка):** `src/pages/cases/lunacy.html` → после сборки `public/cases/lunacy.html` +- **eyebrow:** Icons8 · desktop +- **meta description:** Кейс: работа над интерфейсом Lunacy в Icons8 — сценарии, итерации UI и скриншоты процесса. + +**Заметка по путям к медиа:** ниже пути от корня сгенерированного сайта (`public/`), папка `assets/lunacy/`. Картинки подгружаются последовательно (`data-case-sequential-images` + `data-src`); `cover.webp` на странице кейса не используется (только обложка карточки на главной). + +## Оглавление секций + +1. **Ввод** — роль в Icons8, ссылка на продукт. +2. **Обзор** — `Lunacy_app_overview.webp`. +3. **Blob на холсте** — `blob_settings_on_canvas.webp`. +4. **Компоненты и сравнение** — `compare_components_modal_window`, `components_update_indicator_location_panel`. +5. **Прототип в панели** — `modal_window_for_prototype_create_on_canvas`, `modal_window_for_prototype_panel_states`. +6. **Shadow Pro** — `shadow_pro_settings_panel`, `shadow_pro_settings_ideas`, модалки auto on/off. +7. **Панель blob: версии v1–v9** — сетка 3 колонки по ширине контента, файлы `blob_settings_panel_v1` … `v9`. +8. **Слайдер: версии** — сетка 4 колонки: `slider_v1` … `v13`, `slider_14`, `v15` … `v18`. +9. **Слайдеры: общий кадр** — `sliders_all_set.webp`. + +## Ввод + +Работа над интерфейсом Lunacy: user flow, прототипы, доработка функциональности и визуальной логики. Продукт: [icons8.com/lunacy](https://icons8.com/lunacy). + +## Обзор + +Экран-обзор приложения — отправная точка для материалов кейса. + +## Blob на холсте + +Сценарий настроек blob в контексте холста; далее в HTML — серия версий панели v1–v9. + +## Компоненты и сравнение + +Модальное сравнение компонентов и индикатор обновлений в панели. + +## Прототип в панели + +Создание прототипа на холсте и состояния панели для режима прототипа. + +## Shadow Pro + +Панель, идеи и модалки с вариантами авто-настройки. + +## Панель blob: версии v1–v9 + +Девять итераций в одной сетке (три колонки на широком экране); клик по ячейке открывает полноэкранный просмотр. + +## Слайдер: версии v1–v18 и кадр 14 + +Порядок по именам файлов; `slider_14` без суффикса `v` стоит между v13 и v15. Сетка на странице — четыре колонки по ширине контента. + +## Слайдеры: общий кадр + +Сводный экран `sliders_all_set` после ряда по версиям. + +--- + +*Блоки «Контакты» и футер на странице кейса совпадают с главной — см. `texts/main.md`.* diff --git a/texts/cases/orc-automation-panel.md b/texts/cases/orc-automation-panel.md new file mode 100644 index 0000000..3226ece --- /dev/null +++ b/texts/cases/orc-automation-panel.md @@ -0,0 +1,22 @@ +# Веб-панель для оркестрации автоматизаций + +- **Источник:** `src/pages/cases/orc-automation-panel.html` (сборка → `public/cases/orc-automation-panel.html`) +- **Ассеты:** `public/assets/orc-primo-rpa/` +- **meta description:** Кейс: редизайн веб-панели оркестратора Primo RPA — кураторство дизайна, внедрение Ant Design и Storybook, синхронизация токенов с Figma. + +## Карточка портфолио + +**Заголовок:** Веб-панель для оркестрации автоматизаций +**Теги:** UX/UI, Web App +**Кратко:** Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. + +## Структура кейса + +1. **Контекст** — роль оркестратора, состояние интерфейса до редизайна +2. **Роль и подход** — кураторство, найм Елизаветы (150+ заявок), онбординг 2–3 мес, планирование с разработкой +3. **Технический стек и инструменты** — Ant Design (последняя версия, Theme Designer, токены), Storybook +4. **Дизайн-система и синхронизация** — синхронизация токенов Ant Design ↔ Figma, компоненты Figma с нуля, плагины Storybook +5. **Рабочая среда дизайнера** — локальный Storybook + Git, JSX-описания, иконки с фильтрацией/сортировкой, обновление без разработчика +6. **UX-улучшения** — предложения Елизаветы, внедрённые и отложенные +7. **Список проектов** — было / стало (`projects--table-old`, `projects--table-new`) +8. **Результаты и рефлексия** — отзывы клиентов, передача проекта, появление AI-инструментов (Claude Design), итоговая оценка diff --git a/texts/cases/task-tracker.md b/texts/cases/task-tracker.md new file mode 100644 index 0000000..4c7b357 --- /dev/null +++ b/texts/cases/task-tracker.md @@ -0,0 +1,172 @@ +# Таск-трекер для внутренней бек-офис системы + +- **Источник:** `public/cases/task-tracker.html` +- **eyebrow:** Тестовое задание · back-office +- **meta description:** Интерфейс задач для операционного отдела: вкладки, фильтры, виды отображения, прототипы Figma и сценарии исследований. + +--- + +**Заметка по путям к медиа:** ниже пути от корня сгенерированного сайта (как в `public/`), папка `assets/task-tracker/` (картинки и видео вперемешку). + +## Задание + +Реализовать интерфейс для планирования и распределения задач между сотрудниками операционного отдела, работающими в некой бек-офис системе. Существует большое количество разноплановых задач, которые можно сгруппировать: Тип-1, Тип-2, Тип-3, Тип-4, Тип-5, Тип-6, Тип-7. У каждой задачи есть свой, выставляемый автоматически, приоритет. Пользователю доступны только задачи из определенных категорий. + +Нужно реализовать: + +- **Общий экран:** + - где пользователь может посмотреть все открытые общие задачи и взять какие-то себе. + - персональный ToDo лист, где отображаются как взятые вручную задачи, так и автоматически назначенные. + - у взятой задачи есть возможность передать ее другому сотруднику или вернуть в общий список. +- **Экран**, где можно посмотреть, что у кого в работе. + +## Введение + +Так как у меня лично есть обширный опыт работы с таск-трекерами, то я опираюсь на свой опыт и опыт моих коллег с учётом требований задания. + +## Референсы + +Референсы + +- Таск-трекеры (Trello, Monday, YouTrack и др.) +- Сервисы для визуальной работы с базами данных (Notion, Airtable и др.) + +## Решение + +### Скринкаст + +(Видео: `assets/task-tracker/full_preview.webm`) + +- **Прототип Figma (интерактив):** [STENN (Factoring) — proto](https://www.figma.com/proto/aFvwvTZuksD0JTo6yFXyUz/STENN-(Factoring)?page-id=0%3A1&node-id=20%3A1291&viewport=-5744%2C876%2C1.35&scaling=contain&starting-point-node-id=20%3A1291) +Превью: `assets/task-tracker/tab_all-tasks.webp` +Подпись: Интерактивный сценарий по задачам и представлениям + +> **Примечание:** Предполагается, что сотрудник не может создавать задачи, но может их просматривать и частично редактировать, поэтому администратор или менеджер настраивает, какие задачи будут доступны сотруднику. + +### Вкладки (Tabs) + +На вкладке **All tasks** сотрудник может ознакомиться со всеми доступными задачами. + +All tasks + +На вкладке **My tasks** отображаются только те задачи, что закреплены за текущим сотрудником. Группировка идёт по статусам задач (статус в карточке задачи скрыт). + +My tasks + +На вкладке **Task by assign** отображены все задачи c разбивкой по исполнителю. + +Tasks by assign + +В правой части имеются опции для текущей вкладки. + +Опции страницы + +Все изменения сохраняются после ухода с вкладки и после закрытия всей страницы **Tasks**. Эти настройки индивидуальны и каждый сотрудник может настроить страницу как ему удобно. + +- **Group** — позволяет создать дополнительную группировку по свойству таски (категория, приоритет, исполнитель, статус, дата создания, дата изменения). +- **View** — позволяет изменить отображение текущих задач на другой вид: доска, список, таблица. +- **Filter** — позволяет скрывать задачи по свойствам. +- **Sort** — позволяет определять порядок отображения задач по свойствам. Если включена сортировка по статусу High, Medium, Low то можно выбрать либо по алфавиту, либо в обратном порядке, а также можно создать свой порядок. С датами и цифрами работает принцип по возрастанию/убыванию. +- **Search on page** — позволяет отобразить только те задачи, в названии или описании которых есть поисковое слово или фраза. (Можно улучшить функционал поиска, добавив поисковые операторы, если исследования докажут эту необходимость) + +На странице работает постепенная подгрузка задач. По мере скрола вниз, будут подгружаться новые задачи. Кол-во задач указывается в заголовках, это может быть полезно, чтобы оценить как далеко надо скролить, чтобы все посмотреть. Задач может быть очень много и тогда возможно имеет смысл добавить ещё и переход по страницам. + +### Варианты отображения (Views) + +Разные виды отображения одних и тех же задач могут быть полезны для разных контекстов использования страницы **Tasks** и также в угоду личным предпочтениям сотрудника, что повышает его эффективность. Сотрудник, которого не раздражает интерфейс работает продуктивнее и приносит больше пользы. + +Меню видов + +> **Идея:** После смены вида также меняется иконка у опции **View**. + +Вид **Board** позволяет удобнее работать с функцией Drag&Drop (см. ниже). Также визуально легче определить кол-во задач в категории, подразумеваю что это может быть полезно. В случае использования группировки задач по статусам выполнения, перемещение карточек слева направо создаёт естественное горизонтальное течение задач из точки А в точку Б. + +Board + +Вид **List** позволяет увидеть больше информации на меньшей площади экрана. При этом этот вид визуально и функционально легче табличного вида, а значит меньше когнитивной нагрузки на пользователя. Также здесь все заголовки задач начинаются в крайнем левом положении, поэтому становится легко *пробежаться глазами* по списку. + +List + +Вид **Table** позволяет сразу же работать со всеми полями задачи, без раскрытия её в модальном окне или отдельной странице. Таблица подразумевает пользовательскую настройку ширины и порядка столбцов, что может быть удобно в некоторых кейсах использования. + +Table + +> **Идея:** Секции можно сворачивать, чтобы уместить на экране только нужный объём контента. (Может даже имеет смысл сохранять положение свёрнуто/развёрнуто после переключения вида, вкладки и перезагрузки страницы.) + +(Видео: `assets/task-tracker/expand-collapse_group.webm`) + +- **Прототип Figma (виды):** [STENN (Task-Tracker) — Board, List, Table](https://www.figma.com/proto/aFvwvTZuksD0JTo6yFXyUz/STENN-(Task-Tracker)?page-id=0%3A1&node-id=39%3A700&viewport=-1875%2C-125%2C0.55&scaling=min-zoom&starting-point-node-id=20%3A1291&hide-ui=1) + +### Drag&Drop + +Во всех видах можно перетаскивать элементы (карточки/элементы списка/строки и столбцы таблицы). Это способствует более продуктивной работе и выглядит естественным для пользователя. Например, если требуется раскидать задачи между сотрудниками (для админа или менеджера), поменять статус для нескольких задач разом или в короткий отрезок времени. + +**Board view** — видео: `assets/task-tracker/drag-drop-item_board-view.webm` +[Figma: Drag&Drop, Board](https://www.figma.com/proto/aFvwvTZuksD0JTo6yFXyUz/STENN-Task-Tracker?node-id=108%3A970&viewport=2248%2C341%2C0.33&scaling=contain&starting-point-node-id=108%3A1968&show-proto-sidebar=1) + +**List view** — видео: `assets/task-tracker/drag-drop-item_list-view.webm` +[Figma: Drag&Drop, List](https://www.figma.com/proto/aFvwvTZuksD0JTo6yFXyUz/STENN-Task-Tracker?node-id=108%3A970&viewport=2248%2C341%2C0.33&scaling=contain&starting-point-node-id=108%3A2607&show-proto-sidebar=1) + +**Продвинутый интерактивный прототип в ProtoPie** + +Схематичное представление того как работает Drag&Drop. Такой прототип помогает дизайнеру лучше понять какие нюансы нужно учесть в юзерфлоу, а также и при подготовке спецификации для разработчика. Также попробовав данный прототип можно прийти к тому, что функционал должен работать совсем иначе и переделать его сразу. Это экономит общее время разработки. + +(Видео: `assets/task-tracker/drag-drop-action_example.webm`) + +- [Прототип ProtoPie Cloud](https://cloud.protopie.io/p/e7a45bd3f2?touchHint=false&ui=false&scaleToFit=false&cursorType=arrow&mockup=false&bgColor=%23F5F5F5&playSpeed=1&playerAppPopup=true) + +В прототипе можно перемещать только голубую карточку и не все положения работают корректно. Можно посмотреть запись, которая доступна на той же странице прототипа. + +## Стиль + +Визуальный стиль может быть любым, не меняя самого *каркаса.* Например, чуть более красочным и с более выразительными шрифтами. + +**Светлая цветная тема** + +Светлая цветная тема + +- [Фрейм в Figma — светлая цветная тема](https://www.figma.com/file/aFvwvTZuksD0JTo6yFXyUz/STENN-(Task-Tracker)?node-id=174%3A5703) + +**Нейтральная тёмная тема** + +Нейтральная тёмная тема + +- [Фрейм в Figma — нейтральная тёмная тема](https://www.figma.com/proto/aFvwvTZuksD0JTo6yFXyUz/STENN--Task-Tracker-?node-id=135-5400&t=BzGQOTE0ty7u2E50-1) + +## Исследования + +На этапе прототипов Figma можно провести интервью с несколькими сотрудниками, например 5 человек. Предварительно в прототип нужно добавить реальные задачи из текущей системы, порядка 20 должно хватить. Далее можно созвониться по видеосвязи с шэрингом экрана респондента или встретиться лично и задать несколько заданий и вопросов. Во время сессии респондент может тыкать в прототип, но если что-то не сработает интервьюер может зафиксировать попытку и объяснить, что этот функционал пока не работает, а также поинтересоваться что респондент ожидает увидеть дальше. + +### Задания + +1. Найти свои актуальные задачи со страницы **Tasks** вкладки **All tasks** +2. Назначить себе задачи, чтобы взять в работу +3. Найти задачу про что-то конкретное (интервьюер приводит пример), которую он уже выполнил ранее +4. Показать задачи, которые относятся только к определённой категории и должны быть сделаны до конца недели +5. Попросить поменять приоритет у нескольких задач одновременно +6. Оценить визуальную привлекательность интерфейса по шкале от 1 до 10 +7. Оценить общее впечатление от предложенного концепта по шкале от 1 до 10 +8. Предложить ещё функции, которые были бы полезны + +### Аналитика + +Для оценки актуальности реализованного функционала необходимо собирать следующие показатели. + +- Кол-во просмотров страницы **Tasks** `page_views_tasks` с разбиением: + - по вкладкам: All tasks `all_tasks_tab`, My tasks `my_tasks_tab`, Tasks by assign `tasks_by_assign` + - по ролям: Admin `admin`, Manager `manager`, User `user` + - по попыткам поиска: Search Used `search used` +- Кол-во включённых пользовательских настроек **Custom Settings** `custom_settings` (по вкладкам, ролям, типам: Group `group`, Filter `filter`, Sort `sort`) +- Кол-во включенных видов **View Used** `view_used` (по вкладкам и ролям) + +Далее в течение полугода (может и раньше, в зависимости от активности пользователей) можно будет увидеть результат и провести исследование (в виде интервью) по функциям, которые используются реже всего и тем на которые есть жалобы, чтобы получить качественные данные и составить полную картину происходящего. + +## Дополнительные детали + +При создании мокапов в Figma были использованы: возможности автолэаутов; интерактивные компоненты, плагины ([Iconify](https://www.figma.com/community/plugin/735098390272716381/Iconify), [Fitter](https://www.figma.com/community/plugin/917796239623005893/Fitter), [Protofly](https://www.figma.com/community/plugin/1021879782774011952), [Shadow Maker](https://www.figma.com/community/plugin/889676455045507628/Shadow-Maker), [Dark Side](https://www.figma.com/community/plugin/986289377230504703) и др.), файл Community ([+40 Types of Cursor](https://www.figma.com/community/file/831142089959745518)). Слои названы и организованы для более удобной работы где-то на 60%. Используется сетка 8pt + есть размеры 2pt, 4pt. Имеются цветовые стили для светлой и тёмной темы. Присутствует адаптивность под изменяющиеся размеры окна (мобильной версии нет). + +- [Исходный файл в Figma — STENN (Task-Tracker)](https://www.figma.com/file/aFvwvTZuksD0JTo6yFXyUz/STENN-(Task-Tracker)) + +--- + +*Блоки «Контакты» и футер на странице кейса совпадают с главной — см. `texts/main.md`.* \ No newline at end of file diff --git a/texts/cases/template-elements-demo.md b/texts/cases/template-elements-demo.md new file mode 100644 index 0000000..6d02075 --- /dev/null +++ b/texts/cases/template-elements-demo.md @@ -0,0 +1,73 @@ +# Пример кейса: демо элементов + +- **Источник (разметка):** `src/pages/cases/template-elements-demo.html` → после сборки `public/cases/template-elements-demo.html` +- **eyebrow:** Демо · template +- **meta description:** Демо-страница кейса со всеми разработанными элементами: карточки ссылок и медиа-блоки. +- **Подзаголовок (h1 sub):** Рыба-текст и блоки для быстрой сборки лонгрида + +*Источник шаблона (устаревшая ссылка в HTML): можно вести на этот файл — `texts/cases/template-elements-demo.md`.* + +## Контекст + +Этот раздел показывает пример рыбы для вступления. Здесь можно коротко описать продукт, аудиторию и ограничения проекта. Текст нейтральный: цель — быстро набросать структуру и проверить визуальный ритм страницы. + +## Задача + +Нужно собрать демонстрационный лонгрид с основными UI-элементами: карточками ссылок, медиа-блоками и примерами оформления контента. Дополнительно важно проверить, как блоки ведут себя на узких и широких экранах. + +## Решение + +Ниже собраны готовые примеры, которые можно копировать в реальные кейсы. + +### Карточки ссылок + +- **С превью** — [www.examples.com](https://www.examples.com/) +Короткая подпись: что пользователь увидит по ссылке. Превью: `assets/template-elements-demo/wallpaper-1.jpg` +- **С favicon** — [www.examples.com/docs](https://www.examples.com/docs) +Вариант для более лёгких ссылок без скриншота. + +### Картинка: 50% от оригинала (без превью) + +`assets/template-elements-demo/hello.gif` — демо GIF в натуральном размере, по центру. + +*Подпись к figure:* Изображение в уменьшенном натуральном размере, по центру. + +### Картинка: по ширине контента (с превью) + +`assets/template-elements-demo/wallpaper-1.jpg` — клик открывает viewer (в UI). + +*Подпись:* Изображение по ширине контента. Клик открывает viewer. + +### Картинка: чуть шире контента (с превью) + +Тот же ассет — изображение немного выходит за пределы контентной колонки. + +### Длинный скрин: свёрнутая высота + развернуть + +Разметка с `data-case-tall-media` и `data-case-tall-width` (`content` / `wide`): туман только в свёрнутом виде; кнопки под картинкой; после раскрытия туман скрывается. Исходник длинного кадра: `public/assets/template-elements-demo/img-long.png` → WebP командой `npm run optimize-images -- public/assets/template-elements-demo`. См. `public/assets/README.md`. + +### Галерея: сетка по ширине контента + +Семь файлов `assets/template-elements-demo/small-image-1.webp` … `small-image-7.webp` (рядом в той же папке лежат исходные PNG; WebP — `npm run optimize-images -- public/assets/template-elements-demo`). На `figure` задано `--case-gallery-cols: 3` для десктопа; ниже порогов ширины окна число колонок уменьшается (см. `docs/case-page-blocks.md`). Клик по ячейке открывает viewer. + +### Галерея: сетка на ширину страницы (wide) + +Те же `small-image-*.webp`, класс `case-media-gallery--wide`, `--case-gallery-cols: 2`. + +### Callout: важный абзац с эмоджи + +> Это пример акцентного callout-блока. Эмоджи вынесен влево и пульсирует, чтобы визуально усилить важную мысль. (в HTML: эмоджи 📌) + +### Видео: карточка с тенью + +`assets/template-elements-demo/video-1.webm` — пример видео-карточки в стиле кейса. + +*Подпись:* Пример видео-карточки в стиле кейса. + +## Результат + +Шаблон готов для копирования в новый кейс: остаётся заменить рыбу на фактический текст, подставить реальные ссылки и медиа проекта. + +--- + +*Новые картинки для демо и кейсов клади в `public/assets/…` (см. `public/assets/README.md`).* \ No newline at end of file diff --git a/texts/content-edits/.gitkeep b/texts/content-edits/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/texts/content-edits/README.md b/texts/content-edits/README.md new file mode 100644 index 0000000..ce89dd3 --- /dev/null +++ b/texts/content-edits/README.md @@ -0,0 +1,57 @@ +# Правки контента (content-edits) + +Один файл очереди для агента и режима правок на `http://localhost:4175` (`npm run serve`). + +## Файл + +**`texts/content-edits/pending.json`** — все страницы, все правки. + +Старые файлы `cases--.json` при первом запросе к API переносятся в `pending.json` и удаляются. + +## Формат (version 2) + +```json +{ + "version": 2, + "updatedAt": "2026-05-16T12:00:00.000Z", + "items": [ + { + "n": 1, + "page": "cases/ai-platform-primo-rpa.html", + "instruction": "Перенести «Вид редактора…» ниже «Добавил режим…»", + "target": { + "selector": "main#case-main #patterns > p.section__prose:nth-of-type(1)", + "anchorId": "patterns", + "tag": "p", + "content": "полный текст основного блока (до ~2000 символов)", + "snippet": "первые ~80 символов" + }, + "refs": [ + { + "label": "Вид редактора в режиме «Во весь экран»", + "target": { + "selector": "main#case-main #zadachi > figure.case-media-gallery:nth-of-type(2)", + "anchorId": "zadachi", + "tag": "figure", + "content": "первые ~200 символов", + "snippet": "первые ~80 символов" + } + } + ] + } + ] +} +``` + +- **`page`** — путь относительно `public/` (как в адресной строке без ведущего `/`). +- **`n`** — порядок apply по всему файлу (на странице в FAB-списке снова 1, 2, 3… только для текущей страницы). +- **`target`** — основной блок правки (обычный клик). Для **общей правки страницы** без блока: `"scope": "page"`. +- **`refs`** — дополнительные блоки (Shift+клик в инструкции). `label` (~50 символов) вставляется в текст как `«…»`; `target.content` у ref короче (~200), чем у основного `target`. + +## Apply + +В Cursor: **«примени правки»** / **`/apply-edits`** — агент читает `pending.json`, правит `src/pages/`, `humanizer-ru`, `npm run build:pages`. + +После apply **`items` не трогаем** — очередь для проверки; удаление пунктов вручную в dock или повторный apply с уточнённой instruction. + +См. `.cursor/rules/content-edit-apply.mdc`. diff --git a/texts/content-edits/pending.json b/texts/content-edits/pending.json new file mode 100644 index 0000000..d3bede6 --- /dev/null +++ b/texts/content-edits/pending.json @@ -0,0 +1,21 @@ +{ + "version": 2, + "updatedAt": "2026-06-06T11:59:34.336Z", + "items": [ + { + "instruction": "замени: без ломки базовых сценариев\nна: без больших переделок", + "target": { + "scope": "page", + "selector": "main#case-main", + "anchorId": "case-main", + "tag": "main", + "content": "Общая правка страницы", + "snippet": "Общая правка страницы" + }, + "refs": [], + "n": 1, + "page": "cases/ai-platform-primo-rpa.html" + } + ], + "lastAppliedAt": "2026-06-06T11:54:50.470Z" +} diff --git a/texts/cookie-policy.md b/texts/cookie-policy.md new file mode 100644 index 0000000..01c16c9 --- /dev/null +++ b/texts/cookie-policy.md @@ -0,0 +1,42 @@ +# Политика использования файлов cookie и локального хранилища + +**Дата последнего обновления:** 9 мая 2026 г. + +Настоящий документ описывает, как на личном сайте-портфолио Николая Мамадаева (далее — «сайт») используются технологии хранения данных в браузере. + +## Кто отвечает за сайт + +Оператором сайта является **Николай Мамадаев**. По вопросам обработки данных используйте контакты в блоке «Контакты» на главной странице сайта (Telegram, ВКонтакте, Яндекс и почта через копирование адреса кнопкой). + +## Используются ли HTTP cookie + +В текущей версии сайта **сторонние рекламные или аналитические HTTP cookie не подключаются**. В разметке страниц нет счётчиков аналитики (например, Яндекс.Метрики или Google Analytics), которые обычно устанавливают собственные cookie. + +При размещении сайта на хостинге или за прокси технические записи (например, журналы сервера с IP-адресом и временем запроса) могут обрабатываться хостинг-провайдером по его документам — это не настраивается кодом данного сайта. + +## Local Storage и аналогичные технологии браузера + +Для удобства работы сайт сохраняет на вашем устройстве небольшие объёмы данных через **механизм localStorage** в браузере (это не HTTP cookie, но по смыслу близко к ним и также относится к хранению на стороне клиента). + +Используются следующие ключи: + +| Ключ | Назначение | +|------|------------| +| `siteThemeV1` | Настройки оформления: тема (светлая/тёмная/системная), оттенок, скругления, шрифт, фон и связанные параметры панели темы. | +| `siteCookieConsentV1` | Значение `accepted`, если вы нажали «Принять» в уведомлении о cookie; после этого баннер скрывается. | + +Эти данные **не передаются на сервер сайта** автоматически: они остаются только в вашем браузере. + +## Срок хранения + +Данные в localStorage сохраняются до тех пор, пока вы **не удалите их вручную** (очистка данных сайта / полное удаление данных браузера) или пока браузер не сбросит хранилище по своим правилам. + +## Согласие и отказ + +Нажимая «Принять» в баннере, вы подтверждаете, что ознакомились с настоящей политикой. Если вы не нажимаете «Принять», баннер остаётся доступным; функциональность сайта при этом по возможности сохраняется, но запись о согласии не создаётся. + +Вы можете в любой момент **очистить localStorage** для этого сайта в настройках браузера — при этом сбросятся сохранённые тема и отметка о принятии уведомления, и баннер может снова отобразиться. + +## Изменения + +Текст политики может обновляться при изменении технологий на сайте. Актуальная версия публикуется на странице «Политика cookie» по адресу, указанному на сайте. diff --git a/texts/main.md b/texts/main.md new file mode 100644 index 0000000..0d523f9 --- /dev/null +++ b/texts/main.md @@ -0,0 +1,214 @@ +# Главная страница (источник: `public/index.html`) + +## Meta + +- **title:** Николай Мамадаев — продуктовый дизайнер +- **description:** Продуктовый дизайнер и вайбкодер с опытом более 10 лет. Проектирую цифровые продукты, интерфейсы и дизайн‑системы, совмещая UX, no-code и код для аккуратных рабочих решений. + +## Шапка: навигация + +- Навыки → `#skills` +- Опыт работы → `#experience` +- Портфолио → `#projects` +- Мини-проекты → `#mini-projects` +- Контакты → `#contact` + +(Подменю «Ещё разделы» и панель темы — UI, без копирования сюда.) + +## Hero + +- **eyebrow:** Николай Мамадаев +- **h1:** Создаю интерфейсы для продуктов +- **ротатор (подзаголовок):** web, mobile, desktop (смена слов в UI) +- **теги:** UX/UI · 10+ лет опыта · Продуктовое мышление · Дизайн‑системы · Менторство и наставничество · AI инструменты и вайбкодинг +- **кнопки:** Написать мне (`#contact`) · Смотреть портфолио (`#projects`) + +(Фото: `assets/index/ava-bg-1.webp`, `assets/index/me-transparentBG-1.webp`.) + +## Навыки (`#skills`) + +**Заголовок секции:** Навыки + +**Вступление (чат, два сообщения):** + +1. В моём опыте есть и запуск первых версий продукта с нуля, и развитие уже зрелых решений, где важно не сломать привычный сценарий, а аккуратно улучшить его. +2. Ниже я собрал примеры задач от бизнеса и то, как я их решал + +### Продуктовый подход и логика в интерфейсах + + +| Задача | Как решаю | +| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Сделать сложный продукт понятнее, чтобы пользователи доходили до ключевых действий. | Анализирую путь пользователя и убираю шаги, которые не помогают ему продвинуться к цели. Проектирую флоу так, чтобы в каждом шаге было понятно, что происходит и что делать дальше. Делаю так, чтобы даже сложный функционал выглядел естественно, использовал знакомые паттерны и привычные элементы интерфейса. | +| Улучшить первые шаги в продукте и подвести человека к первой ценности. | Убираю всё, что отвлекает от первого результата: лишние шаги, необязательные поля, второстепенные детали. Заменяю длинные объяснения небольшими подсказками в момент, когда они действительно нужны без длинных туров и сложных инструкций. | +| Снизить нагрузку на техподдержку за счёт интерфейса. | Собираю частые обращения и на их основе упрощаю сценарий и интерфейс так, чтобы человек мог решить вопрос самостоятельно. | +| Связать интерфейс с целями продукта, а не только с набором фич. | Начинаю с того, какую задачу бизнеса и пользователя мы решаем, и уже под это собираю сценарии и интерфейс. Перевожу проблемы в сценариях в понятные гипотезы и помогаю продакту выбрать, что действительно даёт эффект. | + + +### Дизайн‑системы и консистентность + + +| Задача | Как решаю | +| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Привести несколько продуктов или модулей к единому виду и логике. | Собираю общий UI‑kit и базовые принципы, которые можно использовать во всех продуктах. Выделяю повторяющиеся паттерны и свожу их к одной системе, вместо десятка похожих решений. Перевожу разрозненные решения в общую дизайн‑систему, чтобы ей было удобно пользоваться и дизайнерам, и разработчикам. | +| Обновить внешний вид продукта, чтобы он не выглядел устаревшим на фоне конкурентов. | Начинаю с часто используемых экранов и элементов, чтобы эффект был заметен и для пользователей, и для бизнеса. Подстраиваю этапы обновления под текущую дорожную карту и работу разработки, чтобы не ломать привычные сценарии и релизы. Настраиваю базовый стиль: типографика, цвет, отступы — чтобы интерфейс выглядел аккуратно и современно. | +| Навести порядок в интерфейсах, которые долго росли кусками. | Объединяю похожие решения в общие компоненты и паттерны, убираю дубли и случайные отличия.Слежу за тем, чтобы интерфейс выглядел аккуратно и современно: читаемая типографика, иерархия, акценты без визуального шума. | +| Сделать интерфейс так, чтобы его можно было спокойно расширять и не городить костыли. | Формулирую простые дизайн‑принципы и правила использования компонентов. Настраиваю структуру дизайн‑системы так, чтобы её было реально поддерживать и дополнять новыми паттернами. | + + +### Исследования, метрики и аналитика + + +| Задача | Как решаю | +| -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Получить реальную картину поведения пользователей, а не полагаться на догадки команды. | Общаюсь с пользователями: смотрю, как они решают свои задачи в продукте и что делают на каждом шаге. Перевожу выводы из исследований в конкретные изменения в интерфейсе и сценариях. | +| Убедиться, что ключевые сценарии работают, прежде чем выкатывать их в прод. | Готовлю простые сценарии юзабилити‑тестов под реальные задачи пользователей. | +| Понимать, как изменения в интерфейсе влияют на ключевые метрики продукта. | Помогаю описать ключевые события и воронки, которые отражают реальные шаги пользователя. Смотрю на метрики вместе с реальными сценариями использования и предлагаю, что в интерфейсе поменять, чтобы людям было проще и продукт работал лучше. | + + +### Развитие команды дизайнеров и наставничество + + +| Задача | Как решаю | +| ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Выстроить понятные процессы внутри дизайн-команды. | Ввожу регулярные дизайн‑ревью с разбором реализованных задач, где каждый может получить полезную экологичную обратную связь. Договариваюсь о шаблоне постановки задачи и прозрачных критериях приёмки, чтобы всем было ясно, когда задачу считать действительно законченой. Настраиваю порядок работ, который позволяет выполнять как плановые задачи, так и "горящие". | +| Сделать так, чтобы дизайн, продукт и разработка работали как одна команда, а не три отдельных лагеря. | Беру на себя роль связующего: обсуждаю сценарии с продактом, ограничения — с разработкой и фиксирую решения в интерфейсе. | +| Нанять и вырастить продуктовых дизайнеров для работы над сложным продуктом. | Помогаю сформировать необходимые требования к кандидату. Участвую в отборе: проверяю, как кандидат работает со сценариями, ограничениями и сложными кейсами. Выстраиваиваю интервью так, чтобы можно было оценить ход мысли и используемые инструменты. Настраиваю онбординг через реальные задачи и регулярные разборы, чтобы дизайнер быстрее разобрался в продукте и начал приносить пользу. Провожу регулярные созвоны один на один с дизайнерами: разбираем решения, точки роста и следующие шаги. | + + +## Опыт работы (`#experience`) + +Кнопка «Показать все» раскрывает скрытые карточки (первые три видны сразу). + +1. **Primo RPA** — [primo-rpa.com](https://primo-rpa.com/) + Февраль 2023 — Ноябрь 2025 · 2 года 10 месяцев + Платформа для автоматизации бизнес‑процессов с комплексом продуктов: студией для создания роботов, оркестратором для их управления, Idea Hub для отбора процессов и AI‑серверами для работы с моделями и распознаванием данных. +2. **Icons8 (Lunacy)** — [icons8.com/lunacy](https://icons8.com/lunacy) + Июль 2022 — Январь 2023 · 7 месяцев + Векторный редактор для UI/UX и веб‑дизайна с поддержкой Sketch‑файлов, встроенной библиотекой иконок/фото/иллюстраций и набором AI‑инструментов для ускорения рутинных задач. +3. **MANU Video Game Maker** — [manu.co](https://manu.co/) + Январь 2019 — Декабрь 2021 · 3 года + No-code/low-code платформа для создания 2D и 3D игр без необходимости писать код. +4. **AEGEES** — [aegees.com](https://aegees.com/) + Октябрь 2017 — Декабрь 2018 · 1 год 3 месяца + Защищённый мессенджер с end‑to‑end шифрованием и отсутствием хранения сообщений на серверах, сфокусированный на максимальной приватности пользователей. +5. **Orion Innovation (ex MERA)** — [orioninnovation.com](https://www.orioninnovation.com/) + Июль 2016 — Октябрь 2017 · 1 год 4 месяца + Международная технологическая компания, специализирующаяся на заказной разработке и инженерных решениях для крупных корпоративных клиентов. +6. **SpaceshipApps** — [spaceshipapps.ru](https://spaceshipapps.ru/) + Июнь 2015 — Июнь 2016 · 1 год 1 месяц + Студия разработки мобильных и веб‑приложений под ключ для бизнеса и предпринимателей. + +## Портфолио — карточки (`#projects`) + +1. **Мобильное приложение для сети клиник** + Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям. + **Теги:** UX/UI, Mobile App + **Ссылка:** [Подробнее (Notion)](https://mamadaevv.notion.site/7afdbacd178347229d0d73df47428f81) +2. **Игровой движок MANU** + Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев. + **Теги:** Product Design, Desktop App + **Ссылка:** [Подробнее (Notion)](https://mamadaevv.notion.site/7afdbacd178347229d0d73df47428f81) +3. **Веб-панель для оркестрации автоматизаций** + Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен. + **Теги:** UX/UI, Web App + **Ссылка на сайт:** [Кейс](cases/orc-automation-panel.html) — полный текст: `texts/cases/orc-automation-panel.md` +4. **Платформа для работы с AI** + Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR. + **Теги:** UX/UI, Web‑продукт, Data‑heavy интерфейсы, Figma, Research + **Ссылка на сайт:** [Кейс](cases/ai-platform-primo-rpa.html) — полный текст: `texts/cases/ai-platform-primo-rpa.md` +5. **Концепт сервиса распределения задач** + Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы. + **Теги:** UX/UI, Analytics, Web App + **Ссылка:** [Подробнее (Notion)](https://mamadaevv.notion.site/7afdbacd178347229d0d73df47428f81) +6. **Графический редактор Lunacy** + Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики. + **Теги:** UX/UI, Desktop App + **Ссылка на сайт:** [Кейс](cases/lunacy.html) — полный текст: `texts/cases/lunacy.md` +7. **Таск-трекер для бек-офис системы** + Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, виды доска / список / таблица, Drag&Drop. Тестовое задание, прототипы в Figma. + **Теги:** Product Design, Web App + **Ссылка на сайт:** [Кейс](cases/task-tracker.html) — полный текст: `texts/cases/task-tracker.md` + +## Мини-проекты (`#mini-projects`) + +**Заголовок секции:** Мини-проекты + +Сетка карточек: `public/index.html`, превью по умолчанию `assets/shared/placeholder.webp`. Максимальная ширина карточки в сетке — 3 «клетки» (`data-mp-cells`). Подробности разметки — `docs/mini-projects-cards.md`. + +**Вступление (чат, два сообщения):** + +1. **Николай М:** Параллельно большим кейсам из портфолио я собираю маленькие штуки для себя: утилиты, странички, эксперименты с UI и кодом. Этот блок — чтобы они не терялись в заметках и архивах. +2. Карточки можно задавать разной ширины и шаблона; сетка сама их упакует. Часть строк по умолчанию свёрнута — остальное открывается кнопкой «Показать все». + +Кнопка **«Показать все»** раскрывает карточки, помеченные в разметке как дополнительные (`data-mp-extra`). + +### Карточки (видимые в свёрнутом блоке) + +1. **Генератор подписей к постам** + **Тип:** скрипт · **Шаблон:** stack, `data-mp-cells="3"` · **Ссылка:** [github.com](https://github.com) (заглушка) + Небольшой скрипт на Python: черновики текстов из ключевых слов и ограничений по длине, без внешних API. + +2. **Лендинг для мероприятия** + **Тип:** веб-сайт · **Шаблон:** stack, `data-mp-cells="3"` · **Ссылка:** [example.com](https://example.com) (заглушка) + Статический сайт с расписанием и формой заявки на отдельном сервисе. + +3. **Трекер привычек в Notion** + **Тип:** шаблон · **Шаблон:** horizontal, без внешней ссылки, `data-mp-cells="3"` + Связка баз и rollup для недельного обзора — только для личного пользования. + +4. **Таймер «помидора»** + **Тип:** приложение · **Шаблон:** stack, `data-mp-cells="2"` · **Ссылка:** [example.com](https://example.com) (заглушка) + Локальный таймер с короткими звуками и блокировкой лишних вкладок в браузере. + +5. **Локальный REST‑мок** + **Тип:** утилита · **Шаблон:** compact (только текст), `data-mp-cells="2"` · без ссылки + Поднимает простые эндпоинты из JSON для проверки экранов без бекенда. + +6. **Декоративная ячейка** + **Шаблон:** `mp-card--decor`, `data-mp-cells="2"` — визуальная заглушка в сетке, без заголовка и описания. + +### Карточки под «Показать все» + +7. **Плагин подсветки синтаксиса** + **Тип:** плагин · **Шаблон:** stack, `data-mp-cells="3"` · **Ссылка:** [github.com](https://github.com) (заглушка) + Расширение редактора: подсветка собственного DSL и переход к объявлению по ⌘‑клику. + +8. **Тема для редактора** + **Тип:** тема · **Шаблон:** horizontal, `data-mp-cells="3"` · **Ссылка:** [github.com](https://github.com) (заглушка) + Набор цветовых токенов под долгую работу с кодом и заметками. + +9. **CLI переименования файлов** + **Тип:** cli · **Шаблон:** stack, `data-mp-cells="3"` · **Ссылка:** [github.com](https://github.com) (заглушка) + Префиксы, нумерация и безопасный dry-run перед записью на диск. + +10. **Виджет погоды** + **Тип:** виджет · **Шаблон:** horizontal, `data-mp-cells="2"` · **Ссылка:** [example.com](https://example.com) (заглушка) + Мини‑окно на Electron с почасовым прогнозом и иконками состояния. + +11. **Чеклист регресса UI** + **Тип:** документ · **Шаблон:** compact, `data-mp-cells="2"` · без ссылки + Markdown‑список проверок перед релизом мелких правок в интерфейсе. + +12. **Сниппеты для DevTools** + **Тип:** расширение · **Шаблон:** compact + ссылка, `data-mp-cells="1"` · **Ссылка:** [github.com](https://github.com) (заглушка) + Заготовки console.log и замеров производительности одним жестом. + +13. **Мини‑CRM для себя** + **Тип:** сервис · **Шаблон:** horizontal, `data-mp-cells="3"` · **Ссылка:** [example.com](https://example.com) (заглушка) + Одна таблица контактов, статусы сделок и напоминания в LocalStorage. + +## Контакты (`#contact`) + +- **Telegram** — [t.me/mamadaevv](https://t.me/mamadaevv) — подпись: Отвечаю быстро +- **ВКонтакте** — [vk.com/mamadaevv](https://vk.com/mamadaevv) — Удобно для России +- **Яндекс (чат)** — [приглашение](https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite) — Да, тут тоже можно +- **Почта** — копирование в буфер (адрес в JS `data-email-b64`), подпись: Скопировать адрес + +## Футер + +© 2026 · Дизайн и вёрстка — Николай Мамадаев + +## Баннер cookie + +Сайт использует cookie для комфортной работы. Подробнее — в политике cookies (ссылка пока `href="#"`). Кнопка: Принять. \ No newline at end of file diff --git a/texts/pet-projects/README.md b/texts/pet-projects/README.md new file mode 100644 index 0000000..887893f --- /dev/null +++ b/texts/pet-projects/README.md @@ -0,0 +1,5 @@ +# Пет- и сайд-проекты + +В `public` пока нет отдельных HTML под пет-проекты — тексты сюда добавь, когда появятся страницы или решишь вести материал только в Markdown. + +Шаблон нового проекта: `_template.md`. \ No newline at end of file diff --git a/texts/pet-projects/_template.md b/texts/pet-projects/_template.md new file mode 100644 index 0000000..e2b5904 --- /dev/null +++ b/texts/pet-projects/_template.md @@ -0,0 +1,13 @@ +--- + +## slug: project-slug + +title: Название пет-проекта +summary: Краткое описание +order: 10 + +## Идея + +## Что сделано + +## Ссылки \ No newline at end of file diff --git a/texts/обязанности.txt b/texts/обязанности.txt new file mode 100644 index 0000000..1e07c87 --- /dev/null +++ b/texts/обязанности.txt @@ -0,0 +1,35 @@ +Задачи +Совместно с владельцем продукта погружаться в суть задачи: выявлять и формулировать реальные бизнес-метрики и потребности клиентов, переводя их в ясные дизайн-задачи с измеримыми критериями успеха +Проводить дизайн-исследования: анализировать рынок и аналоги, строить путь клиента, чтобы находить точки роста и вместе с командой формировать обоснованные гипотезы для их решения +Быстро проверять идеи: создавать интерактивные прототипы для валидации гипотез — от концепций до детализированных сценариев +Тестировать с реальными пользователями: участвовать в организации и проведении юзабилити-тестов, лично наблюдая за реакцией пользователей, чтобы получать инсайты +Итеративно улучшать решения: на основе данных тестов и аналитики дорабатывать дизайн, обеспечивая его эффективность и удобство +Готовить финальный дизайн для разработки: создавать чистые, точные макеты, используя и развивая компоненты масштабной дизайн-системы Банка +Развивать дизайн-систему: при необходимости — проектировать, создавать и документировать новые компоненты, внося вклад в инструмент, которым пользуются десятки команд +Работать в комьюнити дизайнеров: проводить дизайн-чек своих макетов и участвовать в ревью работ коллег, поддерживая высокий стандарт качества в команде +Вести дизайн на этапе разработки: передавать макеты разработчикам, оперативно отвечать на вопросы, чтобы vision продукта была реализована без искажений +Контролировать результат: проводить дизайн-ревью готовых реализаций, формулировать и приоритизировать замечания для финальной полировки +Замыкать цикл развития продукта: анализировать метрики и обратную связь после релиза, предлагая и реализуя дальнейшие улучшения +Влиять на процессы: активно участвовать в оптимизации рабочих процессов внутри дизайн- и продуктовой команд + +Опыт работы в веб-дизайне и в проектировании пользовательских интерфейсов не менее 2-х лет; +Опыт работы в продуктовой команде; +Свободное владение Figma с использованием инструментов прототипирования; +Проведение пользовательских исследований, интервью, построение схем сценариев взаимодействия пользователя и системы; +Проектирование с учётом бизнес-требований, технических ограничений и гайдлайнов; +Умеете исследовать пользовательские потребности и собирать требования; + +Разработка digital-продукта (создание самого продукта, а также его ценности для клиентов); +Проектирование интерфейсов на основе статистики и метрик в тесном взаимодействии с внутренней командой; +Отрисовка пользовательского пути в СJM и User Flow, выявление точек роста и внедрение улучшений по нему; +Анализ решений, построение и проверка гипотез; +Подготовка макетов для передачи в разработку и контроль качества реализации интерфейсов. + +коммерческий опыт работы в сложных продуктах от 3 лет; +наличие портфолио с реализованными кейсами (интерфейсы и мобильные приложения); +опыт работы в Figma: работа с UI-библиотеками (компоненты, варианты, стили и пр.), чтение документации, следование гайдам; +сильный практический уровень в проектировании сложных интерфейсов: таблицы, фильтры, карты, дашборды, многошаговые сценарии; +умение презентовать свою работу и обосновывать эффективность выбранных решений; +понимание основ брендинга; +знание основ композиции, типографики, цвета и визуальной иерархии. +