Spaces:
Running
Running
| class StatMeter extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| document.addEventListener('state-update', () => this.update()); | |
| this.update(); | |
| } | |
| update() { | |
| const label = this.getAttribute('label'); | |
| const icon = this.getAttribute('icon'); | |
| const val = state.stats[label] || 0; | |
| // Color logic based on value - "Invisible Future Meter" logic | |
| let colorClass = '#22c55e'; // Green | |
| let glowClass = ''; | |
| if (val < 30) { | |
| colorClass = '#ef4444'; // Red - Danger | |
| glowClass = 'box-shadow: 0 0 10px rgba(239, 68, 68, 0.5);'; | |
| } else if (val < 60) { | |
| colorClass = '#eab308'; // Yellow - Caution | |
| } else { | |
| colorClass = '#3b82f6'; // Blue - Good (using blue for high stat instead of green for money) | |
| } | |
| // Icon mapping | |
| const iconMap = { | |
| 'stability': 'shield', | |
| 'safety': 'activity', | |
| 'debt': 'arrow-down-circle', | |
| 'scamRisk': 'alert-triangle', | |
| 'wealth': 'trending-up' | |
| }; | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| .stat-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; font-size: 0.8rem; } | |
| .bar-bg { flex-grow: 1; height: 8px; background: #334155; border-radius: 4px; overflow: hidden; position: relative; } | |
| .bar-fill { | |
| height: 100%; | |
| transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.3s; | |
| ${glowClass} | |
| } | |
| .label { width: 70px; color: #cbd5e1; display: flex; align-items: center; gap: 6px; font-weight: 500; } | |
| .value { width: 30px; text-align: right; color: #94a3b8; font-family: monospace; } | |
| </style> | |
| <div class="stat-row"> | |
| <div class="label"> | |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg> | |
| ${label} | |
| </div> | |
| <div class="bar-bg"> | |
| <div class="bar-fill" style="width: ${val}%; background-color: ${colorClass};"></div> | |
| </div> | |
| <div class="value">${val}</div> | |
| </div> | |
| `; | |
| } | |
| } | |
| customElements.define('stat-meter', StatMeter); |