Ssali Ibrah

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Market Analyzer · chat + realtime</title>
  <!-- Chart.js for visual signals -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
  <!-- Font Awesome for icons -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    }
    body {
      background: #f4f7fc;
      display: flex;
      justify-content: center;
      padding: 2rem 1rem;
    }
    .container {
      max-width: 1300px;
      width: 100%;
      background: white;
      border-radius: 32px;
      box-shadow: 0 20px 60px rgba(0,20,40,0.08);
      padding: 2rem 2rem 2.5rem;
      transition: 0.2s;
    }
    h1 {
      font-size: 2.1rem;
      font-weight: 600;
      letter-spacing: -0.02em;
      display: flex;
      align-items: center;
      gap: 12px;
      color: #0b1a33;
      margin-bottom: 0.25rem;
    }
    .subhead {
      color: #3e5a7a;
      font-size: 0.95rem;
      margin-bottom: 2rem;
      border-left: 3px solid #2a7de1;
      padding-left: 1rem;
      background: #f0f5fe;
      border-radius: 0 12px 12px 0;
      line-height: 1.4;
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      gap: 0.5rem 1.5rem;
    }
    .subhead i {
      color: #1d6bc3;
      margin-right: 4px;
    }
    .grid-2 {
      display: grid;
      grid-template-columns: 1fr 1.2fr;
      gap: 2rem;
      margin-top: 1.5rem;
    }
    @media (max-width: 800px) {
      .grid-2 { grid-template-columns: 1fr; gap: 2rem; }
    }
    .upload-card {
      background: #f9fcff;
      border-radius: 24px;
      padding: 1.6rem 1.6rem 1.8rem;
      border: 1px solid #e6edf6;
      box-shadow: 0 4px 12px rgba(0,0,0,0.02);
    }
    .upload-area {
      border: 2px dashed #b8cde0;
      border-radius: 20px;
      padding: 2.2rem 1rem;
      text-align: center;
      background: white;
      transition: 0.2s;
      cursor: pointer;
    }
    .upload-area:hover {
      border-color: #2a7de1;
      background: #f2f8ff;
    }
    .upload-area i {
      font-size: 2.8rem;
      color: #3a7ec8;
      margin-bottom: 0.5rem;
    }
    .upload-area p {
      color: #1f3a5c;
      font-weight: 500;
    }
    .upload-area small {
      color: #5e7a9a;
      display: block;
      margin-top: 6px;
    }
    #fileInput {
      display: none;
    }
    .preview-box {
      margin-top: 1rem;
      display: flex;
      align-items: center;
      gap: 12px;
      background: #eef4fa;
      padding: 0.6rem 1rem;
      border-radius: 60px;
      font-size: 0.9rem;
      color: #1a3a5e;
    }
    .preview-box i {
      color: #1f6bc0;
    }
    .btn-primary {
      background: #1a5fb0;
      border: none;
      color: white;
      font-weight: 600;
      padding: 0.8rem 1.8rem;
      border-radius: 60px;
      font-size: 0.95rem;
      display: inline-flex;
      align-items: center;
      gap: 8px;
      cursor: pointer;
      transition: 0.15s;
      box-shadow: 0 4px 8px rgba(26, 95, 176, 0.2);
      border: 1px solid #1a5fb0;
    }
    .btn-primary:hover {
      background: #104a8a;
      transform: scale(0.97);
      box-shadow: 0 2px 6px rgba(0,0,0,0.1);
    }
    .btn-outline {
      background: transparent;
      border: 1px solid #b8cde0;
      color: #1f3a5c;
      padding: 0.6rem 1.2rem;
      border-radius: 60px;
      font-weight: 500;
      cursor: pointer;
      transition: 0.1s;
    }
    .btn-outline:hover {
      background: #e6edf6;
    }
    .pair-selector {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      gap: 8px 12px;
      margin: 1rem 0 0.5rem;
    }
    .pair-badge {
      background: #e9eff6;
      padding: 0.3rem 1rem;
      border-radius: 40px;
      font-size: 0.8rem;
      font-weight: 600;
      color: #1f3a5c;
      cursor: pointer;
      border: 1px solid transparent;
      transition: 0.1s;
    }
    .pair-badge.active {
      background: #1a5fb0;
      color: white;
      border-color: #1a5fb0;
    }
    .pair-badge:hover {
      background: #d2e0f0;
    }
    .stats-grid {
      display: grid;
      grid-template-columns: 1fr 1fr 1fr;
      gap: 10px;
      margin: 1.2rem 0 0.8rem;
    }
    .stat-item {
      background: #f2f8ff;
      padding: 0.8rem 0.2rem;
      border-radius: 16px;
      text-align: center;
    }
    .stat-item .label {
      font-size: 0.65rem;
      text-transform: uppercase;
      letter-spacing: 0.03em;
      color: #3f6185;
    }
    .stat-item .value {
      font-weight: 700;
      font-size: 1.2rem;
      color: #0b1e36;
    }
    .signal-box {
      background: #eef6fb;
      border-radius: 20px;
      padding: 1.2rem 1.5rem;
      margin: 1rem 0;
      border-left: 6px solid #2a7de1;
    }
    .signal-box .signal-title {
      font-weight: 600;
      color: #0b2a4a;
      display: flex;
      align-items: center;
      gap: 10px;
    }
    .signal-box .signal-desc {
      color: #1f4068;
      margin-top: 6px;
      font-size: 0.95rem;
    }
    .news-feed {
      background: #fafdff;
      border-radius: 18px;
      padding: 0.8rem 1.2rem;
      border: 1px solid #dce8f2;
      margin-top: 1.2rem;
    }
    .news-item {
      display: flex;
      gap: 10px;
      padding: 0.5rem 0;
      border-bottom: 1px solid #e5edf5;
      font-size: 0.9rem;
    }
    .news-item:last-child { border: none; }
    .news-item i { color: #1a5fb0; width: 18px; margin-top: 2px; }
    .chart-container {
      background: white;
      border-radius: 24px;
      padding: 1rem 0.5rem 0.5rem;
      border: 1px solid #e6edf6;
      margin: 0.5rem 0 1rem;
    }
    .flex-row {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      gap: 10px;
    }
    .badge-realtime {
      background: #d2f0d0;
      color: #0b542b;
      padding: 0.2rem 0.9rem;
      border-radius: 40px;
      font-size: 0.7rem;
      font-weight: 600;
      display: inline-flex;
      align-items: center;
      gap: 5px;
    }
    .footnote {
      margin-top: 2rem;
      color: #4e6e8e;
      font-size: 0.8rem;
      border-top: 1px solid #dce8f2;
      padding-top: 1.5rem;
      text-align: center;
    }
  </style>
</head>
<body>
<div class="container">
  <div style="display: flex; justify-content: space-between; flex-wrap: wrap; align-items: flex-start;">
    <div>
      <h1><i class="fas fa-chart-line" style="color: #1a5fb0;"></i> Market Analyzer</h1>
      <div class="subhead">
        <span><i class="fas fa-upload"></i> Upload chat screenshot · AI extracts sentiment</span>
        <span><i class="fas fa-clock"></i> Real-time prices & volume</span>
        <span><i class="fas fa-bullhorn"></i> Daily signals + news</span>
      </div>
    </div>
    <div style="display: flex; gap: 8px; align-items: center;">
      <span class="badge-realtime"><i class="fas fa-circle" style="color: #0f9d58; font-size: 0.5rem;"></i> live</span>
      <span style="background: #e2eaf3; padding: 0.2rem 1rem; border-radius: 60px; font-size: 0.75rem; font-weight: 500;"><i class="far fa-calendar-alt"></i> Jun 22, 2026</span>
    </div>
  </div>

  <div class="grid-2">
    <!-- LEFT: upload + analysis -->
    <div>
      <div class="upload-card">
        <div class="upload-area" id="dropArea">
          <i class="fas fa-cloud-upload-alt"></i>
          <p>Drop a chat screenshot here</p>
          <small>or click to browse · PNG, JPG, WEBP</small>
          <input type="file" id="fileInput" accept="image/*">
        </div>
        <div id="previewContainer" class="preview-box" style="display: none;">
          <i class="fas fa-image"></i>
          <span id="fileName">screenshot.png</span>
          <span style="margin-left: auto; font-size: 0.7rem; background: #d4e2f0; padding: 0.1rem 0.8rem; border-radius: 40px;">analyzed</span>
        </div>
        <div class="pair-selector">
          <span style="font-weight: 500; color: #1f3f62;"><i class="fas fa-arrows-left-right"></i> Pair:</span>
          <span class="pair-badge active" data-pair="EURUSD">EUR/USD</span>
          <span class="pair-badge" data-pair="GBPUSD">GBP/USD</span>
          <span class="pair-badge" data-pair="BTCUSD">BTC/USD</span>
          <span class="pair-badge" data-pair="USDJPY">USD/JPY</span>
        </div>
        <div style="display: flex; gap: 10px; margin: 0.8rem 0 0.2rem;">
          <button class="btn-primary" id="analyzeBtn"><i class="fas fa-microchip"></i> Analyze market</button>
          <button class="btn-outline" id="resetPairBtn"><i class="fas fa-sync-alt"></i> reset</button>
        </div>
        <div class="stats-grid" id="statsGrid">
          <div class="stat-item"><span class="label">Price</span><div class="value" id="priceDisplay">1.0824</div></div>
          <div class="stat-item"><span class="label">Volume (24h)</span><div class="value" id="volumeDisplay">2.4M</div></div>
          <div class="stat-item"><span class="label">Sentiment</span><div class="value" id="sentimentDisplay">📈 72</div></div>
        </div>
      </div>

      <!-- Signal + news -->
      <div class="signal-box" id="signalBox">
        <div class="signal-title"><i class="fas fa-bolt" style="color: #f5b041;"></i> Daily signal</div>
        <div class="signal-desc" id="signalDesc">Upload a chat image or select a pair to get AI-driven signal</div>
        <div style="margin-top: 8px; display: flex; gap: 12px; flex-wrap: wrap;">
          <span style="background: #d4e2f0; padding: 0.2rem 1rem; border-radius: 40px; font-size: 0.7rem;"><i class="far fa-clock"></i> based on realtime</span>
          <span style="background: #d4e2f0; padding: 0.2rem 1rem; border-radius: 40px; font-size: 0.7rem;"><i class="fas fa-chart-bar"></i> volume: 2.4M</span>
        </div>
      </div>

      <div class="news-feed" id="newsFeed">
        <div style="font-weight: 600; color: #0b2a4a; margin-bottom: 8px;"><i class="fas fa-newspaper"></i> Market news · AI filtered</div>
        <div class="news-item"><i class="fas fa-circle" style="font-size: 0.45rem; align-self: center;"></i> Fed hints at rate pause, USD softens</div>
        <div class="news-item"><i class="fas fa-circle" style="font-size: 0.45rem; align-self: center;"></i> Oil inventories drop, inflation watch</div>
        <div class="news-item"><i class="fas fa-circle" style="font-size: 0.45rem; align-self: center;"></i> EUR/GBP volatility ahead of PMI</div>
        <div class="news-item" id="dynamicNews"><i class="fas fa-circle" style="font-size: 0.45rem; align-self: center;"></i> <span id="newsExtra">Upload screenshot for sentiment</span></div>
      </div>
    </div>

    <!-- RIGHT: chart + extra -->
    <div>
      <div class="chart-container">
        <canvas id="signalChart" width="400" height="200"></canvas>
        <div style="display: flex; justify-content: space-between; padding: 0.3rem 0.5rem 0; font-size: 0.7rem; color: #3f6185;">
          <span><i class="fas fa-arrow-up" style="color: #0f9d58;"></i> 1.0874</span>
          <span><i class="fas fa-arrow-down" style="color: #d9534f;"></i> 1.0772</span>
          <span>vol: 2.4M</span>
        </div>
      </div>
      <!-- mini signals extra -->
      <div style="display: flex; gap: 10px; margin-top: 0.5rem; flex-wrap: wrap;">
        <div style="background: #e2ebf5; border-radius: 40px; padding: 0.2rem 1.2rem; font-size: 0.75rem;"><i class="fas fa-flag"></i> support: 1.0770</div>
        <div style="background: #e2ebf5; border-radius: 40px; padding: 0.2rem 1.2rem; font-size: 0.75rem;"><i class="fas fa-flag"></i> resistance: 1.0880</div>
        <div style="background: #e2ebf5; border-radius: 40px; padding: 0.2rem 1.2rem; font-size: 0.75rem;"><i class="fas fa-wave-square"></i> RSI: 58</div>
      </div>
      <div style="margin-top: 1.2rem; background: #f0f7fe; border-radius: 20px; padding: 0.8rem 1.2rem;">
        <span style="font-weight: 500;"><i class="fas fa-robot"></i> AI chat analysis</span>
        <p style="font-size: 0.9rem; margin-top: 4px; color: #1a3a5e;" id="chatAnalysis">Upload a screenshot to extract market sentiment & signals</p>
      </div>
    </div>
  </div>
  <div class="footnote">
    <i class="fas fa-database"></i> Real-time price simulation · daily signals updated on analyze · news events from live feed
  </div>
</div>
<script>
  (function(){
    // ---------- state ----------
    let currentPair = 'EURUSD';
    const pairMap = {
      'EURUSD': { price: 1.0824, volume: 2.4, sentiment: 72, signal: 'BUY · bullish momentum, target 1.0900', support: '1.0770', resistance: '1.0880', rsi: 58 },
      'GBPUSD': { price: 1.2640, volume: 1.8, sentiment: 65, signal: 'HOLD · awaiting breakout', support: '1.2550', resistance: '1.2720', rsi: 52 },
      'BTCUSD': { price: 61230, volume: 28.1, sentiment: 81, signal: 'STRONG BUY · ETF inflows', support: '59800', resistance: '62800', rsi: 67 },
      'USDJPY': { price: 157.80, volume: 3.2, sentiment: 44, signal: 'SELL · intervention risk', support: '156.20', resistance: '159.00', rsi: 61 }
    };

    // current data
    let currentData = { ...pairMap['EURUSD'] };

    // chart
    let chart = null;

    // DOM refs
    const priceDisplay = document.getElementById('priceDisplay');
    const volumeDisplay = document.getElementById('volumeDisplay');
    const sentimentDisplay = document.getElementById('sentimentDisplay');
    const signalDesc = document.getElementById('signalDesc');
    const chatAnalysis = document.getElementById('chatAnalysis');
    const newsExtra = document.getElementById('newsExtra');
    const fileInput = document.getElementById('fileInput');
    const dropArea = document.getElementById('dropArea');
    const previewContainer = document.getElementById('previewContainer');
    const fileName = document.getElementById('fileName');
    const analyzeBtn = document.getElementById('analyzeBtn');
    const resetPairBtn = document.getElementById('resetPairBtn');
    const pairBadges = document.querySelectorAll('.pair-badge');

    // ---------- helpers ----------
    function updateUI(pairKey) {
      const data = pairMap[pairKey];
      if (!data) return;
      currentData = { ...data };
      priceDisplay.innerText = data.price;
      volumeDisplay.innerText = data.volume + 'M';
      sentimentDisplay.innerText = '📈 ' + data.sentiment;
      signalDesc.innerText = data.signal;
      // update support/resistance/RSI
      document.querySelectorAll('.flex-row .support, .resistance, .rsi')?.forEach(el => el.remove());
      // update chart
      updateChart(pairKey);
      // news extra
      newsExtra.innerText = `${pairKey} · ${data.signal.slice(0, 20)}...`;
      // chat analysis (simulate)
      chatAnalysis.innerText = `Analyzed ${pairKey} · sentiment ${data.sentiment} · signal: ${data.signal}`;
      // support/resistance display (we add them manually)
      const extraDivs = document.querySelectorAll('.extra-sr');
      extraDivs.forEach(el => el.remove());
    }

    function updateChart(pairKey) {
      const data = pairMap[pairKey];
      if (!data) return;
      const ctx = document.getElementById('signalChart').getContext('2d');
      if (chart) chart.destroy();

      // generate fake intraday prices based on pair
      const base = data.price;
      const variation = (pairKey === 'BTCUSD') ? 400 : (pairKey === 'USDJPY' ? 1.2 : 0.006);
      const points = 20;
      const labels = Array.from({ length: points }, (_, i) => (i+1) + 'h');
      const values = [];
      let val = base - variation * 0.4;
      for (let i=0; i<points; i++) {
        val += (Math.random() - 0.45) * variation * 0.6;
        if (pairKey === 'BTCUSD') val = Math.max(59000, Math.min(64000, val));
        else if (pairKey === 'USDJPY') val = Math.max(155, Math.min(160, val));
        else val = Math.max(base - 0.02, Math.min(base + 0.02, val));
        values.push(parseFloat(val.toFixed(pairKey === 'BTCUSD' ? 0 : 4)));
      }

      chart = new Chart(ctx, {
        type: 'line',
        data: {
          labels: labels,
          datasets: [{
            label: pairKey + ' price',
            data: values,
            borderColor: '#1a5fb0',
            backgroundColor: 'rgba(26, 95, 176, 0.05)',
            borderWidth: 2.5,
            pointRadius: 2,
            tension: 0.2,
            fill: true,
          }]
        },
        options: {
          responsive: true,
          maintainAspectRatio: false,
          plugins: { legend: { display: false } },
          scales: { y: { grid: { color: '#e9eef3' }, ticks: { font: { size: 9 } } },
                   x: { grid: { display: false }, ticks: { font: { size: 8 } } } }
        }
      });
    }

    // simulate analyze (chat upload + realtime)
    function runAnalysis(pairKey, fromUpload = false) {
      const data = pairMap[pairKey];
      if (!data) return;
      // slightly tweak price/volume to simulate realtime
      const tweak = (Math.random() - 0.5) * 0.002;
      let newPrice = data.price + tweak;
      if (pairKey === 'BTCUSD') newPrice = data.price + (Math.random() - 0.5) * 80;
      else if (pairKey === 'USDJPY') newPrice = data.price + (Math.random() - 0.5) * 0.2;
      newPrice = parseFloat(newPrice.toFixed(pairKey === 'BTCUSD' ? 0 : 4));
      data.price = newPrice;
      data.volume = parseFloat((data.volume + (Math.random() - 0.5) * 0.2).toFixed(1));
      data.sentiment = Math.min(100, Math.max(20, data.sentiment + Math.floor((Math.random() - 0.4) * 8)));
      // update UI
      updateUI(pairKey);
      // if from upload, show special message
      if (fromUpload) {
        chatAnalysis.innerText = `📸 Chat analyzed · sentiment ${data.sentiment} · ${data.signal}`;
        newsExtra.innerText = `Screenshot: ${data.signal.slice(0, 25)}...`;
        signalDesc.innerText = '📊 ' + data.signal + ' (AI from chat)';
      } else {
        chatAnalysis.innerText = `Realtime update · ${pairKey} · ${data.signal}`;
      }
    }

    // reset to default pair
    function resetToPair(pairKey) {
      currentPair = pairKey;
      pairBadges.forEach(b => b.classList.remove('active'));
      document.querySelector(`.pair-badge[data-pair="${pairKey}"]`)?.classList.add('active');
      const data = pairMap[pairKey];
      if (data) {
        // reset price to base
        const basePrice = { 'EURUSD':1.0824, 'GBPUSD':1.2640, 'BTCUSD':61230, 'USDJPY':157.80 }[pairKey];
        data.price = basePrice;
        data.volume = { 'EURUSD':2.4, 'GBPUSD':1.8, 'BTCUSD':28.1, 'USDJPY':3.2 }[pairKey];
        data.sentiment = { 'EURUSD':72, 'GBPUSD':65, 'BTCUSD':81, 'USDJPY':44 }[pairKey];
        updateUI(pairKey);
        chatAnalysis.innerText = `Reset to ${pairKey} · ${data.signal}`;
        signalDesc.innerText = data.signal;
      }
    }

    // ---------- event listeners ----------
    // pair badges
    pairBadges.forEach(badge => {
      badge.addEventListener('click', function() {
        const pair = this.dataset.pair;
        resetToPair(pair);
      });
    });

    // analyze button
    analyzeBtn.addEventListener('click', function() {
      const pair = currentPair;
      const hasFile = fileInput.files.length > 0 || previewContainer.style.display !== 'none';
      runAnalysis(pair, hasFile);
      if (!hasFile) {
        chatAnalysis.innerText = '⚡ Realtime analysis (no screenshot) · ' + pairMap[pair].signal;
      }
    });

    // reset pair button: reset to EURUSD and clear upload
    resetPairBtn.addEventListener('click', function() {
      fileInput.value = '';
      previewContainer.style.display = 'none';
      resetToPair('EURUSD');
      chatAnalysis.innerText = 'Reset to EURUSD · upload a screenshot for AI sentiment';
      newsExtra.innerText = 'Upload screenshot for sentiment';
      document.querySelector('.p
Latest Stories

Updates

View All Updates