dhruv575 commited on
Commit
180039f
·
1 Parent(s): c609b48

Fixed the styling

Browse files
Files changed (4) hide show
  1. STYLE_GUIDE.md +156 -0
  2. static/index.html +17 -17
  3. static/script.js +115 -18
  4. static/styles.css +181 -143
STYLE_GUIDE.md ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # Polymarket Macro Dashboard — Style Guide
3
+
4
+ This document captures the visual, interaction, and layout conventions used in the Polymarket **Macro Dashboard**. It is intended as a reference for replicating or extending the Polymarket dashboard aesthetic in product, design, or engineering work.
5
+
6
+ ---
7
+
8
+ ## 1. Design Philosophy
9
+
10
+ - Data-first, probability-centric interface
11
+ - Minimal visual noise; strong information hierarchy
12
+ - Neutral, institutional tone suitable for finance and macro markets
13
+ - Fast scannability over decorative elements
14
+
15
+ ---
16
+
17
+ ## 2. Color System
18
+
19
+ ### Base Colors
20
+ - **Background:** White / very light gray
21
+ - **Primary Text:** Near-black
22
+ - **Secondary Text:** Muted gray
23
+ - **Accent:** Subtle blue for links, interactive states, and focus
24
+
25
+ ### Usage Principles
26
+ - Percentages and odds are visually dominant
27
+ - Color is used sparingly; emphasis comes from weight and spacing
28
+ - No aggressive gradients or saturated backgrounds
29
+
30
+ ---
31
+
32
+ ## 3. Typography
33
+
34
+ - **Font family:** Modern sans-serif
35
+ - **Headings:** Medium to bold weight
36
+ - **Body text:** Regular weight, high legibility
37
+ - **Numerical values:** Bold or semibold to anchor attention
38
+
39
+ ### Hierarchy
40
+ 1. Dashboard title
41
+ 2. Section headers
42
+ 3. Market question text
43
+ 4. Metadata / category labels
44
+
45
+ ---
46
+
47
+ ## 4. Layout Structure
48
+
49
+ ### Global Layout
50
+ - Fixed top navigation bar
51
+ - Vertical scrolling content area
52
+ - Card-based market listing
53
+
54
+ ### Page Structure
55
+ ```
56
+ [Top Navigation]
57
+ [Dashboard Selector]
58
+ [Dashboard Title]
59
+ [Market Sections]
60
+ ├─ Market Card
61
+ ├─ Market Card
62
+ [Footer / Persistent Nav]
63
+ ```
64
+
65
+ Spacing is consistent and generous, prioritizing clarity.
66
+
67
+ ---
68
+
69
+ ## 5. Navigation
70
+
71
+ ### Top Navigation
72
+ - Browse entry point
73
+ - Horizontal category filters (Politics, Macro, Crypto, etc.)
74
+ - Persistent search icon
75
+
76
+ ### Dashboard Selector
77
+ - Inline tab-like controls (Macro, Elections, Fed Rates, etc.)
78
+ - Minimal styling; relies on text weight and underline/contrast
79
+
80
+ ---
81
+
82
+ ## 6. Market Cards
83
+
84
+ Each market card contains:
85
+ - Market question (headline)
86
+ - Probability / chance percentage
87
+ - Optional thumbnail or preview image
88
+ - Category or context label
89
+
90
+ ### Card Characteristics
91
+ - Uniform width
92
+ - Light border or subtle shadow
93
+ - Rounded corners
94
+ - Clickable entire surface
95
+
96
+ ---
97
+
98
+ ## 7. Information Hierarchy
99
+
100
+ Priority order:
101
+ 1. Probability / odds
102
+ 2. Market question
103
+ 3. Category or context
104
+ 4. Supporting metadata
105
+
106
+ The user should be able to scan probabilities without reading full text.
107
+
108
+ ---
109
+
110
+ ## 8. Interaction Design
111
+
112
+ - Hover states are subtle (slight background or border change)
113
+ - Click targets are large and forgiving
114
+ - No modal-heavy flows on the dashboard level
115
+ - Transitions are fast and understated
116
+
117
+ ---
118
+
119
+ ## 9. Motion & Feedback
120
+
121
+ - Minimal animation
122
+ - Instant feedback on navigation
123
+ - No distracting micro-interactions
124
+ - Emphasis on speed and responsiveness
125
+
126
+ ---
127
+
128
+ ## 10. Accessibility & Readability
129
+
130
+ - High contrast between text and background
131
+ - Large tap targets for mobile
132
+ - Clear separation between interactive and static elements
133
+
134
+ ---
135
+
136
+ ## 11. Inferred Design Tokens (Example)
137
+
138
+ ```css
139
+ :root {
140
+ --bg-primary: #ffffff;
141
+ --text-primary: #0a0a0a;
142
+ --text-secondary: #6b6b6b;
143
+ --accent: #1f6feb;
144
+
145
+ --radius-card: 8px;
146
+ --spacing-unit: 16px;
147
+
148
+ --font-body: system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
149
+ }
150
+ ```
151
+
152
+ ---
153
+
154
+ ## 12. Summary
155
+
156
+ The Polymarket Macro Dashboard prioritizes **trust, speed, and signal clarity**. Its design avoids ornamentation in favor of clean structure, strong typography, and probability-forward presentation. Any replication should preserve this restraint and information density.
static/index.html CHANGED
@@ -29,7 +29,7 @@
29
  <section class="controls-section">
30
  <div class="controls-header">
31
  <h2>Simulation Configuration</h2>
32
- <p>Configure your prediction market trading simulation parameters</p>
33
  </div>
34
 
35
  <div class="controls-grid">
@@ -54,38 +54,38 @@
54
 
55
  <!-- Base Parameters -->
56
  <div class="control-group">
57
- <label class="control-label">Starting Capital ($)</label>
58
  <input type="number" id="startingCapital" class="control-input" value="10000" min="1000" max="100000" step="1000">
59
- <div class="control-subtitle">Total initial investment amount</div>
60
  </div>
61
 
62
  <div class="control-group">
63
  <label class="control-label">Number of Simulations</label>
64
  <input type="number" id="numSimulations" class="control-input" value="100" min="10" max="100" step="10">
