diff --git a/Projects/Startup Runway Calculator/README.md b/Projects/Startup Runway Calculator/README.md
new file mode 100644
index 00000000..e3545612
--- /dev/null
+++ b/Projects/Startup Runway Calculator/README.md
@@ -0,0 +1,29 @@
+# Startup Runway Calculator
+
+An advanced financial modeling dashboard for startups to compute cash runway lengths, track operating expenses (OpEx) by category, adjust monthly revenue growth rates, simulate hiring/cost events, and compare planning scenarios.
+
+## Core Features
+
+- **Granular Operating Expenses Tracker**: Itemize cash outlays across key startup operational pools:
+ * **Salaries & Payroll**: Core staff, contractors, benefits.
+ * **Marketing & Acquisition**: Ads, events, agency costs.
+ * **SaaS & Infrastructure**: Server hosting, software subscriptions.
+ * **Office & Overhead**: Rent, utilities, logistics.
+ * **Miscellaneous / Legal**: Fees, insurance, other administrative expenses.
+- **Runway & Net Burn Forecast**: Instantly evaluates how many months of operational cash remain based on current balances, monthly revenue, and monthly growth rate.
+- **Urgency Meter & Alive classification**:
+ * Classified as **Default Alive** (profitable or growing to profitability before depletion) or **Default Dead**.
+ * Dynamic visual status badges (Red for runway < 6 months, Amber for 6-12 months, Emerald for >12 months or Profitable).
+- **Interactive SVG Chart**: Dynamic line chart rendering cash balance decline or upward trajectory over the next 12-24 months.
+- **What-If Scenario Sandbox**: Quick adjustments for revenue growth rate inputs and immediate visualization of how scaling expenses affects cash lifecycle.
+- **Scenario Vault**: Save multiple plan configurations (e.g. "Worst Case", "Moderate Base", "Aggressive Growth Plan") in `localStorage`.
+
+## Run it
+
+Open `index.html` in any modern web browser.
+
+## Technical Details
+
+- **HTML5 & CSS3**: Glassmorphic dashboard templates, neon status indicators, and responsive flexboxes.
+- **Vanilla JavaScript**: Math systems calculating compound growth rates, zero cash dates, and generating dynamic coordinate matrices for responsive SVG chart lines.
+- **Storage**: JSON models mapped and loaded from `localStorage`.
diff --git a/Projects/Startup Runway Calculator/index.html b/Projects/Startup Runway Calculator/index.html
new file mode 100644
index 00000000..1722b417
--- /dev/null
+++ b/Projects/Startup Runway Calculator/index.html
@@ -0,0 +1,233 @@
+
+
+
+
+
+ Startup Runway Calculator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Runway Remaining
+ 0.0 mo
+ Evaluating...
+
+
+
+ Monthly Net Burn
+ $0
+ Revenues vs Expenses
+
+
+
+ Zero Cash Date
+ --/--
+ Estimated depletion
+
+
+
+ Core Status
+ ---
+ Profitability Index
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Month
+ Starting Cash
+ Revenue
+ OpEx
+ Net Burn
+ Ending Cash
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Projects/Startup Runway Calculator/project.json b/Projects/Startup Runway Calculator/project.json
new file mode 100644
index 00000000..4a235025
--- /dev/null
+++ b/Projects/Startup Runway Calculator/project.json
@@ -0,0 +1,17 @@
+{
+ "title": "Startup Runway Calculator",
+ "description": "An advanced financial planning dashboard for startups featuring runway forecasting, OpEx trackers, interactive growth projections, and scenario planning.",
+ "author": {
+ "name": "Sujal",
+ "github": "Sujal"
+ },
+ "tags": [
+ "finance",
+ "startup",
+ "calculator",
+ "vanilla-js",
+ "localstorage"
+ ],
+ "entry": "index.html",
+ "thumbnail": "thumbnail.svg"
+}
diff --git a/Projects/Startup Runway Calculator/script.js b/Projects/Startup Runway Calculator/script.js
new file mode 100644
index 00000000..bf419087
--- /dev/null
+++ b/Projects/Startup Runway Calculator/script.js
@@ -0,0 +1,787 @@
+// Startup Runway Calculator - Interaction Script
+
+// Predefined Scenario Snapshot Templates
+const DEFAULT_SCENARIOS = [
+ {
+ id: "sc-baseline",
+ name: "Current Baseline Plan",
+ cash: 500000,
+ revenue: 25000,
+ growth: 5,
+ payroll: 40000,
+ marketing: 8000,
+ saas: 3000,
+ rent: 4000,
+ misc: 2000
+ },
+ {
+ id: "sc-bootstrap",
+ name: "Bootstrapped Slow Burn",
+ cash: 250000,
+ revenue: 15000,
+ growth: 2,
+ payroll: 18000,
+ marketing: 2000,
+ saas: 1500,
+ rent: 1500,
+ misc: 1000
+ },
+ {
+ id: "sc-aggressive",
+ name: "Aggressive Growth Push",
+ cash: 800000,
+ revenue: 40000,
+ growth: 12,
+ payroll: 85000,
+ marketing: 25000,
+ saas: 8000,
+ rent: 8000,
+ misc: 5000
+ }
+];
+
+// App State
+let scenarios = [];
+let activeScenarioId = "sc-baseline";
+
+// Date configuration (Base date is June 2026)
+const BASE_YEAR = 2026;
+const BASE_MONTH = 5; // 0-indexed (June is 5)
+const MONTH_NAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
+
+// DOM Elements
+const txtCash = document.getElementById("txt-cash");
+const txtRevenue = document.getElementById("txt-revenue");
+const sliderGrowth = document.getElementById("slider-growth");
+const lblGrowthVal = document.getElementById("lbl-growth-val");
+
+const txtPayroll = document.getElementById("txt-payroll");
+const txtMarketing = document.getElementById("txt-marketing");
+const txtSaas = document.getElementById("txt-saas");
+const txtRent = document.getElementById("txt-rent");
+const txtMisc = document.getElementById("txt-misc");
+
+const lblHeaderStatus = document.getElementById("lbl-header-status");
+const lblRunway = document.getElementById("lbl-runway");
+const lblRunwayUrgency = document.getElementById("lbl-runway-urgency");
+const lblNetBurn = document.getElementById("lbl-net-burn");
+const lblZeroDate = document.getElementById("lbl-zero-date");
+const lblClassification = document.getElementById("lbl-classification");
+
+const forecastTableBody = document.getElementById("forecast-table-body");
+const svgElement = document.getElementById("projection-svg");
+const chartContainer = document.getElementById("chart-container");
+
+const txtScenarioName = document.getElementById("txt-scenario-name");
+const btnSaveScenario = document.getElementById("btn-save-scenario");
+const scenarioList = document.getElementById("scenario-list");
+const btnResetWorkspace = document.getElementById("btn-reset-workspace");
+const recommendationsFeed = document.getElementById("recommendations-feed");
+
+// CREATE TOOLTIP ELEMENT
+let tooltip = document.createElement("div");
+tooltip.className = "chart-tooltip";
+document.body.appendChild(tooltip);
+
+// INITIALIZATION
+window.addEventListener("DOMContentLoaded", () => {
+ loadScenarios();
+ setupEventListeners();
+ calculateAndRender();
+});
+
+// Load saved snapshots or seeds
+function loadScenarios() {
+ const stored = localStorage.getItem("runwaysync_scenarios");
+ if (stored) {
+ try {
+ scenarios = JSON.parse(stored);
+ } catch (e) {
+ console.error("Error parsing scenarios", e);
+ scenarios = [...DEFAULT_SCENARIOS];
+ }
+ } else {
+ scenarios = [...DEFAULT_SCENARIOS];
+ saveToStorage(false);
+ }
+}
+
+function saveToStorage(shouldUpdate = true) {
+ localStorage.setItem("runwaysync_scenarios", JSON.stringify(scenarios));
+ if (shouldUpdate) {
+ renderScenarioList();
+ }
+}
+
+// Event Listeners setup
+function setupEventListeners() {
+ const inputs = [txtCash, txtRevenue, txtPayroll, txtMarketing, txtSaas, txtRent, txtMisc];
+
+ inputs.forEach(input => {
+ input.addEventListener("input", () => {
+ activeScenarioId = null; // deselect saved scenario on modifications
+ updateActiveScenarioHighlight();
+ calculateAndRender();
+ });
+ });
+
+ sliderGrowth.addEventListener("input", () => {
+ lblGrowthVal.textContent = `${sliderGrowth.value}%`;
+ activeScenarioId = null;
+ updateActiveScenarioHighlight();
+ calculateAndRender();
+ });
+
+ // Scenario buttons
+ btnSaveScenario.addEventListener("click", saveCurrentScenario);
+ btnResetWorkspace.addEventListener("click", resetWorkspace);
+
+ // Resize window triggers chart updates
+ window.addEventListener("resize", renderChart);
+}
+
+// MAIN CALCULATOR ENGINE
+let monthlyData = [];
+
+function calculateAndRender() {
+ // 1. Read input values
+ const cash = Math.max(0, Number(txtCash.value) || 0);
+ const revenue = Math.max(0, Number(txtRevenue.value) || 0);
+ const growth = Number(sliderGrowth.value) || 0;
+
+ const payroll = Math.max(0, Number(txtPayroll.value) || 0);
+ const marketing = Math.max(0, Number(txtMarketing.value) || 0);
+ const saas = Math.max(0, Number(txtSaas.value) || 0);
+ const rent = Math.max(0, Number(txtRent.value) || 0);
+ const misc = Math.max(0, Number(txtMisc.value) || 0);
+
+ const totalOpEx = payroll + marketing + saas + rent + misc;
+
+ // 2. Perform 24-Month Forecast Projection
+ monthlyData = [];
+ let currentCash = cash;
+ let currentRevenue = revenue;
+ let hasDepleted = false;
+ let zeroCashMonthIndex = -1;
+
+ for (let m = 0; m <= 24; m++) {
+ // Rev growth compounds monthly (Month 0 is baseline starting metrics)
+ if (m > 0) {
+ currentRevenue = currentRevenue * (1 + growth / 100);
+ }
+
+ const netBurn = totalOpEx - currentRevenue;
+ const startingCash = currentCash;
+
+ if (currentCash > 0) {
+ currentCash = currentCash - netBurn;
+ if (currentCash <= 0) {
+ currentCash = 0;
+ if (!hasDepleted) {
+ hasDepleted = true;
+ zeroCashMonthIndex = m;
+ }
+ }
+ } else {
+ currentCash = 0;
+ }
+
+ monthlyData.push({
+ monthIndex: m,
+ monthName: getProjectedMonthName(m),
+ startingCash: startingCash,
+ revenue: currentRevenue,
+ opex: totalOpEx,
+ netBurn: netBurn,
+ endingCash: currentCash
+ });
+ }
+
+ // 3. Compute Runway length (Granular Months)
+ let runwayMonths = 0;
+ let isProfitable = false;
+ let isAlive = false;
+
+ // Evaluate if startup is already profitable or default alive
+ if (revenue >= totalOpEx && growth >= 0) {
+ isProfitable = true;
+ isAlive = true;
+ runwayMonths = Infinity;
+ } else {
+ // If not immediately profitable, simulate forward up to 120 months to find if growth saves them
+ let simCash = cash;
+ let simRev = revenue;
+ let simDepleted = false;
+ let simMonths = 0;
+
+ while (simMonths < 120) {
+ simMonths++;
+ simRev = simRev * (1 + growth / 100);
+ const simBurn = totalOpEx - simRev;
+
+ if (simRev >= totalOpEx) {
+ // Profitable crossover reached before cash depletion
+ isAlive = true;
+ break;
+ }
+
+ if (simCash > 0) {
+ const prevCash = simCash;
+ simCash -= simBurn;
+ if (simCash <= 0) {
+ simDepleted = true;
+ // Calculate fractional month of survival
+ runwayMonths = (simMonths - 1) + (prevCash / simBurn);
+ break;
+ }
+ } else {
+ simDepleted = true;
+ runwayMonths = simMonths - 1;
+ break;
+ }
+ }
+
+ if (!simDepleted && simMonths >= 120) {
+ isAlive = true;
+ runwayMonths = Infinity;
+ }
+ }
+
+ // 4. Update metrics dashboard text labels
+ // Burn (Month 1 baseline burn)
+ const initialBurn = totalOpEx - revenue;
+ lblNetBurn.textContent = formatCurrency(initialBurn);
+
+ if (initialBurn > 0) {
+ lblNetBurn.className = "m-val text-rose";
+ } else {
+ lblNetBurn.className = "m-val text-emerald";
+ lblNetBurn.textContent = "+" + formatCurrency(Math.abs(initialBurn));
+ }
+
+ // Runway Remaining label
+ if (runwayMonths === Infinity) {
+ lblRunway.textContent = "∞ (Infinite)";
+ lblRunway.className = "m-val text-emerald";
+ lblRunwayUrgency.textContent = "Revenue exceeds expenses";
+ lblZeroDate.textContent = "N/A";
+ lblZeroDate.className = "m-val text-emerald";
+ lblClassification.textContent = "Profitable";
+ lblClassification.className = "m-val text-emerald";
+
+ lblHeaderStatus.textContent = "DEFAULT ALIVE";
+ lblHeaderStatus.className = "status-indicator status-green";
+ } else {
+ lblRunway.textContent = `${runwayMonths.toFixed(1)} mo`;
+
+ // Classify Urgency alerts color
+ if (runwayMonths < 6) {
+ lblRunway.className = "m-val text-rose";
+ lblRunwayUrgency.textContent = "Critical cash runway";
+ lblZeroDate.className = "m-val text-rose";
+ } else if (runwayMonths <= 12) {
+ lblRunway.className = "m-val text-amber";
+ lblRunwayUrgency.textContent = "Caution cash runway";
+ lblZeroDate.className = "m-val text-amber";
+ } else {
+ lblRunway.className = "m-val text-emerald";
+ lblRunwayUrgency.textContent = "Stable cash runway";
+ lblZeroDate.className = "m-val text-emerald";
+ }
+
+ // Set zero-cash date text
+ const zeroDate = getProjectedDateFromMonths(runwayMonths);
+ lblZeroDate.textContent = zeroDate;
+
+ // Set Default Alive vs Dead status
+ if (isAlive) {
+ lblClassification.textContent = "Default Alive";
+ lblClassification.className = "m-val text-emerald";
+ lblHeaderStatus.textContent = "DEFAULT ALIVE";
+ lblHeaderStatus.className = "status-indicator status-green";
+ } else {
+ lblClassification.textContent = "Default Dead";
+ lblClassification.className = "m-val text-rose";
+ lblHeaderStatus.textContent = "DEFAULT DEAD";
+ lblHeaderStatus.className = "status-indicator status-red";
+ }
+ }
+
+ // 5. Populate Monthly ledgers table
+ renderForecastTable();
+
+ // 6. Draw dynamic forecast SVG line chart
+ renderChart();
+
+ // 7. Render Scenario Vault list
+ renderScenarioList();
+
+ // 8. Render Runway recommendations feed
+ renderRecommendations(runwayMonths, totalOpEx, payroll, marketing, saas, growth);
+}
+
+// Monthly Forecast Data Table
+function renderForecastTable() {
+ forecastTableBody.innerHTML = "";
+ monthlyData.forEach(row => {
+ const tr = document.createElement("tr");
+ tr.innerHTML = `
+ ${row.monthName}
+ ${formatCurrency(row.startingCash)}
+ ${formatCurrency(row.revenue)}
+ ${formatCurrency(row.opex)}
+ ${row.netBurn > 0 ? "-" : "+"}${formatCurrency(Math.abs(row.netBurn))}
+ ${formatCurrency(row.endingCash)}
+ `;
+ forecastTableBody.appendChild(tr);
+ });
+}
+
+// Render dynamic forecasting SVG line chart
+function renderChart() {
+ svgElement.innerHTML = "";
+
+ const w = svgElement.clientWidth || 800;
+ const h = 320;
+ const paddingLeft = 70;
+ const paddingRight = 40;
+ const paddingTop = 30;
+ const paddingBottom = 40;
+
+ const chartW = w - paddingLeft - paddingRight;
+ const chartH = h - paddingTop - paddingBottom;
+
+ // Calculate scales Y-max
+ const maxCash = Math.max(...monthlyData.map(d => d.startingCash), ...monthlyData.map(d => d.endingCash), 100000);
+ const maxRevenue = Math.max(...monthlyData.map(d => d.revenue), 10000);
+ const yMax = Math.max(maxCash, maxRevenue * 1.2);
+
+ // Draw Grid Lines (Horizontal and Vertical)
+ const gridCountY = 5;
+ for (let i = 0; i <= gridCountY; i++) {
+ const yVal = yMax * (i / gridCountY);
+ const yPos = paddingTop + chartH - (yVal / yMax) * chartH;
+
+ // Gridline path
+ const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
+ line.setAttribute("x1", paddingLeft);
+ line.setAttribute("y1", yPos);
+ line.setAttribute("x2", w - paddingRight);
+ line.setAttribute("y2", yPos);
+ line.setAttribute("class", "grid-line");
+ svgElement.appendChild(line);
+
+ // Label Text
+ const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
+ text.setAttribute("x", paddingLeft - 10);
+ text.setAttribute("y", yPos + 4);
+ text.setAttribute("text-anchor", "end");
+ text.setAttribute("class", "axis-label");
+ text.textContent = formatCurrencyShort(yVal);
+ svgElement.appendChild(text);
+ }
+
+ // Draw X-axis labels
+ const labelInterval = 4;
+ monthlyData.forEach((d, i) => {
+ const xPos = paddingLeft + (i / 24) * chartW;
+
+ // Vertical grid ticks
+ if (i % labelInterval === 0 || i === 24) {
+ const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
+ line.setAttribute("x1", xPos);
+ line.setAttribute("y1", paddingTop);
+ line.setAttribute("x2", xPos);
+ line.setAttribute("y2", paddingTop + chartH);
+ line.setAttribute("class", "grid-line");
+ svgElement.appendChild(line);
+
+ const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
+ text.setAttribute("x", xPos);
+ text.setAttribute("y", paddingTop + chartH + 20);
+ text.setAttribute("text-anchor", "middle");
+ text.setAttribute("class", "axis-label");
+ text.textContent = d.monthName;
+ svgElement.appendChild(text);
+ }
+ });
+
+ // Axis lines
+ const xAxis = document.createElementNS("http://www.w3.org/2000/svg", "line");
+ xAxis.setAttribute("x1", paddingLeft);
+ xAxis.setAttribute("y1", paddingTop + chartH);
+ xAxis.setAttribute("x2", w - paddingRight);
+ xAxis.setAttribute("y2", paddingTop + chartH);
+ xAxis.setAttribute("class", "axis-line");
+ svgElement.appendChild(xAxis);
+
+ const yAxis = document.createElementNS("http://www.w3.org/2000/svg", "line");
+ yAxis.setAttribute("x1", paddingLeft);
+ yAxis.setAttribute("y1", paddingTop);
+ yAxis.setAttribute("x2", paddingLeft);
+ yAxis.setAttribute("y2", paddingTop + chartH);
+ yAxis.setAttribute("class", "axis-line");
+ svgElement.appendChild(yAxis);
+
+ // Draw Revenue Line path
+ let revPathPoints = "";
+ monthlyData.forEach((d, i) => {
+ const x = paddingLeft + (i / 24) * chartW;
+ const y = paddingTop + chartH - (d.revenue / yMax) * chartH;
+ revPathPoints += `${i === 0 ? "M" : "L"} ${x} ${y}`;
+ });
+
+ const revPath = document.createElementNS("http://www.w3.org/2000/svg", "path");
+ revPath.setAttribute("d", revPathPoints);
+ revPath.setAttribute("class", "line-revenue");
+ svgElement.appendChild(revPath);
+
+ // Draw Cash Projection Line path
+ let cashPathPoints = "";
+ let crossoverX = null;
+ let crossoverY = null;
+ let zeroCashIndex = -1;
+
+ monthlyData.forEach((d, i) => {
+ const x = paddingLeft + (i / 24) * chartW;
+ const y = paddingTop + chartH - (d.endingCash / yMax) * chartH;
+
+ cashPathPoints += `${i === 0 ? "M" : "L"} ${x} ${y}`;
+
+ if (d.endingCash === 0 && zeroCashIndex === -1 && i > 0 && monthlyData[i-1].endingCash > 0) {
+ zeroCashIndex = i;
+ // Interpolate depletion intersection
+ const prevX = paddingLeft + ((i - 1) / 24) * chartW;
+ const prevY = paddingTop + chartH - (monthlyData[i-1].endingCash / yMax) * chartH;
+ const diffCash = monthlyData[i-1].endingCash;
+ const burn = monthlyData[i].netBurn;
+ const frac = diffCash / burn;
+
+ crossoverX = prevX + frac * (x - prevX);
+ crossoverY = paddingTop + chartH; // Y coordinate is bottom axis
+ }
+ });
+
+ const cashPath = document.createElementNS("http://www.w3.org/2000/svg", "path");
+ cashPath.setAttribute("d", cashPathPoints);
+ cashPath.setAttribute("class", "line-cash");
+ svgElement.appendChild(cashPath);
+
+ // Draw Crossover Dot (Zero cash date indicator)
+ if (crossoverX !== null) {
+ const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
+ dot.setAttribute("cx", crossoverX);
+ dot.setAttribute("cy", crossoverY);
+ dot.setAttribute("class", "chart-dot dot-cash-depletion");
+ dot.setAttribute("title", "Cash Depletion Date");
+ svgElement.appendChild(dot);
+
+ dot.addEventListener("mouseenter", (e) => {
+ showTooltip(e, `Cash Depletion Intersection Runway ends here.`);
+ });
+ dot.addEventListener("mouseleave", hideTooltip);
+ }
+
+ // Draw Hover Dots/Nodes for Tooltips details
+ monthlyData.forEach((d, i) => {
+ const x = paddingLeft + (i / 24) * chartW;
+ const yCash = paddingTop + chartH - (d.endingCash / yMax) * chartH;
+
+ const dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
+ dot.setAttribute("cx", x);
+ dot.setAttribute("cy", yCash);
+ dot.setAttribute("r", 4);
+ dot.setAttribute("fill", "#0ea5e9");
+ dot.setAttribute("stroke", "#ffffff");
+ dot.setAttribute("stroke-width", "1");
+ dot.setAttribute("opacity", "0");
+ dot.setAttribute("style", "cursor: pointer; pointer-events: all;");
+ svgElement.appendChild(dot);
+
+ // Event hooks
+ dot.addEventListener("mouseenter", (e) => {
+ dot.setAttribute("opacity", "1");
+ dot.setAttribute("r", 6);
+ showTooltip(e, `
+ ${d.monthName} Forecast
+ Starting Cash: ${formatCurrency(d.startingCash)}
+ Revenue: ${formatCurrency(d.revenue)}
+ OpEx: ${formatCurrency(d.opex)}
+ Net Burn: ${d.netBurn > 0 ? "" : "+"}${formatCurrency(-d.netBurn)}
+ Ending Cash: ${formatCurrency(d.endingCash)}
+ `);
+ });
+
+ dot.addEventListener("mouseleave", () => {
+ dot.setAttribute("opacity", "0");
+ dot.setAttribute("r", 4);
+ hideTooltip();
+ });
+ });
+}
+
+// Tooltip helpers
+function showTooltip(e, htmlContent) {
+ tooltip.innerHTML = htmlContent;
+ tooltip.style.display = "block";
+
+ // Position tooltip relative to screen dimensions
+ const tooltipW = tooltip.offsetWidth;
+ const tooltipH = tooltip.offsetHeight;
+
+ let x = e.pageX + 15;
+ let y = e.pageY - tooltipH - 10;
+
+ if (x + tooltipW > window.innerWidth) {
+ x = e.pageX - tooltipW - 15;
+ }
+ if (y < window.scrollY) {
+ y = e.pageY + 20;
+ }
+
+ tooltip.style.left = `${x}px`;
+ tooltip.style.top = `${y}px`;
+}
+
+function hideTooltip() {
+ tooltip.style.display = "none";
+}
+
+// Helper date generator
+function getProjectedMonthName(monthsFromNow) {
+ const date = new Date(BASE_YEAR, BASE_MONTH + monthsFromNow, 1);
+ return `${MONTH_NAMES[date.getMonth()]} ${date.getFullYear()}`;
+}
+
+function getProjectedDateFromMonths(months) {
+ if (months === Infinity) return "N/A";
+ const intMonths = Math.floor(months);
+ const frac = months - intMonths;
+
+ const date = new Date(BASE_YEAR, BASE_MONTH + intMonths, 1);
+ // Interpolate day approximation
+ const daysInMonth = new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
+ const day = Math.max(1, Math.round(frac * daysInMonth));
+
+ return `${MONTH_NAMES[date.getMonth()]} ${day}, ${date.getFullYear()}`;
+}
+
+// CURRENCY FORMATTERS
+function formatCurrency(amount) {
+ return new Intl.NumberFormat("en-US", {
+ style: "currency",
+ currency: "USD",
+ maximumFractionDigits: 0
+ }).format(amount);
+}
+
+function formatCurrencyShort(amount) {
+ if (amount >= 1000000) {
+ return `$${(amount / 1000000).toFixed(1)}M`;
+ } else if (amount >= 1000) {
+ return `$${(amount / 1000).toFixed(0)}k`;
+ }
+ return `$${amount}`;
+}
+
+// RUNWAY RECOMMENDATIONS ALERTS GENERATOR
+function renderRecommendations(runway, totalOpEx, payroll, marketing, saas, growth) {
+ recommendationsFeed.innerHTML = "";
+
+ // 1. General Urgency Alert
+ const alertCard = document.createElement("div");
+ if (runway === Infinity) {
+ alertCard.className = "advisory-item adv-success";
+ alertCard.innerHTML = `
+ Sustainable Status
+ Your startup is Default Alive. Revenue projections surpass operational expenses, creating self-sustainability without immediate external capital.
+ `;
+ } else if (runway < 6) {
+ alertCard.className = "advisory-item adv-danger";
+ alertCard.innerHTML = `
+ Action Required!
+ Critical runway length. Cash depletes in ${runway.toFixed(1)} months. Pause non-essential hiring immediately and seek bridge funding sources.
+ `;
+ } else if (runway <= 12) {
+ alertCard.className = "advisory-item adv-warning";
+ alertCard.innerHTML = `
+ Warning Runway
+ Caution cash burn. Runway is ${runway.toFixed(1)} months. Optimize vendor contracts and focus marketing budgets strictly on high-converting channels.
+ `;
+ } else {
+ alertCard.className = "advisory-item adv-success";
+ alertCard.innerHTML = `
+ Stable Health
+ Healthy Runway of ${runway.toFixed(1)} months. You have adequate space to focus on product-market fit or launch next equity funding cycles.
+ `;
+ }
+ recommendationsFeed.appendChild(alertCard);
+
+ // 2. OpEx Analysis Advice
+ const opexCard = document.createElement("div");
+ opexCard.className = "advisory-item";
+ opexCard.style.borderLeftColor = "var(--clr-primary)";
+ opexCard.style.background = "rgba(14, 165, 233, 0.05)";
+
+ const payrollPct = totalOpEx > 0 ? Math.round((payroll / totalOpEx) * 100) : 0;
+ const marketingPct = totalOpEx > 0 ? Math.round((marketing / totalOpEx) * 100) : 0;
+
+ if (payrollPct > 65) {
+ opexCard.innerHTML = `
+ Personnel Expense Heavy
+ Payroll represents ${payrollPct}% of your operational cost. Consider structuring new hires on equity-heavy compensation packages to save baseline burn.
+ `;
+ } else if (marketingPct > 25 && runway < 12) {
+ opexCard.innerHTML = `
+ Reduce Acquisition Costs
+ Marketing spends eat ${marketingPct}% of cash flow. Scaling down customer acquisition budgets by 30% could extend your runway by ${(runway * 0.15).toFixed(1)} months.
+ `;
+ } else {
+ opexCard.innerHTML = `
+ Balanced Expenditures
+ OpEx is evenly divided: Payroll (${payrollPct}%) and SaaS/Admin overhead. Focus operational focus on customer feedback metrics.
+ `;
+ }
+ recommendationsFeed.appendChild(opexCard);
+
+ // 3. Growth rate advice
+ if (growth > 10 && runway < 12) {
+ const growthCard = document.createElement("div");
+ growthCard.className = "advisory-item adv-warning";
+ growthCard.innerHTML = `
+ Over-optimistic Expansion
+ Compounding a ${growth}% growth rate is high. If sales growth pulls back to 2%, your runway will drop instantly. Test conservative models.
+ `;
+ recommendationsFeed.appendChild(growthCard);
+ }
+}
+
+// SCENARIO VAULT CONTROLLERS
+function renderScenarioList() {
+ scenarioList.innerHTML = "";
+
+ if (scenarios.length === 0) {
+ scenarioList.innerHTML = `No plans saved yet. `;
+ return;
+ }
+
+ scenarios.forEach(sc => {
+ const li = document.createElement("li");
+ li.className = `scenario-item ${sc.id === activeScenarioId ? "active-scenario" : ""}`;
+
+ li.innerHTML = `
+ ${escapeHtml(sc.name)}
+
+ `;
+
+ // Click on name to load scenario details
+ li.addEventListener("click", (e) => {
+ if (e.target.tagName !== "I" && e.target.tagName !== "BUTTON") {
+ loadScenarioDetails(sc.id);
+ }
+ });
+
+ // Delete scenario button
+ li.querySelector(".btn-delete-scenario").addEventListener("click", (e) => {
+ e.stopPropagation();
+ deleteScenario(sc.id);
+ });
+
+ scenarioList.appendChild(li);
+ });
+}
+
+// Load values from active scenario
+function loadScenarioDetails(id) {
+ const sc = scenarios.find(s => s.id === id);
+ if (!sc) return;
+
+ activeScenarioId = id;
+
+ txtCash.value = sc.cash;
+ txtRevenue.value = sc.revenue;
+ sliderGrowth.value = sc.growth;
+ lblGrowthVal.textContent = `${sc.growth}%`;
+
+ txtPayroll.value = sc.payroll;
+ txtMarketing.value = sc.marketing;
+ txtSaas.value = sc.saas;
+ txtRent.value = sc.rent;
+ txtMisc.value = sc.misc;
+
+ updateActiveScenarioHighlight();
+ calculateAndRender();
+}
+
+// Highlight active scenario in Vault
+function updateActiveScenarioHighlight() {
+ document.querySelectorAll(".scenario-item").forEach(item => {
+ item.classList.remove("active-scenario");
+ });
+ if (activeScenarioId) {
+ renderScenarioList();
+ }
+}
+
+// Save Current scenario Snapshot
+function saveCurrentScenario() {
+ const name = txtScenarioName.value.trim();
+ if (!name) {
+ alert("Please enter a Scenario Name first.");
+ return;
+ }
+
+ const id = "sc-" + Date.now();
+ const snapshot = {
+ id: id,
+ name: name,
+ cash: Number(txtCash.value) || 0,
+ revenue: Number(txtRevenue.value) || 0,
+ growth: Number(sliderGrowth.value) || 0,
+ payroll: Number(txtPayroll.value) || 0,
+ marketing: Number(txtMarketing.value) || 0,
+ saas: Number(txtSaas.value) || 0,
+ rent: Number(txtRent.value) || 0,
+ misc: Number(txtMisc.value) || 0
+ };
+
+ scenarios.push(snapshot);
+ txtScenarioName.value = "";
+ activeScenarioId = id;
+
+ saveToStorage();
+ calculateAndRender();
+}
+
+// Delete scenario
+function deleteScenario(id) {
+ if (confirm("Are you sure you want to delete this planning scenario?")) {
+ scenarios = scenarios.filter(s => s.id !== id);
+ if (activeScenarioId === id) {
+ activeScenarioId = null;
+ }
+ saveToStorage();
+ calculateAndRender();
+ }
+}
+
+// Reset data parameters memory
+function resetWorkspace() {
+ if (confirm("Are you absolutely sure you want to clear scenarios? This will restore baseline templates.")) {
+ scenarios = [...DEFAULT_SCENARIOS];
+ activeScenarioId = "sc-baseline";
+ saveToStorage();
+ loadScenarioDetails("sc-baseline");
+ }
+}
+
+// Escape HTML utility
+function escapeHtml(str) {
+ if (!str) return "";
+ return str
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+}
diff --git a/Projects/Startup Runway Calculator/style.css b/Projects/Startup Runway Calculator/style.css
new file mode 100644
index 00000000..80c7067b
--- /dev/null
+++ b/Projects/Startup Runway Calculator/style.css
@@ -0,0 +1,758 @@
+/* Startup Runway Calculator - Dashboard Styles */
+
+:root {
+ --bg-main: #090d16;
+ --bg-card: #111827;
+ --bg-card-hover: #1f2937;
+ --border-color: #374151;
+ --text-main: #f3f4f6;
+ --text-muted: #9ca3af;
+ --text-highlight: #ffffff;
+
+ /* Accent theme palettes */
+ --clr-primary: #0ea5e9;
+ --clr-primary-glow: rgba(14, 165, 233, 0.15);
+
+ --clr-emerald: #10b981;
+ --clr-emerald-glow: rgba(16, 185, 129, 0.15);
+
+ --clr-amber: #f59e0b;
+ --clr-amber-glow: rgba(245, 158, 11, 0.15);
+
+ --clr-rose: #ef4444;
+ --clr-rose-glow: rgba(239, 68, 68, 0.15);
+
+ --font-headers: 'Outfit', sans-serif;
+ --font-body: 'Inter', sans-serif;
+
+ --transition-speed: 0.25s;
+ --radius-sm: 8px;
+ --radius-md: 12px;
+ --radius-lg: 16px;
+ --glow-shadow: 0 0 20px rgba(14, 165, 233, 0.25);
+}
+
+/* GENERAL STYLES */
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-color: var(--bg-main);
+ color: var(--text-main);
+ font-family: var(--font-body);
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ overflow-x: hidden;
+ line-height: 1.5;
+}
+
+/* GLOW BACKGROUND */
+.glow-bg {
+ position: absolute;
+ top: -150px;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 800px;
+ height: 400px;
+ background: radial-gradient(circle, rgba(14, 165, 233, 0.1) 0%, rgba(16, 185, 129, 0.05) 50%, rgba(9, 13, 22, 0) 100%);
+ filter: blur(80px);
+ z-index: -1;
+ pointer-events: none;
+}
+
+/* SCROLLBARS */
+::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+}
+
+::-webkit-scrollbar-track {
+ background: rgba(0, 0, 0, 0.1);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--border-color);
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--text-muted);
+}
+
+/* HEADER styling */
+.app-header {
+ background: rgba(17, 24, 39, 0.7);
+ backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--border-color);
+ padding: 1rem 2rem;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+}
+
+.header-container {
+ max-width: 1600px;
+ margin: 0 auto;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 1rem;
+}
+
+.logo {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+}
+
+.logo h1 {
+ font-family: var(--font-headers);
+ font-size: 1.75rem;
+ font-weight: 800;
+ letter-spacing: -0.5px;
+ background: linear-gradient(135deg, #ffffff 30%, var(--clr-primary) 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+}
+
+.logo h1 span {
+ color: var(--text-muted);
+ -webkit-text-fill-color: var(--text-muted);
+ font-weight: 400;
+}
+
+.glow-icon {
+ font-size: 1.5rem;
+ color: var(--clr-primary);
+ text-shadow: 0 0 10px rgba(14, 165, 233, 0.5);
+ animation: pulse 3s infinite alternate;
+}
+
+.logo .badge {
+ font-size: 0.75rem;
+ font-weight: 600;
+ padding: 0.25rem 0.6rem;
+ background: rgba(31, 41, 55, 0.6);
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-sm);
+ color: var(--text-muted);
+ text-transform: uppercase;
+ letter-spacing: 1px;
+}
+
+.header-stats {
+ display: flex;
+ gap: 1rem;
+}
+
+.status-indicator {
+ display: inline-flex;
+ align-items: center;
+ padding: 0.4rem 0.8rem;
+ border-radius: var(--radius-sm);
+ font-size: 0.8rem;
+ font-weight: 700;
+ letter-spacing: 0.5px;
+ transition: all var(--transition-speed);
+}
+
+.status-green {
+ background: var(--clr-emerald-glow);
+ color: #6ee7b7;
+ border: 1px solid var(--clr-emerald);
+ box-shadow: 0 0 10px rgba(16, 185, 129, 0.15);
+}
+
+.status-amber {
+ background: var(--clr-amber-glow);
+ color: #fde047;
+ border: 1px solid var(--clr-amber);
+ box-shadow: 0 0 10px rgba(245, 158, 11, 0.15);
+}
+
+.status-red {
+ background: var(--clr-rose-glow);
+ color: #fca5a5;
+ border: 1px solid var(--clr-rose);
+ box-shadow: 0 0 10px rgba(239, 68, 68, 0.15);
+}
+
+/* MAIN LAYOUT */
+.main-container {
+ display: grid;
+ grid-template-columns: 300px 1fr 300px;
+ gap: 1.5rem;
+ max-width: 1600px;
+ width: 100%;
+ margin: 0 auto;
+ padding: 1.5rem 2rem;
+ flex: 1;
+}
+
+/* SECTION CARDS */
+.section-card {
+ background: var(--bg-card);
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-md);
+ padding: 1.25rem;
+ margin-bottom: 1.25rem;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ transition: border-color var(--transition-speed);
+}
+
+.section-card:hover {
+ border-color: rgba(255, 255, 255, 0.08);
+}
+
+.card-header-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 1rem;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.05);
+ padding-bottom: 0.5rem;
+}
+
+.card-header-row h3 {
+ font-family: var(--font-headers);
+ font-size: 1.1rem;
+ font-weight: 600;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ color: var(--text-highlight);
+}
+
+/* INPUTS & CONTROLS */
+.form-group {
+ margin-bottom: 1rem;
+}
+
+.form-group label {
+ display: block;
+ font-size: 0.8rem;
+ font-weight: 500;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ margin-bottom: 0.4rem;
+ letter-spacing: 0.5px;
+}
+
+input[type="text"],
+input[type="number"],
+select {
+ width: 100%;
+ padding: 0.65rem 0.9rem;
+ background-color: rgba(9, 13, 22, 0.6);
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-sm);
+ color: var(--text-main);
+ font-family: var(--font-body);
+ font-size: 0.9rem;
+ transition: border-color var(--transition-speed), box-shadow var(--transition-speed);
+}
+
+input[type="text"]:focus,
+input[type="number"]:focus,
+select:focus {
+ outline: none;
+ border-color: var(--clr-primary);
+ box-shadow: 0 0 0 2px rgba(14, 165, 233, 0.2);
+}
+
+/* CUSTOM RANGE SLIDER */
+.slider-label-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.slider-val {
+ font-weight: 700;
+ color: var(--clr-primary);
+ font-size: 0.9rem;
+}
+
+input[type="range"] {
+ -webkit-appearance: none;
+ width: 100%;
+ background: transparent;
+ margin: 0.5rem 0;
+}
+
+input[type="range"]:focus {
+ outline: none;
+}
+
+input[type="range"]::-webkit-slider-runnable-track {
+ width: 100%;
+ height: 6px;
+ cursor: pointer;
+ background: var(--border-color);
+ border-radius: 3px;
+}
+
+input[type="range"]::-webkit-slider-thumb {
+ height: 16px;
+ width: 16px;
+ border-radius: 50%;
+ background: var(--clr-primary);
+ cursor: pointer;
+ -webkit-appearance: none;
+ margin-top: -5px;
+ box-shadow: 0 0 10px rgba(14, 165, 233, 0.5);
+ transition: transform 0.1s;
+}
+
+input[type="range"]::-webkit-slider-thumb:hover {
+ transform: scale(1.2);
+}
+
+/* BUTTONS */
+.btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ padding: 0.65rem 1.25rem;
+ border-radius: var(--radius-sm);
+ font-family: var(--font-body);
+ font-weight: 600;
+ font-size: 0.9rem;
+ cursor: pointer;
+ transition: all var(--transition-speed);
+ border: 1px solid transparent;
+ width: 100%;
+}
+
+.btn-sm {
+ padding: 0.45rem 0.9rem;
+ font-size: 0.8rem;
+}
+
+.btn-primary {
+ background: linear-gradient(135deg, var(--clr-primary) 0%, #0284c7 100%);
+ color: white;
+ box-shadow: var(--glow-shadow);
+}
+
+.btn-primary:hover {
+ transform: translateY(-1px);
+ filter: brightness(1.1);
+ box-shadow: 0 0 25px rgba(14, 165, 233, 0.4);
+}
+
+.btn-danger {
+ background: linear-gradient(135deg, var(--clr-rose) 0%, #dc2626 100%);
+ color: white;
+}
+
+.btn-danger:hover {
+ filter: brightness(1.1);
+}
+
+.footer-btn {
+ background: transparent;
+ border: 1px dashed var(--border-color);
+ color: var(--text-muted);
+ padding: 0.75rem;
+ border-radius: var(--radius-sm);
+ cursor: pointer;
+ transition: all var(--transition-speed);
+ font-family: var(--font-body);
+ font-size: 0.85rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 0.5rem;
+ width: 100%;
+}
+
+.footer-btn:hover {
+ border-color: var(--clr-rose);
+ color: var(--clr-rose);
+ background: rgba(239, 68, 68, 0.05);
+}
+
+/* SIDEBAR COLUMN (LEFT / RIGHT) */
+.sidebar-column {
+ display: flex;
+ flex-direction: column;
+}
+
+/* CENTER COLUMN METRICS */
+.chart-column {
+ display: flex;
+ flex-direction: column;
+}
+
+.metrics-grid {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 0.75rem;
+ margin-bottom: 1.25rem;
+}
+
+.metric-card {
+ background: var(--bg-card);
+ border: 1px solid var(--border-color);
+ padding: 1rem 0.75rem;
+ border-radius: var(--radius-md);
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+}
+
+.m-lbl {
+ font-size: 0.7rem;
+ color: var(--text-muted);
+ font-weight: 500;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+}
+
+.m-val {
+ font-family: var(--font-headers);
+ font-size: 1.5rem;
+ font-weight: 800;
+ color: var(--text-highlight);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.m-sub {
+ font-size: 0.7rem;
+ color: var(--text-muted);
+}
+
+.text-rose { color: #fca5a5; }
+.text-amber { color: #fde047; }
+.text-emerald { color: #6ee7b7; }
+
+/* SVG CHART WORKSPACE */
+.chart-card {
+ padding: 1.25rem;
+}
+
+.chart-legend {
+ display: flex;
+ gap: 1rem;
+ font-size: 0.75rem;
+}
+
+.legend-item {
+ display: flex;
+ align-items: center;
+ gap: 0.35rem;
+ color: var(--text-muted);
+}
+
+.legend-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+}
+
+.dot-cyan { background-color: var(--clr-primary); }
+.dot-emerald { background-color: var(--clr-emerald); }
+
+.chart-container {
+ width: 100%;
+ height: 300px;
+ margin-top: 1rem;
+ position: relative;
+}
+
+#projection-svg {
+ width: 100%;
+ height: 100%;
+ display: block;
+}
+
+/* CHART SVG SPECIFICS */
+.grid-line {
+ stroke: rgba(255, 255, 255, 0.05);
+ stroke-width: 1;
+}
+
+.axis-line {
+ stroke: var(--border-color);
+ stroke-width: 1.5;
+}
+
+.axis-label {
+ fill: var(--text-muted);
+ font-size: 10px;
+ font-family: var(--font-body);
+}
+
+.line-cash {
+ fill: none;
+ stroke: var(--clr-primary);
+ stroke-width: 3;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ filter: drop-shadow(0px 0px 6px rgba(14, 165, 233, 0.3));
+}
+
+.line-revenue {
+ fill: none;
+ stroke: var(--clr-emerald);
+ stroke-width: 2.5;
+ stroke-linecap: round;
+ stroke-linejoin: round;
+ stroke-dasharray: 4,4;
+}
+
+.chart-dot {
+ fill: #090d16;
+ stroke-width: 2.5;
+}
+
+.dot-cash-depletion {
+ fill: var(--clr-rose);
+ stroke: #ffffff;
+ r: 6;
+ cursor: pointer;
+}
+
+.chart-interactive-overlay {
+ fill: none;
+ pointer-events: all;
+}
+
+.chart-tooltip {
+ position: absolute;
+ background: rgba(17, 24, 39, 0.95);
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-sm);
+ padding: 0.5rem;
+ font-size: 0.75rem;
+ color: var(--text-main);
+ pointer-events: none;
+ box-shadow: 0 4px 10px rgba(0,0,0,0.5);
+ z-index: 10;
+ display: none;
+}
+
+/* DATA TABLE */
+.table-card {
+ margin-top: 1.25rem;
+}
+
+.table-wrapper {
+ max-height: 250px;
+ overflow-y: auto;
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--border-color);
+}
+
+.forecast-table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 0.8rem;
+ text-align: left;
+}
+
+.forecast-table th,
+.forecast-table td {
+ padding: 0.6rem 0.8rem;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.03);
+}
+
+.forecast-table th {
+ background: rgba(17, 24, 39, 0.9);
+ color: var(--text-muted);
+ font-weight: 600;
+ position: sticky;
+ top: 0;
+ z-index: 1;
+}
+
+.forecast-table tbody tr:hover {
+ background: rgba(255, 255, 255, 0.02);
+}
+
+/* SCENARIO VAULT */
+.scenario-save-form {
+ padding: 0.75rem;
+ background: rgba(9, 13, 22, 0.4);
+ border: 1px solid rgba(255, 255, 255, 0.02);
+ border-radius: var(--radius-sm);
+ margin-bottom: 1rem;
+}
+
+.saved-scenarios-section h5 {
+ font-family: var(--font-headers);
+ font-size: 0.85rem;
+ font-weight: 700;
+ text-transform: uppercase;
+ color: var(--text-muted);
+ margin-bottom: 0.5rem;
+}
+
+.scenario-ul {
+ list-style: none;
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ max-height: 180px;
+ overflow-y: auto;
+}
+
+.scenario-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background: rgba(9, 13, 22, 0.6);
+ border: 1px solid var(--border-color);
+ padding: 0.4rem 0.6rem;
+ border-radius: var(--radius-sm);
+ font-size: 0.8rem;
+ cursor: pointer;
+ transition: all var(--transition-speed);
+}
+
+.scenario-item:hover {
+ border-color: var(--clr-primary);
+ background: rgba(17, 24, 39, 0.8);
+}
+
+.scenario-item.active-scenario {
+ border-color: var(--clr-emerald);
+ background: rgba(16, 185, 129, 0.05);
+}
+
+.scenario-name {
+ font-weight: 600;
+ color: var(--text-highlight);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 180px;
+}
+
+.btn-delete-scenario {
+ background: transparent;
+ border: none;
+ color: var(--text-muted);
+ cursor: pointer;
+ padding: 0.2rem;
+ transition: color var(--transition-speed);
+}
+
+.btn-delete-scenario:hover {
+ color: var(--clr-rose);
+}
+
+/* RECOMMENDATIONS FEED */
+.advisory-card {
+ flex: 1;
+}
+
+.advisory-feed {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ max-height: 300px;
+ overflow-y: auto;
+}
+
+.advisory-item {
+ padding: 0.75rem;
+ border-radius: var(--radius-sm);
+ font-size: 0.8rem;
+ border-left: 4px solid transparent;
+ background: rgba(9, 13, 22, 0.4);
+}
+
+.adv-success {
+ border-left-color: var(--clr-emerald);
+ background: rgba(16, 185, 129, 0.05);
+ color: #a7f3d0;
+}
+
+.adv-warning {
+ border-left-color: var(--clr-amber);
+ background: rgba(245, 158, 11, 0.05);
+ color: #fef08a;
+}
+
+.adv-danger {
+ border-left-color: var(--clr-rose);
+ background: rgba(239, 68, 68, 0.05);
+ color: #fecaca;
+}
+
+.advisory-title {
+ font-weight: 700;
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ margin-bottom: 0.25rem;
+ font-size: 0.85rem;
+}
+
+/* FOOTER */
+.app-footer {
+ border-top: 1px solid var(--border-color);
+ padding: 1.5rem 2rem;
+ text-align: center;
+ background-color: rgba(9, 13, 22, 0.8);
+ font-size: 0.85rem;
+ color: var(--text-muted);
+ margin-top: auto;
+}
+
+.footer-container a {
+ color: var(--clr-primary);
+ text-decoration: none;
+ transition: color var(--transition-speed);
+}
+
+.footer-container a:hover {
+ color: #38bdf8;
+ text-decoration: underline;
+}
+
+/* ANIMATIONS */
+@keyframes pulse {
+ 0% { text-shadow: 0 0 8px rgba(14, 165, 233, 0.3); }
+ 100% { text-shadow: 0 0 16px rgba(14, 165, 233, 0.7); }
+}
+
+/* RESPONSIVE LAYOUTS */
+@media (max-width: 1200px) {
+ .main-container {
+ grid-template-columns: 280px 1fr;
+ }
+ .advisory-card, .scenario-card {
+ grid-column: span 1;
+ }
+}
+
+@media (max-width: 900px) {
+ .main-container {
+ grid-template-columns: 1fr;
+ padding: 1rem;
+ }
+ .sidebar-column, .chart-column {
+ grid-column: span 1;
+ }
+ .metrics-grid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+ .header-container {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+}
diff --git a/Projects/Startup Runway Calculator/thumbnail.svg b/Projects/Startup Runway Calculator/thumbnail.svg
new file mode 100644
index 00000000..e59357ca
--- /dev/null
+++ b/Projects/Startup Runway Calculator/thumbnail.svg
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ RunwaySync
+
+
+ FORECAST
+
+
+
+
+
+
+ DEFAULT ALIVE
+
+
+
+
+
+
+ RUNWAY REMAINING
+ 18.4 mo
+
+
+
+ MONTHLY BURN
+ $27,000
+
+
+
+ CASH BALANCE
+ $500,000
+
+
+
+ REV GROWTH
+ +5.0%
+
+
+
+
+
+ 24-Month Forecast
+
+
+
+ Cash
+
+ Rev
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Jun '26
+ Dec '27
+ May '28
+
+
+
+
+
+ Scenario Vault
+
+
+
+
+ ★ Baseline Plan
+
+
+
+ Slow Burn
+
+
+
+
+ Growth Push
+
+
+
+
+
+
+ 💡 Runways stable.
+
+
+