Brajmovech commited on
Commit
e3f4ae3
·
1 Parent(s): 0982595

feat: cap headlines panel at 5 entries, add geo/macro category tags

Browse files

- style.css: --headlines-max-height: 310px cap with smooth scroll and
thin custom scrollbar; --status-amber / --status-amber-glow variables;
.headline-item--geo/.headline-item--macro amber left-border modifiers;
.headline-tag amber pill badge; .headlines-scroll-hint fade-in hint
- app.js: category-aware li class assignment; Geopolitical/Macro tag
pill appended to meta row; scroll hint shown when list overflows
- index.html: .headlines-scroll-hint element added below ul; app.js
bumped to v=17, style.css to v=2

Files changed (3) hide show
  1. static/app.js +19 -1
  2. static/style.css +55 -5
  3. templates/index.html +3 -2
static/app.js CHANGED
@@ -977,7 +977,11 @@ document.addEventListener('DOMContentLoaded', () => {
977
  const isLink = /^https?:\/\//i.test(url);
978
 
979
  const li = document.createElement('li');
980
- li.className = 'headline-item' + (isLink ? '' : ' headline-item--no-url');
 
 
 
 
981
 
982
  // Title — clickable link or plain span
983
  const titleEl = document.createElement(isLink ? 'a' : 'span');
@@ -1013,12 +1017,26 @@ document.addEventListener('DOMContentLoaded', () => {
1013
  metaEl.appendChild(srcSpan);
1014
  }
1015
 
 
 
 
 
 
 
 
1016
  li.appendChild(titleEl);
1017
  if (metaEl.hasChildNodes()) li.appendChild(metaEl);
1018
  headlinesList.appendChild(li);
1019
  });
1020
  }
1021
 
 
 
 
 
 
 
 
1022
  if (!headlinesList.children.length) {
1023
  const li = document.createElement('li');
1024
  li.className = 'headline-item headline-item--empty';
 
977
  const isLink = /^https?:\/\//i.test(url);
978
 
979
  const li = document.createElement('li');
980
+ const category = String(typeof headline === 'string' ? 'financial' : (headline?.category || 'financial')).trim().toLowerCase();
981
+ const catClass = category === 'geopolitical' ? ' headline-item--geo'
982
+ : category === 'macro' ? ' headline-item--macro'
983
+ : '';
984
+ li.className = 'headline-item' + catClass + (isLink ? '' : ' headline-item--no-url');
985
 
986
  // Title — clickable link or plain span
987
  const titleEl = document.createElement(isLink ? 'a' : 'span');
 
1017
  metaEl.appendChild(srcSpan);
1018
  }
1019
 
1020
+ if (category === 'geopolitical' || category === 'macro') {
1021
+ const tagEl = document.createElement('span');
1022
+ tagEl.className = 'headline-tag';
1023
+ tagEl.textContent = category === 'macro' ? 'Macro' : 'Geopolitical';
1024
+ metaEl.appendChild(tagEl);
1025
+ }
1026
+
1027
  li.appendChild(titleEl);
1028
  if (metaEl.hasChildNodes()) li.appendChild(metaEl);
1029
  headlinesList.appendChild(li);
1030
  });
1031
  }
1032
 