65
- <div class="control-subtitle">Monte Carlo simulation runs (max 100)</div>
66
  </div>
67
 
68
  <div class="control-group">
69
  <label class="control-label">Start Date</label>
70
  <input type="date" id="startDate" class="control-input" value="2025-01-01" min="2025-01-01">
71
- <div class="control-subtitle">Simulation start date (2025+ only)</div>
72
  </div>
73
 
74
  <div class="control-group">
75
- <label class="control-label">Max Duration (Days)</label>
76
  <input type="number" id="maxDuration" class="control-input" value="365" min="30" max="730" step="30">
77
- <div class="control-subtitle">Maximum simulation length</div>
78
  </div>
79
 
80
  <!-- Probability Thresholds -->
81
  <div class="control-group">
82
- <label class="control-label">Min Probability 7d (%)</label>
83
  <input type="number" id="minProb7d" class="control-input" value="90" min="50" max="99" step="1">
84
- <div class="control-subtitle">Minimum market probability 7 days before</div>
85
  </div>
86
 
87
  <div class="control-group">
88
- <label class="control-label">Min Probability Current (%)</label>
89
  <input type="number" id="minProbCurrent" class="control-input" value="90" min="50" max="99" step="1">
90
  <div class="control-subtitle">Minimum probability at investment</div>
91
  </div>
@@ -93,7 +93,7 @@
93
  <div class="control-group">
94
  <label class="control-label">Days Before Resolution</label>
95
  <input type="number" id="daysBefore" class="control-input" value="1" min="1" max="7" step="1">
96
- <div class="control-subtitle">When to invest before market closes</div>
97
  </div>
98
 
99
  <div class="control-group">
@@ -104,21 +104,21 @@
104
 
105
  <!-- Threshold-specific controls -->
106
  <div class="control-group threshold-only" style="display: none;">
107
- <label class="control-label">Target Return (%)</label>
108
  <select id="targetReturn" class="control-input">
109
  <option value="4.14">4.14% (Treasury Rate)</option>
110
  <option value="10.56">10.56% (NASDAQ Average)</option>
111
  <option value="custom">Custom</option>
112
  </select>
113
  <input type="number" id="customTarget" class="control-input" style="display: none; margin-top: 8px;" min="1" max="50" step="0.1">
114
- <div class="control-subtitle">Stop trading when target is reached</div>
115
  </div>
116
 
117
  <!-- Multi-fund specific controls -->
118
  <div class="control-group multi-only" style="display: none;">
119
  <label class="control-label">Number of Funds</label>
120
  <input type="number" id="numFunds" class="control-input" value="5" min="2" max="10" step="1">
121
- <div class="control-subtitle">Split capital into N independent funds (max 10)</div>
122
  </div>
123
  </div>
124
 
@@ -129,7 +129,7 @@
129
  <div class="run-spinner" style="display: none;"></div>
130
  </button>
131
  <div class="run-info">
132
- <span id="estimatedTime">Estimated time: ~5-10 seconds</span>
133
  </div>
134
  </div>
135
  </section>
@@ -150,8 +150,8 @@
150
  <!-- Results Section -->
151
  <section class="results-section" id="resultsSection" style="display: none;">
152
  <div class="results-header">
153
- <h2>Simulation Results</h2>
154
- <button class="export-button" onclick="exportResults()" id="exportBtn">Export Data</button>
155
  </div>
156
 
157
  <!-- Summary Statistics -->
 
29
  <section class="controls-section">
30
  <div class="controls-header">
31
  <h2>Simulation Configuration</h2>
32
+ <p>Configure trading simulation parameters</p>
33
  </div>
34
 
35
  <div class="controls-grid">
 
54
 
55
  <!-- Base Parameters -->
56
  <div class="control-group">
57
+ <label class="control-label">Starting Capital</label>
58
  <input type="number" id="startingCapital" class="control-input" value="10000" min="1000" max="100000" step="1000">
59
+ <div class="control-subtitle">Initial investment amount</div>
60
  </div>
61
 
62
  <div class="control-group">
63
  <label class="control-label">Number of Simulations</label>
64
  <input type="number" id="numSimulations" class="control-input" value="100" min="10" max="100" step="10">
65
+ <div class="control-subtitle">Monte Carlo runs (max 100)</div>
66
  </div>
67
 
68
  <div class="control-group">
69
  <label class="control-label">Start Date</label>
70
  <input type="date" id="startDate" class="control-input" value="2025-01-01" min="2025-01-01">
71
+ <div class="control-subtitle">Simulation start date</div>
72
  </div>
73
 
74
  <div class="control-group">
75
+ <label class="control-label">Max Duration</label>
76
  <input type="number" id="maxDuration" class="control-input" value="365" min="30" max="730" step="30">
77
+ <div class="control-subtitle">Maximum days</div>
78
  </div>
79
 
80
  <!-- Probability Thresholds -->
81
  <div class="control-group">
82
+ <label class="control-label">Min Probability 7d</label>
83
  <input type="number" id="minProb7d" class="control-input" value="90" min="50" max="99" step="1">
84
+ <div class="control-subtitle">Minimum probability 7 days before</div>
85
  </div>
86
 
87
  <div class="control-group">
88
+ <label class="control-label">Min Probability Current</label>
89
  <input type="number" id="minProbCurrent" class="control-input" value="90" min="50" max="99" step="1">
90
  <div class="control-subtitle">Minimum probability at investment</div>
91
  </div>
 
93
  <div class="control-group">
94
  <label class="control-label">Days Before Resolution</label>
95
  <input type="number" id="daysBefore" class="control-input" value="1" min="1" max="7" step="1">
96
+ <div class="control-subtitle">Investment timing before market closes</div>
97
  </div>
98
 
99
  <div class="control-group">
 
104
 
105
  <!-- Threshold-specific controls -->
106
  <div class="control-group threshold-only" style="display: none;">
107
+ <label class="control-label">Target Return</label>
108
  <select id="targetReturn" class="control-input">
109
  <option value="4.14">4.14% (Treasury Rate)</option>
110
  <option value="10.56">10.56% (NASDAQ Average)</option>
111
  <option value="custom">Custom</option>
112
  </select>
113
  <input type="number" id="customTarget" class="control-input" style="display: none; margin-top: 8px;" min="1" max="50" step="0.1">
