AndyKandy26 commited on
Commit
01e2f61
·
verified ·
1 Parent(s): ba8cb8f

Upload 2 files

Browse files
Files changed (2) hide show
  1. index.html +222 -162
  2. picks.html +1466 -0
index.html CHANGED
@@ -30,14 +30,14 @@
30
  pointer-events: none;
31
  }
32
  .hero-greeting { font-family: var(--font-head); font-size: 13px; color: var(--text2); text-transform: uppercase; letter-spacing: 0.1em; }
33
- .hero-amount { font-family: var(--font-head); font-size: 42px; font-weight: 800; line-height: 1; margin: 8px 0; }
34
- .hero-sub { font-size: 14px; color: var(--text2); }
35
- .hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }
36
  .portfolio-value-change { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
37
 
38
  .quick-actions {
39
  display: grid;
40
- grid-template-columns: repeat(4, 1fr);
41
  gap: 12px;
42
  margin-bottom: 24px;
43
  }
@@ -57,15 +57,34 @@
57
  transform: translateY(-3px);
58
  box-shadow: var(--glow-c);
59
  }
60
- .qa-icon { font-size: 28px; margin-bottom: 8px; }
 
 
 
 
 
 
 
 
 
61
  .qa-label { font-size: 12px; font-weight: 700; color: var(--text2); text-transform: uppercase; letter-spacing: 0.06em; }
 
 
 
 
 
 
 
 
 
 
 
 
62
 
63
  .chart-card { height: 100%; }
64
  .chart-container { position: relative; height: 240px; }
65
 
66
- .goal-item {
67
- margin-bottom: 16px;
68
- }
69
  .goal-header {
70
  display: flex;
71
  justify-content: space-between;
@@ -73,7 +92,7 @@
73
  font-size: 13px;
74
  }
75
  .goal-name { font-weight: 600; }
76
- .goal-pct { color: var(--cyan); font-family: var(--font-mono); }
77
 
78
  .activity-item {
79
  display: flex;
@@ -118,189 +137,231 @@
118
  }
119
  .legend-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
120
  .legend-name { flex: 1; color: var(--text2); }
