diff --git a/Projects/Election Campaign Simulator/README.md b/Projects/Election Campaign Simulator/README.md new file mode 100644 index 00000000..7fe5eb18 --- /dev/null +++ b/Projects/Election Campaign Simulator/README.md @@ -0,0 +1,11 @@ +# Election Campaign Simulator + +Manage a 30-day political campaign with a $1,000,000 budget. Take actions, deliver speeches, and track voter sentiment across demographic groups to win the election. + +## Features +- **Budget Management** — Spend on ads, rallies, canvassing, and fundraising +- **Speech Writer** — Write and deliver speeches on key topics +- **Voter Sentiment** — Track approval across youth, suburban, rural, urban, and senior demographics +- **Random Events** — Endorsements, scandals, and surprises affect your campaign + +Open `index.html` in any browser to play. diff --git a/Projects/Election Campaign Simulator/index.html b/Projects/Election Campaign Simulator/index.html new file mode 100644 index 00000000..dd3cf0ae --- /dev/null +++ b/Projects/Election Campaign Simulator/index.html @@ -0,0 +1,65 @@ + + + + + + + Election Campaign Simulator + + + +
+
+

Election Campaign Simulator

+

Budget · Speeches · Voter Sentiment

+
+ +
+
+
Budget$1,000,000
+
Approval50%
+
Day1 / 30
+
Votes0
+
+ +
+
+

Campaign Actions

+
+
+ +
+

Speech Writer

+
+ + + +
+

No speeches delivered yet.

+
+ +
+

Voter Sentiment

+
+
+
HostileNeutralAdoring
+
+
+
+
+ +
+

Campaign Trail Log

+

Your campaign begins today. Make every decision count.