114
+ <div class="control-subtitle">Stop when target reached</div>
115
  </div>
116
 
117
  <!-- Multi-fund specific controls -->
118
  <div class="control-group multi-only" style="display: none;">
119
  <label class="control-label">Number of Funds</label>
120
  <input type="number" id="numFunds" class="control-input" value="5" min="2" max="10" step="1">
121
+ <div class="control-subtitle">Independent funds (max 10)</div>
122
  </div>
123
  </div>
124
 
 
129
  <div class="run-spinner" style="display: none;"></div>
130
  </button>
131
  <div class="run-info">
132
+ <span id="estimatedTime">Estimated: ~5-10 seconds</span>
133
  </div>
134
  </div>
135
  </section>
 
150
  <!-- Results Section -->
151
  <section class="results-section" id="resultsSection" style="display: none;">
152
  <div class="results-header">
153
+ <h2>Results</h2>
154
+ <button class="export-button" onclick="exportResults()" id="exportBtn">Export</button>
155
  </div>
156
 
157
  <!-- Summary Statistics -->
static/script.js CHANGED
@@ -501,8 +501,8 @@ function createReturnDistributionChart(runs) {
501
  datasets: [{
502
  label: 'Frequency',
503
  data: histogram.data,
504
- backgroundColor: 'rgba(59, 130, 246, 0.7)',
505
- borderColor: 'rgba(59, 130, 246, 1)',
506
  borderWidth: 1
507
  }]
508
  },
@@ -516,13 +516,33 @@ function createReturnDistributionChart(runs) {
516
  x: {
517
  title: {
518
  display: true,
519
- text: 'Return (%)'
 
 
 
 
 
 
 
 
 
 
520
  }
521
  },
522
  y: {
523
  title: {
524
  display: true,
525
- text: 'Frequency'
 
 
 
 
 
 
 
 
 
 
526
  }
527
  }
528
  }
@@ -534,12 +554,21 @@ function createReturnDistributionChart(runs) {
534
  function createCapitalEvolutionChart(sampleRuns) {
535
  const ctx = document.getElementById('capitalChart').getContext('2d');
536
 
 
 
 
 
 
 
 
 
 
537
  const datasets = sampleRuns.slice(0, 5).map((run, i) => ({
538
  label: `Run ${i + 1}`,
539
  data: run.capitalHistory || [run.finalCapital],
540
- borderColor: `hsla(${i * 60}, 70%, 50%, 0.8)`,
541
- backgroundColor: `hsla(${i * 60}, 70%, 50%, 0.1)`,
542
- borderWidth: 2,
543
  fill: false
544
  }));
545
 
@@ -550,19 +579,47 @@ function createCapitalEvolutionChart(sampleRuns) {
550
  responsive: true,
551
  maintainAspectRatio: false,
552
  plugins: {
553
- legend: { display: true }
 
 
 
 
 
 
 
 
554
  },
555
  scales: {
556
  x: {
557
  title: {
558
  display: true,
559
- text: 'Trade Number'
 
 
 
 
 
 
 
 
 
 
560
  }
561
  },
562
  y: {
563
  title: {
564
  display: true,
565
- text: 'Capital ($)'
 
 
 
 
 
 
 
 
 
 
566
  }
567
  }
568
  }
@@ -584,8 +641,8 @@ function createCapitalDistributionChart(runs) {
584
  datasets: [{
585
  label: 'Frequency',
586
  data: histogram.data,
587
- backgroundColor: 'rgba(16, 185, 129, 0.7)',
588
- borderColor: 'rgba(16, 185, 129, 1)',
589
  borderWidth: 1
590
  }]
591
  },
@@ -599,13 +656,33 @@ function createCapitalDistributionChart(runs) {
599
  x: {
600
  title: {
601
  display: true,
602
- text: 'Final Capital ($)'
 
 
 
 
 
 
 
 
 
 
603
  }
604
  },
605
  y: {
606
  title: {
607
  display: true,
608
- text: 'Frequency'
 
 
 
 
 
 
 
 
 
 
609
  }
610
  }
611
  }
@@ -630,8 +707,8 @@ function createSurvivorshipChart(runs, numFunds) {
630
  datasets: [{
631
  label: 'Frequency',
632
  data: Object.values(histogram),
633
- backgroundColor: 'rgba(245, 158, 11, 0.7)',
634
- borderColor: 'rgba(245, 158, 11, 1)',
635
  borderWidth: 1
636
  }]
637
  },
@@ -645,13 +722,33 @@ function createSurvivorshipChart(runs, numFunds) {
645
  x: {
646
  title: {
647
  display: true,
648
- text: 'Surviving Funds'
 
 
 
 
 
 
 
 
 
 
649
  }
650
  },
651
  y: {
652
  title: {
653
  display: true,
654
- text: 'Frequency'
 
 
 
 
 
 
 
 
 
 
655
  }
656
  }
657
  }
 
501
  datasets: [{
502
  label: 'Frequency',
503
  data: histogram.data,
504
+ backgroundColor: 'rgba(31, 111, 235, 0.15)',
505
+ borderColor: '#1f6feb',
506
  borderWidth: 1
507
  }]
508
  },
 
516
  x: {
517
  title: {
518
  display: true,
519
+ text: 'Return (%)',
520
+ color: '#6b6b6b',
521
+ font: { size: 12 }
522
+ },
523
+ grid: {
524
+ color: 'rgba(0, 0, 0, 0.05)',
525
+ drawBorder: false
526
+ },
527
+ ticks: {
528
+ color: '#6b6b6b',
529
+ font: { size: 11 }
530
  }
531
  },
532
  y: {
533
  title: {
534
  display: true,
535
+ text: 'Frequency',
536
+ color: '#6b6b6b',
537
+ font: { size: 12 }
538
+ },
539
+ grid: {
540
+ color: 'rgba(0, 0, 0, 0.05)',
541
+ drawBorder: false
542
+ },
543
+ ticks: {
544
+ color: '#6b6b6b',
545
+ font: { size: 11 }
546
  }
547
  }
548
  }
 
554
  function createCapitalEvolutionChart(sampleRuns) {
555
  const ctx = document.getElementById('capitalChart').getContext('2d');
556
 
557
+ // Subtle color palette matching Polymarket style
558
+ const colors = [
559
+ { border: '#1f6feb', bg: 'rgba(31, 111, 235, 0.1)' },
560
+ { border: '#6b6b6b', bg: 'rgba(107, 107, 107, 0.1)' },
561
+ { border: '#0a0a0a', bg: 'rgba(10, 10, 10, 0.1)' },
562
+ { border: '#1f6feb', bg: 'rgba(31, 111, 235, 0.05)' },
563
+ { border: '#6b6b6b', bg: 'rgba(107, 107, 107, 0.05)' }
564
+ ];
565
+
566
  const datasets = sampleRuns.slice(0, 5).map((run, i) => ({
567
  label: `Run ${i + 1}`,
568
  data: run.capitalHistory || [run.finalCapital],
569
+ borderColor: colors[i % colors.length].border,
570
+ backgroundColor: colors[i % colors.length].bg,
571
+ borderWidth: 1.5,
572
  fill: false
573
  }));
574
 
 
579
  responsive: true,
580
  maintainAspectRatio: false,
581
  plugins: {
582
+ legend: {
583
+ display: true,
584
+ labels: {
585
+ color: '#6b6b6b',
586
+ font: { size: 11 },
587
+ usePointStyle: true,
588
+ padding: 12
589
+ }
590
+ }
591
  },
592
  scales: {
593
  x: {
594
  title: {
595
  display: true,
596
+ text: 'Trade Number',
597
+ color: '#6b6b6b',
598
+ font: { size: 12 }
599
+ },
600
+ grid: {
601
+ color: 'rgba(0, 0, 0, 0.05)',
602
+ drawBorder: false
603
+ },
604
+ ticks: {
605
+ color: '#6b6b6b',
606
+ font: { size: 11 }
607
  }
608
  },
609
  y: {
610
  title: {
611
  display: true,
612
+ text: 'Capital ($)',
613
+ color: '#6b6b6b',
614
+ font: { size: 12 }
615
+ },
616
+ grid: {
617
+ color: 'rgba(0, 0, 0, 0.05)',
618
+ drawBorder: false
619
+ },
620
+ ticks: {
621
+ color: '#6b6b6b',
622
+ font: { size: 11 }
623
  }
624
  }
625
  }
 
641
  datasets: [{
642
  label: 'Frequency',
643
  data: histogram.data,
644
+ backgroundColor: 'rgba(31, 111, 235, 0.15)',
645
+ borderColor: '#1f6feb',
646
  borderWidth: 1
647
  }]
648
  },
 
656
  x: {
657
  title: {
658
  display: true,
659
+ text: 'Final Capital ($)',
660
+ color: '#6b6b6b',
661
+ font: { size: 12 }
662
+ },
663
+ grid: {
664
+ color: 'rgba(0, 0, 0, 0.05)',
665
+ drawBorder: false
666
+ },
667
+ ticks: {
668
+ color: '#6b6b6b',
669
+ font: { size: 11 }
670
  }
671
  },
672
  y: {
673
  title: {
674
  display: true,
675
+ text: 'Frequency',
676
+ color: '#6b6b6b',
677
+ font: { size: 12 }
678
+ },
679
+ grid: {
680
+ color: 'rgba(0, 0, 0, 0.05)',
681
+ drawBorder: false
682
+ },
683
+ ticks: {
684
+ color: '#6b6b6b',
685
+ font: { size: 11 }
686
  }
687
  }
688
  }
 
