diff --git a/Domains/Frontend/MiniProjects/Stock-Exchange/app.js b/Domains/Frontend/MiniProjects/Stock-Exchange/app.js
new file mode 100644
index 00000000..b14eec65
--- /dev/null
+++ b/Domains/Frontend/MiniProjects/Stock-Exchange/app.js
@@ -0,0 +1,520 @@
+/**
+ * FinFlow - Advanced Stock Analysis App
+ * JavaScript for Interactivity and Data Visualization
+ */
+
+// --- 1. MOCK DATA SETUP ---
+const MOCK_DATA = {
+ marketStatus: [
+ { name: "Nifty 50", value: "22,501.80", change: "+125.40", percent: "0.56%", isPositive: true },
+ { name: "Sensex", value: "74,085.99", change: "-88.20", percent: "0.12%", isPositive: false },
+ { name: "Bank Nifty", value: "48,510.15", change: "+410.30", percent: "0.85%", isPositive: true },
+ { name: "USD/INR", value: "83.45", change: "+0.02", percent: "0.02%", isPositive: false },
+ ],
+ watchlist: [
+ { symbol: "TCS", price: 3412.00, change: 0.70, chartData: [3400, 3405, 3412, 3410, 3415, 3420, 3412] },
+ { symbol: "RELIANCE", price: 2950.50, change: -1.25, chartData: [2980, 2975, 2960, 2955, 2950, 2948, 2950], isNegative: true },
+ { symbol: "HDFCBANK", price: 1530.20, change: 2.10, chartData: [1500, 1515, 1520, 1530, 1525, 1535, 1530] },
+ { symbol: "INFY", price: 1475.10, change: -0.55, chartData: [1480, 1478, 1475, 1470, 1472, 1476, 1475], isNegative: true },
+ ],
+ holdings: [
+ { symbol: "TCS", name: "Tata Consultancy Services", qty: 10, avgPrice: 3200.00, currentPrice: 3412.00, sector: "IT" },
+ { symbol: "SBIN", name: "State Bank of India", qty: 25, avgPrice: 700.00, currentPrice: 755.50, sector: "Finance" },
+ { symbol: "ASIANPAINT", name: "Asian Paints Ltd.", qty: 5, avgPrice: 3000.00, currentPrice: 2850.10, sector: "Chemicals" },
+ ],
+ movers: [
+ { symbol: "BAJFINANCE", change: 5.10, isPositive: true },
+ { symbol: "HCLTECH", change: 4.85, isPositive: true },
+ { symbol: "SUNPHARMA", change: 4.12, isPositive: true },
+ { symbol: "ULTRACEMCO", change: -3.55, isPositive: false },
+ { symbol: "ADANIPORTS", change: -3.20, isPositive: false },
+ { symbol: "TITAN", change: -2.90, isPositive: false },
+ ],
+ news: [
+ "RBI holds interest rates steady; forecasts strong economic growth.",
+ "Tata Motors stock surges 4% after robust Q4 earnings report.",
+ "Global chip shortage concerns ease, boosting IT sector outlook.",
+ "Crude oil prices drop, providing relief for airline and paint stocks.",
+ ],
+ tradeData: {
+ 'TCS': {
+ symbol: 'TCS', price: 3412.00, change: 0.70, open: 3400, high: 3445, low: 3380, volume: '2.4M',
+ candlestick: {
+ x: ['2025-01-01', '2025-01-02', '2025-01-03', '2025-01-06', '2025-01-07'],
+ open: [3400, 3420, 3410, 3435, 3450], high: [3425, 3440, 3430, 3460, 3470], low: [3380, 3400, 3400, 3430, 3440], close: [3420, 3410, 3435, 3450, 3465]
+ },
+ indicators: { x: ['2025-01-01', '2025-01-02', '2025-01-03', '2025-01-06', '2025-01-07'], rsi: [65.2, 60.5, 68.9, 72.1, 75.0] }
+ },
+ 'RELIANCE': {
+ symbol: 'RELIANCE', price: 2950.50, change: -1.25, open: 2980, high: 2990, low: 2945, volume: '1.8M',
+ candlestick: {
+ x: ['2025-01-01', '2025-01-02', '2025-01-03', '2025-01-06', '2025-01-07'],
+ open: [2980, 2960, 2970, 2955, 2940], high: [2985, 2970, 2980, 2965, 2950], low: [2950, 2950, 2960, 2940, 2930], close: [2960, 2970, 2955, 2940, 2935]
+ },
+ indicators: { x: ['2025-01-01', '2025-01-02', '2025-01-03', '2025-01-06', '2025-01-07'], rsi: [45.2, 40.5, 38.9, 32.1, 28.0] }
+ }
+ }
+};
+
+// --- 2. GLOBAL STATE ---
+let currentState = {
+ activeScreen: 'dashboard',
+ selectedStock: 'TCS'
+};
+
+// --- 3. CORE FUNCTIONS ---
+
+/** Utility to format currency */
+const formatCurrency = (value) => {
+ return `₹${value.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
+};
+
+/** Switches the active screen and updates the bottom navigation. */
+function goTo(screenId, symbol = null) {
+ document.querySelectorAll('main > section').forEach(section => {
+ section.style.display = 'none';
+ });
+
+ const targetScreen = document.getElementById(`screen-${screenId}`);
+ if (targetScreen) {
+ targetScreen.style.display = 'block';
+ currentState.activeScreen = screenId;
+ }
+
+ document.querySelectorAll('.nav-item').forEach(item => {
+ item.classList.remove('active');
+ // Use a more robust check for the correct nav item
+ const onclickAttr = item.getAttribute('onclick');
+ if (onclickAttr && onclickAttr.includes(`goTo('${screenId}')`)) {
+ item.classList.add('active');
+ }
+ });
+
+ if (screenId === 'trade' && symbol) {
+ loadTradeScreen(symbol);
+ } else if (screenId === 'trade' && !symbol) {
+ loadTradeScreen(currentState.selectedStock);
+ } else if (screenId === 'portfolio') {
+ renderPortfolioCharts();
+ } else if (screenId === 'analytics') {
+ renderAnalyticsCharts();
+ }
+}
+
+// --- 4. RENDER FUNCTIONS (Dashboard) ---
+
+/** Renders the market status bar. */
+function renderMarketStatus() {
+ const container = document.getElementById('marketStatus');
+ container.innerHTML = MOCK_DATA.marketStatus.map(item => `
+
+ ${item.name}
+ ${item.value}
+
+ ${item.isPositive ? '▲' : '▼'} ${item.percent}
+
+
+ `).join('');
+}
+
+/** Renders the watchlist carousel. */
+function renderWatchlist() {
+ const container = document.getElementById('watchlist');
+ container.innerHTML = MOCK_DATA.watchlist.map(stock => {
+ const changeClass = stock.change > 0 ? 'positive' : 'negative';
+ const changeText = `${stock.change > 0 ? '+' : ''}${stock.change.toFixed(2)}%`;
+ const cardClass = stock.change > 0 ? '' : 'negative';
+
+ // Set a timeout to ensure the DOM elements are ready before plotting charts
+ setTimeout(() => plotMiniChart(stock.symbol, stock.chartData, stock.change > 0 ? 'var(--success)' : 'var(--danger)'), 0);
+
+ return `
+
+
${stock.symbol}
+
${formatCurrency(stock.price)}
+
${changeText}
+
+
+ `;
+ }).join('');
+}
+
+/** Plots a simple line mini-chart for a stock. */
+function plotMiniChart(symbol, data, color) {
+ const chartDiv = document.getElementById(`mini-chart-${symbol}`);
+ if (!chartDiv) return;
+
+ const trace = {
+ y: data,
+ mode: 'lines',
+ line: { color: color, width: 2 },
+ fill: 'tozeroy',
+ // Convert CSS variable to RGBA for Plotly fill color
+ fillcolor: color.replace(')', ', 0.2)').replace('var(', 'rgba('),
+ };
+
+ const layout = {
+ margin: { l: 0, r: 0, t: 0, b: 0 }, height: 30, width: 140,
+ xaxis: { showgrid: false, zeroline: false, showticklabels: false },
+ yaxis: { showgrid: false, zeroline: false, showticklabels: false },
+ paper_bgcolor: 'rgba(0,0,0,0)', plot_bgcolor: 'rgba(0,0,0,0)', hovermode: false
+ };
+
+ Plotly.newPlot(chartDiv, [trace], layout, { displayModeBar: false });
+}
+
+/** Renders top movers. */
+function renderMovers() {
+ const container = document.getElementById('movers');
+ container.innerHTML = MOCK_DATA.movers.slice(0, 3).map(mover => {
+ const changeClass = mover.isPositive ? 'positive' : 'negative';
+ const changeText = `${mover.isPositive ? '+' : ''}${mover.change.toFixed(2)}%`;
+ return `
+
+
${mover.symbol}
+
${changeText}
+
+ `;
+ }).join('');
+}
+
+/** Renders the market news list. */
+function renderNews() {
+ const container = document.getElementById('news');
+ container.innerHTML = MOCK_DATA.news.map(item => `
+
+ ${item}
+
+ `).join('');
+}
+
+/** Renders the dashboard performance chart (Line Chart). */
+function renderPerformanceChart() {
+ const chartDiv = document.getElementById('performanceChart');
+ const dates = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
+ const portfolioValue = [100000, 105000, 112000, 110500, 118000, 124832];
+ const benchmark = [100000, 102000, 108000, 109000, 115000, 120500];
+
+ const trace1 = { x: dates, y: portfolioValue, mode: 'lines', name: 'My Portfolio', line: { color: 'var(--primary)', width: 3 } };
+ const trace2 = { x: dates, y: benchmark, mode: 'lines', name: 'Benchmark (Nifty)', line: { color: 'var(--text-light)', dash: 'dash', width: 2 } };
+
+ const layout = {
+ margin: { l: 40, r: 10, t: 10, b: 40 }, xaxis: { showgrid: false, zeroline: false }, yaxis: { showgrid: true, zeroline: false },
+ showlegend: true, legend: { x: 0, y: 1.15, orientation: 'h' },
+ paper_bgcolor: 'var(--card)', plot_bgcolor: 'var(--card)', font: { family: 'Inter', color: 'var(--text)' }
+ };
+
+ Plotly.newPlot(chartDiv, [trace1, trace2], layout, { displayModeBar: false });
+}
+
+// --- 5. RENDER FUNCTIONS (Trade) ---
+
+/** Loads and renders the trade screen data for a specific stock. */
+function loadTradeScreen(symbol) {
+ currentState.selectedStock = symbol;
+ const stockData = MOCK_DATA.tradeData[symbol] || MOCK_DATA.tradeData['TCS'];
+ const isPositive = stockData.change > 0;
+ const changeClass = isPositive ? 'text-success' : 'text-danger';
+ const changeText = `${isPositive ? '+' : ''}${stockData.change.toFixed(2)}%`;
+
+ document.getElementById('tradeSymbol').textContent = stockData.symbol;
+ document.getElementById('tradePrice').innerHTML = `${formatCurrency(stockData.price)} ${changeText}`;
+
+ // Update stock details
+ document.querySelector('#screen-trade .stats-grid .stat-card:nth-child(1) .stat-value').textContent = formatCurrency(stockData.open);
+ document.querySelector('#screen-trade .stats-grid .stat-card:nth-child(2) .stat-value').textContent = formatCurrency(stockData.high);
+ document.querySelector('#screen-trade .stats-grid .stat-card:nth-child(3) .stat-value').textContent = formatCurrency(stockData.low);
+ document.querySelector('#screen-trade .stats-grid .stat-card:nth-child(4) .stat-value').textContent = stockData.volume;
+
+ changeTimeframe('1D'); // Render the default '1D' chart
+}
+
+/** Renders the Candlestick and Indicator charts. */
+function plotTradeCharts(data) {
+ const chartDiv = document.getElementById('chart1');
+ const indicatorsDiv = document.getElementById('indicatorsChart');
+
+ // 1. Candlestick Chart
+ const traceCandle = {
+ x: data.candlestick.x, open: data.candlestick.open, high: data.candlestick.high,
+ low: data.candlestick.low, close: data.candlestick.close, type: 'candlestick',
+ name: 'Price',
+ increasing: { line: { color: 'var(--success)' }, fillcolor: 'var(--success)' },
+ decreasing: { line: { color: 'var(--danger)' }, fillcolor: 'var(--danger)' }
+ };
+
+ const layoutCandle = {
+ margin: { l: 40, r: 10, t: 10, b: 20 }, height: 320,
+ xaxis: { showgrid: false, zeroline: false, rangeslider: { visible: false } }, yaxis: { showgrid: true, zeroline: false },
+ paper_bgcolor: 'var(--card)', plot_bgcolor: 'var(--card)', font: { family: 'Inter', color: 'var(--text)' }, hovermode: 'x unified',
+ };
+
+ Plotly.newPlot(chartDiv, [traceCandle], layoutCandle, { displayModeBar: false });
+
+ // 2. RSI Indicator Chart
+ const traceRSI = {
+ x: data.indicators.x, y: data.indicators.rsi, mode: 'lines', name: 'RSI (14)',
+ line: { color: 'var(--primary)', width: 2 },
+ };
+
+ const layoutRSI = {
+ margin: { l: 40, r: 10, t: 10, b: 40 }, height: 200,
+ xaxis: { showgrid: false, zeroline: false }, yaxis: { showgrid: true, zeroline: false, range: [20, 80], title: 'RSI' },
+ shapes: [
+ // Overbought line (70)
+ { type: 'line', xref: 'paper', yref: 'y', x0: 0, y0: 70, x1: 1, y1: 70, line: { color: 'var(--danger)', width: 1, dash: 'dot' } },
+ // Oversold line (30)
+ { type: 'line', xref: 'paper', yref: 'y', x0: 0, y0: 30, x1: 1, y1: 30, line: { color: 'var(--success)', width: 1, dash: 'dot' } }
+ ],
+ paper_bgcolor: 'var(--card)', plot_bgcolor: 'var(--card)', font: { family: 'Inter', color: 'var(--text)' }
+ };
+
+ Plotly.newPlot(indicatorsDiv, [traceRSI], layoutRSI, { displayModeBar: false });
+}
+
+
+/** Changes the active timeframe for the trade chart. */
+function changeTimeframe(timeframe) {
+ document.querySelectorAll('.chart-tab').forEach(tab => {
+ tab.classList.remove('active');
+ });
+ // Find the correct button using its text content or attribute
+ const activeTab = Array.from(document.querySelectorAll('.chart-tab')).find(tab => tab.textContent.trim() === timeframe);
+ if (activeTab) {
+ activeTab.classList.add('active');
+ }
+
+ const stockData = MOCK_DATA.tradeData[currentState.selectedStock] || MOCK_DATA.tradeData['TCS'];
+ plotTradeCharts(stockData); // Chart plotting uses the same mock data regardless of timeframe for this example
+}
+
+// --- 6. RENDER FUNCTIONS (Portfolio) ---
+
+/** Renders the list of user holdings. */
+function renderHoldings() {
+ const container = document.getElementById('holdings');
+ container.innerHTML = MOCK_DATA.holdings.map(holding => {
+ const value = holding.currentPrice * holding.qty;
+ const invested = holding.avgPrice * holding.qty;
+ const pnl = value - invested;
+ const pnlPercent = (pnl / invested) * 100;
+ const pnlClass = pnl > 0 ? 'text-success' : 'text-danger';
+ const pnlText = `${pnl > 0 ? '+' : ''}${formatCurrency(pnl)} (${pnlPercent.toFixed(2)}%)`;
+
+ return `
+
+
+
${holding.symbol} - ${holding.name}
+
${holding.qty} Shares @ ${formatCurrency(holding.avgPrice)}
+
+
+
${formatCurrency(value)}
+
${pnlText}
+
+
+ `;
+ }).join('');
+}
+
+/** Renders the Portfolio and Sector Allocation charts. */
+function renderPortfolioCharts() {
+ let totalPortfolioValue = 0;
+ const allocationData = MOCK_DATA.holdings.map(h => {
+ const value = h.currentPrice * h.qty;
+ totalPortfolioValue += value;
+ return { symbol: h.symbol, value, sector: h.sector };
+ });
+
+ // 1. Asset Allocation (Donut/Pie Chart)
+ const portfolioChartDiv = document.getElementById('portfolio-chart');
+ const assetLabels = allocationData.map(d => d.symbol);
+ const assetValues = allocationData.map(d => d.value);
+
+ const traceAsset = {
+ labels: assetLabels, values: assetValues, type: 'pie', hole: .4,
+ marker: { colors: ['#5367FF', '#00C48C', '#FF4B55', '#FFC107', '#9C27B0'] }
+ };
+
+ Plotly.newPlot(portfolioChartDiv, [traceAsset], {
+ margin: { t: 20, b: 20, l: 20, r: 20 }, showlegend: true, paper_bgcolor: 'var(--card)', font: { family: 'Inter', color: 'var(--text)' }
+ }, { displayModeBar: false });
+
+ // 2. Sector Distribution (Bar Chart)
+ const sectorChartDiv = document.getElementById('sector-chart');
+ const sectorMap = allocationData.reduce((acc, curr) => {
+ acc[curr.sector] = (acc[curr.sector] || 0) + curr.value;
+ return acc;
+ }, {});
+
+ const sectorLabels = Object.keys(sectorMap);
+ const sectorValues = Object.values(sectorMap);
+
+ const traceSector = { x: sectorLabels, y: sectorValues, type: 'bar', marker: { color: 'var(--primary)' } };
+
+ Plotly.newPlot(sectorChartDiv, [traceSector], {
+ margin: { t: 20, b: 40, l: 40, r: 10 }, xaxis: { automargin: true }, yaxis: { title: 'Value (₹)' },
+ paper_bgcolor: 'var(--card)', plot_bgcolor: 'var(--card)', font: { family: 'Inter', color: 'var(--text)' }
+ }, { displayModeBar: false });
+}
+
+// --- 7. RENDER FUNCTIONS (Analytics) ---
+
+/** Renders the Analytics screen charts. */
+function renderAnalyticsCharts() {
+ // 1. Portfolio Growth (Area Chart)
+ const growthChartDiv = document.getElementById('growthChart');
+ const dates = ['2024-01', '2024-03', '2024-05', '2024-07', '2024-09', '2024-11'];
+ const growthData = [95000, 105000, 115000, 110000, 120000, 124832];
+
+ const traceGrowth = {
+ x: dates, y: growthData, mode: 'lines', fill: 'tozeroy', name: 'Portfolio Value',
+ line: { color: 'var(--primary)', width: 2 }, fillcolor: 'rgba(83,103,255,0.2)',
+ hovertemplate: '%{x}
Value: %{y:$,.0f}'
+ };
+
+ Plotly.newPlot(growthChartDiv, [traceGrowth], {
+ margin: { l: 40, r: 10, t: 10, b: 40 }, height: 260,
+ xaxis: { showgrid: false, zeroline: false }, yaxis: { showgrid: true, zeroline: false, tickprefix: '₹' },
+ paper_bgcolor: 'var(--card)', plot_bgcolor: 'var(--card)', font: { family: 'Inter', color: 'var(--text)' }
+ }, { displayModeBar: false });
+
+ // 2. Monthly Returns (Bar Chart)
+ const returnsChartDiv = document.getElementById('returnsChart');
+ const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
+ const returns = [2.5, 4.1, -1.5, 0.8, 3.2, 1.1];
+
+ const traceReturns = {
+ x: months, y: returns, type: 'bar',
+ marker: { color: returns.map(r => r > 0 ? 'var(--success)' : 'var(--danger)') },
+ hovertemplate: '%{x}
Return: %{y:.2f}%'
+ };
+
+ Plotly.newPlot(returnsChartDiv, [traceReturns], {
+ margin: { l: 40, r: 10, t: 10, b: 40 }, height: 240,
+ xaxis: { automargin: true }, yaxis: { title: 'Return (%)' },
+ paper_bgcolor: 'var(--card)', plot_bgcolor: 'var(--card)', font: { family: 'Inter', color: 'var(--text)' }
+ }, { displayModeBar: false });
+
+ // 3. Risk Analysis (Bar Chart)
+ const riskChartDiv = document.getElementById('riskChart');
+ const riskMetrics = ['Volatility', 'Sharpe Ratio', 'Beta', 'Max Drawdown'];
+ const metricValues = [15.2, 1.25, 1.1, -8.5];
+
+ const traceRisk = {
+ x: riskMetrics, y: metricValues, type: 'bar', name: 'Risk Metrics',
+ marker: { color: ['var(--danger)', 'var(--success)', 'var(--danger)', 'var(--danger)'] }
+ };
+
+ Plotly.newPlot(riskChartDiv, [traceRisk], {
+ margin: { l: 40, r: 10, t: 10, b: 40 }, height: 240,
+ xaxis: { automargin: true }, yaxis: { title: 'Value' },
+ paper_bgcolor: 'var(--card)', plot_bgcolor: 'var(--card)', font: { family: 'Inter', color: 'var(--text)' }
+ }, { displayModeBar: false });
+}
+
+// --- 8. INTERACTIVE LOGIC (Modals & Actions) ---
+
+/** Shows the generic modal. */
+function showModal() {
+ document.getElementById('searchModal').classList.add('active');
+ document.getElementById('searchInput').focus();
+}
+
+/** Hides the generic modal. */
+function hideModal() {
+ document.getElementById('searchModal').classList.remove('active');
+ document.getElementById('searchInput').value = '';
+ document.getElementById('searchResults').innerHTML = '';
+}
+
+/** Simple stock search function. */
+function searchStocks() {
+ const input = document.getElementById('searchInput').value.toUpperCase();
+ const resultsDiv = document.getElementById('searchResults');
+ resultsDiv.innerHTML = '';
+
+ if (input.length < 2) return;
+
+ // Aggregate all unique symbols from mock data
+ const allSymbols = [
+ ...MOCK_DATA.watchlist, ...MOCK_DATA.holdings,
+ ...MOCK_DATA.movers.map(m => ({ symbol: m.symbol })),
+ ...Object.values(MOCK_DATA.tradeData)
+ ].filter((v, i, a) => a.findIndex(t => t.symbol === v.symbol) === i);
+
+ const filtered = allSymbols.filter(stock => stock.symbol.includes(input));
+
+ if (filtered.length === 0) {
+ resultsDiv.innerHTML = 'No results found.
';
+ return;
+ }
+
+ resultsDiv.innerHTML = filtered.map(stock => `
+
+
+
${stock.symbol}
+
${stock.name || 'Equity'}
+
+
+
+ `).join('');
+}
+
+/** Shows the Top Movers modal. */
+function showMoversModal() {
+ document.getElementById('moversModal').classList.add('active');
+ const container = document.getElementById('allMovers');
+ container.innerHTML = MOCK_DATA.movers.map(mover => {
+ const changeClass = mover.isPositive ? 'positive' : 'negative';
+ const changeText = `${mover.isPositive ? '+' : ''}${mover.change.toFixed(2)}%`;
+ return `
+
+
${mover.symbol}
+
${changeText}
+
+ `;
+ }).join('');
+}
+
+/** Hides the Top Movers modal. */
+function hideMoversModal() {
+ document.getElementById('moversModal').classList.remove('active');
+}
+
+/** Simulates placing a buy/sell order. */
+function place(type) {
+ const qtyInput = document.getElementById('qty');
+ const qty = qtyInput.value;
+ const symbol = currentState.selectedStock;
+
+ if (qty <= 0) {
+ alert('Please enter a valid quantity.');
+ return;
+ }
+
+ if (confirm(`Confirm ${type.toUpperCase()} ${qty} shares of ${symbol}?`)) {
+ alert(`${type.toUpperCase()} order placed successfully for ${qty} shares of ${symbol}!`);
+ qtyInput.value = 1;
+ }
+}
+
+
+// --- 9. INITIALIZATION ---
+
+/** Runs on page load to initialize the app. */
+function init() {
+ renderMarketStatus();
+ renderWatchlist();
+ renderPerformanceChart();
+ renderMovers();
+ renderNews();
+ renderHoldings();
+ loadTradeScreen('TCS'); // Load trade data initially for TCS
+ // Go to dashboard to ensure correct display, nav, and chart visibility
+ goTo('dashboard');
+}
+
+// Initial application load
+window.onload = init;
\ No newline at end of file
diff --git a/Domains/Frontend/MiniProjects/Stock-Exchange/index.html b/Domains/Frontend/MiniProjects/Stock-Exchange/index.html
new file mode 100644
index 00000000..c5ae5725
--- /dev/null
+++ b/Domains/Frontend/MiniProjects/Stock-Exchange/index.html
@@ -0,0 +1,256 @@
+
+
+
+
+
+FinFlow — Advanced Stock Analysis
+
+
+
+
+
+
+
+
+
+
+
+
Total Portfolio Value
+
₹1,24,832
+
+₹4,312 (3.5%) Today
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Technical Indicators
+
+
+
+
+
Place Order
+
+
+
+
+
+
+
+
+
+
+
+
+
Total Investment
+
₹1,20,520
+
Current: ₹1,24,832
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Domains/Frontend/MiniProjects/Stock-Exchange/style.css b/Domains/Frontend/MiniProjects/Stock-Exchange/style.css
new file mode 100644
index 00000000..d7e37107
--- /dev/null
+++ b/Domains/Frontend/MiniProjects/Stock-Exchange/style.css
@@ -0,0 +1,842 @@
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
+
+:root{
+ /* Fixed minor syntax issue: removed extra spaces after colons */
+ --primary: #5367FF;
+ --success: #00C48C;
+ --danger: #FF4B55;
+ --bg: #F7F9FC;
+ --card: #FFFFFF;
+ --text: #1F2937;
+ --text-light: #6B7280;
+ --border: #E5E7EB;
+ font-family: 'Inter', system-ui, sans-serif;
+}
+
+* { box-sizing: border-box; margin: 0; padding: 0; }
+
+html, body {
+ height: 100%;
+ background: var(--bg);
+ color: var(--text);
+}
+
+.app {
+ max-width: 428px;
+ margin: 0 auto;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ background: var(--bg);
+}
+
+header {
+ padding: 16px;
+ background: var(--card);
+ border-bottom: 1px solid var(--border);
+ position: sticky;
+ top: 0;
+ z-index: 100;
+}
+
+.header-top {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16px;
+}
+
+.brand {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.logo {
+ width: 40px;
+ height: 40px;
+ border-radius: 10px;
+ background: linear-gradient(135deg, var(--primary), #7C3AED);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-weight: 800;
+ color: #fff;
+ font-size: 16px;
+}
+
+.brand-text .title {
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--text);
+}
+
+.brand-text .subtitle {
+ font-size: 11px;
+ color: var(--text-light);
+}
+
+.header-actions {
+ display: flex;
+ gap: 12px;
+}
+
+.icon-btn {
+ width: 36px;
+ height: 36px;
+ border-radius: 8px;
+ background: var(--bg);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.2s;
+ font-size: 18px;
+ border: none;
+}
+
+.icon-btn:hover {
+ background: var(--border);
+ transform: scale(1.1);
+}
+
+.market-status {
+ display: flex;
+ gap: 12px;
+ overflow-x: auto;
+ padding: 8px 0;
+}
+
+.market-status::-webkit-scrollbar {
+ display: none;
+}
+
+.index-item {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 8px 12px;
+ background: var(--bg);
+ border-radius: 8px;
+ min-width: fit-content;
+ font-size: 13px;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.index-item:hover {
+ background: var(--card);
+ box-shadow: 0 2px 8px rgba(0,0,0,0.08);
+}
+
+.index-name {
+ color: var(--text-light);
+ font-weight: 600;
+}
+
+.index-value {
+ font-weight: 700;
+ color: var(--text);
+}
+
+.index-change {
+ font-size: 12px;
+ font-weight: 600;
+ padding: 2px 6px;
+ border-radius: 4px;
+}
+
+.index-change.positive {
+ color: var(--success);
+ background: #D1FAE5;
+}
+
+.index-change.negative {
+ color: var(--danger);
+ background: #FEE2E2;
+}
+
+main {
+ flex: 1;
+ padding: 16px 16px 80px;
+ overflow-y: auto;
+}
+
+.section {
+ margin-bottom: 20px;
+}
+
+.section-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+}
+
+.section-title {
+ font-size: 16px;
+ font-weight: 700;
+ color: var(--text);
+}
+
+.section-action {
+ font-size: 13px;
+ color: var(--primary);
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.2s;
+}
+
+.section-action:hover {
+ color: #7C3AED;
+}
+
+.card {
+ background: var(--card);
+ border-radius: 12px;
+ padding: 16px;
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
+ border: 1px solid var(--border);
+ transition: all 0.3s;
+}
+
+.card:hover {
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+}
+
+.portfolio-card {
+ background: linear-gradient(135deg, var(--primary), #7C3AED);
+ color: white;
+ padding: 20px;
+ margin-bottom: 16px;
+ cursor: pointer;
+ position: relative;
+ overflow: hidden;
+}
+
+.portfolio-card::before {
+ content: '';
+ position: absolute;
+ top: -50%;
+ right: -50%;
+ width: 200%;
+ height: 200%;
+ background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
+ animation: pulse 3s infinite;
+}
+
+@keyframes pulse {
+ 0%, 100% { transform: scale(1); opacity: 0.5; }
+ 50% { transform: scale(1.1); opacity: 0.8; }
+}
+
+.portfolio-value {
+ font-size: 11px;
+ opacity: 0.9;
+ margin-bottom: 4px;
+}
+
+.portfolio-amount {
+ font-size: 32px;
+ font-weight: 800;
+ margin-bottom: 8px;
+}
+
+.portfolio-change {
+ display: inline-block;
+ font-size: 14px;
+ font-weight: 600;
+ padding: 6px 12px;
+ background: rgba(255,255,255,0.2);
+ border-radius: 6px;
+}
+
+.watchlist {
+ display: flex;
+ gap: 12px;
+ overflow-x: auto;
+ padding: 4px 0;
+}
+
+.watchlist::-webkit-scrollbar {
+ display: none;
+}
+
+.stock-card {
+ min-width: 140px;
+ padding: 14px;
+ background: var(--card);
+ border: 1px solid var(--border);
+ border-radius: 10px;
+ cursor: pointer;
+ transition: all 0.3s;
+ position: relative;
+}
+
+.stock-card::after {
+ content: '';
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ height: 3px;
+ background: var(--success);
+ transform: scaleX(0);
+ transition: transform 0.3s;
+}
+
+.stock-card.negative::after {
+ background: var(--danger);
+}
+
+.stock-card:hover {
+ transform: translateY(-4px);
+ box-shadow: 0 8px 16px rgba(0,0,0,0.1);
+ border-color: var(--primary);
+}
+
+.stock-card:hover::after {
+ transform: scaleX(1);
+}
+
+.stock-symbol {
+ font-size: 14px;
+ font-weight: 700;
+ color: var(--text);
+ margin-bottom: 6px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.stock-price {
+ font-size: 16px;
+ font-weight: 700;
+ color: var(--text);
+ margin-bottom: 4px;
+}
+
+.stock-change {
+ font-size: 12px;
+ font-weight: 600;
+}
+
+.stock-change.positive {
+ color: var(--success);
+}
+
+.stock-change.negative {
+ color: var(--danger);
+}
+
+.mini-chart {
+ height: 30px;
+ margin-top: 8px;
+ opacity: 0.6;
+}
+
+.holdings-list {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.holding-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 14px;
+ background: var(--bg);
+ border-radius: 10px;
+ cursor: pointer;
+ transition: all 0.2s;
+ border: 2px solid transparent;
+}
+
+.holding-item:hover {
+ background: var(--card);
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+ border-color: var(--primary);
+ transform: translateX(4px);
+}
+
+.holding-info {
+ flex: 1;
+}
+
+.holding-name {
+ font-size: 14px;
+ font-weight: 600;
+ color: var(--text);
+ margin-bottom: 4px;
+}
+
+.holding-qty {
+ font-size: 12px;
+ color: var(--text-light);
+}
+
+.holding-values {
+ text-align: right;
+}
+
+.holding-value {
+ font-size: 14px;
+ font-weight: 700;
+ color: var(--text);
+ margin-bottom: 4px;
+}
+
+.holding-pnl {
+ font-size: 12px;
+ font-weight: 600;
+}
+
+.movers-grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: 10px;
+}
+
+.mover-card {
+ padding: 12px;
+ background: var(--bg);
+ border-radius: 8px;
+ text-align: center;
+ cursor: pointer;
+ transition: all 0.3s;
+ border: 2px solid transparent;
+}
+
+.mover-card:hover {
+ background: var(--card);
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+ transform: translateY(-2px) scale(1.05);
+ border-color: var(--primary);
+}
+
+.mover-symbol {
+ font-size: 12px;
+ font-weight: 700;
+ color: var(--text);
+ margin-bottom: 6px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.mover-change {
+ font-size: 16px;
+ font-weight: 700;
+}
+
+.chart-container {
+ background: var(--card);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 16px;
+ margin-bottom: 16px;
+}
+
+.chart-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+}
+
+.chart-symbol {
+ font-size: 18px;
+ font-weight: 700;
+}
+
+.chart-price {
+ font-size: 24px;
+ font-weight: 800;
+ margin: 8px 0;
+}
+
+.chart-tabs {
+ display: flex;
+ gap: 8px;
+ margin-bottom: 12px;
+ overflow-x: auto;
+}
+
+.chart-tabs::-webkit-scrollbar {
+ display: none;
+}
+
+.chart-tab {
+ padding: 6px 14px;
+ border-radius: 6px;
+ background: var(--bg);
+ font-size: 12px;
+ font-weight: 600;
+ color: var(--text-light);
+ cursor: pointer;
+ white-space: nowrap;
+ border: none;
+ transition: all 0.2s;
+}
+
+.chart-tab:hover {
+ background: var(--border);
+}
+
+.chart-tab.active {
+ background: var(--primary);
+ color: white;
+}
+
+.chart-wrap {
+ height: 320px;
+ border-radius: 8px;
+ overflow: hidden;
+}
+
+.order-section {
+ margin-top: 16px;
+}
+
+.qty-input {
+ width: 100%;
+ padding: 14px;
+ border: 2px solid var(--border);
+ border-radius: 8px;
+ font-size: 15px;
+ font-weight: 600;
+ margin-bottom: 12px;
+ background: var(--bg);
+ color: var(--text);
+ transition: all 0.2s;
+}
+
+.qty-input:focus {
+ outline: none;
+ border-color: var(--primary);
+ background: var(--card);
+ box-shadow: 0 0 0 4px rgba(83,103,255,0.1);
+}
+
+.order-buttons {
+ display: flex;
+ gap: 12px;
+}
+
+.order-btn {
+ flex: 1;
+ padding: 16px;
+ border: none;
+ border-radius: 8px;
+ font-size: 15px;
+ font-weight: 700;
+ cursor: pointer;
+ transition: all 0.3s;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ position: relative;
+ overflow: hidden;
+}
+
+.order-btn::before {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 0;
+ height: 0;
+ background: rgba(255,255,255,0.3);
+ border-radius: 50%;
+ transform: translate(-50%, -50%);
+ transition: width 0.6s, height 0.6s;
+}
+
+.order-btn:active::before {
+ width: 300px;
+ height: 300px;
+}
+
+.order-btn.buy {
+ background: var(--success);
+ color: white;
+}
+
+.order-btn.buy:hover {
+ background: #00B37E;
+ transform: translateY(-2px);
+ box-shadow: 0 6px 16px rgba(0,196,140,0.3);
+}
+
+.order-btn.sell {
+ background: var(--danger);
+ color: white;
+}
+
+.order-btn.sell:hover {
+ background: #E63946;
+ transform: translateY(-2px);
+ box-shadow: 0 6px 16px rgba(255,75,85,0.3);
+}
+
+.news-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.news-item {
+ padding: 12px;
+ background: var(--bg);
+ border-radius: 8px;
+ font-size: 13px;
+ line-height: 1.5;
+ color: var(--text);
+ cursor: pointer;
+ transition: all 0.3s;
+ border: 1px solid transparent;
+}
+
+.news-item:hover {
+ background: var(--card);
+ border-color: var(--primary);
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+ transform: translateX(4px);
+}
+
+.bottom-nav {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: var(--card);
+ border-top: 1px solid var(--border);
+ padding: 8px 16px 12px;
+ z-index: 100;
+ max-width: 428px;
+ margin: 0 auto;
+}
+
+.nav-items {
+ display: flex;
+ justify-content: space-around;
+}
+
+.nav-item {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+ padding: 8px;
+ cursor: pointer;
+ border-radius: 8px;
+ transition: all 0.3s;
+ position: relative;
+}
+
+.nav-item::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 40%;
+ height: 3px;
+ background: var(--primary);
+ border-radius: 0 0 3px 3px;
+ opacity: 0;
+ transition: all 0.3s;
+}
+
+.nav-item.active::before {
+ opacity: 1;
+}
+
+.nav-item:hover {
+ background: var(--bg);
+}
+
+.nav-icon {
+ font-size: 22px;
+ transition: transform 0.3s;
+}
+
+.nav-item:hover .nav-icon {
+ transform: scale(1.2);
+}
+
+.nav-label {
+ font-size: 11px;
+ font-weight: 600;
+ color: var(--text-light);
+ transition: color 0.3s;
+}
+
+.nav-item.active .nav-label {
+ color: var(--primary);
+}
+
+.quick-actions {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 12px;
+}
+
+.action-btn {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 6px;
+ padding: 14px 8px;
+ background: var(--bg);
+ border-radius: 10px;
+ cursor: pointer;
+ transition: all 0.3s;
+ border: none;
+ color: var(--text);
+}
+
+.action-btn:hover {
+ background: var(--card);
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+ transform: translateY(-2px);
+}
+
+.action-icon {
+ font-size: 24px;
+}
+
+.action-label {
+ font-size: 11px;
+ font-weight: 600;
+ text-align: center;
+}
+
+.fab {
+ position: fixed;
+ right: 20px;
+ bottom: 80px;
+ width: 56px;
+ height: 56px;
+ border-radius: 16px;
+ background: var(--primary);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: white;
+ font-size: 24px;
+ font-weight: 700;
+ cursor: pointer;
+ box-shadow: 0 4px 16px rgba(83,103,255,0.4);
+ z-index: 99;
+ transition: all 0.3s;
+}
+
+.fab:hover {
+ transform: scale(1.1) rotate(90deg);
+ box-shadow: 0 8px 24px rgba(83,103,255,0.6);
+}
+
+.stats-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 12px;
+ margin-top: 12px;
+}
+
+.stat-card {
+ padding: 12px;
+ background: var(--bg);
+ border-radius: 8px;
+ text-align: center;
+ transition: all 0.3s;
+}
+
+.stat-card:hover {
+ background: var(--card);
+ box-shadow: 0 4px 12px rgba(0,0,0,0.08);
+ transform: scale(1.05);
+}
+
+.stat-label {
+ font-size: 11px;
+ color: var(--text-light);
+ margin-bottom: 4px;
+}
+
+.stat-value {
+ font-size: 18px;
+ font-weight: 700;
+ color: var(--text);
+}
+
+.text-success { color: var(--success); }
+.text-danger { color: var(--danger); }
+.text-muted { color: var(--text-light); }
+
+::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+}
+
+::-webkit-scrollbar-track {
+ background: var(--bg);
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--border);
+ border-radius: 3px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--text-light);
+}
+
+.modal {
+ display: none;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0,0,0,0.5);
+ z-index: 1000;
+ align-items: center;
+ justify-content: center;
+}
+
+.modal.active {
+ display: flex;
+}
+
+.modal-content {
+ background: var(--card);
+ border-radius: 16px;
+ padding: 24px;
+ max-width: 360px;
+ width: 90%;
+ animation: slideUp 0.3s ease-out;
+}
+
+@keyframes slideUp {
+ from { transform: translateY(50px); opacity: 0; }
+ to { transform: translateY(0); opacity: 1; }
+}
+
+.modal-header {
+ font-size: 18px;
+ font-weight: 700;
+ margin-bottom: 16px;
+}
+
+.modal-close {
+ float: right;
+ font-size: 24px;
+ cursor: pointer;
+ color: var(--text-light);
+}
+
+.modal-close:hover {
+ color: var(--text);
+}
\ No newline at end of file