monacousa-portal/design-mockups/pages/board/ProfessionalBoardDashboard.vue

1249 lines
31 KiB
Vue

<template>
<div class="board-dashboard">
<!-- Sidebar Navigation -->
<aside :class="['sidebar', { 'sidebar--collapsed': sidebarCollapsed }]">
<div class="sidebar__header">
<div class="sidebar__logo">
<img src="/MONACOUSA-Flags_376x376.png" alt="MonacoUSA" class="sidebar__logo-img" />
<span v-if="!sidebarCollapsed" class="sidebar__logo-text">Board Portal</span>
</div>
<button @click="sidebarCollapsed = !sidebarCollapsed" class="sidebar__toggle">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
:d="sidebarCollapsed ? 'M13 5l7 7-7 7' : 'M11 19l-7-7 7-7'" />
</svg>
</button>
</div>
<nav class="sidebar__nav">
<a v-for="item in boardNavItems" :key="item.name"
:href="item.path"
:class="['sidebar__nav-item', { 'sidebar__nav-item--active': item.active }]">
<component :is="item.icon" class="sidebar__nav-icon" />
<span v-if="!sidebarCollapsed" class="sidebar__nav-label">{{ item.name }}</span>
</a>
</nav>
<div class="sidebar__footer">
<div class="sidebar__profile">
<div class="sidebar__profile-avatar">
<img src="https://ui-avatars.com/api/?name=Board+Member&background=DC2626&color=fff" alt="Profile" />
</div>
<div v-if="!sidebarCollapsed" class="sidebar__profile-info">
<span class="sidebar__profile-name">Board Member</span>
<span class="sidebar__profile-role">Executive Board</span>
</div>
</div>
</div>
</aside>
<!-- Main Content -->
<main class="main-content">
<!-- Top Bar -->
<header class="topbar">
<div class="topbar__left">
<h1 class="topbar__title">Board Overview</h1>
<span class="topbar__subtitle">Strategic Insights & Governance</span>
</div>
<div class="topbar__right">
<button class="topbar__notification">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
<span class="topbar__notification-badge">3</span>
</button>
<div class="topbar__date">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
{{ currentDate }}
</div>
</div>
</header>
<!-- Executive Summary Cards -->
<section class="executive-summary">
<StatCard
v-for="metric in executiveMetrics"
:key="metric.label"
:label="metric.label"
:value="metric.value"
:trend="metric.trend"
:prefix="metric.prefix"
:variant="metric.variant"
:icon="metric.icon"
:description="metric.description"
:format="metric.format"
/>
</section>
<!-- Strategic Insights Grid -->
<div class="insights-grid">
<!-- Financial Performance Chart -->
<NeumorphicCard class="financial-chart">
<template #header>
<div class="card-header">
<h2 class="card-title">Financial Performance</h2>
<div class="card-actions">
<select class="period-selector">
<option>Quarterly</option>
<option>Monthly</option>
<option>Yearly</option>
</select>
</div>
</div>
</template>
<div class="chart-container">
<canvas ref="financialChart"></canvas>
</div>
<template #footer>
<div class="chart-legend">
<span class="legend-item">
<span class="legend-dot" style="background: #DC2626"></span>
Revenue
</span>
<span class="legend-item">
<span class="legend-dot" style="background: #10B981"></span>
Profit
</span>
<span class="legend-item">
<span class="legend-dot" style="background: #3B82F6"></span>
Expenses
</span>
</div>
</template>
</NeumorphicCard>
<!-- Key Performance Indicators -->
<NeumorphicCard class="kpi-card">
<template #header>
<h2 class="card-title">Key Performance Indicators</h2>
</template>
<div class="kpi-list">
<div v-for="kpi in keyPerformanceIndicators" :key="kpi.name" class="kpi-item">
<div class="kpi-header">
<span class="kpi-name">{{ kpi.name }}</span>
<span :class="['kpi-status', `kpi-status--${kpi.status}`]">
{{ kpi.status }}
</span>
</div>
<div class="kpi-progress">
<div class="kpi-progress-bar">
<div class="kpi-progress-fill"
:style="{ width: `${kpi.progress}%` }"
:class="`kpi-progress-fill--${kpi.status}`"></div>
</div>
<span class="kpi-value">{{ kpi.value }} / {{ kpi.target }}</span>
</div>
</div>
</div>
</NeumorphicCard>
</div>
<!-- Board Activities and Decisions -->
<div class="board-grid">
<!-- Upcoming Board Meetings -->
<NeumorphicCard class="meetings-card">
<template #header>
<h2 class="card-title">Upcoming Board Meetings</h2>
</template>
<div class="meetings-list">
<div v-for="meeting in upcomingMeetings" :key="meeting.id" class="meeting-item">
<div class="meeting-date">
<span class="meeting-month">{{ meeting.month }}</span>
<span class="meeting-day">{{ meeting.day }}</span>
</div>
<div class="meeting-details">
<h3 class="meeting-title">{{ meeting.title }}</h3>
<p class="meeting-info">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
{{ meeting.time }} • {{ meeting.duration }}
</p>
<div class="meeting-attendees">
<img v-for="attendee in meeting.attendees.slice(0, 3)"
:key="attendee"
:src="`https://ui-avatars.com/api/?name=${attendee}&background=random`"
:alt="attendee"
class="attendee-avatar" />
<span v-if="meeting.attendees.length > 3" class="attendee-more">
+{{ meeting.attendees.length - 3 }}
</span>
</div>
</div>
<ProfessionalButton size="sm" variant="outline">
View Agenda
</ProfessionalButton>
</div>
</div>
</NeumorphicCard>
<!-- Recent Resolutions -->
<NeumorphicCard class="resolutions-card">
<template #header>
<div class="card-header">
<h2 class="card-title">Recent Resolutions</h2>
<ProfessionalButton size="sm" variant="ghost">View All</ProfessionalButton>
</div>
</template>
<div class="resolutions-list">
<div v-for="resolution in recentResolutions" :key="resolution.id" class="resolution-item">
<div class="resolution-status" :class="`resolution-status--${resolution.status}`">
<svg v-if="resolution.status === 'approved'" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
<svg v-else-if="resolution.status === 'pending'" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd" />
</svg>
<svg v-else fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</div>
<div class="resolution-content">
<h4 class="resolution-title">{{ resolution.title }}</h4>
<p class="resolution-description">{{ resolution.description }}</p>
<div class="resolution-meta">
<span class="resolution-date">{{ resolution.date }}</span>
<span class="resolution-votes">
{{ resolution.votesFor }}-{{ resolution.votesAgainst }}-{{ resolution.abstain }}
</span>
</div>
</div>
</div>
</div>
</NeumorphicCard>
</div>
<!-- Strategic Initiatives -->
<NeumorphicCard class="initiatives-card">
<template #header>
<div class="card-header">
<h2 class="card-title">Strategic Initiatives</h2>
<div class="card-actions">
<ProfessionalButton size="sm" variant="primary">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
</svg>
New Initiative
</ProfessionalButton>
</div>
</div>
</template>
<div class="initiatives-grid">
<div v-for="initiative in strategicInitiatives" :key="initiative.id" class="initiative-card">
<div class="initiative-header">
<span :class="['initiative-priority', `initiative-priority--${initiative.priority}`]">
{{ initiative.priority }} Priority
</span>
<span class="initiative-deadline">Due {{ initiative.deadline }}</span>
</div>
<h3 class="initiative-title">{{ initiative.title }}</h3>
<p class="initiative-description">{{ initiative.description }}</p>
<div class="initiative-progress">
<div class="progress-header">
<span class="progress-label">Progress</span>
<span class="progress-value">{{ initiative.progress }}%</span>
</div>
<div class="progress-bar">
<div class="progress-fill" :style="{ width: `${initiative.progress}%` }"></div>
</div>
</div>
<div class="initiative-team">
<img v-for="member in initiative.team.slice(0, 4)"
:key="member"
:src="`https://ui-avatars.com/api/?name=${member}&background=random`"
:alt="member"
class="team-avatar" />
<span v-if="initiative.team.length > 4" class="team-more">
+{{ initiative.team.length - 4 }}
</span>
</div>
</div>
</div>
</NeumorphicCard>
</main>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import Chart from 'chart.js/auto';
import NeumorphicCard from '../../components/core/NeumorphicCard.vue';
import ProfessionalButton from '../../components/core/ProfessionalButton.vue';
import StatCard from '../../components/core/StatCard.vue';
// Data
const sidebarCollapsed = ref(false);
const currentDate = ref(new Date().toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }));
const boardNavItems = [
{ name: 'Overview', path: '/board', icon: 'HomeIcon', active: true },
{ name: 'Financial Reports', path: '/board/financial', icon: 'ChartIcon' },
{ name: 'Governance', path: '/board/governance', icon: 'ShieldIcon' },
{ name: 'Committees', path: '/board/committees', icon: 'UsersIcon' },
{ name: 'Documents', path: '/board/documents', icon: 'DocumentIcon' },
{ name: 'Voting', path: '/board/voting', icon: 'VoteIcon' },
{ name: 'Calendar', path: '/board/calendar', icon: 'CalendarIcon' },
{ name: 'Communications', path: '/board/communications', icon: 'MailIcon' }
];
const executiveMetrics = [
{
label: 'Annual Revenue',
value: 8500000,
trend: 12.5,
prefix: '$',
variant: 'primary',
description: 'YoY Growth',
format: 'currency'
},
{
label: 'Net Profit Margin',
value: 18.3,
trend: 2.1,
suffix: '%',
variant: 'success',
description: 'Above industry average',
format: 'percentage'
},
{
label: 'Member Retention',
value: 94.2,
trend: 3.5,
suffix: '%',
variant: 'info',
description: 'Best in 5 years',
format: 'percentage'
},
{
label: 'Strategic Goals Met',
value: '14/16',
trend: 0,
variant: 'warning',
description: 'This quarter',
format: 'string'
}
];
const keyPerformanceIndicators = ref([
{ name: 'Revenue Growth', progress: 85, value: '8.5M', target: '10M', status: 'on-track' },
{ name: 'Cost Reduction', progress: 92, value: '920K', target: '1M', status: 'achieved' },
{ name: 'Member Acquisition', progress: 68, value: '340', target: '500', status: 'at-risk' },
{ name: 'Digital Transformation', progress: 75, value: '15', target: '20', status: 'on-track' },
{ name: 'ESG Score', progress: 88, value: '88', target: '100', status: 'on-track' }
]);
const upcomingMeetings = ref([
{
id: 1,
month: 'JAN',
day: '15',
title: 'Q1 Board Meeting',
time: '2:00 PM EST',
duration: '3 hours',
attendees: ['John D.', 'Sarah M.', 'Robert K.', 'Lisa T.', 'Michael B.']
},
{
id: 2,
month: 'FEB',
day: '10',
title: 'Strategic Planning Session',
time: '10:00 AM EST',
duration: 'Full day',
attendees: ['John D.', 'Sarah M.', 'Robert K.']
},
{
id: 3,
month: 'MAR',
day: '22',
title: 'Annual General Meeting',
time: '3:00 PM EST',
duration: '2 hours',
attendees: ['John D.', 'Sarah M.', 'Robert K.', 'Lisa T.']
}
]);
const recentResolutions = ref([
{
id: 1,
title: 'Technology Infrastructure Upgrade',
description: 'Approved $500K investment in cloud migration and cybersecurity enhancements.',
status: 'approved',
date: 'Dec 20, 2024',
votesFor: 7,
votesAgainst: 1,
abstain: 1
},
{
id: 2,
title: 'ESG Policy Framework',
description: 'Pending review of environmental, social, and governance policy implementation.',
status: 'pending',
date: 'Dec 28, 2024',
votesFor: 0,
votesAgainst: 0,
abstain: 0
},
{
id: 3,
title: 'Executive Compensation Review',
description: 'Approved revised compensation structure aligned with performance metrics.',
status: 'approved',
date: 'Dec 15, 2024',
votesFor: 8,
votesAgainst: 0,
abstain: 1
}
]);
const strategicInitiatives = ref([
{
id: 1,
title: 'Digital Member Experience',
description: 'Transform member journey through AI-powered personalization and seamless digital services.',
priority: 'high',
progress: 65,
deadline: 'Q2 2025',
team: ['Tech Team', 'UX Team', 'Data Team', 'Marketing', 'Operations']
},
{
id: 2,
title: 'International Expansion',
description: 'Establish presence in 3 new European markets with localized services and partnerships.',
priority: 'high',
progress: 40,
deadline: 'Q4 2025',
team: ['Business Dev', 'Legal', 'Marketing']
},
{
id: 3,
title: 'Sustainability Program',
description: 'Achieve carbon neutrality and implement comprehensive ESG reporting framework.',
priority: 'medium',
progress: 55,
deadline: 'Q3 2025',
team: ['Operations', 'Finance', 'Compliance', 'Facilities']
},
{
id: 4,
title: 'Partnership Network',
description: 'Build strategic alliances with 10+ industry leaders for enhanced member benefits.',
priority: 'medium',
progress: 30,
deadline: 'Q2 2025',
team: ['Business Dev', 'Legal']
}
]);
// Chart setup
const financialChart = ref(null);
onMounted(() => {
if (financialChart.value) {
new Chart(financialChart.value, {
type: 'line',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [
{
label: 'Revenue',
data: [1800000, 2100000, 2300000, 2300000],
borderColor: '#DC2626',
backgroundColor: 'rgba(220, 38, 38, 0.1)',
tension: 0.4
},
{
label: 'Profit',
data: [320000, 380000, 410000, 420000],
borderColor: '#10B981',
backgroundColor: 'rgba(16, 185, 129, 0.1)',
tension: 0.4
},
{
label: 'Expenses',
data: [1480000, 1720000, 1890000, 1880000],
borderColor: '#3B82F6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
tension: 0.4
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
}
},
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + (value / 1000000).toFixed(1) + 'M';
}
}
}
}
}
});
}
});
</script>
<style lang="scss" scoped>
@import '../../styles/neumorphic-system.scss';
.board-dashboard {
display: flex;
min-height: 100vh;
background: linear-gradient(135deg, $neutral-50 0%, $neutral-100 100%);
}
// Sidebar styles (same as admin dashboard)
.sidebar {
width: $sidebar-width;
background: linear-gradient(145deg, #ffffff, #f0f0f0);
box-shadow: $shadow-soft-lg;
display: flex;
flex-direction: column;
transition: width $transition-base $ease-in-out-soft;
position: relative;
z-index: 10;
&--collapsed {
width: $sidebar-width-collapsed;
}
&__header {
padding: $space-6;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid rgba($neutral-300, 0.3);
}
&__logo {
display: flex;
align-items: center;
gap: $space-3;
}
&__logo-img {
width: 40px;
height: 40px;
object-fit: contain;
}
&__logo-text {
font-family: $font-heading;
font-size: $text-lg;
font-weight: $font-bold;
color: $neutral-800;
}
&__toggle {
width: 32px;
height: 32px;
border: none;
background: $neutral-100;
border-radius: $radius-lg;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: $shadow-soft-sm;
transition: all $transition-base;
svg {
width: 16px;
height: 16px;
color: $neutral-600;
}
&:hover {
box-shadow: $shadow-soft-md;
}
&:active {
box-shadow: $shadow-inset-sm;
}
}
&__nav {
flex: 1;
padding: $space-4;
overflow-y: auto;
}
&__nav-item {
display: flex;
align-items: center;
gap: $space-3;
padding: $space-3 $space-4;
margin-bottom: $space-2;
border-radius: $radius-lg;
color: $neutral-700;
text-decoration: none;
transition: all $transition-base;
&:hover {
background: rgba($primary-500, 0.05);
color: $primary-600;
}
&--active {
background: linear-gradient(145deg, rgba($primary-500, 0.1), rgba($primary-600, 0.15));
color: $primary-600;
box-shadow: $shadow-inset-sm;
}
}
&__nav-icon {
width: 20px;
height: 20px;
flex-shrink: 0;
}
&__nav-label {
font-size: $text-sm;
font-weight: $font-medium;
}
&__footer {
padding: $space-4;
border-top: 1px solid rgba($neutral-300, 0.3);
}
&__profile {
display: flex;
align-items: center;
gap: $space-3;
}
&__profile-avatar {
width: 40px;
height: 40px;
border-radius: $radius-full;
overflow: hidden;
box-shadow: $shadow-soft-sm;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
&__profile-info {
display: flex;
flex-direction: column;
}
&__profile-name {
font-size: $text-sm;
font-weight: $font-semibold;
color: $neutral-800;
}
&__profile-role {
font-size: $text-xs;
color: $neutral-600;
}
}
// Main content
.main-content {
flex: 1;
padding: $space-8;
overflow-y: auto;
}
// Topbar
.topbar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: $space-8;
&__left {
display: flex;
flex-direction: column;
gap: $space-1;
}
&__title {
font-family: $font-heading;
font-size: $text-3xl;
font-weight: $font-bold;
color: $neutral-800;
}
&__subtitle {
font-size: $text-base;
color: $neutral-600;
}
&__right {
display: flex;
align-items: center;
gap: $space-4;
}
&__notification {
position: relative;
width: 44px;
height: 44px;
border: none;
background: linear-gradient(145deg, #ffffff, #f0f0f0);
border-radius: $radius-lg;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: $shadow-soft-sm;
transition: all $transition-base;
svg {
width: 20px;
height: 20px;
color: $neutral-600;
}
&:hover {
box-shadow: $shadow-soft-md;
}
}
&__notification-badge {
position: absolute;
top: 8px;
right: 8px;
width: 18px;
height: 18px;
background: $primary-500;
color: white;
border-radius: $radius-full;
font-size: $text-xs;
font-weight: $font-bold;
display: flex;
align-items: center;
justify-content: center;
}
&__date {
display: flex;
align-items: center;
gap: $space-2;
padding: $space-2 $space-4;
background: linear-gradient(145deg, #ffffff, #f0f0f0);
border-radius: $radius-lg;
box-shadow: $shadow-soft-sm;
svg {
width: 16px;
height: 16px;
color: $neutral-500;
}
font-size: $text-sm;
color: $neutral-700;
}
}
// Executive Summary
.executive-summary {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: $space-6;
margin-bottom: $space-8;
}
// Insights Grid
.insights-grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: $space-6;
margin-bottom: $space-8;
@media (max-width: $breakpoint-lg) {
grid-template-columns: 1fr;
}
}
// Board Grid
.board-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: $space-6;
margin-bottom: $space-8;
@media (max-width: $breakpoint-md) {
grid-template-columns: 1fr;
}
}
// Card styles
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.card-title {
font-family: $font-heading;
font-size: $text-xl;
font-weight: $font-semibold;
color: $neutral-800;
}
.card-actions {
display: flex;
gap: $space-2;
}
// Financial Chart
.financial-chart {
.chart-container {
height: 300px;
padding: $space-4 0;
}
.chart-legend {
display: flex;
justify-content: center;
gap: $space-6;
.legend-item {
display: flex;
align-items: center;
gap: $space-2;
font-size: $text-sm;
color: $neutral-600;
}
.legend-dot {
width: 12px;
height: 12px;
border-radius: $radius-full;
}
}
}
.period-selector {
padding: $space-2 $space-3;
background: $neutral-50;
border: none;
border-radius: $radius-md;
box-shadow: $shadow-inset-sm;
font-size: $text-sm;
color: $neutral-700;
cursor: pointer;
}
// KPI Card
.kpi-list {
display: flex;
flex-direction: column;
gap: $space-4;
}
.kpi-item {
padding: $space-3;
background: rgba($neutral-100, 0.5);
border-radius: $radius-lg;
}
.kpi-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: $space-2;
}
.kpi-name {
font-size: $text-sm;
font-weight: $font-medium;
color: $neutral-700;
}
.kpi-status {
font-size: $text-xs;
font-weight: $font-semibold;
text-transform: uppercase;
padding: $space-1 $space-2;
border-radius: $radius-full;
&--achieved {
background: rgba($success-500, 0.1);
color: $success-500;
}
&--on-track {
background: rgba($info-500, 0.1);
color: $info-500;
}
&--at-risk {
background: rgba($warning-500, 0.1);
color: $warning-500;
}
}
.kpi-progress {
display: flex;
flex-direction: column;
gap: $space-2;
}
.kpi-progress-bar {
height: 6px;
background: rgba($neutral-300, 0.3);
border-radius: $radius-full;
overflow: hidden;
box-shadow: $shadow-inset-sm;
}
.kpi-progress-fill {
height: 100%;
border-radius: $radius-full;
transition: width $transition-slow;
&--achieved {
background: linear-gradient(90deg, $success-500, #059669);
}
&--on-track {
background: linear-gradient(90deg, $info-500, #2563EB);
}
&--at-risk {
background: linear-gradient(90deg, $warning-500, #D97706);
}
}
.kpi-value {
font-size: $text-xs;
color: $neutral-600;
text-align: right;
}
// Meetings Card
.meetings-list {
display: flex;
flex-direction: column;
gap: $space-4;
}
.meeting-item {
display: flex;
gap: $space-4;
padding: $space-4;
background: rgba($neutral-100, 0.5);
border-radius: $radius-lg;
transition: all $transition-base;
&:hover {
background: rgba($neutral-100, 0.8);
box-shadow: $shadow-soft-sm;
}
}
.meeting-date {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 60px;
height: 60px;
background: linear-gradient(135deg, $primary-500, $primary-600);
border-radius: $radius-lg;
color: white;
flex-shrink: 0;
.meeting-month {
font-size: $text-xs;
text-transform: uppercase;
opacity: 0.9;
}
.meeting-day {
font-size: $text-xl;
font-weight: $font-bold;
}
}
.meeting-details {
flex: 1;
.meeting-title {
font-size: $text-base;
font-weight: $font-semibold;
color: $neutral-800;
margin-bottom: $space-1;
}
.meeting-info {
display: flex;
align-items: center;
gap: $space-2;
font-size: $text-sm;
color: $neutral-600;
margin-bottom: $space-2;
svg {
width: 14px;
height: 14px;
}
}
.meeting-attendees {
display: flex;
align-items: center;
gap: -$space-2;
.attendee-avatar {
width: 24px;
height: 24px;
border-radius: $radius-full;
border: 2px solid white;
margin-right: -8px;
}
.attendee-more {
margin-left: $space-2;
font-size: $text-xs;
color: $neutral-600;
}
}
}
// Resolutions Card
.resolutions-list {
display: flex;
flex-direction: column;
gap: $space-3;
}
.resolution-item {
display: flex;
gap: $space-3;
padding: $space-3;
background: rgba($neutral-100, 0.5);
border-radius: $radius-lg;
}
.resolution-status {
width: 32px;
height: 32px;
border-radius: $radius-lg;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
svg {
width: 16px;
height: 16px;
}
&--approved {
background: rgba($success-500, 0.1);
color: $success-500;
}
&--pending {
background: rgba($warning-500, 0.1);
color: $warning-500;
}
&--rejected {
background: rgba($error-500, 0.1);
color: $error-500;
}
}
.resolution-content {
flex: 1;
.resolution-title {
font-size: $text-sm;
font-weight: $font-semibold;
color: $neutral-800;
margin-bottom: $space-1;
}
.resolution-description {
font-size: $text-sm;
color: $neutral-600;
line-height: $leading-normal;
margin-bottom: $space-2;
}
.resolution-meta {
display: flex;
gap: $space-3;
font-size: $text-xs;
color: $neutral-500;
.resolution-votes {
font-weight: $font-medium;
}
}
}
// Strategic Initiatives
.initiatives-card {
margin-bottom: $space-8;
}
.initiatives-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: $space-4;
}
.initiative-card {
padding: $space-4;
background: rgba($neutral-100, 0.5);
border-radius: $radius-lg;
transition: all $transition-base;
&:hover {
background: rgba($neutral-100, 0.8);
box-shadow: $shadow-soft-sm;
transform: translateY(-2px);
}
}
.initiative-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: $space-3;
}
.initiative-priority {
font-size: $text-xs;
font-weight: $font-semibold;
text-transform: uppercase;
padding: $space-1 $space-2;
border-radius: $radius-full;
&--high {
background: rgba($error-500, 0.1);
color: $error-500;
}
&--medium {
background: rgba($warning-500, 0.1);
color: $warning-500;
}
&--low {
background: rgba($info-500, 0.1);
color: $info-500;
}
}
.initiative-deadline {
font-size: $text-xs;
color: $neutral-600;
}
.initiative-title {
font-size: $text-base;
font-weight: $font-semibold;
color: $neutral-800;
margin-bottom: $space-2;
}
.initiative-description {
font-size: $text-sm;
color: $neutral-600;
line-height: $leading-normal;
margin-bottom: $space-3;
}
.initiative-progress {
margin-bottom: $space-3;
.progress-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: $space-1;
}
.progress-label,
.progress-value {
font-size: $text-xs;
color: $neutral-600;
}
.progress-value {
font-weight: $font-semibold;
}
.progress-bar {
height: 6px;
background: rgba($neutral-300, 0.3);
border-radius: $radius-full;
overflow: hidden;
box-shadow: $shadow-inset-sm;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, $primary-500, $primary-600);
border-radius: $radius-full;
transition: width $transition-slow;
}
}
.initiative-team {
display: flex;
align-items: center;
gap: -$space-2;
.team-avatar {
width: 28px;
height: 28px;
border-radius: $radius-full;
border: 2px solid white;
margin-right: -8px;
}
.team-more {
margin-left: $space-3;
font-size: $text-xs;
font-weight: $font-medium;
color: $neutral-600;
background: rgba($neutral-200, 0.5);
padding: $space-1 $space-2;
border-radius: $radius-full;
}
}
// Dark mode support
@include dark-mode {
.board-dashboard {
background: linear-gradient(135deg, $neutral-900 0%, $neutral-800 100%);
}
// Update other dark mode styles as needed
}
</style>