diff --git a/src/app/election/components/candidate-analysis/candidate-analysis.component.html b/src/app/election/components/candidate-analysis/candidate-analysis.component.html index 24016c4aa..2f3de9232 100644 --- a/src/app/election/components/candidate-analysis/candidate-analysis.component.html +++ b/src/app/election/components/candidate-analysis/candidate-analysis.component.html @@ -487,7 +487,7 @@
savings

Financial & Family Engagement

- 6 Analysis Dimensions + 5 Analysis Dimensions
@@ -584,6 +584,7 @@
savings
Savings Account Depth + {{ activeSavingsPct(data) }}% Penetration
@if (data.savingsBreakdown?.length > 0) { @@ -605,6 +606,29 @@
}
+
+
+
{{ data.activeSavingsHolders }}
+
Active Savings
+
+
+
+ {{ data.totalActiveShareholders - data.activeSavingsHolders }} +
+
No Savings
+
+
+
{{ activeSavingsPct(data) }}%
+
Penetration Rate
+
+
+
+ info_outline + High savings penetration means members are financially active and have stronger ties to the + institution — a positive signal for candidate support. +
} @else {

No savings data available.

} @@ -655,61 +679,6 @@ - - -
-
-
family_restroom
- Family Member Network Influence -
-
-
-
-
- group -
-
-
{{ data.shareholdersWithFamily }}
-
Shareholders with Family Records
-
-
-
-
-
- diversity_1 -
-
-
{{ data.totalFamilyMembers }}
-
Total Family Members Registered
-
-
-
-
-
- calculate -
-
-
- {{ - data.shareholdersWithFamily > 0 - ? (data.totalFamilyMembers / data.shareholdersWithFamily | number: '1.1-1') - : '—' - }} -
-
Avg Registered Members / Household
-
-
-
-
- insights - Family records indicate broader community networks. A single voting shareholder with multiple family - records acts as a proxy shapeholder, often scaling voting decisions across their entire - household. -
-
-
diff --git a/src/app/election/components/candidate-analysis/candidate-analysis.component.scss b/src/app/election/components/candidate-analysis/candidate-analysis.component.scss index 8f003d561..d55c66342 100644 --- a/src/app/election/components/candidate-analysis/candidate-analysis.component.scss +++ b/src/app/election/components/candidate-analysis/candidate-analysis.component.scss @@ -41,7 +41,7 @@ $accent-green: #10b981; min-height: 100%; font-family: $font; color: $text-main; - padding-bottom: 40px; + padding-bottom: 24px; position: relative; overflow-x: hidden; } @@ -89,7 +89,7 @@ $accent-green: #10b981; // ─── Hero Header (Redesigned - Light Mode Infographic Style) ────────────────── .hero { background: linear-gradient(135deg, #eef2ff 0%, #e0f2fe 50%, #f0fdf4 100%); - padding: 24px 32px 36px; + padding: 14px 24px 18px; position: relative; overflow: hidden; border-bottom: 1px solid #cbd5e1; @@ -132,9 +132,9 @@ $accent-green: #10b981; gap: 4px; color: #475569; text-decoration: none; - font-size: 13px; + font-size: 12px; font-weight: 600; - margin-bottom: 24px; + margin-bottom: 12px; transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); position: relative; z-index: 2; @@ -160,14 +160,14 @@ $accent-green: #10b981; .hero-body { display: flex; align-items: center; - gap: 28px; + gap: 18px; position: relative; z-index: 2; @media (width <= 768px) { flex-direction: column; align-items: flex-start; - gap: 20px; + gap: 12px; } } @@ -177,13 +177,13 @@ $accent-green: #10b981; } .hero-avatar { - width: 80px; - height: 80px; + width: 58px; + height: 58px; border-radius: 50%; background: linear-gradient(135deg, #6366f1 0%, #3b82f6 100%); border: 2px solid #fff; color: #fff; - font-size: 38px; + font-size: 26px; font-weight: 800; display: flex; align-items: center; @@ -249,21 +249,21 @@ $accent-green: #10b981; } .hero-name { - font-size: 32px; + font-size: 22px; font-weight: 800; color: #0f172a; - margin: 0 0 12px; - letter-spacing: -0.8px; + margin: 0 0 6px; + letter-spacing: -0.5px; line-height: 1.15; } .hero-criteria { display: flex; align-items: center; - gap: 8px; + gap: 6px; flex-wrap: wrap; - margin-top: 14px; - padding-top: 12px; + margin-top: 8px; + padding-top: 8px; border-top: 1px solid #cbd5e1; } @@ -376,8 +376,8 @@ $accent-green: #10b981; .kpi-row { display: grid; grid-template-columns: 1.4fr repeat(5, 1fr); - gap: 16px; - padding: 24px 32px; + gap: 10px; + padding: 12px 24px; position: relative; z-index: 2; @@ -387,8 +387,8 @@ $accent-green: #10b981; @media (width <= 768px) { grid-template-columns: repeat(2, 1fr); - padding: 16px 20px; - gap: 12px; + padding: 10px 16px; + gap: 8px; } @media (width <= 480px) { @@ -398,11 +398,11 @@ $accent-green: #10b981; .kpi { background: white; - border-radius: $radius; - padding: 18px 20px; + border-radius: $radius-sm; + padding: 10px 14px; display: flex; align-items: center; - gap: 16px; + gap: 10px; box-shadow: $shadow-sm; border: 1px solid $border-color; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); @@ -425,18 +425,18 @@ $accent-green: #10b981; } .kpi-icon { - width: 48px; - height: 48px; - border-radius: 12px; + width: 34px; + height: 34px; + border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; mat-icon { - font-size: 24px; - height: 24px; - width: 24px; + font-size: 18px; + height: 18px; + width: 18px; } } @@ -445,54 +445,54 @@ $accent-green: #10b981; } .kpi-val { - font-size: 28px; + font-size: 20px; font-weight: 800; color: $text-main; line-height: 1; - margin-bottom: 4px; - letter-spacing: -0.8px; + margin-bottom: 2px; + letter-spacing: -0.5px; } .featured-val { color: #2563eb; - font-size: 32px; + font-size: 24px; } .kpi-lbl { - font-size: 11px; + font-size: 10px; font-weight: 700; color: $text-sub; - line-height: 1.35; + line-height: 1.3; text-transform: uppercase; letter-spacing: 0.3px; } .kpi-sub { - font-size: 11px; + font-size: 10px; font-weight: 700; color: #2563eb; - margin-top: 3px; + margin-top: 2px; } .kpi-sub-text { - font-size: 10px; + font-size: 9.5px; font-weight: 500; color: $text-sub; - margin-top: 2px; + margin-top: 1px; } // ─── Dashboard Sections Layout ─────────────────────────────────────────────── .dashboard-sections { - padding: 0 32px; + padding: 0 20px; display: flex; flex-direction: column; - gap: 36px; + gap: 20px; position: relative; z-index: 2; @media (width <= 768px) { - padding: 0 20px; - gap: 28px; + padding: 0 14px; + gap: 16px; } } @@ -521,20 +521,20 @@ $accent-green: #10b981; .section-header { display: flex; align-items: center; - gap: 12px; - margin-bottom: 20px; - padding-bottom: 8px; + gap: 10px; + margin-bottom: 12px; + padding-bottom: 6px; border-bottom: 2px solid #e2e8f0; mat-icon { color: $primary; - font-size: 26px; - height: 26px; - width: 26px; + font-size: 20px; + height: 20px; + width: 20px; } h2 { - font-size: 18px; + font-size: 15px; font-weight: 800; color: $text-main; margin: 0; @@ -543,11 +543,11 @@ $accent-green: #10b981; .section-badge { margin-left: auto; - font-size: 11px; + font-size: 10px; font-weight: 700; color: $primary; background: rgb(79 70 229 / 8%); - padding: 3px 10px; + padding: 2px 8px; border-radius: 99px; text-transform: uppercase; letter-spacing: 0.3px; @@ -558,7 +558,7 @@ $accent-green: #10b981; .a-grid { display: grid; grid-template-columns: repeat(2, 1fr); - gap: 20px; + gap: 12px; @media (width <= 1024px) { grid-template-columns: 1fr; @@ -568,7 +568,7 @@ $accent-green: #10b981; .a-card { background: white; border-radius: $radius; - padding: 24px; + padding: 16px; box-shadow: 0 4px 20px -2px rgb(0 0 0 / 3%), 0 1px 3px rgb(0 0 0 / 2%); @@ -577,7 +577,7 @@ $accent-green: #10b981; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: flex; flex-direction: column; - justify-content: space-between; + justify-content: flex-start; &:hover { box-shadow: @@ -596,14 +596,14 @@ $accent-green: #10b981; .ac-head { display: flex; align-items: center; - gap: 12px; - margin-bottom: 20px; + gap: 10px; + margin-bottom: 12px; } .ac-icon { - width: 40px; - height: 40px; - border-radius: 10px; + width: 32px; + height: 32px; + border-radius: 8px; background: var(--ac-bg, #f1f5f9); display: flex; align-items: center; @@ -611,15 +611,15 @@ $accent-green: #10b981; flex-shrink: 0; mat-icon { - font-size: 20px; - height: 20px; - width: 20px; + font-size: 16px; + height: 16px; + width: 16px; color: var(--ac, #64748b); } } .ac-title { - font-size: 15px; + font-size: 13px; font-weight: 700; color: $text-main; flex: 1; @@ -674,11 +674,11 @@ $accent-green: #10b981; // ─── Donut Center Overlay ──────────────────────────────────────────────────── .donut-wrap { position: relative; - width: 150px; - height: 150px; + width: 120px; + height: 120px; flex-shrink: 0; - margin-bottom: 20px; - filter: drop-shadow(0 6px 12px rgb(0 0 0 / 4%)); + margin-bottom: 12px; + filter: drop-shadow(0 4px 8px rgb(0 0 0 / 4%)); } .donut-center { @@ -698,7 +698,7 @@ $accent-green: #10b981; } .dc-val { - font-size: 24px; + font-size: 18px; font-weight: 800; color: $text-main; line-height: 1; @@ -719,14 +719,14 @@ $accent-green: #10b981; width: 100%; display: flex; flex-direction: column; - gap: 8px; + gap: 5px; } .cl-row { display: flex; align-items: center; - gap: 10px; - padding: 8px 12px; + gap: 8px; + padding: 5px 8px; background: #f8fafc; border-radius: 10px; border: 1px solid #f1f5f9; @@ -946,18 +946,18 @@ $accent-green: #10b981; .loan-stats { display: flex; - gap: 16px; - margin-bottom: 16px; + gap: 10px; + margin-bottom: 10px; flex-wrap: wrap; } .loan-stat { flex: 1; - min-width: 180px; + min-width: 160px; background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 12px; - padding: 16px; + padding: 10px; transition: all 0.2s ease; &.loan-stat-active { @@ -997,12 +997,12 @@ $accent-green: #10b981; } .ls-num { - font-size: 34px; + font-size: 26px; font-weight: 800; color: $text-main; line-height: 1; - margin-bottom: 4px; - letter-spacing: -1px; + margin-bottom: 3px; + letter-spacing: -0.8px; } .ls-pct { @@ -1137,8 +1137,8 @@ $accent-green: #10b981; .influence-insight { display: grid; grid-template-columns: repeat(4, 1fr); - gap: 16px; - margin-top: 8px; + gap: 12px; + margin-top: 6px; @media (width <= 1100px) { grid-template-columns: repeat(2, 1fr); @@ -1154,11 +1154,11 @@ $accent-green: #10b981; flex-direction: column; align-items: center; text-align: center; - padding: 20px 16px; + padding: 12px; background: #f8fafc; - border-radius: 14px; + border-radius: 12px; border: 1px solid #e2e8f0; - gap: 6px; + gap: 4px; transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); &.im-highlight { @@ -1175,41 +1175,75 @@ $accent-green: #10b981; } .im-icon { - width: 44px; - height: 44px; - border-radius: 12px; + width: 34px; + height: 34px; + border-radius: 9px; display: flex; align-items: center; justify-content: center; - margin-bottom: 6px; + margin-bottom: 4px; flex-shrink: 0; mat-icon { - font-size: 22px; - height: 22px; - width: 22px; + font-size: 18px; + height: 18px; + width: 18px; } } .im-val { - font-size: 2.4rem; + font-size: 1.8rem; font-weight: 800; line-height: 1; color: $text-main; - letter-spacing: -1.5px; + letter-spacing: -1px; } .im-pct { - font-size: 1rem; + font-size: 0.85rem; font-weight: 700; } .im-label { - font-size: 11px; + font-size: 10.5px; color: $text-sub; font-weight: 500; line-height: 1.4; - max-width: 160px; + max-width: 140px; +} + +// ─── Savings Stats Grid ────────────────────────────────────────────────────── +.sav-stats { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + width: 100%; + margin-top: 10px; +} + +.sav-stat { + background: #f8fafc; + border: 1px solid #e2e8f0; + border-radius: 8px; + padding: 10px 8px; + text-align: center; +} + +.sav-num { + font-size: 22px; + font-weight: 800; + line-height: 1; + margin-bottom: 3px; + letter-spacing: -0.5px; +} + +.sav-lbl { + font-size: 9.5px; + color: #64748b; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.3px; + line-height: 1.3; } // ─── Helpers ────────────────────────────────────────────────────────────────── diff --git a/src/app/election/components/candidate-analysis/candidate-analysis.component.ts b/src/app/election/components/candidate-analysis/candidate-analysis.component.ts index fd5cb152d..2a20e7626 100644 --- a/src/app/election/components/candidate-analysis/candidate-analysis.component.ts +++ b/src/app/election/components/candidate-analysis/candidate-analysis.component.ts @@ -313,9 +313,9 @@ export class CandidateAnalysisComponent implements OnInit, OnDestroy { { data: data, backgroundColor: colors, - borderWidth: 3, + borderWidth: breakdown.length === 1 ? 0 : 3, borderColor: '#ffffff', - borderRadius: 5, // Rounded corners on doughnut segments for clean graphic style + borderRadius: breakdown.length === 1 ? 0 : 5, hoverOffset: 6 } ]