datamk commited on
Commit
6318970
·
verified ·
1 Parent(s): 492a220

Upload 9 files

Browse files
data/news_sentiment.json CHANGED
The diff for this file is too large to render. See raw diff
 
data/sentiment_trends.json CHANGED
@@ -1,4 +1,12 @@
1
  [
 
 
 
 
 
 
 
 
2
  {
3
  "time": "2026-02-17T22:30:04.101Z",
4
  "score": 2.236625514403292
@@ -190,13 +198,5 @@
190
  {
191
  "time": "2026-03-22T18:54:01.373Z",
192
  "score": 0.4885799404170804
193
- },
194
- {
195
- "time": "2026-04-02T22:20:26.605Z",
196
- "score": 0.6515769944341373
197
- },
198
- {
199
- "time": "2026-04-02T22:25:02.356Z",
200
- "score": 0.6784124629080118
201
  }
202
  ]
 
1
  [
2
+ {
3
+ "time": "2026-02-17T22:20:04.427Z",
4
+ "score": 2.2378947368421054
5
+ },
6
+ {
7
+ "time": "2026-02-17T22:25:04.187Z",
8
+ "score": 2.259336099585062
9
+ },
10
  {
11
  "time": "2026-02-17T22:30:04.101Z",
12
  "score": 2.236625514403292
 
198
  {
199
  "time": "2026-03-22T18:54:01.373Z",
200
  "score": 0.4885799404170804
 
 
 
 
 
 
 
 
201
  }
202
  ]
index.js CHANGED
@@ -168,12 +168,7 @@ async function fetchIndices() {
168
  'SENSEX': '^BSESN',
169
  'FINNIFTY': 'NIFTY_FIN_SERVICE.NS',
170
  'INDIA VIX': '^INDIAVIX',
171
- 'USD/INR': 'INR=X',
172
- 'S&P 500': '^GSPC',
173
- 'NASDAQ': '^IXIC',
174
- 'DAX': '^GDAXI',
175
- 'FTSE 100': '^FTSE',
176
- 'NIKKEI 225': '^N225'
177
  };
178
 
179
  const results = {};
 
168
  'SENSEX': '^BSESN',
169
  'FINNIFTY': 'NIFTY_FIN_SERVICE.NS',
170
  'INDIA VIX': '^INDIAVIX',
171
+ 'USD/INR': 'INR=X'
 
 
 
 
 
172
  };
173
 
174
  const results = {};
public/app.js CHANGED
@@ -2,26 +2,14 @@ let allNews = [];
2
  let sentimentTrend = [];
3
  let currentFilter = 'all';
4
  let currentSource = 'all';
5
- let currentSector = 'all';
6
- let watchlistMode = false;
7
  let searchQuery = '';
8
  let renderedCount = 0;
9
  let currentRenderedFiltered = [];
10
- let watchlist = JSON.parse(localStorage.getItem('trading_pulse_watchlist') || '["RELIANCE", "TCS", "HDFC", "INFY"]');
11
- let lastSeenNewsId = null;
12
 
13
  const IMPACT_KEYWORDS = {
14
- high: ['crash', 'crisis', 'urgent', 'breaking', 'collapsed', 'warns', 'surge', 'plunge', 'lockdown', 'rating', 'result', 'focus', 'alert'],
15
- pos: ['profit', 'growth', 'record', 'dividend', 'buyback', 'partnership', 'acquired', 'expansion', 'jump', 'bullish', 'buy', 'outperforms'],
16
- neg: ['loss', 'fall', 'slump', 'down', 'decline', 'investigation', 'scam', 'penalty', 'lawsuit', 'bearish', 'sell', 'warning']
17
- };
18
-
19
- const SECTOR_KEYWORDS = {
20
- 'Banking': ['bank', 'hdfc', 'sbi', 'icici', 'axis', 'kotak', 'pnb', 'rbi', 'repo', 'npa', 'loan'],
21
- 'IT': ['tcs', 'infosys', 'infy', 'wipro', 'hcl', 'techm', 'nasdaq', 'software', 'ai', 'cloud', 'it services'],
22
- 'Pharma': ['pharma', 'sun', 'drreddy', 'cipla', 'lupin', 'divislab', 'biocon', 'healthcare', 'drug', 'fda'],
23
- 'Auto': ['auto', 'tata motors', 'maruti', 'mahindra', 'm&m', 'bajaj', 'eicher', 'heromotocorp', 'ev', 'vehicle'],
24
- 'Energy': ['reliance', 'ril', 'adani', 'ongc', 'ntpc', 'power', 'green energy', 'oil', 'gas', 'coal']
25
  };
26
 
27
  async function fetchNews() {
@@ -31,7 +19,6 @@ async function fetchNews() {
31
  allNews = data.news;
32
  sentimentTrend = data.trend;
33
 
34
- checkForFlashAlerts(allNews);
35
  renderDashboard();
36
  renderIndices(data.indices);
37
  } catch (error) {
@@ -41,49 +28,6 @@ async function fetchNews() {
41
  }
42
  }
43
 
44
- function checkForFlashAlerts(news) {
45
- if (!news.length) return;
46
- const latest = news[0];
47
- if (lastSeenNewsId === latest.id) return;
48
-
49
- // Only check news from last 5 minutes to avoid spamming on initial load
50
- const pubDate = new Date(latest.pubDate);
51
- const diff = (new Date() - pubDate) / (1000 * 60);
52
-
53
- if (diff < 5 && isHighImpact(latest.title)) {
54
- showFlashAlert(latest);
55
- }
56
- lastSeenNewsId = latest.id;
57
- }
58
-
59
- function isHighImpact(title) {
60
- if (!title) return false;
61
- return IMPACT_KEYWORDS.high.some(word => title.toLowerCase().includes(word));
62
- }
63
-
64
- function showFlashAlert(item) {
65
- const container = document.getElementById('flash-alert');
66
- const alert = document.createElement('div');
67
- const isPos = item.sentiment.score > 0;
68
- alert.className = `flash-alert ${isPos ? 'positive' : ''}`;
69
- alert.innerHTML = `
70
- <h4>FLASH: ${item.source}</h4>
71
- <p>${item.title}</p>
72
- `;
73
- container.appendChild(alert);
74
-
75
- // Browser notification
76
- if (Notification.permission === 'granted') {
77
- new Notification(`Market Alert: ${item.source}`, { body: item.title });
78
- }
79
-
80
- setTimeout(() => {
81
- alert.style.opacity = '0';
82
- alert.style.transform = 'translateX(100%)';
83
- setTimeout(() => alert.remove(), 300);
84
- }, 8000);
85
- }
86
-
87
  async function fetchIndicesOnly() {
88
  try {
89
  const response = await fetch('/api/indices');
@@ -105,13 +49,6 @@ function renderFeed() {
105
  let filtered = allNews;
106
  if (currentFilter !== 'all') filtered = filtered.filter(n => n.sentiment.label === currentFilter);
107
  if (currentSource !== 'all') filtered = filtered.filter(n => n.source === currentSource);
108
- if (currentSector !== 'all') {
109
- const keywords = SECTOR_KEYWORDS[currentSector];
110
- filtered = filtered.filter(n => keywords.some(k => n.title.toLowerCase().includes(k)));
111
- }
112
- if (watchlistMode) {
113
- filtered = filtered.filter(n => watchlist.some(stock => n.title.toUpperCase().includes(stock.toUpperCase())));
114
- }
115
  if (searchQuery) {
116
  const query = searchQuery.toLowerCase();
117
  filtered = filtered.filter(n =>
@@ -186,35 +123,25 @@ function setupObserver(trigger) {
186
  }
187
 
188
  function renderIndices(indices) {
189
- const indianContainer = document.getElementById('index-ticker');
190
- const globalContainer = document.getElementById('global-ticker');
191
- if (!indianContainer || !globalContainer || !indices) return;
192
-
193
- const indianKeys = ['NIFTY 50', 'BANK NIFTY', 'SENSEX', 'FINNIFTY', 'INDIA VIX', 'USD/INR'];
194
- const globalKeys = ['S&P 500', 'NASDAQ', 'DAX', 'FTSE 100', 'NIKKEI 225'];
195
-
196
- const renderIndicesHelper = (keys) => Object.entries(indices)
197
- .filter(([name]) => keys.includes(name))
198
- .map(([name, data]) => {
199
- const isUp = parseFloat(data.change) >= 0;
200
- const sign = isUp ? '+' : '';
201
- return `
202
- <div class="ticker-item">
203
- <span class="ticker-name">${name}</span>
204
- <div class="ticker-data">
205
- <span class="ticker-price">${parseFloat(data.price).toLocaleString('en-IN', { minimumFractionDigits: 2 })}</span>
206
- <span class="ticker-change ${isUp ? 'up' : 'down'}">${sign}${data.changePercent}%</span>
207
- </div>
208
- </div>
209
- `;
210
- }).join('');
211
 
212
- indianContainer.innerHTML = renderIndicesHelper(indianKeys);
213
- globalContainer.innerHTML = renderIndicesHelper(globalKeys);
 
 
 
 
 
 
 
 
 
 
 
214
  }
215
 
216
  function highlightImpact(title) {
217
- if (!title) return '';
218
  let result = title;
219
  Object.entries(IMPACT_KEYWORDS).forEach(([type, words]) => {
220
  words.forEach(word => {
@@ -236,66 +163,12 @@ function getTimeAgo(date) {
236
 
237
  function filterBySentiment(sentiment) {
238
  currentFilter = sentiment;
239
- watchlistMode = false;
240
  document.querySelectorAll('.filter-btn').forEach(btn => {
241
  btn.classList.toggle('active', btn.dataset.sentiment === sentiment);
242
  });
243
  renderFeed();
244
  }
245
 
246
- function filterBySector(sector) {
247
- currentSector = sector;
248
- document.querySelectorAll('.sector-btn').forEach(btn => {
249
- btn.classList.toggle('active', btn.innerText.includes(sector) || (sector === 'all' && btn.innerText === 'All Sectors'));
250
- });
251
- renderFeed();
252
- }
253
-
254
- function toggleWatchlistFilter() {
255
- watchlistMode = !watchlistMode;
256
- currentFilter = 'all';
257
- document.getElementById('watchlist-toggle').classList.toggle('active', watchlistMode);
258
- document.querySelectorAll('.filter-btn[data-sentiment]').forEach(btn => btn.classList.remove('active'));
259
- if (!watchlistMode) document.querySelector('.filter-btn[data-sentiment="all"]').classList.add('active');
260
- renderFeed();
261
- }
262
-
263
- function openWatchlistModal() {
264
- document.getElementById('watchlist-modal').classList.add('active');
265
- renderWatchlistItems();
266
- }
267
-
268
- function closeWatchlistModal() {
269
- document.getElementById('watchlist-modal').classList.remove('active');
270
- if (watchlistMode) renderFeed();
271
- }
272
-
273
- function addToWatchlist() {
274
- const input = document.getElementById('watchlist-input');
275
- const value = input.value.trim().toUpperCase();
276
- if (value && !watchlist.includes(value)) {
277
- watchlist.push(value);
278
- localStorage.setItem('trading_pulse_watchlist', JSON.stringify(watchlist));
279
- input.value = '';
280
- renderWatchlistItems();
281
- }
282
- }
283
-
284
- function removeFromWatchlist(stock) {
285
- watchlist = watchlist.filter(s => s !== stock);
286
- localStorage.setItem('trading_pulse_watchlist', JSON.stringify(watchlist));
287
- renderWatchlistItems();
288
- }
289
-
290
- function renderWatchlistItems() {
291
- const container = document.getElementById('watchlist-items');
292
- container.innerHTML = watchlist.map(stock => `
293
- <div class="wl-item">
294
- ${stock} <span class="wl-remove" onclick="removeFromWatchlist('${stock}')">&times;</span>
295
- </div>
296
- `).join('');
297
- }
298
-
299
  let searchTimeout;
300
  function handleSearch(val) {
301
  clearTimeout(searchTimeout);
@@ -326,11 +199,7 @@ window.addEventListener('popstate', function (e) {
326
  }
327
  });
328
 
329
- // Request notification permission
330
- if (window.Notification && Notification.permission !== 'granted') {
331
- Notification.requestPermission();
332
- }
333
 
334
  fetchNews();
335
- setInterval(fetchNews, 300000); // 5 minutes
336
  setInterval(fetchIndicesOnly, 10000);
 
2
  let sentimentTrend = [];
3
  let currentFilter = 'all';
4
  let currentSource = 'all';
 
 
5
  let searchQuery = '';
6
  let renderedCount = 0;
7
  let currentRenderedFiltered = [];
 
 
8
 
9
  const IMPACT_KEYWORDS = {
10
+ high: ['crash', 'crisis', 'urgent', 'breaking', 'collapsed', 'warns', 'surge', 'plunge', 'lockdown', 'rating', 'result', 'focus'],
11
+ pos: ['profit', 'growth', 'record', 'dividend', 'buyback', 'partnership', 'acquired', 'expansion', 'jump', 'bullish', 'buy'],
12
+ neg: ['loss', 'fall', 'slump', 'down', 'decline', 'investigation', 'scam', 'penalty', 'lawsuit', 'bearish', 'sell']
 
 
 
 
 
 
 
 
13
  };
14
 
15
  async function fetchNews() {
 
19
  allNews = data.news;
20
  sentimentTrend = data.trend;
21
 
 
22
  renderDashboard();
23
  renderIndices(data.indices);
24
  } catch (error) {
 
28
  }
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  async function fetchIndicesOnly() {
32
  try {
33
  const response = await fetch('/api/indices');
 
49
  let filtered = allNews;
50
  if (currentFilter !== 'all') filtered = filtered.filter(n => n.sentiment.label === currentFilter);
51
  if (currentSource !== 'all') filtered = filtered.filter(n => n.source === currentSource);
 
 
 
 
 
 
 
52
  if (searchQuery) {
53
  const query = searchQuery.toLowerCase();
54
  filtered = filtered.filter(n =>
 
123
  }
124
 
125
  function renderIndices(indices) {
126
+ const container = document.getElementById('index-ticker');
127
+ if (!container || !indices) return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
+ container.innerHTML = Object.entries(indices).map(([name, data]) => {
130
+ const isUp = parseFloat(data.change) >= 0;
131
+ const sign = isUp ? '+' : '';
132
+ return `
133
+ <div class="ticker-item">
134
+ <span class="ticker-name">${name}</span>
135
+ <div class="ticker-data">
136
+ <span class="ticker-price">${parseFloat(data.price).toLocaleString('en-IN', { minimumFractionDigits: 2 })}</span>
137
+ <span class="ticker-change ${isUp ? 'up' : 'down'}">${sign}${data.changePercent}%</span>
138
+ </div>
139
+ </div>
140
+ `;
141
+ }).join('');
142
  }
143
 
144
  function highlightImpact(title) {
 
145
  let result = title;
146
  Object.entries(IMPACT_KEYWORDS).forEach(([type, words]) => {
147
  words.forEach(word => {
 
163
 
164
  function filterBySentiment(sentiment) {
165
  currentFilter = sentiment;
 
166
  document.querySelectorAll('.filter-btn').forEach(btn => {
167
  btn.classList.toggle('active', btn.dataset.sentiment === sentiment);
168
  });
169
  renderFeed();
170
  }
171
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  let searchTimeout;
173
  function handleSearch(val) {
174
  clearTimeout(searchTimeout);
 
199
  }
200
  });
201
 
 
 
 
 
202
 
203
  fetchNews();
204
+ setInterval(fetchNews, 30000);
205
  setInterval(fetchIndicesOnly, 10000);
public/index.html CHANGED
@@ -23,11 +23,8 @@
23
  <header class="header">
24
 
25
 
26
- <div id="index-ticker" class="index-ticker Indian">
27
- <!-- Indian Indices will be injected here -->
28
- </div>
29
- <div id="global-ticker" class="index-ticker Global">
30
- <!-- Global Indices will be injected here -->
31
  </div>
32
 
33
  <div class="stats">
@@ -55,22 +52,10 @@
55
  onclick="filterBySentiment('Positive');">Bullish</button>
56
  <button class="filter-btn" data-sentiment="Negative"
57
  onclick="filterBySentiment('Negative');">Bearish</button>
58
- <button class="filter-btn watchlist-btn" id="watchlist-toggle"
59
- onclick="toggleWatchlistFilter();">Watchlist ⭐</button>
60
  </div>
61
  </div>
62
  </div>
63
 
64
- <div class="sector-filters">
65
- <button class="sector-btn active" onclick="filterBySector('all')">All Sectors</button>
66
- <button class="sector-btn" onclick="filterBySector('Banking')">Banking</button>
67
- <button class="sector-btn" onclick="filterBySector('IT')">IT</button>
68
- <button class="sector-btn" onclick="filterBySector('Pharma')">Pharma</button>
69
- <button class="sector-btn" onclick="filterBySector('Auto')">Auto</button>
70
- <button class="sector-btn" onclick="filterBySector('Energy')">Energy/Reliance</button>
71
- <button class="sector-btn edit-watchlist" onclick="openWatchlistModal()">⭐ Edit Watchlist</button>
72
- </div>
73
-
74
  <div id="news-feed" class="news-feed">
75
  <div class="loader">Synchronizing with market feeds...</div>
76
  </div>
@@ -78,24 +63,6 @@
78
  </div>
79
  </main>
80
 
81
- <div id="watchlist-modal" class="support-modal" onclick="closeWatchlistModal()">
82
- <div class="support-modal-content" onclick="event.stopPropagation()">
83
- <h3>Manage Watchlist</h3>
84
- <div class="watchlist-input-container">
85
- <input type="text" id="watchlist-input" placeholder="e.g. RELIANCE, TCS, ADANI...">
86
- <button onclick="addToWatchlist()">Add</button>
87
- </div>
88
- <div id="watchlist-items" class="watchlist-items">
89
- <!-- Items injected here -->
90
- </div>
91
- <button class="close-btn" onclick="closeWatchlistModal()">Done</button>
92
- </div>
93
- </div>
94
-
95
- <div id="flash-alert" class="flash-alert-container">
96
- <!-- Flash alerts shown here -->
97
- </div>
98
-
99
  <div id="support-modal" class="support-modal" onclick="closeSupportModal()">
100
  <div class="support-modal-content" onclick="event.stopPropagation()">
101
  <h3>Support Us</h3>
@@ -104,7 +71,7 @@
104
  </div>
105
  </div>
106
 
107
- <script src="app.js?v=1.1"></script>
108
  </body>
109
 
110
  </html>
 
23
  <header class="header">
24
 
25
 
26
+ <div id="index-ticker" class="index-ticker">
27
+ <!-- Data will be injected here by app.js -->
 
 
 
28
  </div>
29
 
30
  <div class="stats">
 
52
  onclick="filterBySentiment('Positive');">Bullish</button>
53
  <button class="filter-btn" data-sentiment="Negative"
54
  onclick="filterBySentiment('Negative');">Bearish</button>
 
 
55
  </div>
56
  </div>
57
  </div>
58
 
 
 
 
 
 
 
 
 
 
 
59
  <div id="news-feed" class="news-feed">
60
  <div class="loader">Synchronizing with market feeds...</div>
61
  </div>
 
63
  </div>
64
  </main>
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  <div id="support-modal" class="support-modal" onclick="closeSupportModal()">
67
  <div class="support-modal-content" onclick="event.stopPropagation()">
68
  <h3>Support Us</h3>
 
71
  </div>
72
  </div>
73
 
74
+ <script src="app.js"></script>
75
  </body>
76
 
77
  </html>
public/style.css CHANGED
@@ -100,18 +100,13 @@ body {
100
  }
101
 
102
  .index-ticker {
 
103
  display: flex;
104
  flex-wrap: wrap;
105
  gap: 0.4rem 0.75rem;
106
  padding: 0 0.5rem;
107
- justify-content: flex-start;
108
  align-items: center;
109
- border-right: 1px solid var(--card-border);
110
- }
111
-
112
- .index-ticker.Global {
113
- border-right: none;
114
- border-left: 1px solid var(--card-border);
115
  }
116
 
117
  .ticker-item {
@@ -325,39 +320,6 @@ body {
325
  }
326
  }
327
 
328
- .sector-filters {
329
- display: flex;
330
- overflow-x: auto;
331
- gap: 0.6rem;
332
- padding: 0.5rem 0 1rem 0;
333
- scrollbar-width: none;
334
- }
335
-
336
- .sector-btn {
337
- background: var(--card-bg);
338
- border: 1px solid var(--card-border);
339
- color: var(--text-secondary);
340
- padding: 6px 14px;
341
- border-radius: 8px;
342
- font-size: 0.75rem;
343
- cursor: pointer;
344
- white-space: nowrap;
345
- transition: all 0.2s;
346
- }
347
-
348
- .sector-btn.active {
349
- background: rgba(82, 175, 255, 0.15);
350
- border-color: var(--accent-blue);
351
- color: var(--accent-blue);
352
- }
353
-
354
- .sector-btn.edit-watchlist {
355
- margin-left: auto;
356
- background: rgba(255, 215, 64, 0.1);
357
- color: var(--accent-gold);
358
- border-color: rgba(255, 215, 64, 0.3);
359
- }
360
-
361
  .feed-section {
362
  min-width: 0;
363
  overflow: hidden;
@@ -600,114 +562,6 @@ body {
600
  background: rgba(82, 175, 255, 0.15);
601
  }
602
 
603
- .watchlist-input-container {
604
- display: flex;
605
- gap: 0.5rem;
606
- margin-bottom: 1.5rem;
607
- }
608
-
609
- .watchlist-input-container input {
610
- flex: 1;
611
- background: rgba(255,255,255,0.05);
612
- border: 1px solid var(--card-border);
613
- color: white;
614
- padding: 10px;
615
- border-radius: 8px;
616
- }
617
-
618
- .watchlist-input-container button {
619
- background: var(--accent-blue);
620
- border: none;
621
- color: black;
622
- padding: 0 1rem;
623
- border-radius: 8px;
624
- font-weight: 700;
625
- cursor: pointer;
626
- }
627
-
628
- .watchlist-items {
629
- display: flex;
630
- flex-wrap: wrap;
631
- gap: 0.5rem;
632
- margin-bottom: 2rem;
633
- max-height: 200px;
634
- overflow-y: auto;
635
- }
636
-
637
- .wl-item {
638
- background: var(--card-border);
639
- padding: 4px 10px;
640
- border-radius: 15px;
641
- font-size: 0.75rem;
642
- display: flex;
643
- align-items: center;
644
- gap: 6px;
645
- }
646
-
647
- .wl-remove {
648
- cursor: pointer;
649
- font-weight: 700;
650
- opacity: 0.6;
651
- }
652
-
653
- .wl-remove:hover {
654
- opacity: 1;
655
- color: var(--accent-red);
656
- }
657
-
658
- .flash-alert-container {
659
- position: fixed;
660
- bottom: 2rem;
661
- right: 2rem;
662
- z-index: 2000;
663
- display: flex;
664
- flex-direction: column;
665
- gap: 0.75rem;
666
- }
667
-
668
- .flash-alert {
669
- background: rgba(255, 82, 82, 0.95);
670
- color: white;
671
- padding: 1rem 1.5rem;
672
- border-radius: 12px;
673
- box-shadow: 0 8px 32px rgba(255, 82, 82, 0.4);
674
- min-width: 250px;
675
- max-width: 400px;
676
- animation: slideIn 0.3s ease-out;
677
- display: flex;
678
- flex-direction: column;
679
- gap: 4px;
680
- }
681
-
682
- .flash-alert.positive {
683
- background: rgba(0, 230, 118, 0.95);
684
- box-shadow: 0 8px 32px rgba(0, 230, 118, 0.4);
685
- }
686
-
687
- .flash-alert h4 {
688
- font-size: 0.8rem;
689
- text-transform: uppercase;
690
- font-weight: 900;
691
- opacity: 0.9;
692
- }
693
-
694
- .flash-alert p {
695
- font-size: 0.9rem;
696
- font-weight: 600;
697
- line-height: 1.2;
698
- }
699
-
700
- @keyframes slideIn {
701
- from {
702
- transform: translateX(100%);
703
- opacity: 0;
704
- }
705
- to {
706
- transform: translateX(0);
707
- opacity: 1;
708
- }
709
- }
710
-
711
  @media (max-width: 480px) {
712
  .support-modal-content {
713
  padding: 1rem;
 
100
  }
101
 
102
  .index-ticker {
103
+ flex: 1;
104
  display: flex;
105
  flex-wrap: wrap;
106
  gap: 0.4rem 0.75rem;
107
  padding: 0 0.5rem;
108
+ justify-content: space-evenly;
109
  align-items: center;
 
 
 
 
 
 
110
  }
111
 
112
  .ticker-item {
 
320
  }
321
  }
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  .feed-section {
324
  min-width: 0;
325
  overflow: hidden;
 
562
  background: rgba(82, 175, 255, 0.15);
563
  }
564
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565
  @media (max-width: 480px) {
566
  .support-modal-content {
567
  padding: 1rem;