Commit Graph

930 Commits

Author SHA1 Message Date
aa5064
cfbd1ad8a1 feat: add Gulf FDI investment database and panel component
772-line database of Saudi Arabia and UAE foreign direct investments in
global critical infrastructure (ports, energy, data centers, railways, etc.)
with filterable/sortable table panel.

Originally contributed as standalone 'infra' variant in PR #61.
2026-02-17 15:31:37 +04:00
Elie Habib
8c8fb0ae0a fix: resolve P2 reload guard and harness assertion drift 2026-02-17 12:25:34 +04:00
Elie Habib
4a639c79c6 feat(header): move UTC clock from map overlay to centered header bar
- Add centered header-clock in GLOBAL SITUATION panel header
- Remove map-timestamp from Map.ts and DeckGLMap.ts
- Clock ticks every second with monospace font
2026-02-17 12:00:23 +04:00
Elie Habib
fb512e7918 fix(trending): suppress month names and strip source attributions from titles
- Add goldman, sachs, off, and all 12 month names to SUPPRESSED_TRENDING_TERMS
- Add stripSourceAttribution() to remove feed name suffixes (e.g. "- Wall Street Journal") from RSS titles before keyword extraction
2026-02-17 11:34:28 +04:00
Elie Habib
a78a072079 fix(deploy): prevent stale chunk 404s after Vercel redeployment
- vercel.json: add no-cache headers for / and /index.html so CDN never serves stale HTML
- main.ts: add vite:preloadError listener to auto-reload once on chunk 404s
- vite.config.ts: remove HTML from SW precache, add NetworkFirst for navigation requests
2026-02-17 11:30:58 +04:00
Elie Habib
9a31eeba09 chore(release): finalize 2.3.8 changelog and version 2026-02-17 09:53:03 +04:00
Elie Habib
a524ab3ad7 merge(main): integrate finance variant and resilience hardening
Merge branch 'feature/finance-variant' into main.