+
+
+
+ + + diff --git a/Projects/Election Campaign Simulator/project.json b/Projects/Election Campaign Simulator/project.json new file mode 100644 index 00000000..6a2548f7 --- /dev/null +++ b/Projects/Election Campaign Simulator/project.json @@ -0,0 +1,10 @@ +{ + "title": "Election Campaign Simulator", + "description": "Manage your campaign budget, deliver speeches, and track voter sentiment to win the election.", + "entry": "index.html", + "tags": ["html", "css", "javascript", "simulation"], + "author": { + "name": "Girish Madarkar", + "github": "Girish0902" + } +} diff --git a/Projects/Election Campaign Simulator/script.js b/Projects/Election Campaign Simulator/script.js new file mode 100644 index 00000000..9663b8ad --- /dev/null +++ b/Projects/Election Campaign Simulator/script.js @@ -0,0 +1,152 @@ +const state = { + budget: 1000000, + approval: 50, + day: 1, + maxDays: 30, + votes: 0, + log: [], + sentiment: { + overall: 50, + youth: 50, suburban: 50, rural: 50, urban: 50, + seniors: 50, undecided: 50, + }, +}; + +const ACTIONS = [ + { name: "TV Ad Campaign", cost: 80000, approval: 3, votes: 5000, desc: "Broadcast ads across key networks" }, + { name: "Rally in City", cost: 30000, approval: 2, votes: 3000, desc: "Hold a major rally in an urban center" }, + { name: "Door-to-Door Canvassing", cost: 15000, approval: 1, votes: 2000, desc: "Volunteers engage voters personally" }, + { name: "Social Media Blitz", cost: 10000, approval: 1, votes: 1500, desc: "Targeted digital campaign" }, + { name: "Town Hall Meeting", cost: 20000, approval: 4, votes: 1000, desc: "Answer questions from undecided voters" }, + { name: "Radio Interview", cost: 5000, approval: 1, votes: 800, desc: "Speak on popular talk radio" }, + { name: "Fundraising Dinner", cost: -40000, approval: 0, votes: 0, desc: "Raise funds from donors (gain budget)" }, + { name: "Opposition Research", cost: 25000, approval: 0, votes: 6000, desc: "Uncover weakness in opponent's record" }, + { name: "Get Out The Vote", cost: 40000, approval: 0, votes: 8000, desc: "Mobilize supporters on election day" }, +]; + +const SPEECHES = { + economy: { impact: { youth: 2, suburban: 3, rural: 2, seniors: 3, urban: 2 }, approval: 2 }, + healthcare: { impact: { youth: 3, suburban: 3, rural: 2, seniors: 4, urban: 3 }, approval: 3 }, + education: { impact: { youth: 4, suburban: 3, rural: 1, seniors: 1, urban: 3 }, approval: 2 }, + security: { impact: { youth: 1, suburban: 2, rural: 3, seniors: 4, urban: 1 }, approval: 2 }, + environment: { impact: { youth: 4, suburban: 3, rural: 1, seniors: 1, urban: 2 }, approval: 1 }, +}; + +const NAMES = ["Urban voters","Suburban families","Rural communities","Young voters","Senior citizens","Undecided voters"]; + +const $=id=>document.getElementById(id); + +function updateUI(){ + $('budgetVal').textContent='$'+state.budget.toLocaleString(); + $('approvalVal').textContent=state.approval+'%'; + $('approvalVal').style.color=state.approval>=60?'var(--green)':state.approval>=40?'var(--gold)':'var(--red)'; + $('dayVal').textContent=state.day+' / '+state.maxDays; + $('votesVal').textContent=state.votes.toLocaleString(); + const fill=$('sentimentFill'); + fill.style.width=state.sentiment.overall+'%'; + const labels=['Hostile','Unfavorable','Neutral','Favorable','Adoring']; + const idx=state.sentiment.overall<20?0:state.sentiment.overall<40?1:state.sentiment.overall<60?2:state.sentiment.overall<80?3:4; + $('sentimentLabel').textContent=labels[idx]; + + const demo=$('demographics'); + const groups=['youth','suburban','rural','urban','seniors','undecided']; + demo.innerHTML=groups.map(g=>{ + const val=state.sentiment[g]; + const color=val>=60?'var(--green)':val>=40?'var(--gold)':'var(--red)'; + const label=g==='youth'?'Youth (18-29)':g==='suburban'?'Suburban':g==='rural'?'Rural':g==='urban'?'Urban':g==='seniors'?'Seniors (65+)':'Undecided'; + return `
${label}${val}%
`; + }).join(''); + + const acts=$('actionsList'); + acts.innerHTML=ACTIONS.map((a,i)=>{ + const affordable=a.cost<=0||a.cost<=state.budget; + const canAct=state.day + ${a.name} ${a.cost<0?'+$'+Math.abs(a.cost).toLocaleString():'$'+a.cost.toLocaleString()} · ${a.votes.toLocaleString()} votes · +${a.approval}% app. + `; + }).join(''); + acts.querySelectorAll('.action-btn').forEach(b=>b.addEventListener('click',()=>performAction(parseInt(b.dataset.idx)))); +} + +function performAction(idx){ + const a=ACTIONS[idx]; + if(a.cost>0&&a.cost>state.budget) return; + if(state.day>=state.maxDays) return; + state.budget-=a.cost; + state.approval=Math.min(100,Math.max(0,state.approval+a.approval+Math.floor(Math.random()*3-1))); + state.votes+=Math.floor(a.votes*(0.8+Math.random()*0.4)); + state.sentiment.overall=Math.min(100,Math.max(0,state.sentiment.overall+Math.floor(Math.random()*4-1))); + state.day++; + addLog(`Day ${state.day-1}: ${a.name}`, a.desc); + randomEvent(); + updateUI(); + if(state.day>=state.maxDays) endCampaign(); +} + +function deliverSpeech(){ + const topic=$('speechTopic').value; + const text=$('speechText').value.trim(); + if(!text){ addLog('Speech draft empty','Write something before delivering.'); return; } + if(state.day>=state.maxDays) return; + + const sp=SPEECHES[topic]; + Object.keys(sp.impact).forEach(k=>{ + state.sentiment[k]=Math.min(100,Math.max(0,state.sentiment[k]+sp.impact[k])); + }); + const avg=Object.values(state.sentiment).slice(0,5).reduce((a,b)=>a+b,0)/5; + state.sentiment.overall=Math.round(avg); + state.approval=Math.min(100,Math.max(0,state.approval+sp.approval+Math.floor(Math.random()*2))); + state.day++; + addLog(`Speech on ${topic}`, text.length>80?text.slice(0,80)+'...':text); + $('speechText').value=''; + + const log=$('speechLog'); + const entry=document.createElement('div'); + entry.className='speech-entry'; + entry.innerHTML=`[${topic}] "${text.length>60?text.slice(0,60)+'...':text}" +${sp.approval}% approval`; + log.prepend(entry); + if(log.children.length>5) log.removeChild(log.lastChild); + + randomEvent(); + updateUI(); + if(state.day>=state.maxDays) endCampaign(); +} + +function randomEvent(){ + const events=[ + { msg:"Endorsement from a local newspaper!", approval:2, votes:2000 }, + { msg:"Your opponent released a negative ad.", approval:-2, votes:-1000 }, + { msg:"A gaffe at a public event hurts your campaign.", approval:-3, votes:-1500 }, + { msg:"A celebrity endorses you!", approval:2, votes:3000 }, + { msg:"Debate performance praised by pundits.", approval:3, votes:2500 }, + { msg:"Bad weather reduces rally turnout.", approval:-1, votes:-500 }, + { msg:"A policy proposal gains national attention!", approval:3, votes:4000 }, + { msg:"Campaign staff error causes scheduling chaos.", approval:-1, votes:-500 }, + ]; + if(Math.random()<0.35){ + const e=events[Math.floor(Math.random()*events.length)]; + state.approval=Math.min(100,Math.max(0,state.approval+e.approval)); + state.votes=Math.max(0,state.votes+e.votes); + addLog('Event: '+e.msg,''); + } +} + +function addLog(title,desc){ + const el=$('logEntries'); + const entry=document.createElement('div'); + entry.className='log-entry'; + entry.innerHTML=`D${state.day} ${title}${desc?' — '+desc:''}`; + el.prepend(entry); + if(el.children.length>20) el.removeChild(el.lastChild); +} + +function endCampaign(){ + const win=state.votes>=50000; + const msg=win?'Congratulations! You won the election with '+state.votes.toLocaleString()+' votes!' : 'You lost the election with '+state.votes.toLocaleString()+' votes. Try a different strategy next time.'; + addLog('Election Day!',msg); + $('actionsList').innerHTML=`
Campaign Over — ${msg}

`; +} + +$('deliverSpeech').addEventListener('click',deliverSpeech); +updateUI(); +addLog('Campaign Kickoff','Your campaign for office has begun. You have 30 days and $1,000,000.'); diff --git a/Projects/Election Campaign Simulator/style.css b/Projects/Election Campaign Simulator/style.css new file mode 100644 index 00000000..3c119e41 --- /dev/null +++ b/Projects/Election Campaign Simulator/style.css @@ -0,0 +1,46 @@ +*,*::before,*::after{margin:0;padding:0;box-sizing:border-box} +:root{--bg:#0b1120;--surface:#111827;--card:rgba(30,41,59,0.6);--border:#334155;--gold:#d4a017;--gold-glow:rgba(212,160,23,0.12);--text:#f8fafc;--text2:#cbd5e1;--text3:#64748b;--accent:#93c5fd;--green:#22c55e;--red:#ef4444;--blue:#3b82f6;--radius:10px;--trans:all 0.3s cubic-bezier(0.16,1,0.3,1)} +body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--bg);color:var(--text2);min-height:100vh} +.app{max-width:1200px;margin:0 auto;padding:20px} +.topbar{text-align:center;padding:20px 0;border-bottom:1px solid var(--border);margin-bottom:20px} +.topbar h1{font-size:22px;font-weight:700;color:var(--gold);letter-spacing:1px} +.topbar .subtitle{font-size:13px;color:var(--text3);margin-top:4px} +.stats-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px} +.stat-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:16px;text-align:center;backdrop-filter:blur(8px)} +.stat-label{font-size:11px;color:var(--text3);text-transform:uppercase;letter-spacing:0.8px;display:block} +.stat-value{font-family:ui-monospace,Consolas,monospace;font-size:22px;font-weight:700;color:var(--text);margin-top:4px;display:block} +.stat-value.gold{color:var(--gold)} +.main-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px} +@media(max-width:800px){.main-grid{grid-template-columns:1fr}.stats-row{grid-template-columns:repeat(2,1fr)}} +.panel{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:20px;backdrop-filter:blur(8px)} +.panel h2{font-size:13px;font-weight:600;color:var(--accent);text-transform:uppercase;letter-spacing:1px;margin-bottom:14px;padding-bottom:8px;border-bottom:1px solid var(--border)} +.actions{display:grid;grid-template-columns:1fr;gap:8px} +.action-btn{padding:12px 16px;background:var(--surface);border:1px solid var(--border);border-radius:8px;color:var(--text2);font-size:13px;cursor:pointer;transition:var(--trans);text-align:left;font-family:inherit} +.action-btn:hover{border-color:var(--gold);background:var(--gold-glow)} +.action-btn .cost{font-family:ui-monospace,Consolas,monospace;font-size:11px;color:var(--gold);display:block;margin-top:3px} +.action-btn:disabled{opacity:0.3;cursor:not-allowed} +.speech-area select,.speech-area textarea{width:100%;padding:10px 12px;background:var(--surface);color:var(--text);border:1px solid var(--border);border-radius:8px;font-size:13px;margin-bottom:8px;font-family:inherit;outline:none} +.speech-area select:focus,.speech-area textarea:focus{border-color:var(--gold)} +.speech-area textarea{resize:vertical;min-height:80px} +.btn{padding:10px 24px;background:var(--gold-glow);border:1px solid var(--gold);border-radius:8px;color:var(--gold);font-size:13px;font-weight:500;cursor:pointer;transition:var(--trans);font-family:inherit;width:100%} +.btn:hover{box-shadow:0 0 20px var(--gold-glow)} +.btn:disabled{opacity:0.3;cursor:not-allowed} +.speech-log{margin-top:12px;max-height:200px;overflow-y:auto} +.speech-entry{padding:10px;background:var(--surface);border-radius:6px;margin-bottom:6px;font-size:12px;line-height:1.5} +.speech-entry .topic{color:var(--gold);font-weight:600} +.speech-entry .impact{color:var(--green)} +.sentiment-gauge{margin-bottom:16px} +.gauge-bar{height:12px;background:var(--surface);border-radius:6px;overflow:hidden;border:1px solid var(--border)} +.gauge-fill{height:100%;background:linear-gradient(90deg,var(--red),var(--gold),var(--green));border-radius:6px;transition:width 0.6s cubic-bezier(0.16,1,0.3,1)} +.gauge-labels{display:flex;justify-content:space-between;font-size:10px;color:var(--text3);margin-top:4px} +.gauge-labels span:nth-child(2){color:var(--gold);font-weight:600} +.demographics{display:grid;gap:8px} +.demo-row{display:flex;justify-content:space-between;align-items:center;font-size:12px;padding:4px 0} +.demo-row .label{color:var(--text2)} +.demo-row .val{font-family:ui-monospace,Consolas,monospace;font-size:11px} +.event-log{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:20px;backdrop-filter:blur(8px)} +.event-log h3{font-size:12px;font-weight:600;color:var(--accent);text-transform:uppercase;letter-spacing:1px;margin-bottom:10px} +.log-entries{max-height:180px;overflow-y:auto} +.log-entry{padding:8px 0;border-bottom:1px solid rgba(51,65,85,0.4);font-size:12px;color:var(--text2);line-height:1.5;display:flex;gap:8px} +.log-entry .day{font-family:ui-monospace,Consolas,monospace;color:var(--gold);white-space:nowrap} +.empty-state{text-align:center;padding:20px;color:var(--text3);font-size:12px} diff --git a/Projects/Election Campaign Simulator/thumbnail.svg b/Projects/Election Campaign Simulator/thumbnail.svg new file mode 100644 index 00000000..51a408bc --- /dev/null +++ b/Projects/Election Campaign Simulator/thumbnail.svg @@ -0,0 +1,27 @@ + + + + ELECTION CAMPAIGN + Simulator + + $1,000,000 + Starting Budget + + TV Ads · Rallies · Canvassing + Social Media · Town Halls + Fundraising · Opposition Research + + Speech Writer + Write and deliver speeches onEconomy, Healthcare, Education,National Security, Environment + Each speech impacts specific demographics + + Voter Sentiment + + + Youth · Suburban · Rural + Urban · Seniors · Undecided + + Budget · Speeches · Voter Sentiment + Interactive Campaign Management Simulation + 30 days to win the election + diff --git a/Projects/Public Policy Impact Simulator/README.md b/Projects/Public Policy Impact Simulator/README.md new file mode 100644 index 00000000..8c0adc97 --- /dev/null +++ b/Projects/Public Policy Impact Simulator/README.md @@ -0,0 +1,10 @@ +# Public Policy Impact Simulator + +Enact policy changes and observe their simulated economic effects on GDP, unemployment, inflation, budget deficit, and consumer confidence over time. + +## Features +- **Policy Library** — 10 distinct policies from tax cuts to universal basic income +- **Economic Indicators** — Real-time GDP, unemployment, inflation, deficit, and confidence tracking +- **Impact Timeline** — Visual chart showing how each policy affects the economy over years + +Open `index.html` in any browser to start simulating. diff --git a/Projects/Public Policy Impact Simulator/index.html b/Projects/Public Policy Impact Simulator/index.html new file mode 100644 index 00000000..b48473ac --- /dev/null +++ b/Projects/Public Policy Impact Simulator/index.html @@ -0,0 +1,59 @@ + + + + + + + Public Policy Impact Simulator + + + +
+
+

Public Policy Impact Simulator

+

Policy Changes · Economic Effects

+
+ +
+
+
GDP Growth2.1%
+
Unemployment4.8%
+
Inflation2.3%
+
Budget Deficit$340B
+
Consumer Confidence72
+
Year2026
+
+ +
+
+

Available Policies

+
+
+ +
+

Enacted Policies

+

No policies enacted yet. Choose from the left panel.

+
+ +
+

Economic Impact Timeline

+
+
+
+
+ GDP + Unemployment + Inflation +
+
+
+ +
+

Policy Impact Log

+

Simulation started. Enact policies to see their effects.

+
+
+
+ + + diff --git a/Projects/Public Policy Impact Simulator/project.json b/Projects/Public Policy Impact Simulator/project.json new file mode 100644 index 00000000..8d000102 --- /dev/null +++ b/Projects/Public Policy Impact Simulator/project.json @@ -0,0 +1,10 @@ +{ + "title": "Public Policy Impact Simulator", + "description": "Enact policy changes and observe their economic effects on GDP, unemployment, inflation, and more.", + "entry": "index.html", + "tags": ["html", "css", "javascript", "simulation"], + "author": { + "name": "Girish Madarkar", + "github": "Girish0902" + } +} diff --git a/Projects/Public Policy Impact Simulator/script.js b/Projects/Public Policy Impact Simulator/script.js new file mode 100644 index 00000000..839267a7 --- /dev/null +++ b/Projects/Public Policy Impact Simulator/script.js @@ -0,0 +1,170 @@ +const state = { + year: 2026, + gdp: 2.1, + unemployment: 4.8, + inflation: 2.3, + deficit: 340, + confidence: 72, + enactedPolicies: [], + history: [], +}; + +const POLICIES = [ + { + name: "Cut Corporate Tax", + desc: "Reduce corporate tax rate from 21% to 15%", + effects: { gdp: 0.8, unemployment: -0.3, inflation: 0.4, deficit: 120, confidence: 5 }, + }, + { + name: "Increase Infrastructure Spending", + desc: "$500B investment in roads, bridges, and broadband", + effects: { gdp: 1.2, unemployment: -0.6, inflation: 0.3, deficit: 180, confidence: 8 }, + }, + { + name: "Raise Minimum Wage", + desc: "Increase federal minimum wage to $15/hour", + effects: { gdp: 0.1, unemployment: 0.5, inflation: 0.6, deficit: 20, confidence: 3 }, + }, + { + name: "Universal Healthcare", + desc: "Implement single-payer healthcare system", + effects: { gdp: -0.3, unemployment: 0.1, inflation: 0.2, deficit: 250, confidence: 6 }, + }, + { + name: "Education Reform", + desc: "Free public college and vocational training", + effects: { gdp: 0.5, unemployment: -0.2, inflation: 0.1, deficit: 90, confidence: 7 }, + }, + { + name: "Green Energy Subsidies", + desc: "Tax credits for renewable energy adoption", + effects: { gdp: 0.6, unemployment: -0.1, inflation: 0.2, deficit: 60, confidence: 4 }, + }, + { + name: "Deregulation Package", + desc: "Reduce business regulations across industries", + effects: { gdp: 0.7, unemployment: -0.4, inflation: 0.1, deficit: -10, confidence: 2 }, + }, + { + name: "Trade Tariffs", + desc: "Impose 10% tariff on imported goods", + effects: { gdp: -0.4, unemployment: 0.2, inflation: 1.1, deficit: -40, confidence: -3 }, + }, + { + name: "Universal Basic Income", + desc: "$500/month basic income for all citizens", + effects: { gdp: 0.3, unemployment: 0.3, inflation: 1.0, deficit: 320, confidence: 2 }, + }, + { + name: "Housing Affordability Act", + desc: "Subsidies and incentives for affordable housing", + effects: { gdp: 0.4, unemployment: -0.2, inflation: 0.3, deficit: 70, confidence: 5 }, + }, +]; + +const $=id=>document.getElementById(id); + +function addLog(msg){ + const el=$('logEntries'); + const e=document.createElement('div'); e.className='log-entry'; + e.innerHTML=`${state.year} ${msg}`; + el.prepend(e); + if(el.children.length>30) el.removeChild(el.lastChild); +} + +function updateUI(){ + $('gdpVal').textContent=state.gdp.toFixed(1)+'%'; + $('gdpVal').style.color=state.gdp>=2?'var(--green)':state.gdp>=0?'var(--gold)':'var(--red)'; + $('unempVal').textContent=state.unemployment.toFixed(1)+'%'; + $('unempVal').style.color=state.unemployment<=5?'var(--green)':state.unemployment<=7?'var(--gold)':'var(--red)'; + $('inflVal').textContent=state.inflation.toFixed(1)+'%'; + $('inflVal').style.color=state.inflation<=3?'var(--green)':state.inflation<=5?'var(--gold)':'var(--red)'; + $('defVal').textContent='$'+(state.deficit>=0?state.deficit:0)+'B'; + $('defVal').style.color=state.deficit<=200?'var(--green)':state.deficit<=400?'var(--gold)':'var(--red)'; + $('confVal').textContent=state.confidence; + $('confVal').style.color=state.confidence>=70?'var(--green)':state.confidence>=50?'var(--gold)':'var(--red)'; + $('yearVal').textContent=state.year; + + renderPolicies(); + renderEnacted(); + renderChart(); +} + +function renderPolicies(){ + const list=$('policyList'); + list.innerHTML=POLICIES.map((p,i)=>{ + const canEnact=!state.enactedPolicies.includes(i); + return ``; + }).join(''); + list.querySelectorAll('.policy-btn').forEach(b=>b.addEventListener('click',()=>enact(parseInt(b.dataset.idx)))); +} + +function enact(idx){ + const p=POLICIES[idx]; + state.enactedPolicies.push(idx); + state.gdp+=p.effects.gdp; + state.unemployment+=p.effects.unemployment; + state.inflation+=p.effects.inflation; + state.deficit+=p.effects.deficit; + state.confidence+=p.effects.confidence; + state.gdp=Math.round(state.gdp*10)/10; + state.unemployment=Math.round(Math.max(1,state.unemployment)*10)/10; + state.inflation=Math.round(Math.max(0,state.inflation)*10)/10; + state.deficit=Math.max(0,state.deficit); + state.confidence=Math.min(100,Math.max(0,state.confidence)); + state.year++; + + state.history.push({ + year: state.year-1, + policy: p.name, + gdp: state.gdp, + unemployment: state.unemployment, + inflation: state.inflation, + }); + + addLog(`Enacted "${p.name}" — GDP: ${state.gdp.toFixed(1)}%, Unemployment: ${state.unemployment.toFixed(1)}%, Inflation: ${state.inflation.toFixed(1)}%`); + updateUI(); +} + +function renderEnacted(){ + const el=$('enactedPolicies'); + if(!state.enactedPolicies.length){ + el.innerHTML='

No policies enacted yet. Choose from the left panel.

'; + return; + } + el.innerHTML=state.enactedPolicies.map(i=>{ + const p=POLICIES[i]; + return `
${p.name}
${p.desc}
`; + }).join(''); +} + +function renderChart(){ + const bars=$('chartBars'); + const data=state.history; + if(!data.length){ + bars.innerHTML='
Enact policies to see the economic impact timeline.
'; + return; + } + const max=Math.max(...data.map(d=>Math.max(d.gdp,d.unemployment,d.inflation,5))); + bars.innerHTML=data.map(d=>{ + const gH=Math.max(2,(d.gdp/max)*180); + const uH=Math.max(2,(d.unemployment/max)*180); + const iH=Math.max(2,(d.inflation/max)*180); + return `
+
+
+
+
${d.year}
`; + }).join(''); +} + +updateUI(); +addLog('Simulation started. GDP: 2.1%, Unemployment: 4.8%, Inflation: 2.3%'); diff --git a/Projects/Public Policy Impact Simulator/style.css b/Projects/Public Policy Impact Simulator/style.css new file mode 100644 index 00000000..85700727 --- /dev/null +++ b/Projects/Public Policy Impact Simulator/style.css @@ -0,0 +1,39 @@ +*,*::before,*::after{margin:0;padding:0;box-sizing:border-box} +:root{--bg:#0b1120;--surface:#111827;--card:rgba(30,41,59,0.6);--border:#334155;--gold:#d4a017;--gold-glow:rgba(212,160,23,0.12);--text:#f8fafc;--text2:#cbd5e1;--text3:#64748b;--accent:#93c5fd;--green:#22c55e;--red:#ef4444;--radius:10px;--trans:all 0.3s cubic-bezier(0.16,1,0.3,1)} +body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--bg);color:var(--text2);min-height:100vh} +.app{max-width:1200px;margin:0 auto;padding:20px} +.topbar{text-align:center;padding:20px 0;border-bottom:1px solid var(--border);margin-bottom:20px} +.topbar h1{font-size:22px;font-weight:700;color:var(--gold);letter-spacing:1px} +.topbar .subtitle{font-size:13px;color:var(--text3);margin-top:4px} +.indicators{display:grid;grid-template-columns:repeat(6,1fr);gap:10px;margin-bottom:20px} +@media(max-width:900px){.indicators{grid-template-columns:repeat(3,1fr)}} +.indicator{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:14px;text-align:center;backdrop-filter:blur(8px)} +.ind-label{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:0.8px} +.ind-value{font-family:ui-monospace,Consolas,monospace;font-size:20px;font-weight:700;color:var(--text);margin-top:4px;display:block} +.main-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:20px} +.panel{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:20px;backdrop-filter:blur(8px)} +.panel.wide{grid-column:1/-1} +.panel h2{font-size:12px;font-weight:600;color:var(--accent);text-transform:uppercase;letter-spacing:1px;margin-bottom:14px;padding-bottom:8px;border-bottom:1px solid var(--border)} +.policy-list,.enacted-list{display:grid;gap:8px} +.policy-btn{width:100%;padding:12px 16px;background:var(--surface);border:1px solid var(--border);border-radius:8px;color:var(--text2);font-size:13px;cursor:pointer;transition:var(--trans);text-align:left;font-family:inherit} +.policy-btn:hover{border-color:var(--gold);background:var(--gold-glow)} +.policy-btn .effects{font-size:11px;color:var(--text3);display:block;margin-top:4px} +.policy-btn .effects .pos{color:var(--green)}.policy-btn .effects .neg{color:var(--red)} +.policy-btn:disabled{opacity:0.3;cursor:not-allowed} +.enacted-item{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px;margin-bottom:8px;font-size:12px;line-height:1.6} +.enacted-item .name{color:var(--gold);font-weight:600} +.chart-area{height:200px;display:flex;align-items:flex-end;padding:10px 0} +.chart-bars{display:flex;align-items:flex-end;gap:6px;width:100%;height:100%} +.chart-col{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;position:relative} +.chart-bar-wrap{width:100%;display:flex;gap:2px;height:100%;align-items:flex-end} +.chart-bar{flex:1;border-radius:3px 3px 0 0;min-height:2px;transition:height 0.6s cubic-bezier(0.16,1,0.3,1)} +.chart-bar.gdp{background:var(--green)}.chart-bar.unemp{background:var(--red)}.chart-bar.infl{background:var(--gold)} +.chart-col .year-label{font-size:9px;color:var(--text3);margin-top:4px;white-space:nowrap} +.chart-legend{display:flex;gap:20px;justify-content:center;margin-top:8px;font-size:11px;color:var(--text2)} +.chart-legend .dot{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:4px;vertical-align:middle} +.event-log{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:20px;backdrop-filter:blur(8px)} +.event-log h3{font-size:12px;font-weight:600;color:var(--accent);text-transform:uppercase;letter-spacing:1px;margin-bottom:10px} +.log-entries{max-height:200px;overflow-y:auto} +.log-entry{padding:8px 0;border-bottom:1px solid rgba(51,65,85,0.4);font-size:12px;color:var(--text2);line-height:1.5} +.log-entry .year{font-family:ui-monospace,Consolas,monospace;color:var(--gold)} +.empty-state{text-align:center;padding:30px;color:var(--text3);font-size:12px} diff --git a/Projects/Public Policy Impact Simulator/thumbnail.svg b/Projects/Public Policy Impact Simulator/thumbnail.svg new file mode 100644 index 00000000..6031d7cc --- /dev/null +++ b/Projects/Public Policy Impact Simulator/thumbnail.svg @@ -0,0 +1,35 @@ + + + + PUBLIC POLICY IMPACT + Simulator + + GDP GROWTH + 2.1% + + UNEMPLOYMENT + 4.8% + + INFLATION + 2.3% + + CONFIDENCE + 72 + + ECONOMIC IMPACT TIMELINE + + + + + + + + + + + Policy Changes · Economic Effects + + + 10 distinct policies to enact and observe + Interactive Economic Policy Simulation +