707
  datasets: [{
708
  label: 'Frequency',
709
  data: Object.values(histogram),
710
+ backgroundColor: 'rgba(31, 111, 235, 0.15)',
711
+ borderColor: '#1f6feb',
712
  borderWidth: 1
713
  }]
714
  },
 
722
  x: {
723
  title: {
724
  display: true,
725
+ text: 'Surviving Funds',
726
+ color: '#6b6b6b',
727
+ font: { size: 12 }
728
+ },
729
+ grid: {
730
+ color: 'rgba(0, 0, 0, 0.05)',
731
+ drawBorder: false
732
+ },
733
+ ticks: {
734
+ color: '#6b6b6b',
735
+ font: { size: 11 }
736
  }
737
  },
738
  y: {
739
  title: {
740
  display: true,
741
+ text: 'Frequency',
742
+ color: '#6b6b6b',
743
+ font: { size: 12 }
744
+ },
745
+ grid: {
746
+ color: 'rgba(0, 0, 0, 0.05)',
747
+ drawBorder: false
748
+ },
749
+ ticks: {
750
+ color: '#6b6b6b',
751
+ font: { size: 11 }
752
  }
753
  }
754
  }
static/styles.css CHANGED
@@ -1,20 +1,31 @@
1
- /* CSS Variables for Polymarket-inspired design */
 
2
  :root {
3
- --polymarket-blue: #3B82F6;
4
- --polymarket-blue-dark: #2563EB;
5
- --polymarket-blue-light: #DBEAFE;
6
- --light-gray: #F8FAFC;
7
- --medium-gray: #E2E8F0;
8
- --dark-gray: #64748B;
9
- --text-primary: #1E293B;
10
- --text-secondary: #475569;
11
- --white: #FFFFFF;
12
- --success: #10B981;
13
- --warning: #F59E0B;
14
- --error: #EF4444;
15
- --shadow-sm: 0 1px 1px 0 rgba(0, 0, 0, 0.03);
16
- --shadow-md: 0 1px 2px 0 rgba(0, 0, 0, 0.04);
17
- --shadow-lg: 0 2px 4px 0 rgba(0, 0, 0, 0.05);
 
 
 
 
 
 
 
 
 
 
18
  }
19
 
20
  /* Reset and base styles */
@@ -25,18 +36,19 @@
25
  }
26
 
27
  body {
28
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif;
29
- background-color: var(--light-gray);
30
  color: var(--text-primary);
31
- line-height: 1.5;
32
  min-height: 100vh;
 
 
33
  }
34
 
35
  /* Top Navigation Bar */
