Pulse: добавлены блоки Нематериальная мотивация, КПД, Кадровый резерв

This commit is contained in:
Katipa 2026-08-21 10:28:48 +00:00
parent ecf7e3277f
commit 4f82da47bb
4 changed files with 949 additions and 1 deletions

176
app.js
View File

@ -11,6 +11,9 @@ document.addEventListener('DOMContentLoaded', () => {
initFilters();
initModals();
renderCharts();
loadMotivation();
loadKPI();
loadReserve();
});
// Навигация между секциями
@ -247,6 +250,63 @@ function initForms() {
e.target.reset();
});
// Форма благодарности
document.getElementById('thankFormEl').addEventListener('submit', (e) => {
e.preventDefault();
const thank = {
id: Date.now(),
to: document.getElementById('thankTo').value,
from: document.getElementById('thankAnonymous').checked ? 'Анонимно' : appData.profile.name,
reason: document.getElementById('thankReason').value,
type: document.getElementById('thankType').value,
date: new Date().toISOString().split('T')[0],
anonymous: document.getElementById('thankAnonymous').checked
};
appData.motivation.thanks.unshift(thank);
saveData(appData);
document.getElementById('thankForm').style.display = 'none';
loadMotivation();
alert('Благодарность отправлена!');
});
// Цели КПД
document.getElementById('kpiGoalsForm').addEventListener('submit', (e) => {
e.preventDefault();
appData.kpi.goals = [
document.getElementById('kpiGoal1').value,
document.getElementById('kpiGoal2').value,
document.getElementById('kpiGoal3').value
];
saveData(appData);
alert('Цели сохранены!');
});
// Заявка в кадровый резерв
document.getElementById('reserveFormEl').addEventListener('submit', (e) => {
e.preventDefault();
const application = {
id: Date.now(),
position: document.getElementById('reservePosition').value,
experience: document.getElementById('reserveExperience').value,
motivation: document.getElementById('reserveMotivation').value,
skills: document.getElementById('reserveSkills').value,
date: new Date().toISOString().split('T')[0],
status: 'new'
};
appData.reserve.applications.push(application);
saveData(appData);
document.getElementById('reserveForm').style.display = 'none';
alert('Заявка подана! HR свяжется с вами.');
});
// Форма автоматизации
document.getElementById('automationForm').addEventListener('submit', (e) => {
e.preventDefault();
@ -423,6 +483,122 @@ window.closeModal = function(modalId) {
document.getElementById(modalId).classList.remove('active');
};
// Мотивация
function loadMotivation() {
const mot = appData.motivation;
if (mot.employeeOfMonth) {
const empEl = document.getElementById('employeeOfMonth');
if (empEl) {
empEl.innerHTML = `
<div class="badge-avatar">${mot.employeeOfMonth.avatar}</div>
<div class="badge-name">${mot.employeeOfMonth.name}</div>
<div class="badge-dept">${mot.employeeOfMonth.dept}</div>
`;
}
}
if (mot.ideaOfMonth) {
const ideaEl = document.getElementById('ideaOfMonth');
if (ideaEl) {
ideaEl.innerHTML = `
<div class="idea-badge-title">${mot.ideaOfMonth.title}</div>
<div class="idea-badge-author">${mot.ideaOfMonth.author}</div>
`;
}
}
const thanksList = document.getElementById('thanksList');
if (thanksList && mot.thanks) {
thanksList.innerHTML = mot.thanks.map(t => `
<div class="thank-card">
<div class="thank-header">
<span class="thank-to">${t.to}</span>
<span class="thank-type">${getThankTypeName(t.type)}</span>
</div>
<div class="thank-reason">${t.reason}</div>
<div class="thank-meta">
<span>От: ${t.anonymous ? 'Анонимно' : t.from}</span>
<span>${formatDate(t.date)}</span>
</div>
</div>
`).join('');
}
}
window.showThankForm = function() {
document.getElementById('thankForm').style.display = 'block';
document.getElementById('thankFormEl').reset();
};
window.nominateEmployee = function() {
alert('Форма номинации будет доступна в конце месяца');
};
window.loadAchievements = function() {
const achievements = appData.motivation.achievements;
const html = achievements.map(a => `
<div class="achievement-item">
<span class="achievement-icon">${a.icon}</span>
<span class="achievement-name">${a.name}</span>
<span class="achievement-count">x${a.count}</span>
</div>
`).join('');
alert('Ваши достижения:\n\n' + achievements.map(a => `${a.icon} ${a.name}: ${a.count}`).join('\n'));
};
function getThankTypeName(type) {
const names = {
help: 'За помощь',
mentor: 'За наставничество',
initiative: 'За инициативу',
team: 'За команду',
other: 'Другое'
};
return names[type] || type;
}
// КПД
function loadKPI() {
const kpi = appData.kpi;
document.getElementById('kpiValue').textContent = kpi.overall;
document.getElementById('kpiCirclePath').style.strokeDasharray = `${kpi.overall}, 100`;
const kpiChartCanvas = document.getElementById('kpiChartCanvas');
if (kpiChartCanvas) {
const ctx = kpiChartCanvas.getContext('2d');
drawLineChart(ctx, kpi.history, '#4A90E2', 400, 200);
}
}
// Кадровый резерв
function loadReserve() {
const participants = appData.reserve.participants;
const list = document.getElementById('participantsList');
if (list) {
list.innerHTML = participants.map(p => `
<div class="participant-card">
<div class="participant-avatar">👤</div>
<div class="participant-info">
<div class="participant-name">${p.name}</div>
<div class="participant-dept">${p.dept}</div>
<div class="participant-stage">Этап: ${p.stage}</div>
</div>
<div class="participant-progress">
<div class="progress-bar"><div class="progress-fill" style="width: ${p.progress}%"></div></div>
<span>${p.progress}%</span>
</div>
</div>
`).join('');
}
}
window.showReserveForm = function() {
document.getElementById('reserveForm').style.display = 'block';
document.getElementById('reserveForm').scrollIntoView({ behavior: 'smooth' });
};
window.resetFeedbackForm = function() {
document.getElementById('feedbackForm').reset();
document.getElementById('feedbackForm').style.display = 'flex';

35
data.js
View File

@ -35,9 +35,42 @@ const INITIAL_DATA = {
},
settings: {
engagementIndex: 78,
engagementTrend: 'up', // up, stable, down
engagementTrend: 'up',
totalEmployees: 245,
departments: ['hr', 'it', 'finance', 'procurement', 'sales', 'support']
},
motivation: {
employeeOfMonth: { name: 'Алексей К.', dept: 'IT Департамент', avatar: '👤' },
ideaOfMonth: { title: 'Чат-бот для HR', author: 'Сергей Л.' },
thanks: [
{ id: 1, to: 'Мария С.', from: 'Александр И.', reason: 'За помощь в обучении новой системы', type: 'help', date: '2026-08-18', anonymous: false },
{ id: 2, to: 'Дмитрий В.', from: 'Анонимно', reason: 'За наставничество и поддержку', type: 'mentor', date: '2026-08-17', anonymous: true },
{ id: 3, to: 'Ольга Н.', from: 'Анна П.', reason: 'За инициативу в оптимизации закупок', type: 'initiative', date: '2026-08-15', anonymous: false }
],
achievements: [
{ id: 1, name: 'Новичок года', icon: '🌟', count: 1 },
{ id: 2, name: 'Генератор идей', icon: '💡', count: 3 },
{ id: 3, name: 'Наставник', icon: '🎓', count: 2 }
]
},
kpi: {
overall: 75,
components: {
tasks: 85,
deadlines: 78,
quality: 82,
initiative: 65,
team: 88
},
history: [68, 70, 72, 71, 74, 75],
goals: ['', '', '']
},
reserve: {
participants: [
{ id: 1, name: 'Мария С.', dept: 'HR Департамент', stage: 'Обучение', progress: 50 },
{ id: 2, name: 'Дмитрий В.', dept: 'IT Департамент', stage: 'Стажировка', progress: 75 }
],
applications: []
}
};

View File

@ -20,6 +20,9 @@
<a href="#" class="nav-link" data-section="discipline">Трудовая дисциплина</a>
<a href="#" class="nav-link" data-section="automation">Автоматизация</a>
<a href="#" class="nav-link" data-section="ideas">Инновации</a>
<a href="#" class="nav-link" data-section="motivation">Мотивация</a>
<a href="#" class="nav-link" data-section="kpi">КПД</a>
<a href="#" class="nav-link" data-section="reserve">Кадровый резерв</a>
<a href="#" class="nav-link" data-section="feedback">Обратная связь</a>
<a href="#" class="nav-link" data-section="profile">Профиль</a>
<a href="#" class="nav-link" data-section="analytics">Аналитика</a>
@ -410,6 +413,296 @@
</div>
</section>
<!-- Секция: Нематериальная мотивация -->
<section id="motivation" class="section">
<div class="section-header">
<h1>Нематериальная мотивация</h1>
<p class="section-subtitle">Признание заслуг и поощрение сотрудников</p>
</div>
<div class="motivation-grid">
<div class="motivation-card highlight">
<h3>🏆 Сотрудник месяца</h3>
<p>Лучший сотрудник по итогам месяца</p>
<div class="employee-badge" id="employeeOfMonth">
<div class="badge-avatar">👤</div>
<div class="badge-name">Алексей К.</div>
<div class="badge-dept">IT Департамент</div>
</div>
<button class="btn-secondary" onclick="nominateEmployee()">Номинировать</button>
</div>
<div class="motivation-card">
<h3>⭐ Благодарности</h3>
<p>Поблагодарите коллегу за помощь</p>
<button class="btn-secondary" onclick="showThankForm()">Отправить благодарность</button>
</div>
<div class="motivation-card">
<h3>🎖 Достижения</h3>
<p>Ваши награды и значки</p>
<button class="btn-secondary" onclick="loadAchievements()">Мои достижения</button>
</div>
<div class="motivation-card">
<h3>💡 Идея месяца</h3>
<p>Лучшая идея месяца</p>
<div class="idea-badge" id="ideaOfMonth">
<div class="idea-badge-title">Чат-бот для HR</div>
<div class="idea-badge-author">Сергей Л.</div>
</div>
</div>
</div>
<div class="thanks-wall" id="thanksWall">
<h2>Стена благодарностей</h2>
<div class="thanks-list" id="thanksList"></div>
</div>
<div id="thankForm" class="thank-form" style="display: none;">
<h3>Отправить благодарность</h3>
<form id="thankFormEl">
<div class="form-group">
<label for="thankTo">Кому</label>
<input type="text" id="thankTo" placeholder="ФИО сотрудника" required>
</div>
<div class="form-group">
<label for="thankReason">За что</label>
<textarea id="thankReason" rows="3" placeholder="Опишите, за что благодарите" required></textarea>
</div>
<div class="form-group">
<label for="thankType">Тип благодарности</label>
<select id="thankType" required>
<option value="help">За помощь в работе</option>
<option value="mentor">За наставничество</option>
<option value="initiative">За инициативу</option>
<option value="team">За командную работу</option>
<option value="other">Другое</option>
</select>
</div>
<div class="form-group checkbox-group">
<label class="checkbox-label">
<input type="checkbox" id="thankAnonymous">
<span class="checkbox-text">Отправить анонимно</span>
</label>
</div>
<button type="submit" class="btn-primary">Отправить благодарность</button>
</form>
</div>
</section>
<!-- Секция: КПД (Коэффициент Полезного Действия) -->
<section id="kpi" class="section">
<div class="section-header">
<h1>КПД сотрудника</h1>
<p class="section-subtitle">Оценка эффективности и продуктивности</p>
</div>
<div class="kpi-employee-card">
<div class="kpi-employee-header">
<div class="kpi-avatar">👤</div>
<div>
<h2 id="kpiEmployeeName">Александр Иванов</h2>
<p class="kpi-dept">IT Департамент</p>
</div>
</div>
<div class="kpi-score">
<div class="kpi-circle">
<svg viewBox="0 0 36 36" class="kpi-svg">
<path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="#E5E7EB" stroke-width="2"/>
<path id="kpiCirclePath" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" fill="none" stroke="#4A90E2" stroke-width="2" stroke-dasharray="75, 100"/>
</svg>
<div class="kpi-value" id="kpiValue">75</div>
</div>
<div class="kpi-label">Общий КПД</div>
</div>
<div class="kpi-components">
<div class="kpi-component">
<div class="kpi-comp-label">Выполнение задач</div>
<div class="kpi-bar"><div class="kpi-bar-fill" style="width: 85%"></div></div>
<div class="kpi-comp-value">85%</div>
</div>
<div class="kpi-component">
<div class="kpi-comp-label">Соблюдение сроков</div>
<div class="kpi-bar"><div class="kpi-bar-fill" style="width: 78%"></div></div>
<div class="kpi-comp-value">78%</div>
</div>
<div class="kpi-component">
<div class="kpi-comp-label">Качество работы</div>
<div class="kpi-bar"><div class="kpi-bar-fill" style="width: 82%"></div></div>
<div class="kpi-comp-value">82%</div>
</div>
<div class="kpi-component">
<div class="kpi-comp-label">Инициативность</div>
<div class="kpi-bar"><div class="kpi-bar-fill" style="width: 65%"></div></div>
<div class="kpi-comp-value">65%</div>
</div>
<div class="kpi-component">
<div class="kpi-comp-label">Командная работа</div>
<div class="kpi-bar"><div class="kpi-bar-fill" style="width: 88%"></div></div>
<div class="kpi-comp-value">88%</div>
</div>
</div>
</div>
<div class="kpi-dynamics">
<h3>Динамика КПД</h3>
<div class="kpi-chart">
<canvas id="kpiChartCanvas"></canvas>
</div>
</div>
<div class="kpi-goals">
<h3>Цели на следующий период</h3>
<form id="kpiGoalsForm">
<div class="form-group">
<label for="kpiGoal1">Цель 1</label>
<input type="text" id="kpiGoal1" placeholder="Например: завершить проект X до конца месяца">
</div>
<div class="form-group">
<label for="kpiGoal2">Цель 2</label>
<input type="text" id="kpiGoal2" placeholder="Например: пройти обучение по Y">
</div>
<div class="form-group">
<label for="kpiGoal3">Цель 3</label>
<input type="text" id="kpiGoal3" placeholder="Например: оптимизировать процесс Z">
</div>
<button type="submit" class="btn-primary">Сохранить цели</button>
</form>
</div>
</section>
<!-- Секция: Кадровый резерв -->
<section id="reserve" class="section">
<div class="section-header">
<h1>Кадровый резерв</h1>
<p class="section-subtitle">Программа развития и подготовки руководителей</p>
</div>
<div class="reserve-info">
<div class="reserve-banner">
<h2>🎯 Программа кадрового резерва</h2>
<p>Участвуйте в программе подготовки руководителей и получите возможность карьерного роста</p>
<button class="btn-primary" onclick="showReserveForm()">Подать заявку</button>
</div>
</div>
<div class="reserve-requirements">
<h3>Требования для участия</h3>
<div class="requirements-grid">
<div class="requirement-card">
<div class="req-icon">📊</div>
<div class="req-title">Стаж работы</div>
<div class="req-desc">Не менее 2 лет в компании</div>
</div>
<div class="requirement-card">
<div class="req-icon">⭐</div>
<div class="req-title">Рейтинг</div>
<div class="req-desc">КПД не ниже 75%</div>
</div>
<div class="requirement-card">
<div class="req-icon">🎓</div>
<div class="req-title">Обучение</div>
<div class="req-desc">Пройденные курсы лидерства</div>
</div>
<div class="requirement-card">
<div class="req-icon">💡</div>
<div class="req-title">Инициативы</div>
<div class="req-desc">Реализованные проекты</div>
</div>
</div>
</div>
<div class="reserve-program">
<h3>Этапы программы</h3>
<div class="stages-timeline">
<div class="stage">
<div class="stage-dot">1</div>
<div class="stage-content">
<h4>Отборочный этап</h4>
<p>Собеседование с HR, оценка компетенций</p>
</div>
</div>
<div class="stage">
<div class="stage-dot">2</div>
<div class="stage-content">
<h4>Обучение</h4>
<p>Курсы по управлению, лидерству, коммуникациям</p>
</div>
</div>
<div class="stage">
<div class="stage-dot">3</div>
<div class="stage-content">
<h4>Стажировка</h4>
<p>Практика под руководством наставника</p>
</div>
</div>
<div class="stage">
<div class="stage-dot">4</div>
<div class="stage-content">
<h4>Аттестация</h4>
<p>Финальная оценка и включение в резерв</p>
</div>
</div>
</div>
</div>
<div class="reserve-participants">
<h3>Текущие участники программы</h3>
<div class="participants-list" id="participantsList">
<div class="participant-card">
<div class="participant-avatar">👤</div>
<div class="participant-info">
<div class="participant-name">Мария С.</div>
<div class="participant-dept">HR Департамент</div>
<div class="participant-stage">Этап: Обучение</div>
</div>
<div class="participant-progress">
<div class="progress-bar"><div class="progress-fill" style="width: 50%"></div></div>
<span>50%</span>
</div>
</div>
<div class="participant-card">
<div class="participant-avatar">👤</div>
<div class="participant-info">
<div class="participant-name">Дмитрий В.</div>
<div class="participant-dept">IT Департамент</div>
<div class="participant-stage">Этап: Стажировка</div>
</div>
<div class="participant-progress">
<div class="progress-bar"><div class="progress-fill" style="width: 75%"></div></div>
<span>75%</span>
</div>
</div>
</div>
</div>
<div id="reserveForm" class="reserve-form" style="display: none;">
<h3>Заявка на участие в кадровом резерве</h3>
<form id="reserveFormEl">
<div class="form-group">
<label for="reservePosition">Желаемая должность</label>
<input type="text" id="reservePosition" placeholder="Например: Руководитель отдела" required>
</div>
<div class="form-group">
<label for="reserveExperience">Опыт работы</label>
<textarea id="reserveExperience" rows="3" placeholder="Опишите ваш опыт и достижения" required></textarea>
</div>
<div class="form-group">
<label for="reserveMotivation">Мотивация</label>
<textarea id="reserveMotivation" rows="4" placeholder="Почему вы хотите участвовать в программе?" required></textarea>
</div>
<div class="form-group">
<label for="reserveSkills">Ключевые навыки</label>
<input type="text" id="reserveSkills" placeholder="Перечислите через запятую">
</div>
<button type="submit" class="btn-primary">Подать заявку</button>
</form>
</div>
</section>
<!-- Секция: Аналитика (HR/Руководители) -->
<section id="analytics" class="section">
<div class="section-header">

446
style.css
View File

@ -836,6 +836,452 @@ textarea {
color: var(--primary);
}
/* Motivation */
.motivation-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 20px;
margin-bottom: 32px;
}
.motivation-card {
background: var(--white);
padding: 24px;
border-radius: 12px;
box-shadow: var(--shadow);
text-align: center;
}
.motivation-card.highlight {
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: var(--white);
}
.motivation-card h3 {
font-size: 18px;
margin-bottom: 8px;
}
.motivation-card p {
color: var(--text-gray);
margin-bottom: 16px;
font-size: 14px;
}
.motivation-card.highlight p {
color: rgba(255,255,255,0.9);
}
.employee-badge,
.idea-badge {
background: rgba(255,255,255,0.2);
padding: 16px;
border-radius: 8px;
margin-bottom: 16px;
}
.badge-avatar {
font-size: 48px;
margin-bottom: 8px;
}
.badge-name {
font-size: 18px;
font-weight: 600;
margin-bottom: 4px;
}
.badge-dept {
font-size: 14px;
opacity: 0.9;
}
.idea-badge-title {
font-size: 16px;
font-weight: 600;
margin-bottom: 4px;
}
.idea-badge-author {
font-size: 14px;
opacity: 0.9;
}
.thanks-wall {
background: var(--white);
padding: 24px;
border-radius: 12px;
box-shadow: var(--shadow);
margin-top: 24px;
}
.thanks-wall h2 {
font-size: 20px;
margin-bottom: 16px;
}
.thanks-list {
display: grid;
gap: 16px;
}
.thank-card {
border: 1px solid var(--border);
border-radius: 8px;
padding: 16px;
background: var(--bg-light);
}
.thank-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.thank-to {
font-weight: 600;
font-size: 16px;
}
.thank-type {
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
background: var(--primary-light);
color: var(--primary);
}
.thank-reason {
color: var(--text-dark);
margin-bottom: 8px;
}
.thank-meta {
display: flex;
gap: 16px;
font-size: 13px;
color: var(--text-gray);
}
.thank-form {
background: var(--white);
padding: 32px;
border-radius: 12px;
box-shadow: var(--shadow);
margin-top: 24px;
max-width: 600px;
}
.thank-form h3 {
margin-bottom: 20px;
}
/* KPI Employee */
.kpi-employee-card {
background: var(--white);
padding: 32px;
border-radius: 12px;
box-shadow: var(--shadow);
margin-bottom: 24px;
}
.kpi-employee-header {
display: flex;
align-items: center;
gap: 20px;
margin-bottom: 32px;
}
.kpi-avatar {
font-size: 64px;
}
.kpi-employee-header h2 {
font-size: 24px;
margin-bottom: 4px;
}
.kpi-dept {
color: var(--text-gray);
}
.kpi-score {
text-align: center;
margin-bottom: 32px;
}
.kpi-circle {
position: relative;
width: 150px;
height: 150px;
margin: 0 auto 16px;
}
.kpi-svg {
width: 100%;
height: 100%;
transform: rotate(-90deg);
}
.kpi-value {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 36px;
font-weight: 700;
color: var(--primary);
}
.kpi-label {
font-size: 16px;
color: var(--text-gray);
}
.kpi-components {
display: grid;
gap: 16px;
max-width: 600px;
margin: 0 auto;
}
.kpi-component {
display: grid;
grid-template-columns: 1fr 80px 50px;
align-items: center;
gap: 12px;
}
.kpi-comp-label {
font-size: 14px;
color: var(--text-gray);
}
.kpi-bar {
height: 8px;
background: var(--border);
border-radius: 4px;
overflow: hidden;
}
.kpi-bar-fill {
height: 100%;
background: var(--primary);
border-radius: 4px;
transition: width 0.3s;
}
.kpi-comp-value {
font-weight: 600;
color: var(--primary);
font-size: 14px;
}
.kpi-dynamics,
.kpi-goals {
background: var(--white);
padding: 24px;
border-radius: 12px;
box-shadow: var(--shadow);
margin-bottom: 24px;
}
.kpi-dynamics h3,
.kpi-goals h3 {
margin-bottom: 16px;
}
.kpi-chart {
height: 250px;
background: var(--bg-light);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
}
.kpi-goals form {
max-width: 600px;
display: flex;
flex-direction: column;
gap: 16px;
}
/* Reserve */
.reserve-info {
margin-bottom: 32px;
}
.reserve-banner {
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: var(--white);
padding: 40px;
border-radius: 12px;
text-align: center;
}
.reserve-banner h2 {
font-size: 28px;
margin-bottom: 12px;
}
.reserve-banner p {
font-size: 16px;
margin-bottom: 24px;
opacity: 0.95;
}
.reserve-requirements,
.reserve-program,
.reserve-participants {
background: var(--white);
padding: 24px;
border-radius: 12px;
box-shadow: var(--shadow);
margin-bottom: 24px;
}
.reserve-requirements h3,
.reserve-program h3,
.reserve-participants h3 {
margin-bottom: 20px;
}
.requirements-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
}
.requirement-card {
background: var(--bg-light);
padding: 20px;
border-radius: 8px;
text-align: center;
}
.req-icon {
font-size: 36px;
margin-bottom: 12px;
}
.req-title {
font-weight: 600;
margin-bottom: 8px;
}
.req-desc {
font-size: 14px;
color: var(--text-gray);
}
.stages-timeline {
display: grid;
gap: 20px;
}
.stage {
display: flex;
gap: 16px;
align-items: flex-start;
}
.stage-dot {
width: 40px;
height: 40px;
border-radius: 50%;
background: var(--primary);
color: var(--white);
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
flex-shrink: 0;
}
.stage-content h4 {
font-size: 18px;
margin-bottom: 4px;
}
.stage-content p {
color: var(--text-gray);
font-size: 14px;
}
.participants-list {
display: grid;
gap: 16px;
}
.participant-card {
display: flex;
align-items: center;
gap: 16px;
padding: 16px;
border: 1px solid var(--border);
border-radius: 8px;
}
.participant-avatar {
font-size: 40px;
}
.participant-info {
flex: 1;
}
.participant-name {
font-weight: 600;
margin-bottom: 4px;
}
.participant-dept {
font-size: 13px;
color: var(--text-gray);
margin-bottom: 4px;
}
.participant-stage {
font-size: 13px;
color: var(--primary);
}
.participant-progress {
display: flex;
align-items: center;
gap: 12px;
min-width: 120px;
}
.progress-bar {
flex: 1;
height: 8px;
background: var(--border);
border-radius: 4px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background: var(--primary);
border-radius: 4px;
transition: width 0.3s;
}
.reserve-form {
background: var(--white);
padding: 32px;
border-radius: 12px;
box-shadow: var(--shadow);
max-width: 700px;
}
.reserve-form h3 {
margin-bottom: 20px;
}
/* Modal */
.modal {
display: none;