Changelog (2.3.8):
- add dedicated finance variant with finance/trading focused feeds, panels, and desktop profile
- stage feed category loading with bounded concurrency to reduce startup pressure
- add AI classification admission control and tighter non-finance budgets
- harden external source behavior (Polymarket fallback probing, FRED graceful empty payloads)
- replace brittle MarketWatch direct RSS usage with resilient Google News fallbacks across variants
- keep finance data-rich panels while adding news panels, and ensure first-class desktop Deck.GL behavior
2026-02-17 09:50:56 +04:00
Elie Habib
26c03ca545 fix(trending): suppress noisy finance/generic terms from keyword spikes
Add 28 terms to SUPPRESSED_TRENDING_TERMS: common finance jargon
(trading, stock, earnings, ipo, currency, dollar, usd, etc.),
generic news words (today, chief, focus, basel), date fragments,
and web artifacts (com, platform, block).
2026-02-17 09:47:51 +04:00
Elie Habib
b2c3144a7e Harden full and tech variants against feed/API pressure 2026-02-17 09:46:25 +04:00
Elie Habib
116fc80fc7 Merge remote-tracking branch 'origin/main' into feature/finance-variant
# Conflicts:
#	index.html
#	src/components/DeckGLMap.ts
2026-02-17 09:37:47 +04:00
Elie Habib
ed9cc922e2 Fix finance variant runtime resiliency and API pressure 2026-02-17 09:34:15 +04:00
Elie Habib
5382e79ac7 fix(finance): keep data panels and add desktop finance map layers 2026-02-17 09:06:35 +04:00
Elie Habib
ef2b67ad22 fix(finance): address PR review blocking issues
- Add missing RSS proxy domains (seekingalpha, coindesk, cointelegraph)
- Fix operator precedence in finance marker zoom checks (explicit parens)
- Add Number.isFinite() NaN guards on all finance marker projections
- Include finance variant in aggregated test:e2e script
2026-02-17 08:38:25 +04:00
Elie Habib
2ac23dcabf fix: wire timeline filtering across map and news panels 2026-02-17 08:12:13 +04:00
Elie Habib
b1e917972e fix(banner): hide desktop download prompt on mobile devices 2026-02-17 07:54:02 +04:00
Elie Habib
0ea47330ba fix(panels): standardize error messages with specific causes
Differentiate missing API key, upstream down, and empty data states.
Name the actual data source in error messages instead of generic text.
2026-02-17 00:24:55 +04:00
Elie Habib
65dea2e4f9 fix(desktop): batch keychain reads to reduce macOS password prompts
Add get_all_secrets command that reads all 18 keys in a single IPC call.
This triggers one Keychain prompt instead of 18 on fresh installs.
2026-02-17 00:24:44 +04:00
Elie Habib
631a5e2112 chore(ai): switch OpenRouter model to auto-routed free tier 2026-02-17 00:15:11 +04:00
Elie Habib
88ad25cb93 release: v2.3.7
Full light mode theme, header dark/light toggle, desktop update checker,
bundled Node.js in installer, CORS fixes, and panel defaults update.
v2.3.7
2026-02-16 23:56:28 +04:00
Elie Habib
49d5100480 feat(panels): enable UCDP, UNHCR, Climate, and Population panels by default 2026-02-16 23:53:21 +04:00
Elie Habib
c2992c2fae refactor(header): remove redundant theme toggle from panels modal
Now that the header has a sun/moon dark/light toggle, the Appearance
section in the settings modal is redundant. Revert modal title from
"Settings" back to "Panels" and remove theme radio buttons and CSS.
2026-02-16 23:48:39 +04:00
Elie Habib
9f0a2107ed chore: add ideas/ to .gitignore 2026-02-16 23:38:01 +04:00
Elie Habib
72d191c6db chore: add markdown linting config and CI workflow 2026-02-16 23:34:01 +04:00
Elie Habib
c31dfbb70e docs: update documentation, release packaging, and validation report 2026-02-16 23:33:06 +04:00
Elie Habib
c94ec0b4ad Adding Node in the Tauri Installer 2026-02-16 23:30:19 +04:00
Elie Habib
9a7a988846 feat(header): replace UTC clock with dark/light mode toggle
Remove the duplicate time display from the header bar and add a
theme toggle button (sun/moon icon) that hooks into the existing
theme-manager. Bidirectional sync with settings modal radios.
2026-02-16 23:20:32 +04:00
Elie Habib
b59235fc45 CORS fixes for Tauri desktop app 2026-02-16 23:14:08 +04:00
Elie Habib
cccfdac0f9 feat(update): add desktop update check with architecture-aware download links 2026-02-16 23:13:10 +04:00
Elie Habib
2e15ee6815 fix(markets): keep Yahoo-backed data visible when Finnhub is skipped 2026-02-16 23:12:00 +04:00
Elie Habib
60cec92a16 fix(windows): preserve UNC paths when sanitizing sidecar script path 2026-02-16 23:09:30 +04:00
Elie Habib
6c41fec3bb feat: add light mode theme with full UI, map, and chart theming (#84)
## Summary

Adds a complete dual-theme system to WorldMonitor. Users can toggle
between dark and light mode in Settings, with the preference persisted
across sessions. Every panel, the map, charts, and all chrome are fully
themed.

**41 files changed, +1,591 / -1,128 lines**

## What's included

### CSS Foundation (Phase 1)
- 124+ hardcoded colors centralized into CSS custom properties
- Theme colors separated from semantic colors (threat reds, DEFCON,
status badges stay identical)
- `getCSSColor()` runtime utility with theme-aware cache for dynamic TS
components

### Theme Core (Phase 2)
- `ThemeManager` module with `get/set/apply` theme functions and
localStorage persistence
- FOUC prevention inline scripts in both HTML entry points
- Dark/Light radio toggle in Settings → Appearance section

### Map & Visualization Theming (Phase 3)
- Map auto-swaps between dark CARTO and light Voyager tiles (no flash)
- Deck.GL overlay layers adjust opacity/saturation per theme for
readability
- D3 CountryTimeline chart colors converted to theme-aware
`getCSSColor()`

### Polish & Accessibility (Phase 4)
- Smooth 200ms CSS transitions for all theme switching
- WCAG AA contrast compliance (`--text-muted` #767676, 4.54:1 ratio)
- Both build variants (full geopolitical + tech/startup) verified
working

## Demo

### Toggle dark ↔ light


https://github.com/user-attachments/assets/ce8d3bbe-fb5e-49cb-9bbd-5da5d900a15a

### Dark mode (unchanged)

<img width="5120" height="2648" alt="image"
src="https://github.com/user-attachments/assets/6a055ae6-e9a9-4d85-b328-a035b7bcd165"
/>

### Light mode

<img width="5120" height="2650" alt="image"
src="https://github.com/user-attachments/assets/3531c952-a801-43a5-8ef3-68c160fb85b8"
/>


## Review focus areas

1. **`src/styles/main.css`** — Bulk of the CSS variable conversion (~12K
lines). Check that `var()` references and `[data-theme="light"]`
overrides look correct.
2. **`src/utils/theme-manager.ts`** — New module. Simple but critical:
localStorage read/write, event dispatch, FOUC prevention.
3. **`src/utils/theme-colors.ts`** — `getCSSColor()` cache utility.
Verify cache invalidation on theme change is correct.
4. **`src/components/DeckGLMap.ts`** — Basemap tile swap logic and
`getOverlayColors()` per-theme adjustments.
5. **`index.html` / `settings.html`** — Inline FOUC prevention scripts.
CSP updated with `unsafe-inline` for script-src.
6. **`src/App.ts`** — Theme toggle UI wiring in settings modal. Check
event listener patterns.

## What NOT to worry about

- ~99 remaining hardcoded colors are documented acceptable exclusions
(canvas drawing, console.log, deprecated constants with migration paths,
category identifier colors)
- Dark mode is visually identical to before — no regressions

## Test plan

- [x] Run `npm run build` — builds without errors for both variants
- [x] Open app — dark mode loads by default, no FOUC
- [x] Go to Settings → Appearance → select Light — all panels, header,
sidebar switch smoothly
- [x] Verify map switches from dark CARTO to light Voyager tiles (no
blank flash)
- [x] Refresh page — light mode persists, no FOUC
- [x] Switch back to dark — everything returns to original look
- [x] Check semantic colors (threat dots, DEFCON badges, LIVE
indicators) identical in both themes
- [x] Open DevTools → inspect text contrast in light mode (should be
≥4.5:1)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-16 22:56:03 +04:00
Elie Habib
d94dc32d3b fix: use darken-* variables for dark overlay backgrounds
overlay-heavy is rgba(255,255,255,0.2) in dark mode (lightening tint),
but 11 places originally used rgba(0,0,0,x) (darkening tint). This
caused visible regressions in dark mode (channel bar, CII cards, etc).

Adds --darken-light/medium/heavy CSS variables that stay black-tinted
in both themes, and applies them to the affected selectors.
2026-02-16 22:49:54 +04:00
Sebastien Melki
346b974ef6 fix: darken neon semantic colors for light mode readability
Add light-mode overrides for 12 semantic CSS variables that had
terrible contrast on light backgrounds (as low as 1.25:1 for #44ff88).
Uses Tailwind's light-friendly palette (green-600/700, amber-600,
orange-600/700, yellow-600, sky-600).

Also darken DeckGL overlay marker colors (startup hub, accelerator,
nuclear, datacenter) and their legend SVGs in light mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 18:03:04 +02:00
Sebastien Melki
297e9cf218 chore: remove .planning files from git tracking
These are local development/planning files that should be gitignored.
Already covered by .gitignore entries for .planning/ and .idea/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
db5eff4300 feat(04-01): add no-transition class lifecycle for FOUC prevention
- index.html and settings.html FOUC scripts add no-transition class to <html>
- src/main.ts removes no-transition after first paint via requestAnimationFrame
- src/settings-main.ts removes no-transition after first paint via requestAnimationFrame
- Prevents transition sweep from dark-to-light on page load while enabling smooth theme toggles

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
78e0478228 feat(04-01): add theme transition CSS rules and fix text-muted contrast
- Add wildcard 200ms ease transition on background-color, color, border-color, box-shadow
- Add .no-transition suppression rule with !important for FOUC prevention
- Add canvas/maplibregl/deck-canvas transition exclusion to prevent rendering artifacts
- Fix --text-muted in light theme from #8a8a8a to #767676 (WCAG AA 4.54:1 vs #f8f9fa)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
d450ef0f4c docs(03-01): complete DeckGL basemap and overlay theming plan
- Create 03-01-SUMMARY.md with execution results
- Update STATE.md with Phase 3 completion, metrics, and decisions
2026-02-16 17:17:30 +02:00
Sebastien Melki
fa9b361754 feat(03-01): make Deck.GL overlay layer colors theme-aware
- Replace static COLORS constant with getOverlayColors() function
- Refresh COLORS at top of buildLayers() on each render cycle
- Conflict zone fills more transparent in light mode (alpha 60 vs 100)
- Conflict zone line color reduced alpha in light mode (120 vs 180)
- Displacement arc colors deeper/more saturated on light backgrounds
- Threat dots remain identical in both modes (user locked decision)
- Infrastructure markers unchanged (semantic category colors)
2026-02-16 17:17:30 +02:00
Sebastien Melki
4e623cd5cb feat(03-02): update Map light theme CSS and add theme-change re-render
- Update --map-country to warm cream (#f0e8d8) for Voyager-style land
- Update --map-stroke to warm border (#c8b8a8) complementing cream land
- Subtler blue grid (#b0c8d8) for light mode
- Add theme-changed event listener in Map.ts resetting baseRendered flag
- Dark theme map values unchanged

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
72851b9936 feat(03-02): convert CountryTimeline hardcoded colors to theme-aware getCSSColor()
- Replace 8+ hardcoded rgba/hex colors with getCSSColor() CSS variable reads
- Convert tooltip, grid, axes, now-marker, empty labels, event circles
- Add theme-changed event listener for automatic re-render on theme toggle
- Keep semantic LANE_COLORS (protest/conflict/natural/military) unchanged

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
120bfa5c72 feat(02-02): add CSS styles for theme toggle section in settings modal
- Add .theme-toggle-section with border-bottom separator
- Add .modal .section-label for APPEARANCE/PANELS headings (scoped to modal)
- Add .theme-toggle-group flex layout with gap
- Add .theme-option radio button labels with hover/active states
- Hide radio inputs, use :has(input:checked) for active state
- Override .section-label padding inside .theme-toggle-section to avoid double-padding

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
d77ef6c4cb feat(02-02): add theme toggle UI and event wiring in App.ts
- Import setTheme/getCurrentTheme from ThemeManager
- Add APPEARANCE section with Dark/Light radio buttons to settings modal
- Wire theme toggle change listener calling setTheme()
- Add theme-changed listener to re-render map on theme switch
- Rename modal title from 'Panel Settings' to 'Settings'

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
eb8a4dcc87 docs(02-01): complete ThemeManager module plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
14f7d856cd feat(02-01): add FOUC prevention scripts and wire entry points
- Add inline FOUC prevention script to index.html and settings.html <head>
- Update CSP script-src to allow 'unsafe-inline' for FOUC prevention
- Import and call applyStoredTheme() in src/main.ts before App init
- Import and call applyStoredTheme() in src/settings-main.ts before loadDesktopSecrets

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
3e3576ee7f feat(02-01): create ThemeManager module and barrel exports
- Add src/utils/theme-manager.ts with getStoredTheme, getCurrentTheme, setTheme, applyStoredTheme
- Export Theme type and all 4 functions from src/utils/index.ts barrel
- setTheme invalidates color cache, updates meta theme-color, dispatches theme-changed event
- applyStoredTheme is a lightweight pre-mount theme applicator (no events/cache invalidation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:17:30 +02:00
Sebastien Melki
fdd23888bd Merge branch 'main' into light_mode 2026-02-16 17:10:49 +02:00
Rau1CS
7a734db5b8 fix: add finance types to PopupData union and auto-create variant panels
- Add StockExchangePopupData, FinancialCenterPopupData, CentralBankPopupData,
  CommodityHubPopupData to PopupData.data union, removing unsafe double casts
  (as unknown as) in MapPopup.ts
- Dynamically create NewsPanel instances for any FEEDS category that doesn't
  already have a hardcoded panel, so finance-specific categories (forex, bonds,
  centralbanks, derivatives, fintech, regulation, institutional, analysis, etc.)
  get their own dedicated panels instead of being silently dropped

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 11:56:44 +01:00
Rau1CS
67788bf886 fix: dynamically enumerate FEEDS categories in loadNews()
Replace hardcoded feed category list with Object.entries(FEEDS) so that
variant-specific feed categories (e.g. finance variant's markets, forex,
bonds, commodities, crypto, etc.) are automatically discovered and loaded
instead of being silently skipped.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 11:40:29 +01:00
Claude
01fb23df5c feat: add finance/trading variant with market-focused dashboard
Add a new 'finance' site variant (finance.worldmonitor.app) following the
same pattern as the existing tech variant. Includes:

- Finance-specific RSS feeds: markets, forex, bonds, commodities, crypto,
  central banks, economic data, IPOs/M&A, derivatives, fintech, regulation,
  institutional investors, and market analysis (all free/open RSS sources)
- Finance-focused panels with trading-themed labels (Market Headlines,
  Live Markets, Forex & Currencies, Fixed Income, etc.)
- Geographic data for stock exchanges (30+), financial centers (20+),
  central banks (14), and commodity hubs (10) worldwide
- Four new map layers: stockExchanges, financialCenters, centralBanks,
  commodityHubs with tier-based icons and zoom-dependent labels
- Map popup rendering for all finance marker types
- Variant switcher updated with FINANCE tab in header
- Search modal with finance-specific sources and icons
- Vite HTML variant plugin metadata for SEO
- Build scripts (dev:finance, build:finance, test:e2e:finance)
- Tauri desktop config for Finance Monitor app

https://claude.ai/code/session_01CCmkws2EYuUHjYDonzXEtY
2026-02-16 11:22:17 +01:00
Sebastien Melki
b44790bf9f docs(01-04): complete dynamic inline style color conversion plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 11:20:51 +02:00