1033
+ // Show scroll hint if list overflows its capped height
1034
+ const hintEl = headlinesList.parentElement?.querySelector('.headlines-scroll-hint');
1035
+ if (hintEl) {
1036
+ const overflows = headlinesList.scrollHeight > headlinesList.clientHeight;
1037
+ hintEl.classList.toggle('visible', overflows);
1038
+ }
1039
+
1040
  if (!headlinesList.children.length) {
1041
  const li = document.createElement('li');
1042
  li.className = 'headline-item headline-item--empty';
static/style.css CHANGED
@@ -22,6 +22,10 @@
22
  --status-red-glow: rgba(182, 78, 90, 0.24);
23
  --status-yellow: #b48c3a;
24
  --status-yellow-glow: rgba(180, 140, 58, 0.22);
 
 
 
 
25
 
26
  --logo-grad-start: #1f2838;
27
  --logo-grad-end: #71839c;
@@ -534,10 +538,6 @@ header {
534
  }
535
 
536
  .dash-col--right .headlines-card .headlines-list {
537
- flex: 1;
538
- min-height: 0; /* essential for overflow:auto inside flex */
539
- max-height: none;
540
- overflow-y: auto;
541
  padding-right: 0.25rem;
542
  }
543
 
@@ -754,8 +754,19 @@ header {
754
  display: flex;
755
  flex-direction: column;
756
  gap: 0;
 
 
 
 
757
  scrollbar-width: thin;
758
- scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
 
 
 
 
 
 
 
759
  }
760
 
761
  .headline-item {
@@ -779,6 +790,45 @@ header {
779
  opacity: 0.72;
780
  }
781
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
782
  .headline-item--empty {
783
  font-style: italic;
784
  color: var(--text-muted);
 
22
  --status-red-glow: rgba(182, 78, 90, 0.24);
23
  --status-yellow: #b48c3a;
24
  --status-yellow-glow: rgba(180, 140, 58, 0.22);
25
+ --status-amber: #ba7517;
26
+ --status-amber-glow: rgba(186, 117, 23, 0.25);
27
+
28
+ --headlines-max-height: 310px;
29
 
30
  --logo-grad-start: #1f2838;
31
  --logo-grad-end: #71839c;
 
538
  }
539
 
540
  .dash-col--right .headlines-card .headlines-list {
 
 
 
 
541
  padding-right: 0.25rem;
542
  }
543
 
 
754
  display: flex;
755
  flex-direction: column;
756
  gap: 0;
757
+ max-height: var(--headlines-max-height);
758
+ overflow-y: auto;
759
+ overflow-x: hidden;
760
+ scroll-behavior: smooth;
761
  scrollbar-width: thin;
762
+ scrollbar-color: rgba(209,212,220,0.2) transparent;
763
+ }
764
+
765
+ .headlines-list::-webkit-scrollbar { width: 4px; }
766
+ .headlines-list::-webkit-scrollbar-track { background: transparent; }
767
+ .headlines-list::-webkit-scrollbar-thumb {
768
+ background: rgba(209,212,220,0.2);
769
+ border-radius: 99px;
770
  }
771
 
772
  .headline-item {
 
790
  opacity: 0.72;
791
  }
792
 
793
+ .headline-item--geo {
794
+ border-left-color: var(--status-amber, #ba7517);
795
+ }
796
+
797
+ .headline-item--macro {
798
+ border-left-color: var(--status-amber, #ba7517);
799
+ opacity: 0.92;
800
+ }
801
+
802
+ .headline-tag {
803
+ display: inline-block;
804
+ font-size: 9px;
805
+ line-height: 1;
806
+ padding: 2px 5px;
807
+ border-radius: 3px;
808
+ background: rgba(186, 117, 23, 0.18);
809
+ color: #ba7517;
810
+ white-space: nowrap;
811
+ margin-left: auto;
812
+ flex-shrink: 0;
813
+ align-self: center;
814
+ }
815
+
816
+ .headlines-scroll-hint {
817
+ font-size: 10px;
818
+ color: var(--text-muted);
819
+ text-align: center;
820
+ padding-top: 6px;
821
+ border-top: 1px solid rgba(209,212,220,0.08);
822
+ margin-top: 4px;
823
+ opacity: 0;
824
+ transition: opacity 0.2s;
825
+ pointer-events: none;
826
+ }
827
+
828
+ .headlines-scroll-hint.visible {
829
+ opacity: 1;
830
+ }
831
+
832
  .headline-item--empty {
833
  font-style: italic;
834
  color: var(--text-muted);
templates/index.html CHANGED
@@ -14,7 +14,7 @@
14
  })();
15
  </script>
16
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
17
- <link rel="stylesheet" href="/static/style.css">
18
  <link rel="icon" type="image/svg+xml"
19
  href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22 fill=%22%233b82f6%22>IA</text></svg>">
20
  </head>
@@ -126,6 +126,7 @@
126
  <div class="card glass-panel headlines-card">
127
  <h3>Recent Headlines Analyzed</h3>
128
  <ul id="headlines-list" class="headlines-list"></ul>
 
129
  </div>
130
 
131
  </div>
@@ -178,7 +179,7 @@
178
  <!-- TradingView Lightweight Charts -->
179
  <script
180
  src="https://unpkg.com/lightweight-charts@4.1.1/dist/lightweight-charts.standalone.production.js?v=4"></script>
181
- <script src="/static/app.js?v=16"></script>
182
  </body>
183
 
184
  </html>
 
14
  })();
15
  </script>
16
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap" rel="stylesheet">
17
+ <link rel="stylesheet" href="/static/style.css?v=2">
18
  <link rel="icon" type="image/svg+xml"
19
  href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22 fill=%22%233b82f6%22>IA</text></svg>">
20
  </head>
 
126
  <div class="card glass-panel headlines-card">
127
  <h3>Recent Headlines Analyzed</h3>
128
  <ul id="headlines-list" class="headlines-list"></ul>
129
+ <div class="headlines-scroll-hint">scroll for more</div>
130
  </div>
131
 
132
  </div>
 
179
  <!-- TradingView Lightweight Charts -->
180
  <script
181
  src="https://unpkg.com/lightweight-charts@4.1.1/dist/lightweight-charts.standalone.production.js?v=4"></script>
182
+ <script src="/static/app.js?v=17"></script>
183
  </body>
184
 
185
  </html>