121
- .legend-pct { font-family: var(--font-mono); font-size: 12px; color: var(--text); font-weight: 600; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  </style>
123
  </head>
124
  <body>
125
  <div class="app-shell">
126
 
127
- <!-- Sidebar -->
128
- <nav class="sidebar">
129
- <div class="sidebar-logo">
130
- <div class="logo-mark">
131
- <div class="logo-icon">📈</div>
132
- <div>
133
- <div class="logo-text">FinWise</div>
134
- <div class="logo-sub">Smart Investing</div>
135
- </div>
136
  </div>
137
  </div>
138
- <div class="nav-section">
139
- <div class="nav-label">Main</div>
140
- <a href="index.html" class="nav-item"><span class="nav-icon">🏠</span> Dashboard</a>
141
- <a href="portfolio.html" class="nav-item"><span class="nav-icon">📊</span> Portfolio Builder</a>
142
- <a href="risk.html" class="nav-item"><span class="nav-icon">🎯</span> Risk Analyzer</a>
143
- <a href="tracker.html" class="nav-item"><span class="nav-icon">📈</span> Tracker</a>
144
- <div class="nav-label">Tools</div>
145
- <a href="calculators.html" class="nav-item"><span class="nav-icon">🧮</span> Calculators</a>
146
- <a href="insights.html" class="nav-item"><span class="nav-icon">💡</span> Insights <span class="nav-badge">New</span></a>
147
- </div>
148
- <div class="sidebar-footer">
149
- <div class="market-ticker">Live Market</div>
150
- <div id="sidebar-tickers"></div>
151
- </div>
152
- </nav>
 
 
 
153
 
154
- <!-- Main -->
155
- <main class="main-content">
156
 
157
- <!-- Hero Banner -->
158
- <div class="hero-banner fade-in">
159
- <div>
160
- <div class="hero-greeting">👋 Good morning, Investor</div>
161
- <div class="hero-amount" id="hero-amount">$0.00</div>
162
- <div class="portfolio-value-change">
163
- <span class="badge badge-emerald" id="hero-badge">▲ +$0.00 today</span>
164
- <span class="text-muted text-sm">Total portfolio value</span>
165
- </div>
166
- <div class="hero-sub" style="margin-top:10px;">Your portfolio is performing <strong style="color:var(--cyan)">above average</strong> this month 🚀</div>
167
- </div>
168
- <div class="hero-actions">
169
- <a href="portfolio.html" class="btn btn-primary">🔧 Build Portfolio</a>
170
- <a href="tracker.html" class="btn btn-secondary">📊 View Tracker</a>
171
  </div>
 
172
  </div>
173
-
174
- <!-- Stat Grid -->
175
- <div class="stat-grid fade-in fade-in-1">
176
- <div class="stat-card" style="--accent-color: var(--cyan)">
177
- <div class="stat-label">Total Invested</div>
178
- <div class="stat-value" id="stat-invested">$0</div>
179
- <div class="stat-change up">📅 Since inception</div>
180
- </div>
181
- <div class="stat-card" style="--accent-color: var(--emerald)">
182
- <div class="stat-label">Total Gain/Loss</div>
183
- <div class="stat-value up" id="stat-gain">+$0</div>
184
- <div class="stat-change up" id="stat-gain-pct">▲ 0.00%</div>
185
- </div>
186
- <div class="stat-card" style="--accent-color: var(--violet)">
187
- <div class="stat-label">Risk Score</div>
188
- <div class="stat-value" id="stat-risk">—</div>
189
- <div class="stat-change" id="stat-risk-label">Moderate</div>
190
- </div>
191
- <div class="stat-card" style="--accent-color: var(--amber)">
192
- <div class="stat-label">Diversification</div>
193
- <div class="stat-value" id="stat-div">—</div>
194
- <div class="stat-change up">▲ Well balanced</div>
195
- </div>
196
  </div>
 
197
 
198
- <!-- Quick Actions -->
199
- <div class="quick-actions fade-in fade-in-2">
200
- <a href="portfolio.html" class="quick-action-card"><div class="qa-icon">🏗️</div><div class="qa-label">Build Portfolio</div></a>
201
- <a href="risk.html" class="quick-action-card"><div class="qa-icon">🎯</div><div class="qa-label">Risk Check</div></a>
202
- <a href="calculators.html" class="quick-action-card"><div class="qa-icon">🧮</div><div class="qa-label">Calculators</div></a>
203
- <a href="insights.html" class="quick-action-card"><div class="qa-icon">💡</div><div class="qa-label">AI Insights</div></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  </div>
 
205
 
206
- <!-- Charts Row -->
207
- <div class="grid-60-40 fade-in fade-in-3" style="margin-bottom:20px">
208
- <div class="card chart-card">
209
- <div class="card-title">📈 Portfolio Performance <span class="badge badge-emerald" style="margin-left:auto">+12.4% YTD</span></div>
210
- <div class="chart-container">
211
- <canvas id="performanceChart"></canvas>
212
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  </div>
214
- <div class="card">
215
- <div class="card-title">🥧 Allocation</div>
216
- <div style="position:relative;height:180px">
217
- <canvas id="allocChart"></canvas>
218
- </div>
219
- <div class="allocation-legend" id="alloc-legend"></div>
220
  </div>
 
221
  </div>
 
222
 
223
- <!-- Bottom Row -->
224
- <div class="grid-2 fade-in fade-in-4">
225
- <!-- Goals -->
226
- <div class="card">
227
- <div class="card-title">🎯 Goal Progress</div>
228
- <div id="goals-list">
229
- <div class="goal-item">
230
- <div class="goal-header"><span class="goal-name">🏖️ Retirement Fund</span><span class="goal-pct">34%</span></div>
231
- <div class="progress-bar"><div class="progress-fill" style="width:34%;background:linear-gradient(90deg,var(--cyan),var(--emerald))"></div></div>
232
- <div class="text-sm text-muted" style="margin-top:4px">$34,000 / $100,000 target by 2045</div>
233
- </div>
234
- <div class="goal-item">
235
- <div class="goal-header"><span class="goal-name">🏠 Down Payment</span><span class="goal-pct">61%</span></div>
236
- <div class="progress-bar"><div class="progress-fill" style="width:61%;background:linear-gradient(90deg,var(--violet),var(--cyan))"></div></div>
237
- <div class="text-sm text-muted" style="margin-top:4px">$30,500 / $50,000 target by 2027</div>
238
- </div>
239
- <div class="goal-item">
240
- <div class="goal-header"><span class="goal-name">📚 Education Fund</span><span class="goal-pct">18%</span></div>
241
- <div class="progress-bar"><div class="progress-fill" style="width:18%;background:linear-gradient(90deg,var(--amber),var(--rose))"></div></div>
242
- <div class="text-sm text-muted" style="margin-top:4px">$3,600 / $20,000 target by 2030</div>
243
- </div>
244
  </div>
245
- <a href="calculators.html" class="btn btn-secondary btn-sm btn-full" style="margin-top:16px">Plan a new goal →</a>
246
  </div>
 
 
247
 
248
- <!-- Recent Activity -->
249
- <div class="card">
250
- <div class="card-title">⚡ Recent Activity</div>
251
- <div id="activity-list">
252
- <div class="activity-item">
253
- <div class="activity-icon" style="background:rgba(16,185,129,0.15)">💰</div>
254
- <div class="activity-info"><div class="activity-name">Bought VOO</div><div class="activity-date">May 1, 2026</div></div>
255
- <div class="activity-amount up">+3 shares</div>
256
- </div>
257
- <div class="activity-item">
258
- <div class="activity-icon" style="background:rgba(34,211,238,0.15)">📥</div>
259
- <div class="activity-info"><div class="activity-name">Dividend — AAPL</div><div class="activity-date">Apr 28, 2026</div></div>
260
- <div class="activity-amount up">+$12.40</div>
261
- </div>
262
- <div class="activity-item">
263
- <div class="activity-icon" style="background:rgba(139,92,246,0.15)">🔄</div>
264
- <div class="activity-info"><div class="activity-name">Rebalanced Portfolio</div><div class="activity-date">Apr 20, 2026</div></div>
265
- <div class="activity-amount" style="color:var(--text2)">Optimized</div>
266
- </div>
267
- <div class="activity-item">
268
- <div class="activity-icon" style="background:rgba(245,158,11,0.15)">💹</div>
269
- <div class="activity-info"><div class="activity-name">Added NVDA</div><div class="activity-date">Apr 15, 2026</div></div>
270
- <div class="activity-amount up">+1 share</div>
271
- </div>
272
  </div>
273
- <a href="tracker.html" class="btn btn-secondary btn-sm btn-full" style="margin-top:16px">Full history →</a>
274
  </div>
 
275
  </div>
 
276
 
277
- <!-- Market Overview -->
278
- <div class="card fade-in" style="margin-top:20px">
279
- <div class="card-title">🌐 Market Overview</div>
280
- <div class="market-overview">
281
- <div class="market-item"><div class="market-sym">S&P 500</div><div class="market-val">5,308</div><div class="market-chg up">▲ +0.26%</div></div>
282
- <div class="market-item"><div class="market-sym">NASDAQ</div><div class="market-val">16,742</div><div class="market-chg down">▼ -0.46%</div></div>
283
- <div class="market-item"><div class="market-sym">DOW</div><div class="market-val">39,512</div><div class="market-chg up">▲ +0.18%</div></div>
284
- <div class="market-item"><div class="market-sym">BTC</div><div class="market-val">$68,420</div><div class="market-chg up">▲ +2.14%</div></div>
285
- <div class="market-item"><div class="market-sym">GOLD</div><div class="market-val">$2,318</div><div class="market-chg up">▲ +1.49%</div></div>
286
- <div class="market-item"><div class="market-sym">10Y BOND</div><div class="market-val">4.48%</div><div class="market-chg down">▼ -0.03%</div></div>
287
- <div class="market-item"><div class="market-sym">USD/EUR</div><div class="market-val">0.924</div><div class="market-chg down">▼ -0.12%</div></div>
288
- <div class="market-item"><div class="market-sym">VIX</div><div class="market-val">14.82</div><div class="market-chg up">▲ +3.2%</div></div>
289
- </div>
 
 
 
 
 
 
 
290
  </div>
 
 
291
 
292
- </main>
293
  </div>
294
 
295
- <!-- Mobile Bottom Nav -->
296
  <nav class="bottom-nav">
297
  <div class="bottom-nav-inner">
298
- <a href="index.html" class="bottom-nav-item"><span class="bnav-icon">🏠</span>Home</a>
299
  <a href="portfolio.html" class="bottom-nav-item"><span class="bnav-icon">📊</span>Portfolio</a>
300
  <a href="risk.html" class="bottom-nav-item"><span class="bnav-icon">🎯</span>Risk</a>
301
  <a href="tracker.html" class="bottom-nav-item"><span class="bnav-icon">📈</span>Track</a>
302
  <a href="calculators.html" class="bottom-nav-item"><span class="bnav-icon">🧮</span>Calc</a>
303
- <a href="insights.html" class="bottom-nav-item"><span class="bnav-icon">💡</span>Insights</a>
 
304
  </div>
305
  </nav>
306
 
@@ -309,9 +370,9 @@
309
  document.addEventListener('DOMContentLoaded', () => {
310
  const portfolio = getPortfolio();
311
  const currentValue = portfolio.assets.reduce((s,a) => s + a.shares * a.price, 0);
312
- const invested = portfolio.totalInvested;
313
- const gain = currentValue - invested;
314
- const gainPct = (gain / invested) * 100;
315
  const todayChange = currentValue * 0.0026;
316
 
317
  // Hero
@@ -327,11 +388,10 @@ document.addEventListener('DOMContentLoaded', () => {
327
  document.getElementById('stat-gain-pct').className = 'stat-change ' + (gain >= 0 ? 'up' : 'down');
328
 
329
  const riskScore = calcRiskScore(portfolio);
330
- const divScore = calcDiversification(portfolio);
331
  document.getElementById('stat-risk').textContent = riskScore + '/100';
332
  const riskLabels = ['Very Low','Low','Moderate','Moderate-High','High'];
333
- const riskLabel = riskLabels[Math.floor(riskScore / 25)];
334
- document.getElementById('stat-risk-label').textContent = '→ ' + riskLabel;
335
  document.getElementById('stat-div').textContent = divScore + '/100';
336
 
337
  // Performance Chart
 
30
  pointer-events: none;
31
  }
32
  .hero-greeting { font-family: var(--font-head); font-size: 13px; color: var(--text2); text-transform: uppercase; letter-spacing: 0.1em; }
33
+ .hero-amount { font-family: var(--font-head); font-size: 42px; font-weight: 800; line-height: 1; margin: 8px 0; }
34
+ .hero-sub { font-size: 14px; color: var(--text2); }
35
+ .hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }
36
  .portfolio-value-change { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
37
 
38
  .quick-actions {
39
  display: grid;
40
+ grid-template-columns: repeat(5, 1fr);
41
  gap: 12px;
42
  margin-bottom: 24px;
43
  }
 
57
  transform: translateY(-3px);
58
  box-shadow: var(--glow-c);
59
  }
60
+ /* Picks card highlight */
61
+ .quick-action-card.picks-card {
62
+ border-color: rgba(16,185,129,0.35);
63
+ background: rgba(16,185,129,0.04);
64
+ }
65
+ .quick-action-card.picks-card:hover {
66
+ border-color: var(--emerald);
67
+ box-shadow: 0 0 18px rgba(16,185,129,0.18);
68
+ }
69
+ .qa-icon { font-size: 28px; margin-bottom: 8px; }
70
  .qa-label { font-size: 12px; font-weight: 700; color: var(--text2); text-transform: uppercase; letter-spacing: 0.06em; }
71
+ .qa-badge-pill {
72
+ display: inline-block;
73
+ margin-top: 5px;
74
+ background: var(--emerald);
75
+ color: #000;
76
+ font-size: 9px;
77
+ font-weight: 800;
78
+ padding: 2px 7px;
79
+ border-radius: 20px;
80
+ text-transform: uppercase;
81
+ letter-spacing: .5px;
82
+ }
83
 
84
  .chart-card { height: 100%; }
85
  .chart-container { position: relative; height: 240px; }
86
 
87
+ .goal-item { margin-bottom: 16px; }
 
 
88
  .goal-header {
89
  display: flex;
90
  justify-content: space-between;
 
92
  font-size: 13px;
93
  }
94
  .goal-name { font-weight: 600; }
95
+ .goal-pct { color: var(--cyan); font-family: var(--font-mono); }
96
 
97
  .activity-item {
98
  display: flex;
 
137
  }
138
  .legend-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
139
  .legend-name { flex: 1; color: var(--text2); }
140
+ .legend-pct { font-family: var(--font-mono); font-size: 12px; color: var(--text); font-weight: 600; }
141
+
142
+ /* Picks CTA banner */
143
+ .picks-cta {
144
+ background: linear-gradient(135deg, rgba(16,185,129,0.1), rgba(34,211,238,0.06));
145
+ border: 1px solid rgba(16,185,129,0.4);
146
+ border-radius: var(--r-lg);
147
+ padding: 22px 28px;
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: space-between;
151
+ gap: 16px;
152
+ flex-wrap: wrap;
153
+ margin-top: 20px;
154
+ }
155
+ .picks-cta-title { font-size: 15px; font-weight: 800; margin-bottom: 5px; }
156
+ .picks-cta-sub { font-size: 13px; color: var(--text2); }
157
+
158
+ @media (max-width: 768px) {
159
+ .quick-actions { grid-template-columns: repeat(3, 1fr); }
160
+ .picks-cta { flex-direction: column; align-items: flex-start; }
161
+ }
162
+ @media (max-width: 480px) {
163
+ .quick-actions { grid-template-columns: repeat(2, 1fr); }
164
+ }
165
  </style>
166
  </head>
167
  <body>
168
  <div class="app-shell">
169
 
170
+ <!-- ══════════ SIDEBAR ══════════ -->
171
+ <nav class="sidebar">
172
+ <div class="sidebar-logo">
173
+ <div class="logo-mark">
174
+ <div class="logo-icon">📈</div>
175
+ <div>
176
+ <div class="logo-text">FinWise</div>
177
+ <div class="logo-sub">Smart Investing</div>
 
178
  </div>
179
  </div>
180
+ </div>
181
+ <div class="nav-section">
182
+ <div class="nav-label">Main</div>
183
+ <a href="index.html" class="nav-item active"><span class="nav-icon">🏠</span> Dashboard</a>
184
+ <a href="portfolio.html" class="nav-item"><span class="nav-icon">📊</span> Portfolio Builder</a>
185
+ <a href="risk.html" class="nav-item"><span class="nav-icon">🎯</span> Risk Analyzer</a>
186
+ <a href="tracker.html" class="nav-item"><span class="nav-icon">📈</span> Tracker</a>
187
+ <div class="nav-label">Tools</div>
188
+ <a href="calculators.html" class="nav-item"><span class="nav-icon">🧮</span> Calculators</a>
189
+ <a href="insights.html" class="nav-item"><span class="nav-icon">💡</span> Insights <span class="nav-badge">New</span></a>
190
+ <!-- ✅ NEW: Stock & Option Picks -->
191
+ <a href="picks.html" class="nav-item"><span class="nav-icon">🏹</span> Stock &amp; Option Picks <span class="nav-badge" style="background:var(--emerald);color:#000">New</span></a>
192
+ </div>
193
+ <div class="sidebar-footer">
194
+ <div class="market-ticker">Live Market</div>
195
+ <div id="sidebar-tickers"></div>
196
+ </div>
197
+ </nav>
198
 
199
+ <!-- ══════════ MAIN ══════════ -->
200
+ <main class="main-content">
201
 
202
+ <!-- Hero Banner -->
203
+ <div class="hero-banner fade-in">
204
+ <div>
205
+ <div class="hero-greeting">👋 Good morning, Investor</div>
206
+ <div class="hero-amount" id="hero-amount">$0.00</div>
207
+ <div class="portfolio-value-change">
208
+ <span class="badge badge-emerald" id="hero-badge">▲ +$0.00 today</span>
209
+ <span class="text-muted text-sm">Total portfolio value</span>
 
 
 
 
 
 
210
  </div>
211
+ <div class="hero-sub" style="margin-top:10px;">Your portfolio is performing <strong style="color:var(--cyan)">above average</strong> this month 🚀</div>
212
  </div>
213
+ <div class="hero-actions">
214
+ <a href="portfolio.html" class="btn btn-primary">🔧 Build Portfolio</a>
215
+ <a href="tracker.html" class="btn btn-secondary">📊 View Tracker</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  </div>
217
+ </div>
218
 
219
+ <!-- Stat Grid -->
220
+ <div class="stat-grid fade-in fade-in-1">
221
+ <div class="stat-card" style="--accent-color: var(--cyan)">
222
+ <div class="stat-label">Total Invested</div>
223
+ <div class="stat-value" id="stat-invested">$0</div>
224
+ <div class="stat-change up">📅 Since inception</div>
225
+ </div>
226
+ <div class="stat-card" style="--accent-color: var(--emerald)">
227
+ <div class="stat-label">Total Gain/Loss</div>
228
+ <div class="stat-value up" id="stat-gain">+$0</div>
229
+ <div class="stat-change up" id="stat-gain-pct">▲ 0.00%</div>
230
+ </div>
231
+ <div class="stat-card" style="--accent-color: var(--violet)">
232
+ <div class="stat-label">Risk Score</div>
233
+ <div class="stat-value" id="stat-risk">—</div>
234
+ <div class="stat-change" id="stat-risk-label">Moderate</div>
235
+ </div>
236
+ <div class="stat-card" style="--accent-color: var(--amber)">
237
+ <div class="stat-label">Diversification</div>
238
+ <div class="stat-value" id="stat-div">—</div>
239
+ <div class="stat-change up">▲ Well balanced</div>
240
  </div>
241
+ </div>
242
 
243
+ <!-- Quick Actions — now 5 cols with Picks -->
244
+ <div class="quick-actions fade-in fade-in-2">
245
+ <a href="portfolio.html" class="quick-action-card"><div class="qa-icon">🏗️</div><div class="qa-label">Build Portfolio</div></a>
246
+ <a href="risk.html" class="quick-action-card"><div class="qa-icon">🎯</div><div class="qa-label">Risk Check</div></a>
247
+ <a href="calculators.html" class="quick-action-card"><div class="qa-icon">🧮</div><div class="qa-label">Calculators</div></a>
248
+ <a href="insights.html" class="quick-action-card"><div class="qa-icon">💡</div><div class="qa-label">AI Insights</div></a>
249
+ <!-- ✅ NEW -->
250
+ <a href="picks.html" class="quick-action-card picks-card">
251
+ <div class="qa-icon">🏹</div>
252
+ <div class="qa-label">Picks</div>
253
+ <div class="qa-badge-pill">47 Live</div>
254
+ </a>
255
+ </div>
256
+
257
+ <!-- Charts Row -->
258
+ <div class="grid-60-40 fade-in fade-in-3" style="margin-bottom:20px">
259
+ <div class="card chart-card">
260
+ <div class="card-title">📈 Portfolio Performance <span class="badge badge-emerald" style="margin-left:auto">+12.4% YTD</span></div>
261
+ <div class="chart-container">
262
+ <canvas id="performanceChart"></canvas>
263
  </div>
264
+ </div>
265
+ <div class="card">
266
+ <div class="card-title">🥧 Allocation</div>
267
+ <div style="position:relative;height:180px">
268
+ <canvas id="allocChart"></canvas>
 
269
  </div>
270
+ <div class="allocation-legend" id="alloc-legend"></div>
271
  </div>
272
+ </div>
273
 
274
+ <!-- Bottom Row -->
275
+ <div class="grid-2 fade-in fade-in-4">
276
+ <!-- Goals -->
277
+ <div class="card">
278
+ <div class="card-title">🎯 Goal Progress</div>
279
+ <div id="goals-list">
280
+ <div class="goal-item">
281
+ <div class="goal-header"><span class="goal-name">🏖️ Retirement Fund</span><span class="goal-pct">34%</span></div>
282
+ <div class="progress-bar"><div class="progress-fill" style="width:34%;background:linear-gradient(90deg,var(--cyan),var(--emerald))"></div></div>
283
+ <div class="text-sm text-muted" style="margin-top:4px">$34,000 / $100,000 target by 2045</div>
284
+ </div>
285
+ <div class="goal-item">
286
+ <div class="goal-header"><span class="goal-name">🏠 Down Payment</span><span class="goal-pct">61%</span></div>
287
+ <div class="progress-bar"><div class="progress-fill" style="width:61%;background:linear-gradient(90deg,var(--violet),var(--cyan))"></div></div>
288
+ <div class="text-sm text-muted" style="margin-top:4px">$30,500 / $50,000 target by 2027</div>
289
+ </div>
290
+ <div class="goal-item">
291
+ <div class="goal-header"><span class="goal-name">📚 Education Fund</span><span class="goal-pct">18%</span></div>
292
+ <div class="progress-bar"><div class="progress-fill" style="width:18%;background:linear-gradient(90deg,var(--amber),var(--rose))"></div></div>
293
+ <div class="text-sm text-muted" style="margin-top:4px">$3,600 / $20,000 target by 2030</div>
 
294
  </div>
 
295
  </div>
296
+ <a href="calculators.html" class="btn btn-secondary btn-sm btn-full" style="margin-top:16px">Plan a new goal →</a>
297
+ </div>
298
 
299
+ <!-- Recent Activity -->
300
+ <div class="card">
301
+ <div class="card-title">⚡ Recent Activity</div>
302
+ <div id="activity-list">
303
+ <div class="activity-item">
304
+ <div class="activity-icon" style="background:rgba(16,185,129,0.15)">💰</div>
305
+ <div class="activity-info"><div class="activity-name">Bought VOO</div><div class="activity-date">May 1, 2026</div></div>
306
+ <div class="activity-amount up">+3 shares</div>
307
+ </div>
308
+ <div class="activity-item">
309
+ <div class="activity-icon" style="background:rgba(34,211,238,0.15)">📥</div>
310
+ <div class="activity-info"><div class="activity-name">Dividend — AAPL</div><div class="activity-date">Apr 28, 2026</div></div>
311
+ <div class="activity-amount up">+$12.40</div>
312
+ </div>
313
+ <div class="activity-item">
314
+ <div class="activity-icon" style="background:rgba(139,92,246,0.15)">🔄</div>
315
+ <div class="activity-info"><div class="activity-name">Rebalanced Portfolio</div><div class="activity-date">Apr 20, 2026</div></div>
316
+ <div class="activity-amount" style="color:var(--text2)">Optimized</div>
317
+ </div>
318
+ <div class="activity-item">
319
+ <div class="activity-icon" style="background:rgba(245,158,11,0.15)">💹</div>
320
+ <div class="activity-info"><div class="activity-name">Added NVDA</div><div class="activity-date">Apr 15, 2026</div></div>
321
+ <div class="activity-amount up">+1 share</div>
 
322
  </div>
 
323
  </div>
324
+ <a href="tracker.html" class="btn btn-secondary btn-sm btn-full" style="margin-top:16px">Full history →</a>
325
  </div>
326
+ </div>
327
 
328
+ <!-- Market Overview -->
329
+ <div class="card fade-in" style="margin-top:20px">
330
+ <div class="card-title">🌐 Market Overview</div>
331
+ <div class="market-overview">
332
+ <div class="market-item"><div class="market-sym">S&P 500</div><div class="market-val">5,308</div><div class="market-chg up">▲ +0.26%</div></div>
333
+ <div class="market-item"><div class="market-sym">NASDAQ</div><div class="market-val">16,742</div><div class="market-chg down">▼ -0.46%</div></div>
334
+ <div class="market-item"><div class="market-sym">DOW</div><div class="market-val">39,512</div><div class="market-chg up">▲ +0.18%</div></div>
335
+ <div class="market-item"><div class="market-sym">BTC</div><div class="market-val">$68,420</div><div class="market-chg up">▲ +2.14%</div></div>
336
+ <div class="market-item"><div class="market-sym">GOLD</div><div class="market-val">$2,318</div><div class="market-chg up">▲ +1.49%</div></div>
337
+ <div class="market-item"><div class="market-sym">10Y BOND</div><div class="market-val">4.48%</div><div class="market-chg down">▼ -0.03%</div></div>
338
+ <div class="market-item"><div class="market-sym">USD/EUR</div><div class="market-val">0.924</div><div class="market-chg down">▼ -0.12%</div></div>
339
+ <div class="market-item"><div class="market-sym">VIX</div><div class="market-val">14.82</div><div class="market-chg up">▲ +3.2%</div></div>
340
+ </div>
341
+ </div>
342
+
343
+ <!-- ✅ NEW: Picks CTA Banner -->
344
+ <div class="picks-cta fade-in">
345
+ <div>
346
+ <div class="picks-cta-title">🏹 Stock &amp; Option Picks — Now Live</div>
347
+ <div class="picks-cta-sub">47 curated picks across momentum stocks, option selling strategies (CSP, Covered Calls, Strangles, Iron Condors), LEAP calls, and 3× leveraged ETFs. Full filters, sparklines &amp; live refresh.</div>
348
  </div>
349
+ <a href="picks.html" class="btn btn-primary" style="white-space:nowrap;flex-shrink:0">Explore Picks →</a>
350
+ </div>
351
 
352
+ </main>
353
  </div>
354
 
355
+ <!-- ══════════ MOBILE BOTTOM NAV ══════════ -->
356
  <nav class="bottom-nav">
357
  <div class="bottom-nav-inner">
358
+ <a href="index.html" class="bottom-nav-item active"><span class="bnav-icon">🏠</span>Home</a>
359
  <a href="portfolio.html" class="bottom-nav-item"><span class="bnav-icon">📊</span>Portfolio</a>
360
  <a href="risk.html" class="bottom-nav-item"><span class="bnav-icon">🎯</span>Risk</a>
361
  <a href="tracker.html" class="bottom-nav-item"><span class="bnav-icon">📈</span>Track</a>
362
  <a href="calculators.html" class="bottom-nav-item"><span class="bnav-icon">🧮</span>Calc</a>
363
+ <!-- ✅ NEW -->
364
+ <a href="picks.html" class="bottom-nav-item"><span class="bnav-icon">🏹</span>Picks</a>
365
  </div>
366
  </nav>
367
 
 
370
  document.addEventListener('DOMContentLoaded', () => {
371
  const portfolio = getPortfolio();
372
  const currentValue = portfolio.assets.reduce((s,a) => s + a.shares * a.price, 0);
373
+ const invested = portfolio.totalInvested;
374
+ const gain = currentValue - invested;
375
+ const gainPct = (gain / invested) * 100;
376
  const todayChange = currentValue * 0.0026;
377
 
378
  // Hero
 
388
  document.getElementById('stat-gain-pct').className = 'stat-change ' + (gain >= 0 ? 'up' : 'down');
389
 
390
  const riskScore = calcRiskScore(portfolio);
391
+ const divScore = calcDiversification(portfolio);
392
  document.getElementById('stat-risk').textContent = riskScore + '/100';
393
  const riskLabels = ['Very Low','Low','Moderate','Moderate-High','High'];
394
+ document.getElementById('stat-risk-label').textContent = '→ ' + riskLabels[Math.floor(riskScore / 25)];
 
395
  document.getElementById('stat-div').textContent = divScore + '/100';
396
 
397
  // Performance Chart
picks.html ADDED
@@ -0,0 +1,1466 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Stock & Option Picks — FinWise</title>
7
+ <link rel="stylesheet" href="shared.css" />
8
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
9
+ <style>
10
+ /* ── Page-specific styles (no shared.css edits) ── */
11
+ :root {
12
+ --cyan: #22d3ee;
13
+ --emerald: #10b981;
14
+ --violet: #8b5cf6;
15
+ --amber: #f59e0b;
16
+ --rose: #f43f5e;
17
+ --card: #1e2535;
18
+ --border: #2a3347;
19
+ --bg3: #151c2c;
20
+ --text2: #94a3b8;
21
+ --bg: #0f1623;
22
+ --text: #e2e8f0;
23
+ }
24
+
25
+ * { box-sizing: border-box; margin: 0; padding: 0; }
26
+
27
+ body {
28
+ font-family: 'Segoe UI', system-ui, sans-serif;
29
+ background: var(--bg);
30
+ color: var(--text);
31
+ min-height: 100vh;
32
+ display: flex;
33
+ }
34
+
35
+ /* ── Sidebar ── */
36
+ .sidebar {
37
+ width: 240px;
38
+ min-height: 100vh;
39
+ background: var(--bg3);
40
+ border-right: 1px solid var(--border);
41
+ padding: 1.5rem 1rem;
42
+ display: flex;
43
+ flex-direction: column;
44
+ position: fixed;
45
+ top: 0; left: 0; bottom: 0;
46
+ overflow-y: auto;
47
+ z-index: 100;
48
+ }
49
+ .sidebar-logo {
50
+ font-size: 1.4rem;
51
+ font-weight: 800;
52
+ color: var(--cyan);
53
+ letter-spacing: -0.5px;
54
+ margin-bottom: 2rem;
55
+ padding-left: .5rem;
56
+ }
57
+ .sidebar-logo span { color: var(--text); }
58
+ .nav-label {
59
+ font-size: 0.65rem;
60
+ font-weight: 700;
61
+ text-transform: uppercase;
62
+ letter-spacing: 1.2px;
63
+ color: var(--text2);
64
+ padding: .5rem .5rem .25rem;
65
+ margin-top: .75rem;
66
+ }
67
+ .nav-item {
68
+ display: flex;
69
+ align-items: center;
70
+ gap: .6rem;
71
+ padding: .55rem .75rem;
72
+ border-radius: 8px;
73
+ color: var(--text2);
74
+ text-decoration: none;
75
+ font-size: .875rem;
76
+ font-weight: 500;
77
+ transition: all .15s;
78
+ position: relative;
79
+ }
80
+ .nav-item:hover { background: var(--card); color: var(--text); }
81
+ .nav-item.active { background: rgba(34,211,238,.1); color: var(--cyan); }
82
+ .nav-icon { font-size: 1rem; width: 20px; text-align: center; }
83
+ .nav-badge {
84
+ margin-left: auto;
85
+ background: var(--rose);
86
+ color: #fff;
87
+ font-size: .6rem;
88
+ font-weight: 700;
89
+ padding: 2px 6px;
90
+ border-radius: 20px;
91
+ text-transform: uppercase;
92
+ letter-spacing: .5px;
93
+ }
94
+ .nav-badge.new { background: var(--emerald); }
95
+
96
+ /* ── Main Content ── */
97
+ .main-content {
98
+ margin-left: 240px;
99
+ padding: 1.5rem;
100
+ flex: 1;
101
+ min-width: 0;
102
+ }
103
+
104
+ /* ── Page Header ── */
105
+ .page-header {
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: space-between;
109
+ margin-bottom: 1.5rem;
110
+ flex-wrap: wrap;
111
+ gap: 1rem;
112
+ }
113
+ .page-title { font-size: 1.6rem; font-weight: 800; letter-spacing: -.5px; }
114
+ .page-title span { color: var(--cyan); }
115
+ .page-subtitle { color: var(--text2); font-size: .875rem; margin-top: .2rem; }
116
+ .header-actions { display: flex; gap: .75rem; align-items: center; }
117
+
118
+ /* ── Buttons ── */
119
+ .btn {
120
+ display: inline-flex;
121
+ align-items: center;
122
+ gap: .4rem;
123
+ padding: .5rem 1rem;
124
+ border-radius: 8px;
125
+ border: none;
126
+ font-size: .85rem;
127
+ font-weight: 600;
128
+ cursor: pointer;
129
+ transition: all .15s;
130
+ }
131
+ .btn-primary { background: var(--cyan); color: #000; }
132
+ .btn-primary:hover { opacity: .85; }
133
+ .btn-ghost {
134
+ background: transparent;
135
+ color: var(--text2);
136
+ border: 1px solid var(--border);
137
+ }
138
+ .btn-ghost:hover { background: var(--card); color: var(--text); }
139
+
140
+ /* ── Stat Grid ── */
141
+ .stat-grid {
142
+ display: grid;
143
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
144
+ gap: 1rem;
145
+ margin-bottom: 1.5rem;
146
+ }
147
+ .stat-card {
148
+ background: var(--card);
149
+ border: 1px solid var(--border);
150
+ border-radius: 12px;
151
+ padding: 1rem 1.25rem;
152
+ }
153
+ .stat-label { font-size: .72rem; color: var(--text2); text-transform: uppercase; letter-spacing: .8px; font-weight: 600; }
154
+ .stat-value { font-size: 1.6rem; font-weight: 800; margin: .25rem 0 .1rem; font-variant-numeric: tabular-nums; }
155
+ .stat-sub { font-size: .75rem; color: var(--text2); }
156
+ .stat-up { color: var(--emerald); }
157
+ .stat-down { color: var(--rose); }
158
+ .stat-cyan { color: var(--cyan); }
159
+ .stat-amber { color: var(--amber); }
160
+ .stat-violet { color: var(--violet); }
161
+
162
+ /* ── Tab Bar ── */
163
+ .tab-bar {
164
+ display: flex;
165
+ gap: .25rem;
166
+ background: var(--bg3);
167
+ border: 1px solid var(--border);
168
+ border-radius: 12px;
169
+ padding: .35rem;
170
+ margin-bottom: 1.25rem;
171
+ width: fit-content;
172
+ }
173
+ .tab-btn {
174
+ padding: .5rem 1.25rem;
175
+ border-radius: 8px;
176
+ border: none;
177
+ background: transparent;
178
+ color: var(--text2);
179
+ font-size: .875rem;
180
+ font-weight: 600;
181
+ cursor: pointer;
182
+ transition: all .15s;
183
+ white-space: nowrap;
184
+ }
185
+ .tab-btn.active { background: var(--card); color: var(--cyan); box-shadow: 0 0 0 1px var(--border); }
186
+ .tab-btn:hover:not(.active) { color: var(--text); }
187
+
188
+ /* ── Pill Toggle ── */
189
+ .pill-toggle {
190
+ display: flex;
191
+ gap: .2rem;
192
+ background: var(--bg3);
193
+ border: 1px solid var(--border);
194
+ border-radius: 20px;
195
+ padding: .25rem;
196
+ margin-bottom: 1.25rem;
197
+ width: fit-content;
198
+ }
199
+ .pill-btn {
200
+ padding: .35rem 1rem;
201
+ border-radius: 16px;
202
+ border: none;
203
+ background: transparent;
204
+ color: var(--text2);
205
+ font-size: .8rem;
206
+ font-weight: 600;
207
+ cursor: pointer;
208
+ transition: all .15s;
209
+ }
210
+ .pill-btn.active { background: var(--cyan); color: #000; }
211
+
212
+ /* ── Filter Panel ── */
213
+ .filter-panel {
214
+ background: var(--card);
215
+ border: 1px solid var(--border);
216
+ border-radius: 12px;
217
+ padding: 1.25rem;
218
+ margin-bottom: 1.25rem;
219
+ }
220
+ .filter-header {
221
+ display: flex;
222
+ align-items: center;
223
+ justify-content: space-between;
224
+ cursor: pointer;
225
+ user-select: none;
226
+ }
227
+ .filter-title { font-size: .875rem; font-weight: 700; display: flex; align-items: center; gap: .5rem; }
228
+ .filter-toggle-icon { transition: transform .2s; font-size: .75rem; color: var(--text2); }
229
+ .filter-toggle-icon.open { transform: rotate(180deg); }
230
+ .filter-body {
231
+ display: grid;
232
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
233
+ gap: 1rem;
234
+ margin-top: 1rem;
235
+ border-top: 1px solid var(--border);
236
+ padding-top: 1rem;
237
+ }
238
+ .filter-body.collapsed { display: none; }
239
+ .filter-group label {
240
+ display: block;
241
+ font-size: .72rem;
242
+ font-weight: 600;
243
+ text-transform: uppercase;
244
+ letter-spacing: .7px;
245
+ color: var(--text2);
246
+ margin-bottom: .4rem;
247
+ }
248
+ .filter-group input[type=range] {
249
+ width: 100%;
250
+ accent-color: var(--cyan);
251
+ cursor: pointer;
252
+ }
253
+ .range-val { font-size: .8rem; color: var(--cyan); font-weight: 700; margin-top: .2rem; }
254
+ .filter-group select {
255
+ width: 100%;
256
+ background: var(--bg3);
257
+ border: 1px solid var(--border);
258
+ border-radius: 6px;
259
+ color: var(--text);
260
+ padding: .4rem .6rem;
261
+ font-size: .82rem;
262
+ }
263
+ .filter-checkboxes { display: flex; flex-direction: column; gap: .3rem; }
264
+ .filter-checkboxes label {
265
+ display: flex;
266
+ align-items: center;
267
+ gap: .4rem;
268
+ font-size: .82rem;
269
+ font-weight: 500;
270
+ text-transform: none;
271
+ letter-spacing: 0;
272
+ color: var(--text);
273
+ cursor: pointer;
274
+ }
275
+ .filter-checkboxes input[type=checkbox] { accent-color: var(--cyan); }
276
+ .search-box {
277
+ display: flex;
278
+ align-items: center;
279
+ gap: .5rem;
280
+ background: var(--bg3);
281
+ border: 1px solid var(--border);
282
+ border-radius: 8px;
283
+ padding: .45rem .75rem;
284
+ }
285
+ .search-box input {
286
+ background: transparent;
287
+ border: none;
288
+ outline: none;
289
+ color: var(--text);
290
+ font-size: .875rem;
291
+ width: 180px;
292
+ }
293
+ .search-box input::placeholder { color: var(--text2); }
294
+ .filter-actions {
295
+ display: flex;
296
+ gap: .75rem;
297
+ align-items: center;
298
+ margin-top: .75rem;
299
+ flex-wrap: wrap;
300
+ }
301
+
302
+ /* ── Card / Table Container ── */
303
+ .table-wrap {
304
+ background: var(--card);
305
+ border: 1px solid var(--border);
306
+ border-radius: 12px;
307
+ overflow: hidden;
308
+ }
309
+ .table-scroll { overflow-x: auto; }
310
+ table {
311
+ width: 100%;
312
+ border-collapse: collapse;
313
+ font-size: .83rem;
314
+ }
315
+ thead tr {
316
+ background: var(--bg3);
317
+ border-bottom: 1px solid var(--border);
318
+ }
319
+ thead th {
320
+ padding: .75rem 1rem;
321
+ text-align: left;
322
+ font-size: .72rem;
323
+ font-weight: 700;
324
+ text-transform: uppercase;
325
+ letter-spacing: .7px;
326
+ color: var(--text2);
327
+ white-space: nowrap;
328
+ cursor: pointer;
329
+ user-select: none;
330
+ transition: color .15s;
331
+ }
332
+ thead th:hover { color: var(--cyan); }
333
+ thead th .sort-icon { margin-left: .3rem; opacity: .4; }
334
+ thead th.sorted .sort-icon { opacity: 1; color: var(--cyan); }
335
+ tbody tr {
336
+ border-bottom: 1px solid var(--border);
337
+ transition: background .12s;
338
+ }
339
+ tbody tr:last-child { border-bottom: none; }
340
+ tbody tr:hover { background: rgba(255,255,255,.025); }
341
+ td { padding: .7rem 1rem; white-space: nowrap; vertical-align: middle; }
342
+
343
+ /* ── Badges & Pills ── */
344
+ .badge {
345
+ display: inline-block;
346
+ padding: 2px 8px;
347
+ border-radius: 20px;
348
+ font-size: .68rem;
349
+ font-weight: 700;
350
+ text-transform: uppercase;
351
+ letter-spacing: .5px;
352
+ }
353
+ .badge-cyan { background: rgba(34,211,238,.15); color: var(--cyan); }
354
+ .badge-emerald { background: rgba(16,185,129,.15); color: var(--emerald); }
355
+ .badge-amber { background: rgba(245,158,11,.15); color: var(--amber); }
356
+ .badge-rose { background: rgba(244,63,94,.15); color: var(--rose); }
357
+ .badge-violet { background: rgba(139,92,246,.15); color: var(--violet); }
358
+ .badge-gray { background: rgba(148,163,184,.12); color: var(--text2); }
359
+
360
+ /* Sector badges */
361
+ .sector-tech { background: rgba(34,211,238,.15); color: var(--cyan); }
362
+ .sector-energy { background: rgba(245,158,11,.15); color: var(--amber); }
363
+ .sector-health { background: rgba(16,185,129,.15); color: var(--emerald); }
364
+ .sector-finance { background: rgba(139,92,246,.15); color: var(--violet); }
365
+ .sector-consumer { background: rgba(244,63,94,.12); color: var(--rose); }
366
+ .sector-industrial { background: rgba(148,163,184,.12); color: var(--text2); }
367
+ .sector-etf { background: rgba(34,211,238,.12); color: var(--cyan); }
368
+
369
+ /* ── Change Colors ── */
370
+ .up { color: var(--emerald); font-weight: 600; }
371
+ .down { color: var(--rose); font-weight: 600; }
372
+ .neutral { color: var(--text2); }
373
+
374
+ /* ── Stars ── */
375
+ .stars { color: var(--amber); letter-spacing: 1px; font-size: .85rem; }
376
+
377
+ /* ── Progress Bar ── */
378
+ .progress-bar {
379
+ background: var(--bg3);
380
+ border-radius: 4px;
381
+ height: 6px;
382
+ width: 80px;
383
+ overflow: hidden;
384
+ }
385
+ .progress-fill { height: 100%; border-radius: 4px; transition: width .3s; }
386
+ .fill-cyan { background: var(--cyan); }
387
+ .fill-emerald { background: var(--emerald); }
388
+ .fill-amber { background: var(--amber); }
389
+ .fill-rose { background: var(--rose); }
390
+
391
+ /* ── Mini Sparkline ── */
392
+ .sparkline-wrap { width: 80px; height: 32px; display: inline-block; }
393
+ .sparkline-wrap canvas { width: 80px !important; height: 32px !important; }
394
+
395
+ /* ── Ticker Cell ── */
396
+ .ticker-cell { display: flex; align-items: flex-start; gap: .5rem; flex-direction: column; }
397
+ .ticker-sym { font-size: .9rem; font-weight: 800; font-family: 'Courier New', monospace; color: var(--text); }
398
+ .ticker-name { font-size: .72rem; color: var(--text2); max-width: 140px; white-space: normal; line-height: 1.3; }
399
+
400
+ /* ── Intrinsic bar ── */
401
+ .int-bar {
402
+ display: flex;
403
+ width: 80px;
404
+ height: 8px;
405
+ border-radius: 4px;
406
+ overflow: hidden;
407
+ }
408
+ .int-intrinsic { background: var(--emerald); }
409
+ .int-time { background: var(--violet); }
410
+ .int-label { font-size: .65rem; color: var(--text2); margin-top: 2px; }
411
+
412
+ /* ── DTE warning ── */
413
+ .dte-warn { color: var(--rose); font-weight: 700; }
414
+ .dte-ok { color: var(--emerald); font-weight: 600; }
415
+
416
+ /* ── Empty State ── */
417
+ .empty-state {
418
+ text-align: center;
419
+ padding: 3rem 1rem;
420
+ color: var(--text2);
421
+ }
422
+ .empty-state .icon { font-size: 2.5rem; margin-bottom: .75rem; }
423
+ .empty-state p { font-size: .9rem; }
424
+
425
+ /* ── Section card ── */
426
+ .section-card {
427
+ background: var(--card);
428
+ border: 1px solid var(--border);
429
+ border-radius: 12px;
430
+ padding: 1.25rem;
431
+ margin-bottom: 1.25rem;
432
+ }
433
+
434
+ /* ── Mobile ── */
435
+ .bottom-nav {
436
+ display: none;
437
+ position: fixed;
438
+ bottom: 0; left: 0; right: 0;
439
+ background: var(--bg3);
440
+ border-top: 1px solid var(--border);
441
+ z-index: 200;
442
+ padding: .4rem 0;
443
+ }
444
+ .bottom-nav-inner {
445
+ display: flex;
446
+ justify-content: space-around;
447
+ align-items: center;
448
+ }
449
+ .bottom-nav-item {
450
+ display: flex;
451
+ flex-direction: column;
452
+ align-items: center;
453
+ gap: 2px;
454
+ color: var(--text2);
455
+ text-decoration: none;
456
+ font-size: .65rem;
457
+ font-weight: 600;
458
+ padding: .3rem .5rem;
459
+ border-radius: 8px;
460
+ }
461
+ .bottom-nav-item .bn-icon { font-size: 1.1rem; }
462
+ .bottom-nav-item.active { color: var(--cyan); }
463
+
464
+ @media (max-width: 768px) {
465
+ .sidebar { display: none; }
466
+ .main-content { margin-left: 0; padding: 1rem; padding-bottom: 5rem; }
467
+ .bottom-nav { display: block; }
468
+ .filter-body { grid-template-columns: 1fr 1fr; }
469
+ .sparkline-wrap { display: none; }
470
+ .page-title { font-size: 1.3rem; }
471
+ .stat-grid { grid-template-columns: 1fr 1fr; }
472
+ }
473
+ @media (max-width: 480px) {
474
+ .filter-body { grid-template-columns: 1fr; }
475
+ .stat-grid { grid-template-columns: 1fr; }
476
+ .tab-bar { width: 100%; overflow-x: auto; }
477
+ }
478
+
479
+ /* ── Spin animation for refresh ── */
480
+ @keyframes spin { to { transform: rotate(360deg); } }
481
+ .spinning { animation: spin .6s linear; }
482
+
483
+ /* ── Tooltip ── */
484
+ [data-tip] { position: relative; cursor: help; }
485
+ [data-tip]:hover::after {
486
+ content: attr(data-tip);
487
+ position: absolute;
488
+ bottom: 120%;
489
+ left: 50%;
490
+ transform: translateX(-50%);
491
+ background: #000;
492
+ color: #fff;
493
+ font-size: .72rem;
494
+ padding: .3rem .6rem;
495
+ border-radius: 6px;
496
+ white-space: nowrap;
497
+ z-index: 999;
498
+ pointer-events: none;
499
+ }
500
+
501
+ /* Tab panel visibility */
502
+ .tab-panel { display: none; }
503
+ .tab-panel.active { display: block; }
504
+
505
+ /* Sub-panel visibility */
506
+ .sub-panel { display: none; }
507
+ .sub-panel.active { display: block; }
508
+
509
+ /* Premium color threshold */
510
+ .prem-good { color: var(--emerald); font-weight: 700; }
511
+ .prem-bad { color: var(--rose); font-weight: 600; }
512
+
513
+ /* Delta color */
514
+ .delta-good { color: var(--emerald); font-weight: 700; }
515
+ .delta-warn { color: var(--amber); font-weight: 600; }
516
+
517
+ /* Leap expiry warning */
518
+ .exp-warn::after { content: ' ⚠️'; }
519
+
520
+ /* Risk badge */
521
+ .risk-high { background: rgba(244,63,94,.15); color: var(--rose); }
522
+ .risk-vhigh { background: rgba(244,63,94,.25); color: #ff2048; }
523
+ </style>
524
+ </head>
525
+ <body>
526
+
527
+ <!-- ════════════════ SIDEBAR ════════════════ -->
528
+ <nav class="sidebar">
529
+ <div class="sidebar-logo">Fin<span>Wise</span></div>
530
+
531
+ <div class="nav-label">Main</div>
532
+ <a href="index.html" class="nav-item"><span class="nav-icon">📊</span> Dashboard</a>
533
+ <a href="portfolio.html" class="nav-item"><span class="nav-icon">💼</span> Portfolio Builder</a>
534
+ <a href="tracker.html" class="nav-item"><span class="nav-icon">📈</span> Investment Tracker</a>
535
+ <a href="risk.html" class="nav-item"><span class="nav-icon">🛡️</span> Risk Analyzer</a>
536
+
537
+ <div class="nav-label">Tools</div>
538
+ <a href="calculators.html" class="nav-item"><span class="nav-icon">🧮</span> Calculators</a>
539
+ <a href="insights.html" class="nav-item"><span class="nav-icon">💡</span> Insights & Tips</a>
540
+ <a href="picks.html" class="nav-item active"><span class="nav-icon">🏹</span> Stock & Option Picks <span class="nav-badge new">New</span></a>
541
+ </nav>
542
+
543
+ <!-- ════════════════ MAIN CONTENT ════════════════ -->
544
+ <main class="main-content">
545
+
546
+ <!-- Page Header -->
547
+ <div class="page-header">
548
+ <div>
549
+ <div class="page-title">Stock &amp; <span>Option Picks</span></div>
550
+ <div class="page-subtitle">Curated momentum plays, option setups, and leveraged ETF trades — updated in real-time</div>
551
+ </div>
552
+ <div class="header-actions">
553
+ <div class="search-box">
554
+ <span>🔍</span>
555
+ <input type="text" id="globalSearch" placeholder="Search ticker…" />
556
+ </div>
557
+ <button class="btn btn-primary" id="refreshBtn" onclick="refreshAllData()">
558
+ <span id="refreshIcon">🔄</span> Refresh Picks
559
+ </button>
560
+ </div>
561
+ </div>
562
+
563
+ <!-- Stat Strip -->
564
+ <div class="stat-grid" id="statStrip">
565
+ <div class="stat-card">
566
+ <div class="stat-label">Total Picks</div>
567
+ <div class="stat-value stat-cyan" id="statTotal">—</div>
568
+ <div class="stat-sub">across all tabs</div>
569
+ </div>
570
+ <div class="stat-card">
571
+ <div class="stat-label">Avg Premium %</div>
572
+ <div class="stat-value stat-emerald" id="statPrem">—</div>
573
+ <div class="stat-sub">option selling tab</div>
574
+ </div>
575
+ <div class="stat-card">
576
+ <div class="stat-label">Avg LEAP Delta</div>
577
+ <div class="stat-value stat-violet" id="statDelta">—</div>
578
+ <div class="stat-sub">LEAP calls sub-tab</div>
579
+ </div>
580
+ <div class="stat-card">
581
+ <div class="stat-label">Above Threshold</div>
582
+ <div class="stat-value stat-amber" id="statThresh">—</div>
583
+ <div class="stat-sub">prem ≥ 0.7% or delta 60–80</div>
584
+ </div>
585
+ </div>
586
+
587
+ <!-- Main Tab Bar -->
588
+ <div class="tab-bar">
589
+ <button class="tab-btn active" onclick="switchTab('stocks', this)">📈 Stock Picks</button>
590
+ <button class="tab-btn" onclick="switchTab('options', this)">📋 Option Picks</button>
591
+ <button class="tab-btn" onclick="switchTab('etfs', this)">⚡ 3× ETF Picks</button>
592
+ </div>
593
+
594
+ <!-- ══════════════ TAB 1: STOCK PICKS ══════════════ -->
595
+ <div class="tab-panel active" id="tab-stocks">
596
+
597
+ <!-- Filters -->
598
+ <div class="filter-panel">
599
+ <div class="filter-header" onclick="toggleFilter(this)">
600
+ <div class="filter-title">⚙️ Filters &amp; Sort</div>
601
+ <span class="filter-toggle-icon open">▼</span>
602
+ </div>
603
+ <div class="filter-body" id="stockFilters">
604
+ <div class="filter-group">
605
+ <label>Price Range</label>
606
+ <input type="range" min="0" max="1000" value="1000" id="sPriceMax"
607
+ oninput="document.getElementById('sPriceVal').textContent='$0–$'+this.value; renderStocks()">
608
+ <div class="range-val" id="sPriceVal">$0–$1000</div>
609
+ </div>
610
+ <div class="filter-group">
611
+ <label>Strategy</label>
612
+ <div class="filter-checkboxes">
613
+ <label><input type="checkbox" checked value="Momentum" class="s-strategy" onchange="renderStocks()"> Momentum</label>
614
+ <label><input type="checkbox" checked value="Sector Rotation" class="s-strategy" onchange="renderStocks()"> Sector Rotation</label>
615
+ <label><input type="checkbox" checked value="Hot News/Rumor" class="s-strategy" onchange="renderStocks()"> Hot News/Rumor</label>
616
+ </div>
617
+ </div>
618
+ <div class="filter-group">
619
+ <label>Sector</label>
620
+ <select id="sSector" onchange="renderStocks()">
621
+ <option value="">All Sectors</option>
622
+ <option value="Technology">Technology</option>
623
+ <option value="Energy">Energy</option>
624
+ <option value="Healthcare">Healthcare</option>
625
+ <option value="Finance">Finance</option>
626
+ <option value="Consumer">Consumer</option>
627
+ <option value="Industrial">Industrial</option>
628
+ </select>
629
+ </div>
630
+ <div class="filter-group">
631
+ <label>Min Conviction (Stars)</label>
632
+ <input type="range" min="1" max="5" value="1" id="sConvMin"
633
+ oninput="document.getElementById('sConvVal').textContent=this.value+'★'; renderStocks()">
634
+ <div class="range-val" id="sConvVal">1★</div>
635
+ </div>
636
+ <div class="filter-group">
637
+ <label>Signal Strength</label>
638
+ <select id="sSignal" onchange="renderStocks()">
639
+ <option value="">All</option>
640
+ <option value="Strong">Strong</option>
641
+ <option value="Moderate">Moderate</option>
642
+ <option value="Watch">Watch</option>
643
+ </select>
644
+ </div>
645
+ </div>
646
+ </div>
647
+
648
+ <!-- Table -->
649
+ <div class="table-wrap">
650
+ <div class="table-scroll">
651
+ <table id="stockTable">
652
+ <thead>
653
+ <tr>
654
+ <th onclick="sortTable('stocks','ticker')">Ticker <span class="sort-icon">⇅</span></th>
655
+ <th onclick="sortTable('stocks','price')">Price <span class="sort-icon">⇅</span></th>
656
+ <th onclick="sortTable('stocks','chg1d')">1D % <span class="sort-icon">⇅</span></th>
657
+ <th onclick="sortTable('stocks','chg1w')">1W % <span class="sort-icon">⇅</span></th>
658
+ <th onclick="sortTable('stocks','chg1m')">1M % <span class="sort-icon">⇅</span></th>
659
+ <th>Strategy</th>
660
+ <th>Hold Window</th>
661
+ <th>Trend</th>
662
+ <th onclick="sortTable('stocks','conviction')">Conviction <span class="sort-icon">⇅</span></th>
663
+ <th onclick="sortTable('stocks','signal')">Signal <span class="sort-icon">⇅</span></th>
664
+ </tr>
665
+ </thead>
666
+ <tbody id="stockBody"></tbody>
667
+ </table>
668
+ </div>
669
+ </div>
670
+ </div><!-- /tab-stocks -->
671
+
672
+ <!-- ══════════════ TAB 2: OPTION PICKS ══════════════ -->
673
+ <div class="tab-panel" id="tab-options">
674
+
675
+ <div class="pill-toggle">
676
+ <button class="pill-btn active" onclick="switchPill('optSell', this)">Option Selling</button>
677
+ <button class="pill-btn" onclick="switchPill('leaps', this)">LEAP Calls</button>
678
+ </div>
679
+
680
+ <!-- Option Selling -->
681
+ <div class="sub-panel active" id="sub-optSell">
682
+ <div class="filter-panel">
683
+ <div class="filter-header" onclick="toggleFilter(this)">
684
+ <div class="filter-title">⚙️ Option Selling Filters</div>
685
+ <span class="filter-toggle-icon open">▼</span>
686
+ </div>
687
+ <div class="filter-body" id="sellFilters">
688
+ <div class="filter-group">
689
+ <label>Max DTE</label>
690
+ <input type="range" min="0" max="20" value="20" id="osDTE"
691
+ oninput="document.getElementById('osDTEVal').textContent=this.value+'d'; renderOptSell()">
692
+ <div class="range-val" id="osDTEVal">20d</div>
693
+ </div>
694
+ <div class="filter-group">
695
+ <label>Min Premium %</label>
696
+ <input type="range" min="0" max="3" step="0.1" value="0.7" id="osPremMin"
697
+ oninput="document.getElementById('osPremVal').textContent=this.value+'%'; renderOptSell()">
698
+ <div class="range-val" id="osPremVal">0.7%</div>
699
+ </div>
700
+ <div class="filter-group">
701
+ <label>Min IV Rank</label>
702
+ <input type="range" min="0" max="100" value="0" id="osIVR"
703
+ oninput="document.getElementById('osIVRVal').textContent=this.value+'%'; renderOptSell()">
704
+ <div class="range-val" id="osIVRVal">0%</div>
705
+ </div>
706
+ <div class="filter-group">
707
+ <label>Strategy Type</label>
708
+ <div class="filter-checkboxes">
709
+ <label><input type="checkbox" checked value="CSP" class="os-strat" onchange="renderOptSell()"> Cash-Secured Put</label>
710
+ <label><input type="checkbox" checked value="Covered Call" class="os-strat" onchange="renderOptSell()"> Covered Call</label>
711
+ <label><input type="checkbox" checked value="Strangle" class="os-strat" onchange="renderOptSell()"> Strangle</label>
712
+ <label><input type="checkbox" checked value="Iron Condor" class="os-strat" onchange="renderOptSell()"> Iron Condor</label>
713
+ </div>
714
+ </div>
715
+ <div class="filter-group">
716
+ <label>Max Stock Price</label>
717
+ <input type="range" min="0" max="1000" value="1000" id="osPrice"
718
+ oninput="document.getElementById('osPriceVal').textContent='$'+this.value; renderOptSell()">
719
+ <div class="range-val" id="osPriceVal">$1000</div>
720
+ </div>
721
+ </div>
722
+ </div>
723
+
724
+ <div class="table-wrap">
725
+ <div class="table-scroll">
726
+ <table id="sellTable">
727
+ <thead>
728
+ <tr>
729
+ <th onclick="sortTable('optSell','ticker')">Ticker <span class="sort-icon">⇅</span></th>
730
+ <th>Strategy</th>
731
+ <th>Strike</th>
732
+ <th>Expiry</th>
733
+ <th onclick="sortTable('optSell','dte')">DTE <span class="sort-icon">⇅</span></th>
734
+ <th onclick="sortTable('optSell','premium')">Premium $ <span class="sort-icon">⇅</span></th>
735
+ <th onclick="sortTable('optSell','premPct')">Prem % <span class="sort-icon">⇅</span></th>
736
+ <th onclick="sortTable('optSell','ivr')">IV Rank <span class="sort-icon">⇅</span></th>
737
+ <th>Max Risk</th>
738
+ <th>P/L</th>
739
+ </tr>
740
+ </thead>
741
+ <tbody id="sellBody"></tbody>
742
+ </table>
743
+ </div>
744
+ </div>
745
+ </div><!-- /sub-optSell -->
746
+
747
+ <!-- LEAP Calls -->
748
+ <div class="sub-panel" id="sub-leaps">
749
+ <div class="filter-panel">
750
+ <div class="filter-header" onclick="toggleFilter(this)">
751
+ <div class="filter-title">⚙️ LEAP Call Filters</div>
752
+ <span class="filter-toggle-icon open">▼</span>
753
+ </div>
754
+ <div class="filter-body" id="leapFilters">
755
+ <div class="filter-group">
756
+ <label>Delta Range (min)</label>
757
+ <input type="range" min="40" max="100" value="60" id="lDeltaMin"
758
+ oninput="document.getElementById('lDeltaMinVal').textContent=this.value; renderLeaps()">
759
+ <div class="range-val" id="lDeltaMinVal">60</div>
760
+ </div>
761
+ <div class="filter-group">
762
+ <label>Delta Range (max)</label>
763
+ <input type="range" min="40" max="100" value="80" id="lDeltaMax"
764
+ oninput="document.getElementById('lDeltaMaxVal').textContent=this.value; renderLeaps()">
765
+ <div class="range-val" id="lDeltaMaxVal">80</div>
766
+ </div>
767
+ <div class="filter-group">
768
+ <label>Min DTE (days)</label>
769
+ <input type="range" min="100" max="900" value="300" id="lDTEMin"
770
+ oninput="document.getElementById('lDTEMinVal').textContent=this.value+'d (~'+Math.round(this.value/30)+'mo)'; renderLeaps()">
771
+ <div class="range-val" id="lDTEMinVal">300d (~10mo)</div>
772
+ </div>
773
+ <div class="filter-group">
774
+ <label>Max Underlying Price</label>
775
+ <input type="range" min="0" max="1000" value="1000" id="lPrice"
776
+ oninput="document.getElementById('lPriceVal').textContent='$'+this.value; renderLeaps()">
777
+ <div class="range-val" id="lPriceVal">$1000</div>
778
+ </div>
779
+ <div class="filter-group">
780
+ <label>Sector</label>
781
+ <select id="lSector" onchange="renderLeaps()">
782
+ <option value="">All Sectors</option>
783
+ <option value="Technology">Technology</option>
784
+ <option value="Energy">Energy</option>
785
+ <option value="Healthcare">Healthcare</option>
786
+ <option value="Finance">Finance</option>
787
+ <option value="Consumer">Consumer</option>
788
+ </select>
789
+ </div>
790
+ </div>
791
+ </div>
792
+
793
+ <div class="table-wrap">
794
+ <div class="table-scroll">
795
+ <table id="leapTable">
796
+ <thead>
797
+ <tr>
798
+ <th onclick="sortTable('leaps','ticker')">Ticker <span class="sort-icon">⇅</span></th>
799
+ <th>Strike</th>
800
+ <th>Expiry</th>
801
+ <th onclick="sortTable('leaps','dte')">DTE <span class="sort-icon">⇅</span></th>
802
+ <th onclick="sortTable('leaps','delta')">Delta <span class="sort-icon">⇅</span></th>
803
+ <th onclick="sortTable('leaps','cost')">Cost/Contract <span class="sort-icon">⇅</span></th>
804
+ <th>Underlying $</th>
805
+ <th>Intrinsic vs Time</th>
806
+ <th onclick="sortTable('leaps','conviction')">Conviction <span class="sort-icon">⇅</span></th>
807
+ </tr>
808
+ </thead>
809
+ <tbody id="leapBody"></tbody>
810
+ </table>
811
+ </div>
812
+ </div>
813
+ </div><!-- /sub-leaps -->
814
+
815
+ </div><!-- /tab-options -->
816
+
817
+ <!-- ══════════════ TAB 3: 3× ETF PICKS ══════════════ -->
818
+ <div class="tab-panel" id="tab-etfs">
819
+
820
+ <div class="pill-toggle">
821
+ <button class="pill-btn active" onclick="switchPill('etfHold', this)">ETF Holds</button>
822
+ <button class="pill-btn" onclick="switchPill('etfOpts', this)">ETF Options</button>
823
+ </div>
824
+
825
+ <!-- ETF Holds -->
826
+ <div class="sub-panel active" id="sub-etfHold">
827
+ <div class="filter-panel">
828
+ <div class="filter-header" onclick="toggleFilter(this)">
829
+ <div class="filter-title">⚙️ ETF Filters</div>
830
+ <span class="filter-toggle-icon open">▼</span>
831
+ </div>
832
+ <div class="filter-body" id="etfFilters">
833
+ <div class="filter-group">
834
+ <label>Max ETF Price</label>
835
+ <input type="range" min="0" max="500" value="500" id="efPrice"
836
+ oninput="document.getElementById('efPriceVal').textContent='$'+this.value; renderETFHolds()">
837
+ <div class="range-val" id="efPriceVal">$500</div>
838
+ </div>
839
+ <div class="filter-group">
840
+ <label>Underlying Sector</label>
841
+ <div class="filter-checkboxes">
842
+ <label><input type="checkbox" checked value="Tech" class="ef-sector" onchange="renderETFHolds()"> Technology</label>
843
+ <label><input type="checkbox" checked value="Semi" class="ef-sector" onchange="renderETFHolds()"> Semiconductors</label>
844
+ <label><input type="checkbox" checked value="Broad" class="ef-sector" onchange="renderETFHolds()"> Broad Market</label>
845
+ <label><input type="checkbox" checked value="Finance" class="ef-sector" onchange="renderETFHolds()"> Finance</label>
846
+ <label><input type="checkbox" checked value="Bio" class="ef-sector" onchange="renderETFHolds()"> Biotech</label>
847
+ <label><input type="checkbox" checked value="Defense" class="ef-sector" onchange="renderETFHolds()"> Defense</label>
848
+ </div>
849
+ </div>
850
+ <div class="filter-group">
851
+ <label>Momentum Direction</label>
852
+ <select id="efMomentum" onchange="renderETFHolds()">
853
+ <option value="">All</option>
854
+ <option value="Bullish">Bullish</option>
855
+ <option value="Bearish">Bearish</option>
856
+ </select>
857
+ </div>
858
+ <div class="filter-group">
859
+ <label>Risk Level</label>
860
+ <select id="efRisk" onchange="renderETFHolds()">
861
+ <option value="">All</option>
862
+ <option value="High">High</option>
863
+ <option value="Very High">Very High</option>
864
+ </select>
865
+ </div>
866
+ </div>
867
+ </div>
868
+
869
+ <div class="table-wrap">
870
+ <div class="table-scroll">
871
+ <table id="etfHoldTable">
872
+ <thead>
873
+ <tr>
874
+ <th onclick="sortTable('etfHold','ticker')">Ticker <span class="sort-icon">⇅</span></th>
875
+ <th>Index</th>
876
+ <th onclick="sortTable('etfHold','price')">Price <span class="sort-icon">⇅</span></th>
877
+ <th onclick="sortTable('etfHold','chg1d')">1D% <span class="sort-icon">⇅</span></th>
878
+ <th onclick="sortTable('etfHold','chg1w')">1W% <span class="sort-icon">⇅</span></th>
879
+ <th onclick="sortTable('etfHold','chg1m')">1M% <span class="sort-icon">⇅</span></th>
880
+ <th>Avg Volume</th>
881
+ <th>Momentum</th>
882
+ <th>Strategy</th>
883
+ <th>Risk</th>
884
+ <th onclick="sortTable('etfHold','conviction')">Conviction <span class="sort-icon">⇅</span></th>
885
+ </tr>
886
+ </thead>
887
+ <tbody id="etfHoldBody"></tbody>
888
+ </table>
889
+ </div>
890
+ </div>
891
+ </div><!-- /sub-etfHold -->
892
+
893
+ <!-- ETF Options -->
894
+ <div class="sub-panel" id="sub-etfOpts">
895
+ <div class="section-card" style="border-left:3px solid var(--amber); padding:.75rem 1rem; margin-bottom:1rem;">
896
+ <span style="color:var(--amber); font-weight:700;">ℹ️ ETF Options</span>
897
+ <span style="color:var(--text2); font-size:.82rem;"> — Premium ≥ 0.7% threshold highlighted. DTE filtered 0–20 days.</span>
898
+ </div>
899
+ <div class="table-wrap">
900
+ <div class="table-scroll">
901
+ <table id="etfOptTable">
902
+ <thead>
903
+ <tr>
904
+ <th onclick="sortTable('etfOpts','ticker')">ETF <span class="sort-icon">⇅</span></th>
905
+ <th>Strategy</th>
906
+ <th>Strike</th>
907
+ <th>Expiry</th>
908
+ <th onclick="sortTable('etfOpts','dte')">DTE <span class="sort-icon">⇅</span></th>
909
+ <th onclick="sortTable('etfOpts','premium')">Premium $ <span class="sort-icon">⇅</span></th>
910
+ <th onclick="sortTable('etfOpts','premPct')">Prem % <span class="sort-icon">⇅</span></th>
911
+ <th onclick="sortTable('etfOpts','ivr')">IV Rank <span class="sort-icon">⇅</span></th>
912
+ <th>Max Risk</th>
913
+ <th>P/L</th>
914
+ </tr>
915
+ </thead>
916
+ <tbody id="etfOptBody"></tbody>
917
+ </table>
918
+ </div>
919
+ </div>
920
+ </div><!-- /sub-etfOpts -->
921
+
922
+ </div><!-- /tab-etfs -->
923
+
924
+ </main><!-- /main-content -->
925
+
926
+ <!-- ════════════════ BOTTOM NAV (mobile) ════════════════ -->
927
+ <nav class="bottom-nav">
928
+ <div class="bottom-nav-inner">
929
+ <a href="index.html" class="bottom-nav-item"><span class="bn-icon">📊</span>Dashboard</a>
930
+ <a href="portfolio.html" class="bottom-nav-item"><span class="bn-icon">💼</span>Portfolio</a>
931
+ <a href="risk.html" class="bottom-nav-item"><span class="bn-icon">🛡️</span>Risk</a>
932
+ <a href="calculators.html" class="bottom-nav-item"><span class="bn-icon">🧮</span>Calc</a>
933
+ <a href="picks.html" class="bottom-nav-item active"><span class="bn-icon">🏹</span>Picks</a>
934
+ </div>
935
+ </nav>
936
+
937
+ <!-- ════════════════ SCRIPT ════════════════ -->
938
+ <script>
939
+ /* ─────────────────────────────────────────────
940
+ SEED DATA
941
+ ───────────────────────────────────────────── */
942
+ const BASE = {
943
+ stocks: [
944
+ { ticker:'NVDA', name:'NVIDIA Corp', sector:'Technology', price:875.24, chg1d:2.4, chg1w:7.8, chg1m:22.1, strategy:'Momentum', window:'4–8 months', conviction:5, signal:'Strong', trend:[820,830,848,842,860,870,875] },
945
+ { ticker:'AMZN', name:'Amazon.com Inc', sector:'Consumer', price:192.45, chg1d:0.8, chg1w:3.2, chg1m:11.4, strategy:'Momentum', window:'3–6 months', conviction:4, signal:'Strong', trend:[178,180,184,182,188,190,192] },
946
+ { ticker:'AAPL', name:'Apple Inc', sector:'Technology', price:211.30, chg1d:0.4, chg1w:1.9, chg1m:6.2, strategy:'Sector Rotation', window:'4–8 months', conviction:4, signal:'Moderate', trend:[198,202,205,204,208,210,211] },
947
+ { ticker:'META', name:'Meta Platforms', sector:'Technology', price:504.10, chg1d:3.1, chg1w:9.4, chg1m:28.7, strategy:'Momentum', window:'4–8 months', conviction:5, signal:'Strong', trend:[430,445,460,472,488,497,504] },
948
+ { ticker:'TSLA', name:'Tesla Inc', sector:'Consumer', price:248.80, chg1d:-1.3, chg1w:-4.2, chg1m:5.6, strategy:'Hot News/Rumor', window:'2–4 months', conviction:3, signal:'Moderate', trend:[245,258,265,260,252,251,248] },
949
+ { ticker:'MSFT', name:'Microsoft Corp', sector:'Technology', price:420.55, chg1d:0.6, chg1w:2.3, chg1m:8.8, strategy:'Sector Rotation', window:'6–12 months', conviction:5, signal:'Strong', trend:[390,398,405,408,414,418,420] },
950
+ { ticker:'GOOGL', name:'Alphabet Inc', sector:'Technology', price:176.80, chg1d:1.2, chg1w:4.1, chg1m:14.3, strategy:'Momentum', window:'4–8 months', conviction:4, signal:'Strong', trend:[158,162,167,169,172,175,176] },
951
+ { ticker:'WMT', name:'Walmart Inc', sector:'Consumer', price:68.40, chg1d:0.3, chg1w:1.1, chg1m:4.5, strategy:'Sector Rotation', window:'6–12 months', conviction:3, signal:'Moderate', trend:[64,65,66,66,67,68,68] },
952
+ { ticker:'JPM', name:'JPMorgan Chase', sector:'Finance', price:212.70, chg1d:-0.5, chg1w:-1.8, chg1m:3.2, strategy:'Sector Rotation', window:'3–6 months', conviction:3, signal:'Watch', trend:[205,207,210,212,211,213,212] },
953
+ { ticker:'XOM', name:'Exxon Mobil', sector:'Energy', price:118.25, chg1d:1.8, chg1w:5.2, chg1m:9.4, strategy:'Hot News/Rumor', window:'2–4 months', conviction:4, signal:'Strong', trend:[107,109,112,114,116,117,118] },
954
+ { ticker:'AMD', name:'Advanced Micro Devices', sector:'Technology', price:168.40, chg1d:2.2, chg1w:8.1, chg1m:18.5, strategy:'Momentum', window:'4–8 months', conviction:5, signal:'Strong', trend:[138,145,152,158,163,166,168] },
955
+ { ticker:'MCD', name:"McDonald's Corp", sector:'Consumer', price:291.60, chg1d:0.2, chg1w:0.9, chg1m:3.1, strategy:'Sector Rotation', window:'6–12 months', conviction:3, signal:'Watch', trend:[284,285,287,288,290,291,291] },
956
+ { ticker:'LLY', name:'Eli Lilly', sector:'Healthcare', price:768.90, chg1d:1.4, chg1w:4.8, chg1m:16.2, strategy:'Hot News/Rumor', window:'3–6 months', conviction:5, signal:'Strong', trend:[680,695,710,724,738,755,768] },
957
+ { ticker:'GE', name:'GE Aerospace', sector:'Industrial', price:164.30, chg1d:1.6, chg1w:5.1, chg1m:12.8, strategy:'Momentum', window:'4–8 months', conviction:4, signal:'Strong', trend:[142,148,154,157,160,162,164] },
958
+ { ticker:'SMCI', name:'Super Micro Computer', sector:'Technology', price:742.60, chg1d:4.1, chg1w:12.3, chg1m:35.8, strategy:'Hot News/Rumor', window:'2–4 months', conviction:4, signal:'Strong', trend:[550,590,625,660,695,720,742] },
959
+ { ticker:'VST', name:'Vistra Corp', sector:'Energy', price:94.20, chg1d:2.9, chg1w:8.7, chg1m:24.1, strategy:'Momentum', window:'3–6 months', conviction:4, signal:'Strong', trend:[72,76,80,84,88,91,94] },
960
+ { ticker:'AXON', name:'Axon Enterprise', sector:'Industrial', price:310.50, chg1d:1.1, chg1w:3.7, chg1m:10.2, strategy:'Momentum', window:'4–8 months', conviction:3, signal:'Moderate', trend:[280,285,292,298,304,308,310] },
961
+ { ticker:'RKLB', name:'Rocket Lab USA', sector:'Industrial', price:7.84, chg1d:3.7, chg1w:11.2, chg1m:28.9, strategy:'Hot News/Rumor', window:'2–4 months', conviction:3, signal:'Moderate', trend:[5.8,6.1,6.5,6.9,7.2,7.6,7.8] },
962
+ ],
963
+
964
+ optSell: [
965
+ { ticker:'NVDA', name:'NVIDIA', sector:'Technology', strategy:'CSP', strike:'$840 PUT', expiry:'May 17', dte:7, premium:7.20, premPct:0.86, ivr:68, maxRisk:84000, underlyingPrice:875 },
966
+ { ticker:'AMZN', name:'Amazon', sector:'Consumer', strategy:'Covered Call', strike:'$195 CALL', expiry:'May 17', dte:7, premium:1.90, premPct:0.99, ivr:44, maxRisk:19200, underlyingPrice:192 },
967
+ { ticker:'META', name:'Meta', sector:'Technology', strategy:'Strangle', strike:'$490/520', expiry:'May 24', dte:14, premium:6.80, premPct:1.38, ivr:72, maxRisk:49000, underlyingPrice:504 },
968
+ { ticker:'TSLA', name:'Tesla', sector:'Consumer', strategy:'Iron Condor', strike:'$235/$245/$255/$265', expiry:'May 10', dte:0, premium:2.10, premPct:0.85, ivr:88, maxRisk:8000, underlyingPrice:248 },
969
+ { ticker:'SPY', name:'S&P 500 ETF', sector:'Broad', strategy:'CSP', strike:'$515 PUT', expiry:'May 17', dte:7, premium:2.80, premPct:0.54, ivr:18, maxRisk:51500, underlyingPrice:522 },
970
+ { ticker:'QQQ', name:'Invesco QQQ', sector:'Tech', strategy:'Covered Call', strike:'$445 CALL', expiry:'May 17', dte:7, premium:3.10, premPct:0.71, ivr:24, maxRisk:44000, underlyingPrice:439 },
971
+ { ticker:'AAPL', name:'Apple', sector:'Technology', strategy:'CSP', strike:'$205 PUT', expiry:'May 24', dte:14, premium:1.60, premPct:0.78, ivr:32, maxRisk:20500, underlyingPrice:211 },
972
+ { ticker:'AMD', name:'AMD', sector:'Technology', strategy:'Strangle', strike:'$160/$175', expiry:'May 17', dte:7, premium:2.40, premPct:1.43, ivr:78, maxRisk:16000, underlyingPrice:168 },
973
+ { ticker:'XOM', name:'ExxonMobil', sector:'Energy', strategy:'Covered Call', strike:'$120 CALL', expiry:'May 31', dte:21, premium:0.92, premPct:0.78, ivr:41, maxRisk:11825, underlyingPrice:118 },
974
+ { ticker:'LLY', name:'Eli Lilly', sector:'Healthcare', strategy:'CSP', strike:'$740 PUT', expiry:'May 17', dte:7, premium:7.80, premPct:1.05, ivr:55, maxRisk:74000, underlyingPrice:768 },
975
+ { ticker:'MSFT', name:'Microsoft', sector:'Technology', strategy:'Iron Condor', strike:'$410/$415/$425/$430', expiry:'May 17', dte:7, premium:1.85, premPct:0.44, ivr:22, maxRisk:31500, underlyingPrice:420 },
976
+ { ticker:'GS', name:'Goldman Sachs', sector:'Finance', strategy:'CSP', strike:'$450 PUT', expiry:'May 24', dte:14, premium:4.20, premPct:0.93, ivr:46, maxRisk:45000, underlyingPrice:462 },
977
+ ],
978
+
979
+ leaps: [
980
+ { ticker:'NVDA', name:'NVIDIA', sector:'Technology', strike:'$700C', expiry:'Jan 2027', dte:608, delta:78, cost:22800, underlyingPrice:875, intrinsicPct:75 },
981
+ { ticker:'AAPL', name:'Apple', sector:'Technology', strike:'$190C', expiry:'Jan 2027', dte:608, delta:74, cost:3200, underlyingPrice:211, intrinsicPct:72 },
982
+ { ticker:'MSFT', name:'Microsoft', sector:'Technology', strike:'$370C', expiry:'Jan 2027', dte:608, delta:71, cost:5800, underlyingPrice:420, intrinsicPct:68 },
983
+ { ticker:'AMZN', name:'Amazon', sector:'Consumer', strike:'$170C', expiry:'Jan 2027', dte:608, delta:76, cost:2650, underlyingPrice:192, intrinsicPct:64 },
984
+ { ticker:'META', name:'Meta', sector:'Technology', strike:'$440C', expiry:'Jan 2027', dte:608, delta:68, cost:8400, underlyingPrice:504, intrinsicPct:70 },
985
+ { ticker:'LLY', name:'Eli Lilly', sector:'Healthcare', strike:'$680C', expiry:'Jan 2027', dte:608, delta:63, cost:12600, underlyingPrice:768, intrinsicPct:65 },
986
+ { ticker:'AMD', name:'AMD', sector:'Technology', strike:'$140C', expiry:'Jan 2026', dte:244, delta:72, cost:3500, underlyingPrice:168, intrinsicPct:60 },
987
+ { ticker:'JPM', name:'JPMorgan', sector:'Finance', strike:'$190C', expiry:'Jan 2027', dte:608, delta:65, cost:2900, underlyingPrice:212, intrinsicPct:58 },
988
+ { ticker:'XOM', name:'ExxonMobil', sector:'Energy', strike:'$105C', expiry:'Jan 2027', dte:608, delta:61, cost:1640, underlyingPrice:118, intrinsicPct:62 },
989
+ { ticker:'GOOGL', name:'Alphabet', sector:'Technology', strike:'$155C', expiry:'Jan 2027', dte:608, delta:70, cost:2880, underlyingPrice:176, intrinsicPct:67 },
990
+ ],
991
+
992
+ etfHolds: [
993
+ { ticker:'TQQQ', name:'ProShares UltraPro QQQ', index:'NASDAQ-100', price:68.40, chg1d:2.1, chg1w:6.4, chg1m:18.2, volume:'98.4M', momentum:'Bullish', strategy:'Momentum', risk:'Very High', conviction:5, sector:'Tech', trend:[54,57,60,62,65,67,68] },
994
+ { ticker:'SOXL', name:'Direxion Semi 3×', index:'PHLX Semiconductor', price:42.80, chg1d:3.8, chg1w:11.2, chg1m:28.4, volume:'42.1M', momentum:'Bullish', strategy:'Sector Play', risk:'Very High', conviction:5, sector:'Semi', trend:[29,32,35,37,40,41,42] },
995
+ { ticker:'UPRO', name:'ProShares UltraPro S&P500', index:'S&P 500', price:86.20, chg1d:1.4, chg1w:4.1, chg1m:12.6, volume:'12.7M', momentum:'Bullish', strategy:'Momentum', risk:'Very High', conviction:4, sector:'Broad', trend:[72,75,78,80,83,85,86] },
996
+ { ticker:'FNGU', name:'MicroSectors FANG+ 3×', index:'NYSE FANG+', price:318.50, chg1d:3.2, chg1w:9.7, chg1m:24.1, volume:'3.8M', momentum:'Bullish', strategy:'Momentum', risk:'Very High', conviction:5, sector:'Tech', trend:[240,258,272,285,298,310,318] },
997
+ { ticker:'LABU', name:'Direxion Biotech 3×', index:'S&P Biotech', price:12.40, chg1d:-1.8, chg1w:-5.2, chg1m:-8.4, volume:'18.3M', momentum:'Bearish', strategy:'Short-Term Trade', risk:'Very High', conviction:2, sector:'Bio', trend:[15,14,13.5,13,12.8,12.5,12.4] },
998
+ { ticker:'TNA', name:'Direxion Small Cap 3×', index:'Russell 2000', price:38.60, chg1d:1.2, chg1w:3.8, chg1m:9.4, volume:'8.9M', momentum:'Bullish', strategy:'Sector Play', risk:'Very High', conviction:3, sector:'Broad', trend:[32,33,35,36,37,38,38] },
999
+ { ticker:'TECL', name:'Direxion Technology 3×', index:'Russell 1000 Tech', price:74.80, chg1d:2.4, chg1w:7.1, chg1m:19.8, volume:'6.2M', momentum:'Bullish', strategy:'Momentum', risk:'Very High', conviction:5, sector:'Tech', trend:[58,62,66,68,71,73,74] },
1000
+ { ticker:'SPXL', name:'Direxion S&P500 3×', index:'S&P 500', price:148.20, chg1d:1.5, chg1w:4.3, chg1m:13.2, volume:'4.8M', momentum:'Bullish', strategy:'Momentum', risk:'Very High', conviction:4, sector:'Broad', trend:[122,127,132,136,141,146,148] },
1001
+ { ticker:'FAS', name:'Direxion Financials 3×', index:'Russell 1000 Finance', price:118.40, chg1d:-0.8, chg1w:-2.4, chg1m:4.1, volume:'3.1M', momentum:'Bearish', strategy:'Short-Term Trade', risk:'High', conviction:3, sector:'Finance', trend:[112,113,115,117,119,118,118] },
1002
+ { ticker:'NAIL', name:'Direxion Homebuilders 3×', index:'DJUSHB', price:84.60, chg1d:1.9, chg1w:5.7, chg1m:14.3, volume:'1.8M', momentum:'Bullish', strategy:'Sector Play', risk:'High', conviction:3, sector:'Industrial', trend:[70,73,76,79,81,83,84] },
1003
+ { ticker:'DFEN', name:'Direxion Defense 3×', index:'DJUSDS', price:52.80, chg1d:2.2, chg1w:6.8, chg1m:15.6, volume:'1.2M', momentum:'Bullish', strategy:'Sector Play', risk:'High', conviction:4, sector:'Defense', trend:[42,44,46,48,50,52,52] },
1004
+ { ticker:'UDOW', name:'ProShares UltraPro Dow30', index:'DJIA', price:94.30, chg1d:1.1, chg1w:3.4, chg1m:10.2, volume:'2.4M', momentum:'Bullish', strategy:'Momentum', risk:'Very High', conviction:3, sector:'Broad', trend:[80,83,86,88,91,93,94] },
1005
+ ],
1006
+
1007
+ etfOpts: [
1008
+ { ticker:'TQQQ', name:'ProShares TQQQ', sector:'Tech ETF', strategy:'CSP', strike:'$64 PUT', expiry:'May 17', dte:7, premium:0.92, premPct:1.38, ivr:62, maxRisk:6400, underlyingPrice:68 },
1009
+ { ticker:'SOXL', name:'Direxion SOXL', sector:'Semi ETF', strategy:'Covered Call', strike:'$44 CALL', expiry:'May 17', dte:7, premium:0.64, premPct:1.51, ivr:84, maxRisk:4280, underlyingPrice:42 },
1010
+ { ticker:'SPXL', name:'Direxion SPXL', sector:'Broad ETF', strategy:'CSP', strike:'$142 PUT', expiry:'May 17', dte:7, premium:1.48, premPct:1.04, ivr:38, maxRisk:14200, underlyingPrice:148 },
1011
+ { ticker:'TECL', name:'Direxion TECL', sector:'Tech ETF', strategy:'Strangle', strike:'$70/$78', expiry:'May 24', dte:14, premium:1.85, premPct:2.47, ivr:74, maxRisk:7000, underlyingPrice:74 },
1012
+ { ticker:'UDOW', name:'ProShares UDOW', sector:'Broad ETF', strategy:'Iron Condor', strike:'$90/$92/$97/$99', expiry:'May 17', dte:7, premium:0.72, premPct:0.77, ivr:42, maxRisk:9200, underlyingPrice:94 },
1013
+ { ticker:'FNGU', name:'MicroSectors FNGU', sector:'Tech ETF', strategy:'CSP', strike:'$305 PUT', expiry:'May 17', dte:7, premium:4.20, premPct:1.38, ivr:76, maxRisk:30500, underlyingPrice:318 },
1014
+ ],
1015
+ };
1016
+
1017
+ /* ─────────────────────────────────────────────
1018
+ WORKING COPY (gets mutated on refresh)
1019
+ ───────────────────────────────────────────── */
1020
+ let D = JSON.parse(JSON.stringify(BASE));
1021
+
1022
+ /* Sort state */
1023
+ const sortState = {};
1024
+
1025
+ /* ─────────────────────────────────────────────
1026
+ HELPERS
1027
+ ───────────────────────────────────────────── */
1028
+ const $ = id => document.getElementById(id);
1029
+ const sectorClass = s => ({
1030
+ Technology:'sector-tech', Energy:'sector-energy', Healthcare:'sector-health',
1031
+ Finance:'sector-finance', Consumer:'sector-consumer', Industrial:'sector-industrial',
1032
+ Broad:'sector-etf', Tech:'sector-tech', Semi:'sector-tech', Bio:'sector-health',
1033
+ Defense:'sector-industrial','Tech ETF':'sector-tech','Semi ETF':'sector-tech',
1034
+ 'Broad ETF':'sector-etf','Finance ETF':'sector-finance'
1035
+ }[s] || 'sector-industrial');
1036
+
1037
+ function stars(n) {
1038
+ return '<span class="stars">' + '★'.repeat(n) + '<span style="opacity:.2">' + '★'.repeat(5 - n) + '</span></span>';
1039
+ }
1040
+ function chgCell(v) {
1041
+ if (v > 0) return `<span class="up">▲ ${v.toFixed(2)}%</span>`;
1042
+ if (v < 0) return `<span class="down">▼ ${Math.abs(v).toFixed(2)}%</span>`;
1043
+ return `<span class="neutral">0.00%</span>`;
1044
+ }
1045
+ function signalBadge(s) {
1046
+ const m = { Strong:'badge-cyan', Moderate:'badge-amber', Watch:'badge-rose' };
1047
+ return `<span class="badge ${m[s]||'badge-gray'}">${s}</span>`;
1048
+ }
1049
+ function stratBadge(s) {
1050
+ const m = { Momentum:'badge-cyan', 'Sector Rotation':'badge-violet', 'Hot News/Rumor':'badge-amber',
1051
+ CSP:'badge-emerald','Covered Call':'badge-cyan', Strangle:'badge-amber','Iron Condor':'badge-violet' };
1052
+ return `<span class="badge ${m[s]||'badge-gray'}">${s}</span>`;
1053
+ }
1054
+ function stratBadgeETF(s) {
1055
+ const m = { Momentum:'badge-cyan','Sector Play':'badge-violet','Short-Term Trade':'badge-amber' };
1056
+ return `<span class="badge ${m[s]||'badge-gray'}">${s}</span>`;
1057
+ }
1058
+ function riskBadge(r) {
1059
+ return r==='Very High'
1060
+ ? `<span class="badge risk-vhigh">Very High ⚡</span>`
1061
+ : `<span class="badge risk-high">High ⚠️</span>`;
1062
+ }
1063
+ function sparkCanvas(id) {
1064
+ return `<div class="sparkline-wrap"><canvas id="${id}"></canvas></div>`;
1065
+ }
1066
+ function formatVol(v) {
1067
+ return v;
1068
+ }
1069
+ function premPctCell(p) {
1070
+ return p >= 0.7
1071
+ ? `<span class="prem-good">✅ ${p.toFixed(2)}%</span>`
1072
+ : `<span class="prem-bad">${p.toFixed(2)}%</span>`;
1073
+ }
1074
+ function plCell(p) {
1075
+ return p >= 0.7
1076
+ ? `<span class="badge badge-emerald">▲ On Target</span>`
1077
+ : `<span class="badge badge-rose">▼ Below Min</span>`;
1078
+ }
1079
+ function deltaCell(d) {
1080
+ if (d >= 60 && d <= 80) return `<span class="delta-good">✅ ${d}</span>`;
1081
+ return `<span class="delta-warn">⚠️ ${d}</span>`;
1082
+ }
1083
+ function dteCell(d) {
1084
+ return d > 20
1085
+ ? `<span class="dte-warn">${d}d ⚠️</span>`
1086
+ : `<span class="dte-ok">${d}d</span>`;
1087
+ }
1088
+ function leapExpCell(expiry, dte) {
1089
+ const tooClose = dte < 300;
1090
+ return tooClose ? `<span class="exp-warn">${expiry}</span>` : expiry;
1091
+ }
1092
+ function intBar(pct) {
1093
+ const ip = Math.round(pct);
1094
+ const tp = 100 - ip;
1095
+ return `
1096
+ <div class="int-bar"><div class="int-intrinsic" style="width:${ip}%"></div><div class="int-time" style="width:${tp}%"></div></div>
1097
+ <div class="int-label"><span style="color:var(--emerald)">■</span>${ip}% int &nbsp;<span style="color:var(--violet)">■</span>${tp}% time</div>`;
1098
+ }
1099
+ function momentumArrow(m) {
1100
+ return m === 'Bullish'
1101
+ ? `<span class="up">▲ Bullish</span>`
1102
+ : `<span class="down">▼ Bearish</span>`;
1103
+ }
1104
+
1105
+ /* Draw sparkline */
1106
+ function drawSparkline(canvasId, data) {
1107
+ const el = document.getElementById(canvasId);
1108
+ if (!el) return;
1109
+ const last = data[data.length - 1];
1110
+ const first = data[0];
1111
+ const color = last >= first ? '#10b981' : '#f43f5e';
1112
+ new Chart(el, {
1113
+ type: 'line',
1114
+ data: {
1115
+ labels: data.map((_,i) => i),
1116
+ datasets: [{ data, borderColor: color, borderWidth: 1.5, pointRadius: 0, tension: 0.4, fill: true,
1117
+ backgroundColor: color + '22' }]
1118
+ },
1119
+ options: {
1120
+ responsive: false, animation: false, plugins: { legend: { display: false }, tooltip: { enabled: false } },
1121
+ scales: { x: { display: false }, y: { display: false } }
1122
+ }
1123
+ });
1124
+ }
1125
+
1126
+ /* ─────────────────────────────────────────────
1127
+ GLOBAL SEARCH
1128
+ ───────────────────────────────────────────── */
1129
+ $('globalSearch').addEventListener('input', function() {
1130
+ renderStocks(); renderOptSell(); renderLeaps(); renderETFHolds(); renderETFOpts();
1131
+ });
1132
+ function globalQ() { return $('globalSearch').value.trim().toUpperCase(); }
1133
+
1134
+ /* ─────────────────────────────────────────────
1135
+ TAB SWITCHING
1136
+ ───────────────────────────────────────────── */
1137
+ function switchTab(id, btn) {
1138
+ document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('active'));
1139
+ document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
1140
+ document.getElementById('tab-' + id).classList.add('active');
1141
+ btn.classList.add('active');
1142
+ updateStats();
1143
+ }
1144
+
1145
+ function switchPill(id, btn) {
1146
+ const parent = btn.closest('.tab-panel');
1147
+ parent.querySelectorAll('.sub-panel').forEach(p => p.classList.remove('active'));
1148
+ parent.querySelectorAll('.pill-btn').forEach(b => b.classList.remove('active'));
1149
+ document.getElementById('sub-' + id).classList.add('active');
1150
+ btn.classList.add('active');
1151
+ updateStats();
1152
+ }
1153
+
1154
+ /* ─────────────────────────────────────────────
1155
+ FILTER TOGGLE
1156
+ ───────────────────────────────────────────── */
1157
+ function toggleFilter(header) {
1158
+ const body = header.nextElementSibling;
1159
+ const icon = header.querySelector('.filter-toggle-icon');
1160
+ body.classList.toggle('collapsed');
1161
+ icon.classList.toggle('open');
1162
+ }
1163
+
1164
+ /* ─────────────────────────────────────────────
1165
+ SORTING
1166
+ ───────────────────────────────────────────── */
1167
+ function sortTable(dataset, key) {
1168
+ const ds = dataset;
1169
+ if (!sortState[ds]) sortState[ds] = { key, asc: true };
1170
+ else if (sortState[ds].key === key) sortState[ds].asc = !sortState[ds].asc;
1171
+ else { sortState[ds].key = key; sortState[ds].asc = true; }
1172
+
1173
+ const asc = sortState[ds].asc;
1174
+ D[ds === 'stocks' ? 'stocks' : ds === 'optSell' ? 'optSell' : ds === 'leaps' ? 'leaps' : ds === 'etfHold' ? 'etfHolds' : 'etfOpts']
1175
+ .sort((a, b) => {
1176
+ const av = a[key], bv = b[key];
1177
+ if (typeof av === 'string') return asc ? av.localeCompare(bv) : bv.localeCompare(av);
1178
+ return asc ? av - bv : bv - av;
1179
+ });
1180
+
1181
+ const rMap = { stocks: renderStocks, optSell: renderOptSell, leaps: renderLeaps, etfHold: renderETFHolds, etfOpts: renderETFOpts };
1182
+ if (rMap[ds]) rMap[ds]();
1183
+ }
1184
+
1185
+ /* ─────────────────────────────────────────────
1186
+ RENDER: STOCKS
1187
+ ───────────────────────────────────────────── */
1188
+ function renderStocks() {
1189
+ const priceMax = parseFloat($('sPriceMax').value);
1190
+ const strategies = [...document.querySelectorAll('.s-strategy:checked')].map(e => e.value);
1191
+ const sector = $('sSector').value;
1192
+ const convMin = parseInt($('sConvMin').value);
1193
+ const signal = $('sSignal').value;
1194
+ const q = globalQ();
1195
+
1196
+ const rows = D.stocks.filter(s =>
1197
+ s.price <= priceMax &&
1198
+ strategies.includes(s.strategy) &&
1199
+ (!sector || s.sector === sector) &&
1200
+ s.conviction >= convMin &&
1201
+ (!signal || s.signal === signal) &&
1202
+ (!q || s.ticker.includes(q) || s.name.toUpperCase().includes(q))
1203
+ );
1204
+
1205
+ const tbody = $('stockBody');
1206
+ if (!rows.length) { tbody.innerHTML = `<tr><td colspan="10"><div class="empty-state"><div class="icon">🔍</div><p>No picks match your filters.</p></div></td></tr>`; return; }
1207
+
1208
+ tbody.innerHTML = rows.map((s, i) => {
1209
+ const sid = `spark-s-${i}`;
1210
+ return `<tr>
1211
+ <td>
1212
+ <div class="ticker-cell">
1213
+ <span class="ticker-sym">${s.ticker}</span>
1214
+ <span class="badge ${sectorClass(s.sector)}">${s.sector}</span>
1215
+ <span class="ticker-name">${s.name}</span>
1216
+ </div>
1217
+ </td>
1218
+ <td style="font-family:monospace;font-weight:700">$${s.price.toLocaleString('en-US',{minimumFractionDigits:2,maximumFractionDigits:2})}</td>
1219
+ <td>${chgCell(s.chg1d)}</td>
1220
+ <td>${chgCell(s.chg1w)}</td>
1221
+ <td>${chgCell(s.chg1m)}</td>
1222
+ <td>${stratBadge(s.strategy)}</td>
1223
+ <td style="color:var(--text2);font-size:.8rem">${s.window}</td>
1224
+ <td>${sparkCanvas(sid)}</td>
1225
+ <td>${stars(s.conviction)}</td>
1226
+ <td>${signalBadge(s.signal)}</td>
1227
+ </tr>`;
1228
+ }).join('');
1229
+
1230
+ // Draw sparklines after DOM update
1231
+ rows.forEach((s, i) => drawSparkline(`spark-s-${i}`, s.trend));
1232
+ updateStats();
1233
+ }
1234
+
1235
+ /* ─────────────────────────────────────────────
1236
+ RENDER: OPTION SELLING
1237
+ ───────────────────────────────────────────── */
1238
+ function renderOptSell() {
1239
+ const dteMax = parseInt($('osDTE').value);
1240
+ const premMin = parseFloat($('osPremMin').value);
1241
+ const ivrMin = parseInt($('osIVR').value);
1242
+ const strats = [...document.querySelectorAll('.os-strat:checked')].map(e => e.value);
1243
+ const priceMax = parseFloat($('osPrice').value);
1244
+ const q = globalQ();
1245
+
1246
+ const rows = D.optSell.filter(o =>
1247
+ o.dte <= dteMax &&
1248
+ o.premPct >= premMin &&
1249
+ o.ivr >= ivrMin &&
1250
+ strats.includes(o.strategy) &&
1251
+ o.underlyingPrice <= priceMax &&
1252
+ (!q || o.ticker.includes(q) || o.name.toUpperCase().includes(q))
1253
+ );
1254
+
1255
+ const tbody = $('sellBody');
1256
+ if (!rows.length) { tbody.innerHTML = `<tr><td colspan="10"><div class="empty-state"><div class="icon">🔍</div><p>No positions match your filters.</p></div></td></tr>`; return; }
1257
+
1258
+ tbody.innerHTML = rows.map(o => `<tr>
1259
+ <td>
1260
+ <div class="ticker-cell">
1261
+ <span class="ticker-sym">${o.ticker}</span>
1262
+ <span class="badge ${sectorClass(o.sector)}">${o.sector}</span>
1263
+ </div>
1264
+ </td>
1265
+ <td>${stratBadge(o.strategy)}</td>
1266
+ <td style="font-family:monospace;font-weight:700;color:var(--amber)">${o.strike}</td>
1267
+ <td style="color:var(--text2)">${o.expiry}</td>
1268
+ <td>${dteCell(o.dte)}</td>
1269
+ <td style="font-family:monospace;font-weight:700">$${o.premium.toFixed(2)}</td>
1270
+ <td>${premPctCell(o.premPct)}</td>
1271
+ <td><span class="badge badge-violet" data-tip="Implied Volatility Rank">${o.ivr}%</span></td>
1272
+ <td style="font-family:monospace;color:var(--rose)">$${o.maxRisk.toLocaleString()}</td>
1273
+ <td>${plCell(o.premPct)}</td>
1274
+ </tr>`).join('');
1275
+ updateStats();
1276
+ }
1277
+
1278
+ /* ─────────────────────────────────────────────
1279
+ RENDER: LEAPS
1280
+ ───────────────────────────────────────────── */
1281
+ function renderLeaps() {
1282
+ const dMin = parseInt($('lDeltaMin').value);
1283
+ const dMax = parseInt($('lDeltaMax').value);
1284
+ const dteMin = parseInt($('lDTEMin').value);
1285
+ const priceMax = parseFloat($('lPrice').value);
1286
+ const sector = $('lSector').value;
1287
+ const q = globalQ();
1288
+
1289
+ const rows = D.leaps.filter(l =>
1290
+ l.dte >= dteMin &&
1291
+ l.underlyingPrice <= priceMax &&
1292
+ (!sector || l.sector === sector) &&
1293
+ (!q || l.ticker.includes(q) || l.name.toUpperCase().includes(q))
1294
+ );
1295
+
1296
+ const tbody = $('leapBody');
1297
+ if (!rows.length) { tbody.innerHTML = `<tr><td colspan="9"><div class="empty-state"><div class="icon">🔍</div><p>No LEAPs match your filters.</p></div></td></tr>`; return; }
1298
+
1299
+ tbody.innerHTML = rows.map(l => `<tr>
1300
+ <td>
1301
+ <div class="ticker-cell">
1302
+ <span class="ticker-sym">${l.ticker}</span>
1303
+ <span class="badge ${sectorClass(l.sector)}">${l.sector}</span>
1304
+ <span class="ticker-name">${l.name}</span>
1305
+ </div>
1306
+ </td>
1307
+ <td style="font-family:monospace;font-weight:700;color:var(--cyan)">${l.strike}</td>
1308
+ <td>${leapExpCell(l.expiry, l.dte)}</td>
1309
+ <td>${l.dte >= 300 ? `<span class="dte-ok">${l.dte}d</span>` : `<span class="dte-warn">${l.dte}d ⚠️</span>`}</td>
1310
+ <td>${deltaCell(l.delta)}</td>
1311
+ <td style="font-family:monospace;font-weight:700">$${l.cost.toLocaleString()}</td>
1312
+ <td style="font-family:monospace">$${l.underlyingPrice.toFixed(2)}</td>
1313
+ <td>${intBar(l.intrinsicPct)}</td>
1314
+ <td>${stars(4)}</td>
1315
+ </tr>`).join('');
1316
+ updateStats();
1317
+ }
1318
+
1319
+ /* ─────────────────────────────────────────────
1320
+ RENDER: ETF HOLDS
1321
+ ───────────────────────────────────────────── */
1322
+ function renderETFHolds() {
1323
+ const priceMax = parseFloat($('efPrice').value);
1324
+ const sectors = [...document.querySelectorAll('.ef-sector:checked')].map(e => e.value);
1325
+ const momentum = $('efMomentum').value;
1326
+ const risk = $('efRisk').value;
1327
+ const q = globalQ();
1328
+
1329
+ const rows = D.etfHolds.filter(e =>
1330
+ e.price <= priceMax &&
1331
+ sectors.includes(e.sector) &&
1332
+ (!momentum || e.momentum === momentum) &&
1333
+ (!risk || e.risk === risk) &&
1334
+ (!q || e.ticker.includes(q) || e.name.toUpperCase().includes(q))
1335
+ );
1336
+
1337
+ const tbody = $('etfHoldBody');
1338
+ if (!rows.length) { tbody.innerHTML = `<tr><td colspan="11"><div class="empty-state"><div class="icon">🔍</div><p>No ETFs match your filters.</p></div></td></tr>`; return; }
1339
+
1340
+ tbody.innerHTML = rows.map((e, i) => {
1341
+ const sid = `spark-ef-${i}`;
1342
+ return `<tr>
1343
+ <td>
1344
+ <div class="ticker-cell">
1345
+ <span class="ticker-sym">${e.ticker}</span>
1346
+ <span class="ticker-name">${e.name}</span>
1347
+ </div>
1348
+ </td>
1349
+ <td style="color:var(--text2);font-size:.8rem">${e.index}</td>
1350
+ <td style="font-family:monospace;font-weight:700">$${e.price.toFixed(2)}</td>
1351
+ <td>${chgCell(e.chg1d)}</td>
1352
+ <td>${chgCell(e.chg1w)}</td>
1353
+ <td>${chgCell(e.chg1m)}</td>
1354
+ <td style="color:var(--text2);font-size:.8rem">${e.volume}</td>
1355
+ <td>${sparkCanvas(sid)}</td>
1356
+ <td>${momentumArrow(e.momentum)}</td>
1357
+ <td>${stratBadgeETF(e.strategy)}</td>
1358
+ <td>${riskBadge(e.risk)}</td>
1359
+ <td>${stars(e.conviction)}</td>
1360
+ </tr>`;
1361
+ }).join('');
1362
+
1363
+ rows.forEach((e, i) => drawSparkline(`spark-ef-${i}`, e.trend));
1364
+ updateStats();
1365
+ }
1366
+
1367
+ /* ─────────────────────────────────────────────
1368
+ RENDER: ETF OPTIONS
1369
+ ───────────────────────────────────────────── */
1370
+ function renderETFOpts() {
1371
+ const q = globalQ();
1372
+ const rows = D.etfOpts.filter(o =>
1373
+ o.dte <= 20 &&
1374
+ (!q || o.ticker.includes(q) || o.name.toUpperCase().includes(q))
1375
+ );
1376
+
1377
+ const tbody = $('etfOptBody');
1378
+ if (!rows.length) { tbody.innerHTML = `<tr><td colspan="10"><div class="empty-state"><div class="icon">🔍</div><p>No ETF options match.</p></div></td></tr>`; return; }
1379
+
1380
+ tbody.innerHTML = rows.map(o => `<tr>
1381
+ <td>
1382
+ <div class="ticker-cell">
1383
+ <span class="ticker-sym">${o.ticker}</span>
1384
+ <span class="badge ${sectorClass(o.sector)}">${o.sector}</span>
1385
+ </div>
1386
+ </td>
1387
+ <td>${stratBadge(o.strategy)}</td>
1388
+ <td style="font-family:monospace;font-weight:700;color:var(--amber)">${o.strike}</td>
1389
+ <td style="color:var(--text2)">${o.expiry}</td>
1390
+ <td>${dteCell(o.dte)}</td>
1391
+ <td style="font-family:monospace;font-weight:700">$${o.premium.toFixed(2)}</td>
1392
+ <td>${premPctCell(o.premPct)}</td>
1393
+ <td><span class="badge badge-violet">${o.ivr}%</span></td>
1394
+ <td style="font-family:monospace;color:var(--rose)">$${o.maxRisk.toLocaleString()}</td>
1395
+ <td>${plCell(o.premPct)}</td>
1396
+ </tr>`).join('');
1397
+ updateStats();
1398
+ }
1399
+
1400
+ /* ─────────────────────────────────────────────
1401
+ STAT STRIP UPDATE
1402
+ ───────────────────────────────────────────── */
1403
+ function updateStats() {
1404
+ const total = D.stocks.length + D.optSell.length + D.leaps.length + D.etfHolds.length + D.etfOpts.length;
1405
+ $('statTotal').textContent = total;
1406
+
1407
+ const avgPrem = D.optSell.reduce((a, o) => a + o.premPct, 0) / D.optSell.length;
1408
+ $('statPrem').textContent = avgPrem.toFixed(2) + '%';
1409
+
1410
+ const avgDelta = D.leaps.reduce((a, l) => a + l.delta, 0) / D.leaps.length;
1411
+ $('statDelta').textContent = avgDelta.toFixed(1);
1412
+
1413
+ const aboveThresh = [
1414
+ ...D.optSell.filter(o => o.premPct >= 0.7),
1415
+ ...D.leaps.filter(l => l.delta >= 60 && l.delta <= 80),
1416
+ ...D.etfOpts.filter(o => o.premPct >= 0.7),
1417
+ ].length;
1418
+ const totalElig = D.optSell.length + D.leaps.length + D.etfOpts.length;
1419
+ $('statThresh').textContent = Math.round(aboveThresh / totalElig * 100) + '%';
1420
+ }
1421
+
1422
+ /* ─────────────────────────────────────────────
1423
+ REFRESH (randomise mock data slightly)
1424
+ ───────────────────────────────────────────── */
1425
+ function refreshAllData() {
1426
+ const icon = $('refreshIcon');
1427
+ icon.classList.add('spinning');
1428
+ setTimeout(() => icon.classList.remove('spinning'), 650);
1429
+
1430
+ // Nudge prices ±2%
1431
+ D = JSON.parse(JSON.stringify(BASE));
1432
+ D.stocks.forEach(s => {
1433
+ const nudge = 1 + (Math.random() * .04 - .02);
1434
+ s.price = parseFloat((s.price * nudge).toFixed(2));
1435
+ s.chg1d = parseFloat((s.chg1d + (Math.random() * .6 - .3)).toFixed(2));
1436
+ s.trend = s.trend.map(v => parseFloat((v * (1 + (Math.random()*.02-.01))).toFixed(2)));
1437
+ });
1438
+ D.optSell.forEach(o => {
1439
+ o.premium = parseFloat((o.premium * (1 + (Math.random()*.1-.05))).toFixed(2));
1440
+ o.premPct = parseFloat((o.premPct * (1 + (Math.random()*.1-.05))).toFixed(2));
1441
+ o.ivr = Math.max(10, Math.min(99, Math.round(o.ivr + (Math.random()*6-3))));
1442
+ });
1443
+ D.etfHolds.forEach(e => {
1444
+ const nudge = 1 + (Math.random() * .04 - .02);
1445
+ e.price = parseFloat((e.price * nudge).toFixed(2));
1446
+ e.chg1d = parseFloat((e.chg1d + (Math.random() * .8 - .4)).toFixed(2));
1447
+ e.trend = e.trend.map(v => parseFloat((v * (1 + (Math.random()*.02-.01))).toFixed(2)));
1448
+ });
1449
+
1450
+ renderStocks(); renderOptSell(); renderLeaps(); renderETFHolds(); renderETFOpts();
1451
+ }
1452
+
1453
+ /* ─────────────────────────────────────────────
1454
+ INIT
1455
+ ───────────────────────────────────────────── */
1456
+ document.addEventListener('DOMContentLoaded', () => {
1457
+ renderStocks();
1458
+ renderOptSell();
1459
+ renderLeaps();
1460
+ renderETFHolds();
1461
+ renderETFOpts();
1462
+ updateStats();
1463
+ });
1464
+ </script>
1465
+ </body>
1466
+ </html>