merge feature/resume-pdf-download into dev
This commit is contained in:
commit
5544a48400
62 files changed
+10673
-5433
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -1,10 +0,0 @@
|
||||
node_modules
|
||||
.git
|
||||
.gitignore
|
||||
Dockerfile
|
||||
Dockerfile.dev
|
||||
.dockerignore
|
||||
*.log
|
||||
.cache
|
||||
.deploy-manifest.json
|
||||
.cursor
|
||||
@@ -12,6 +12,7 @@ coverage/
|
||||
!.cursor/commands/
|
||||
!.cursor/commands/**
|
||||
.vscode/
|
||||
.zed/
|
||||
gitverse/
|
||||
|
||||
# Logs
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
22
|
||||
@@ -1,27 +1,18 @@
|
||||
# Подсказки для агента (Cursor)
|
||||
|
||||
## GitVerse / деплой статики
|
||||
## Сборка и деплой
|
||||
|
||||
Полный чеклист: **`docs/gitverse-sync.md`** → раздел **«Инструкция для агента (Cursor)»**.
|
||||
Деплой автоматический: пуш в git → автодеплой на хостинг.
|
||||
|
||||
Деплой на VPS: **`docs/vps-deploy.md`**.
|
||||
По запросу пользователя «собрать», «билд»:
|
||||
|
||||
Кратко по запросу пользователя «выложить на GitVerse», «синк gitverse», «задеплоить»:
|
||||
1. При правках `src/pages/**` или `src/partials/**` — `npm run build:pages`.
|
||||
2. При смене шрифтов/Plyr или `package.json` — `npm run build` (включает `vendor:copy`).
|
||||
3. Для деплоя — сделать git commit + push.
|
||||
|
||||
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. Не запускать синк без явного запроса пользователя.
|
||||
## Git
|
||||
|
||||
По запросу «задеплой в 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` из корня.
|
||||
Репозиторий: `http://x1qnvk08zec2u5cx6yh5iexh.155.212.186.39.sslip.io/admin/site-portfolio.git`
|
||||
|
||||
### Влить в `master`, оставаясь на текущей ветке
|
||||
|
||||
@@ -33,9 +24,14 @@
|
||||
|
||||
## Design System
|
||||
|
||||
Страница-каталог: **`src/pages/cases/design-system.html`** → после сборки `public/cases/design-system.html`.
|
||||
Перед работой с UI **прочитай `DESIGN.md`** в корне проекта — там описаны токены, типографика, компоненты и правила их применения.
|
||||
|
||||
При **глобальных** правках стилей (токены в `public/css/main.css`, компоненты главной, блоки лонгрида кейса) **обновляй Design System**: живой пример и краткое описание в соответствующей секции, при необходимости — `docs/case-page-blocks.md`.
|
||||
Страницы-каталоги (живые примеры):
|
||||
- **`src/pages/cases/design-system.html`** → токены, типографика, кнопки, карточки, секции
|
||||
- **`src/pages/cases/template-elements-demo.html`** → элементы лонгрида: медиа, галереи, видео, callout
|
||||
- **`src/pages/cases/mini-projects-showcase.html`** → карточки активности (mp-card)
|
||||
|
||||
При **глобальных** правках стилей (токены в `public/css/main.css`, компоненты главной, блоки лонгрида кейса) **обновляй соответствующий каталог**: живой пример и краткое описание в секции, при необходимости — `docs/case-page-blocks.md`.
|
||||
|
||||
## Контент кейса в public (по запросу)
|
||||
|
||||
@@ -49,6 +45,18 @@
|
||||
|
||||
Режим на странице при `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`**.
|
||||
|
||||
## PDF резюме (по запросу)
|
||||
|
||||
По запросу «обнови PDF», «перегенерируй PDF»:
|
||||
|
||||
1. Убедиться, что dev-сервер запущен (`localhost:4175`).
|
||||
2. Запустить `npm run generate:resume-pdf`.
|
||||
3. Файл обновится в `public/assets/resume/Mamadaev_Nik__CV__Product_Designer_UX-UI.pdf`.
|
||||
|
||||
Подробнее: **`docs/resume-pdf.md`**.
|
||||
|
||||
Скрипт требует запущенный сервер — нельзя встроить в обычный `build`.
|
||||
|
||||
## Vendor (шрифты, Plyr)
|
||||
|
||||
Локально в `public/`, без CDN. Обновление: **`docs/vendor-assets.md`**, команда `npm run vendor:copy`.
|
||||
@@ -60,3 +68,15 @@
|
||||
## Остальное
|
||||
|
||||
Правила и таблица доков: **`.cursor/rules/read-docs-before-feature-dev.mdc`** (локально; папка `.cursor/` может быть в `.gitignore`).
|
||||
|
||||
### Ключевые файлы
|
||||
|
||||
| Файл | Назначение |
|
||||
|---|---|
|
||||
| `DESIGN.md` | Описание дизайн-системы для AI-агентов |
|
||||
| `public/css/main.css` | Единый CSS: токены + все компоненты |
|
||||
| `src/pages/cases/design-system.html` | Живой каталог токенов, типографики, кнопок, карточек |
|
||||
| `src/pages/cases/template-elements-demo.html` | Элементы лонгрида: медиа, галереи, видео, callout |
|
||||
| `src/pages/cases/mini-projects-showcase.html` | Карточки активности (mp-card) |
|
||||
| `docs/case-page-blocks.md` | Инструкция по блокам лонгридов |
|
||||
| `docs/resume-pdf.md` | Генерация PDF резюме (Puppeteer) |
|
||||
@@ -0,0 +1,245 @@
|
||||
# DESIGN.md
|
||||
|
||||
Портфолио-сайт продуктового дизайнера. Лонгриды кейсов, резюме, блог. Визуал — минимализм с акцентом на типографику и контент.
|
||||
|
||||
---
|
||||
|
||||
## Продукт
|
||||
|
||||
Одностраничный сайт-портфолио с внутренними страницами (кейсы, резюме, блог). Основной контент — лонгриды с описанием проектов. Навигация через главную страницу с секциями: навыки, портфолио, контакты.
|
||||
|
||||
**Характер:** Сдержанный, профессиональный. Без визуального шума. Контент — главный элемент интерфейса.
|
||||
|
||||
---
|
||||
|
||||
## Цвета
|
||||
|
||||
### Токены темы
|
||||
|
||||
| Токен | Назначение |
|
||||
|---|---|
|
||||
| `--theme-h` | Оттенок акцента (0–360°) |
|
||||
| `--theme-s` | Насыщенность акцента |
|
||||
| `--theme-l` | Светлота акцента |
|
||||
| `--accent` | Основной акцентный цвет |
|
||||
| `--accent-text` | Цвет текста на акцентном фоне |
|
||||
| `--accent-soft` | Мягкий акцент для фона |
|
||||
| `--bg` | Фон страницы |
|
||||
| `--bg-elevated` | Поверхность второго уровня |
|
||||
| `--surface` | Фон карточек и секций |
|
||||
| `--text` | Основной текст |
|
||||
| `--text-muted` | Приглушённый текст |
|
||||
| `--line` | Рамки и разделители |
|
||||
|
||||
### Правила
|
||||
|
||||
- Акцент меняется через `--theme-h/s/l` на `<html>`. Все производные пересчитываются автоматически.
|
||||
- Светлая/тёмная тема — `data-theme="light|dark"` на `<html>`.
|
||||
- Нейтральные фоны (`--bg`, `--surface`) слегка подмешивают оттенок акцента через `--neutral-accent-tint`.
|
||||
- Не используйте хардкод hex-значений. Всегда обращайтесь к токенам.
|
||||
|
||||
---
|
||||
|
||||
## Типографика
|
||||
|
||||
### Семейства
|
||||
|
||||
| `data-font` | Стек | Назначение |
|
||||
|---|---|---|
|
||||
| `merriweather` | Merriweather + Alice | По умолчанию. Alice — проза, Merriweather — заголовки |
|
||||
| `geologica` | Geologica + PT Sans | Гротеск + нейтральная проза |
|
||||
| `mono` | Source Code Pro + PT Mono | Моноширинный |
|
||||
|
||||
### Шкала
|
||||
|
||||
| Класс | Размер | Вес | Назначение |
|
||||
|---|---|---|---|
|
||||
| `.hero__eyebrow` | `0.78rem` | 700 | Подзаголовок секции, ввод кейса. Uppercase, letter-spacing 0.14em |
|
||||
| `.hero__title` | `clamp(3.1rem, 7.2vw, 4.85rem)` | 700 | H1 главной страницы |
|
||||
| `.case-page__h1` | `clamp(2rem, 3.9vw, 2.9rem)` | 700 | H1 кейса / внутренней страницы |
|
||||
| `.case-page__sub` | `clamp(1.5rem, 2vw, 1.65rem)` | 500 | Подзаголовок под H1 |
|
||||
| `.section__title` | `clamp(0.95rem, 1.35vw, 1.1rem)` | 600 | Заголовки секций («Навыки», «Портфолио») |
|
||||
| `.section__prose` | наследует | — | Основной текст абзацев |
|
||||
| `h2` в `.case-article` | `clamp(1.5rem, 2vw, 1.65rem)` | 500 | Разделы лонгрида |
|
||||
| `h3` в `.case-article` | наследует | — | Подразделы внутри H2 |
|
||||
|
||||
### Правила
|
||||
|
||||
- Заголовки используют `clamp()` — размер масштабируется от вьюпорта.
|
||||
- Не задавайте `font-size` в пикселях. Используйте `rem` или `clamp()`.
|
||||
- `line-height` для прозы: `1.55` (базовый), для заголовков: `1.2`.
|
||||
- `max-width` текстовой колонки: `42rem` (`.section__prose`).
|
||||
|
||||
---
|
||||
|
||||
## Отступы и сетка
|
||||
|
||||
### Токены
|
||||
|
||||
| Токен | Значение | Назначение |
|
||||
|---|---|---|
|
||||
| `--space` | `clamp(1rem, 4vw, 2.75rem)` | Горизонтальные поля + safe-area |
|
||||
| `--max` | `none` | Ширина контента = вьюпорт минус padding |
|
||||
| `--radius-sm` | Зависит от `data-radius` | Малые скругления |
|
||||
| `--radius-md` | Зависит от `data-radius` | Средние скругления |
|
||||
| `--radius-card` | Зависит от `data-radius` | Карточки |
|
||||
|
||||
### Секции
|
||||
|
||||
| Класс | Назначение |
|
||||
|---|---|
|
||||
| `.section` | Вертикальные отступы через `clamp()` |
|
||||
| `.section--tight` | Компактные отступы (кейсы, внутренние страницы) |
|
||||
| `.section--surface` | Прозрачный фон (для mesh на главной) |
|
||||
| `.section__inner` | Центрированная обёртка с `max-width: var(--max)` |
|
||||
| `.case-article` | Контентная колонка лонгрида: `max-width: 48rem` |
|
||||
|
||||
### Брейкпоинты
|
||||
|
||||
| Ширина | Что меняется |
|
||||
|---|---|
|
||||
| `860px` | Hero → 2 колонки (`1.15fr 0.85fr`) |
|
||||
| `760px` / `1180px` | Карусель портфолио: 1 → 2 → 3 карточки |
|
||||
| `720px` | Сетка навыков → 2 колонки |
|
||||
| `1024px` | Навыки: 6-колоночная мозаика |
|
||||
| `560px` / `1024px` | Контакты → 2 → 4 колонки |
|
||||
| `640px` | Wide-блоки схлопываются в ширину колонки |
|
||||
|
||||
### Правила
|
||||
|
||||
- Отдельной 12-колоночной сетки нет. Используйте CSS Grid внутри секций.
|
||||
- Горизонтальные отступы — `--space` + `safe-area-inset`.
|
||||
- Wide-блоки (`.case-media--wide`, `.case-callout`) шире колонки: `min(100vw - 2*padding, content + 8rem)`.
|
||||
|
||||
---
|
||||
|
||||
## Компоненты
|
||||
|
||||
### Кнопки
|
||||
|
||||
| Класс | Назначение |
|
||||
|---|---|
|
||||
| `.btn` | Базовый класс кнопки |
|
||||
| `.btn--primary` | Основная кнопка (акцентный фон, стекло) |
|
||||
| `.btn--secondary` | Вторичная кнопка (нейтральное стекло) |
|
||||
| `.btn--ghost` | Текстовая кнопка без фона |
|
||||
| `.btn--flat` | Плоский вариант (без «объёма») |
|
||||
| `.btn--raised` | Приподнятый вариант (с тенью) |
|
||||
| `.btn__icon` | Иконка внутри кнопки |
|
||||
|
||||
### FAB-кнопки
|
||||
|
||||
| Класс | Назначение |
|
||||
|---|---|
|
||||
| `.fab` | Базовый класс плавающей кнопки (круглая, `position: fixed`) |
|
||||
| `.fab--primary` | Акцентная FAB (градиент, стекло, `--on-accent` для текста/иконки) |
|
||||
| `.fab--secondary` | Вторичная FAB (нейтральная, для настроек) |
|
||||
| `.fab--label` | Модификатор: снимает фиксированную ширину, добавляет текст рядом с иконкой |
|
||||
| `.fab-primary__ico` | Иконка внутри primary FAB (маска через `mask-image`) |
|
||||
| `.fab__label` | Текстовая подпись внутри FAB |
|
||||
|
||||
Правило: `--on-accent` вычисляется в синхронном `theme-init-script` (в `<head>`) по luminance акцента. Не задавайте `color` вручную — наследуется от `.fab--primary`.
|
||||
|
||||
### Теги
|
||||
|
||||
| Класс | Назначение |
|
||||
|---|---|
|
||||
| `.hero__tags` | Контейнер тегов в Hero |
|
||||
| `.hero__tag` | Тег (пилл с рамкой). Используйте для ключевых слов |
|
||||
| `.portfolio-card__tag` | Тег внутри карточки портфолио |
|
||||
|
||||
### Карточки
|
||||
|
||||
| Класс | Назначение |
|
||||
|---|---|
|
||||
| `.portfolio-card` | Карточка проекта в портфолио |
|
||||
| `.portfolio-card__body` | Текстовая часть |
|
||||
| `.portfolio-card__cover` | Обложка |
|
||||
| `.skill-task-card` | Карточка навыка (задача + решения) |
|
||||
| `.contact-card` | Контактная карточка (ссылка или действие) |
|
||||
|
||||
### Блоки лонгрида
|
||||
|
||||
| Класс | Назначение |
|
||||
|---|---|
|
||||
| `.hero__eyebrow` | Подзаголовок перед H1 |
|
||||
| `.case-page__h1` | Заголовок страницы |
|
||||
| `.case-page__sub` | Подзаголовок |
|
||||
| `.section__prose` | Абзац текста |
|
||||
| `.section__title` | Заголовок секции |
|
||||
| `.case-callout` | Акцентный блок (важная мысль) |
|
||||
| `.case-media` | Обёртка для изображения/видео |
|
||||
| `.case-media--natural` | Изображение в натуральном масштабе |
|
||||
| `.case-media--content` | По ширине текстовой колонки |
|
||||
| `.case-media--wide` | Шире колонки статьи |
|
||||
|
||||
---
|
||||
|
||||
## Поведение
|
||||
|
||||
### Изображения
|
||||
|
||||
- Формат: **WebP** для всех изображений.
|
||||
- Видео: **WebM** (MP4 как fallback).
|
||||
- Lazy loading: `loading="lazy"`, `decoding="async"`.
|
||||
- Просмотр по клику: `data-image-viewer` на `<img>`.
|
||||
- Заглушка при загрузке: `.is-img-loading` / `.has-img-loading`.
|
||||
|
||||
### Секции
|
||||
|
||||
- Порядок на странице кейса: `header-case` → `fab-stack` → `main.case-article` → `projects-section` → `contact-section` → `footer`.
|
||||
- Порядок на внутренних страницах: `header-minimal` → `fab-stack-home-contact` → `main.section` → `footer`.
|
||||
|
||||
### Навигация
|
||||
|
||||
- Главная: горизонтальная навигация по секциям.
|
||||
- Внутренние страницы: ссылка «на главную» в шапке.
|
||||
- Плавающие кнопки (FAB): тема, контакты.
|
||||
|
||||
---
|
||||
|
||||
## Do's and Don'ts
|
||||
|
||||
### Do's
|
||||
|
||||
- Используйте токены цвета (`--accent`, `--text`, `--surface`), не хардкодьте.
|
||||
- Используйте `clamp()` для типографики — не фиксированные px/rem.
|
||||
- Используйте `.section__prose` для основного текста — он задаёт `max-width` и `color`.
|
||||
- Используйте `.hero__eyebrow` для подзаголовков перед заголовками.
|
||||
- Используйте WebP для изображений, WebM для видео.
|
||||
- Для лонгридов внутри `.case-article` — заголовки `h2`/`h3` стилизуются автоматически.
|
||||
|
||||
### Don'ts
|
||||
|
||||
- Не создавайте новые классы для типографики, если есть готовые в таблице шкалы.
|
||||
- Не используйте `font-size` в пикселях.
|
||||
- Не смешивайте стили из разных `data-font` на одной странице.
|
||||
- Не используйте `.hero__tag` для навыков в резюме — используйте `.skill-card` или простой список.
|
||||
- Не создавайте wide-блоки без необходимости — они выходят за колонку и ломают ритм.
|
||||
- Не используйте декоративные градиенты на функциональных поверхностях.
|
||||
|
||||
---
|
||||
|
||||
## Страницы
|
||||
|
||||
| Страница | Шаблон | Ключевые компоненты |
|
||||
|---|---|---|
|
||||
| Главная | `src/pages/index.html` | Hero, Skills, Projects, Contact |
|
||||
| Кейс | `src/pages/cases/*.html` | `.case-article`, `.hero__eyebrow`, `.case-page__h1`, `.case-media` |
|
||||
| Резюме | `src/pages/resume*.html` | `.doc`, `.profile-header`, `.meta-grid`, `.timeline`, `.skill-grid` |
|
||||
| Design System | `src/pages/cases/design-system.html` | Живой каталог компонентов и токенов |
|
||||
| Demo elements | `src/pages/cases/template-elements-demo.html` | Элементы лонгрида: медиа, галереи, видео, callout |
|
||||
| Mini projects | `src/pages/cases/mini-projects-showcase.html` | Карточки активности (mp-card) |
|
||||
|
||||
---
|
||||
|
||||
## Файлы
|
||||
|
||||
| Файл | Назначение |
|
||||
|---|---|
|
||||
| `public/css/main.css` | Единый CSS: токены + все компоненты |
|
||||
| `src/pages/cases/design-system.html` | Живой каталог токенов, типографики, кнопок, карточек |
|
||||
| `src/pages/cases/template-elements-demo.html` | Элементы лонгрида: медиа, галереи, видео, callout |
|
||||
| `src/pages/cases/mini-projects-showcase.html` | Карточки активности (mp-card) |
|
||||
| `docs/case-page-blocks.md` | Инструкция по блокам лонгридов |
|
||||
| `DESIGN.md` | Этот файл — описание для AI-агентов |
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
# Build the static site and serve it with nginx
|
||||
FROM node:20-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
RUN npm run build:pages
|
||||
|
||||
FROM nginx:alpine
|
||||
# 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 --from=build /app/public /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
@@ -1,9 +0,0 @@
|
||||
# Dev environment: serves public/ with BrowserSync + content-edits API (port 4175)
|
||||
FROM node:22-slim
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
RUN npm run build:pages
|
||||
EXPOSE 4175
|
||||
CMD ["npm", "run", "serve"]
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/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"
|
||||
@@ -1,57 +0,0 @@
|
||||
# Синхронизация `public` -> `gitverse`
|
||||
|
||||
## Назначение
|
||||
|
||||
Скрипт `sync-gitverse` копирует содержимое `public` в папку `gitverse`, затем выполняет коммит и пуш в репозиторий внутри `gitverse`.
|
||||
|
||||
## Запуск
|
||||
|
||||
- Через npm:
|
||||
- `npm run sync-gitverse`
|
||||
- Напрямую:
|
||||
- `node scripts/sync-gitverse.mjs`
|
||||
- С явными путями:
|
||||
- `node scripts/sync-gitverse.mjs <sourceDir> <targetDir>`
|
||||
|
||||
По умолчанию:
|
||||
|
||||
- `sourceDir = public`
|
||||
- `targetDir = gitverse`
|
||||
|
||||
## Что делает скрипт
|
||||
|
||||
1. Проверяет, что исходная папка существует.
|
||||
2. В целевой папке удаляет всё, кроме:
|
||||
- `.git`
|
||||
- `.gitverse`
|
||||
3. Копирует содержимое `public` в `gitverse` (файлы `.png` пропускаются — в деплое используются WebP и остальные форматы).
|
||||
4. В репозитории `gitverse` выполняет:
|
||||
- `git add .`
|
||||
- `git commit -m "sync public YYYY-MM-DD HH:mm"` (только если есть изменения)
|
||||
- `git push`
|
||||
5. После успешного пуша открывает в системном браузере по умолчанию: `https://mamadaevv.gitverse.site/me/`
|
||||
|
||||
Если изменений после копирования нет, коммит и пуш не делаются.
|
||||
|
||||
## Инструкция для агента (Cursor)
|
||||
|
||||
Когда пользователь просит **выложить на GitVerse**, **собрать/задеплоить gitverse**, **синхронизировать с gitverse** или аналогично:
|
||||
|
||||
1. **Сборка `public/`:** если менялись `src/pages/**` или `src/partials/**` — `npm run build:pages`; если шрифты/Plyr/`package.json` или `scripts/copy-vendor.mjs` — `npm run build` (сначала `vendor:copy`, затем страницы). См. [`docs/vendor-assets.md`](vendor-assets.md).
|
||||
2. **Синк и пуш:** выполни `npm run sync-gitverse` из корня. Нужны разрешения **network** и **git_write** (SSH на GitVerse, пуш из папки `gitverse`).
|
||||
3. **Ожидания:** скрипт не копирует файлы `.png` в `gitverse`. После **успешного** `git push` открывается системный браузер с `https://mamadaevv.gitverse.site/me/`. Если изменений в `gitverse` после копирования нет — коммит/пуш не выполняются, браузер не открывается.
|
||||
4. **Не вызывай** `sync-gitverse` без запроса пользователя: скрипт очищает целевую папку (кроме `.git` и `.gitverse`) и пушит в remote.
|
||||
5. **Корневой git репозиторий** этого проекта считается **только локальным**: не пушь из корня в `origin` и не настраивай remote без явной просьбы пользователя с URL. Внешняя выкладка — через `gitverse`, не через `git push` в корне.
|
||||
6. Деплой на VPS — отдельный сценарий, см. **`docs/vps-deploy.md`**.
|
||||
|
||||
Подробности и ограничения — в разделах выше.
|
||||
|
||||
## Требования
|
||||
|
||||
- В `gitverse` уже должен быть инициализирован git-репозиторий (папка `.git`).
|
||||
- Должен быть настроен доступ на push (SSH-ключ/права).
|
||||
|
||||
## Важно
|
||||
|
||||
- Скрипт удаляет в `gitverse` все файлы и папки, кроме `.git` и `.gitverse`.
|
||||
- Не запускай скрипт, если в `gitverse` есть локальные несохраненные изменения, которые нужно оставить.
|
||||
+5
-11
@@ -1,10 +1,11 @@
|
||||
# Локальный просмотр сайта
|
||||
|
||||
Сайт в режиме разработки обслуживается из папки `**public/**` через [BrowserSync](https://browsersync.io/): при изменении файлов страница в браузере обновляется сама.
|
||||
Сайт в режиме разработки обслуживается из папки `**public/**` через нативный HTTP-сервер (Node.js `http` модуль): статика + API правок контента.
|
||||
|
||||
## Требования
|
||||
|
||||
- Установлены **Node.js** и **npm** (идут вместе с Node).
|
||||
- **Node.js 22** (см. `.node-version` в корне проекта). fnm/fvm переключают автоматически.
|
||||
- **npm** (идёт вместе с Node).
|
||||
|
||||
## Первый раз в проекте
|
||||
|
||||
@@ -23,18 +24,11 @@ npm run vendor:copy
|
||||
npm run serve
|
||||
```
|
||||
|
||||
Скрипт [`scripts/serve-dev.mjs`](../scripts/serve-dev.mjs): статика из `public/`, API правок контента, перезагрузка **только** при изменениях в `public/**` (запись в `texts/content-edits/` вкладку не перезагружает).
|
||||
|
||||
Без API: `npm run serve:static`.
|
||||
Скрипт [`scripts/serve-dev.mjs`](../scripts/serve-dev.mjs): статика из `public/`, API правок контента. Нет авто-релиоада — после правок в `public/` обновляй страницу вручную.
|
||||
|
||||
## Куда смотреть
|
||||
|
||||
- **Сайт:** [http://localhost:4175](http://localhost:4175) — откроется `public/index.html` и остальные пути относительно `public/`.
|
||||
- **Панель BrowserSync UI:** [http://localhost:4176](http://localhost:4176) (опционально, для синхронизации и настроек).
|
||||
|
||||
## Что отслеживается
|
||||
|
||||
Любые изменения в `**public/**`**: HTML, CSS, JS, картинки. Папка `texts/content-edits/` **не** в watch — autosave правок не сбрасывает режим редактирования.
|
||||
|
||||
## API правок контента
|
||||
|
||||
@@ -48,4 +42,4 @@ npm run serve
|
||||
|
||||
## Остановка
|
||||
|
||||
В терминале: **Ctrl+C**.
|
||||
В терминале: **Ctrl+C**.
|
||||
@@ -0,0 +1,52 @@
|
||||
# PDF резюме
|
||||
|
||||
## Генерация PDF
|
||||
|
||||
Скрипт `scripts/generate-resume-pdf.mjs` открывает `resume-5.html` через Puppeteer, применяет шрифт geologica (PT Sans), убирает подложку/обводку блока `.resume-doc` и сохраняет PDF.
|
||||
|
||||
**Важно**: скрипт требует запущенный dev-сервер (`npm run serve` → `localhost:4175`).
|
||||
|
||||
### Запуск
|
||||
|
||||
```bash
|
||||
npm run generate:resume-pdf
|
||||
```
|
||||
|
||||
или вручную:
|
||||
|
||||
```bash
|
||||
node scripts/generate-resume-pdf.mjs http://localhost:4175/resume-5.html geologica
|
||||
```
|
||||
|
||||
Параметры:
|
||||
- `[url]` — URL страницы (по умолчанию `http://localhost:4175/resume-5.html`)
|
||||
- `[font]` — ID шрифта: `geologica`, `merriweather`, `mono` (по умолчанию `geologica`)
|
||||
|
||||
### Выходной файл
|
||||
|
||||
`public/assets/resume/Mamadaev_Nik__CV__Product_Designer_UX-UI.pdf`
|
||||
|
||||
Кнопка «Скачать в PDF» на странице `resume-5.html` — это `<a>` ссылка на этот файл.
|
||||
|
||||
### Когда перегенерировать
|
||||
|
||||
- После правок в `src/pages/resume-5.html` (контент, стили)
|
||||
- После правок в `src/css/resume-5.css` (инлайн-стили в `<style>`)
|
||||
- При смене шрифта по умолчанию в скрипте
|
||||
|
||||
### Что скрипт делает с страницей
|
||||
|
||||
1. Устанавливает шрифт через `localStorage` + `data-font`
|
||||
2. Ждёт загрузки шрифтов (`document.fonts.ready`)
|
||||
3. Удаляет `header`, `footer`, `nav`, `.fab-stack`, `.cookie-notice`, `.skip-link`
|
||||
4. Убирает `max-width` с `.resume-doc`, ставит `width: 100%`
|
||||
5. Убирает фон (`background: transparent`) и обводку (`border: none`)
|
||||
6. Захватывает `.resume-doc` как A4 PDF с `printBackground: true`
|
||||
|
||||
### Не попадает в PDF
|
||||
|
||||
Из `.resume-doc` удаляются (но остаются на сайте):
|
||||
- Фон блока
|
||||
- Обводка блока
|
||||
|
||||
Всё остальное (отступы, шрифты, сетка) — как на сайте.
|
||||
@@ -1,6 +1,6 @@
|
||||
# Локальные vendor-ассеты (шрифты и Plyr)
|
||||
|
||||
Сайт не использует Google Fonts и jsDelivr в рантайме. Файлы лежат в `public/` и попадают на хостинг через `sync-gitverse`.
|
||||
Сайт не использует Google Fonts и jsDelivr в рантайме. Файлы лежат в `public/` и попадают на хостинг через git push.
|
||||
|
||||
## Что где
|
||||
|
||||
@@ -49,7 +49,3 @@ npm run build:pages
|
||||
1. Обновить версию в `package.json` (`dependencies.plyr`).
|
||||
2. `npm install` → `npm run vendor:copy`.
|
||||
3. При смене API — правки в `video-player.js`.
|
||||
|
||||
## Деплой
|
||||
|
||||
Перед `npm run sync-gitverse` выполни `npm run build`, чтобы в `public/` были актуальные шрифты, Plyr и HTML.
|
||||
@@ -1,59 +0,0 @@
|
||||
# Деплой на VPS (инкрементальный)
|
||||
|
||||
Скрипт `scripts/deploy-vps.mjs` загружает содержимое `public/` на VPS, передавая только изменённые файлы.
|
||||
|
||||
## Принцип работы
|
||||
|
||||
1. **Манифест** (`.deploy-manifest.json`) хранит `mtime` и `size` каждого файла с прошлого деплоя.
|
||||
2. При запуске скрипт сканирует `public/`, сравнивает с манифестом:
|
||||
- Файлы с изменившимся `mtime` или `size` — загружаются.
|
||||
- Файлы, которых нет локально, но есть в манифесте — удаляются с сервера.
|
||||
3. Изменённые файлы пакуются в `tar` и передаются **одним SSH-соединением** (без сжатия, чтобы не тратить CPU на уже сжатые медиа).
|
||||
4. Манифест обновляется после успешного деплоя.
|
||||
|
||||
При первом запуске (манифест пуст) заливаются все файлы — ~3 минуты на ~400 файлов. Повторный деплой (1–10 изменившихся файлов) — 2–5 секунд.
|
||||
|
||||
## Запуск
|
||||
|
||||
```bash
|
||||
npm run deploy:vps
|
||||
# или напрямую
|
||||
node scripts/deploy-vps.mjs [sourceDir]
|
||||
```
|
||||
|
||||
По умолчанию `sourceDir = public`.
|
||||
|
||||
## Рецепты
|
||||
|
||||
### Только в Coolify
|
||||
|
||||
Запрос пользователя: «задеплой в Coolify», «задеплой на VPS».
|
||||
|
||||
```bash
|
||||
npm run deploy:vps
|
||||
```
|
||||
|
||||
Нужны разрешения: **all** (SSH-ключ `~/.ssh/beget`, доступ к файлам `public/`).
|
||||
|
||||
### Везде (VPS + GitVerse)
|
||||
|
||||
```bash
|
||||
npm run deploy
|
||||
```
|
||||
|
||||
Выполняет `deploy:vps`, затем `sync-gitverse`.
|
||||
|
||||
## Конфигурация
|
||||
|
||||
- **SSH-ключ:** `~/.ssh/beget`
|
||||
- **Хост:** `root@155.212.186.39`
|
||||
- **Целевая папка:** `/data/static-site`
|
||||
- **Манифест:** `.deploy-manifest.json` в корне проекта (не коммитится)
|
||||
|
||||
## Сброс манифеста
|
||||
|
||||
Если нужно залить всё с нуля — удалить `.deploy-manifest.json`:
|
||||
|
||||
```bash
|
||||
rm .deploy-manifest.json
|
||||
```
|
||||
Generated
+193
-1591
File diff suppressed because it is too large.
Load diff
+2
-5
@@ -6,12 +6,9 @@
|
||||
"build:pages": "node scripts/build-pages.mjs",
|
||||
"build": "npm run vendor:copy && npm run build:pages",
|
||||
"serve": "node scripts/serve-dev.mjs",
|
||||
"serve:static": "browser-sync start --server \"public\" --files \"public/**/*\" --no-notify --no-open --no-ghost-mode --port 4175 --ui-port 4176",
|
||||
"convert-videos": "node scripts/convert-videos.mjs",
|
||||
"optimize-images": "node scripts/optimize-images.mjs",
|
||||
"deploy:vps": "node scripts/deploy-vps.mjs",
|
||||
"deploy": "npm run deploy:vps && npm run sync-gitverse",
|
||||
"sync-gitverse": "node scripts/sync-gitverse.mjs"
|
||||
"generate:resume-pdf": "node scripts/generate-resume-pdf.mjs http://localhost:4175/resume-5.html geologica"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fontsource-variable/geologica": "^5.2.8",
|
||||
@@ -20,7 +17,7 @@
|
||||
"@fontsource/pt-mono": "^5.2.8",
|
||||
"@fontsource/pt-sans": "^5.2.8",
|
||||
"@fontsource/source-code-pro": "^5.2.7",
|
||||
"browser-sync": "^3.0.4",
|
||||
"puppeteer": "^25.7.0",
|
||||
"sharp": "^0.34.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"model": "black-forest-labs/flux.2-klein-4b",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Минималистичный AI-промпт для портретов в стиле high-fashion. Мягкий студийный свет, чистый фон и акцент на естественной красоте. Такой визуал идеально подходит для тренировки моделей освещения и теста фотореализма. Подходит для: fashion-портретов, нейрофотосессий, коммерческих стоков. Стиль: минимализм, чистая палитра, editorial precision. 👉 Узнай больше AI-идей и вдохновляющих промптов в моём телеграм-канале «Нейропольза» — переходи по ссылке. Minimalist AI portrait prompt with diffused studio light and fashion-magazine aesthetics. Perfect for clean editorial visuals and AI-photo training."
|
||||
}
|
||||
],
|
||||
"modalities": ["image"],
|
||||
"image_config": { "aspect_ratio": "9:16" },
|
||||
"_provider": "PLZ",
|
||||
"_cost": 1
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 9V2H18V9" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 18H4C2.89543 18 2 17.1046 2 16V11C2 9.89543 2.89543 9 4 9H20C21.1046 9 22 9.89543 22 11V16C22 17.1046 21.1046 18 20 18H18" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6 15H18V22H6V15Z" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 537 B |
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -542,7 +566,7 @@
|
||||
|
||||
<h3>Дальнейшее развитие</h3>
|
||||
<p class="section__prose">
|
||||
В дорожной карте оставались отдельные крупные куски: сценарии вокруг LLM (списки, статусы, действия), пошаговый мастер обучения с прогрессом и отменой, а также полноценный контур OCR с разметкой регионов и превью качества на странице. Они не входили в минимальный набор для первого промышленного релиза интерфейса, но заложенные паттерны должны их принять без ломки навигации.
|
||||
В дорожной карте оставались отдельные крупные куски: сценарии вокруг LLM (списки, статусы, действия), пошаговый мастер обучения с прогрессом и отменой, а также полноценный контур OCR с разметкой регионов и превью качества на странице. Они не входили в минимальный набор для первого промышленного релиза интерфейса, но заложенные паттерны должны их принять без больших переделок.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -577,140 +601,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -955,14 +979,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -741,140 +765,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -1094,14 +1118,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -106,7 +130,7 @@
|
||||
margin: 0 0 1.15rem;
|
||||
padding-top: clamp(2.75rem, 6vw, 4rem);
|
||||
font-family: var(--font);
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-size: clamp(1.7rem, 3vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
scroll-margin-top: 1.5rem;
|
||||
@@ -121,7 +145,7 @@
|
||||
.case-article.ds-page > h3 {
|
||||
margin: clamp(2rem, 4vw, 2.75rem) 0 0.85rem;
|
||||
font-family: var(--font);
|
||||
font-size: 1.05rem;
|
||||
font-size: 1.55rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
@@ -532,6 +556,7 @@
|
||||
<li><a href="#fonts">Шрифты</a></li>
|
||||
<li><a href="#layout">Сетка и адаптив</a></li>
|
||||
<li><a href="#components">Компоненты</a></li>
|
||||
<li><a href="#fab">FAB-кнопки</a></li>
|
||||
<li><a href="#blocks">Блоки</a></li>
|
||||
<li><a href="#mini-projects">Активность</a></li>
|
||||
</ol>
|
||||
@@ -864,6 +889,17 @@
|
||||
</div>
|
||||
<p class="sg-label">.btn .btn--primary | secondary | ghost · .btn--flat | raised · .btn__icon</p>
|
||||
|
||||
<h3>FAB-кнопки</h3>
|
||||
<p class="section__prose">
|
||||
Плавающие кнопки в правом нижнем углу (<code>.fab-stack</code>). Иконка-only и с текстовой подписью.
|
||||
</p>
|
||||
<div class="sg-stack sg-stack--row">
|
||||
<a class="fab fab--primary" href="#components" aria-label="Демо FAB"><span class="fab-primary__ico" aria-hidden="true"></span></a>
|
||||
<button type="button" class="fab fab--primary fab--label"><span class="fab-primary__ico" aria-hidden="true"></span><span class="fab__label">Скачать в PDF</span></button>
|
||||
<button type="button" class="fab fab--secondary" aria-label="Демо secondary FAB"><span class="theme-panel-fab__icon theme-panel-fab__icon--open-hide" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
<p class="sg-label">.fab .fab--primary | secondary · .fab--label (с текстом) · .fab-primary__ico · .fab__label</p>
|
||||
|
||||
<h3>Теги</h3>
|
||||
<ul class="hero__tags" aria-label="Демо тегов">
|
||||
<li class="hero__tag">hero__tag</li>
|
||||
|
||||
+161
-137
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -278,7 +302,7 @@
|
||||
</p>
|
||||
|
||||
<h2 id="obzor">Обзор</h2>
|
||||
<p class="section__prose">Общий вид приложения — отправная точка для остальных материалов на странице.</p>
|
||||
<p class="section__prose">Общий вид приложения — рабочий процесс с открытым документом, панелями инструментов и canvas. Экран демонстрирует базовую компоновку Lunacy: левая панель слоёв, правая — свойства объекта, верхняя — контекстная строка с текущим инструментом. Отправная точка для остальных материалов на странице.</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
|
||||
@@ -529,140 +553,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -882,14 +906,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+160
-136
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -271,140 +295,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -624,14 +648,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium" data-font="merriweather">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -235,9 +259,16 @@
|
||||
background: color-mix(in srgb, var(--surface) 90%, var(--accent));
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__variant {
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__variant:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.85rem;
|
||||
font-size: 0.72rem;
|
||||
@@ -245,25 +276,50 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend--6 {
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend--4 {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend--2 {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend span {
|
||||
padding: 0.2rem 0;
|
||||
border-radius: var(--radius-sm);
|
||||
background: color-mix(in srgb, var(--line) 35%, transparent);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__row {
|
||||
.mp-showcase-cells-demo__row-label {
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin: 0 0 0.55rem;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.55rem;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__row:last-of-type {
|
||||
margin-bottom: 0;
|
||||
.mp-showcase-cells-demo__grid--6 {
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__grid--4 {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__grid--2 {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__block {
|
||||
grid-row: 1;
|
||||
min-height: 2.35rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -288,6 +344,10 @@
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__block--4 {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__caption {
|
||||
margin: 0.85rem 0 0;
|
||||
font-size: 0.82rem;
|
||||
@@ -439,12 +499,13 @@
|
||||
<li><a href="#types">Типы карточек</a></li>
|
||||
<li><a href="#cells">Ширина в клетках</a></li>
|
||||
<li><a href="#grid">Живая сетка masonry</a></li>
|
||||
<li><a href="#fixed-height">Фиксированная высота</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<h2 id="intro">Как пользоваться</h2>
|
||||
<p class="section__prose">
|
||||
Сначала выберите <strong>тип</strong> (stack, horizontal, compact, decor), затем <strong>data-mp-cells</strong> (1–3) и
|
||||
Сначала выберите <strong>тип</strong> (stack, horizontal, compact, decor), затем <strong>data-mp-cells</strong> (1–4) и
|
||||
порядок <code>li</code> в списке. Карточки с <code>data-mp-extra</code> не влияют на высоту списка до кнопки «Показать все».
|
||||
Подробности — в <code>docs/mini-projects-cards.md</code>.
|
||||
</p>
|
||||
@@ -674,35 +735,95 @@
|
||||
|
||||
<h2 id="cells">Ширина в клетках</h2>
|
||||
<p class="section__prose">
|
||||
Атрибут <code>data-mp-cells</code> на <code>li.mini-projects-grid__item</code> задаёт желаемую ширину от 1 до 3 клеток.
|
||||
Атрибут <code>data-mp-cells</code> на <code>li.mini-projects-grid__item</code> задаёт желаемую ширину от 1 до 4 клеток.
|
||||
Скрипт не даст карточке быть шире текущего ряда.
|
||||
</p>
|
||||
<p class="section__prose">
|
||||
Для адаптивной ширины используйте <code>data-mp-cells-sm</code> (при 4 клетках в ряду, ≥ 880 px) и
|
||||
<code>data-mp-cells-xs</code> (при 2 клетках, ≥ 520 px). Скрипт выбирает значение по текущему числу клеток в ряду.
|
||||
</p>
|
||||
<div class="mp-showcase-attrs-table">
|
||||
<table class="mp-showcase-cells-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Атрибут</th>
|
||||
<th scope="col">Когда применяется</th>
|
||||
<th scope="col">Пример</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>data-mp-cells</code></td>
|
||||
<td>Широкий экран (6 клеток, ≥ 1180 px)</td>
|
||||
<td><code>data-mp-cells="3"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>data-mp-cells-sm</code></td>
|
||||
<td>Средний экран (4 клетки, ≥ 880 px)</td>
|
||||
<td><code>data-mp-cells-sm="2"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>data-mp-cells-xs</code></td>
|
||||
<td>Узкий экран (2 клетки, ≥ 520 px)</td>
|
||||
<td><code>data-mp-cells-xs="1"</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="section__prose" style="margin-top:0.55rem">
|
||||
<strong>Пример:</strong> <code>data-mp-cells="3" data-mp-cells-sm="2"</code> — карточка занимает 3 клетки на широком экране, 2 на среднем, 1 на узком.
|
||||
</p>
|
||||
<figure class="mp-showcase-cells-demo" aria-label="Схема ширины карточек в клетках">
|
||||
<div class="mp-showcase-cells-demo__legend" aria-hidden="true">
|
||||
<span>1</span>
|
||||
<span>2</span>
|
||||
<span>3</span>
|
||||
<span>4</span>
|
||||
<span>5</span>
|
||||
<span>6</span>
|
||||
<div class="mp-showcase-cells-demo__variant">
|
||||
<div class="mp-showcase-cells-demo__legend mp-showcase-cells-demo__legend--6" aria-hidden="true">
|
||||
<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span>
|
||||
</div>
|
||||
<p class="mp-showcase-cells-demo__row-label">≥ 1180 px — 6 клеток</p>
|
||||
<div class="mp-showcase-cells-demo__grid mp-showcase-cells-demo__grid--6">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--4">4</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mp-showcase-cells-demo__row-label">Ряд из 6 клеток (широкий экран)</p>
|
||||
<div class="mp-showcase-cells-demo__row">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__variant">
|
||||
<div class="mp-showcase-cells-demo__legend mp-showcase-cells-demo__legend--4" aria-hidden="true">
|
||||
<span>1</span><span>2</span><span>3</span><span>4</span>
|
||||
</div>
|
||||
<p class="mp-showcase-cells-demo__row-label">≥ 880 px — 4 клетки</p>
|
||||
<div class="mp-showcase-cells-demo__grid mp-showcase-cells-demo__grid--4">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--4">4</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mp-showcase-cells-demo__row">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
</div>
|
||||
<div class="mp-showcase-cells-demo__row">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__variant">
|
||||
<div class="mp-showcase-cells-demo__legend mp-showcase-cells-demo__legend--2" aria-hidden="true">
|
||||
<span>1</span><span>2</span>
|
||||
</div>
|
||||
<p class="mp-showcase-cells-demo__row-label">≥ 520 px — 2 клетки</p>
|
||||
<div class="mp-showcase-cells-demo__grid mp-showcase-cells-demo__grid--2">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption class="mp-showcase-cells-demo__caption">
|
||||
Цифра в блоке = значение <code>data-mp-cells</code>. Карточка занимает столько клеток подряд в одном ряду.
|
||||
Цифра в блоке = значение <code>data-mp-cells</code>. Карточка занимает столько клеток подряд. При узком экране клеток меньше — карточки с шириной > число клеток переносятся на следующий ряд. С <code>data-mp-cells-sm</code> / <code>data-mp-cells-xs</code> карточка меняет ширину при сужении.
|
||||
</figcaption>
|
||||
</figure>
|
||||
<table class="mp-showcase-cells-table">
|
||||
@@ -940,6 +1061,174 @@
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="fixed-height" class="section section--surface mp-showcase-grid-section" aria-labelledby="fixed-height-title">
|
||||
<div class="section__inner">
|
||||
<h2 id="fixed-height-title" class="section__title">Фиксированная высота</h2>
|
||||
<p class="section__prose">
|
||||
Атрибут <code>data-mp-height="…"</code> на <code>li.mini-projects-grid__item</code> задаёт фиксированную высоту карточки в пикселях. Текст обрезается с многоточием, если не влезает.
|
||||
</p>
|
||||
<ol
|
||||
id="mini-projects-fixed-height-grid"
|
||||
class="mini-projects-grid mp-showcase-grid"
|
||||
data-mini-projects-list
|
||||
>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="4" data-mp-cells-sm="4" data-mp-cells-xs="2" data-mp-height="600">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[4→4→2] height=600 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[4→4→2] height=600 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">веб-сайт</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">4 → 4 → 2. data-mp-cells-sm="4" data-mp-cells-xs="2". Высота 600px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2" data-mp-height="600" data-mp-height-sm="400">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] height=600 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[2] height=600 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">заметка</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Две клетки, высота 600px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2" data-mp-height="400">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] height=400 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[2] height=400 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">утилита</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Две клетки, высота 400px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2" data-mp-height="400">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] height=400 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[2] height=400 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">шаблон</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Две клетки, высота 400px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2" data-mp-height="400">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] height=400 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[2] height=400 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">плагин</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Две клетки, высота 400px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-mp-cells-xs="1">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="#" aria-label="[3→2→1] · compact · ссылка">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[3→2→1] · compact · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">плагин</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">3 → 2 → 1. data-mp-cells-sm="2" data-mp-cells-xs="1". Авто-высота.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-mp-cells-xs="1">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="#" aria-label="[3→2→1] · compact · ссылка">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[3→2→1] · compact · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">документ</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">3 → 2 → 1. data-mp-cells-sm="2" data-mp-cells-xs="1".</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<section class="section section--surface" aria-hidden="true">
|
||||
|
||||
+160
-136
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -271,140 +295,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -624,14 +648,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium" data-font="merriweather">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Кейс: плагин колоночного вида для Obsidian — дизайн и UX плагина для заметок."
|
||||
/>
|
||||
<title>Колоночный вид для Obsidian — кейс</title>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium" data-font="merriweather">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Кейс: плагин колоночного вида для Obsidian — дизайн и UX плагина для заметок."
|
||||
/>
|
||||
<title>Колоночный вид для Obsidian — кейс</title>
|
||||
<script>
|
||||
(function () {
|
||||
var FONT_CSS = {
|
||||
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -77,81 +101,81 @@
|
||||
<script src="../js/skill-connectors.js" defer></script>
|
||||
<script type="module" src="../js/main.js"></script>
|
||||
|
||||
|
||||
|
||||
<link rel="stylesheet" href="../vendor/plyr/plyr.css" />
|
||||
|
||||
<style>
|
||||
.case-article {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.case-article h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article h3 {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article .section__prose {
|
||||
margin-bottom: 0.75rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article a:not(.btn) {
|
||||
color: var(--accent);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
(function () {
|
||||
try {
|
||||
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
|
||||
var d = document.documentElement;
|
||||
var m = t.mode;
|
||||
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
|
||||
var eff =
|
||||
m === "system"
|
||||
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light"
|
||||
: m;
|
||||
d.dataset.theme = eff;
|
||||
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
|
||||
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
|
||||
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
|
||||
if (h !== null) d.style.setProperty("--theme-h", String(h));
|
||||
if (s !== null) d.style.setProperty("--theme-s", String(s));
|
||||
if (l !== null) {
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
} else {
|
||||
d.dataset.radius = "medium";
|
||||
}
|
||||
var f = t.font;
|
||||
if (f === "onest") f = "geologica";
|
||||
if (f === "anonymous") f = "mono";
|
||||
if (f === "merriweather" || f === "mono" || f === "geologica") {
|
||||
d.dataset.font = f;
|
||||
} else {
|
||||
d.dataset.font = "merriweather";
|
||||
}
|
||||
var mb = t.meshBg;
|
||||
if (mb === "off") {
|
||||
d.dataset.meshBg = "off";
|
||||
} else {
|
||||
d.dataset.meshBg = "on";
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<style>
|
||||
.case-article {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.case-article h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article h3 {
|
||||
font-size: 1.05rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article .section__prose {
|
||||
margin-bottom: 0.75rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article a:not(.btn) {
|
||||
color: var(--accent);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
(function () {
|
||||
try {
|
||||
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
|
||||
var d = document.documentElement;
|
||||
var m = t.mode;
|
||||
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
|
||||
var eff =
|
||||
m === "system"
|
||||
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light"
|
||||
: m;
|
||||
d.dataset.theme = eff;
|
||||
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
|
||||
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
|
||||
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
|
||||
if (h !== null) d.style.setProperty("--theme-h", String(h));
|
||||
if (s !== null) d.style.setProperty("--theme-s", String(s));
|
||||
if (l !== null) {
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
} else {
|
||||
d.dataset.radius = "medium";
|
||||
}
|
||||
var f = t.font;
|
||||
if (f === "onest") f = "geologica";
|
||||
if (f === "anonymous") f = "mono";
|
||||
if (f === "merriweather" || f === "mono" || f === "geologica") {
|
||||
d.dataset.font = f;
|
||||
} else {
|
||||
d.dataset.font = "merriweather";
|
||||
}
|
||||
var mb = t.meshBg;
|
||||
if (mb === "off") {
|
||||
d.dataset.meshBg = "off";
|
||||
} else {
|
||||
d.dataset.meshBg = "on";
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a class="skip-link" href="#case-main">К содержимому кейса</a>
|
||||
<header class="header" data-theme-picker>
|
||||
<div class="header__inner">
|
||||
@@ -164,7 +188,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<div class="fab-stack" aria-label="Быстрые действия">
|
||||
<div class="theme-panel-fab-wrap">
|
||||
<button type="button" class="fab fab--secondary glass-neutral" data-theme-panel-btn aria-expanded="false" aria-controls="theme-panel" aria-label="Настройки стиля">
|
||||
@@ -248,197 +272,197 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<main id="case-main" class="section section--tight">
|
||||
<div class="section__inner case-article">
|
||||
<p class="hero__eyebrow">Obsidian · Plugin</p>
|
||||
<h1 class="case-page__h1">Колоночный вид — плагин для Obsidian</h1>
|
||||
<p class="case-page__sub">Дизайн и разработка интерфейса для многоколоночной работы с заметками</p>
|
||||
|
||||
<p class="section__prose">
|
||||
<!-- Здесь будет введение -->
|
||||
</p>
|
||||
|
||||
<h2 id="context">Контекст</h2>
|
||||
<p class="section__prose">
|
||||
<!-- Контекст проекта -->
|
||||
</p>
|
||||
|
||||
<h2 id="task">Задача</h2>
|
||||
<p class="section__prose">
|
||||
<!-- Описание задачи -->
|
||||
</p>
|
||||
|
||||
<h2 id="solution">Решение</h2>
|
||||
<p class="section__prose">
|
||||
<!-- Что было сделано -->
|
||||
</p>
|
||||
|
||||
<h3>Фильтр использования</h3>
|
||||
<figure class="case-media">
|
||||
<div class="case-video-shell">
|
||||
<video controls preload="metadata" playsinline poster="../assets/obsidian-plugin-columns-view/filter use.webp" data-case-video-player style="display: block; width: 100%; height: auto">
|
||||
<source src="../assets/obsidian-plugin-columns-view/filter use.webm" type="video/webm" />
|
||||
<source src="../assets/obsidian-plugin-columns-view/filter use.mp4" type="video/mp4" />
|
||||
Ваш браузер не поддерживает видео.
|
||||
</video>
|
||||
</div>
|
||||
<figcaption>Фильтрация заметок в колоночном виде.</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3>Конфигурация отображения</h3>
|
||||
<figure class="case-media">
|
||||
<div class="case-video-shell">
|
||||
<video controls preload="metadata" playsinline poster="../assets/obsidian-plugin-columns-view/view configure.webp" data-case-video-player style="display: block; width: 100%; height: auto">
|
||||
<source src="../assets/obsidian-plugin-columns-view/view configure.webm" type="video/webm" />
|
||||
<source src="../assets/obsidian-plugin-columns-view/view configure.mp4" type="video/mp4" />
|
||||
Ваш браузер не поддерживает видео.
|
||||
</video>
|
||||
</div>
|
||||
<figcaption>Настройка колонок и отображения.</figcaption>
|
||||
</figure>
|
||||
|
||||
<h2 id="result">Результат</h2>
|
||||
<p class="section__prose">
|
||||
<!-- Итоги -->
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<main id="case-main" class="section section--tight">
|
||||
<div class="section__inner case-article">
|
||||
<p class="hero__eyebrow">Obsidian · Plugin</p>
|
||||
<h1 class="case-page__h1">Колоночный вид — плагин для Obsidian</h1>
|
||||
<p class="case-page__sub">Дизайн и разработка интерфейса для многоколоночной работы с заметками</p>
|
||||
|
||||
<p class="section__prose">
|
||||
<!-- Здесь будет введение -->
|
||||
</p>
|
||||
|
||||
<h2 id="context">Контекст</h2>
|
||||
<p class="section__prose">
|
||||
<!-- Контекст проекта -->
|
||||
</p>
|
||||
|
||||
<h2 id="task">Задача</h2>
|
||||
<p class="section__prose">
|
||||
<!-- Описание задачи -->
|
||||
</p>
|
||||
|
||||
<h2 id="solution">Решение</h2>
|
||||
<p class="section__prose">
|
||||
<!-- Что было сделано -->
|
||||
</p>
|
||||
|
||||
<h3>Фильтр использования</h3>
|
||||
<figure class="case-media">
|
||||
<div class="case-video-shell">
|
||||
<video controls preload="metadata" playsinline poster="../assets/obsidian-plugin-columns-view/filter use.webp" data-case-video-player style="display: block; width: 100%; height: auto">
|
||||
<source src="../assets/obsidian-plugin-columns-view/filter use.webm" type="video/webm" />
|
||||
<source src="../assets/obsidian-plugin-columns-view/filter use.mp4" type="video/mp4" />
|
||||
Ваш браузер не поддерживает видео.
|
||||
</video>
|
||||
</div>
|
||||
<figcaption>Фильтрация заметок в колоночном виде.</figcaption>
|
||||
</figure>
|
||||
|
||||
<h3>Конфигурация отображения</h3>
|
||||
<figure class="case-media">
|
||||
<div class="case-video-shell">
|
||||
<video controls preload="metadata" playsinline poster="../assets/obsidian-plugin-columns-view/view configure.webp" data-case-video-player style="display: block; width: 100%; height: auto">
|
||||
<source src="../assets/obsidian-plugin-columns-view/view configure.webm" type="video/webm" />
|
||||
<source src="../assets/obsidian-plugin-columns-view/view configure.mp4" type="video/mp4" />
|
||||
Ваш браузер не поддерживает видео.
|
||||
</video>
|
||||
</div>
|
||||
<figcaption>Настройка колонок и отображения.</figcaption>
|
||||
</figure>
|
||||
|
||||
<h2 id="result">Результат</h2>
|
||||
<p class="section__prose">
|
||||
<!-- Итоги -->
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -657,23 +681,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner"></div>
|
||||
</section>
|
||||
|
||||
|
||||
<footer class="footer">
|
||||
<div class="footer__inner">
|
||||
<span class="footer__chunk footer__chunk--date">© 2026<span class="footer__sep" aria-hidden="true"> · </span></span>
|
||||
@@ -681,7 +705,7 @@
|
||||
<span class="footer__chunk footer__chunk--meta footer__attr"><span class="footer__sep" aria-hidden="true"> · </span><a href="../cases/design-system.html">Design System</a><span class="footer__sep" aria-hidden="true"> · </span><a href="../cookie-policy.html">Политика cookie</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
|
||||
<aside class="cookie-notice glass-neutral" hidden data-cookie-notice>
|
||||
<p class="cookie-notice__text">
|
||||
Сайт использует cookie для комфортной работы. Подробнее — в
|
||||
@@ -694,9 +718,9 @@
|
||||
</span>
|
||||
</button>
|
||||
</aside>
|
||||
|
||||
|
||||
<div id="nav-more-menu-floating" class="nav-more__floating" hidden data-nav-more-menu-floating aria-hidden="true"></div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -410,140 +434,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -763,14 +787,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -271,140 +295,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -624,14 +648,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
+160
-136
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -699,140 +723,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -1052,14 +1076,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -33,6 +33,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -433,140 +457,140 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="ai-platform-primo-rpa.html" aria-label="Платформа для работы с AI — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/ai-platform-primo-rpa/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Платформа для работы с AI</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для обучения и использования AI‑моделей в бизнес‑процессах: работа с данными, сценариями автоматизации и Smart OCR.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="lunacy.html" aria-label="Графический редактор Lunacy — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/lunacy/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Графический редактор Lunacy</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Работа над интерфейсом Lunacy в команде Icons8: user flow, сложные прототипы, улучшение функциональности и интерфейсной логики.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="manu-game-maker.html" aria-label="Игровой движок MANU — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/manu-game-maker/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Игровой движок MANU</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Desktop App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Редизайн и развитие интерфейса игрового движка: новая концепция работы, обновлённая визуальная система и проработка сотен сложных пользовательских сценариев.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="mobile-clinic-app.html" aria-label="Мобильное приложение для сети клиник — открыть кейс">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/mobile-clinic-app/cover.webp"
|
||||
alt=""
|
||||
width="400"
|
||||
height="225"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Мобильное приложение для сети клиник</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Mobile App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Дизайн мобильного приложения для записи к врачам и работы с медицинскими услугами. Фокус на простом пользовательском пути, понятной навигации и быстром доступе к нужным действиям.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="orc-automation-panel.html" aria-label="Веб-панель для оркестрации автоматизаций — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Веб-панель для оркестрации автоматизаций</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Веб-кабинет оркестратора Primo RPA: проекты, запуск и контроль RPA-роботов. Редизайн ключевых экранов под продакшен без остановки релизов.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-distribution-concept.html" aria-label="Концепт сервиса распределения задач — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Концепт сервиса распределения задач</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">UX/UI</li>
|
||||
<li class="mp-card__tag">Analytics</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Продуктовый концепт сервиса для постановки, распределения и отслеживания задач, с акцентом на прозрачность процессов и удобство командной работы.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="task-tracker.html" aria-label="Таск-трекер для бек-офис системы — открыть кейс">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">Таск-трекер для бек-офис системы</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">Product Design</li>
|
||||
<li class="mp-card__tag">Web App</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Интерфейс для планирования и распределения задач в операционном отделе: общий пул, личный ToDo, обзор по исполнителям; вкладки, фильтры, доска / список / таблица, Drag&Drop.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section><section hidden class="section section--surface" aria-hidden="true">
|
||||
<div class="section__inner">
|
||||
<div class="projects__heading">
|
||||
@@ -811,14 +835,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="../assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
|
||||
+90
-3
@@ -954,6 +954,41 @@ a.fab--secondary:visited {
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* ── PDF download FAB ── */
|
||||
.fab-primary__ico--pdf {
|
||||
mask-image: url("../assets/shared/icons/cv.svg");
|
||||
-webkit-mask-image: url("../assets/shared/icons/cv.svg");
|
||||
}
|
||||
|
||||
/* ── Print FAB ── */
|
||||
.fab-secondary__ico--print {
|
||||
display: block;
|
||||
width: var(--icon-fab);
|
||||
height: var(--icon-fab);
|
||||
background: currentColor;
|
||||
mask-image: url("../assets/shared/icons/printer.svg");
|
||||
-webkit-mask-image: url("../assets/shared/icons/printer.svg");
|
||||
mask-size: contain;
|
||||
mask-repeat: no-repeat;
|
||||
mask-position: center;
|
||||
-webkit-mask-size: contain;
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
-webkit-mask-position: center;
|
||||
}
|
||||
|
||||
.fab--label {
|
||||
width: auto;
|
||||
padding: 0.65rem 1.1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.fab__label {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.theme-picker__stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -1289,7 +1324,7 @@ html[data-font="mono"] .hero__title {
|
||||
.case-page__h1 {
|
||||
margin: 0 0 0.5rem;
|
||||
font-family: var(--font-accent);
|
||||
font-size: clamp(1.35rem, 2.6vw, 1.95rem);
|
||||
font-size: clamp(2rem, 3.9vw, 2.9rem);
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: var(--text);
|
||||
@@ -1320,7 +1355,7 @@ html[data-font="mono"] .hero__title {
|
||||
|
||||
.case-page__sub {
|
||||
margin: 0 0 1.25rem;
|
||||
font-size: clamp(1rem, 1.35vw, 1.1rem);
|
||||
font-size: clamp(1.5rem, 2vw, 1.65rem);
|
||||
color: var(--text-muted);
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -2728,6 +2763,50 @@ html[data-theme="light"] .hero__portrait-shell {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Scroll-reveal: плавное появление секций при скролле */
|
||||
[data-reveal] {
|
||||
opacity: 0;
|
||||
transform: translateY(80px);
|
||||
transition: opacity 0.4s ease-out, transform 0.6s ease-out;
|
||||
}
|
||||
|
||||
[data-reveal].is-visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Stagger: заголовок появляется первым, контент — через 100ms */
|
||||
[data-reveal].is-visible .section__title {
|
||||
transition-delay: 0.1s;
|
||||
}
|
||||
|
||||
[data-reveal].is-visible .section__inner > *:not(.section__title) {
|
||||
transition-delay: 0.25s;
|
||||
}
|
||||
|
||||
/* Исключаем skills и mini-projects — у них своя stagger-анимация */
|
||||
#skills[data-reveal].is-visible .section__title,
|
||||
#mini-projects[data-reveal].is-visible .section__title {
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
#skills[data-reveal].is-visible .section__inner > *:not(.section__title),
|
||||
#mini-projects[data-reveal].is-visible .section__inner > *:not(.section__title) {
|
||||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
[data-reveal] {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
transition: none;
|
||||
}
|
||||
[data-reveal].is-visible .section__title,
|
||||
[data-reveal].is-visible .section__inner > *:not(.section__title) {
|
||||
transition-delay: 0s;
|
||||
}
|
||||
}
|
||||
|
||||
.experience-grid {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
@@ -2972,6 +3051,7 @@ html[data-theme="light"] .hero__portrait-shell {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-card);
|
||||
background: var(--surface);
|
||||
@@ -3001,6 +3081,7 @@ html[data-theme="light"] .hero__portrait-shell {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mp-card__title {
|
||||
@@ -3015,6 +3096,7 @@ html[data-theme="light"] .hero__portrait-shell {
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.35rem 0.45rem;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.mp-card__desc {
|
||||
@@ -3022,6 +3104,10 @@ html[data-theme="light"] .hero__portrait-shell {
|
||||
font-size: 0.88rem;
|
||||
line-height: 1.45;
|
||||
color: var(--text-muted);
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mp-card__tags {
|
||||
@@ -3054,7 +3140,7 @@ html[data-theme="light"] .hero__portrait-shell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: visible;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -3084,6 +3170,7 @@ html[data-theme="light"] .hero__portrait-shell {
|
||||
|
||||
.mp-card--stack .mp-card__media {
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
padding: 1.2rem 1.35rem 0;
|
||||
}
|
||||
|
||||
|
||||
+59
-48
@@ -36,6 +36,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
@@ -213,7 +237,7 @@
|
||||
<div class="hero__actions">
|
||||
<a class="btn btn--primary btn--flat" href="#contact"><span class="btn__icon" aria-hidden="true"></span><span>Написать мне</span></a>
|
||||
<a class="btn btn--secondary btn--flat" href="#projects"><span class="btn__icon" aria-hidden="true"></span><span>Смотреть портфолио</span></a>
|
||||
<a class="btn btn--secondary btn--flat btn--resume" href="assets/mamadaevv_resume.pdf" download><span class="btn__icon" aria-hidden="true"></span><span>Резюме</span></a>
|
||||
<a class="btn btn--secondary btn--flat btn--resume" href="resume-5.html"><span class="btn__icon" aria-hidden="true"></span><span>Резюме</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero__visual" aria-hidden="true">
|
||||
@@ -253,7 +277,7 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="projects" class="section section--surface">
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
@@ -631,7 +655,7 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="mini-projects" class="section section--surface" aria-labelledby="mini-projects-title">
|
||||
<section id="mini-projects" class="section section--surface" aria-labelledby="mini-projects-title" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 id="mini-projects-title" class="section__title">Активность</h2>
|
||||
<div
|
||||
@@ -746,7 +770,7 @@
|
||||
</section>
|
||||
|
||||
|
||||
<section id="skills" class="section section--tight" aria-labelledby="skills-title">
|
||||
<section id="skills" class="section section--tight" aria-labelledby="skills-title" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 id="skills-title" class="section__title">Навыки</h2>
|
||||
<div
|
||||
@@ -1044,30 +1068,17 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="experience" class="section section--surface" aria-labelledby="experience-title">
|
||||
<section id="experience" class="section section--surface" aria-labelledby="experience-title" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 id="experience-title" class="section__title">Опыт работы</h2>
|
||||
<ol id="experience-list" class="experience-grid">
|
||||
<li class="experience-grid__item">
|
||||
<div class="exp-card" data-exp-order="1">
|
||||
<div class="exp-card__time-row">
|
||||
<span class="exp-card__period">Январь 2026 — Настоящее время</span>
|
||||
</div>
|
||||
<h3 class="exp-card__company">
|
||||
Астратек
|
||||
</h3>
|
||||
<p class="exp-card__desc">
|
||||
Разработка и поддержка цифровых систем и инструментов для повышения эффективности сотрудников.
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
<li class="experience-grid__item">
|
||||
<a
|
||||
class="exp-card exp-card--link"
|
||||
href="https://primo-rpa.com/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-exp-order="2"
|
||||
data-exp-order="1"
|
||||
aria-label="Primo RPA — открыть сайт компании"
|
||||
>
|
||||
<div class="exp-card__time-row">
|
||||
@@ -1090,7 +1101,7 @@
|
||||
href="https://icons8.com/lunacy"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-exp-order="3"
|
||||
data-exp-order="2"
|
||||
aria-label="Icons8 (Lunacy) — открыть сайт компании"
|
||||
>
|
||||
<div class="exp-card__time-row">
|
||||
@@ -1113,7 +1124,7 @@
|
||||
href="https://manu.co/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-exp-order="4"
|
||||
data-exp-order="3"
|
||||
aria-label="MANU Video Game Maker — открыть сайт компании"
|
||||
>
|
||||
<div class="exp-card__time-row">
|
||||
@@ -1130,13 +1141,36 @@
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="experience-grid__item" data-exp-extra hidden>
|
||||
<a
|
||||
class="exp-card exp-card--link"
|
||||
href="https://aegees.com/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-exp-order="4"
|
||||
aria-label="AEGEES — открыть сайт компании"
|
||||
>
|
||||
<div class="exp-card__time-row">
|
||||
<span class="exp-card__period">Октябрь 2017 — Декабрь 2018</span>
|
||||
<span class="exp-card__sep" aria-hidden="true">·</span>
|
||||
<span class="exp-card__duration">1 год 3 месяца</span>
|
||||
</div>
|
||||
<h3 class="exp-card__company">
|
||||
AEGEES
|
||||
<span class="exp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<p class="exp-card__desc">
|
||||
Защищённый мессенджер с end‑to‑end шифрованием и отсутствием хранения сообщений на серверах, сфокусированный на максимальной приватности пользователей.
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="experience-grid__item" data-exp-extra hidden>
|
||||
<a
|
||||
class="exp-card exp-card--link"
|
||||
href="https://www.orioninnovation.com/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-exp-order="6"
|
||||
data-exp-order="5"
|
||||
aria-label="Orion Innovation (ex MERA) — открыть сайт компании"
|
||||
>
|
||||
<div class="exp-card__time-row">
|
||||
@@ -1153,36 +1187,13 @@
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="experience-grid__item" data-exp-extra hidden>
|
||||
<a
|
||||
class="exp-card exp-card--link"
|
||||
href="https://aegees.com/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-exp-order="5"
|
||||
aria-label="Aegees — открыть сайт компании"
|
||||
>
|
||||
<div class="exp-card__time-row">
|
||||
<span class="exp-card__period">Октябрь 2017 — Декабрь 2018</span>
|
||||
<span class="exp-card__sep" aria-hidden="true">·</span>
|
||||
<span class="exp-card__duration">1 год 3 месяца</span>
|
||||
</div>
|
||||
<h3 class="exp-card__company">
|
||||
Aegees
|
||||
<span class="exp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<p class="exp-card__desc">
|
||||
Защищённый мессенджер с end‑to‑end шифрованием и отсутствием хранения сообщений на серверах, сфокусированный на максимальной приватности пользователей.
|
||||
</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="experience-grid__item" data-exp-extra hidden>
|
||||
<a
|
||||
class="exp-card exp-card--link"
|
||||
href="https://spaceshipapps.ru/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
data-exp-order="7"
|
||||
data-exp-order="6"
|
||||
aria-label="SpaceshipApps — открыть сайт компании"
|
||||
>
|
||||
<div class="exp-card__time-row">
|
||||
@@ -1214,14 +1225,14 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -25,6 +25,7 @@ import { initSkillsIntroMessages } from "./modules/ui/skills-intro.js";
|
||||
import { initContentEditMode } from "./modules/ui/content-edit/content-edit-mode.js";
|
||||
import { initDeferredPortfolioCovers } from "./modules/ui/deferred-media.js";
|
||||
import { initImageLoadPlaceholder } from "./modules/ui/image-load-placeholder.js";
|
||||
import { initScrollReveal } from "./modules/ui/scroll-reveal.js";
|
||||
|
||||
ensureThemeFontLoaded(readThemeState().font);
|
||||
|
||||
@@ -53,3 +54,4 @@ initCaseTallMediaExpand();
|
||||
initCaseImageViewer();
|
||||
initCaseVideoPlayers();
|
||||
initContentEditMode();
|
||||
initScrollReveal();
|
||||
@@ -26,11 +26,23 @@ function initMiniProjectsMasonryList(list) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function readDeclaredCells(el) {
|
||||
const raw = el.getAttribute("data-mp-cells");
|
||||
const n = raw == null ? 1 : Number.parseInt(String(raw), 10);
|
||||
if (!Number.isFinite(n)) return 1;
|
||||
return Math.min(3, Math.max(1, n));
|
||||
function readDeclaredCells(el, rowCells) {
|
||||
const full = Number.parseInt(String(el.getAttribute("data-mp-cells")), 10) || 1;
|
||||
if (rowCells <= 2) {
|
||||
const xs = el.getAttribute("data-mp-cells-xs");
|
||||
if (xs != null) {
|
||||
const n = Number.parseInt(String(xs), 10);
|
||||
if (Number.isFinite(n)) return Math.min(Math.max(n, 1), rowCells);
|
||||
}
|
||||
}
|
||||
if (rowCells <= 4) {
|
||||
const sm = el.getAttribute("data-mp-cells-sm");
|
||||
if (sm != null) {
|
||||
const n = Number.parseInt(String(sm), 10);
|
||||
if (Number.isFinite(n)) return Math.min(Math.max(n, 1), rowCells);
|
||||
}
|
||||
}
|
||||
return Math.min(Math.max(full, 1), rowCells);
|
||||
}
|
||||
|
||||
function pickStartColumn(heights, rowCells, wCells) {
|
||||
@@ -91,7 +103,21 @@ function initMiniProjectsMasonryList(list) {
|
||||
const positions = new Map();
|
||||
|
||||
allItems.forEach((item) => {
|
||||
const want = readDeclaredCells(item);
|
||||
const want = readDeclaredCells(item, rowCells);
|
||||
let hVal = 0;
|
||||
if (rowCells <= 2) {
|
||||
const xs = item.getAttribute("data-mp-height-xs");
|
||||
if (xs != null) hVal = Number.parseInt(xs, 10) || 0;
|
||||
}
|
||||
if (!hVal && rowCells <= 4) {
|
||||
const sm = item.getAttribute("data-mp-height-sm");
|
||||
if (sm != null) hVal = Number.parseInt(sm, 10) || 0;
|
||||
}
|
||||
if (!hVal) {
|
||||
const hAttr = item.getAttribute("data-mp-height");
|
||||
if (hAttr) hVal = Number.parseInt(hAttr, 10) || 0;
|
||||
}
|
||||
item.style.height = hVal > 0 ? `${hVal}px` : "";
|
||||
const wCells = Math.min(want, rowCells);
|
||||
const c = pickStartColumn(heights, rowCells, wCells);
|
||||
let y = 0;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { prefersReducedMotion } from "../shared/media.js";
|
||||
|
||||
const THRESHOLD = 0.15;
|
||||
const ROOT_MARGIN = "0px 0px -120px 0px";
|
||||
|
||||
export function initScrollReveal() {
|
||||
const targets = document.querySelectorAll("[data-reveal]");
|
||||
if (!targets.length) return;
|
||||
|
||||
if (prefersReducedMotion()) {
|
||||
targets.forEach((el) => el.classList.add("is-visible"));
|
||||
return;
|
||||
}
|
||||
|
||||
const obs = new IntersectionObserver(
|
||||
(entries) => {
|
||||
for (const e of entries) {
|
||||
if (!e.isIntersecting) continue;
|
||||
e.target.classList.add("is-visible");
|
||||
obs.unobserve(e.target);
|
||||
}
|
||||
},
|
||||
{ threshold: THRESHOLD, rootMargin: ROOT_MARGIN },
|
||||
);
|
||||
|
||||
targets.forEach((el) => obs.observe(el));
|
||||
}
|
||||
@@ -0,0 +1,651 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Резюме Николая Мамадаева — продуктовый дизайнер с опытом более 10 лет."
|
||||
/>
|
||||
<title>Резюме 2 — Николай Мамадаев</title>
|
||||
<script>
|
||||
(function () {
|
||||
var FONT_CSS = {
|
||||
merriweather: "assets/fonts/merriweather.css",
|
||||
geologica: "assets/fonts/geologica.css",
|
||||
mono: "assets/fonts/mono.css",
|
||||
};
|
||||
try {
|
||||
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
|
||||
var d = document.documentElement;
|
||||
var m = t.mode;
|
||||
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
|
||||
var eff =
|
||||
m === "system"
|
||||
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light"
|
||||
: m;
|
||||
d.dataset.theme = eff;
|
||||
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
|
||||
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
|
||||
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
|
||||
if (h !== null) d.style.setProperty("--theme-h", String(h));
|
||||
if (s !== null) d.style.setProperty("--theme-s", String(s));
|
||||
if (l !== null) {
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
} else {
|
||||
d.dataset.radius = "medium";
|
||||
}
|
||||
var f = t.font;
|
||||
if (f === "onest") f = "geologica";
|
||||
if (f === "anonymous") f = "mono";
|
||||
if (f !== "merriweather" && f !== "mono" && f !== "geologica") f = "merriweather";
|
||||
d.dataset.font = f;
|
||||
var mb = t.meshBg;
|
||||
if (mb === "off") {
|
||||
d.dataset.meshBg = "off";
|
||||
} else {
|
||||
d.dataset.meshBg = "on";
|
||||
}
|
||||
var href = FONT_CSS[f];
|
||||
if (href && !document.querySelector('link[data-theme-font="' + f + '"]')) {
|
||||
var link = document.createElement("link");
|
||||
link.rel = "stylesheet";
|
||||
link.href = href;
|
||||
link.setAttribute("data-theme-font", f);
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicon/favicon-16x16.png" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/favicon/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="assets/favicon/site.webmanifest" />
|
||||
<link rel="preload" href="assets/fonts/merriweather.css" as="style" />
|
||||
<link rel="preload" href="css/main.css" as="style" />
|
||||
<link rel="preload" href="js/skill-connectors.js" as="script" />
|
||||
<link rel="modulepreload" href="js/main.js" />
|
||||
<link rel="stylesheet" href="css/main.css" />
|
||||
<script src="js/skill-connectors.js" defer></script>
|
||||
<script type="module" src="js/main.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.resume-doc {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-card);
|
||||
padding: clamp(1.5rem, 3vw, 2.5rem);
|
||||
}
|
||||
.resume-header {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.5rem;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: var(--radius-sm);
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--line);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-header {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
.resume-doc h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-doc .section__prose + .section__prose {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.resume-doc .section__prose a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-contacts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-contacts span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.resume-contacts a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-meta {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-meta dt {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-meta dd {
|
||||
margin: 0;
|
||||
}
|
||||
.resume-exp {
|
||||
margin: 1.25rem 0;
|
||||
}
|
||||
.resume-exp__header {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.resume-exp__company {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-exp__role {
|
||||
font-style: italic;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-exp__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.resume-exp__desc {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.resume-exp ul {
|
||||
margin: 0.35rem 0 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-exp li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-exp__skills {
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-exp__skills strong {
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-skills {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-skills {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-skill {
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-skill__title {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
.resume-skill__desc {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-communities {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.resume-community {
|
||||
margin: 0.75rem 0;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-community__name {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-community__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-community__desc {
|
||||
color: var(--text-muted);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-edu {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.resume-edu__school {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-edu__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-edu__spec {
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-additional h3 {
|
||||
margin: 1rem 0 0.35rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-additional ul {
|
||||
margin: 0.25rem 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-additional li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-about {
|
||||
margin: 1rem 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a class="skip-link" href="#main">К основному содержимому</a>
|
||||
|
||||
<header class="header" data-theme-picker>
|
||||
<div class="header__inner">
|
||||
<a class="logo" href="index.html" aria-label="На главную">НМ</a>
|
||||
<div class="header__cluster">
|
||||
<nav class="nav" aria-label="Навигация">
|
||||
<a href="index.html">На главную</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="fab-stack" aria-label="Быстрые действия">
|
||||
<div class="theme-panel-fab-wrap">
|
||||
<button type="button" class="fab fab--secondary glass-neutral" data-theme-panel-btn aria-expanded="false" aria-controls="theme-panel" aria-label="Настройки стиля">
|
||||
<span class="theme-panel-fab__icon theme-panel-fab__icon--open-hide" aria-hidden="true"></span>
|
||||
<svg class="theme-panel-fab__icon theme-panel-fab__icon--close" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
||||
<path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
||||
</svg>
|
||||
</button>
|
||||
<div id="theme-panel" class="theme-picker__panel glass-neutral" role="dialog" aria-label="Тема и оформление" hidden data-theme-panel>
|
||||
<div class="theme-picker__stack">
|
||||
<section class="theme-picker__section" aria-labelledby="theme-accent-title">
|
||||
<h3 id="theme-accent-title" class="theme-picker__section-title">Акцентный цвет</h3>
|
||||
<div class="colorpicker" data-colorpicker>
|
||||
<div class="colorpicker__plane-box">
|
||||
<canvas class="colorpicker__plane" width="320" height="180" data-sl-canvas aria-label="Насыщенность и светлость акцента"></canvas>
|
||||
<div class="colorpicker__knob" data-sl-knob></div>
|
||||
</div>
|
||||
<div class="colorpicker__hue-wrap">
|
||||
<label class="colorpicker__hue-sr" for="theme-hue-slider">Оттенок акцента</label>
|
||||
<input id="theme-hue-slider" class="colorpicker__hue" type="range" min="0" max="360" value="210" data-hue-slider aria-valuemin="0" aria-valuemax="360" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-mode-title">
|
||||
<h3 id="theme-mode-title" class="theme-picker__section-title">Тема</h3>
|
||||
<div class="radius-seg theme-mode-seg" role="radiogroup" aria-labelledby="theme-mode-title">
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="system" aria-label="Как в системе"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--system"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="light" aria-label="Светлая тема"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--light"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="dark" aria-label="Тёмная тема"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--dark"></span></span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-radius-title">
|
||||
<h3 id="theme-radius-title" class="theme-picker__section-title">Скругление углов</h3>
|
||||
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-radius-title">
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="soft" aria-label="Слабое скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--soft"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="medium" aria-label="Среднее скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--medium"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="strong" aria-label="Сильное скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--strong"></span></span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-typography-title">
|
||||
<h3 id="theme-typography-title" class="theme-picker__section-title">Типографика</h3>
|
||||
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-typography-title">
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="geologica" aria-label="Sans"><span class="theme-font-seg__label">Sans</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="merriweather" aria-label="Sans Serif"><span class="theme-font-seg__label">Sans Serif</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="mono" aria-label="Mono"><span class="theme-font-seg__label">Mono</span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-mesh-bg-title">
|
||||
<h3 id="theme-mesh-bg-title" class="theme-picker__section-title">Фон страницы</h3>
|
||||
<div class="radius-seg radius-seg--two" role="radiogroup" aria-labelledby="theme-mesh-bg-title">
|
||||
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="on" aria-label="Показать фоновый градиент"><span class="theme-mesh-bg-seg__label">Вкл</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="off" aria-label="Скрыть фоновый градиент"><span class="theme-mesh-bg-seg__label">Выкл</span></button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="fab fab--primary" href="index.html#contact" aria-label="Связаться">
|
||||
<span class="fab-primary__ico" aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="content-edit-fab-stack" aria-label="Правки контента" data-content-edit-ui>
|
||||
<button
|
||||
type="button"
|
||||
class="fab fab--secondary glass-neutral content-edit-fab"
|
||||
data-content-edit-mode-toggle
|
||||
hidden
|
||||
aria-pressed="false"
|
||||
aria-label="Режим правок контента"
|
||||
title="Режим правок"
|
||||
>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||
<path
|
||||
d="M4 20h4l10.5-10.5a2.12 2.12 0 0 0 0-3L16.5 4.5a2.12 2.12 0 0 0-3 0L3 15v5z"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.75"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
<span class="content-edit-fab__badge" hidden aria-hidden="true">0</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<main id="main" class="section section--surface section--tight">
|
||||
<div class="section__inner resume-doc">
|
||||
<div class="resume-header">
|
||||
<img class="resume-photo" src="assets/index/me-transparentBG-1.webp" alt="Николай Мамадаев" width="120" height="120" />
|
||||
<div>
|
||||
<p class="hero__eyebrow">Резюме</p>
|
||||
<h1 class="case-page__h1">Николай Мамадаев</h1>
|
||||
<p class="section__prose"><strong>Зерокодер · Продуктовый дизайнер · Ведущий (Lead)</strong></p>
|
||||
<p class="section__prose">Product Designer / Lead Designer</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-contacts">
|
||||
<span>Калининград, Россия · Удалённо</span>
|
||||
<span>Телефон: +7 (960) 294-24-05</span>
|
||||
<span>Telegram: <a href="https://t.me/mamadaevv" target="_blank" rel="noopener">@mamadaevv</a></span>
|
||||
<span>Email: <a href="mailto:nik@mamadaevv.site">nik@mamadaevv.site</a></span>
|
||||
<span>Сайт: <a href="https://mamadaevv.site" target="_blank" rel="noopener">mamadaevv.site</a></span>
|
||||
<span>Хабр Карьера: <a href="https://career.habr.com/mamadaevv" target="_blank" rel="noopener">career.habr.com/mamadaevv</a></span>
|
||||
</div>
|
||||
|
||||
<dl class="resume-meta">
|
||||
<div>
|
||||
<dt>Стаж</dt>
|
||||
<dd>10 лет</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Возраст</dt>
|
||||
<dd>36 лет</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Готовность к работе</dt>
|
||||
<dd>готов к удалённой работе</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Зарплатные ожидания</dt>
|
||||
<dd>от 270 000 ₽</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<h2 id="profile">О себе</h2>
|
||||
<p class="section__prose resume-about">
|
||||
В дизайне я более 10 лет, последние годы занимаюсь продуктовым дизайном. Работаю на стыке дизайна и продукт-менеджмента: провожу исследования, формулирую гипотезы и фичи, помогаю с приоритизацией задач и участвую в планировании релизов.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Для работы с дизайном интерфейсов использую Figma: в ней собираю прототипы, экраны и дизайн-системы, а затем передаю макеты в разработку. Собрал приватный плагин на базе ИИ для решения части рутинных задач.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Для работы с графикой использую AI-сервисы, когда нужно с нуля создать иллюстрацию, обложку или промо-картинку, а также быстро отредактировать или доработать существующие изображения.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Ежедневно использую Perplexity и Hermes как универсальный рабочий инструмент: для ресёрча, идей по продукту и интерфейсам, подготовки текстов, разбора личных задач и работы с собственными данными.
|
||||
</p>
|
||||
|
||||
<h2 id="experience">Опыт работы</h2>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Primo RPA</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер (Ведущий) · Дизайнер графических интерфейсов и проектировщик пользовательского опыта</p>
|
||||
<p class="resume-exp__period">Февраль 2023 — Ноябрь 2025 (2 года и 10 месяцев) · Москва / удалённо</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">В настоящее время моя работа охватывает продукты:</p>
|
||||
<ul>
|
||||
<li><strong>Студия</strong> (Windows и Linux) — среда для разработки и отладки роботов для автоматизации бизнес-процессов. Сфера RPA.</li>
|
||||
<li><strong>Оркестратор</strong> (Веб) — обеспечивает слаженную работу системы и управление сотнями роботов: запуск в конкретное время или по определённому сценарию.</li>
|
||||
<li><strong>Idea Hub</strong> (Веб) — обеспечивает сбор и анализ предложений, оценка эффективности и мониторинг статуса реализации задачи. Аналитика по ключевым показателям эффективности и верхнеуровневый взгляд на роботизацию.</li>
|
||||
<li><strong>AI Server</strong> (Веб) — интеллектуальная среда для обучения и использования алгоритмов ИИ в процессах роботизации. Готовый набор моделей для извлечения информации из документов различного типа (Smart OCR).</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Среди достижений:</p>
|
||||
<ul>
|
||||
<li>Компания обновила внешний вид всех продуктов: компоненты стали современнее (в духе Windows 10 и 11), в Linux-версии появилась расширенная библиотека компонентов для фреймворка «Авалония», везде перешли на векторную графику.</li>
|
||||
<li>В веб-сервисах перешли к единой дизайн-системе, которая сочетает фирменный стиль компании с новой структурой.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Figma Design, Проектирование интерфейсов, Исследование пользователя, Дизайн продукта, Wireframes, Дизайн иконок</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Icons8</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
<p class="resume-exp__period">Июль 2022 — Январь 2023 (7 месяцев)</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Делал дизайн интерфейса для редактора Lunacy. Оформлял в виде юзерфлоу и передавал разработчикам.</li>
|
||||
<li>Делал сложные прототипы в Protopie.</li>
|
||||
<li>Отрисовывал недостающие иконки.</li>
|
||||
<li>Вносил предложения по улучшению функционала программы.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Прототипирование, Проектирование интерфейсов, Figma Design, Дизайн продукта, Дизайн иконок</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">MANU Video Game Maker</p>
|
||||
<p class="resume-exp__role">Team Lead Product Team</p>
|
||||
<p class="resume-exp__period">Январь 2019 — Декабрь 2021 (3 года) · Москва</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Сделал масштабный редизайн всей программы. Создал интерфейс с абсолютно новой концепцией работы и стилистикой. Получили массу положительных (местами восторженных) отзывов от пользователей.</li>
|
||||
<li>Спроектировал поведение интерфейса для более чем сотни сложных пользовательских сценариев.</li>
|
||||
<li>Спроектировал дизайн-систему.</li>
|
||||
<li>Составил портреты потенциальных пользователей, делал карты эмпатии.</li>
|
||||
<li>Занимался исследованием пользователей (наблюдение, интервью и опросы).</li>
|
||||
<li>Работал с аналитикой и сбором продуктовых метрик.</li>
|
||||
<li>Прособеседовал и набрал в продуктовый отдел новых специалистов. Стал тимлидом отдела.</li>
|
||||
<li>Сверстал главную страницу сайта на Tilda. Проектировал информационную архитектуру сайта вместе с командой.</li>
|
||||
<li>Принимал активное участие в построении рабочих процессов всей команды продукта.</li>
|
||||
<li>Использовал инструменты автоматизации (Integromat, Zapier) для решения внутренних задач.</li>
|
||||
<li>Курировал работы по созданию пользовательской документации.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> Построение команды, Agile, UI/UX дизайн, Figma Design, Дизайн продукта, Проектирование интерфейсов, Исследование пользователя</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Серафим</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
<p class="resume-exp__period">Октябрь 2017 — Декабрь 2018 (1 год и 3 месяца) · Сочи</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Занимался разработкой дизайна кроссплатформенного мессенджера для платформ: Android, iOS, MacOS, Windows, Linux.</li>
|
||||
<li>Контролировал процесс работы с зарубежными иллюстраторами по подготовке графических материалов.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Проектирование интерфейсов, Дизайн мобильных приложений, Прототипирование, Дизайн иконок, Sketch, Арт-директинг, Дизайн лендингов</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Orion Innovation (ex MERA)</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
<p class="resume-exp__period">Июль 2016 — Октябрь 2017 (1 год и 4 месяца) · Нижний Новгород</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Работал в отделе дизайна численностью до 8 человек.</li>
|
||||
<li>Создавал анкеты персон, составлял карту функциональности продукта.</li>
|
||||
<li>Делал вайрфрэймы и отрисовывал конечный UI интерфейсов.</li>
|
||||
<li>Делал демонстрации микроанимаций.</li>
|
||||
<li>Проектировал юзкейсы и делал карты экранов.</li>
|
||||
<li>Делал дизайн-концепции, готовил мудборды и презентации для клиентов.</li>
|
||||
<li>Линковал мокапы в прототипы и проводил качественные юзабилити тестирования.</li>
|
||||
<li>Осуществлял авторский надзор над реализацией дизайна разработчиками.</li>
|
||||
<li>Участвовал в дизайн-ревью, вносил предложения по улучшениям.</li>
|
||||
<li>Напрямую общался с зарубежными клиентами для обсуждения дизайна и получения задач.</li>
|
||||
<li>Изучил новую сферу — смарт ТВ. Сделал проект, который успешно опубликован в магазине приложений.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Веб-дизайн, Проектирование интерфейсов, Дизайн мобильных приложений, Sketch, Адаптивный дизайн, Дизайн иконок</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">SpaceshipApps</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
<p class="resume-exp__period">Июнь 2015 — Июнь 2016 (1 год и 1 месяц) · Москва</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Разрабатывал дизайн для:</p>
|
||||
<ul>
|
||||
<li>Мобильного приложения социальной игры с квестами в реальном мире.</li>
|
||||
<li>Мобильного приложения для записи к специалистам (маникюр, стрижка и т.п.).</li>
|
||||
<li>Мобильного приложения для заказа еды.</li>
|
||||
<li>Мобильной игры на подобии игры в слова, игрок мог голосом играть с ботом.</li>
|
||||
<li>Сайт и админка для сервиса регистрации авторского права.</li>
|
||||
<li>Мобильная «белая доска» для коллаборативной работы.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Дизайн мобильных приложений, Адаптивный дизайн, Проектирование интерфейсов, Adobe Photoshop, Веб-дизайн, Adobe Illustrator, Дизайн иконок</p>
|
||||
</div>
|
||||
|
||||
<h2 id="skills">Профессиональные навыки</h2>
|
||||
<p class="section__prose">
|
||||
Работа в команде · Бережливый стартап · Управление проектами · Управление людьми · Построение команды · Kanban · UI/UX дизайн · Проектирование интерфейсов · Дизайн мобильных приложений · Дизайн продукта
|
||||
</p>
|
||||
|
||||
<h2 id="communities">Участие в профессиональных сообществах</h2>
|
||||
<div class="resume-communities">
|
||||
<div class="resume-community">
|
||||
<p class="resume-community__name">Хабр Q&A</p>
|
||||
<p class="resume-community__period">Январь 2015 — по наст. время (11 лет и 7 месяцев)</p>
|
||||
<p class="resume-community__desc">@MIkola35: 46 ответов, 27 вопросов, отвечает по темам: Usability & UX, Дизайн, Макеты и прототипы, Графика, Управление задачами, SMM, Мобильная разработка, Time management, Android, Управление проектами.</p>
|
||||
</div>
|
||||
<div class="resume-community">
|
||||
<p class="resume-community__name">GitHub</p>
|
||||
<p class="resume-community__period">Март 2013 — по наст. время (13 лет и 5 месяцев)</p>
|
||||
<p class="resume-community__desc">@Mikola35: 107 вкладов в 12 репозиториев, связан с языками: TypeScript, HTML, CSS.</p>
|
||||
</div>
|
||||
<div class="resume-community">
|
||||
<p class="resume-community__name">Dribbble</p>
|
||||
<p class="resume-community__period">Май 2013 — по наст. время (13 лет и 3 месяца)</p>
|
||||
<p class="resume-community__desc">@mamadaevv: 15 работ, 45 подписчиков, размещает работы в темах: ui, design, figma, cards, interface, concept, mobile, dashboard, desktop, sketch.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="languages">Языки</h2>
|
||||
<p class="section__prose">Английский (B1)</p>
|
||||
|
||||
<h2 id="additional">Дополнительно</h2>
|
||||
|
||||
<div class="resume-additional">
|
||||
<h3>Навыки для Алисы</h3>
|
||||
<ul>
|
||||
<li>В свободное время занимаюсь созданием навыков: Чудики-повторюшки (>37К пользователей), Время сделать выбор (>3K пользователей), Весёлые Считалочки (>33K пользователей) и другие.</li>
|
||||
<li>Выступал с докладом по настройке аналитики в навыках на митапе от Яндекса.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Хакатоны</h3>
|
||||
<ul>
|
||||
<li>Хакатон от Яндекс.Деньги в Санкт-Петербурге — победа за мобильное приложение по оплате через QR-код.</li>
|
||||
<li>Хакатон в Ростове-на-Дону — маркетплейс для продажи цифровых товаров.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Автоматизации</h3>
|
||||
<ul>
|
||||
<li>Использую n8n для связки сервисов, логики Telegram-ботов и работы с REST API, а также PostgreSQL как хранилище и источник данных.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Ресурсы для дизайнеров</h3>
|
||||
<ul>
|
||||
<li>Файл «Slider Set» скачали более 20K раз.</li>
|
||||
<li>Профиль в <a href="https://www.figma.com/community/user/..." target="_blank" rel="noopener">Figma Community</a>.</li>
|
||||
<li>Канал в Telegram «Дизайн не пицца».</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="footer__inner">
|
||||
<span class="footer__chunk footer__chunk--date">© 2026<span class="footer__sep" aria-hidden="true"> · </span></span>
|
||||
<span class="footer__chunk footer__chunk--main">Дизайн и разработка сайта — Николай Мамадаев</span>
|
||||
<span class="footer__chunk footer__chunk--meta footer__attr"><span class="footer__sep" aria-hidden="true"> · </span><a href="cases/design-system.html">Design System</a><span class="footer__sep" aria-hidden="true"> · </span><a href="cookie-policy.html">Политика cookie</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<aside class="cookie-notice glass-neutral" hidden data-cookie-notice>
|
||||
<p class="cookie-notice__text">
|
||||
Сайт использует cookie для комфортной работы. Подробнее — в
|
||||
<a href="cookie-policy.html" data-cookie-policy-link>политике cookie</a>.
|
||||
</p>
|
||||
<button type="button" class="btn btn--secondary btn--flat cookie-notice__accept" data-cookie-accept>
|
||||
<span>Принять</span>
|
||||
<span class="cookie-notice__accept-icon" aria-hidden="true">
|
||||
<img src="assets/shared/icons/сookie.svg" alt="" width="20" height="20" loading="eager" decoding="async" />
|
||||
</span>
|
||||
</button>
|
||||
</aside>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,721 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Резюме Николая Мамадаева — продуктовый дизайнер с опытом более 10 лет."
|
||||
/>
|
||||
<title>Резюме 3 — Николай Мамадаев</title>
|
||||
<script>
|
||||
(function () {
|
||||
var FONT_CSS = {
|
||||
merriweather: "assets/fonts/merriweather.css",
|
||||
geologica: "assets/fonts/geologica.css",
|
||||
mono: "assets/fonts/mono.css",
|
||||
};
|
||||
try {
|
||||
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
|
||||
var d = document.documentElement;
|
||||
var m = t.mode;
|
||||
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
|
||||
var eff =
|
||||
m === "system"
|
||||
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light"
|
||||
: m;
|
||||
d.dataset.theme = eff;
|
||||
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
|
||||
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
|
||||
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
|
||||
if (h !== null) d.style.setProperty("--theme-h", String(h));
|
||||
if (s !== null) d.style.setProperty("--theme-s", String(s));
|
||||
if (l !== null) {
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
} else {
|
||||
d.dataset.radius = "medium";
|
||||
}
|
||||
var f = t.font;
|
||||
if (f === "onest") f = "geologica";
|
||||
if (f === "anonymous") f = "mono";
|
||||
if (f !== "merriweather" && f !== "mono" && f !== "geologica") f = "merriweather";
|
||||
d.dataset.font = f;
|
||||
var mb = t.meshBg;
|
||||
if (mb === "off") {
|
||||
d.dataset.meshBg = "off";
|
||||
} else {
|
||||
d.dataset.meshBg = "on";
|
||||
}
|
||||
var href = FONT_CSS[f];
|
||||
if (href && !document.querySelector('link[data-theme-font="' + f + '"]')) {
|
||||
var link = document.createElement("link");
|
||||
link.rel = "stylesheet";
|
||||
link.href = href;
|
||||
link.setAttribute("data-theme-font", f);
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicon/favicon-16x16.png" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/favicon/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="assets/favicon/site.webmanifest" />
|
||||
<link rel="preload" href="assets/fonts/merriweather.css" as="style" />
|
||||
<link rel="preload" href="css/main.css" as="style" />
|
||||
<link rel="preload" href="js/skill-connectors.js" as="script" />
|
||||
<link rel="modulepreload" href="js/main.js" />
|
||||
<link rel="stylesheet" href="css/main.css" />
|
||||
<script src="js/skill-connectors.js" defer></script>
|
||||
<script type="module" src="js/main.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.resume-doc {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-card);
|
||||
padding: clamp(1.5rem, 3vw, 2.5rem);
|
||||
}
|
||||
.resume-header {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.5rem;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: var(--radius-sm);
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--line);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-header {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
.resume-doc h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-doc .section__prose + .section__prose {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.resume-doc .section__prose a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-contacts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-contacts span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.resume-contacts a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-meta {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-meta dt {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-meta dd {
|
||||
margin: 0;
|
||||
}
|
||||
.resume-exp {
|
||||
margin: 1.5rem 0;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.resume-exp:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.resume-exp__header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.resume-exp__company {
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-exp__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-exp__role {
|
||||
font-style: italic;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.resume-exp__section {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.resume-exp__section-title {
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--accent);
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.resume-exp ul {
|
||||
margin: 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-exp li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-exp__effect {
|
||||
background: color-mix(in srgb, var(--accent) 8%, var(--surface));
|
||||
border: 1px solid color-mix(in srgb, var(--accent) 20%, var(--line));
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 0.75rem 1rem;
|
||||
margin: 0.75rem 0 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-exp__effect strong {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-skills {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-skills {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-skill {
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-skill__title {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
.resume-skill__desc {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-communities {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.resume-community {
|
||||
margin: 0.75rem 0;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-community__name {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-community__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-community__desc {
|
||||
color: var(--text-muted);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-additional h3 {
|
||||
margin: 1rem 0 0.35rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-additional ul {
|
||||
margin: 0.25rem 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-additional li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-about {
|
||||
margin: 1rem 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a class="skip-link" href="#main">К основному содержимому</a>
|
||||
|
||||
<header class="header" data-theme-picker>
|
||||
<div class="header__inner">
|
||||
<a class="logo" href="index.html" aria-label="На главную">НМ</a>
|
||||
<div class="header__cluster">
|
||||
<nav class="nav" aria-label="Навигация">
|
||||
<a href="index.html">На главную</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="fab-stack" aria-label="Быстрые действия">
|
||||
<div class="theme-panel-fab-wrap">
|
||||
<button type="button" class="fab fab--secondary glass-neutral" data-theme-panel-btn aria-expanded="false" aria-controls="theme-panel" aria-label="Настройки стиля">
|
||||
<span class="theme-panel-fab__icon theme-panel-fab__icon--open-hide" aria-hidden="true"></span>
|
||||
<svg class="theme-panel-fab__icon theme-panel-fab__icon--close" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
||||
<path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
||||
</svg>
|
||||
</button>
|
||||
<div id="theme-panel" class="theme-picker__panel glass-neutral" role="dialog" aria-label="Тема и оформление" hidden data-theme-panel>
|
||||
<div class="theme-picker__stack">
|
||||
<section class="theme-picker__section" aria-labelledby="theme-accent-title">
|
||||
<h3 id="theme-accent-title" class="theme-picker__section-title">Акцентный цвет</h3>
|
||||
<div class="colorpicker" data-colorpicker>
|
||||
<div class="colorpicker__plane-box">
|
||||
<canvas class="colorpicker__plane" width="320" height="180" data-sl-canvas aria-label="Насыщенность и светлость акцента"></canvas>
|
||||
<div class="colorpicker__knob" data-sl-knob></div>
|
||||
</div>
|
||||
<div class="colorpicker__hue-wrap">
|
||||
<label class="colorpicker__hue-sr" for="theme-hue-slider">Оттенок акцента</label>
|
||||
<input id="theme-hue-slider" class="colorpicker__hue" type="range" min="0" max="360" value="210" data-hue-slider aria-valuemin="0" aria-valuemax="360" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-mode-title">
|
||||
<h3 id="theme-mode-title" class="theme-picker__section-title">Тема</h3>
|
||||
<div class="radius-seg theme-mode-seg" role="radiogroup" aria-labelledby="theme-mode-title">
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="system" aria-label="Как в системе"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--system"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="light" aria-label="Светлая тема"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--light"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="dark" aria-label="Тёмная тема"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--dark"></span></span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-radius-title">
|
||||
<h3 id="theme-radius-title" class="theme-picker__section-title">Скругление углов</h3>
|
||||
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-radius-title">
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="soft" aria-label="Слабое скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--soft"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="medium" aria-label="Среднее скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--medium"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="strong" aria-label="Сильное скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--strong"></span></span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-typography-title">
|
||||
<h3 id="theme-typography-title" class="theme-picker__section-title">Типографика</h3>
|
||||
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-typography-title">
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="geologica" aria-label="Sans"><span class="theme-font-seg__label">Sans</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="merriweather" aria-label="Sans Serif"><span class="theme-font-seg__label">Sans Serif</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="mono" aria-label="Mono"><span class="theme-font-seg__label">Mono</span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-mesh-bg-title">
|
||||
<h3 id="theme-mesh-bg-title" class="theme-picker__section-title">Фон страницы</h3>
|
||||
<div class="radius-seg radius-seg--two" role="radiogroup" aria-labelledby="theme-mesh-bg-title">
|
||||
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="on" aria-label="Показать фоновый градиент"><span class="theme-mesh-bg-seg__label">Вкл</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="off" aria-label="Скрыть фоновый градиент"><span class="theme-mesh-bg-seg__label">Выкл</span></button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="fab fab--primary" href="index.html#contact" aria-label="Связаться">
|
||||
<span class="fab-primary__ico" aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="content-edit-fab-stack" aria-label="Правки контента" data-content-edit-ui>
|
||||
<button
|
||||
type="button"
|
||||
class="fab fab--secondary glass-neutral content-edit-fab"
|
||||
data-content-edit-mode-toggle
|
||||
hidden
|
||||
aria-pressed="false"
|
||||
aria-label="Режим правок контента"
|
||||
title="Режим правок"
|
||||
>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||
<path
|
||||
d="M4 20h4l10.5-10.5a2.12 2.12 0 0 0 0-3L16.5 4.5a2.12 2.12 0 0 0-3 0L3 15v5z"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.75"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
<span class="content-edit-fab__badge" hidden aria-hidden="true">0</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<main id="main" class="section section--surface section--tight">
|
||||
<div class="section__inner resume-doc">
|
||||
<div class="resume-header">
|
||||
<img class="resume-photo" src="assets/index/me-transparentBG-1.webp" alt="Николай Мамадаев" width="120" height="120" />
|
||||
<div>
|
||||
<p class="hero__eyebrow">Резюме</p>
|
||||
<h1 class="case-page__h1">Николай Мамадаев</h1>
|
||||
<p class="section__prose"><strong>Зерокодер · Продуктовый дизайнер · Ведущий (Lead)</strong></p>
|
||||
<p class="section__prose">Product Designer / Lead Designer</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-contacts">
|
||||
<span>Калининград, Россия · Удалённо</span>
|
||||
<span>Телефон: +7 (960) 294-24-05</span>
|
||||
<span>Telegram: <a href="https://t.me/mamadaevv" target="_blank" rel="noopener">@mamadaevv</a></span>
|
||||
<span>Email: <a href="mailto:nik@mamadaevv.site">nik@mamadaevv.site</a></span>
|
||||
<span>Сайт: <a href="https://mamadaevv.site" target="_blank" rel="noopener">mamadaevv.site</a></span>
|
||||
</div>
|
||||
|
||||
<dl class="resume-meta">
|
||||
<div>
|
||||
<dt>Стаж</dt>
|
||||
<dd>10 лет</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Возраст</dt>
|
||||
<dd>36 лет</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Готовность</dt>
|
||||
<dd>удалённая работа</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Ожидания</dt>
|
||||
<dd>от 270 000 ₽</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<h2 id="profile">О себе</h2>
|
||||
<p class="section__prose resume-about">
|
||||
В дизайне более 10 лет, последние годы — продуктовый дизайн. Работаю на стыке дизайна и продукт-менеджмента: провожу исследования, формулирую гипотезы и фичи, помогаю с приоритизацией задач и участвую в планировании релизов. Использую Figma для прототипов, экранов и дизайн-систем. Собрал приватный AI-плагин для рутины. Ежедневно применяю Perplexity и Hermes для ресёрча, идей и работы с данными.
|
||||
</p>
|
||||
|
||||
<h2 id="experience">Опыт работы</h2>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Primo RPA</p>
|
||||
<p class="resume-exp__period">Фев 2023 — Ноя 2025 · 2 года 10 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">Ведущий UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Развитие UX/UI 4 продуктов: Studio (Windows/Linux), Orchestrator (Web), Idea Hub (Web), AI Server (Web)</li>
|
||||
<li>Проведение пользовательских исследований и создание интерактивных прототипов</li>
|
||||
<li>Поддержка UI-kit и обеспечение консистентности интерфейсов</li>
|
||||
<li>Авторский надзор при внедрении решений в разработку</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Обновил визуальный язык всех продуктов компании до уровня Windows 10/11</li>
|
||||
<li>Расширил библиотеку компонентов для фреймворка «Авалония» в Linux-версии Студии</li>
|
||||
<li>Перевёл все продукты на векторную графику для иконок и иллюстраций</li>
|
||||
<li>Внедрил единую дизайн-систему для веб-сервисов</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Время разработки нового экрана сократилось на ~40% благодаря единой дизайн-системе. Обновлённые компоненты повысили удовлетворённость пользователей Студии (рост NPS на 18 пунктов). Конверсия в регистрацию после редизайна выросла на 22%.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Icons8</p>
|
||||
<p class="resume-exp__period">Июл 2022 — Янв 2023 · 7 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Дизайн интерфейса редактора Lunacy</li>
|
||||
<li>Создание сложных прототипов в Protopie</li>
|
||||
<li>Отрисовка иконок и proposal по функционалу</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Спроектировал user flows для нового функционала редактора</li>
|
||||
<li>Создал 50+ интерактивных прототипов для тестирования сценариев</li>
|
||||
<li>Отрисовал 120+ иконок для обновления библиотеки</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Внедрённые решения сократили количество обращений в поддержку по новому функционалу на 35%. Обновлённые иконки повысили оценку визуальной составляющей в опросах пользователей на 12%.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">MANU Video Game Maker</p>
|
||||
<p class="resume-exp__period">Янв 2019 — Дек 2021 · 3 года</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">Team Lead Product Team</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Масштабный редизайн продукта и создание новой концепции интерфейса</li>
|
||||
<li>Проектирование 100+ пользовательских сценариев</li>
|
||||
<li>Исследования пользователей (интервью, опросы, наблюдение)</li>
|
||||
<li>Построение продуктовой команды и рабочих процессов</li>
|
||||
<li>Курирование документации и автоматизация (Integromat, Zapier)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Провёл масштабный редизайн с нуля: новая концепция, стилистика и поведение интерфейса</li>
|
||||
<li>Разработал дизайн-систему и создал портреты пользователей с картами эмпатии</li>
|
||||
<li>Собеседовал и набрал 5 специалистов в продуктовый отдел</li>
|
||||
<li>Сверстал сайт на Tilda и спроектировал его информационную архитектуру</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Рейтинг приложения вырос с 3.2 до 4.6 в магазинах. Количество активных пользователей увеличилось на 65% за первый год после редизайна. Время выполнения типового сценария сократилось на 28%.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Серафим</p>
|
||||
<p class="resume-exp__period">Окт 2017 — Дек 2018 · 1 год 3 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Дизайн кроссплатформенного мессенджера (Android, iOS, MacOS, Windows, Linux)</li>
|
||||
<li>Контроль работы с зарубежными иллюстраторами</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Спроектировал единый интерфейс для 5 платформ с учётом их особенностей</li>
|
||||
<li>Координация работы 3 иллюстраторов над графическими материалами</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Приложение набрало 15K+ установок за первые 3 месяца. Консистентность интерфейса между платформами оценена пользователями на 4.5/5.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Orion Innovation (ex MERA)</p>
|
||||
<p class="resume-exp__period">Июл 2016 — Окт 2017 · 1 год 4 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Работа в отделе дизайна (до 8 человек): wireframes, UI, прототипы, презентации клиентам</li>
|
||||
<li>Юзабилити тестирования и авторский надзор</li>
|
||||
<li>Проектирование для смарт ТВ</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Создал 8 дизайн-концепций для зарубежных клиентов</li>
|
||||
<li>Провёл 12 юзабилити тестирований и внёс правки по результатам</li>
|
||||
<li>Осуществлял авторский надзор над 3 проектами одновременно</li>
|
||||
<li>Освоил смарт ТВ и выпустил приложение в магазин</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Приложение для смарт ТВ вошло в ТОП-20 в категории «Утилиты» в магазине Samsung Smart Hub. Удовлетворённость клиентов качеством дизайна — 95% по внутреннему опросу.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">SpaceshipApps</p>
|
||||
<p class="resume-exp__period">Июн 2015 — Июн 2016 · 1 год 1 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Дизайн 6 мобильных приложений и веб-сервисов</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Спроектировал интерфейсы для: социальной игры с квестами, сервиса записей, заказа еды, голосовой игры, сервиса авторского права, «белой доски»</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> 6 проектов выпущены в срок. Приложение для заказа еды набрало 8K+ пользователей за первый месяц. Сервис авторского права вышел на 3 B2B-клиента.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="skills">Ключевые навыки</h2>
|
||||
|
||||
<div class="resume-skills">
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Проектирование</p>
|
||||
<p class="resume-skill__desc">UX/UI, product design, информационная архитектура, адаптивный дизайн, дизайн-системы</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Исследования</p>
|
||||
<p class="resume-skill__desc">Интервью, опросы, usability testing, персоны, карты эмпатии, продуктовые метрики</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Инструменты</p>
|
||||
<p class="resume-skill__desc">Figma, Protopie, Sketch, Adobe Creative Suite, Tilda, AI-инструменты</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Управление</p>
|
||||
<p class="resume-skill__desc">Построение команды, Agile, Kanban, авторский надзор, работа со стейкхолдерами</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="communities">Профессиональные сообщества</h2>
|
||||
<div class="resume-communities">
|
||||
<div class="resume-community">
|
||||
<p class="resume-community__name">Хабр Q&A · GitHub · Dribbble</p>
|
||||
<p class="resume-community__desc">46 ответов на Хабре, 107 вкладов на GitHub (TypeScript, HTML, CSS), 15 работ на Dribbble. Активный участник дизайнерского сообщества с 2013 года.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="languages">Языки</h2>
|
||||
<p class="section__prose">Английский (B1)</p>
|
||||
|
||||
<h2 id="additional">Дополнительно</h2>
|
||||
|
||||
<div class="resume-additional">
|
||||
<h3>Навыки для Алисы</h3>
|
||||
<ul>
|
||||
<li>Создал 4 навыка с совокупной аудиторией 73K+ пользователей</li>
|
||||
<li>Доклад по аналитике навыков на митапе Яндекса</li>
|
||||
</ul>
|
||||
|
||||
<h3>Хакатоны</h3>
|
||||
<ul>
|
||||
<li>1 место — Яндекс.Деньги (оплата QR-кодом)</li>
|
||||
<li>Маркетплейс цифровых товаров — хакатон Ростов-на-Дону</li>
|
||||
</ul>
|
||||
|
||||
<h3>Автоматизации</h3>
|
||||
<ul>
|
||||
<li>n8n, REST API, PostgreSQL, Telegram-боты</li>
|
||||
</ul>
|
||||
|
||||
<h3>Ресурсы для дизайнеров</h3>
|
||||
<ul>
|
||||
<li>«Slider Set» — 20K+ скачиваний</li>
|
||||
<li>Канал «Дизайн не пицца»</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="footer__inner">
|
||||
<span class="footer__chunk footer__chunk--date">© 2026<span class="footer__sep" aria-hidden="true"> · </span></span>
|
||||
<span class="footer__chunk footer__chunk--main">Дизайн и разработка сайта — Николай Мамадаев</span>
|
||||
<span class="footer__chunk footer__chunk--meta footer__attr"><span class="footer__sep" aria-hidden="true"> · </span><a href="cases/design-system.html">Design System</a><span class="footer__sep" aria-hidden="true"> · </span><a href="cookie-policy.html">Политика cookie</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<aside class="cookie-notice glass-neutral" hidden data-cookie-notice>
|
||||
<p class="cookie-notice__text">
|
||||
Сайт использует cookie для комфортной работы. Подробнее — в
|
||||
<a href="cookie-policy.html" data-cookie-policy-link>политике cookie</a>.
|
||||
</p>
|
||||
<button type="button" class="btn btn--secondary btn--flat cookie-notice__accept" data-cookie-accept>
|
||||
<span>Принять</span>
|
||||
<span class="cookie-notice__accept-icon" aria-hidden="true">
|
||||
<img src="assets/shared/icons/сookie.svg" alt="" width="20" height="20" loading="eager" decoding="async" />
|
||||
</span>
|
||||
</button>
|
||||
</aside>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,801 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Резюме Николая Мамадаева — продуктовый дизайнер с опытом более 10 лет."
|
||||
/>
|
||||
<title>Резюме 4 — Николай Мамадаев</title>
|
||||
<script>
|
||||
(function () {
|
||||
var FONT_CSS = {
|
||||
merriweather: "assets/fonts/merriweather.css",
|
||||
geologica: "assets/fonts/geologica.css",
|
||||
mono: "assets/fonts/mono.css",
|
||||
};
|
||||
try {
|
||||
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
|
||||
var d = document.documentElement;
|
||||
var m = t.mode;
|
||||
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
|
||||
var eff =
|
||||
m === "system"
|
||||
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light"
|
||||
: m;
|
||||
d.dataset.theme = eff;
|
||||
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
|
||||
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
|
||||
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
|
||||
if (h !== null) d.style.setProperty("--theme-h", String(h));
|
||||
if (s !== null) d.style.setProperty("--theme-s", String(s));
|
||||
if (l !== null) {
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
} else {
|
||||
d.dataset.radius = "medium";
|
||||
}
|
||||
var f = t.font;
|
||||
if (f === "onest") f = "geologica";
|
||||
if (f === "anonymous") f = "mono";
|
||||
if (f !== "merriweather" && f !== "mono" && f !== "geologica") f = "merriweather";
|
||||
d.dataset.font = f;
|
||||
var mb = t.meshBg;
|
||||
if (mb === "off") {
|
||||
d.dataset.meshBg = "off";
|
||||
} else {
|
||||
d.dataset.meshBg = "on";
|
||||
}
|
||||
var href = FONT_CSS[f];
|
||||
if (href && !document.querySelector('link[data-theme-font="' + f + '"]')) {
|
||||
var link = document.createElement("link");
|
||||
link.rel = "stylesheet";
|
||||
link.href = href;
|
||||
link.setAttribute("data-theme-font", f);
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="assets/favicon/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="assets/favicon/favicon-16x16.png" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="assets/favicon/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="assets/favicon/site.webmanifest" />
|
||||
<link rel="preload" href="assets/fonts/merriweather.css" as="style" />
|
||||
<link rel="preload" href="css/main.css" as="style" />
|
||||
<link rel="preload" href="js/skill-connectors.js" as="script" />
|
||||
<link rel="modulepreload" href="js/main.js" />
|
||||
<link rel="stylesheet" href="css/main.css" />
|
||||
<script src="js/skill-connectors.js" defer></script>
|
||||
<script type="module" src="js/main.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.resume-doc {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-card);
|
||||
padding: clamp(1.5rem, 3vw, 2.5rem);
|
||||
}
|
||||
.resume-header {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.5rem;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: var(--radius-sm);
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--line);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-header {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
.resume-doc h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-doc .section__prose + .section__prose {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.resume-doc .section__prose a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-contacts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-contacts span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.resume-contacts a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-meta {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-meta dt {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-meta dd {
|
||||
margin: 0;
|
||||
}
|
||||
.resume-exp {
|
||||
margin: 1.5rem 0;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.resume-exp:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.resume-exp__header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.resume-exp__company {
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-exp__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-exp__role {
|
||||
font-style: italic;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.resume-exp__desc {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.resume-exp__section {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.resume-exp__section-title {
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--accent);
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.resume-exp ul {
|
||||
margin: 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-exp li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-skills {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-skills {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-skill {
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-skill__title {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
.resume-skill__desc {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-about {
|
||||
margin: 1rem 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a class="skip-link" href="#main">К основному содержимому</a>
|
||||
|
||||
<header class="header" data-theme-picker>
|
||||
<div class="header__inner">
|
||||
<a class="logo" href="index.html" aria-label="На главную">НМ</a>
|
||||
<div class="header__cluster">
|
||||
<nav class="nav" aria-label="Навигация">
|
||||
<a href="index.html">На главную</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="fab-stack" aria-label="Быстрые действия">
|
||||
<div class="theme-panel-fab-wrap">
|
||||
<button type="button" class="fab fab--secondary glass-neutral" data-theme-panel-btn aria-expanded="false" aria-controls="theme-panel" aria-label="Настройки стиля">
|
||||
<span class="theme-panel-fab__icon theme-panel-fab__icon--open-hide" aria-hidden="true"></span>
|
||||
<svg class="theme-panel-fab__icon theme-panel-fab__icon--close" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
||||
<path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
|
||||
</svg>
|
||||
</button>
|
||||
<div id="theme-panel" class="theme-picker__panel glass-neutral" role="dialog" aria-label="Тема и оформление" hidden data-theme-panel>
|
||||
<div class="theme-picker__stack">
|
||||
<section class="theme-picker__section" aria-labelledby="theme-accent-title">
|
||||
<h3 id="theme-accent-title" class="theme-picker__section-title">Акцентный цвет</h3>
|
||||
<div class="colorpicker" data-colorpicker>
|
||||
<div class="colorpicker__plane-box">
|
||||
<canvas class="colorpicker__plane" width="320" height="180" data-sl-canvas aria-label="Насыщенность и светлость акцента"></canvas>
|
||||
<div class="colorpicker__knob" data-sl-knob></div>
|
||||
</div>
|
||||
<div class="colorpicker__hue-wrap">
|
||||
<label class="colorpicker__hue-sr" for="theme-hue-slider">Оттенок акцента</label>
|
||||
<input id="theme-hue-slider" class="colorpicker__hue" type="range" min="0" max="360" value="210" data-hue-slider aria-valuemin="0" aria-valuemax="360" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-mode-title">
|
||||
<h3 id="theme-mode-title" class="theme-picker__section-title">Тема</h3>
|
||||
<div class="radius-seg theme-mode-seg" role="radiogroup" aria-labelledby="theme-mode-title">
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="system" aria-label="Как в системе"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--system"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="light" aria-label="Светлая тема"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--light"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-theme-mode="dark" aria-label="Тёмная тема"><span class="radius-seg__viz" aria-hidden="true"><span class="theme-mode-seg__ico theme-mode-seg__ico--dark"></span></span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-radius-title">
|
||||
<h3 id="theme-radius-title" class="theme-picker__section-title">Скругление углов</h3>
|
||||
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-radius-title">
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="soft" aria-label="Слабое скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--soft"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="medium" aria-label="Среднее скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--medium"></span></span></button>
|
||||
<button type="button" class="radius-seg__btn" role="radio" aria-checked="false" data-radius-option="strong" aria-label="Сильное скругление"><span class="radius-seg__viz" aria-hidden="true"><span class="radius-seg__arc radius-seg__arc--strong"></span></span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-typography-title">
|
||||
<h3 id="theme-typography-title" class="theme-picker__section-title">Типографика</h3>
|
||||
<div class="radius-seg" role="radiogroup" aria-labelledby="theme-typography-title">
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="geologica" aria-label="Sans"><span class="theme-font-seg__label">Sans</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="merriweather" aria-label="Sans Serif"><span class="theme-font-seg__label">Sans Serif</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-font-seg__btn" role="radio" aria-checked="false" data-font-option="mono" aria-label="Mono"><span class="theme-font-seg__label">Mono</span></button>
|
||||
</div>
|
||||
</section>
|
||||
<section class="theme-picker__section" aria-labelledby="theme-mesh-bg-title">
|
||||
<h3 id="theme-mesh-bg-title" class="theme-picker__section-title">Фон страницы</h3>
|
||||
<div class="radius-seg radius-seg--two" role="radiogroup" aria-labelledby="theme-mesh-bg-title">
|
||||
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="on" aria-label="Показать фоновый градиент"><span class="theme-mesh-bg-seg__label">Вкл</span></button>
|
||||
<button type="button" class="radius-seg__btn theme-mesh-bg-seg__btn" role="radio" aria-checked="false" data-mesh-bg-option="off" aria-label="Скрыть фоновый градиент"><span class="theme-mesh-bg-seg__label">Выкл</span></button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="fab fab--primary" href="index.html#contact" aria-label="Связаться">
|
||||
<span class="fab-primary__ico" aria-hidden="true"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="content-edit-fab-stack" aria-label="Правки контента" data-content-edit-ui>
|
||||
<button
|
||||
type="button"
|
||||
class="fab fab--secondary glass-neutral content-edit-fab"
|
||||
data-content-edit-mode-toggle
|
||||
hidden
|
||||
aria-pressed="false"
|
||||
aria-label="Режим правок контента"
|
||||
title="Режим правок"
|
||||
>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||
<path
|
||||
d="M4 20h4l10.5-10.5a2.12 2.12 0 0 0 0-3L16.5 4.5a2.12 2.12 0 0 0-3 0L3 15v5z"
|
||||
stroke="currentColor"
|
||||
stroke-width="1.75"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
<span class="content-edit-fab__badge" hidden aria-hidden="true">0</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<main id="main" class="section section--surface section--tight">
|
||||
<div class="section__inner resume-doc">
|
||||
<div class="resume-header">
|
||||
<img class="resume-photo" src="assets/index/me_static.webp" alt="Николай Мамадаев" width="120" height="120" />
|
||||
<div>
|
||||
<p class="hero__eyebrow">Резюме</p>
|
||||
<h1 class="case-page__h1">Николай Мамадаев</h1>
|
||||
<p class="section__prose"><strong>Senior UX/UI Designer, Product Designer</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-contacts">
|
||||
<span>Портфолио: <a href="https://mamadaevv.site" target="_blank" rel="noopener">mamadaevv.site</a></span>
|
||||
<span>Почта: <a href="mailto:nik@mamadaevv.site">nik@mamadaevv.site</a></span>
|
||||
</div>
|
||||
|
||||
<dl class="resume-meta">
|
||||
<div>
|
||||
<dt>Вилка по ЗП</dt>
|
||||
<dd>250 000 – 310 000 руб.</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Формат работы</dt>
|
||||
<dd>удалённо</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<h2 id="experience">Опыт работы</h2>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Собственные продукты и исследование AI-инструментов</p>
|
||||
<p class="resume-exp__period">Декабрь 2025 — настоящее время</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Период самостоятельной практики: изучение AI-инструментов в продуктовом и дизайн-процессе, разработка собственных продуктов полного цикла — от идеи до работающего релиза.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">AI-плагин для Figma (внутренний инструмент)</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Определил сценарии автоматизации на основе аудита собственного рабочего процесса: замерил, какие операции повторяются чаще всего и съедают больше всего времени</li>
|
||||
<li>Спроектировал интерфейс плагина: панель, состояния обработки, обработка ошибок, работа с выделением</li>
|
||||
<li>Собрал архитектуру взаимодействия с LLM: промпт-шаблоны, валидация ответа, повторные попытки</li>
|
||||
<li>Довёл до рабочей версии самостоятельно, с помощью AI-ассистированной разработки</li>
|
||||
<li>Веду плагин как продукт: собираю обратную связь, приоритизирую доработки, выпускаю обновления</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Автоматизировал 7 рутинных операций дизайн-процесса: нейминг слоёв, генерация контента для макетов, приведение текстов к тону продукта, локализация</li>
|
||||
<li>Сократил время на подготовку макета к передаче в разработку примерно на 40%</li>
|
||||
<li>Экономлю около 5 часов в неделю на операциях, которые раньше делал руками</li>
|
||||
<li>Прошёл полный цикл продукта в одиночку: проблема → решение → реализация → эксплуатация</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Автоматизации и сервисы на n8n (личные проекты)</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование логики сценариев: триггеры, ветвления, обработка ошибок, повторные запуски</li>
|
||||
<li>Работа с PostgreSQL как хранилищем и источником данных для процессов</li>
|
||||
<li>Интеграция внешних сервисов через REST API</li>
|
||||
<li>Проектирование и запуск Telegram-ботов: сценарии диалога, состояния, интерфейс сообщений</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Собрал 12 рабочих сценариев автоматизации, закрывающих личные и рабочие рутины</li>
|
||||
<li>Запустил 3 Telegram-бота с собственной продуктовой логикой и базой данных</li>
|
||||
<li>Свёл разрозненные сервисы в единый процесс без единой строки ручной работы</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Пет-проекты на AI-ассистированной разработке</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Продуктовое проектирование: формулировка проблемы, сценарии, интерфейс, приоритизация функций</li>
|
||||
<li>Реализация фронтенда и логики с помощью AI-ассистентов</li>
|
||||
<li>Развёртывание и поддержка работающих сервисов</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Довёл 5 идей до состояния работающего продукта, а не макета в Figma</li>
|
||||
<li>Научился доводить гипотезу до проверяемого прототипа за 2–3 дня вместо нескольких недель ожидания разработки</li>
|
||||
<li>Закрыл разрыв между дизайном и реализацией: теперь проверяю идеи в коде, а не только на макетах</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Primo RPA</p>
|
||||
<p class="resume-exp__period">Февраль 2023 — Ноябрь 2025 (2 года и 10 месяцев)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Российская RPA-платформа корпоративного уровня: линейка из desktop-среды разработки роботов и веб-сервисов управления, аналитики и ML. Работал ведущим дизайнером на всю продуктовую линейку из 6 продуктов.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">AI Server platform (Saas)</p>
|
||||
<p class="resume-exp__desc">Панель управления для обучения/запуска/тестирования и других операций с нейросетями развёрнутыми внутри контура компании.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса управления моделями: обучение, запуск, тестирование, версионирование, мониторинг</li>
|
||||
<li>Проработка сценариев работы с Smart OCR — извлечение данных из документов различных типов</li>
|
||||
<li>Проектирование разметки документов и валидации результатов распознавания</li>
|
||||
<li>Работа с состояниями долгих процессов: обучение модели, прогресс, ошибки, откат</li>
|
||||
<li>Подготовка интерактивных прототипов и авторский надзор за реализацией</li>
|
||||
<li>Проведение интервью с ML-инженерами и бизнес-пользователями для сверки моделей поведения</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Упаковал сложную ML-логику в интерфейс, понятный не только ML-инженеру, но и бизнес-аналитику без технического бэкграунда</li>
|
||||
<li>Свёл работу с моделями к единому предсказуемому сценарию из 4 шагов вместо 9 разрозненных экранов</li>
|
||||
<li>Сократил время настройки новой модели с 40 до 15 минут по результатам замеров на тестировании</li>
|
||||
<li>Спроектировал интерфейс разметки документов, который снял 60% обращений в поддержку по этой теме</li>
|
||||
<li>Провёл 8 юзабилити-сессий, по итогам переработал ключевой сценарий обучения модели</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Robot automation studio (Windows)</p>
|
||||
<p class="resume-exp__desc">Среда для разработки и отладки роботов для автоматизации бизнес-процессов.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса профессиональной desktop-IDE: рабочая область, панели инструментов, дерево процесса, отладчик</li>
|
||||
<li>Развитие библиотеки компонентов и визуального языка продукта</li>
|
||||
<li>Проработка сценариев отладки: точки останова, пошаговое выполнение, просмотр переменных</li>
|
||||
<li>Проектирование работы с большими деревьями активностей и вложенностью</li>
|
||||
<li>Работа в паре с разработкой по реализации компонентов, авторский надзор</li>
|
||||
<li>Ведение регулярных дизайн-ревью внутри команды</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Обновил визуальный язык продукта до уровня Windows 10/11 — компоненты стали на поколение современнее</li>
|
||||
<li>Переработал 80+ экранов и диалогов, приведя их к единой сетке и типографике</li>
|
||||
<li>Собрал библиотеку из 140 компонентов, закрывшую 90% потребностей интерфейса</li>
|
||||
<li>Перевёл иконки и часть иллюстраций на векторную графику: корректное отображение при любом масштабировании и DPI</li>
|
||||
<li>Сократил время сборки нового экрана командой с 2 дней до 4 часов за счёт готовых компонентов</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Robot automation studio (Linux)</p>
|
||||
<p class="resume-exp__desc">Среда для разработки и отладки роботов для автоматизации бизнес-процессов.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Адаптация дизайна Студии под Linux-версию на фреймворке Avalonia</li>
|
||||
<li>Проектирование компонентов с учётом технических ограничений фреймворка</li>
|
||||
<li>Синхронизация визуального языка между Windows- и Linux-версиями продукта</li>
|
||||
<li>Совместная работа с разработкой над тем, что технически реализуемо в Avalonia, а что требует обходных решений</li>
|
||||
<li>Подготовка спецификаций поведения компонентов для реализации</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Собрал расширенную библиотеку из 95 компонентов для Avalonia, которой в проекте не существовало до меня</li>
|
||||
<li>Обеспечил единообразие продукта на двух платформах при разных технологических стеках</li>
|
||||
<li>Сократил количество визуальных расхождений между версиями с нескольких десятков до единичных случаев</li>
|
||||
<li>Дал команде Linux-версии готовый набор решений вместо дизайна каждого экрана с нуля</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Idea Hub Dashboard (Saas)</p>
|
||||
<p class="resume-exp__desc">Обеспечивает сбор и анализ предложений сотрудников, оценка эффективности и мониторинг статуса реализации автоматизаций. Аналитика по ключевым показателям эффективности и верхнеуровневый взгляд на роботизацию.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование дашбордов и аналитических представлений по KPI роботизации</li>
|
||||
<li>Проработка жизненного цикла идеи: подача → оценка → приоритизация → реализация → замер эффекта</li>
|
||||
<li>Информационная архитектура раздела, работа с плотными таблицами, фильтрами и массовыми операциями</li>
|
||||
<li>Проектирование ролевой модели: сотрудник, аналитик, руководитель</li>
|
||||
<li>Подбор типов визуализации данных под конкретные управленческие вопросы</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Свёл верхнеуровневую аналитику и работу с конкретной идеей в один непрерывный сценарий без переключения между разделами</li>
|
||||
<li>Спроектировал представление данных так, что руководитель видит эффект от роботизации без ручных выгрузок в Excel</li>
|
||||
<li>Сократил путь от подачи идеи до её оценки с 6 шагов до 3</li>
|
||||
<li>Спроектировал 12 виджетов аналитики, покрывающих основные вопросы заказчиков о ROI роботизации</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Orchestrator Automation Management Tool (Saas)</p>
|
||||
<p class="resume-exp__desc">Обеспечивает слаженную работу системы и управление сотнями роботов: запуски, мониторинг и менеджмент.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса управления парком из сотен роботов: расписания, очереди, приоритеты, мониторинг</li>
|
||||
<li>Проработка состояний и обработки ошибок при массовых запусках</li>
|
||||
<li>Проектирование системы уведомлений и алертов о сбоях</li>
|
||||
<li>Работа со сложными таблицами: сортировка, фильтрация, массовые действия, сохранённые представления</li>
|
||||
<li>Прототипирование сложных сценариев для валидации до начала разработки</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Спроектировал управление сотнями объектов так, что оператор не теряется в масштабе: от общей картины до конкретного робота за 2 клика</li>
|
||||
<li>Привёл сервис к единой дизайн-системе вместе с остальными веб-продуктами линейки</li>
|
||||
<li>Сократил время реакции оператора на сбой робота с 12 до 4 минут за счёт переработанной системы алертов</li>
|
||||
<li>Свёл 5 разных представлений списка роботов к одному настраиваемому</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">QnA portal (WEB)</p>
|
||||
<p class="resume-exp__desc">Площадка для постинга вопросов и получения ответов от службы поддержки</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование сценариев публикации вопроса, ответа и поиска по накопленной базе знаний</li>
|
||||
<li>Дизайн интерфейса портала на базе общей дизайн-системы компании</li>
|
||||
<li>Проработка ролевой модели: пользователь, эксперт, служба поддержки, модератор</li>
|
||||
<li>Проектирование механики поиска и подсказок похожих вопросов при публикации</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Запустил портал на готовых компонентах дизайн-системы за 3 недели вместо запланированных 8</li>
|
||||
<li>Снизил нагрузку на поддержку примерно на 25% за счёт переиспользования уже данных ответов</li>
|
||||
<li>Механика подсказок похожих вопросов сократила количество дублей на 45%</li>
|
||||
<li>Обеспечил визуальную преемственность с продуктами линейки — портал не выглядит сторонним сервисом</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Общее по компании</p>
|
||||
<ul>
|
||||
<li>Инициировал обновление внешнего вида всей продуктовой линейки — решение о редизайне компания приняла с моим приходом</li>
|
||||
<li>Собрал и внедрил единую дизайн-систему для веб-сервисов, соединив фирменный стиль компании с новой структурой интерфейсов</li>
|
||||
<li>Дизайн-систему приняли 4 продуктовые команды; она включает 210 компонентов и токены темизации</li>
|
||||
<li>Сократил среднее время подготовки макетов по линейке на 35%</li>
|
||||
<li>Создавал и поддерживал UI-kit для консистентности и ускорения разработки</li>
|
||||
<li>Провёл более 20 пользовательских исследований и юзабилити-сессий за время работы</li>
|
||||
<li>Вёл авторский надзор за реализацией, участвовал в дизайн-ревью, продуктовых обсуждениях и планировании релизов</li>
|
||||
<li>Был единственным ведущим дизайнером на всю линейку из 6 продуктов и двух платформ</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Lunacy (Icons8)</p>
|
||||
<p class="resume-exp__period">Июль 2022 — Январь 2023 (7 месяцев)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Графический редактор для работы над дизайном интерфейсов и прочих макетов. Аналог Sketch App и Figma.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса графического редактора: инструменты, панели свойств, работа с холстом и слоями</li>
|
||||
<li>Оформление решений в виде юзерфлоу и передача разработчикам</li>
|
||||
<li>Создание сложных интерактивных прототипов в Protopie для демонстрации поведения инструментов</li>
|
||||
<li>Отрисовка недостающих иконок в стилистике продукта</li>
|
||||
<li>Внесение предложений по улучшению функциональности редактора</li>
|
||||
<li>Участие в обсуждениях продуктовых решений с командой</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Спроектировал 6 функциональных блоков редактора, включая работу с компонентами и стилями</li>
|
||||
<li>Собрал 15+ прототипов в Protopie, что позволило отсечь неудачные решения до разработки</li>
|
||||
<li>Часть моих предложений по функциональности вошла в релизы продукта</li>
|
||||
<li>Отрисовал более 60 иконок, дополнивших системный набор редактора</li>
|
||||
<li>Работал над продуктом для профессиональной аудитории дизайнеров, где требования к деталям интерфейса выше обычных</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">MANU Video Game Maker</p>
|
||||
<p class="resume-exp__period">Январь 2019 — Декабрь 2021 (3 года)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Игровой движок для создания видеоигр без написания кода.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Продуктовый дизайн движка целиком: от концепции взаимодействия до конечного UI</li>
|
||||
<li>Проектирование поведения интерфейса для сложных пользовательских сценариев</li>
|
||||
<li>Исследования пользователей: наблюдение, глубинные интервью, опросы</li>
|
||||
<li>Составление портретов потенциальных пользователей и карт эмпатии</li>
|
||||
<li>Работа с продуктовой аналитикой и метриками, завязанными на пользовательские сценарии</li>
|
||||
<li>Вёрстка главной страницы сайта на Tilda, проектирование информационной архитектуры сайта вместе с командой</li>
|
||||
<li>Контроль работы веб-графического дизайнера</li>
|
||||
<li>Найм в продуктовый отдел: проведение собеседований и отбор специалистов</li>
|
||||
<li>Руководство отделом, построение рабочих процессов всей продуктовой команды</li>
|
||||
<li>Кураторство работ по созданию пользовательской документации</li>
|
||||
<li>Внедрение инструментов автоматизации (Integromat, Zapier) для внутренних задач</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Провёл масштабный редизайн всей программы: заложил принципиально новую концепцию работы и стилистику</li>
|
||||
<li>Спроектировал поведение интерфейса для 100+ сложных пользовательских сценариев</li>
|
||||
<li>Спроектировал дизайн-систему продукта с нуля: 120 компонентов</li>
|
||||
<li>Получили массу положительных, местами восторженных отзывов пользователей — в продукте стало значительно легче ориентироваться</li>
|
||||
<li>Завершаемость онбординга выросла с 34% до 58% после редизайна</li>
|
||||
<li>Провёл 25 глубинных интервью и 4 волны опросов, на их основе переработал 3 ключевых сценария</li>
|
||||
<li>Нанял 4 специалистов в продуктовый отдел и вырос из дизайнера в тимлида команды</li>
|
||||
<li>Выстроил процессы отдела: дизайн-ревью, работа с бэклогом, передача в разработку</li>
|
||||
<li>Автоматизировал внутренние рутины команды, освободив время на продуктовые задачи</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Aegees Messenger</p>
|
||||
<p class="resume-exp__period">Октябрь 2017 — Декабрь 2018 (1 год и 3 месяца)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Кроссплатформенный мессенджер с защищенным хранилищем и аудиозвонками.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Дизайн мессенджера сразу под пять платформ: Android, iOS, macOS, Windows, Linux</li>
|
||||
<li>Проработка сценариев защищённого хранилища и аудиозвонков</li>
|
||||
<li>Проектирование сценариев регистрации, шифрования и восстановления доступа</li>
|
||||
<li>Адаптация единой продуктовой логики под гайдлайны каждой платформы</li>
|
||||
<li>Контроль работы зарубежных иллюстраторов по подготовке графических материалов</li>
|
||||
<li>Подготовка материалов для магазинов приложений</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Выстроил единый визуальный язык продукта при соблюдении гайдлайнов пяти платформ одновременно</li>
|
||||
<li>Спроектировал более 90 экранов в пяти платформенных вариантах</li>
|
||||
<li>Обеспечил стабильный поток графических материалов от внешних подрядчиков без потери стилистики</li>
|
||||
<li>Упростил сценарий защищённого хранилища так, чтобы им пользовались люди без технической подготовки</li>
|
||||
<li>Работал в чувствительной области приватности и безопасности, где ошибка в интерфейсе стоит доверия пользователя</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Orion Innovation (ex MERA)</p>
|
||||
<p class="resume-exp__period">Июль 2016 — Октябрь 2017 (1 год и 4 месяца)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Разработка ПО для внешних заказчиков.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Работа в дизайн-отделе численностью до 8 человек</li>
|
||||
<li>Создание анкет персон и составление карты функциональности продукта в соответствии с потребностями персон</li>
|
||||
<li>Вайрфреймы и отрисовка конечного UI интерфейсов</li>
|
||||
<li>Проектирование юзкейсов, карт экранов, демонстрации микроанимаций</li>
|
||||
<li>Подготовка мудбордов и дизайн-концепций, обсуждение их с клиентами</li>
|
||||
<li>Подготовка и проведение презентаций дизайн-концепций</li>
|
||||
<li>Линковка мокапов в прототипы, написание сценариев и проведение качественных юзабилити-тестирований</li>
|
||||
<li>Внесение правок по результатам тестирований</li>
|
||||
<li>Авторский надзор над реализацией дизайна разработчиками</li>
|
||||
<li>Участие в дизайн-ревью: разбор работ коллег и защита собственных решений</li>
|
||||
<li>Прямая коммуникация с зарубежными клиентами для обсуждения дизайна и получения задач</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Провёл 10 сессий юзабилити-тестирования от написания сценария до внесения правок</li>
|
||||
<li>Освоил новую для себя платформу Smart TV и довёл проект до успешной публикации в магазине приложений</li>
|
||||
<li>Вёл коммуникацию с зарубежными заказчиками напрямую, без посредников</li>
|
||||
<li>Активно участвовал в улучшении рабочего процесса дизайн-отдела компании</li>
|
||||
<li>Прошёл полный цикл продуктового дизайна на 5 клиентских проектах</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">SpaceshipApps Studio</p>
|
||||
<p class="resume-exp__period">Июнь 2015 — Июнь 2016 (1 год и 1 месяц)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Студия разработки мобильных приложений и сайтов.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Дизайн мобильных и веб-продуктов в потоковом режиме студии</li>
|
||||
<li>Работа с разными доменами: соцгейминг, бьюти-услуги, доставка еды, голосовые интерфейсы, легал-сервисы, коллаборативные инструменты</li>
|
||||
<li>Адаптивный веб-дизайн и дизайн административных панелей</li>
|
||||
<li>Отрисовка иконок и подготовка графики для проектов</li>
|
||||
<li>Подготовка макетов к передаче в разработку</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Выпустил 6 продуктов за год: геолокационная социальная игра с квестами в реальном мире, приложение записи к бьюти-специалистам, сервис доставки еды, голосовая игра со словами, сайт и админка сервиса регистрации авторского права, мобильная «белая доска» для совместной работы</li>
|
||||
<li>Научился быстро входить в новую предметную область и держать качество при высоком темпе студии</li>
|
||||
<li>Закрыл весь спектр задач: мобайл, веб, админ-панели, графика</li>
|
||||
<li>Заложил базу для перехода от исполнительского дизайна к продуктовому</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="skills">Навыки</h2>
|
||||
<p class="section__prose">Figma, AI, n8n, Rest API, HTML, CSS, JS, JTBD, UJM, KISS</p>
|
||||
|
||||
<h2 id="about">О себе</h2>
|
||||
<p class="section__prose resume-about">
|
||||
В дизайне больше 10 лет, последние годы — продуктовый дизайн сложных B2B-продуктов. Работаю на стыке дизайна и продакт-менеджмента: провожу исследования, формулирую гипотезы и фичи, помогаю с приоритизацией и участвую в планировании релизов.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Люблю разбираться в сложном и делать его понятным — поэтому мне комфортно в продуктах вроде IDE, оркестраторов и ML-панелей, где обычному дизайнеру скучно или страшно.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Не жду, пока задачу сделает кто-то другой: пишу себе инструменты сам. Собрал приватный AI-плагин для Figma, автоматизирую процессы на n8n и PostgreSQL, довожу свои идеи до работающих продуктов с помощью AI-ассистированной разработки. Собственные навыки для Алисы набрали 37 000+ и 33 000+ пользователей, файл Slider Set для дизайнеров скачали больше 20 000 раз.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Участвую в жизни сообщества: веду Telegram-канал «Дизайн не пицца», выкладываю полезности в Figma Community, выступал на митапе Яндекса с докладом по аналитике, побеждал на хакатонах — самая приятная победа на хакатоне Яндекс.Денег в Петербурге за приложение оплаты по QR-коду.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Английский — B1. Работаю удалённо, спокойно веду коммуникацию с распределённой командой.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="footer__inner">
|
||||
<span class="footer__chunk footer__chunk--date">© 2026<span class="footer__sep" aria-hidden="true"> · </span></span>
|
||||
<span class="footer__chunk footer__chunk--main">Дизайн и разработка сайта — Николай Мамадаев</span>
|
||||
<span class="footer__chunk footer__chunk--meta footer__attr"><span class="footer__sep" aria-hidden="true"> · </span><a href="cases/design-system.html">Design System</a><span class="footer__sep" aria-hidden="true"> · </span><a href="cookie-policy.html">Политика cookie</a></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<aside class="cookie-notice glass-neutral" hidden data-cookie-notice>
|
||||
<p class="cookie-notice__text">
|
||||
Сайт использует cookie для комфортной работы. Подробнее — в
|
||||
<a href="cookie-policy.html" data-cookie-policy-link>политике cookie</a>.
|
||||
</p>
|
||||
<button type="button" class="btn btn--secondary btn--flat cookie-notice__accept" data-cookie-accept>
|
||||
<span>Принять</span>
|
||||
<span class="cookie-notice__accept-icon" aria-hidden="true">
|
||||
<img src="assets/shared/icons/сookie.svg" alt="" width="20" height="20" loading="eager" decoding="async" />
|
||||
</span>
|
||||
</button>
|
||||
</aside>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,179 +0,0 @@
|
||||
/**
|
||||
* Инкрементальный деплой public/ на VPS в Docker volume nginx.
|
||||
* Загружает только изменённые файлы через tar-пайп над SSH (одно соединение).
|
||||
*
|
||||
* Использование:
|
||||
* node scripts/deploy-vps.mjs [sourceDir]
|
||||
*/
|
||||
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import { execFile, spawn } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const projectRoot = path.resolve(__dirname, "..");
|
||||
|
||||
const SSH_KEY = path.join(os.homedir(), ".ssh", "beget");
|
||||
const SSH_RAW_OPTS = [
|
||||
"-i", SSH_KEY,
|
||||
"-o", "StrictHostKeyChecking=accept-new",
|
||||
"-o", "ConnectTimeout=15",
|
||||
"-o", "ServerAliveInterval=30",
|
||||
];
|
||||
const SSH_HOST = "root@155.212.186.39";
|
||||
const TARGET_DIR = "/var/lib/docker/volumes/s9mrcps8xw02r1dak0fsznix-www-data/_data";
|
||||
const MANIFEST_PATH = path.join(projectRoot, ".deploy-manifest.json");
|
||||
|
||||
const SOURCE_DIR = (() => {
|
||||
const raw = process.argv[2] ?? "public";
|
||||
return path.isAbsolute(raw) ? raw : path.resolve(projectRoot, raw);
|
||||
})();
|
||||
|
||||
function ssh(args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
execFile("ssh", [...SSH_RAW_OPTS, SSH_HOST, ...args], { maxBuffer: 1024 * 1024 }, (err, stdout) => {
|
||||
if (err) reject(new Error((err.stderr || "").trim() || err.message));
|
||||
else resolve((stdout || "").trim());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function scanFiles(dir) {
|
||||
const entries = [];
|
||||
const walk = (current, relative) => {
|
||||
for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
|
||||
const rel = relative ? `${relative}/${entry.name}` : entry.name;
|
||||
const full = path.join(current, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
walk(full, rel);
|
||||
} else if (entry.isFile()) {
|
||||
const stat = fs.statSync(full);
|
||||
entries.push({
|
||||
relPath: rel.replace(/\\/g, "/"),
|
||||
mtime: stat.mtimeMs,
|
||||
size: stat.size,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
walk(dir, "");
|
||||
return entries;
|
||||
}
|
||||
|
||||
function loadManifest() {
|
||||
try {
|
||||
return JSON.parse(fs.readFileSync(MANIFEST_PATH, "utf-8"));
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function saveManifest(manifest) {
|
||||
fs.writeFileSync(MANIFEST_PATH, JSON.stringify(manifest, null, 2), "utf-8");
|
||||
}
|
||||
|
||||
/** Загрузить изменённые файлы одним tar-пайпом через SSH */
|
||||
function uploadViaTar(filePaths, sourceDir) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const listPath = path.join(os.tmpdir(), `deploy-files-${Date.now()}.txt`);
|
||||
fs.writeFileSync(listPath, filePaths.join("\n"), "utf-8");
|
||||
|
||||
// cwd вместо -C — обходит баг bsdtar с кириллицей в пути
|
||||
const tar = spawn("tar", [
|
||||
"-c",
|
||||
`--files-from=${listPath}`,
|
||||
"--format=ustar",
|
||||
], { cwd: sourceDir });
|
||||
|
||||
const sshProc = spawn("ssh", [
|
||||
...SSH_RAW_OPTS,
|
||||
SSH_HOST,
|
||||
`tar xf - -C ${TARGET_DIR}`,
|
||||
]);
|
||||
|
||||
tar.stdout.pipe(sshProc.stdin);
|
||||
|
||||
let stderrChunks = [];
|
||||
sshProc.stderr.on("data", (d) => { stderrChunks.push(d); });
|
||||
tar.stderr.on("data", (d) => { stderrChunks.push(d); });
|
||||
|
||||
function cleanup() {
|
||||
try { fs.unlinkSync(listPath); } catch { /* ok */ }
|
||||
}
|
||||
|
||||
sshProc.on("close", (code) => {
|
||||
cleanup();
|
||||
if (code !== 0) {
|
||||
const msg = Buffer.concat(stderrChunks).toString().trim();
|
||||
reject(new Error(msg || `ssh exited with code ${code}`));
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
sshProc.on("error", (err) => { cleanup(); reject(err); });
|
||||
tar.on("error", (err) => { cleanup(); sshProc.kill(); reject(err); });
|
||||
});
|
||||
}
|
||||
|
||||
async function deploy() {
|
||||
// 1. Убедиться, что целевая директория существует
|
||||
console.log("Проверка соединения...");
|
||||
await ssh([`mkdir -p ${TARGET_DIR}`]);
|
||||
|
||||
// 2. Сравнить локальные файлы с манифестом
|
||||
console.log("Сканирование...");
|
||||
const localFiles = scanFiles(SOURCE_DIR);
|
||||
const manifest = loadManifest();
|
||||
|
||||
const changedPaths = [];
|
||||
for (const f of localFiles) {
|
||||
const prev = manifest[f.relPath];
|
||||
if (!prev || prev.mtime !== f.mtime || prev.size !== f.size) {
|
||||
changedPaths.push(f.relPath);
|
||||
}
|
||||
}
|
||||
|
||||
const localPaths = new Set(localFiles.map((f) => f.relPath));
|
||||
const removedPaths = Object.keys(manifest).filter((p) => !localPaths.has(p));
|
||||
|
||||
if (changedPaths.length === 0 && removedPaths.length === 0) {
|
||||
console.log("Изменений нет — деплой не требуется.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Изменено/новых: ${changedPaths.length}, удалено: ${removedPaths.length}`);
|
||||
|
||||
// 3. Загрузить изменённые файлы одним tar-пайпом
|
||||
if (changedPaths.length > 0) {
|
||||
console.log("Загрузка файлов...");
|
||||
await uploadViaTar(changedPaths, SOURCE_DIR);
|
||||
console.log("Загрузка завершена.");
|
||||
}
|
||||
|
||||
// 4. Удалить файлы, которых больше нет локально
|
||||
if (removedPaths.length > 0) {
|
||||
console.log("Удаление лишних файлов...");
|
||||
const rmList = removedPaths.map((p) => `${TARGET_DIR}/${p}`).join(" ");
|
||||
await ssh([`rm -f ${rmList}`]);
|
||||
await ssh([`find ${TARGET_DIR} -type d -empty -delete 2>/dev/null || true`]);
|
||||
}
|
||||
|
||||
// 5. Обновить манифест
|
||||
saveManifest(
|
||||
Object.fromEntries(localFiles.map((f) => [f.relPath, { mtime: f.mtime, size: f.size }])),
|
||||
);
|
||||
}
|
||||
|
||||
const relDir = path.relative(projectRoot, SOURCE_DIR);
|
||||
|
||||
deploy()
|
||||
.then(() => {
|
||||
console.log(`Готово: ${relDir}/ → ${SSH_HOST}:${TARGET_DIR}`);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Ошибка деплоя:", err.message || err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,63 @@
|
||||
import puppeteer from 'puppeteer';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname, resolve } from 'path';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const OUT = resolve(__dirname, '../public/assets/resume/Mamadaev_Nik__CV__Product_Designer_UX-UI.pdf');
|
||||
const PAGE = process.argv[2] || 'http://localhost:4175/resume-5.html';
|
||||
const FONT = process.argv[3] || 'geologica';
|
||||
|
||||
const browser = await puppeteer.launch({ headless: true });
|
||||
const page = await browser.newPage();
|
||||
|
||||
await page.goto(PAGE, { waitUntil: 'networkidle0', timeout: 30000 });
|
||||
await page.waitForSelector('.resume-doc', { timeout: 5000 });
|
||||
|
||||
await page.evaluate((font) => {
|
||||
localStorage.setItem('siteThemeV1', JSON.stringify({ font }));
|
||||
document.documentElement.dataset.font = font;
|
||||
const href = `assets/fonts/${font}.css`;
|
||||
if (!document.querySelector(`link[data-theme-font="${font}"]`)) {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = href;
|
||||
link.dataset.themeFont = font;
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
}, FONT);
|
||||
await page.evaluate(() => document.fonts.ready);
|
||||
await new Promise(r => setTimeout(r, 1500));
|
||||
|
||||
const fontInfo = await page.evaluate(() => ({
|
||||
dataFont: document.documentElement.dataset.font,
|
||||
computedFont: getComputedStyle(document.body).fontFamily,
|
||||
}));
|
||||
console.log('Font:', fontInfo);
|
||||
|
||||
await page.evaluate(() => {
|
||||
document.querySelectorAll('header, footer, nav, .fab-stack, .cookie-notice, .skip-link').forEach(el => el.remove());
|
||||
const doc = document.querySelector('.resume-doc');
|
||||
if (doc) {
|
||||
doc.style.removeProperty('max-width');
|
||||
doc.style.width = '100%';
|
||||
doc.style.margin = '0';
|
||||
doc.style.setProperty('background', 'transparent', 'important');
|
||||
doc.style.border = 'none';
|
||||
document.documentElement.style.setProperty('background', 'transparent', 'important');
|
||||
document.body.style.background = 'transparent';
|
||||
document.body.innerHTML = '';
|
||||
document.body.appendChild(doc);
|
||||
document.body.style.margin = '0';
|
||||
document.body.style.padding = '0';
|
||||
}
|
||||
});
|
||||
|
||||
await page.pdf({
|
||||
path: OUT,
|
||||
format: 'A4',
|
||||
printBackground: true,
|
||||
margin: { top: '10mm', bottom: '10mm', left: '10mm', right: '10mm' }
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
console.log('PDF saved:', OUT);
|
||||
+53
-14
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* Локальный сервер: public/ + BrowserSync + API правок контента (только localhost).
|
||||
* Локальный сервер: public/ + API правок контента (только localhost).
|
||||
* Фолбэк: нативный http без browser-sync (portscanner глючит на Node 23+).
|
||||
*/
|
||||
import browserSync from "browser-sync";
|
||||
import http from "node:http";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
@@ -199,17 +200,55 @@ if (!fs.existsSync(PENDING_FILE)) {
|
||||
}
|
||||
migrateLegacyFiles();
|
||||
|
||||
browserSync.create().init({
|
||||
server: {
|
||||
baseDir: publicDir,
|
||||
middleware: [contentEditsApi],
|
||||
},
|
||||
files: [path.join(publicDir, "**", "*")],
|
||||
port: 4175,
|
||||
ui: { port: 4176 },
|
||||
notify: false,
|
||||
open: false,
|
||||
ghostMode: false,
|
||||
const MIME = {
|
||||
".html": "text/html; charset=utf-8",
|
||||
".css": "text/css; charset=utf-8",
|
||||
".js": "application/javascript; charset=utf-8",
|
||||
".mjs": "application/javascript; charset=utf-8",
|
||||
".json": "application/json; charset=utf-8",
|
||||
".svg": "image/svg+xml",
|
||||
".png": "image/png",
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".webp": "image/webp",
|
||||
".gif": "image/gif",
|
||||
".ico": "image/x-icon",
|
||||
".woff": "font/woff",
|
||||
".woff2": "font/woff2",
|
||||
".ttf": "font/ttf",
|
||||
".mp4": "video/mp4",
|
||||
".webm": "video/webm",
|
||||
};
|
||||
|
||||
function serveStatic(req, res) {
|
||||
const url = new URL(req.url || "/", "http://localhost");
|
||||
let filePath = path.join(publicDir, decodeURIComponent(url.pathname));
|
||||
if (filePath.endsWith(path.sep)) filePath = path.join(filePath, "index.html");
|
||||
|
||||
fs.stat(filePath, (err, stat) => {
|
||||
if (err || !stat.isFile()) {
|
||||
const fallback = path.join(publicDir, "index.html");
|
||||
fs.readFile(fallback, (e2, data) => {
|
||||
if (e2) { res.writeHead(404); res.end("Not found"); return; }
|
||||
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
||||
res.end(data);
|
||||
});
|
||||
return;
|
||||
}
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
const mime = MIME[ext] || "application/octet-stream";
|
||||
fs.readFile(filePath, (e2, data) => {
|
||||
if (e2) { res.writeHead(500); res.end("Error"); return; }
|
||||
res.writeHead(200, { "Content-Type": mime });
|
||||
res.end(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
contentEditsApi(req, res, () => serveStatic(req, res));
|
||||
});
|
||||
|
||||
console.log("serve-dev: http://localhost:4175 (public/, reload only public/**)");
|
||||
server.listen(4175, () => {
|
||||
console.log("serve-dev: http://localhost:4175 (public/)");
|
||||
});
|
||||
@@ -1,162 +0,0 @@
|
||||
/**
|
||||
* Копирует содержимое папки public в папку gitverse.
|
||||
* Файлы `.png` не копируются (на GitVerse достаточно WebP и прочих ассетов).
|
||||
*
|
||||
* По умолчанию:
|
||||
* node scripts/sync-gitverse.mjs
|
||||
* (копирует projectRoot/public -> projectRoot/gitverse)
|
||||
*
|
||||
* Можно передать свои пути:
|
||||
* node scripts/sync-gitverse.mjs <sourceDir> <targetDir>
|
||||
*/
|
||||
|
||||
import path from "node:path";
|
||||
import os from "node:os";
|
||||
import fsp from "node:fs/promises";
|
||||
import { execFile, spawn } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const projectRoot = path.resolve(__dirname, "..");
|
||||
const PRESERVE_IN_TARGET = new Set([".git", ".gitverse"]);
|
||||
|
||||
function shouldSkipGitverseFile(fileName) {
|
||||
return path.extname(fileName).toLowerCase() === ".png";
|
||||
}
|
||||
const DEFAULT_SSH_KEY_PATH = path.join(os.homedir(), ".ssh", "id_ed25519_work");
|
||||
const GITVERSE_SITE_URL = "https://mamadaevv.gitverse.site/me/";
|
||||
|
||||
/** Системный браузер по умолчанию (Windows / macOS / Linux). */
|
||||
function openUrlInDefaultBrowser(url) {
|
||||
if (typeof url !== "string" || !/^https?:\/\//i.test(url)) return;
|
||||
const opts = { detached: true, stdio: "ignore" };
|
||||
let child;
|
||||
if (process.platform === "win32") {
|
||||
child = spawn("cmd", ["/c", "start", "", url], opts);
|
||||
} else if (process.platform === "darwin") {
|
||||
child = spawn("open", [url], opts);
|
||||
} else {
|
||||
child = spawn("xdg-open", [url], opts);
|
||||
}
|
||||
child?.unref();
|
||||
}
|
||||
|
||||
function resolveDir(input, fallback) {
|
||||
const raw = input ?? fallback;
|
||||
return path.isAbsolute(raw) ? raw : path.resolve(projectRoot, raw);
|
||||
}
|
||||
|
||||
async function ensureDirExists(dirPath, label) {
|
||||
try {
|
||||
const st = await fsp.stat(dirPath);
|
||||
if (!st.isDirectory()) {
|
||||
throw new Error(`${label} не является папкой: ${dirPath}`);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error && error.code === "ENOENT") {
|
||||
throw new Error(`${label} не найдена: ${dirPath}`);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function cleanTargetDir(targetDir) {
|
||||
await fsp.mkdir(targetDir, { recursive: true });
|
||||
const entries = await fsp.readdir(targetDir, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (PRESERVE_IN_TARGET.has(entry.name)) continue;
|
||||
const fullPath = path.join(targetDir, entry.name);
|
||||
await fsp.rm(fullPath, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
async function copyDirFiltered(sourceDir, targetDir) {
|
||||
await fsp.mkdir(targetDir, { recursive: true });
|
||||
const entries = await fsp.readdir(sourceDir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const srcPath = path.join(sourceDir, entry.name);
|
||||
const dstPath = path.join(targetDir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
await copyDirFiltered(srcPath, dstPath);
|
||||
continue;
|
||||
}
|
||||
if (!entry.isFile() || shouldSkipGitverseFile(entry.name)) continue;
|
||||
await fsp.copyFile(srcPath, dstPath);
|
||||
}
|
||||
}
|
||||
|
||||
function runGit(args, cwd) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const gitEnv = {
|
||||
...process.env,
|
||||
GIT_SSH_COMMAND: `ssh -i "${DEFAULT_SSH_KEY_PATH}" -o IdentitiesOnly=yes`,
|
||||
};
|
||||
execFile("git", args, { cwd, encoding: "utf8", env: gitEnv }, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(new Error((stderr || error.message || "").trim()));
|
||||
return;
|
||||
}
|
||||
resolve((stdout || "").trim());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function makeCommitMessage() {
|
||||
const now = new Date();
|
||||
const y = now.getFullYear();
|
||||
const m = String(now.getMonth() + 1).padStart(2, "0");
|
||||
const d = String(now.getDate()).padStart(2, "0");
|
||||
const hh = String(now.getHours()).padStart(2, "0");
|
||||
const mm = String(now.getMinutes()).padStart(2, "0");
|
||||
return `sync public ${y}-${m}-${d} ${hh}:${mm}`;
|
||||
}
|
||||
|
||||
async function commitAndPush(targetDir) {
|
||||
const gitDir = path.join(targetDir, ".git");
|
||||
await ensureDirExists(gitDir, "Git репозиторий (.git)");
|
||||
try {
|
||||
await fsp.access(DEFAULT_SSH_KEY_PATH);
|
||||
} catch {
|
||||
throw new Error(`SSH-ключ не найден: ${DEFAULT_SSH_KEY_PATH}`);
|
||||
}
|
||||
|
||||
await runGit(["add", "."], targetDir);
|
||||
const changed = await runGit(["status", "--porcelain"], targetDir);
|
||||
|
||||
if (!changed) {
|
||||
console.log("Изменений для коммита нет.");
|
||||
return;
|
||||
}
|
||||
|
||||
const message = makeCommitMessage();
|
||||
await runGit(["commit", "-m", message], targetDir);
|
||||
await runGit(["push"], targetDir);
|
||||
console.log(`Коммит и пуш выполнены: ${message}`);
|
||||
openUrlInDefaultBrowser(GITVERSE_SITE_URL);
|
||||
console.log(`Открыт в браузере: ${GITVERSE_SITE_URL}`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const sourceDir = resolveDir(process.argv[2], "public");
|
||||
const targetDir = resolveDir(process.argv[3], "gitverse");
|
||||
|
||||
await ensureDirExists(sourceDir, "Исходная папка");
|
||||
|
||||
if (sourceDir === targetDir) {
|
||||
throw new Error("Исходная и целевая папки совпадают.");
|
||||
}
|
||||
|
||||
await cleanTargetDir(targetDir);
|
||||
await copyDirFiltered(sourceDir, targetDir);
|
||||
|
||||
console.log(
|
||||
`Синхронизировано: ${path.relative(projectRoot, sourceDir)} -> ${path.relative(projectRoot, targetDir)} (сохранены .git и .gitverse)`,
|
||||
);
|
||||
await commitAndPush(targetDir);
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error("Ошибка копирования:", error.message || error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -377,7 +377,7 @@
|
||||
|
||||
<h3>Дальнейшее развитие</h3>
|
||||
<p class="section__prose">
|
||||
В дорожной карте оставались отдельные крупные куски: сценарии вокруг LLM (списки, статусы, действия), пошаговый мастер обучения с прогрессом и отменой, а также полноценный контур OCR с разметкой регионов и превью качества на странице. Они не входили в минимальный набор для первого промышленного релиза интерфейса, но заложенные паттерны должны их принять без ломки навигации.
|
||||
В дорожной карте оставались отдельные крупные куски: сценарии вокруг LLM (списки, статусы, действия), пошаговый мастер обучения с прогрессом и отменой, а также полноценный контур OCR с разметкой регионов и превью качества на странице. Они не входили в минимальный набор для первого промышленного релиза интерфейса, но заложенные паттерны должны их принять без больших переделок.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,552 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium" data-font="merriweather">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Кейс: редизайн Primo RPA AI Server — снижение порога входа для клиентов без команды внедрения."
|
||||
/>
|
||||
<title>AI Server в Primo RPA — кейс</title>
|
||||
{{> head-links}}
|
||||
{{> head-plyr}}
|
||||
<style>
|
||||
.case-article {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.case-article h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.7rem, 3vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article h3 {
|
||||
font-size: 1.55rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article .section__prose {
|
||||
margin-bottom: 0.75rem;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.7;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-article img,
|
||||
.case-article video {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: 0.75rem 0 1rem;
|
||||
}
|
||||
.case-article ul,
|
||||
.case-article ol {
|
||||
margin: 0.5rem 0 1rem 1.25rem;
|
||||
padding: 0;
|
||||
}
|
||||
.case-article li {
|
||||
margin-bottom: 0.35rem;
|
||||
font-size: 1.1rem;
|
||||
line-height: 1.7;
|
||||
}
|
||||
.case-article a:not(.btn) {
|
||||
color: var(--accent);
|
||||
}
|
||||
.case-meta {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
gap: 0.25rem 0.75rem;
|
||||
margin: 1.25rem 0 1.5rem;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.6;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.case-meta dt {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.case-meta dd {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
(function () {
|
||||
try {
|
||||
var t = JSON.parse(localStorage.getItem("siteThemeV1") || "{}");
|
||||
var d = document.documentElement;
|
||||
var m = t.mode;
|
||||
if (m !== "light" && m !== "dark" && m !== "system") m = "system";
|
||||
var eff =
|
||||
m === "system"
|
||||
? window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||
? "dark"
|
||||
: "light"
|
||||
: m;
|
||||
d.dataset.theme = eff;
|
||||
var h = typeof t.h === "number" ? t.h : typeof t.hue === "number" ? t.hue : null;
|
||||
var s = typeof t.s === "number" ? t.s : typeof t.sat === "number" ? t.sat : null;
|
||||
var l = typeof t.l === "number" ? t.l : typeof t.light === "number" ? t.light : null;
|
||||
if (h !== null) d.style.setProperty("--theme-h", String(h));
|
||||
if (s !== null) d.style.setProperty("--theme-s", String(s));
|
||||
if (l !== null) {
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
} else {
|
||||
d.dataset.radius = "medium";
|
||||
}
|
||||
var f = t.font;
|
||||
if (f === "onest") f = "geologica";
|
||||
if (f === "anonymous") f = "mono";
|
||||
if (f === "merriweather" || f === "mono" || f === "geologica") {
|
||||
d.dataset.font = f;
|
||||
} else {
|
||||
d.dataset.font = "merriweather";
|
||||
}
|
||||
var mb = t.meshBg;
|
||||
if (mb === "off") {
|
||||
d.dataset.meshBg = "off";
|
||||
} else {
|
||||
d.dataset.meshBg = "on";
|
||||
}
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
{{> header-case}}
|
||||
{{> fab-stack}}
|
||||
<main id="case-main" class="section section--tight">
|
||||
<div class="section__inner case-article">
|
||||
<p class="hero__eyebrow">Product Design · AI</p>
|
||||
<h1 class="case-page__h1">Упростил настройку Primo RPA AI Server: клиенты настраивают ИИ-сервис без команды внедрения</h1>
|
||||
<p class="case-page__sub">
|
||||
Платформа интеллектуальной обработки документов<br />
|
||||
и оркестрации ИИ-агентов. Обращения к команде внедрения упали на 40%, настройка первого проекта ужалась с ~3 дней до ~4 часов.
|
||||
</p>
|
||||
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/main-new.webp"
|
||||
alt="Обновлённый редактор разметки датасета — главный экран сервиса после редизайна"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
</figure>
|
||||
|
||||
<dl class="case-meta">
|
||||
<dt>Продукт</dt>
|
||||
<dd>AI Server. Нейросети во внутреннем контуре компании, настраивается через веб-интерфейс</dd>
|
||||
<dt>Роль</dt>
|
||||
<dd>UX/UI-дизайнер (единственный на проекте)</dd>
|
||||
<dt>Задача</dt>
|
||||
<dd>Снизить порог входа, чтобы клиент настраивал сервис сам</dd>
|
||||
<dt>Стек</dt>
|
||||
<dd>Ant Design + React, стилизация Hope UI</dd>
|
||||
<dt>Формат</dt>
|
||||
<dd>Редизайн живого продукта, релизы не останавливались</dd>
|
||||
</dl>
|
||||
|
||||
<div class="case-block" id="problem">
|
||||
<h2>С настройкой справлялись только эксперты. Это тормозило продажи</h2>
|
||||
<p class="section__prose">
|
||||
AI Server разворачивается на внутренних серверах клиентов. Продукт активно тестировали, и обратная связь показала неприятное: настроить его могли только эксперты и команда внедрения Primo RPA. Каждый новый клиент съедал часы техподдержки. Продукт терял привлекательность и плохо масштабировался.
|
||||
</p>
|
||||
<aside class="case-callout" data-callout>
|
||||
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">✅</span>
|
||||
<div class="case-callout__content">
|
||||
<p>
|
||||
Бизнес-цель: клиент проходит настройку AI Server сам, без техподдержки и команды внедрения. По этому критерию мы и мерили успех редизайна.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
<p class="section__prose">
|
||||
Начал со знакомства с командой и экспертами по настройке. Разделил сценарии на главные и вспомогательные, собрал визуализацию того, как ведёт себя пользователь, и вместе с разработкой искал, где интерфейс можно упростить. Я уже работал с ИИ и похожими веб-платформами, поэтому быстро разобрался в домене и говорил с разработкой на одном языке.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="constraints">
|
||||
<h2>Ограничения</h2>
|
||||
<ul>
|
||||
<li>Продуктом уже пользовались клиенты. Остановить разработку и пересобрать интерфейс целиком было нельзя.</li>
|
||||
<li>Изменения приходилось вписывать в план релизов, отдельного «редизайн-спринта» никто не выделял.</li>
|
||||
<li>Жёсткий стек: Ant Design под React со стилизацией под Hope UI. Новые компоненты рисовать только в крайнем случае, сначала выжимаем всё из готовой библиотеки.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="navigation">
|
||||
<h2>Навигация путала: разделы проекта смешивались с главным меню</h2>
|
||||
<p class="section__prose">
|
||||
В сервисе стояла привычная для админок схема: слева боковое меню, справа контент. Пространство расходовалось расточительно, а при открытии проекта навигация по его разделам оказывалась вперемешку с главной. Пользователь терялся.
|
||||
</p>
|
||||
<aside class="case-callout" data-callout>
|
||||
<span class="case-callout__emoji" aria-hidden="true">💡</span>
|
||||
<div class="case-callout__content">
|
||||
<p>
|
||||
Две навигации в одном боковом меню заставляли каждый раз разбираться, «где я». Развёл их по уровням: главная сверху, проектная внутри проекта.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/main-new.webp"
|
||||
alt="Главный экран AI Server с компактной верхней навигацией"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Главный экран AI Server с компактной верхней навигацией — список проектов занимает почти всю ширину экрана</figcaption>
|
||||
</figure>
|
||||
<p class="section__prose">
|
||||
Перенёс главную навигацию наверх и ужал её. Контенту стало заметно просторнее, а схема осталась привычной. У проектов появилась собственная навигация, которая с главной не пересекается.
|
||||
</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/nav-project-nlp.webp"
|
||||
alt="Внутренняя навигация NLP-проекта"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Внутренняя навигация NLP-проекта — горизонтальные пункты-шаги под главным меню</figcaption>
|
||||
</figure>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/nav-project-ocr.webp"
|
||||
alt="Внутренняя навигация OCR-проекта"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Внутренняя навигация OCR-проекта — тот же паттерн со своим набором разделов</figcaption>
|
||||
</figure>
|
||||
<aside class="case-callout" data-callout>
|
||||
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">✨</span>
|
||||
<div class="case-callout__content">
|
||||
<p>
|
||||
Стрелочная форма пунктов подсказывает порядок настройки, но не навязывает его: разделы остаются обычными табами. Подсказка без принуждения.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/nav-secondary-detail_view.webp"
|
||||
alt="Крупный план вторичной навигации — пункты в форме стрелок"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Крупный план вторичной навигации — пункты в форме стрелок, ведущих слева направо</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="editor">
|
||||
<h2>Редактор датасета: экран, где пользователи живут</h2>
|
||||
<p class="section__prose">
|
||||
Здесь проводят больше всего времени. Разметка полей на сотнях изображений — работа монотонная, но именно от неё зависит качество данных для обучения модели. Прежний редактор выбивался из общего стиля, выглядел перегруженно и путал в работе с полями.
|
||||
</p>
|
||||
<p class="section__prose">
|
||||
Разобрал редактор на микросценарии, выстроил их по приоритету и связкам. Вместе с командой спроектировали поведение плавнее и понятнее, заложили место под будущий функционал, дизайн привели к общей стилистике сервиса.
|
||||
</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/dataset-editor.webp"
|
||||
alt="Редактор разметки датасета — размечаемый документ в центре, панели полей и инструментов по бокам"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Редактор разметки датасета — размечаемый документ в центре, панели полей и инструментов по бокам</figcaption>
|
||||
</figure>
|
||||
<p class="section__prose">
|
||||
Страница стала симметричной. Почти всё пространство уходит на размечаемое изображение, действия сгруппированы по панелям: нужная функция ищется быстро.
|
||||
</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/dataset_editor-wireframe-default_mode.webp"
|
||||
alt="Схематичный каркас редактора — центральная рабочая область и боковые панели"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Схематичный каркас редактора — центральная рабочая область и боковые панели, режим по умолчанию</figcaption>
|
||||
</figure>
|
||||
<p class="section__prose">
|
||||
Для продвинутых пользователей добавил режим «Во весь экран». Боковые панели сворачиваются, работа идёт через горячие клавиши и нижнюю панель. На небольших мониторах это спасает.
|
||||
</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/full-screen-mode-with-panels.webp"
|
||||
alt="Полноэкранный режим редактора с раскрытыми боковыми панелями"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Полноэкранный режим редактора с раскрытыми боковыми панелями</figcaption>
|
||||
</figure>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/full-screen-mode-zen.webp"
|
||||
alt="Полноэкранный режим без панелей — только размечаемый документ и нижняя панель"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Полноэкранный режим без панелей — на экране только размечаемый документ и нижняя панель инструментов</figcaption>
|
||||
</figure>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/dataset_editor-wireframe-zen_mode-both_panels.webp"
|
||||
alt="Четыре варианта каркаса полноэкранного режима"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Четыре варианта каркаса полноэкранного режима — обе панели, без панелей, только левая, только правая</figcaption>
|
||||
</figure>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/dataset_editor-main_toolbar.webp"
|
||||
alt="Нижняя панель инструментов — переключение между изображениями и быстрые действия разметки"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Нижняя панель инструментов — переключение между изображениями и быстрые действия разметки</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="mapping">
|
||||
<h2>Десятки полей на одном скане, и место под документ не страдает</h2>
|
||||
<p class="section__prose">
|
||||
Смежная задача: настроить уникальные параметры полей датасета. Большая область нужна под скан документа, полей десятки, у каждого свои типы и зависимые параметры.
|
||||
</p>
|
||||
<figure class="case-media" style="margin: 0.85rem 0 1.2rem">
|
||||
<div class="case-video-shell">
|
||||
<video
|
||||
controls
|
||||
preload="metadata"
|
||||
playsinline
|
||||
poster="../assets/ai-platform-primo-rpa/fields-maping.webp"
|
||||
data-case-video-player
|
||||
style="display: block; width: 100%; height: auto; margin: 0"
|
||||
>
|
||||
<source src="../assets/ai-platform-primo-rpa/fields-maping.webm" type="video/webm" />
|
||||
<source src="../assets/ai-platform-primo-rpa/fields-maping.mp4" type="video/mp4" />
|
||||
Ваш браузер не поддерживает видео.
|
||||
</video>
|
||||
</div>
|
||||
<figcaption>Прототип сопоставления полей — пользователь выбирает поле на скане документа и настраивает его параметры в компактной панели</figcaption>
|
||||
</figure>
|
||||
<p class="section__prose">
|
||||
Интерфейс вышел компактным. Механика не считывается с первого взгляда, зато после короткого обучения работать в нём быстро и комфортно.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="learning">
|
||||
<h2>Карточки обучения: паттерн, который разошёлся по всему продукту</h2>
|
||||
<p class="section__prose">
|
||||
После разметки датасета модель дообучают (fine-tuning). Разобрали все действия пользователя, перебрали несколько компоновок страницы. Остановились на ленте из карточек.
|
||||
</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/in_project-learn-overview.webp"
|
||||
alt="Раздел обучения моделей — вертикальная лента карточек"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Раздел обучения моделей — вертикальная лента карточек, сверху карточка настройки нового обучения</figcaption>
|
||||
</figure>
|
||||
<p class="section__prose">
|
||||
В начале ленты карточка настройки: результат разметки активного датасета, параметры, запуск fine-tuning.
|
||||
</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/in_project-learn-card-new.webp"
|
||||
alt="Карточка настройки обучения — матрица качества датасета и блок параметров запуска"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Карточка настройки обучения — матрица качества датасета и блок параметров запуска</figcaption>
|
||||
</figure>
|
||||
<aside class="case-callout" data-callout>
|
||||
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">⭐</span>
|
||||
<div class="case-callout__content">
|
||||
<p>
|
||||
Матрица оценки качества разметки показывает готовность датасета к обучению на одном экране. Раньше приходилось вручную просматривать поля по всем документам.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
<p class="section__prose">
|
||||
Под каждый запущенный процесс появляется своя карточка. Можно завести несколько процессов с разными параметрами и сравнить, какая конфигурация отработала лучше.
|
||||
</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/in_project-learn-card-learning_process.webp"
|
||||
alt="Карточка запущенного процесса обучения — статус, прогресс и метрики"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Карточка запущенного процесса обучения — статус, прогресс и метрики, разнесённые по логическим блокам</figcaption>
|
||||
</figure>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/in_project-learn-card-learning_process_wireframe.webp"
|
||||
alt="Каркас карточки процесса обучения"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Каркас карточки процесса обучения — схема расположения информационных блоков и действий</figcaption>
|
||||
</figure>
|
||||
<p class="section__prose">
|
||||
Карточки сворачиваются, в шапке остаются название и статус.
|
||||
</p>
|
||||
<figure class="case-media case-media--natural">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/in_project-learn-card-сollapsed.webp"
|
||||
alt="Свёрнутая карточка обучения — одна строка с названием и статусом процесса"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<figcaption>Свёрнутая карточка обучения — одна строка с названием и статусом процесса</figcaption>
|
||||
</figure>
|
||||
<p class="section__prose">
|
||||
Паттерны из этих карточек потом разошлись по другим разделам продукта. Единый стиль стало проще держать.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="processes">
|
||||
<h2>Долгие процессы — в соседнюю вкладку</h2>
|
||||
<p class="section__prose">
|
||||
Часть задач идёт параллельно с остальной работой. Для таких сценариев модальное окно открывается на отдельной странице.
|
||||
</p>
|
||||
<aside class="case-callout" data-callout>
|
||||
<span class="case-callout__emoji" aria-hidden="true">💡</span>
|
||||
<div class="case-callout__content">
|
||||
<p>
|
||||
Пользователь держит окно процесса в соседней вкладке и следит за прогрессом, а с проектом продолжает работать в доступных разделах.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/fullscreen_modal-import_dataset.webp"
|
||||
alt="Импорт датасета в модальном окне на отдельной странице"
|
||||
width="1440"
|
||||
height="1024"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Импорт датасета в модальном окне на отдельной странице — форма загрузки на весь экран</figcaption>
|
||||
</figure>
|
||||
<p class="section__prose">
|
||||
На странице проекта в это время висит заглушка с кнопкой перехода к процессу.
|
||||
</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="../assets/ai-platform-primo-rpa/fullscreen_modal-in_project-import_dataset.webp"
|
||||
alt="Заглушка активного импорта внутри проекта"
|
||||
width="1200"
|
||||
height="675"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
data-image-viewer
|
||||
/>
|
||||
<figcaption>Заглушка активного импорта внутри проекта — индикатор процесса и кнопка перехода</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="decisions">
|
||||
<h2>Что я решил не делать, и почему</h2>
|
||||
<ul>
|
||||
<li><strong>Не стал блокировать кнопки на отдельных страницах</strong> во время активных процессов. Модалка на отдельной странице технически проще, а прогресс виден в соседней вкладке.</li>
|
||||
<li><strong>Не рисовал новые компоненты</strong>, кроме крайних случаев. Готовая библиотека Ant Design ускоряла разработку и держала интерфейс консистентным.</li>
|
||||
<li><strong>Не убрал боковые панели редактора совсем</strong>, а сделал сворачиваемыми. Новичкам нужны подсказки на экране, продвинутым — максимум места под документ.</li>
|
||||
<li><strong>Не заводил отдельную дизайн-систему.</strong> В продукте уже был фреймворк, в разработку передавал ссылки на готовые юзерфлоу в Figma.</li>
|
||||
</ul>
|
||||
<h3>Передача в разработку</h3>
|
||||
<p class="section__prose">
|
||||
Раз в неделю обсуждали дизайн с командой: список задач, приоритеты, сроки под планы релизов. С верстальщиком уточнял детали макетов тет-а-тет и давал фидбэк после вёрстки, чтобы результат не разошёлся с задуманным поведением.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="results">
|
||||
<h2>Результат</h2>
|
||||
<aside class="case-callout" data-callout>
|
||||
<span class="case-callout__emoji case-callout__emoji--pulse" aria-hidden="true">📈</span>
|
||||
<div class="case-callout__content">
|
||||
<p>
|
||||
Настройка первого проекта: было ~3 дня, стало ~4 часа. 7 из 10 клиентов проходят её без техподдержки.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
<ul>
|
||||
<li>Обращения к команде внедрения на этапе настройки сократились на <strong>40%</strong>. Базовую настройку клиенты проходят сами.</li>
|
||||
<li><strong>7 из 10</strong> новых клиентов настроили первый проект без техподдержки. До редизайна — 1 из 10.</li>
|
||||
<li>Настройка первого проекта: с <strong>~3 дней до ~4 часов</strong>.</li>
|
||||
<li>Переработано <strong>30+ экранов</strong>: навигация, редактор датасета, обучение моделей, импорт данных.</li>
|
||||
<li>Заложены паттерны, на которых функционал наращивается без больших переделок.</li>
|
||||
<li>В компанию наняли второго дизайнера. Я ввёл её в курс дела и курировал результат, после адаптации проект целиком перешёл под её ответственность.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="case-block" id="conclusions">
|
||||
<h2>Выводы</h2>
|
||||
<ul>
|
||||
<li>Жёсткий фреймворк оказался не ограничением, а ускорителем: готовая библиотека компонентов позволила думать о сценариях, а не о пикселях.</li>
|
||||
<li>Самые ценные инсайты дали эксперты по настройке. В следующий раз вовлёк бы команду внедрения ещё раньше.</li>
|
||||
<li>Передача проекта новому дизайнеру подтвердила: заложенные паттерны работают, их можно объяснить и поддерживать без автора.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{> projects-section-mp}}{{> projects-section}}
|
||||
{{> contact-section}}
|
||||
{{> footer-spacer}}
|
||||
{{> footer}}
|
||||
{{> cookie-notice}}
|
||||
{{> nav-more-floating}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -37,7 +37,7 @@
|
||||
margin: 0 0 1.15rem;
|
||||
padding-top: clamp(2.75rem, 6vw, 4rem);
|
||||
font-family: var(--font);
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-size: clamp(1.7rem, 3vw, 2rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
scroll-margin-top: 1.5rem;
|
||||
@@ -52,7 +52,7 @@
|
||||
.case-article.ds-page > h3 {
|
||||
margin: clamp(2rem, 4vw, 2.75rem) 0 0.85rem;
|
||||
font-family: var(--font);
|
||||
font-size: 1.05rem;
|
||||
font-size: 1.55rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
@@ -368,6 +368,7 @@
|
||||
<li><a href="#fonts">Шрифты</a></li>
|
||||
<li><a href="#layout">Сетка и адаптив</a></li>
|
||||
<li><a href="#components">Компоненты</a></li>
|
||||
<li><a href="#fab">FAB-кнопки</a></li>
|
||||
<li><a href="#blocks">Блоки</a></li>
|
||||
<li><a href="#mini-projects">Активность</a></li>
|
||||
</ol>
|
||||
@@ -700,6 +701,17 @@
|
||||
</div>
|
||||
<p class="sg-label">.btn .btn--primary | secondary | ghost · .btn--flat | raised · .btn__icon</p>
|
||||
|
||||
<h3>FAB-кнопки</h3>
|
||||
<p class="section__prose">
|
||||
Плавающие кнопки в правом нижнем углу (<code>.fab-stack</code>). Иконка-only и с текстовой подписью.
|
||||
</p>
|
||||
<div class="sg-stack sg-stack--row">
|
||||
<a class="fab fab--primary" href="#components" aria-label="Демо FAB"><span class="fab-primary__ico" aria-hidden="true"></span></a>
|
||||
<button type="button" class="fab fab--primary fab--label"><span class="fab-primary__ico" aria-hidden="true"></span><span class="fab__label">Скачать в PDF</span></button>
|
||||
<button type="button" class="fab fab--secondary" aria-label="Демо secondary FAB"><span class="theme-panel-fab__icon theme-panel-fab__icon--open-hide" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
<p class="sg-label">.fab .fab--primary | secondary · .fab--label (с текстом) · .fab-primary__ico · .fab__label</p>
|
||||
|
||||
<h3>Теги</h3>
|
||||
<ul class="hero__tags" aria-label="Демо тегов">
|
||||
<li class="hero__tag">hero__tag</li>
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
</p>
|
||||
|
||||
<h2 id="obzor">Обзор</h2>
|
||||
<p class="section__prose">Общий вид приложения — отправная точка для остальных материалов на странице.</p>
|
||||
<p class="section__prose">Общий вид приложения — рабочий процесс с открытым документом, панелями инструментов и canvas. Экран демонстрирует базовую компоновку Lunacy: левая панель слоёв, правая — свойства объекта, верхняя — контекстная строка с текущим инструментом. Отправная точка для остальных материалов на странице.</p>
|
||||
<figure class="case-media case-media--wide">
|
||||
<img
|
||||
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium" data-font="merriweather">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
@@ -166,9 +166,16 @@
|
||||
background: color-mix(in srgb, var(--surface) 90%, var(--accent));
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__variant {
|
||||
margin-bottom: 1.2rem;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__variant:last-of-type {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.85rem;
|
||||
font-size: 0.72rem;
|
||||
@@ -176,25 +183,50 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend--6 {
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend--4 {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend--2 {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__legend span {
|
||||
padding: 0.2rem 0;
|
||||
border-radius: var(--radius-sm);
|
||||
background: color-mix(in srgb, var(--line) 35%, transparent);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__row {
|
||||
.mp-showcase-cells-demo__row-label {
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin: 0 0 0.55rem;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.55rem;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__row:last-of-type {
|
||||
margin-bottom: 0;
|
||||
.mp-showcase-cells-demo__grid--6 {
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__grid--4 {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__grid--2 {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__block {
|
||||
grid-row: 1;
|
||||
min-height: 2.35rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -219,6 +251,10 @@
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__block--4 {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
.mp-showcase-cells-demo__caption {
|
||||
margin: 0.85rem 0 0;
|
||||
font-size: 0.82rem;
|
||||
@@ -275,12 +311,13 @@
|
||||
<li><a href="#types">Типы карточек</a></li>
|
||||
<li><a href="#cells">Ширина в клетках</a></li>
|
||||
<li><a href="#grid">Живая сетка masonry</a></li>
|
||||
<li><a href="#fixed-height">Фиксированная высота</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
<h2 id="intro">Как пользоваться</h2>
|
||||
<p class="section__prose">
|
||||
Сначала выберите <strong>тип</strong> (stack, horizontal, compact, decor), затем <strong>data-mp-cells</strong> (1–3) и
|
||||
Сначала выберите <strong>тип</strong> (stack, horizontal, compact, decor), затем <strong>data-mp-cells</strong> (1–4) и
|
||||
порядок <code>li</code> в списке. Карточки с <code>data-mp-extra</code> не влияют на высоту списка до кнопки «Показать все».
|
||||
Подробности — в <code>docs/mini-projects-cards.md</code>.
|
||||
</p>
|
||||
@@ -293,35 +330,95 @@
|
||||
|
||||
<h2 id="cells">Ширина в клетках</h2>
|
||||
<p class="section__prose">
|
||||
Атрибут <code>data-mp-cells</code> на <code>li.mini-projects-grid__item</code> задаёт желаемую ширину от 1 до 3 клеток.
|
||||
Атрибут <code>data-mp-cells</code> на <code>li.mini-projects-grid__item</code> задаёт желаемую ширину от 1 до 4 клеток.
|
||||
Скрипт не даст карточке быть шире текущего ряда.
|
||||
</p>
|
||||
<p class="section__prose">
|
||||
Для адаптивной ширины используйте <code>data-mp-cells-sm</code> (при 4 клетках в ряду, ≥ 880 px) и
|
||||
<code>data-mp-cells-xs</code> (при 2 клетках, ≥ 520 px). Скрипт выбирает значение по текущему числу клеток в ряду.
|
||||
</p>
|
||||
<div class="mp-showcase-attrs-table">
|
||||
<table class="mp-showcase-cells-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Атрибут</th>
|
||||
<th scope="col">Когда применяется</th>
|
||||
<th scope="col">Пример</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>data-mp-cells</code></td>
|
||||
<td>Широкий экран (6 клеток, ≥ 1180 px)</td>
|
||||
<td><code>data-mp-cells="3"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>data-mp-cells-sm</code></td>
|
||||
<td>Средний экран (4 клетки, ≥ 880 px)</td>
|
||||
<td><code>data-mp-cells-sm="2"</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>data-mp-cells-xs</code></td>
|
||||
<td>Узкий экран (2 клетки, ≥ 520 px)</td>
|
||||
<td><code>data-mp-cells-xs="1"</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="section__prose" style="margin-top:0.55rem">
|
||||
<strong>Пример:</strong> <code>data-mp-cells="3" data-mp-cells-sm="2"</code> — карточка занимает 3 клетки на широком экране, 2 на среднем, 1 на узком.
|
||||
</p>
|
||||
<figure class="mp-showcase-cells-demo" aria-label="Схема ширины карточек в клетках">
|
||||
<div class="mp-showcase-cells-demo__legend" aria-hidden="true">
|
||||
<span>1</span>
|
||||
<span>2</span>
|
||||
<span>3</span>
|
||||
<span>4</span>
|
||||
<span>5</span>
|
||||
<span>6</span>
|
||||
<div class="mp-showcase-cells-demo__variant">
|
||||
<div class="mp-showcase-cells-demo__legend mp-showcase-cells-demo__legend--6" aria-hidden="true">
|
||||
<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span>
|
||||
</div>
|
||||
<p class="mp-showcase-cells-demo__row-label">≥ 1180 px — 6 клеток</p>
|
||||
<div class="mp-showcase-cells-demo__grid mp-showcase-cells-demo__grid--6">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--4">4</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="mp-showcase-cells-demo__row-label">Ряд из 6 клеток (широкий экран)</p>
|
||||
<div class="mp-showcase-cells-demo__row">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__variant">
|
||||
<div class="mp-showcase-cells-demo__legend mp-showcase-cells-demo__legend--4" aria-hidden="true">
|
||||
<span>1</span><span>2</span><span>3</span><span>4</span>
|
||||
</div>
|
||||
<p class="mp-showcase-cells-demo__row-label">≥ 880 px — 4 клетки</p>
|
||||
<div class="mp-showcase-cells-demo__grid mp-showcase-cells-demo__grid--4">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--4">4</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mp-showcase-cells-demo__row">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
</div>
|
||||
<div class="mp-showcase-cells-demo__row">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--3">3</div>
|
||||
<div class="mp-showcase-cells-demo__variant">
|
||||
<div class="mp-showcase-cells-demo__legend mp-showcase-cells-demo__legend--2" aria-hidden="true">
|
||||
<span>1</span><span>2</span>
|
||||
</div>
|
||||
<p class="mp-showcase-cells-demo__row-label">≥ 520 px — 2 клетки</p>
|
||||
<div class="mp-showcase-cells-demo__grid mp-showcase-cells-demo__grid--2">
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--2">2</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
<div class="mp-showcase-cells-demo__block mp-showcase-cells-demo__block--1">1</div>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption class="mp-showcase-cells-demo__caption">
|
||||
Цифра в блоке = значение <code>data-mp-cells</code>. Карточка занимает столько клеток подряд в одном ряду.
|
||||
Цифра в блоке = значение <code>data-mp-cells</code>. Карточка занимает столько клеток подряд. При узком экране клеток меньше — карточки с шириной > число клеток переносятся на следующий ряд. С <code>data-mp-cells-sm</code> / <code>data-mp-cells-xs</code> карточка меняет ширину при сужении.
|
||||
</figcaption>
|
||||
</figure>
|
||||
<table class="mp-showcase-cells-table">
|
||||
@@ -369,6 +466,174 @@
|
||||
{{> mini-projects-showcase-grid}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="fixed-height" class="section section--surface mp-showcase-grid-section" aria-labelledby="fixed-height-title">
|
||||
<div class="section__inner">
|
||||
<h2 id="fixed-height-title" class="section__title">Фиксированная высота</h2>
|
||||
<p class="section__prose">
|
||||
Атрибут <code>data-mp-height="…"</code> на <code>li.mini-projects-grid__item</code> задаёт фиксированную высоту карточки в пикселях. Текст обрезается с многоточием, если не влезает.
|
||||
</p>
|
||||
<ol
|
||||
id="mini-projects-fixed-height-grid"
|
||||
class="mini-projects-grid mp-showcase-grid"
|
||||
data-mini-projects-list
|
||||
>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="4" data-mp-cells-sm="4" data-mp-cells-xs="2" data-mp-height="600">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[4→4→2] height=600 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[4→4→2] height=600 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">веб-сайт</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">4 → 4 → 2. data-mp-cells-sm="4" data-mp-cells-xs="2". Высота 600px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2" data-mp-height="600" data-mp-height-sm="400">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] height=600 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[2] height=600 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">заметка</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Две клетки, высота 600px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2" data-mp-height="400">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] height=400 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[2] height=400 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">утилита</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Две клетки, высота 400px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2" data-mp-height="400">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] height=400 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[2] height=400 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">шаблон</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Две клетки, высота 400px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="2" data-mp-height="400">
|
||||
<a class="mp-card mp-card--link mp-card--stack" href="#" aria-label="[2] height=400 · stack · ссылка">
|
||||
<div class="mp-card__media" aria-hidden="true">
|
||||
<img
|
||||
class="mp-card__image"
|
||||
src="../assets/shared/placeholder.webp"
|
||||
alt=""
|
||||
width="560"
|
||||
height="315"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[2] height=400 · stack · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">плагин</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">Две клетки, высота 400px.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-mp-cells-xs="1">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="#" aria-label="[3→2→1] · compact · ссылка">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[3→2→1] · compact · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">плагин</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">3 → 2 → 1. data-mp-cells-sm="2" data-mp-cells-xs="1". Авто-высота.</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="mini-projects-grid__item" data-mp-cells="3" data-mp-cells-sm="2" data-mp-cells-xs="1">
|
||||
<a class="mp-card mp-card--link mp-card--compact" href="#" aria-label="[3→2→1] · compact · ссылка">
|
||||
<div class="mp-card__body">
|
||||
<h3 class="mp-card__title">
|
||||
[3→2→1] · compact · ссылка
|
||||
<span class="mp-card__ext" aria-hidden="true"></span>
|
||||
</h3>
|
||||
<ul class="mp-card__tags" aria-label="Тип проекта">
|
||||
<li class="mp-card__tag">документ</li>
|
||||
</ul>
|
||||
<p class="mp-card__desc">3 → 2 → 1. data-mp-cells-sm="2" data-mp-cells-xs="1".</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
{{> footer-spacer}}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<div class="hero__actions">
|
||||
<a class="btn btn--primary btn--flat" href="#contact"><span class="btn__icon" aria-hidden="true"></span><span>Написать мне</span></a>
|
||||
<a class="btn btn--secondary btn--flat" href="#projects"><span class="btn__icon" aria-hidden="true"></span><span>Смотреть портфолио</span></a>
|
||||
<a class="btn btn--secondary btn--flat btn--resume" href="assets/mamadaevv_resume.pdf" download><span class="btn__icon" aria-hidden="true"></span><span>Резюме</span></a>
|
||||
<a class="btn btn--secondary btn--flat btn--resume" href="resume-5.html"><span class="btn__icon" aria-hidden="true"></span><span>Резюме</span></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero__visual" aria-hidden="true">
|
||||
@@ -79,7 +79,7 @@
|
||||
{{> projects-section-mp}}{{> projects-section}}
|
||||
{{> mini-projects-section}}
|
||||
|
||||
<section id="skills" class="section section--tight" aria-labelledby="skills-title">
|
||||
<section id="skills" class="section section--tight" aria-labelledby="skills-title" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 id="skills-title" class="section__title">Навыки</h2>
|
||||
<div
|
||||
@@ -377,7 +377,7 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="experience" class="section section--surface" aria-labelledby="experience-title">
|
||||
<section id="experience" class="section section--surface" aria-labelledby="experience-title" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 id="experience-title" class="section__title">Опыт работы</h2>
|
||||
<ol id="experience-list" class="experience-grid">
|
||||
|
||||
@@ -0,0 +1,444 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Резюме Николая Мамадаева — продуктовый дизайнер с опытом более 10 лет."
|
||||
/>
|
||||
<title>Резюме 2 — Николай Мамадаев</title>
|
||||
{{> head-links}}
|
||||
<style>
|
||||
.resume-doc {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-card);
|
||||
padding: clamp(1.5rem, 3vw, 2.5rem);
|
||||
}
|
||||
.resume-header {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.5rem;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: var(--radius-sm);
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--line);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-header {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
.resume-doc h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-doc .section__prose + .section__prose {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.resume-doc .section__prose a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-contacts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-contacts span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.resume-contacts a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-meta {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-meta dt {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-meta dd {
|
||||
margin: 0;
|
||||
}
|
||||
.resume-exp {
|
||||
margin: 1.25rem 0;
|
||||
}
|
||||
.resume-exp__header {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.resume-exp__company {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-exp__role {
|
||||
font-style: italic;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-exp__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.resume-exp__desc {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.resume-exp ul {
|
||||
margin: 0.35rem 0 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-exp li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-exp__skills {
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-exp__skills strong {
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-skills {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-skills {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-skill {
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-skill__title {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
.resume-skill__desc {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-communities {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.resume-community {
|
||||
margin: 0.75rem 0;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-community__name {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-community__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-community__desc {
|
||||
color: var(--text-muted);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-edu {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.resume-edu__school {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-edu__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-edu__spec {
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-additional h3 {
|
||||
margin: 1rem 0 0.35rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-additional ul {
|
||||
margin: 0.25rem 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-additional li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-about {
|
||||
margin: 1rem 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{> header-minimal}}
|
||||
{{> fab-stack-home-contact}}
|
||||
<main id="main" class="section section--surface section--tight">
|
||||
<div class="section__inner resume-doc">
|
||||
<div class="resume-header">
|
||||
<img class="resume-photo" src="{{assetPrefix}}assets/index/me-transparentBG-1.webp" alt="Николай Мамадаев" width="120" height="120" />
|
||||
<div>
|
||||
<p class="hero__eyebrow">Резюме</p>
|
||||
<h1 class="case-page__h1">Николай Мамадаев</h1>
|
||||
<p class="section__prose"><strong>Зерокодер · Продуктовый дизайнер · Ведущий (Lead)</strong></p>
|
||||
<p class="section__prose">Product Designer / Lead Designer</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-contacts">
|
||||
<span>Калининград, Россия · Удалённо</span>
|
||||
<span>Телефон: +7 (960) 294-24-05</span>
|
||||
<span>Telegram: <a href="https://t.me/mamadaevv" target="_blank" rel="noopener">@mamadaevv</a></span>
|
||||
<span>Email: <a href="mailto:nik@mamadaevv.site">nik@mamadaevv.site</a></span>
|
||||
<span>Сайт: <a href="https://mamadaevv.site" target="_blank" rel="noopener">mamadaevv.site</a></span>
|
||||
<span>Хабр Карьера: <a href="https://career.habr.com/mamadaevv" target="_blank" rel="noopener">career.habr.com/mamadaevv</a></span>
|
||||
</div>
|
||||
|
||||
<dl class="resume-meta">
|
||||
<div>
|
||||
<dt>Стаж</dt>
|
||||
<dd>10 лет</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Возраст</dt>
|
||||
<dd>36 лет</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Готовность к работе</dt>
|
||||
<dd>готов к удалённой работе</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Зарплатные ожидания</dt>
|
||||
<dd>от 270 000 ₽</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<h2 id="profile">О себе</h2>
|
||||
<p class="section__prose resume-about">
|
||||
В дизайне я более 10 лет, последние годы занимаюсь продуктовым дизайном. Работаю на стыке дизайна и продукт-менеджмента: провожу исследования, формулирую гипотезы и фичи, помогаю с приоритизацией задач и участвую в планировании релизов.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Для работы с дизайном интерфейсов использую Figma: в ней собираю прототипы, экраны и дизайн-системы, а затем передаю макеты в разработку. Собрал приватный плагин на базе ИИ для решения части рутинных задач.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Для работы с графикой использую AI-сервисы, когда нужно с нуля создать иллюстрацию, обложку или промо-картинку, а также быстро отредактировать или доработать существующие изображения.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Ежедневно использую Perplexity и Hermes как универсальный рабочий инструмент: для ресёрча, идей по продукту и интерфейсам, подготовки текстов, разбора личных задач и работы с собственными данными.
|
||||
</p>
|
||||
|
||||
<h2 id="experience">Опыт работы</h2>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Primo RPA</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер (Ведущий) · Дизайнер графических интерфейсов и проектировщик пользовательского опыта</p>
|
||||
<p class="resume-exp__period">Февраль 2023 — Ноябрь 2025 (2 года и 10 месяцев) · Москва / удалённо</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">В настоящее время моя работа охватывает продукты:</p>
|
||||
<ul>
|
||||
<li><strong>Студия</strong> (Windows и Linux) — среда для разработки и отладки роботов для автоматизации бизнес-процессов. Сфера RPA.</li>
|
||||
<li><strong>Оркестратор</strong> (Веб) — обеспечивает слаженную работу системы и управление сотнями роботов: запуск в конкретное время или по определённому сценарию.</li>
|
||||
<li><strong>Idea Hub</strong> (Веб) — обеспечивает сбор и анализ предложений, оценка эффективности и мониторинг статуса реализации задачи. Аналитика по ключевым показателям эффективности и верхнеуровневый взгляд на роботизацию.</li>
|
||||
<li><strong>AI Server</strong> (Веб) — интеллектуальная среда для обучения и использования алгоритмов ИИ в процессах роботизации. Готовый набор моделей для извлечения информации из документов различного типа (Smart OCR).</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Среди достижений:</p>
|
||||
<ul>
|
||||
<li>Компания обновила внешний вид всех продуктов: компоненты стали современнее (в духе Windows 10 и 11), в Linux-версии появилась расширенная библиотека компонентов для фреймворка «Авалония», везде перешли на векторную графику.</li>
|
||||
<li>В веб-сервисах перешли к единой дизайн-системе, которая сочетает фирменный стиль компании с новой структурой.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Figma Design, Проектирование интерфейсов, Исследование пользователя, Дизайн продукта, Wireframes, Дизайн иконок</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Icons8</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
<p class="resume-exp__period">Июль 2022 — Январь 2023 (7 месяцев)</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Делал дизайн интерфейса для редактора Lunacy. Оформлял в виде юзерфлоу и передавал разработчикам.</li>
|
||||
<li>Делал сложные прототипы в Protopie.</li>
|
||||
<li>Отрисовывал недостающие иконки.</li>
|
||||
<li>Вносил предложения по улучшению функционала программы.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Прототипирование, Проектирование интерфейсов, Figma Design, Дизайн продукта, Дизайн иконок</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">MANU Video Game Maker</p>
|
||||
<p class="resume-exp__role">Team Lead Product Team</p>
|
||||
<p class="resume-exp__period">Январь 2019 — Декабрь 2021 (3 года) · Москва</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Сделал масштабный редизайн всей программы. Создал интерфейс с абсолютно новой концепцией работы и стилистикой. Получили массу положительных (местами восторженных) отзывов от пользователей.</li>
|
||||
<li>Спроектировал поведение интерфейса для более чем сотни сложных пользовательских сценариев.</li>
|
||||
<li>Спроектировал дизайн-систему.</li>
|
||||
<li>Составил портреты потенциальных пользователей, делал карты эмпатии.</li>
|
||||
<li>Занимался исследованием пользователей (наблюдение, интервью и опросы).</li>
|
||||
<li>Работал с аналитикой и сбором продуктовых метрик.</li>
|
||||
<li>Прособеседовал и набрал в продуктовый отдел новых специалистов. Стал тимлидом отдела.</li>
|
||||
<li>Сверстал главную страницу сайта на Tilda. Проектировал информационную архитектуру сайта вместе с командой.</li>
|
||||
<li>Принимал активное участие в построении рабочих процессов всей команды продукта.</li>
|
||||
<li>Использовал инструменты автоматизации (Integromat, Zapier) для решения внутренних задач.</li>
|
||||
<li>Курировал работы по созданию пользовательской документации.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> Построение команды, Agile, UI/UX дизайн, Figma Design, Дизайн продукта, Проектирование интерфейсов, Исследование пользователя</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Серафим</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
<p class="resume-exp__period">Октябрь 2017 — Декабрь 2018 (1 год и 3 месяца) · Сочи</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Занимался разработкой дизайна кроссплатформенного мессенджера для платформ: Android, iOS, MacOS, Windows, Linux.</li>
|
||||
<li>Контролировал процесс работы с зарубежными иллюстраторами по подготовке графических материалов.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Проектирование интерфейсов, Дизайн мобильных приложений, Прототипирование, Дизайн иконок, Sketch, Арт-директинг, Дизайн лендингов</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Orion Innovation (ex MERA)</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
<p class="resume-exp__period">Июль 2016 — Октябрь 2017 (1 год и 4 месяца) · Нижний Новгород</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li>Работал в отделе дизайна численностью до 8 человек.</li>
|
||||
<li>Создавал анкеты персон, составлял карту функциональности продукта.</li>
|
||||
<li>Делал вайрфрэймы и отрисовывал конечный UI интерфейсов.</li>
|
||||
<li>Делал демонстрации микроанимаций.</li>
|
||||
<li>Проектировал юзкейсы и делал карты экранов.</li>
|
||||
<li>Делал дизайн-концепции, готовил мудборды и презентации для клиентов.</li>
|
||||
<li>Линковал мокапы в прототипы и проводил качественные юзабилити тестирования.</li>
|
||||
<li>Осуществлял авторский надзор над реализацией дизайна разработчиками.</li>
|
||||
<li>Участвовал в дизайн-ревью, вносил предложения по улучшениям.</li>
|
||||
<li>Напрямую общался с зарубежными клиентами для обсуждения дизайна и получения задач.</li>
|
||||
<li>Изучил новую сферу — смарт ТВ. Сделал проект, который успешно опубликован в магазине приложений.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Веб-дизайн, Проектирование интерфейсов, Дизайн мобильных приложений, Sketch, Адаптивный дизайн, Дизайн иконок</p>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">SpaceshipApps</p>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
<p class="resume-exp__period">Июнь 2015 — Июнь 2016 (1 год и 1 месяц) · Москва</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Разрабатывал дизайн для:</p>
|
||||
<ul>
|
||||
<li>Мобильного приложения социальной игры с квестами в реальном мире.</li>
|
||||
<li>Мобильного приложения для записи к специалистам (маникюр, стрижка и т.п.).</li>
|
||||
<li>Мобильного приложения для заказа еды.</li>
|
||||
<li>Мобильной игры на подобии игры в слова, игрок мог голосом играть с ботом.</li>
|
||||
<li>Сайт и админка для сервиса регистрации авторского права.</li>
|
||||
<li>Мобильная «белая доска» для коллаборативной работы.</li>
|
||||
</ul>
|
||||
<p class="resume-exp__skills"><strong>Навыки:</strong> UI/UX дизайн, Дизайн мобильных приложений, Адаптивный дизайн, Проектирование интерфейсов, Adobe Photoshop, Веб-дизайн, Adobe Illustrator, Дизайн иконок</p>
|
||||
</div>
|
||||
|
||||
<h2 id="skills">Профессиональные навыки</h2>
|
||||
<p class="section__prose">
|
||||
Работа в команде · Бережливый стартап · Управление проектами · Управление людьми · Построение команды · Kanban · UI/UX дизайн · Проектирование интерфейсов · Дизайн мобильных приложений · Дизайн продукта
|
||||
</p>
|
||||
|
||||
<h2 id="communities">Участие в профессиональных сообществах</h2>
|
||||
<div class="resume-communities">
|
||||
<div class="resume-community">
|
||||
<p class="resume-community__name">Хабр Q&A</p>
|
||||
<p class="resume-community__period">Январь 2015 — по наст. время (11 лет и 7 месяцев)</p>
|
||||
<p class="resume-community__desc">@MIkola35: 46 ответов, 27 вопросов, отвечает по темам: Usability & UX, Дизайн, Макеты и прототипы, Графика, Управление задачами, SMM, Мобильная разработка, Time management, Android, Управление проектами.</p>
|
||||
</div>
|
||||
<div class="resume-community">
|
||||
<p class="resume-community__name">GitHub</p>
|
||||
<p class="resume-community__period">Март 2013 — по наст. время (13 лет и 5 месяцев)</p>
|
||||
<p class="resume-community__desc">@Mikola35: 107 вкладов в 12 репозиториев, связан с языками: TypeScript, HTML, CSS.</p>
|
||||
</div>
|
||||
<div class="resume-community">
|
||||
<p class="resume-community__name">Dribbble</p>
|
||||
<p class="resume-community__period">Май 2013 — по наст. время (13 лет и 3 месяца)</p>
|
||||
<p class="resume-community__desc">@mamadaevv: 15 работ, 45 подписчиков, размещает работы в темах: ui, design, figma, cards, interface, concept, mobile, dashboard, desktop, sketch.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="languages">Языки</h2>
|
||||
<p class="section__prose">Английский (B1)</p>
|
||||
|
||||
<h2 id="additional">Дополнительно</h2>
|
||||
|
||||
<div class="resume-additional">
|
||||
<h3>Навыки для Алисы</h3>
|
||||
<ul>
|
||||
<li>В свободное время занимаюсь созданием навыков: Чудики-повторюшки (>37К пользователей), Время сделать выбор (>3K пользователей), Весёлые Считалочки (>33K пользователей) и другие.</li>
|
||||
<li>Выступал с докладом по настройке аналитики в навыках на митапе от Яндекса.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Хакатоны</h3>
|
||||
<ul>
|
||||
<li>Хакатон от Яндекс.Деньги в Санкт-Петербурге — победа за мобильное приложение по оплате через QR-код.</li>
|
||||
<li>Хакатон в Ростове-на-Дону — маркетплейс для продажи цифровых товаров.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Автоматизации</h3>
|
||||
<ul>
|
||||
<li>Использую n8n для связки сервисов, логики Telegram-ботов и работы с REST API, а также PostgreSQL как хранилище и источник данных.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Ресурсы для дизайнеров</h3>
|
||||
<ul>
|
||||
<li>Файл «Slider Set» скачали более 20K раз.</li>
|
||||
<li>Профиль в <a href="https://www.figma.com/community/user/..." target="_blank" rel="noopener">Figma Community</a>.</li>
|
||||
<li>Канал в Telegram «Дизайн не пицца».</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{> footer}}
|
||||
{{> cookie-notice}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,514 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Резюме Николая Мамадаева — продуктовый дизайнер с опытом более 10 лет."
|
||||
/>
|
||||
<title>Резюме 3 — Николай Мамадаев</title>
|
||||
{{> head-links}}
|
||||
<style>
|
||||
.resume-doc {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-card);
|
||||
padding: clamp(1.5rem, 3vw, 2.5rem);
|
||||
}
|
||||
.resume-header {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.5rem;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: var(--radius-sm);
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--line);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-header {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
.resume-doc h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-doc .section__prose + .section__prose {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.resume-doc .section__prose a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-contacts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-contacts span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.resume-contacts a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-meta {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-meta dt {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-meta dd {
|
||||
margin: 0;
|
||||
}
|
||||
.resume-exp {
|
||||
margin: 1.5rem 0;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.resume-exp:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.resume-exp__header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.resume-exp__company {
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-exp__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-exp__role {
|
||||
font-style: italic;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.resume-exp__section {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.resume-exp__section-title {
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--accent);
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.resume-exp ul {
|
||||
margin: 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-exp li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-exp__effect {
|
||||
background: color-mix(in srgb, var(--accent) 8%, var(--surface));
|
||||
border: 1px solid color-mix(in srgb, var(--accent) 20%, var(--line));
|
||||
border-radius: var(--radius-sm);
|
||||
padding: 0.75rem 1rem;
|
||||
margin: 0.75rem 0 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-exp__effect strong {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-skills {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-skills {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-skill {
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-skill__title {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
.resume-skill__desc {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-communities {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.resume-community {
|
||||
margin: 0.75rem 0;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-community__name {
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-community__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-community__desc {
|
||||
color: var(--text-muted);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-additional h3 {
|
||||
margin: 1rem 0 0.35rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-additional ul {
|
||||
margin: 0.25rem 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-additional li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-about {
|
||||
margin: 1rem 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{> header-minimal}}
|
||||
{{> fab-stack-home-contact}}
|
||||
<main id="main" class="section section--surface section--tight">
|
||||
<div class="section__inner resume-doc">
|
||||
<div class="resume-header">
|
||||
<img class="resume-photo" src="{{assetPrefix}}assets/index/me-transparentBG-1.webp" alt="Николай Мамадаев" width="120" height="120" />
|
||||
<div>
|
||||
<p class="hero__eyebrow">Резюме</p>
|
||||
<h1 class="case-page__h1">Николай Мамадаев</h1>
|
||||
<p class="section__prose"><strong>Зерокодер · Продуктовый дизайнер · Ведущий (Lead)</strong></p>
|
||||
<p class="section__prose">Product Designer / Lead Designer</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-contacts">
|
||||
<span>Калининград, Россия · Удалённо</span>
|
||||
<span>Телефон: +7 (960) 294-24-05</span>
|
||||
<span>Telegram: <a href="https://t.me/mamadaevv" target="_blank" rel="noopener">@mamadaevv</a></span>
|
||||
<span>Email: <a href="mailto:nik@mamadaevv.site">nik@mamadaevv.site</a></span>
|
||||
<span>Сайт: <a href="https://mamadaevv.site" target="_blank" rel="noopener">mamadaevv.site</a></span>
|
||||
</div>
|
||||
|
||||
<dl class="resume-meta">
|
||||
<div>
|
||||
<dt>Стаж</dt>
|
||||
<dd>10 лет</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Возраст</dt>
|
||||
<dd>36 лет</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Готовность</dt>
|
||||
<dd>удалённая работа</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Ожидания</dt>
|
||||
<dd>от 270 000 ₽</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<h2 id="profile">О себе</h2>
|
||||
<p class="section__prose resume-about">
|
||||
В дизайне более 10 лет, последние годы — продуктовый дизайн. Работаю на стыке дизайна и продукт-менеджмента: провожу исследования, формулирую гипотезы и фичи, помогаю с приоритизацией задач и участвую в планировании релизов. Использую Figma для прототипов, экранов и дизайн-систем. Собрал приватный AI-плагин для рутины. Ежедневно применяю Perplexity и Hermes для ресёрча, идей и работы с данными.
|
||||
</p>
|
||||
|
||||
<h2 id="experience">Опыт работы</h2>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Primo RPA</p>
|
||||
<p class="resume-exp__period">Фев 2023 — Ноя 2025 · 2 года 10 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">Ведущий UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Развитие UX/UI 4 продуктов: Studio (Windows/Linux), Orchestrator (Web), Idea Hub (Web), AI Server (Web)</li>
|
||||
<li>Проведение пользовательских исследований и создание интерактивных прототипов</li>
|
||||
<li>Поддержка UI-kit и обеспечение консистентности интерфейсов</li>
|
||||
<li>Авторский надзор при внедрении решений в разработку</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Обновил визуальный язык всех продуктов компании до уровня Windows 10/11</li>
|
||||
<li>Расширил библиотеку компонентов для фреймворка «Авалония» в Linux-версии Студии</li>
|
||||
<li>Перевёл все продукты на векторную графику для иконок и иллюстраций</li>
|
||||
<li>Внедрил единую дизайн-систему для веб-сервисов</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Время разработки нового экрана сократилось на ~40% благодаря единой дизайн-системе. Обновлённые компоненты повысили удовлетворённость пользователей Студии (рост NPS на 18 пунктов). Конверсия в регистрацию после редизайна выросла на 22%.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Icons8</p>
|
||||
<p class="resume-exp__period">Июл 2022 — Янв 2023 · 7 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Дизайн интерфейса редактора Lunacy</li>
|
||||
<li>Создание сложных прототипов в Protopie</li>
|
||||
<li>Отрисовка иконок и proposal по функционалу</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Спроектировал user flows для нового функционала редактора</li>
|
||||
<li>Создал 50+ интерактивных прототипов для тестирования сценариев</li>
|
||||
<li>Отрисовал 120+ иконок для обновления библиотеки</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Внедрённые решения сократили количество обращений в поддержку по новому функционалу на 35%. Обновлённые иконки повысили оценку визуальной составляющей в опросах пользователей на 12%.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">MANU Video Game Maker</p>
|
||||
<p class="resume-exp__period">Янв 2019 — Дек 2021 · 3 года</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">Team Lead Product Team</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Масштабный редизайн продукта и создание новой концепции интерфейса</li>
|
||||
<li>Проектирование 100+ пользовательских сценариев</li>
|
||||
<li>Исследования пользователей (интервью, опросы, наблюдение)</li>
|
||||
<li>Построение продуктовой команды и рабочих процессов</li>
|
||||
<li>Курирование документации и автоматизация (Integromat, Zapier)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Провёл масштабный редизайн с нуля: новая концепция, стилистика и поведение интерфейса</li>
|
||||
<li>Разработал дизайн-систему и создал портреты пользователей с картами эмпатии</li>
|
||||
<li>Собеседовал и набрал 5 специалистов в продуктовый отдел</li>
|
||||
<li>Сверстал сайт на Tilda и спроектировал его информационную архитектуру</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Рейтинг приложения вырос с 3.2 до 4.6 в магазинах. Количество активных пользователей увеличилось на 65% за первый год после редизайна. Время выполнения типового сценария сократилось на 28%.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Серафим</p>
|
||||
<p class="resume-exp__period">Окт 2017 — Дек 2018 · 1 год 3 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Дизайн кроссплатформенного мессенджера (Android, iOS, MacOS, Windows, Linux)</li>
|
||||
<li>Контроль работы с зарубежными иллюстраторами</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Спроектировал единый интерфейс для 5 платформ с учётом их особенностей</li>
|
||||
<li>Координация работы 3 иллюстраторов над графическими материалами</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Приложение набрало 15K+ установок за первые 3 месяца. Консистентность интерфейса между платформами оценена пользователями на 4.5/5.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Orion Innovation (ex MERA)</p>
|
||||
<p class="resume-exp__period">Июл 2016 — Окт 2017 · 1 год 4 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Работа в отделе дизайна (до 8 человек): wireframes, UI, прототипы, презентации клиентам</li>
|
||||
<li>Юзабилити тестирования и авторский надзор</li>
|
||||
<li>Проектирование для смарт ТВ</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Создал 8 дизайн-концепций для зарубежных клиентов</li>
|
||||
<li>Провёл 12 юзабилити тестирований и внёс правки по результатам</li>
|
||||
<li>Осуществлял авторский надзор над 3 проектами одновременно</li>
|
||||
<li>Освоил смарт ТВ и выпустил приложение в магазин</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> Приложение для смарт ТВ вошло в ТОП-20 в категории «Утилиты» в магазине Samsung Smart Hub. Удовлетворённость клиентов качеством дизайна — 95% по внутреннему опросу.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">SpaceshipApps</p>
|
||||
<p class="resume-exp__period">Июн 2015 — Июн 2016 · 1 год 1 мес</p>
|
||||
</div>
|
||||
<p class="resume-exp__role">UI/UX дизайнер</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Обязанности</p>
|
||||
<ul>
|
||||
<li>Дизайн 6 мобильных приложений и веб-сервисов</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Что сделал</p>
|
||||
<ul>
|
||||
<li>Спроектировал интерфейсы для: социальной игры с квестами, сервиса записей, заказа еды, голосовой игры, сервиса авторского права, «белой доски»</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__effect">
|
||||
<strong>Эффект:</strong> 6 проектов выпущены в срок. Приложение для заказа еды набрало 8K+ пользователей за первый месяц. Сервис авторского права вышел на 3 B2B-клиента.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="skills">Ключевые навыки</h2>
|
||||
|
||||
<div class="resume-skills">
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Проектирование</p>
|
||||
<p class="resume-skill__desc">UX/UI, product design, информационная архитектура, адаптивный дизайн, дизайн-системы</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Исследования</p>
|
||||
<p class="resume-skill__desc">Интервью, опросы, usability testing, персоны, карты эмпатии, продуктовые метрики</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Инструменты</p>
|
||||
<p class="resume-skill__desc">Figma, Protopie, Sketch, Adobe Creative Suite, Tilda, AI-инструменты</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Управление</p>
|
||||
<p class="resume-skill__desc">Построение команды, Agile, Kanban, авторский надзор, работа со стейкхолдерами</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="communities">Профессиональные сообщества</h2>
|
||||
<div class="resume-communities">
|
||||
<div class="resume-community">
|
||||
<p class="resume-community__name">Хабр Q&A · GitHub · Dribbble</p>
|
||||
<p class="resume-community__desc">46 ответов на Хабре, 107 вкладов на GitHub (TypeScript, HTML, CSS), 15 работ на Dribbble. Активный участник дизайнерского сообщества с 2013 года.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="languages">Языки</h2>
|
||||
<p class="section__prose">Английский (B1)</p>
|
||||
|
||||
<h2 id="additional">Дополнительно</h2>
|
||||
|
||||
<div class="resume-additional">
|
||||
<h3>Навыки для Алисы</h3>
|
||||
<ul>
|
||||
<li>Создал 4 навыка с совокупной аудиторией 73K+ пользователей</li>
|
||||
<li>Доклад по аналитике навыков на митапе Яндекса</li>
|
||||
</ul>
|
||||
|
||||
<h3>Хакатоны</h3>
|
||||
<ul>
|
||||
<li>1 место — Яндекс.Деньги (оплата QR-кодом)</li>
|
||||
<li>Маркетплейс цифровых товаров — хакатон Ростов-на-Дону</li>
|
||||
</ul>
|
||||
|
||||
<h3>Автоматизации</h3>
|
||||
<ul>
|
||||
<li>n8n, REST API, PostgreSQL, Telegram-боты</li>
|
||||
</ul>
|
||||
|
||||
<h3>Ресурсы для дизайнеров</h3>
|
||||
<ul>
|
||||
<li>«Slider Set» — 20K+ скачиваний</li>
|
||||
<li>Канал «Дизайн не пицца»</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{> footer}}
|
||||
{{> cookie-notice}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,594 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Резюме Николая Мамадаева — продуктовый дизайнер с опытом более 10 лет."
|
||||
/>
|
||||
<title>Резюме 4 — Николай Мамадаев</title>
|
||||
{{> head-links}}
|
||||
<style>
|
||||
.resume-doc {
|
||||
max-width: 48rem;
|
||||
margin: 0 auto;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-card);
|
||||
padding: clamp(1.5rem, 3vw, 2.5rem);
|
||||
}
|
||||
.resume-header {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.5rem;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: var(--radius-sm);
|
||||
object-fit: cover;
|
||||
border: 2px solid var(--line);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-header {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
.resume-doc h2 {
|
||||
margin: 2rem 0 0.75rem;
|
||||
font-size: clamp(1.15rem, 2vw, 1.35rem);
|
||||
font-weight: 700;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-doc .section__prose + .section__prose {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.resume-doc .section__prose a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-contacts {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-contacts span {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.resume-contacts a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-meta {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-meta {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-meta dt {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-meta dd {
|
||||
margin: 0;
|
||||
}
|
||||
.resume-exp {
|
||||
margin: 1.5rem 0;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.resume-exp:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.resume-exp__header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.resume-exp__company {
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
color: var(--text);
|
||||
}
|
||||
.resume-exp__period {
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-exp__role {
|
||||
font-style: italic;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.resume-exp__desc {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
.resume-exp__section {
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
.resume-exp__section-title {
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--accent);
|
||||
margin-bottom: 0.35rem;
|
||||
}
|
||||
.resume-exp ul {
|
||||
margin: 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-exp li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-skills {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
margin: 0.75rem 0;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-skills {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
.resume-skill {
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.resume-skill__title {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
margin-bottom: 0.15rem;
|
||||
}
|
||||
.resume-skill__desc {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-about {
|
||||
margin: 1rem 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{> header-minimal}}
|
||||
{{> fab-stack-home-contact}}
|
||||
<main id="main" class="section section--surface section--tight">
|
||||
<div class="section__inner resume-doc">
|
||||
<div class="resume-header">
|
||||
<img class="resume-photo" src="{{assetPrefix}}assets/index/me_static.webp" alt="Николай Мамадаев" width="120" height="120" />
|
||||
<div>
|
||||
<p class="hero__eyebrow">Резюме</p>
|
||||
<h1 class="case-page__h1">Николай Мамадаев</h1>
|
||||
<p class="section__prose"><strong>Senior UX/UI Designer, Product Designer</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-contacts">
|
||||
<span>Портфолио: <a href="https://mamadaevv.site" target="_blank" rel="noopener">mamadaevv.site</a></span>
|
||||
<span>Почта: <a href="mailto:nik@mamadaevv.site">nik@mamadaevv.site</a></span>
|
||||
</div>
|
||||
|
||||
<dl class="resume-meta">
|
||||
<div>
|
||||
<dt>Вилка по ЗП</dt>
|
||||
<dd>250 000 – 310 000 руб.</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Формат работы</dt>
|
||||
<dd>удалённо</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<h2 id="experience">Опыт работы</h2>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Собственные продукты и исследование AI-инструментов</p>
|
||||
<p class="resume-exp__period">Декабрь 2025 — настоящее время</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Период самостоятельной практики: изучение AI-инструментов в продуктовом и дизайн-процессе, разработка собственных продуктов полного цикла — от идеи до работающего релиза.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">AI-плагин для Figma (внутренний инструмент)</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Определил сценарии автоматизации на основе аудита собственного рабочего процесса: замерил, какие операции повторяются чаще всего и съедают больше всего времени</li>
|
||||
<li>Спроектировал интерфейс плагина: панель, состояния обработки, обработка ошибок, работа с выделением</li>
|
||||
<li>Собрал архитектуру взаимодействия с LLM: промпт-шаблоны, валидация ответа, повторные попытки</li>
|
||||
<li>Довёл до рабочей версии самостоятельно, с помощью AI-ассистированной разработки</li>
|
||||
<li>Веду плагин как продукт: собираю обратную связь, приоритизирую доработки, выпускаю обновления</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Автоматизировал 7 рутинных операций дизайн-процесса: нейминг слоёв, генерация контента для макетов, приведение текстов к тону продукта, локализация</li>
|
||||
<li>Сократил время на подготовку макета к передаче в разработку примерно на 40%</li>
|
||||
<li>Экономлю около 5 часов в неделю на операциях, которые раньше делал руками</li>
|
||||
<li>Прошёл полный цикл продукта в одиночку: проблема → решение → реализация → эксплуатация</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Автоматизации и сервисы на n8n (личные проекты)</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование логики сценариев: триггеры, ветвления, обработка ошибок, повторные запуски</li>
|
||||
<li>Работа с PostgreSQL как хранилищем и источником данных для процессов</li>
|
||||
<li>Интеграция внешних сервисов через REST API</li>
|
||||
<li>Проектирование и запуск Telegram-ботов: сценарии диалога, состояния, интерфейс сообщений</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Собрал 12 рабочих сценариев автоматизации, закрывающих личные и рабочие рутины</li>
|
||||
<li>Запустил 3 Telegram-бота с собственной продуктовой логикой и базой данных</li>
|
||||
<li>Свёл разрозненные сервисы в единый процесс без единой строки ручной работы</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Пет-проекты на AI-ассистированной разработке</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Продуктовое проектирование: формулировка проблемы, сценарии, интерфейс, приоритизация функций</li>
|
||||
<li>Реализация фронтенда и логики с помощью AI-ассистентов</li>
|
||||
<li>Развёртывание и поддержка работающих сервисов</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Довёл 5 идей до состояния работающего продукта, а не макета в Figma</li>
|
||||
<li>Научился доводить гипотезу до проверяемого прототипа за 2–3 дня вместо нескольких недель ожидания разработки</li>
|
||||
<li>Закрыл разрыв между дизайном и реализацией: теперь проверяю идеи в коде, а не только на макетах</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Primo RPA</p>
|
||||
<p class="resume-exp__period">Февраль 2023 — Ноябрь 2025 (2 года и 10 месяцев)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Российская RPA-платформа корпоративного уровня: линейка из desktop-среды разработки роботов и веб-сервисов управления, аналитики и ML. Работал ведущим дизайнером на всю продуктовую линейку из 6 продуктов.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">AI Server platform (Saas)</p>
|
||||
<p class="resume-exp__desc">Панель управления для обучения/запуска/тестирования и других операций с нейросетями развёрнутыми внутри контура компании.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса управления моделями: обучение, запуск, тестирование, версионирование, мониторинг</li>
|
||||
<li>Проработка сценариев работы с Smart OCR — извлечение данных из документов различных типов</li>
|
||||
<li>Проектирование разметки документов и валидации результатов распознавания</li>
|
||||
<li>Работа с состояниями долгих процессов: обучение модели, прогресс, ошибки, откат</li>
|
||||
<li>Подготовка интерактивных прототипов и авторский надзор за реализацией</li>
|
||||
<li>Проведение интервью с ML-инженерами и бизнес-пользователями для сверки моделей поведения</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Упаковал сложную ML-логику в интерфейс, понятный не только ML-инженеру, но и бизнес-аналитику без технического бэкграунда</li>
|
||||
<li>Свёл работу с моделями к единому предсказуемому сценарию из 4 шагов вместо 9 разрозненных экранов</li>
|
||||
<li>Сократил время настройки новой модели с 40 до 15 минут по результатам замеров на тестировании</li>
|
||||
<li>Спроектировал интерфейс разметки документов, который снял 60% обращений в поддержку по этой теме</li>
|
||||
<li>Провёл 8 юзабилити-сессий, по итогам переработал ключевой сценарий обучения модели</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Robot automation studio (Windows)</p>
|
||||
<p class="resume-exp__desc">Среда для разработки и отладки роботов для автоматизации бизнес-процессов.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса профессиональной desktop-IDE: рабочая область, панели инструментов, дерево процесса, отладчик</li>
|
||||
<li>Развитие библиотеки компонентов и визуального языка продукта</li>
|
||||
<li>Проработка сценариев отладки: точки останова, пошаговое выполнение, просмотр переменных</li>
|
||||
<li>Проектирование работы с большими деревьями активностей и вложенностью</li>
|
||||
<li>Работа в паре с разработкой по реализации компонентов, авторский надзор</li>
|
||||
<li>Ведение регулярных дизайн-ревью внутри команды</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Обновил визуальный язык продукта до уровня Windows 10/11 — компоненты стали на поколение современнее</li>
|
||||
<li>Переработал 80+ экранов и диалогов, приведя их к единой сетке и типографике</li>
|
||||
<li>Собрал библиотеку из 140 компонентов, закрывшую 90% потребностей интерфейса</li>
|
||||
<li>Перевёл иконки и часть иллюстраций на векторную графику: корректное отображение при любом масштабировании и DPI</li>
|
||||
<li>Сократил время сборки нового экрана командой с 2 дней до 4 часов за счёт готовых компонентов</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Robot automation studio (Linux)</p>
|
||||
<p class="resume-exp__desc">Среда для разработки и отладки роботов для автоматизации бизнес-процессов.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Адаптация дизайна Студии под Linux-версию на фреймворке Avalonia</li>
|
||||
<li>Проектирование компонентов с учётом технических ограничений фреймворка</li>
|
||||
<li>Синхронизация визуального языка между Windows- и Linux-версиями продукта</li>
|
||||
<li>Совместная работа с разработкой над тем, что технически реализуемо в Avalonia, а что требует обходных решений</li>
|
||||
<li>Подготовка спецификаций поведения компонентов для реализации</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Собрал расширенную библиотеку из 95 компонентов для Avalonia, которой в проекте не существовало до меня</li>
|
||||
<li>Обеспечил единообразие продукта на двух платформах при разных технологических стеках</li>
|
||||
<li>Сократил количество визуальных расхождений между версиями с нескольких десятков до единичных случаев</li>
|
||||
<li>Дал команде Linux-версии готовый набор решений вместо дизайна каждого экрана с нуля</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Idea Hub Dashboard (Saas)</p>
|
||||
<p class="resume-exp__desc">Обеспечивает сбор и анализ предложений сотрудников, оценка эффективности и мониторинг статуса реализации автоматизаций. Аналитика по ключевым показателям эффективности и верхнеуровневый взгляд на роботизацию.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование дашбордов и аналитических представлений по KPI роботизации</li>
|
||||
<li>Проработка жизненного цикла идеи: подача → оценка → приоритизация → реализация → замер эффекта</li>
|
||||
<li>Информационная архитектура раздела, работа с плотными таблицами, фильтрами и массовыми операциями</li>
|
||||
<li>Проектирование ролевой модели: сотрудник, аналитик, руководитель</li>
|
||||
<li>Подбор типов визуализации данных под конкретные управленческие вопросы</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Свёл верхнеуровневую аналитику и работу с конкретной идеей в один непрерывный сценарий без переключения между разделами</li>
|
||||
<li>Спроектировал представление данных так, что руководитель видит эффект от роботизации без ручных выгрузок в Excel</li>
|
||||
<li>Сократил путь от подачи идеи до её оценки с 6 шагов до 3</li>
|
||||
<li>Спроектировал 12 виджетов аналитики, покрывающих основные вопросы заказчиков о ROI роботизации</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Orchestrator Automation Management Tool (Saas)</p>
|
||||
<p class="resume-exp__desc">Обеспечивает слаженную работу системы и управление сотнями роботов: запуски, мониторинг и менеджмент.</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса управления парком из сотен роботов: расписания, очереди, приоритеты, мониторинг</li>
|
||||
<li>Проработка состояний и обработки ошибок при массовых запусках</li>
|
||||
<li>Проектирование системы уведомлений и алертов о сбоях</li>
|
||||
<li>Работа со сложными таблицами: сортировка, фильтрация, массовые действия, сохранённые представления</li>
|
||||
<li>Прототипирование сложных сценариев для валидации до начала разработки</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Спроектировал управление сотнями объектов так, что оператор не теряется в масштабе: от общей картины до конкретного робота за 2 клика</li>
|
||||
<li>Привёл сервис к единой дизайн-системе вместе с остальными веб-продуктами линейки</li>
|
||||
<li>Сократил время реакции оператора на сбой робота с 12 до 4 минут за счёт переработанной системы алертов</li>
|
||||
<li>Свёл 5 разных представлений списка роботов к одному настраиваемому</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">QnA portal (WEB)</p>
|
||||
<p class="resume-exp__desc">Площадка для постинга вопросов и получения ответов от службы поддержки</p>
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование сценариев публикации вопроса, ответа и поиска по накопленной базе знаний</li>
|
||||
<li>Дизайн интерфейса портала на базе общей дизайн-системы компании</li>
|
||||
<li>Проработка ролевой модели: пользователь, эксперт, служба поддержки, модератор</li>
|
||||
<li>Проектирование механики поиска и подсказок похожих вопросов при публикации</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Запустил портал на готовых компонентах дизайн-системы за 3 недели вместо запланированных 8</li>
|
||||
<li>Снизил нагрузку на поддержку примерно на 25% за счёт переиспользования уже данных ответов</li>
|
||||
<li>Механика подсказок похожих вопросов сократила количество дублей на 45%</li>
|
||||
<li>Обеспечил визуальную преемственность с продуктами линейки — портал не выглядит сторонним сервисом</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Общее по компании</p>
|
||||
<ul>
|
||||
<li>Инициировал обновление внешнего вида всей продуктовой линейки — решение о редизайне компания приняла с моим приходом</li>
|
||||
<li>Собрал и внедрил единую дизайн-систему для веб-сервисов, соединив фирменный стиль компании с новой структурой интерфейсов</li>
|
||||
<li>Дизайн-систему приняли 4 продуктовые команды; она включает 210 компонентов и токены темизации</li>
|
||||
<li>Сократил среднее время подготовки макетов по линейке на 35%</li>
|
||||
<li>Создавал и поддерживал UI-kit для консистентности и ускорения разработки</li>
|
||||
<li>Провёл более 20 пользовательских исследований и юзабилити-сессий за время работы</li>
|
||||
<li>Вёл авторский надзор за реализацией, участвовал в дизайн-ревью, продуктовых обсуждениях и планировании релизов</li>
|
||||
<li>Был единственным ведущим дизайнером на всю линейку из 6 продуктов и двух платформ</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Lunacy (Icons8)</p>
|
||||
<p class="resume-exp__period">Июль 2022 — Январь 2023 (7 месяцев)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Графический редактор для работы над дизайном интерфейсов и прочих макетов. Аналог Sketch App и Figma.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса графического редактора: инструменты, панели свойств, работа с холстом и слоями</li>
|
||||
<li>Оформление решений в виде юзерфлоу и передача разработчикам</li>
|
||||
<li>Создание сложных интерактивных прототипов в Protopie для демонстрации поведения инструментов</li>
|
||||
<li>Отрисовка недостающих иконок в стилистике продукта</li>
|
||||
<li>Внесение предложений по улучшению функциональности редактора</li>
|
||||
<li>Участие в обсуждениях продуктовых решений с командой</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Спроектировал 6 функциональных блоков редактора, включая работу с компонентами и стилями</li>
|
||||
<li>Собрал 15+ прототипов в Protopie, что позволило отсечь неудачные решения до разработки</li>
|
||||
<li>Часть моих предложений по функциональности вошла в релизы продукта</li>
|
||||
<li>Отрисовал более 60 иконок, дополнивших системный набор редактора</li>
|
||||
<li>Работал над продуктом для профессиональной аудитории дизайнеров, где требования к деталям интерфейса выше обычных</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">MANU Video Game Maker</p>
|
||||
<p class="resume-exp__period">Январь 2019 — Декабрь 2021 (3 года)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Игровой движок для создания видеоигр без написания кода.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Продуктовый дизайн движка целиком: от концепции взаимодействия до конечного UI</li>
|
||||
<li>Проектирование поведения интерфейса для сложных пользовательских сценариев</li>
|
||||
<li>Исследования пользователей: наблюдение, глубинные интервью, опросы</li>
|
||||
<li>Составление портретов потенциальных пользователей и карт эмпатии</li>
|
||||
<li>Работа с продуктовой аналитикой и метриками, завязанными на пользовательские сценарии</li>
|
||||
<li>Вёрстка главной страницы сайта на Tilda, проектирование информационной архитектуры сайта вместе с командой</li>
|
||||
<li>Контроль работы веб-графического дизайнера</li>
|
||||
<li>Найм в продуктовый отдел: проведение собеседований и отбор специалистов</li>
|
||||
<li>Руководство отделом, построение рабочих процессов всей продуктовой команды</li>
|
||||
<li>Кураторство работ по созданию пользовательской документации</li>
|
||||
<li>Внедрение инструментов автоматизации (Integromat, Zapier) для внутренних задач</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Провёл масштабный редизайн всей программы: заложил принципиально новую концепцию работы и стилистику</li>
|
||||
<li>Спроектировал поведение интерфейса для 100+ сложных пользовательских сценариев</li>
|
||||
<li>Спроектировал дизайн-систему продукта с нуля: 120 компонентов</li>
|
||||
<li>Получили массу положительных, местами восторженных отзывов пользователей — в продукте стало значительно легче ориентироваться</li>
|
||||
<li>Завершаемость онбординга выросла с 34% до 58% после редизайна</li>
|
||||
<li>Провёл 25 глубинных интервью и 4 волны опросов, на их основе переработал 3 ключевых сценария</li>
|
||||
<li>Нанял 4 специалистов в продуктовый отдел и вырос из дизайнера в тимлида команды</li>
|
||||
<li>Выстроил процессы отдела: дизайн-ревью, работа с бэклогом, передача в разработку</li>
|
||||
<li>Автоматизировал внутренние рутины команды, освободив время на продуктовые задачи</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Aegees Messenger</p>
|
||||
<p class="resume-exp__period">Октябрь 2017 — Декабрь 2018 (1 год и 3 месяца)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Кроссплатформенный мессенджер с защищенным хранилищем и аудиозвонками.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Дизайн мессенджера сразу под пять платформ: Android, iOS, macOS, Windows, Linux</li>
|
||||
<li>Проработка сценариев защищённого хранилища и аудиозвонков</li>
|
||||
<li>Проектирование сценариев регистрации, шифрования и восстановления доступа</li>
|
||||
<li>Адаптация единой продуктовой логики под гайдлайны каждой платформы</li>
|
||||
<li>Контроль работы зарубежных иллюстраторов по подготовке графических материалов</li>
|
||||
<li>Подготовка материалов для магазинов приложений</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Выстроил единый визуальный язык продукта при соблюдении гайдлайнов пяти платформ одновременно</li>
|
||||
<li>Спроектировал более 90 экранов в пяти платформенных вариантах</li>
|
||||
<li>Обеспечил стабильный поток графических материалов от внешних подрядчиков без потери стилистики</li>
|
||||
<li>Упростил сценарий защищённого хранилища так, чтобы им пользовались люди без технической подготовки</li>
|
||||
<li>Работал в чувствительной области приватности и безопасности, где ошибка в интерфейсе стоит доверия пользователя</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Orion Innovation (ex MERA)</p>
|
||||
<p class="resume-exp__period">Июль 2016 — Октябрь 2017 (1 год и 4 месяца)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Разработка ПО для внешних заказчиков.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Работа в дизайн-отделе численностью до 8 человек</li>
|
||||
<li>Создание анкет персон и составление карты функциональности продукта в соответствии с потребностями персон</li>
|
||||
<li>Вайрфреймы и отрисовка конечного UI интерфейсов</li>
|
||||
<li>Проектирование юзкейсов, карт экранов, демонстрации микроанимаций</li>
|
||||
<li>Подготовка мудбордов и дизайн-концепций, обсуждение их с клиентами</li>
|
||||
<li>Подготовка и проведение презентаций дизайн-концепций</li>
|
||||
<li>Линковка мокапов в прототипы, написание сценариев и проведение качественных юзабилити-тестирований</li>
|
||||
<li>Внесение правок по результатам тестирований</li>
|
||||
<li>Авторский надзор над реализацией дизайна разработчиками</li>
|
||||
<li>Участие в дизайн-ревью: разбор работ коллег и защита собственных решений</li>
|
||||
<li>Прямая коммуникация с зарубежными клиентами для обсуждения дизайна и получения задач</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Провёл 10 сессий юзабилити-тестирования от написания сценария до внесения правок</li>
|
||||
<li>Освоил новую для себя платформу Smart TV и довёл проект до успешной публикации в магазине приложений</li>
|
||||
<li>Вёл коммуникацию с зарубежными заказчиками напрямую, без посредников</li>
|
||||
<li>Активно участвовал в улучшении рабочего процесса дизайн-отдела компании</li>
|
||||
<li>Прошёл полный цикл продуктового дизайна на 5 клиентских проектах</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">SpaceshipApps Studio</p>
|
||||
<p class="resume-exp__period">Июнь 2015 — Июнь 2016 (1 год и 1 месяц)</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Студия разработки мобильных приложений и сайтов.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__desc">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Дизайн мобильных и веб-продуктов в потоковом режиме студии</li>
|
||||
<li>Работа с разными доменами: соцгейминг, бьюти-услуги, доставка еды, голосовые интерфейсы, легал-сервисы, коллаборативные инструменты</li>
|
||||
<li>Адаптивный веб-дизайн и дизайн административных панелей</li>
|
||||
<li>Отрисовка иконок и подготовка графики для проектов</li>
|
||||
<li>Подготовка макетов к передаче в разработку</li>
|
||||
</ul>
|
||||
<p class="resume-exp__desc">Достижения:</p>
|
||||
<ul>
|
||||
<li>Выпустил 6 продуктов за год: геолокационная социальная игра с квестами в реальном мире, приложение записи к бьюти-специалистам, сервис доставки еды, голосовая игра со словами, сайт и админка сервиса регистрации авторского права, мобильная «белая доска» для совместной работы</li>
|
||||
<li>Научился быстро входить в новую предметную область и держать качество при высоком темпе студии</li>
|
||||
<li>Закрыл весь спектр задач: мобайл, веб, админ-панели, графика</li>
|
||||
<li>Заложил базу для перехода от исполнительского дизайна к продуктовому</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="skills">Навыки</h2>
|
||||
<p class="section__prose">Figma, AI, n8n, Rest API, HTML, CSS, JS, JTBD, UJM, KISS</p>
|
||||
|
||||
<h2 id="about">О себе</h2>
|
||||
<p class="section__prose resume-about">
|
||||
В дизайне больше 10 лет, последние годы — продуктовый дизайн сложных B2B-продуктов. Работаю на стыке дизайна и продакт-менеджмента: провожу исследования, формулирую гипотезы и фичи, помогаю с приоритизацией и участвую в планировании релизов.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Люблю разбираться в сложном и делать его понятным — поэтому мне комфортно в продуктах вроде IDE, оркестраторов и ML-панелей, где обычному дизайнеру скучно или страшно.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Не жду, пока задачу сделает кто-то другой: пишу себе инструменты сам. Собрал приватный AI-плагин для Figma, автоматизирую процессы на n8n и PostgreSQL, довожу свои идеи до работающих продуктов с помощью AI-ассистированной разработки. Собственные навыки для Алисы набрали 37 000+ и 33 000+ пользователей, файл Slider Set для дизайнеров скачали больше 20 000 раз.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Участвую в жизни сообщества: веду Telegram-канал «Дизайн не пицца», выкладываю полезности в Figma Community, выступал на митапе Яндекса с докладом по аналитике, побеждал на хакатонах — самая приятная победа на хакатоне Яндекс.Денег в Петербурге за приложение оплаты по QR-коду.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Английский — B1. Работаю удалённо, спокойно веду коммуникацию с распределённой командой.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{> footer}}
|
||||
{{> cookie-notice}}
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,875 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" data-theme="dark" data-radius="medium">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Резюме Николая Мамадаева — продуктовый дизайнер с опытом более 10 лет."
|
||||
/>
|
||||
<title>Резюме 5 — Николай Мамадаев</title>
|
||||
{{> head-links}}
|
||||
<style>
|
||||
.resume-doc {
|
||||
max-width: 52rem;
|
||||
margin: 0 auto;
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius-card);
|
||||
padding: clamp(1.5rem, 3vw, 2.5rem);
|
||||
}
|
||||
.resume-header {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
border-radius: var(--radius-sm);
|
||||
object-fit: cover;
|
||||
flex-shrink: 0;
|
||||
order: 1;
|
||||
margin-left: auto;
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-header {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
.resume-photo {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
.resume-doc h2 {
|
||||
margin: 2rem 0 1rem;
|
||||
font-size: clamp(0.95rem, 1.35vw, 1.1rem);
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
letter-spacing: 0.04em;
|
||||
border-top: 1px solid var(--line);
|
||||
padding-top: 1rem;
|
||||
}
|
||||
.resume-doc h2:first-of-type {
|
||||
border-top: none;
|
||||
padding-top: 0;
|
||||
}
|
||||
.resume-doc .section__prose + .section__prose {
|
||||
margin-top: 0.75rem;
|
||||
}
|
||||
.resume-doc .section__prose a {
|
||||
color: var(--accent);
|
||||
}
|
||||
#skills {
|
||||
border-top: none;
|
||||
padding-top: 0;
|
||||
}
|
||||
.resume-meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 0.5rem 1.5rem;
|
||||
margin: 0.75rem 0 1.5rem;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
@media (max-width: 32rem) {
|
||||
.resume-meta {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
.resume-meta dt {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
letter-spacing: 0.03em;
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
.resume-meta dd {
|
||||
margin: 0;
|
||||
}
|
||||
.resume-meta a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.resume-exp {
|
||||
margin: 1.5rem 0;
|
||||
padding-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.resume-exp:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.resume-doc > .resume-exp:last-of-type {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.resume-exp__header {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.resume-exp__company {
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
color: var(--text);
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
.resume-exp__meta-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 0.85rem;
|
||||
color: var(--text-muted);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-exp__meta-row a {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid var(--accent);
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
.resume-exp__meta-row a:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.resume-exp__sep {
|
||||
color: var(--line);
|
||||
}
|
||||
.resume-exp__period {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-muted);
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.resume-exp__desc {
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
margin: 0.5rem 0;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.resume-exp__section {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.resume-exp__cols {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr auto;
|
||||
gap: 0 1.5rem;
|
||||
}
|
||||
.resume-exp__section-title {
|
||||
font-weight: 600;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.resume-exp__label {
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
letter-spacing: 0.03em;
|
||||
margin: 0.75rem 0 0.35rem;
|
||||
}
|
||||
.resume-exp ul {
|
||||
margin: 0;
|
||||
padding-left: 1.25rem;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.92rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.resume-exp li + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.resume-skills {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.resume-skill {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 0.75rem;
|
||||
font-size: 0.92rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.resume-skill__title {
|
||||
font-weight: 600;
|
||||
color: var(--text);
|
||||
min-width: 8rem;
|
||||
flex-shrink: 0;
|
||||
font-size: 0.85rem;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
.resume-skill__desc {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.resume-about {
|
||||
margin: 1.5rem 0;
|
||||
font-size: 0.92rem;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.55;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{{> header-minimal}}
|
||||
{{> fab-stack-resume}}
|
||||
<main id="main" class="section section--surface section--tight">
|
||||
<div class="section__inner resume-doc">
|
||||
<div class="resume-header">
|
||||
<img class="resume-photo" src="{{assetPrefix}}assets/index/me_static.webp" alt="Николай Мамадаев" width="120" height="120" />
|
||||
<div>
|
||||
<p class="hero__eyebrow">Резюме</p>
|
||||
<h1 class="case-page__h1">Николай Мамадаев</h1>
|
||||
<p class="section__prose"><strong>Senior UX/UI Designer, Product Designer</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dl class="resume-meta">
|
||||
<div>
|
||||
<dt>Портфолио</dt>
|
||||
<dd><a href="https://mamadaevv.site" target="_blank" rel="noopener">mamadaevv.site</a></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Почта</dt>
|
||||
<dd><a href="mailto:nik@mamadaevv.site">nik@mamadaevv.site</a></dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Вилка по ЗП</dt>
|
||||
<dd>250 000 – 310 000 руб.</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Формат работы</dt>
|
||||
<dd>удалённо</dd>
|
||||
</div>
|
||||
</dl>
|
||||
|
||||
<h2 id="experience">Опыт работы</h2>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Собственные продукты и исследование AI-инструментов</p>
|
||||
<p class="resume-exp__period">Декабрь 2025 — настоящее время</p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Период самостоятельной практики: изучение AI-инструментов в продуктовом и дизайн-процессе, разработка собственных продуктов полного цикла — от идеи до работающего релиза.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">AI-плагин для Figma (внутренний инструмент)</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Определил сценарии автоматизации на основе аудита собственного рабочего процесса: замерил, какие операции повторяются чаще всего и съедают больше всего времени</li>
|
||||
<li>Спроектировал интерфейс плагина: панель, состояния обработки, обработка ошибок, работа с выделением</li>
|
||||
<li>Собрал архитектуру взаимодействия с LLM: промпт-шаблоны, валидация ответа, повторные попытки</li>
|
||||
<li>Довёл до рабочей версии самостоятельно, с помощью AI-ассистированной разработки</li>
|
||||
<li>Веду плагин как продукт: собираю обратную связь, приоритизирую доработки, выпускаю обновления</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Автоматизировал 7 рутинных операций дизайн-процесса: нейминг слоёв, генерация контента для макетов, приведение текстов к тону продукта, локализация</li>
|
||||
<li>Сократил время на подготовку макета к передаче в разработку примерно на 40%</li>
|
||||
<li>Экономлю около 5 часов в неделю на операциях, которые раньше делал руками</li>
|
||||
<li>Прошёл полный цикл продукта в одиночку: проблема → решение → реализация → эксплуатация</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Figma API</li>
|
||||
<li>AI / LLM</li>
|
||||
<li>Prompt engineering</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Автоматизации и сервисы на n8n (личные проекты)</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование логики сценариев: триггеры, ветвления, обработка ошибок, повторные запуски</li>
|
||||
<li>Работа с PostgreSQL как хранилищем и источником данных для процессов</li>
|
||||
<li>Интеграция внешних сервисов через REST API</li>
|
||||
<li>Проектирование и запуск Telegram-ботов: сценарии диалога, состояния, интерфейс сообщений</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Собрал 12 рабочих сценариев автоматизации, закрывающих личные и рабочие рутины</li>
|
||||
<li>Запустил 3 Telegram-бота с собственной продуктовой логикой и базой данных</li>
|
||||
<li>Свёл разрозненные сервисы в единый процесс без единой строки ручной работы</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>n8n</li>
|
||||
<li>PostgreSQL</li>
|
||||
<li>REST API</li>
|
||||
<li>Telegram Bot API</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Пет-проекты на AI-ассистированной разработке</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Продуктовое проектирование: формулировка проблемы, сценарии, интерфейс, приоритизация функций</li>
|
||||
<li>Реализация фронтенда и логики с помощью AI-ассистентов</li>
|
||||
<li>Развёртывание и поддержка работающих сервисов</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Довёл 5 идей до состояния работающего продукта, а не макета в Figma</li>
|
||||
<li>Научился доводить гипотезу до проверяемого прототипа за 2–3 дня вместо нескольких недель ожидания разработки</li>
|
||||
<li>Закрыл разрыв между дизайном и реализацией: теперь проверяю идеи в коде, а не только на макетах</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Необходимо заполнить</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Primo RPA</p>
|
||||
<p class="resume-exp__meta-row"><span>Февраль 2023 — Ноябрь 2025 (2 года и 10 месяцев)</span><span class="resume-exp__sep">·</span><a href="https://primo-rpa.com/" target="_blank" rel="noopener noreferrer">primo-rpa.com</a></p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Российская RPA-платформа корпоративного уровня: линейка из desktop-среды разработки роботов и веб-сервисов управления, аналитики и ML. Работал ведущим дизайнером на всю продуктовую линейку из 6 продуктов.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">AI Server platform (Saas)</p>
|
||||
<p class="resume-exp__desc">Панель управления для обучения/запуска/тестирования и других операций с нейросетями развёрнутыми внутри контура компании.</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса управления моделями: обучение, запуск, тестирование, версионирование, мониторинг</li>
|
||||
<li>Проработка сценариев работы с Smart OCR — извлечение данных из документов различных типов</li>
|
||||
<li>Проектирование разметки документов и валидации результатов распознавания</li>
|
||||
<li>Работа с состояниями долгих процессов: обучение модели, прогресс, ошибки, откат</li>
|
||||
<li>Подготовка интерактивных прототипов и авторский надзор за реализацией</li>
|
||||
<li>Проведение интервью с ML-инженерами и бизнес-пользователями для сверки моделей поведения</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Упаковал сложную ML-логику в интерфейс, понятный не только ML-инженеру, но и бизнес-аналитику без технического бэкграунда</li>
|
||||
<li>Свёл работу с моделями к единому предсказуемому сценарию из 4 шагов вместо 9 разрозненных экранов</li>
|
||||
<li>Сократил время настройки новой модели с 40 до 15 минут по результатам замеров на тестировании</li>
|
||||
<li>Спроектировал интерфейс разметки документов, который снял 60% обращений в поддержку по этой теме</li>
|
||||
<li>Провёл 8 юзабилити-сессий, по итогам переработал ключевой сценарий обучения модели</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>ML / нейросети</li>
|
||||
<li>Smart OCR</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Robot automation studio (Windows)</p>
|
||||
<p class="resume-exp__desc">Среда для разработки и отладки роботов для автоматизации бизнес-процессов.</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса профессиональной desktop-IDE: рабочая область, панели инструментов, дерево процесса, отладчик</li>
|
||||
<li>Развитие библиотеки компонентов и визуального языка продукта</li>
|
||||
<li>Проработка сценариев отладки: точки останова, пошаговое выполнение, просмотр переменных</li>
|
||||
<li>Проектирование работы с большими деревьями активностей и вложенностью</li>
|
||||
<li>Работа в паре с разработкой по реализации компонентов, авторский надзор</li>
|
||||
<li>Ведение регулярных дизайн-ревью внутри команды</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Обновил визуальный язык продукта до уровня Windows 10/11 — компоненты стали на поколение современнее</li>
|
||||
<li>Переработал 80+ экранов и диалогов, приведя их к единой сетке и типографике</li>
|
||||
<li>Собрал библиотеку из 140 компонентов, закрывшую 90% потребностей интерфейса</li>
|
||||
<li>Перевёл иконки и часть иллюстраций на векторную графику: корректное отображение при любом масштабировании и DPI</li>
|
||||
<li>Сократил время сборки нового экрана командой с 2 дней до 4 часов за счёт готовых компонентов</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Desktop IDE</li>
|
||||
<li>Windows 10/11</li>
|
||||
<li>Компонентная библиотека</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Robot automation studio (Linux)</p>
|
||||
<p class="resume-exp__desc">Среда для разработки и отладки роботов для автоматизации бизнес-процессов.</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Адаптация дизайна Студии под Linux-версию на фреймворке Avalonia</li>
|
||||
<li>Проектирование компонентов с учётом технических ограничений фреймворка</li>
|
||||
<li>Синхронизация визуального языка между Windows- и Linux-версиями продукта</li>
|
||||
<li>Совместная работа с разработкой над тем, что технически реализуемо в Avalonia, а что требует обходных решений</li>
|
||||
<li>Подготовка спецификаций поведения компонентов для реализации</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Собрал расширенную библиотеку из 95 компонентов для Avalonia, которой в проекте не существовало до меня</li>
|
||||
<li>Обеспечил единообразие продукта на двух платформах при разных технологических стеках</li>
|
||||
<li>Сократил количество визуальных расхождений между версиями с нескольких десятков до единичных случаев</li>
|
||||
<li>Дал команде Linux-версии готовый набор решений вместо дизайна каждого экрана с нуля</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Avalonia</li>
|
||||
<li>.NET</li>
|
||||
<li>Linux</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Idea Hub Dashboard (Saas)</p>
|
||||
<p class="resume-exp__desc">Обеспечивает сбор и анализ предложений сотрудников, оценка эффективности и мониторинг статуса реализации автоматизаций. Аналитика по ключевым показателям эффективности и верхнеуровневый взгляд на роботизацию.</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование дашбордов и аналитических представлений по KPI роботизации</li>
|
||||
<li>Проработка жизненного цикла идеи: подача → оценка → приоритизация → реализация → замер эффекта</li>
|
||||
<li>Информационная архитектура раздела, работа с плотными таблицами, фильтрами и массовыми операциями</li>
|
||||
<li>Проектирование ролевой модели: сотрудник, аналитик, руководитель</li>
|
||||
<li>Подбор типов визуализации данных под конкретные управленческие вопросы</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Свёл верхнеуровневую аналитику и работу с конкретной идеей в один непрерывный сценарий без переключения между разделами</li>
|
||||
<li>Спроектировал представление данных так, что руководитель видит эффект от роботизации без ручных выгрузок в Excel</li>
|
||||
<li>Сократил путь от подачи идеи до её оценки с 6 шагов до 3</li>
|
||||
<li>Спроектировал 12 виджетов аналитики, покрывающих основные вопросы заказчиков о ROI роботизации</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Аналитика / дашборды</li>
|
||||
<li>KPI</li>
|
||||
<li>Визуализация данных</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Orchestrator Automation Management Tool (Saas)</p>
|
||||
<p class="resume-exp__desc">Обеспечивает слаженную работу системы и управление сотнями роботов: запуски, мониторинг и менеджмент.</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса управления парком из сотен роботов: расписания, очереди, приоритеты, мониторинг</li>
|
||||
<li>Проработка состояний и обработки ошибок при массовых запусках</li>
|
||||
<li>Проектирование системы уведомлений и алертов о сбоях</li>
|
||||
<li>Работа со сложными таблицами: сортировка, фильтрация, массовые действия, сохранённые представления</li>
|
||||
<li>Прототипирование сложных сценариев для валидации до начала разработки</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Спроектировал управление сотнями объектов так, что оператор не теряется в масштабе: от общей картины до конкретного робота за 2 клика</li>
|
||||
<li>Привёл сервис к единой дизайн-системе вместе с остальными веб-продуктами линейки</li>
|
||||
<li>Сократил время реакции оператора на сбой робота с 12 до 4 минут за счёт переработанной системы алертов</li>
|
||||
<li>Свёл 5 разных представлений списка роботов к одному настраиваемому</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Мониторинг</li>
|
||||
<li>Расписания / очереди</li>
|
||||
<li>Уведомления / алерты</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">QnA portal (WEB)</p>
|
||||
<p class="resume-exp__desc">Площадка для постинга вопросов и получения ответов от службы поддержки</p>
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование сценариев публикации вопроса, ответа и поиска по накопленной базе знаний</li>
|
||||
<li>Дизайн интерфейса портала на базе общей дизайн-системы компании</li>
|
||||
<li>Проработка ролевой модели: пользователь, эксперт, служба поддержки, модератор</li>
|
||||
<li>Проектирование механики поиска и подсказок похожих вопросов при публикации</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Запустил портал на готовых компонентах дизайн-системы за 3 недели вместо запланированных 8</li>
|
||||
<li>Снизил нагрузку на поддержку примерно на 25% за счёт переиспользования уже данных ответов</li>
|
||||
<li>Механика подсказок похожих вопросов сократила количество дублей на 45%</li>
|
||||
<li>Обеспечил визуальную преемственность с продуктами линейки — портал не выглядит сторонним сервисом</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Веб-портал</li>
|
||||
<li>Дизайн-система</li>
|
||||
<li>База знаний</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<p class="resume-exp__section-title">Общее по компании</p>
|
||||
<ul>
|
||||
<li>Инициировал обновление внешнего вида всей продуктовой линейки — решение о редизайне компания приняла с моим приходом</li>
|
||||
<li>Собрал и внедрил единую дизайн-систему для веб-сервисов, соединив фирменный стиль компании с новой структурой интерфейсов</li>
|
||||
<li>Дизайн-систему приняли 4 продуктовые команды; она включает 210 компонентов и токены темизации</li>
|
||||
<li>Сократил среднее время подготовки макетов по линейке на 35%</li>
|
||||
<li>Создавал и поддерживал UI-kit для консистентности и ускорения разработки</li>
|
||||
<li>Провёл более 20 пользовательских исследований и юзабилити-сессий за время работы</li>
|
||||
<li>Вёл авторский надзор за реализацией, участвовал в дизайн-ревью, продуктовых обсуждениях и планировании релизов</li>
|
||||
<li>Был единственным ведущим дизайнером на всю линейку из 6 продуктов и двух платформ</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Lunacy (Icons8)</p>
|
||||
<p class="resume-exp__meta-row"><span>Июль 2022 — Январь 2023 (7 месяцев)</span><span class="resume-exp__sep">·</span><a href="https://icons8.com/lunacy" target="_blank" rel="noopener noreferrer">icons8.com/lunacy</a></p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Графический редактор для работы над дизайном интерфейсов и прочих макетов. Аналог Sketch App и Figma.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Проектирование интерфейса графического редактора: инструменты, панели свойств, работа с холстом и слоями</li>
|
||||
<li>Оформление решений в виде юзерфлоу и передача разработчикам</li>
|
||||
<li>Создание сложных интерактивных прототипов в Protopie для демонстрации поведения инструментов</li>
|
||||
<li>Отрисовка недостающих иконок в стилистике продукта</li>
|
||||
<li>Внесение предложений по улучшению функциональности редактора</li>
|
||||
<li>Участие в обсуждениях продуктовых решений с командой</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Спроектировал 6 функциональных блоков редактора, включая работу с компонентами и стилями</li>
|
||||
<li>Собрал 15+ прототипов в Protopie, что позволило отсечь неудачные решения до разработки</li>
|
||||
<li>Часть моих предложений по функциональности вошла в релизы продукта</li>
|
||||
<li>Отрисовал более 60 иконок, дополнивших системный набор редактора</li>
|
||||
<li>Работал над продуктом для профессиональной аудитории дизайнеров, где требования к деталям интерфейса выше обычных</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Protopie</li>
|
||||
<li>Графический редактор</li>
|
||||
<li>Иконки / иллюстрации</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">MANU Video Game Maker</p>
|
||||
<p class="resume-exp__meta-row"><span>Январь 2019 — Декабрь 2021 (3 года)</span><span class="resume-exp__sep">·</span><a href="https://manu.co/" target="_blank" rel="noopener noreferrer">manu.co</a></p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Игровой движок для создания видеоигр без написания кода.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Продуктовый дизайн движка целиком: от концепции взаимодействия до конечного UI</li>
|
||||
<li>Проектирование поведения интерфейса для сложных пользовательских сценариев</li>
|
||||
<li>Исследования пользователей: наблюдение, глубинные интервью, опросы</li>
|
||||
<li>Составление портретов потенциальных пользователей и карт эмпатии</li>
|
||||
<li>Работа с продуктовой аналитикой и метриками, завязанными на пользовательские сценарии</li>
|
||||
<li>Вёрстка главной страницы сайта на Tilda, проектирование информационной архитектуры сайта вместе с командой</li>
|
||||
<li>Контроль работы веб-графического дизайнера</li>
|
||||
<li>Найм в продуктовый отдел: проведение собеседований и отбор специалистов</li>
|
||||
<li>Руководство отделом, построение рабочих процессов всей продуктовой команды</li>
|
||||
<li>Кураторство работ по созданию пользовательской документации</li>
|
||||
<li>Внедрение инструментов автоматизации (Integromat, Zapier) для внутренних задач</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Провёл масштабный редизайн всей программы: заложил принципиально новую концепцию работы и стилистику</li>
|
||||
<li>Спроектировал поведение интерфейса для 100+ сложных пользовательских сценариев</li>
|
||||
<li>Спроектировал дизайн-систему продукта с нуля: 120 компонентов</li>
|
||||
<li>Получили массу положительных, местами восторженных отзывов пользователей — в продукте стало значительно легче ориентироваться</li>
|
||||
<li>Завершаемость онбординга выросла с 34% до 58% после редизайна</li>
|
||||
<li>Провёл 25 глубинных интервью и 4 волны опросов, на их основе переработал 3 ключевых сценария</li>
|
||||
<li>Нанял 4 специалистов в продуктовый отдел и вырос из дизайнера в тимлида команды</li>
|
||||
<li>Выстроил процессы отдела: дизайн-ревью, работа с бэклогом, передача в разработку</li>
|
||||
<li>Автоматизировал внутренние рутины команды, освободив время на продуктовые задачи</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Tilda</li>
|
||||
<li>Integromat / Zapier</li>
|
||||
<li>Исследования пользователей</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Aegees Messenger</p>
|
||||
<p class="resume-exp__meta-row"><span>Октябрь 2017 — Декабрь 2018 (1 год и 3 месяца)</span><span class="resume-exp__sep">·</span><a href="https://aegees.com/" target="_blank" rel="noopener noreferrer">aegees.com</a></p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Кроссплатформенный мессенджер с защищенным хранилищем и аудиозвонками.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Дизайн мессенджера сразу под пять платформ: Android, iOS, macOS, Windows, Linux</li>
|
||||
<li>Проработка сценариев защищённого хранилища и аудиозвонков</li>
|
||||
<li>Проектирование сценариев регистрации, шифрования и восстановления доступа</li>
|
||||
<li>Адаптация единой продуктовой логики под гайдлайны каждой платформы</li>
|
||||
<li>Контроль работы зарубежных иллюстраторов по подготовке графических материалов</li>
|
||||
<li>Подготовка материалов для магазинов приложений</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Выстроил единый визуальный язык продукта при соблюдении гайдлайнов пяти платформ одновременно</li>
|
||||
<li>Спроектировал более 90 экранов в пяти платформенных вариантах</li>
|
||||
<li>Обеспечил стабильный поток графических материалов от внешних подрядчиков без потери стилистики</li>
|
||||
<li>Упростил сценарий защищённого хранилища так, чтобы им пользовались люди без технической подготовки</li>
|
||||
<li>Работал в чувствительной области приватности и безопасности, где ошибка в интерфейсе стоит доверия пользователя</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Android</li>
|
||||
<li>iOS</li>
|
||||
<li>macOS</li>
|
||||
<li>Windows</li>
|
||||
<li>Linux</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">Orion Innovation (ex MERA)</p>
|
||||
<p class="resume-exp__meta-row"><span>Июль 2016 — Октябрь 2017 (1 год и 4 месяца)</span><span class="resume-exp__sep">·</span><a href="https://www.orioninnovation.com/" target="_blank" rel="noopener noreferrer">orioninnovation.com</a></p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Разработка ПО для внешних заказчиков.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Работа в дизайн-отделе численностью до 8 человек</li>
|
||||
<li>Создание анкет персон и составление карты функциональности продукта в соответствии с потребностями персон</li>
|
||||
<li>Вайрфреймы и отрисовка конечного UI интерфейсов</li>
|
||||
<li>Проектирование юзкейсов, карт экранов, демонстрации микроанимаций</li>
|
||||
<li>Подготовка мудбордов и дизайн-концепций, обсуждение их с клиентами</li>
|
||||
<li>Подготовка и проведение презентаций дизайн-концепций</li>
|
||||
<li>Линковка мокапов в прототипы, написание сценариев и проведение качественных юзабилити-тестирований</li>
|
||||
<li>Внесение правок по результатам тестирований</li>
|
||||
<li>Авторский надзор над реализацией дизайна разработчиками</li>
|
||||
<li>Участие в дизайн-ревью: разбор работ коллег и защита собственных решений</li>
|
||||
<li>Прямая коммуникация с зарубежными клиентами для обсуждения дизайна и получения задач</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Провёл 10 сессий юзабилити-тестирования от написания сценария до внесения правок</li>
|
||||
<li>Освоил новую для себя платформу Smart TV и довёл проект до успешной публикации в магазине приложений</li>
|
||||
<li>Вёл коммуникацию с зарубежными заказчиками напрямую, без посредников</li>
|
||||
<li>Активно участвовал в улучшении рабочего процесса дизайн-отдела компании</li>
|
||||
<li>Прошёл полный цикл продуктового дизайна на 5 клиентских проектах</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Smart TV</li>
|
||||
<li>Юзабилити-тестирование</li>
|
||||
<li>Мудборды / дизайн-концепции</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resume-exp">
|
||||
<div class="resume-exp__header">
|
||||
<p class="resume-exp__company">SpaceshipApps Studio</p>
|
||||
<p class="resume-exp__meta-row"><span>Июнь 2015 — Июнь 2016 (1 год и 1 месяц)</span><span class="resume-exp__sep">·</span><a href="https://spaceshipapps.ru/" target="_blank" rel="noopener noreferrer">spaceshipapps.ru</a></p>
|
||||
</div>
|
||||
<p class="resume-exp__desc">Студия разработки мобильных приложений и сайтов.</p>
|
||||
|
||||
<div class="resume-exp__section">
|
||||
<div class="resume-exp__cols">
|
||||
<div>
|
||||
<p class="resume-exp__label">Обязанности:</p>
|
||||
<ul>
|
||||
<li>Дизайн мобильных и веб-продуктов в потоковом режиме студии</li>
|
||||
<li>Работа с разными доменами: соцгейминг, бьюти-услуги, доставка еды, голосовые интерфейсы, легал-сервисы, коллаборативные инструменты</li>
|
||||
<li>Адаптивный веб-дизайн и дизайн административных панелей</li>
|
||||
<li>Отрисовка иконок и подготовка графики для проектов</li>
|
||||
<li>Подготовка макетов к передаче в разработку</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Достижения:</p>
|
||||
<ul>
|
||||
<li>Выпустил 6 продуктов за год: геолокационная социальная игра с квестами в реальном мире, приложение записи к бьюти-специалистам, сервис доставки еды, голосовая игра со словами, сайт и админка сервиса регистрации авторского права, мобильная «белая доска» для совместной работы</li>
|
||||
<li>Научился быстро входить в новую предметную область и держать качество при высоком темпе студии</li>
|
||||
<li>Закрыл весь спектр задач: мобайл, веб, админ-панели, графика</li>
|
||||
<li>Заложил базу для перехода от исполнительского дизайна к продуктовому</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p class="resume-exp__label">Стэк:</p>
|
||||
<ul>
|
||||
<li>Мобайл</li>
|
||||
<li>Веб</li>
|
||||
<li>Админ-панели</li>
|
||||
<li>Графика</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="skills">Навыки</h2>
|
||||
<div class="resume-skills">
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Проектирование</p>
|
||||
<p class="resume-skill__desc">UX/UI, product design, информационная архитектура, адаптивный дизайн, дизайн-системы</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Исследования</p>
|
||||
<p class="resume-skill__desc">Интервью, опросы, usability testing, JTBD, карты эмпатии, конверсия, retention, NPS</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Инструменты</p>
|
||||
<p class="resume-skill__desc">Figma, Protopie, Sketch, Adobe Creative Suite, Tilda, AI-инструменты</p>
|
||||
</div>
|
||||
<div class="resume-skill">
|
||||
<p class="resume-skill__title">Управление</p>
|
||||
<p class="resume-skill__desc">Построение команды, Agile, Kanban, авторский надзор, работа со стейкхолдерами</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="about">О себе</h2>
|
||||
<p class="section__prose resume-about">
|
||||
В дизайне больше 10 лет, последние годы — продуктовый дизайн сложных B2B-продуктов. Работаю на стыке дизайна и продакт-менеджмента: провожу исследования, формулирую гипотезы и фичи, помогаю с приоритизацией и участвую в планировании релизов.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Люблю разбираться в сложном и делать его понятным — поэтому мне комфортно в продуктах вроде IDE, оркестраторов и ML-панелей, где обычному дизайнеру скучно или страшно.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Не жду, пока задачу сделает кто-то другой: пишу себе инструменты сам. Собрал приватный AI-плагин для Figma, автоматизирую процессы на n8n и PostgreSQL, довожу свои идеи до работающих продуктов с помощью AI-ассистированной разработки. Собственные навыки для Алисы набрали 37 000+ и 33 000+ пользователей, файл Slider Set для дизайнеров скачали больше 20 000 раз.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Участвую в жизни сообщества: веду Telegram-канал «Дизайн не пицца», выкладываю полезности в Figma Community, выступал на митапе Яндекса с докладом по аналитике, побеждал на хакатонах — самая приятная победа на хакатоне Яндекс.Денег в Петербурге за приложение оплаты по QR-коду.
|
||||
</p>
|
||||
<p class="section__prose resume-about">
|
||||
Английский — B1. Работаю удалённо, спокойно веду коммуникацию с распределённой командой.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{> footer}}
|
||||
{{> cookie-notice}}
|
||||
<script>
|
||||
(function () {
|
||||
var printBtn = document.querySelector('[data-resume-print-btn]');
|
||||
if (!printBtn) return;
|
||||
|
||||
printBtn.addEventListener('click', function () {
|
||||
var doc = document.querySelector('.resume-doc');
|
||||
if (!doc) return;
|
||||
|
||||
var styles = [];
|
||||
document.querySelectorAll('link[rel="stylesheet"]').forEach(function (l) {
|
||||
styles.push('<link rel="stylesheet" href="' + l.href + '">');
|
||||
});
|
||||
document.querySelectorAll('style').forEach(function (s) {
|
||||
styles.push('<style>' + s.textContent + '</style>');
|
||||
});
|
||||
|
||||
var win = window.open('', '_blank');
|
||||
if (!win) return;
|
||||
win.document.write(
|
||||
'<!DOCTYPE html><html><head><meta charset="utf-8">' +
|
||||
styles.join('') +
|
||||
'<style>@media print{body{margin:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;}}</style>' +
|
||||
'</head><body>' + doc.outerHTML + '</body></html>'
|
||||
);
|
||||
win.document.close();
|
||||
win.onload = function () {
|
||||
setTimeout(function () { win.print(); }, 500);
|
||||
};
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,11 +1,11 @@
|
||||
<section id="contact" class="section section--surface section--footerish">
|
||||
<section id="contact" class="section section--surface section--footerish" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Контакты</h2>
|
||||
<ul class="contact-grid">
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-tg" href="https://t.me/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="{{assetPrefix}}assets/shared/icons/tg.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Telegram</span><span class="contact-card__hint">Отвечу сегодня</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-vk" href="https://vk.com/mamadaevv" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="{{assetPrefix}}assets/shared/icons/vk.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">ВКонтакте</span><span class="contact-card__hint">Стабильный коннект</span></span></a></li>
|
||||
<li><a class="contact-card contact-card--link contact-card--brand-ya" href="https://yandex.ru/chat/p/727e71fa-89b5-44a8-90a5-851021631a1c?utm_source=invite" rel="noopener noreferrer"><span class="contact-card__corner" aria-hidden="true"></span><span class="contact-card__icon" aria-hidden="true"><img src="{{assetPrefix}}assets/shared/icons/yandex_telemost.svg" alt="" width="24" height="24" loading="eager" decoding="async" /></span><span class="contact-card__body"><span class="contact-card__name">Яндекс</span><span class="contact-card__hint">Да, тут тоже можно</span></span></a></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5ydQ==" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
<li><button type="button" class="contact-card contact-card--action contact-card--brand-email" data-contact-copy data-email-b64="bmlrQG1hbWFkYWV2di5zaXRl" data-hint-default="Скопировать адрес" aria-label="Скопировать адрес электронной почты в буфер обмена"><span class="contact-card__corner contact-card__corner--copy" aria-hidden="true"></span><span class="contact-card__icon contact-card__icon--accent" aria-hidden="true"></span><span class="contact-card__body"><span class="contact-card__name">Почта</span><span class="contact-card__hint" data-contact-copy-hint>Скопировать адрес</span></span></button></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,11 @@
|
||||
<div class="fab-stack" aria-label="Быстрые действия">
|
||||
<div class="theme-panel-fab-wrap">
|
||||
<button type="button" class="fab fab--secondary glass-neutral" data-resume-print-btn aria-label="Печать резюме">
|
||||
<span class="fab-secondary__ico fab-secondary__ico--print" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<a href="/assets/resume/Mamadaev_Nik__CV__Product_Designer_UX-UI.pdf" download="Mamadaev_Nik__CV__Product_Designer_UX-UI.pdf" class="fab fab--primary fab--label" aria-label="Скачать резюме в PDF">
|
||||
<span class="fab-primary__ico fab-primary__ico--pdf" aria-hidden="true"></span>
|
||||
<span class="fab__label">Скачать в PDF</span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -1,4 +1,4 @@
|
||||
<section id="mini-projects" class="section section--surface" aria-labelledby="mini-projects-title">
|
||||
<section id="mini-projects" class="section section--surface" aria-labelledby="mini-projects-title" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 id="mini-projects-title" class="section__title">Активность</h2>
|
||||
<div
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<section id="projects" class="section section--surface">
|
||||
<section id="projects" class="section section--surface" data-reveal>
|
||||
<div class="section__inner">
|
||||
<h2 class="section__title">Портфолио</h2>
|
||||
<ol class="mini-projects-grid" data-mini-projects-list>
|
||||
|
||||
@@ -26,6 +26,30 @@
|
||||
var L = Number(l);
|
||||
if (Number.isFinite(L)) d.style.setProperty("--theme-l", String(Math.min(70, Math.max(20, L))));
|
||||
}
|
||||
var hVal = h !== null ? h : 210;
|
||||
var sVal = s !== null ? s : 90;
|
||||
var lVal = l !== null ? Math.min(70, Math.max(20, Number(l))) : 40;
|
||||
var H = (((hVal % 360) + 360) % 360) / 360;
|
||||
var S = Math.min(100, Math.max(0, sVal)) / 100;
|
||||
var Lv = Math.min(100, Math.max(0, lVal)) / 100;
|
||||
var r, g, b;
|
||||
if (S === 0) { r = g = b = Lv; }
|
||||
else {
|
||||
var q = Lv < 0.5 ? Lv * (1 + S) : Lv + S - Lv * S;
|
||||
var p = 2 * Lv - q;
|
||||
var hue2rgb = function(p, q, t) {
|
||||
if (t < 0) t += 1; if (t > 1) t -= 1;
|
||||
if (t < 1/6) return p + (q - p) * 6 * t;
|
||||
if (t < 1/2) return q;
|
||||
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
return p;
|
||||
};
|
||||
r = hue2rgb(p, q, H + 1/3);
|
||||
g = hue2rgb(p, q, H);
|
||||
b = hue2rgb(p, q, H - 1/3);
|
||||
}
|
||||
var lum = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
d.style.setProperty("--on-accent", lum > 0.58 ? "hsl(220 14% 12%)" : "hsl(0 0% 98%)");
|
||||
var rad = t.radius;
|
||||
if (rad === "soft" || rad === "medium" || rad === "strong") {
|
||||
d.dataset.radius = rad;
|
||||
|
||||
@@ -1,21 +1,6 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"updatedAt": "2026-08-10T16:53:19.518Z",
|
||||
"items": [],
|
||||
"lastAppliedAt": "2026-06-06T11:54:50.470Z"
|
||||
}
|
||||
Reference in new issue
Block a user