36
  .top-bar {
37
- background-color: var(--white);
38
- border-bottom: 1px solid var(--medium-gray);
39
- box-shadow: var(--shadow-sm);
40
  position: sticky;
41
  top: 0;
42
  z-index: 100;
@@ -45,11 +57,11 @@ body {
45
  .nav-container {
46
  max-width: 1200px;
47
  margin: 0 auto;
48
- padding: 0 32px;
49
  display: flex;
50
  align-items: center;
51
  justify-content: space-between;
52
- height: 72px;
53
  }
54
 
55
  .logo-section {
@@ -59,18 +71,19 @@ body {
59
  }
60
 
61
  .logo {
62
- height: 32px;
63
  width: auto;
64
  }
65
 
66
  .app-title {
67
- font-size: 20px;
68
  font-weight: 600;
69
- color: var(--polymarket-blue);
 
70
  }
71
 
72
  .subtitle {
73
- font-size: 14px;
74
  color: var(--text-secondary);
75
  font-weight: 400;
76
  }
@@ -81,53 +94,55 @@ body {
81
  }
82
 
83
  .dataset-info {
84
- font-size: 14px;
85
  color: var(--text-secondary);
86
- background: var(--light-gray);
87
  padding: 6px 12px;
88
- border-radius: 20px;
89
  }
90
 
91
  /* Main Container */
92
  .main-container {
93
  max-width: 1200px;
94
  margin: 0 auto;
95
- padding: 32px;
96
  display: flex;
97
  flex-direction: column;
98
- gap: 32px;
99
  }
100
 
101
  /* Controls Section */
102
  .controls-section {
103
- background: var(--white);
104
- border-radius: 12px;
105
- padding: 32px;
106
- box-shadow: var(--shadow-md);
107
- border: 1px solid var(--medium-gray);
108
  }
109
 
110
  .controls-header {
111
- margin-bottom: 32px;
112
  }
113
 
114
  .controls-header h2 {
115
- font-size: 24px;
116
  font-weight: 600;
117
- margin-bottom: 8px;
118
  color: var(--text-primary);
 
119
  }
120
 
121
  .controls-header p {
122
- font-size: 16px;
123
  color: var(--text-secondary);
 
124
  }
125
 
126
  .controls-grid {
127
  display: grid;
128
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
129
- gap: 24px;
130
- margin-bottom: 32px;
131
  }
132
 
133
  .control-group {
@@ -140,71 +155,76 @@ body {
140
  }
141
 
142
  .control-label {
143
- font-size: 14px;
144
  font-weight: 500;
145
  color: var(--text-primary);
146
- margin-bottom: 10px;
147
  }
148
 
149
  .control-input {
150
- padding: 12px 16px;
151
- border: 1px solid var(--medium-gray);
152
- border-radius: 8px;
153
  font-size: 14px;
154
- background: var(--white);
155
- transition: all 0.2s;
 
156
  outline: none;
 
157
  }
158
 
159
  .control-input:focus {
160
- border-color: var(--polymarket-blue);
161
- box-shadow: 0 0 0 3px var(--polymarket-blue-light);
 
162
  }
163
 
164
  .control-subtitle {
165
  font-size: 12px;
166
  color: var(--text-secondary);
167
  margin-top: 6px;
 
168
  }
169
 
170
  /* Simulation Tabs */
171
  .simulation-tabs {
172
  display: flex;
173
- gap: 16px;
174
- margin-top: 12px;
175
  }
176
 
177
  .sim-tab {
178
  flex: 1;
179
- padding: 20px;
180
- border: 1px solid var(--medium-gray);
181
- border-radius: 8px;
182
- background: var(--white);
183
  cursor: pointer;
184
- transition: all 0.2s;
185
  text-align: left;
186
  }
187
 
188
  .sim-tab:hover {
189
- border-color: var(--polymarket-blue-light);
190
- background: var(--polymarket-blue-light);
191
  }
192
 
193
  .sim-tab.active {
194
- border-color: var(--polymarket-blue);
195
- background: var(--polymarket-blue-light);
196
  }
197
 
198
  .tab-title {
199
- font-size: 16px;
200
  font-weight: 600;
201
  color: var(--text-primary);
202
- margin-bottom: 4px;
203
  }
204
 
205
  .tab-subtitle {
206
- font-size: 14px;
207
  color: var(--text-secondary);
 
208
  }
209
 
210
  /* Run Section */
@@ -212,43 +232,45 @@ body {
212
  display: flex;
213
  align-items: center;
214
  justify-content: center;
215
- gap: 16px;
216
- padding-top: 32px;
217
- border-top: 1px solid var(--medium-gray);
218
- margin-top: 8px;
219
  }
220
 
221
  .run-button {
222
- background: var(--polymarket-blue);
223
- color: var(--white);
224
  border: none;
225
- padding: 14px 32px;
226
- border-radius: 8px;
227
- font-size: 16px;
228
  font-weight: 600;
229
  cursor: pointer;
230
- transition: all 0.2s;
231
  display: flex;
232
  align-items: center;
233
  gap: 8px;
 
234
  }
235
 
236
  .run-button:hover:not(:disabled) {
237
- background: var(--polymarket-blue-dark);
238
  }
239
 
240
  .run-button:disabled {
241
- background: var(--dark-gray);
242
  cursor: not-allowed;
 
243
  }
244
 
245
  .run-spinner {
246
- width: 20px;
247
- height: 20px;
248
  border: 2px solid transparent;
249
- border-top: 2px solid var(--white);
250
  border-radius: 50%;
251
- animation: spin 1s linear infinite;
252
  }
253
 
254
  @keyframes spin {
@@ -257,17 +279,17 @@ body {
257
  }
258
 
259
  .run-info {
260
- font-size: 14px;
261
  color: var(--text-secondary);
262
  }
263
 
264
  /* Progress Section */
265
  .progress-section {
266
- background: var(--white);
267
- border-radius: 12px;
268
- padding: 32px;
269
- box-shadow: var(--shadow-md);
270
- border: 1px solid var(--medium-gray);
271
  }
272
 
273
  .progress-container {
@@ -279,22 +301,24 @@ body {
279
  display: flex;
280
  justify-content: space-between;
281
  align-items: center;
282
- margin-bottom: 12px;
 
 
283
  }
284
 
285
  .progress-bar {
286
  width: 100%;
287
- height: 8px;
288
- background: var(--medium-gray);
289
- border-radius: 4px;
290
  overflow: hidden;
291
  }
292
 
293
  .progress-fill {
294
  height: 100%;
295
- background: var(--polymarket-blue);
296
- border-radius: 4px;
297
- transition: width 0.3s ease;
298
  width: 0%;
299
  }
300
 
@@ -302,72 +326,75 @@ body {
302
  .results-section {
303
  display: flex;
304
  flex-direction: column;
305
- gap: 24px;
306
  }
307
 
308
  .results-header {
309
  display: flex;
310
  justify-content: space-between;
311
  align-items: center;
312
- background: var(--white);
313
- padding: 28px 32px;
314
- border-radius: 12px;
315
- box-shadow: var(--shadow-md);
316
- border: 1px solid var(--medium-gray);
317
  }
318
 
319
  .results-header h2 {
320
- font-size: 24px;
321
  font-weight: 600;
322
  color: var(--text-primary);
 
323
  }
324
 
325
  .export-button {
326
- background: var(--white);
327
- color: var(--polymarket-blue);
328
- border: 1px solid var(--polymarket-blue);
329
- padding: 10px 20px;
330
  border-radius: 6px;
331
- font-size: 14px;
332
  font-weight: 500;
333
  cursor: pointer;
334
- transition: all 0.2s;
 
335
  }
336
 
337
  .export-button:hover {
338
- background: var(--polymarket-blue);
339
- color: var(--white);
340
  }
341
 
342
  /* Statistics Grid */
343
  .stats-grid {
344
  display: grid;
345
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
346
- gap: 24px;
347
  }
348
 
349
  .stat-card {
350
- background: var(--white);
351
- border-radius: 12px;
352
- padding: 28px;
353
- box-shadow: var(--shadow-md);
354
- border: 1px solid var(--medium-gray);
355
  }
356
 
357
  .stat-header {
358
- margin-bottom: 20px;
359
  }
360
 
361
  .stat-header h3 {
362
- font-size: 18px;
363
  font-weight: 600;
364
  color: var(--text-primary);
 
365
  }
366
 
367
  .stat-content {
368
  display: flex;
369
  flex-direction: column;
370
- gap: 16px;
371
  }
372
 
373
  .stat-item {
@@ -377,14 +404,16 @@ body {
377
  }
378
 
379
  .stat-label {
380
- font-size: 14px;
381
  color: var(--text-secondary);
 
382
  }
383
 
384
  .stat-value {
385
  font-size: 16px;
386
  font-weight: 600;
387
  color: var(--text-primary);
 
388
  }
389
 
390
  .stat-value.positive {
@@ -403,25 +432,26 @@ body {
403
  .charts-grid {
404
  display: grid;
405
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
406
- gap: 24px;
407
  }
408
 
409
  .chart-card {
410
- background: var(--white);
411
- border-radius: 12px;
412
- padding: 28px;
413
- box-shadow: var(--shadow-md);
414
- border: 1px solid var(--medium-gray);
415
  }
416
 
417
  .chart-header {
418
- margin-bottom: 20px;
419
  }
420
 
421
  .chart-header h3 {
422
- font-size: 18px;
423
  font-weight: 600;
424
  color: var(--text-primary);
 
425
  }
426
 
427
  .chart-container {
@@ -434,44 +464,52 @@ body {
434
  /* Responsive Design */
435
  @media (max-width: 768px) {
436
  .nav-container {
437
- padding: 0 20px;
438
- height: 64px;
 
 
 
 
 
 
 
 
439
  }
440
 
441
  .main-container {
442
- padding: 20px;
443
- gap: 24px;
444
  }
445
 
446
  .controls-section {
447
- padding: 24px;
448
  }
449
 
450
  .controls-grid {
451
  grid-template-columns: 1fr;
452
- gap: 20px;
453
  }
454
 
455
  .simulation-tabs {
456
  flex-direction: column;
457
- gap: 12px;
458
  }
459
 
460
  .charts-grid {
461
  grid-template-columns: 1fr;
462
- gap: 20px;
463
  }
464
 
465
  .chart-card,
466
  .stat-card {
467
- padding: 20px;
468
  }
469
 
470
  .results-header {
471
  flex-direction: column;
472
- gap: 16px;
473
  align-items: stretch;
474
- padding: 24px;
475
  }
476
  }
477
 
@@ -487,9 +525,9 @@ body {
487
 
488
  /* Conditional visibility classes */
489
  .single-only, .threshold-only, .multi-only {
490
- transition: all 0.3s ease;
491
  }
492
 
493
  .multi-stats, .threshold-stats, .multi-chart {
494
- transition: all 0.3s ease;
495
- }
 
1
+ /* Polymarket Macro Dashboard Style Guide Implementation */
2
+
3
  :root {
4
+ /* Base Colors - Matching Style Guide */
5
+ --bg-primary: #ffffff;
6
+ --text-primary: #0a0a0a;
7
+ --text-secondary: #6b6b6b;
8
+ --accent: #1f6feb;
9
+
10
+ /* Supporting Colors */
11
+ --border-color: #e5e5e5;
12
+ --bg-secondary: #fafafa;
13
+ --accent-hover: #1a5fd9;
14
+ --accent-light: #e8f0fe;
15
+
16
+ /* Status Colors (minimal use) */
17
+ --success: #10b981;
18
+ --error: #ef4444;
19
+ --warning: #f59e0b;
20
+
21
+ /* Design Tokens */
22
+ --radius-card: 8px;
23
+ --spacing-unit: 16px;
24
+ --font-body: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
25
+
26
+ /* Shadows - Very Subtle */
27
+ --shadow-card: 0 1px 2px 0 rgba(0, 0, 0, 0.03);
28
+ --shadow-hover: 0 2px 4px 0 rgba(0, 0, 0, 0.05);
29
  }
30
 
31
  /* Reset and base styles */
 
36
  }
37
 
38
  body {
39
+ font-family: var(--font-body);
40
+ background-color: var(--bg-primary);
41
  color: var(--text-primary);
42
+ line-height: 1.6;
43
  min-height: 100vh;
44
+ -webkit-font-smoothing: antialiased;
45
+ -moz-osx-font-smoothing: grayscale;
46
  }
47
 
48
  /* Top Navigation Bar */
49
  .top-bar {
50
+ background-color: var(--bg-primary);
51
+ border-bottom: 1px solid var(--border-color);
 
52
  position: sticky;
53
  top: 0;
54
  z-index: 100;
 
57
  .nav-container {
58
  max-width: 1200px;
59
  margin: 0 auto;
60
+ padding: 0 calc(var(--spacing-unit) * 2);
61
  display: flex;
62
  align-items: center;
63
  justify-content: space-between;
64
+ height: 64px;
65
  }
66
 
67
  .logo-section {
 
71
  }
72
 
73
  .logo {
74
+ height: 28px;
75
  width: auto;
76
  }
77
 
78
  .app-title {
79
+ font-size: 18px;
80
  font-weight: 600;
81
+ color: var(--text-primary);
82
+ letter-spacing: -0.01em;
83
  }
84
 
85
  .subtitle {
86
+ font-size: 13px;
87
  color: var(--text-secondary);
88
  font-weight: 400;
89
  }
 
94
  }
95
 
96
  .dataset-info {
97
+ font-size: 13px;
98
  color: var(--text-secondary);
99
+ background: var(--bg-secondary);
100
  padding: 6px 12px;
101
+ border-radius: 6px;
102
  }
103
 
104
  /* Main Container */
105
  .main-container {
106
  max-width: 1200px;
107
  margin: 0 auto;
108
+ padding: calc(var(--spacing-unit) * 2);
109
  display: flex;
110
  flex-direction: column;
111
+ gap: calc(var(--spacing-unit) * 2);
112
  }
113
 
114
  /* Controls Section */
115
  .controls-section {
116
+ background: var(--bg-primary);
117
+ border-radius: var(--radius-card);
118
+ padding: calc(var(--spacing-unit) * 2);
119
+ border: 1px solid var(--border-color);
120
+ box-shadow: var(--shadow-card);
121
  }
122
 
123
  .controls-header {
124
+ margin-bottom: calc(var(--spacing-unit) * 2);
125
  }
126
 
127
  .controls-header h2 {
128
+ font-size: 22px;
129
  font-weight: 600;
130
+ margin-bottom: 6px;
131
  color: var(--text-primary);
132
+ letter-spacing: -0.01em;
133
  }
134
 
135
  .controls-header p {
136
+ font-size: 14px;
137
  color: var(--text-secondary);
138
+ font-weight: 400;
139
  }
140
 
141
  .controls-grid {
142
  display: grid;
143
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
144
+ gap: calc(var(--spacing-unit) * 1.5);
145
+ margin-bottom: calc(var(--spacing-unit) * 2);
146
  }
147
 
148
  .control-group {
 
155
  }
156
 
157
  .control-label {
158
+ font-size: 13px;
159
  font-weight: 500;
160
  color: var(--text-primary);
161
+ margin-bottom: 8px;
162
  }
163
 
164
  .control-input {
165
+ padding: 10px 12px;
166
+ border: 1px solid var(--border-color);
167
+ border-radius: 6px;
168
  font-size: 14px;
169
+ background: var(--bg-primary);
170
+ color: var(--text-primary);
171
+ transition: border-color 0.15s ease;
172
  outline: none;
173
+ font-family: var(--font-body);
174
  }
175
 
176
  .control-input:focus {
177
+ border-color: var(--accent);
178
+ outline: 2px solid var(--accent-light);
179
+ outline-offset: 0;
180
  }
181
 
182
  .control-subtitle {
183
  font-size: 12px;
184
  color: var(--text-secondary);
185
  margin-top: 6px;
186
+ font-weight: 400;
187
  }
188
 
189
  /* Simulation Tabs */
190
  .simulation-tabs {
191
  display: flex;
192
+ gap: var(--spacing-unit);
193
+ margin-top: 8px;
194
  }
195
 
196
  .sim-tab {
197
  flex: 1;
198
+ padding: calc(var(--spacing-unit) * 1.25);
199
+ border: 1px solid var(--border-color);
200
+ border-radius: var(--radius-card);
201
+ background: var(--bg-primary);
202
  cursor: pointer;
203
+ transition: border-color 0.15s ease, background-color 0.15s ease;
204
  text-align: left;
205
  }
206
 
207
  .sim-tab:hover {
208
+ border-color: var(--accent);
209
+ background: var(--bg-secondary);
210
  }
211
 
212
  .sim-tab.active {
213
+ border-color: var(--accent);
214
+ background: var(--accent-light);
215
  }
216
 
217
  .tab-title {
218
+ font-size: 15px;
219
  font-weight: 600;
220
  color: var(--text-primary);
221
+ margin-bottom: 3px;
222
  }
223
 
224
  .tab-subtitle {
225
+ font-size: 13px;
226
  color: var(--text-secondary);
227
+ font-weight: 400;
228
  }
229
 
230
  /* Run Section */
 
232
  display: flex;
233
  align-items: center;
234
  justify-content: center;
235
+ gap: var(--spacing-unit);
236
+ padding-top: calc(var(--spacing-unit) * 2);
237
+ border-top: 1px solid var(--border-color);
238
+ margin-top: calc(var(--spacing-unit) * 0.5);
239
  }
240
 
241
  .run-button {
242
+ background: var(--accent);
243
+ color: var(--bg-primary);
244
  border: none;
245
+ padding: 12px 28px;
246
+ border-radius: 6px;
247
+ font-size: 14px;
248
  font-weight: 600;
249
  cursor: pointer;
250
+ transition: background-color 0.15s ease;
251
  display: flex;
252
  align-items: center;
253
  gap: 8px;
254
+ font-family: var(--font-body);
255
  }
256
 
257
  .run-button:hover:not(:disabled) {
258
+ background: var(--accent-hover);
259
  }
260
 
261
  .run-button:disabled {
262
+ background: var(--text-secondary);
263
  cursor: not-allowed;
264
+ opacity: 0.6;
265
  }
266
 
267
  .run-spinner {
268
+ width: 18px;
269
+ height: 18px;
270
  border: 2px solid transparent;
271
+ border-top: 2px solid var(--bg-primary);
272
  border-radius: 50%;
273
+ animation: spin 0.8s linear infinite;
274
  }
275
 
276
  @keyframes spin {
 
279
  }
280
 
281
  .run-info {
282
+ font-size: 13px;
283
  color: var(--text-secondary);
284
  }
285
 
286
  /* Progress Section */
287
  .progress-section {
288
+ background: var(--bg-primary);
289
+ border-radius: var(--radius-card);
290
+ padding: calc(var(--spacing-unit) * 2);
291
+ border: 1px solid var(--border-color);
292
+ box-shadow: var(--shadow-card);
293
  }
294
 
295
  .progress-container {
 
301
  display: flex;
302
  justify-content: space-between;
303
  align-items: center;
304
+ margin-bottom: 10px;
305
+ font-size: 14px;
306
+ color: var(--text-primary);
307
  }
308
 
309
  .progress-bar {
310
  width: 100%;
311
+ height: 6px;
312
+ background: var(--bg-secondary);
313
+ border-radius: 3px;
314
  overflow: hidden;
315
  }
316
 
317
  .progress-fill {
318
  height: 100%;
319
+ background: var(--accent);
320
+ border-radius: 3px;
321
+ transition: width 0.2s ease;
322
  width: 0%;
323
  }
324
 
 
326
  .results-section {
327
  display: flex;
328
  flex-direction: column;
329
+ gap: calc(var(--spacing-unit) * 1.5);
330
  }
331
 
332
  .results-header {
333
  display: flex;
334
  justify-content: space-between;
335
  align-items: center;
336
+ background: var(--bg-primary);
337
+ padding: calc(var(--spacing-unit) * 1.75) calc(var(--spacing-unit) * 2);
338
+ border-radius: var(--radius-card);
339
+ border: 1px solid var(--border-color);
340
+ box-shadow: var(--shadow-card);
341
  }
342
 
343
  .results-header h2 {
344
+ font-size: 22px;
345
  font-weight: 600;
346
  color: var(--text-primary);
347
+ letter-spacing: -0.01em;
348
  }
349
 
350
  .export-button {
351
+ background: var(--bg-primary);
352
+ color: var(--accent);
353
+ border: 1px solid var(--border-color);
354
+ padding: 8px 16px;
355
  border-radius: 6px;
356
+ font-size: 13px;
357
  font-weight: 500;
358
  cursor: pointer;
359
+ transition: all 0.15s ease;
360
+ font-family: var(--font-body);
361
  }
362
 
363
  .export-button:hover {
364
+ background: var(--bg-secondary);
365
+ border-color: var(--accent);
366
  }
367
 
368
  /* Statistics Grid */
369
  .stats-grid {
370
  display: grid;
371
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
372
+ gap: calc(var(--spacing-unit) * 1.5);
373
  }
374
 
375
  .stat-card {
376
+ background: var(--bg-primary);
377
+ border-radius: var(--radius-card);
378
+ padding: calc(var(--spacing-unit) * 1.75);
379
+ border: 1px solid var(--border-color);
380
+ box-shadow: var(--shadow-card);
381
  }
382
 
383
  .stat-header {
384
+ margin-bottom: calc(var(--spacing-unit) * 1.25);
385
  }
386
 
387
  .stat-header h3 {
388
+ font-size: 16px;
389
  font-weight: 600;
390
  color: var(--text-primary);
391
+ letter-spacing: -0.01em;
392
  }
393
 
394
  .stat-content {
395
  display: flex;
396
  flex-direction: column;
397
+ gap: calc(var(--spacing-unit) * 1.25);
398
  }
399
 
400
  .stat-item {
 
404
  }
405
 
406
  .stat-label {
407
+ font-size: 13px;
408
  color: var(--text-secondary);
409
+ font-weight: 400;
410
  }
411
 
412
  .stat-value {
413
  font-size: 16px;
414
  font-weight: 600;
415
  color: var(--text-primary);
416
+ letter-spacing: -0.01em;
417
  }
418
 
419
  .stat-value.positive {
 
432
  .charts-grid {
433
  display: grid;
434
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
435
+ gap: calc(var(--spacing-unit) * 1.5);
436
  }
437
 
438
  .chart-card {
439
+ background: var(--bg-primary);
440
+ border-radius: var(--radius-card);
441
+ padding: calc(var(--spacing-unit) * 1.75);
442
+ border: 1px solid var(--border-color);
443
+ box-shadow: var(--shadow-card);
444
  }
445
 
446
  .chart-header {
447
+ margin-bottom: calc(var(--spacing-unit) * 1.25);
448
  }
449
 
450
  .chart-header h3 {
451
+ font-size: 16px;
452
  font-weight: 600;
453
  color: var(--text-primary);
454
+ letter-spacing: -0.01em;
455
  }
456
 
457
  .chart-container {
 
464
  /* Responsive Design */
465
  @media (max-width: 768px) {
466
  .nav-container {
467
+ padding: 0 var(--spacing-unit);
468
+ height: 56px;
469
+ }
470
+
471
+ .app-title {
472
+ font-size: 16px;
473
+ }
474
+
475
+ .subtitle {
476
+ font-size: 12px;
477
  }
478
 
479
  .main-container {
480
+ padding: var(--spacing-unit);
481
+ gap: var(--spacing-unit);
482
  }
483
 
484
  .controls-section {
485
+ padding: calc(var(--spacing-unit) * 1.5);
486
  }
487
 
488
  .controls-grid {
489
  grid-template-columns: 1fr;
490
+ gap: var(--spacing-unit);
491
  }
492
 
493
  .simulation-tabs {
494
  flex-direction: column;
495
+ gap: var(--spacing-unit);
496
  }
497
 
498
  .charts-grid {
499
  grid-template-columns: 1fr;
500
+ gap: var(--spacing-unit);
501
  }
502
 
503
  .chart-card,
504
  .stat-card {
505
+ padding: calc(var(--spacing-unit) * 1.5);
506
  }
507
 
508
  .results-header {
509
  flex-direction: column;
510
+ gap: var(--spacing-unit);
511
  align-items: stretch;
512
+ padding: calc(var(--spacing-unit) * 1.5);
513
  }
514
  }
515
 
 
525
 
526
  /* Conditional visibility classes */
527
  .single-only, .threshold-only, .multi-only {
528
+ transition: opacity 0.2s ease;
529
  }
530
 
531
  .multi-stats, .threshold-stats, .multi-chart {
532
+ transition: opacity 0.2s ease;
533
+ }