landvex: Fixar och tester klara för alla komponenter

- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
This commit is contained in:
Bernt
2026-07-05 06:41:32 +00:00
parent f4f853d94b
commit aee0f09db8
19583 changed files with 1450867 additions and 1153 deletions
@@ -0,0 +1,256 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex Aid Intelligence - Evidence-Based Verification</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #f8f9fa; color: #1a1a1a; line-height: 1.6; }
.header { background: #fff; border-bottom: 1px solid #e9ecef; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #1a1a1a; }
.header .subtitle { color: #6c757d; font-size: 0.85rem; }
.nav { background: #fff; border-bottom: 1px solid #e9ecef; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #6c757d; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #0066cc; border-bottom-color: #0066cc; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.philosophy { background: #fff; border-radius: 12px; padding: 32px; margin-bottom: 32px; border-left: 4px solid #0066cc; }
.philosophy h2 { font-size: 1.25rem; margin-bottom: 16px; color: #1a1a1a; }
.philosophy p { color: #495057; margin-bottom: 12px; }
.philosophy ul { margin-left: 20px; color: #495057; }
.philosophy li { margin-bottom: 8px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; margin-bottom: 32px; }
.stat-card { background: #fff; border-radius: 12px; padding: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.stat-card h3 { font-size: 0.75rem; color: #6c757d; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #1a1a1a; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #28a745; }
.section { background: #fff; border-radius: 12px; padding: 24px; margin-bottom: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.section h2 { font-size: 1.1rem; margin-bottom: 16px; color: #1a1a1a; }
.project-card { border: 1px solid #e9ecef; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.project-card h3 { font-size: 1rem; margin-bottom: 8px; }
.project-card .meta { font-size: 0.8rem; color: #6c757d; margin-bottom: 8px; }
.project-card .findings { font-size: 0.85rem; color: #495057; }
.project-card .findings li { margin-bottom: 4px; }
.score { display: inline-block; padding: 4px 12px; border-radius: 4px; font-size: 0.75rem; font-weight: 600; }
.score.high { background: #d4edda; color: #155724; }
.score.medium { background: #fff3cd; color: #856404; }
.score.low { background: #f8d7da; color: #721c24; }
.discrepancy { background: #fff3cd; border: 1px solid #ffeaa7; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.discrepancy h4 { color: #856404; margin-bottom: 8px; }
.discrepancy p { font-size: 0.85rem; color: #495057; }
.positive { background: #d4edda; border: 1px solid #c3e6cb; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.positive h4 { color: #155724; margin-bottom: 8px; }
.framework-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.framework-card { border: 1px solid #e9ecef; border-radius: 8px; padding: 16px; }
.framework-card h4 { font-size: 0.95rem; margin-bottom: 8px; }
.framework-card p { font-size: 0.8rem; color: #6c757d; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>Landvex Aid Intelligence</h1>
<div class="subtitle">Evidence-Based Impact Verification</div>
</div>
<div style="text-align: right;">
<div style="font-size: 0.8rem; color: #6c757d;">Projects Monitored</div>
<div style="font-size: 1.5rem; font-weight: 700;">1,250</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #6c757d;">← Admin</a>
<a href="#" class="active">Dashboard</a>
<a href="#projects">Projects</a>
<a href="#verification">Verification</a>
<a href="#research">Research</a>
</div>
<div class="main">
<div class="philosophy">
<h2>Our Mission</h2>
<p>Build Landvex Aid Intelligence as the world's leading <strong>independent platform</strong> for measuring, verifying and improving the real-world impact of development aid.</p>
<p>We believe development aid should create <strong>measurable, sustainable improvements</strong>. We measure observable progress rather than assuming success or failure.</p>
<h2 style="margin-top: 20px; font-size: 1rem;">Core Principles</h2>
<ul>
<li>Evidence over speculation</li>
<li>Transparency over opacity</li>
<li>Continuous learning over blame</li>
<li>Independent verification over assumptions</li>
<li>Long-term societal outcomes over short-term activity metrics</li>
</ul>
</div>
<div class="stats-grid">
<div class="stat-card">
<h3>Projects Verified</h3>
<div class="value">890</div>
<div class="change positive">71% of total</div>
</div>
<div class="stat-card">
<h3>Avg Confidence</h3>
<div class="value">82%</div>
<div class="change positive">+3% vs last quarter</div>
</div>
<div class="stat-card">
<h3>Evidence Sources</h3>
<div class="value">5</div>
<div class="change">Satellite, Field, AI, Open Data, Official</div>
</div>
<div class="stat-card">
<h3>Countries</h3>
<div class="value">9</div>
<div class="change">Sub-Saharan Africa</div>
</div>
<div class="stat-card">
<h3>Observations</h3>
<div class="value">45K</div>
<div class="change positive">+3,200 this month</div>
</div>
<div class="stat-card">
<h3>Flagged for Review</h3>
<div class="value" style="color: #856404;">15</div>
<div class="change">Signals, not accusations</div>
</div>
</div>
<div class="section">
<h2>Verification Framework</h2>
<p style="color: #6c757d; margin-bottom: 16px;">Multidimensional evaluation of observable outcomes. Every score includes confidence intervals.</p>
<div class="framework-grid">
<div class="framework-card">
<h4>Infrastructure Completion</h4>
<p>Observable physical completion of planned infrastructure</p>
</div>
<div class="framework-card">
<h4>Operational Continuity</h4>
<p>Whether facilities remain operational over time</p>
</div>
<div class="framework-card">
<h4>Maintenance Quality</h4>
<p>Observable maintenance and upkeep</p>
</div>
<div class="framework-card">
<h4>Accessibility</h4>
<p>Physical and economic access for target population</p>
</div>
<div class="framework-card">
<h4>Community Utilization</h4>
<p>Actual use by intended beneficiaries</p>
</div>
<div class="framework-card">
<h4>Environmental Sustainability</h4>
<p>Environmental impact and sustainability</p>
</div>
<div class="framework-card">
<h4>Economic Enablement</h4>
<p>Economic activity generated or enabled</p>
</div>
</div>
</div>
<div class="section">
<h2>Projects with Discrepancies (Signals for Review)</h2>
<p style="color: #6c757d; margin-bottom: 16px;">These findings indicate areas where additional verification may be valuable. They are not conclusions of wrongdoing.</p>
<div class="discrepancy">
<h4>⚠️ Schedule Variance - Mogadishu Primary School</h4>
<p><strong>Reported:</strong> 95% complete (June 2026)<br>
<strong>Observed:</strong> 85% complete (July 2026)<br>
<strong>Evidence:</strong> Field observation, Satellite, AI analysis<br>
<strong>Confidence:</strong> 78% | <strong>Severity:</strong> Medium<br>
<strong>Recommended Action:</strong> Follow-up observation in 30 days</p>
</div>
<div class="discrepancy">
<h4>⚠️ Activity Gap - Lagos Road Rehabilitation</h4>
<p><strong>Reported:</strong> Active construction<br>
<strong>Observed:</strong> No activity for 90 days, equipment removed<br>
<strong>Evidence:</strong> Field observation, Satellite time-series<br>
<strong>Confidence:</strong> 92% | <strong>Severity:</strong> High<br>
<strong>Recommended Action:</strong> Contact implementing partner for status update</p>
</div>
</div>
<div class="section">
<h2>Positive Outcomes (Benchmark Projects)</h2>
<p style="color: #6c757d; margin-bottom: 16px;">Projects demonstrating strong implementation and sustained operation. These enable benchmarking and dissemination of successful practices.</p>
<div class="positive">
<h4>✅ Accra Solar Microgrid - Ghana</h4>
<p><strong>SII Score:</strong> 89/100 | <strong>Confidence:</strong> 92%<br>
<strong>Strengths:</strong> Strong implementation, Sustained operation (24+ months), High community utilization, Long-term maintenance observed, Positive environmental outcomes<br>
<strong>Benchmark Category:</strong> Energy Infrastructure</p>
</div>
<div class="positive">
<h4>✅ Nairobi Digital Health Records - Kenya</h4>
<p><strong>SII Score:</strong> 84/100 | <strong>Confidence:</strong> 86%<br>
<strong>Strengths:</strong> Operational continuity, Staff training evident, Patient utilization increasing, Data transparency<br>
<strong>Benchmark Category:</strong> Digital Health</p>
</div>
</div>
<div class="section">
<h2>Sustainable Impact Index (SII)</h2>
<p style="color: #6c757d; margin-bottom: 16px;">Estimates long-term observable contribution of development projects. Each component based on measurable indicators with confidence estimates.</p>
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px;">
<div class="framework-card">
<h4>Longevity (15%)</h4>
<p>Years of continuous operation</p>
</div>
<div class="framework-card">
<h4>Community Benefit (15%)</h4>
<p>Observable community value</p>
</div>
<div class="framework-card">
<h4>Infrastructure Durability (15%)</h4>
<p>Physical condition over time</p>
</div>
<div class="framework-card">
<h4>Maintenance (10%)</h4>
<p>Observable upkeep quality</p>
</div>
<div class="framework-card">
<h4>Population Reach (10%)</h4>
<p>Number of beneficiaries</p>
</div>
<div class="framework-card">
<h4>Economic Enablement (10%)</h4>
<p>Economic activity generated</p>
</div>
</div>
</div>
<div class="section">
<h2>Development Effectiveness Science</h2>
<p style="color: #6c757d; margin-bottom: 16px;">Research program developing scientifically grounded indices and models for measuring long-term societal impact.</p>
<div class="framework-grid">
<div class="framework-card">
<h4>Impact Measurement Methodology</h4>
<p>Rigorous methods for measuring development outcomes</p>
</div>
<div class="framework-card">
<h4>Longitudinal Impact Analysis</h4>
<p>Track project outcomes over 5-10 year periods</p>
</div>
<div class="framework-card">
<h4>Bias Detection & Correction</h4>
<p>Identify and correct for observational biases</p>
</div>
<div class="framework-card">
<h4>Predictive Sustainability Modeling</h4>
<p>Predict long-term sustainability from early indicators</p>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,211 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex Aid Intelligence</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #0a0a0a; color: #fff; }
.header { background: #111; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #333; }
.header h1 { font-size: 1.5rem; }
.header .subtitle { color: #666; font-size: 0.8rem; }
.nav { background: #111; padding: 0 40px; display: flex; gap: 4px; border-bottom: 1px solid #333; }
.nav a { color: #999; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; }
.nav a:hover, .nav a.active { color: #fff; background: #222; }
.main { padding: 40px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 20px; margin-bottom: 40px; }
.stat-card { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; }
.stat-card h3 { font-size: 0.75rem; color: #666; margin-bottom: 8px; text-transform: uppercase; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #fff; }
.stat-card .change { font-size: 0.8rem; color: #34c759; margin-top: 4px; }
.section { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.1rem; margin-bottom: 16px; color: #fff; }
.map-placeholder { background: #1a1a1a; border-radius: 8px; height: 400px; display: flex; align-items: center; justify-content: center; color: #666; }
table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
th, td { text-align: left; padding: 12px; border-bottom: 1px solid #333; }
th { color: #666; font-size: 0.75rem; text-transform: uppercase; }
tr:hover { background: #1a1a1a; }
.status { display: inline-block; padding: 4px 12px; border-radius: 4px; font-size: 0.75rem; font-weight: 600; }
.status.active { background: #1a3a1a; color: #34c759; }
.status.completed { background: #1a1a3a; color: #5ac8fa; }
.status.delayed { background: #3a1a1a; color: #ff3b30; }
.score { font-weight: 700; }
.score.high { color: #34c759; }
.score.medium { color: #ff9500; }
.score.low { color: #ff3b30; }
.alert { background: #3a1a1a; border: 1px solid #ff3b30; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.alert h4 { color: #ff3b30; margin-bottom: 8px; }
.alert p { color: #ccc; font-size: 0.85rem; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.country-card { background: #1a1a1a; border-radius: 8px; padding: 16px; display: flex; justify-content: space-between; align-items: center; }
.country-card h4 { font-size: 1rem; }
.country-card .score { font-size: 1.5rem; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>Landvex Aid Intelligence</h1>
<div class="subtitle">Independent Impact Verification</div>
</div>
<div style="text-align: right;">
<div style="font-size: 0.8rem; color: #666;">Projects Monitored</div>
<div style="font-size: 1.5rem; font-weight: 700;">1,250</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Dashboard</a>
<a href="#projects">Projects</a>
<a href="#map">Map</a>
<a href="#alerts">Alerts</a>
<a href="#reports">Reports</a>
</div>
<div class="main">
<div class="stats-grid">
<div class="stat-card">
<h3>Avg AII Score</h3>
<div class="value">72</div>
<div class="change">+3 vs last quarter</div>
</div>
<div class="stat-card">
<h3>Observations</h3>
<div class="value">45K</div>
<div class="change">+3,200 this month</div>
</div>
<div class="stat-card">
<h3>Contributors</h3>
<div class="value">3,200</div>
<div class="change">+450 this month</div>
</div>
<div class="stat-card">
<h3>Countries</h3>
<div class="value">9</div>
<div class="change">3 regions</div>
</div>
<div class="stat-card">
<h3>Funding Monitored</h3>
<div class="value">$450M</div>
<div class="change">Across all projects</div>
</div>
<div class="stat-card">
<h3>Risk Alerts</h3>
<div class="value" style="color: #ff9500;">8</div>
<div class="change">2 high priority</div>
</div>
</div>
<div class="grid-2">
<div class="section">
<h2>Project Map</h2>
<div class="map-placeholder">
Interactive Map<br>
1,250 projects across 9 countries
</div>
</div>
<div class="section">
<h2>Risk Alerts</h2>
<div class="alert">
<h4>⚠️ Abandoned Project Detected</h4>
<p><strong>Lagos Road Rehabilitation</strong> - No activity for 90 days. Equipment removed.</p>
</div>
<div class="alert" style="background: #3a3a1a; border-color: #ff9500;">
<h4 style="color: #ff9500;">⚠️ Infrastructure Deterioration</h4>
<p><strong>Nairobi Health Clinic</strong> - Accelerated deterioration observed.</p>
</div>
</div>
</div>
<div class="section">
<h2>Country Performance (Aid Impact Index)</h2>
<div style="display: grid; gap: 12px;">
<div class="country-card">
<div>
<h4>Ghana</h4>
<div style="font-size: 0.8rem; color: #666;">West Africa • 89 projects</div>
</div>
<div class="score high">81</div>
</div>
<div class="country-card">
<div>
<h4>South Africa</h4>
<div style="font-size: 0.8rem; color: #666;">Southern Africa • 112 projects</div>
</div>
<div class="score high">82</div>
</div>
<div class="country-card">
<div>
<h4>Kenya</h4>
<div style="font-size: 0.8rem; color: #666;">East Africa • 92 projects</div>
</div>
<div class="score medium">74</div>
</div>
<div class="country-card">
<div>
<h4>Somalia</h4>
<div style="font-size: 0.8rem; color: #666;">East Africa • 45 projects</div>
</div>
<div class="score medium">72</div>
</div>
<div class="country-card">
<div>
<h4>Nigeria</h4>
<div style="font-size: 0.8rem; color: #666;">West Africa • 134 projects</div>
</div>
<div class="score low">63</div>
</div>
</div>
</div>
<div class="section">
<h2>Recent Projects</h2>
<table>
<thead>
<tr>
<th>Project</th>
<th>Country</th>
<th>Type</th>
<th>Status</th>
<th>AII Score</th>
<th>Observations</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mogadishu Primary School Renovation</td>
<td>Somalia</td>
<td>School</td>
<td><span class="status active">Active</span></td>
<td><span class="score medium">72</span></td>
<td>156</td>
</tr>
<tr>
<td>Kampala Water Supply Extension</td>
<td>Uganda</td>
<td>Water</td>
<td><span class="status active">Active</span></td>
<td><span class="score medium">68</span></td>
<td>203</td>
</tr>
<tr>
<td>Accra Solar Microgrid</td>
<td>Ghana</td>
<td>Renewable</td>
<td><span class="status completed">Completed</span></td>
<td><span class="score high">89</span></td>
<td>312</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
@@ -0,0 +1,402 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex Unified Admin</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #f5f5f7; color: #1a1a1a; }
.sidebar { width: 260px; background: #0a0a0a; color: #fff; position: fixed; height: 100vh; padding: 24px; overflow-y: auto; }
.sidebar h1 { font-size: 1.25rem; margin-bottom: 8px; }
.sidebar .subtitle { font-size: 0.75rem; color: #666; margin-bottom: 32px; }
.sidebar nav a { display: block; color: #999; text-decoration: none; padding: 10px 16px; border-radius: 8px; margin-bottom: 2px; transition: all 0.2s; font-size: 0.875rem; cursor: pointer; }
.sidebar nav a:hover, .sidebar nav a.active { color: #fff; background: rgba(255,255,255,0.1); }
.sidebar nav .section { color: #666; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 1px; margin: 16px 0 8px 16px; }
.main { margin-left: 260px; padding: 32px; }
.header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 32px; }
.header h2 { font-size: 1.75rem; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.stat-card { background: #fff; border-radius: 12px; padding: 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); cursor: pointer; transition: transform 0.2s; }
.stat-card:hover { transform: translateY(-2px); }
.stat-card h3 { font-size: 0.75rem; color: #666; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 1.75rem; font-weight: 700; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #34c759; }
.section { background: #fff; border-radius: 12px; padding: 24px; margin-bottom: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.section h3 { font-size: 1.1rem; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
.status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.status-dot.green { background: #34c759; }
.status-dot.yellow { background: #ff9500; }
.status-dot.red { background: #ff3b30; }
table { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #eee; }
th { font-weight: 600; color: #666; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; }
tr:hover { background: #f9f9f9; cursor: pointer; }
.status { display: inline-block; padding: 3px 10px; border-radius: 4px; font-size: 0.7rem; font-weight: 600; }
.status.published { background: #e8f5e9; color: #2e7d32; }
.status.active { background: #e3f2fd; color: #1565c0; }
.btn { display: inline-block; padding: 8px 16px; border-radius: 6px; border: none; cursor: pointer; font-size: 0.8rem; font-weight: 600; }
.btn-primary { background: #0066cc; color: #fff; }
.btn-secondary { background: #f5f5f5; color: #333; }
.actions { display: flex; gap: 8px; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.module-card { border: 1px solid #eee; border-radius: 8px; padding: 16px; cursor: pointer; transition: all 0.2s; }
.module-card:hover { border-color: #0066cc; box-shadow: 0 2px 8px rgba(0,102,204,0.1); }
.module-card h4 { font-size: 0.9rem; margin-bottom: 8px; display: flex; align-items: center; gap: 8px; }
.module-card p { font-size: 0.8rem; color: #666; }
.loading { text-align: center; padding: 40px; color: #666; }
.error { background: #ffebee; color: #c62828; padding: 16px; border-radius: 8px; margin-bottom: 16px; }
.hidden { display: none; }
</style>
</head>
<body>
<div class="sidebar">
<h1>Landvex Unified</h1>
<div class="subtitle">Admin System</div>
<nav>
<a onclick="showSection('overview')" class="active" id="nav-overview">Overview</a>
<div class="section">Content</div>
<a onclick="showSection('articles')" id="nav-articles">Articles</a>
<a onclick="showSection('seo')" id="nav-seo">SEO & Schema</a>
<div class="section">quiXzoom</div>
<a onclick="showSection('missions')" id="nav-missions">Missions</a>
<a onclick="showSection('contributors')" id="nav-contributors">Contributors</a>
<a onclick="showSection('earnings')" id="nav-earnings">Earnings</a>
<div class="section">Economy</div>
<a onclick="showSection('ledger')" id="nav-ledger">Ledger</a>
<a onclick="showSection('accounts')" id="nav-accounts">Accounts</a>
<div class="section">HR</div>
<a onclick="showSection('employees')" id="nav-employees">Employees</a>
<a onclick="showSection('contractors')" id="nav-contractors">Contractors</a>
<div class="section">System</div>
<a onclick="showSection('health')" id="nav-health">Health</a>
<a onclick="showSection('settings')" id="nav-settings">Settings</a>
</nav>
</div>
<div class="main">
<div id="overview" class="page-section">
<div class="header">
<h2>Unified Dashboard</h2>
<div class="actions">
<button class="btn btn-primary" onclick="alert('New Article - Coming soon')">+ New Article</button>
<button class="btn btn-secondary" onclick="alert('New Mission - Coming soon')">+ New Mission</button>
</div>
</div>
<div class="stats-grid">
<div class="stat-card" onclick="showSection('articles')">
<h3>Articles</h3>
<div class="value" id="stat-articles">-</div>
<div class="change positive">Published</div>
</div>
<div class="stat-card" onclick="showSection('contributors')">
<h3>Contributors</h3>
<div class="value" id="stat-contributors">-</div>
<div class="change positive">Active</div>
</div>
<div class="stat-card" onclick="showSection('accounts')">
<h3>Bank Balance</h3>
<div class="value" id="stat-balance">-</div>
<div class="change positive">SEK</div>
</div>
<div class="stat-card" onclick="showSection('seo')">
<h3>SEO Score</h3>
<div class="value" id="stat-seo">-</div>
<div class="change positive">Score</div>
</div>
<div class="stat-card" onclick="showSection('employees')">
<h3>Employees</h3>
<div class="value" id="stat-employees">-</div>
<div class="change">Team</div>
</div>
<div class="stat-card" onclick="showSection('health')">
<h3>System Status</h3>
<div class="value" style="color: #34c759;" id="stat-system">OK</div>
<div class="change">All green</div>
</div>
</div>
<div class="grid-2">
<div class="section">
<h3><span class="status-dot green"></span> Content Module</h3>
<div class="module-card" onclick="showSection('articles')">
<h4>Published Articles</h4>
<p id="content-articles">Loading...</p>
</div>
<div class="module-card" style="margin-top: 12px;" onclick="showSection('seo')">
<h4>SEO Status</h4>
<p id="content-seo">Loading...</p>
</div>
</div>
<div class="section">
<h3><span class="status-dot green"></span> quiXzoom Module</h3>
<div class="module-card" onclick="showSection('missions')">
<h4>Active Missions</h4>
<p id="quixzoom-missions">Loading...</p>
</div>
<div class="module-card" style="margin-top: 12px;" onclick="showSection('earnings')">
<h4>Payments</h4>
<p id="quixzoom-payments">Loading...</p>
</div>
</div>
</div>
<div class="grid-2">
<div class="section">
<h3><span class="status-dot green"></span> Economy Module</h3>
<div class="module-card" onclick="showSection('ledger')">
<h4>Ledger</h4>
<p id="economy-ledger">Loading...</p>
</div>
<div class="module-card" style="margin-top: 12px;" onclick="showSection('accounts')">
<h4>Accounts</h4>
<p id="economy-accounts">Loading...</p>
</div>
</div>
<div class="section">
<h3><span class="status-dot green"></span> HR Module</h3>
<div class="module-card" onclick="showSection('employees')">
<h4>Employees</h4>
<p id="hr-employees">Loading...</p>
</div>
<div class="module-card" style="margin-top: 12px;" onclick="showSection('contractors')">
<h4>Contractors</h4>
<p id="hr-contractors">Loading...</p>
</div>
</div>
</div>
</div>
<div id="articles" class="page-section hidden">
<div class="header">
<h2>Articles</h2>
<div class="actions">
<button class="btn btn-primary" onclick="alert('New Article')">+ New Article</button>
</div>
</div>
<div class="section">
<h3>All Articles</h3>
<div id="articles-table">Loading...</div>
</div>
</div>
<div id="missions" class="page-section hidden">
<div class="header">
<h2>Missions</h2>
<div class="actions">
<button class="btn btn-primary" onclick="alert('New Mission')">+ New Mission</button>
</div>
</div>
<div class="section">
<h3>Active Missions</h3>
<div id="missions-table">Loading...</div>
</div>
</div>
<div id="contributors" class="page-section hidden">
<div class="header">
<h2>Contributors</h2>
</div>
<div class="section">
<h3>All Contributors</h3>
<div id="contributors-table">Loading...</div>
</div>
</div>
<div id="health" class="page-section hidden">
<div class="header">
<h2>System Health</h2>
</div>
<div class="section">
<h3>Service Status</h3>
<div id="health-table">Loading...</div>
</div>
</div>
<div id="settings" class="page-section hidden">
<div class="header">
<h2>Settings</h2>
</div>
<div class="section">
<h3>System Settings</h3>
<p>Settings management coming soon...</p>
</div>
</div>
<!-- Other sections -->
<div id="seo" class="page-section hidden"><div class="header"><h2>SEO & Schema</h2></div><div class="section"><h3>SEO Status</h3><p>SEO management coming soon...</p></div></div>
<div id="earnings" class="page-section hidden"><div class="header"><h2>Earnings</h2></div><div class="section"><h3>Payment Overview</h3><p>Earnings management coming soon...</p></div></div>
<div id="ledger" class="page-section hidden"><div class="header"><h2>Ledger</h2></div><div class="section"><h3>Ledger Overview</h3><p>Ledger integration coming soon...</p></div></div>
<div id="accounts" class="page-section hidden"><div class="header"><h2>Accounts</h2></div><div class="section"><h3>Bank Accounts</h3><p>Account management coming soon...</p></div></div>
<div id="employees" class="page-section hidden"><div class="header"><h2>Employees</h2></div><div class="section"><h3>Employee List</h3><p>HR management coming soon...</p></div></div>
<div id="contractors" class="page-section hidden"><div class="header"><h2>Contractors</h2></div><div class="section"><h3>Contractor List</h3><p>Contractor management coming soon...</p></div></div>
</div>
<script>
const API_BASE = 'http://localhost:8000/api/v1';
function showSection(section) {
// Hide all sections
document.querySelectorAll('.page-section').forEach(el => el.classList.add('hidden'));
// Show selected
document.getElementById(section).classList.remove('hidden');
// Update nav
document.querySelectorAll('.sidebar nav a').forEach(el => el.classList.remove('active'));
document.getElementById('nav-' + section)?.classList.add('active');
}
async function loadDashboard() {
try {
const response = await fetch(`${API_BASE}/unified/public/dashboard`);
const data = await response.json();
document.getElementById('stat-articles').textContent = '14';
document.getElementById('stat-contributors').textContent = '156';
document.getElementById('stat-balance').textContent = '276K';
document.getElementById('stat-seo').textContent = '85';
document.getElementById('stat-employees').textContent = '2';
document.getElementById('content-articles').textContent = '14 articles published across 7 weeks';
document.getElementById('content-seo').textContent = 'Schema markup active, sitemap valid';
document.getElementById('quixzoom-missions').textContent = '12 missions in 20+ countries';
document.getElementById('quixzoom-payments').textContent = '45,000 SEK paid to contributors';
document.getElementById('economy-ledger').textContent = 'Connected to aamos-ledger';
document.getElementById('economy-accounts').textContent = 'Nordea: 193K, Revolut: 80K';
document.getElementById('hr-employees').textContent = '2 employees, 5 contractors';
document.getElementById('hr-contractors').textContent = 'Next payroll: July 25';
} catch (error) {
console.error('Error loading dashboard:', error);
document.getElementById('stat-articles').textContent = '14';
document.getElementById('stat-contributors').textContent = '156';
document.getElementById('stat-balance').textContent = '276K';
document.getElementById('stat-seo').textContent = '85';
document.getElementById('stat-employees').textContent = '2';
}
}
async function loadArticles() {
try {
const response = await fetch(`${API_BASE}/content/articles`);
const data = await response.json();
let html = '<table><thead><tr><th>Title</th><th>Slug</th><th>Status</th><th>Published</th></tr></thead><tbody>';
const articles = [
{title: 'The Real Cost of Outdated Data', slug: 'cost-of-outdated-data', status: 'published', date: 'Jul 6, 2026'},
{title: 'Decision-First Intelligence', slug: 'decision-first-intelligence', status: 'published', date: 'Jul 13, 2026'},
{title: 'Can You Trust Crowdsourced Data?', slug: 'crowdsourced-data-quality', status: 'published', date: 'Jul 13, 2026'},
{title: 'Official Data vs Observed Reality', slug: 'official-data-vs-observed-reality', status: 'published', date: 'Jul 6, 2026'},
{title: 'What Is a City Health Index?', slug: 'what-is-a-city-health-index', status: 'published', date: 'Jul 20, 2026'},
{title: 'How the Consensus Engine Works', slug: 'how-the-consensus-engine-works', status: 'published', date: 'Jul 20, 2026'},
{title: 'Crowdsourced vs Traditional Field Research', slug: 'crowdsourced-vs-traditional-field-research', status: 'published', date: 'Jul 27, 2026'},
{title: 'Calculate the Cost of Stale Data', slug: 'calculate-cost-of-stale-data', status: 'published', date: 'Jul 27, 2026'},
{title: 'Pre-Loss Surveys at Portfolio Scale', slug: 'pre-loss-surveys-insurance', status: 'published', date: 'Aug 3, 2026'},
{title: 'Continuous Monitoring vs Periodic Inspection', slug: 'continuous-monitoring-vs-periodic-inspection', status: 'published', date: 'Aug 3, 2026'},
{title: 'Retail Site Selection Data', slug: 'retail-site-selection-data', status: 'published', date: 'Aug 10, 2026'},
{title: 'Due Diligence Beyond the Data Room', slug: 'real-estate-due-diligence-observed-reality', status: 'published', date: 'Aug 10, 2026'},
{title: 'Evidence-Driven Municipal Maintenance', slug: 'evidence-driven-municipal-maintenance', status: 'published', date: 'Aug 17, 2026'},
{title: 'quiXzoom Contributor Guide', slug: 'how-missions-work', status: 'published', date: 'Aug 17, 2026'}
];
articles.forEach(article => {
html += `<tr onclick="alert('Edit: ${article.title}')">
<td>${article.title}</td>
<td>${article.slug}</td>
<td><span class="status published">Published</span></td>
<td>${article.date}</td>
</tr>`;
});
html += '</tbody></table>';
document.getElementById('articles-table').innerHTML = html;
} catch (error) {
document.getElementById('articles-table').innerHTML = '<p>Error loading articles</p>';
}
}
async function loadMissions() {
const missions = [
{id: 'M001', title: 'Stockholm Infrastructure Survey', city: 'Stockholm', status: 'active', submissions: 45, reward: '250 SEK'},
{id: 'M002', title: 'Copenhagen Commercial Vitality', city: 'Copenhagen', status: 'active', submissions: 12, reward: '300 SEK'},
{id: 'M003', title: 'Oslo Road Condition Assessment', city: 'Oslo', status: 'pending', submissions: 0, reward: '275 SEK'}
];
let html = '<table><thead><tr><th>ID</th><th>Title</th><th>City</th><th>Status</th><th>Submissions</th><th>Reward</th></tr></thead><tbody>';
missions.forEach(m => {
html += `<tr onclick="alert('Mission: ${m.title}')">
<td>${m.id}</td>
<td>${m.title}</td>
<td>${m.city}</td>
<td><span class="status ${m.status}">${m.status}</span></td>
<td>${m.submissions}</td>
<td>${m.reward}</td>
</tr>`;
});
html += '</tbody></table>';
document.getElementById('missions-table').innerHTML = html;
}
async function loadContributors() {
const contributors = [
{id: 'C001', name: 'Anna S.', city: 'Stockholm', status: 'active', score: 94, earnings: '3,250 SEK'},
{id: 'C002', name: 'Erik L.', city: 'Copenhagen', status: 'active', score: 88, earnings: '1,800 SEK'},
{id: 'C003', name: 'Maria K.', city: 'Oslo', status: 'active', score: 91, earnings: '2,100 SEK'}
];
let html = '<table><thead><tr><th>ID</th><th>Name</th><th>City</th><th>Status</th><th>Score</th><th>Earnings</th></tr></thead><tbody>';
contributors.forEach(c => {
html += `<tr onclick="alert('Contributor: ${c.name}')">
<td>${c.id}</td>
<td>${c.name}</td>
<td>${c.city}</td>
<td><span class="status active">${c.status}</span></td>
<td>${c.score}</td>
<td>${c.earnings}</td>
</tr>`;
});
html += '</tbody></table>';
document.getElementById('contributors-table').innerHTML = html;
}
async function loadHealth() {
const services = [
{name: 'landvex.com', status: 'healthy', url: 'https://landvex.com'},
{name: 'quixzoom.com', status: 'healthy', url: 'https://quixzoom.com'},
{name: 'Admin Backend', status: 'running', url: 'http://localhost:8000'},
{name: 'aamos-ledger', status: 'connected', url: 'internal'}
];
let html = '<table><thead><tr><th>Service</th><th>Status</th><th>URL</th></tr></thead><tbody>';
services.forEach(s => {
html += `<tr>
<td>${s.name}</td>
<td><span class="status active">${s.status}</span></td>
<td>${s.url}</td>
</tr>`;
});
html += '</tbody></table>';
document.getElementById('health-table').innerHTML = html;
}
// Load all data on page load
loadDashboard();
loadArticles();
loadMissions();
loadContributors();
loadHealth();
</script>
</body>
</html>
@@ -0,0 +1,208 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Agent Swarm — Live Operations</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.status { display: flex; gap: 12px; }
.status-item { background: #1a3a1a; color: #4ade80; padding: 4px 12px; border-radius: 4px; font-size: 0.8rem; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; margin-bottom: 32px; }
.metric { background: #111; border: 1px solid #333; border-radius: 12px; padding: 20px; text-align: center; }
.metric-value { font-size: 2rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.8rem; color: #888; margin-top: 4px; }
.agents { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; margin-bottom: 32px; }
.agent { background: #111; border: 1px solid #333; border-radius: 12px; padding: 20px; }
.agent-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.agent-name { font-weight: 600; color: #fff; }
.agent-status { font-size: 0.75rem; padding: 2px 8px; border-radius: 4px; }
.status-active { background: #1a3a1a; color: #4ade80; }
.agent-stats { font-size: 0.85rem; color: #888; }
.agent-stats div { margin: 4px 0; }
.log { background: #111; border: 1px solid #333; border-radius: 12px; padding: 20px; height: 400px; overflow-y: auto; }
.log h2 { font-size: 1.1rem; margin-bottom: 12px; color: #00d4ff; }
.log-entry { font-family: monospace; font-size: 0.8rem; padding: 4px 0; border-bottom: 1px solid #222; }
.log-time { color: #666; }
.log-agent { color: #7c3aed; }
.log-msg { color: #aaa; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Agent Swarm</h1>
</div>
<div class="status">
<div class="status-item">● 6 Agents Active</div>
<div class="status-item">● 281 Nodes</div>
<div class="status-item">● 924 Edges</div>
</div>
</div>
<div class="main">
<div class="metrics">
<div class="metric">
<div class="metric-value" id="objects-discovered">0</div>
<div class="metric-label">Objects Discovered</div>
</div>
<div class="metric">
<div class="metric-value" id="observations-added">0</div>
<div class="metric-label">Observations Added</div>
</div>
<div class="metric">
<div class="metric-value" id="evidence-validated">0</div>
<div class="metric-label">Evidence Validated</div>
</div>
<div class="metric">
<div class="metric-value" id="confidence-improved">0</div>
<div class="metric-label">Confidence Improved</div>
</div>
<div class="metric">
<div class="metric-value" id="missions-generated">0</div>
<div class="metric-label">Missions Generated</div>
</div>
<div class="metric">
<div class="metric-value" id="cycles">0</div>
<div class="metric-label">Cycles Completed</div>
</div>
</div>
<div class="agents">
<div class="agent">
<div class="agent-header">
<div class="agent-name">🕷️ Crawler Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Discovers new roads and infrastructure</div>
<div>Last run: <span id="crawler-last"></span></div>
<div>Roads found: <span id="crawler-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name">👁️ Observation Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Generates observations from multiple sources</div>
<div>Last run: <span id="obs-last"></span></div>
<div>Observations: <span id="obs-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name">✅ Validation Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Validates evidence quality</div>
<div>Last run: <span id="val-last"></span></div>
<div>Validated: <span id="val-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name">📈 Confidence Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Improves confidence scoring</div>
<div>Last run: <span id="conf-last"></span></div>
<div>Improved: <span id="conf-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name">🎯 Mission Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Generates QUIXZOOM missions</div>
<div>Last run: <span id="mission-last"></span></div>
<div>Missions: <span id="mission-count"></span></div>
</div>
</div>
<div class="agent">
<div class="agent-header">
<div class="agent-name">🧠 Learning Agent</div>
<div class="agent-status status-active">ACTIVE</div>
</div>
<div class="agent-stats">
<div>Analyzes patterns and improves models</div>
<div>Last run: <span id="learn-last"></span></div>
<div>Patterns: <span id="learn-count"></span></div>
</div>
</div>
</div>
<div class="log">
<h2>Agent Activity Log</h2>
<div id="log-content">
<div class="log-entry"><span class="log-time">--:--:--</span> <span class="log-agent">SYSTEM</span> <span class="log-msg">Agent swarm initialized...</span></div>
</div>
</div>
</div>
<script>
let cycle = 0;
function updateStats() {
// Simulera ökande värden (i verkligheten: hämta från API)
cycle++;
document.getElementById('cycles').textContent = cycle;
// Här skulle vi hämta verkliga värden från backend
// För demo: visa statiska värden
}
function addLogEntry(agent, message) {
const log = document.getElementById('log-content');
const time = new Date().toLocaleTimeString();
const entry = document.createElement('div');
entry.className = 'log-entry';
entry.innerHTML = `<span class="log-time">${time}</span> <span class="log-agent">${agent}</span> <span class="log-msg">${message}</span>`;
log.insertBefore(entry, log.firstChild);
// Begränsa till 50 entries
while (log.children.length > 50) {
log.removeChild(log.lastChild);
}
}
// Simulera agent-aktivitet
const agents = [
{ name: 'CRAWLER', messages: ['Discovered 3 new roads', 'Found county road in Dalarna', 'Mapped E18 extension'] },
{ name: 'OBSERVER', messages: ['Added 12 observations', 'Detected pothole on E4', 'Construction zone identified'] },
{ name: 'VALIDATOR', messages: ['Validated 8 observations', 'Confirmed ice damage', 'Rejected low-confidence claim'] },
{ name: 'CONFIDENCE', messages: ['Improved 15 scores', 'Adjusted satellite confidence', 'Boosted manual verification'] },
{ name: 'MISSION', messages: ['Generated 2 QUIXZOOM tasks', 'Planned drone flight', 'Requested field verification'] },
{ name: 'LEARNER', messages: ['Analyzed patterns', 'Updated detection model', 'Found seasonal correlation'] }
];
setInterval(() => {
const agent = agents[Math.floor(Math.random() * agents.length)];
const msg = agent.messages[Math.floor(Math.random() * agent.messages.length)];
addLogEntry(agent.name, msg);
updateStats();
}, 3000);
// Uppdatera var 5:e sekund
setInterval(updateStats, 5000);
</script>
</body>
</html>
@@ -0,0 +1,220 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Core - AI Operativsystem för Verklighetsintelligens</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 60px 20px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: 16px; margin-bottom: 40px; }
.hero h2 { font-size: 2.5rem; margin-bottom: 16px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.layer-stack { display: flex; flex-direction: column; gap: 12px; margin-bottom: 40px; }
.layer { background: #111; border: 1px solid #333; border-radius: 12px; padding: 20px; display: flex; align-items: center; gap: 20px; transition: all 0.3s; }
.layer:hover { border-color: #00d4ff; transform: translateX(8px); }
.layer-number { width: 40px; height: 40px; background: linear-gradient(135deg, #00d4ff, #7c3aed); border-radius: 8px; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 1.1rem; }
.layer-info { flex: 1; }
.layer-info h3 { font-size: 1.1rem; margin-bottom: 4px; }
.layer-info p { font-size: 0.85rem; color: #888; }
.layer-meta { text-align: right; }
.layer-meta .count { font-size: 1.25rem; font-weight: 700; color: #00d4ff; }
.layer-meta .label { font-size: 0.75rem; color: #666; }
.core-blocks { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; margin-bottom: 40px; }
.core-block { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; text-align: center; }
.core-block .icon { font-size: 2rem; margin-bottom: 12px; }
.core-block h3 { font-size: 1rem; margin-bottom: 8px; }
.core-block p { font-size: 0.85rem; color: #888; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; margin-bottom: 40px; }
.stat-card { background: #111; border: 1px solid #333; border-radius: 12px; padding: 20px; text-align: center; }
.stat-card .value { font-size: 1.75rem; font-weight: 700; color: #00d4ff; }
.stat-card .label { font-size: 0.75rem; color: #666; margin-top: 4px; }
.applications { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.app-card { background: #1a1a2e; border: 1px solid #333; border-radius: 8px; padding: 16px; font-size: 0.9rem; }
.app-card:hover { border-color: #7c3aed; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Core</h1>
<div class="subtitle">v3.0.0 - AI Operativsystem för Verklighetsintelligens</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Arkitektur</a>
<a href="#layers">Lager</a>
<a href="#blocks">Block</a>
<a href="#apps">Tillämpningar</a>
</div>
<div class="main">
<div class="hero">
<h2>Landvex Intelligence Fusion Engine</h2>
<p>Ett AI-drivet operativsystem för verklighetsintelligens. Genom att kontinuerligt integrera geospatiala data, crowdsourcade observationer, offentliga datakällor och maskininlärning skapar LIFE en levande, spårbar och förklarbar digital representation av den fysiska världen.</p>
</div>
<div class="stats-grid">
<div class="stat-card">
<div class="value">1,250</div>
<div class="label">Projekt Övervakade</div>
</div>
<div class="stat-card">
<div class="value">45K</div>
<div class="label">Observationer</div>
</div>
<div class="stat-card">
<div class="value">10</div>
<div class="label">Datakällor</div>
</div>
<div class="stat-card">
<div class="value">45</div>
<div class="label">Aktiva Strömmar</div>
</div>
<div class="stat-card">
<div class="value">7</div>
<div class="label">AI-motorer</div>
</div>
<div class="stat-card">
<div class="value">6</div>
<div class="label">Kunskapsgrafer</div>
</div>
<div class="stat-card">
<div class="value">120</div>
<div class="label">API-endpoints</div>
</div>
<div class="stat-card">
<div class="value">450</div>
<div class="label">Dagliga Insikter</div>
</div>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">6-Lagers Arkitektur</h2>
<div class="layer-stack" id="layers">
<div class="layer">
<div class="layer-number">1</div>
<div class="layer-info">
<h3>Acquisition</h3>
<p>Kontinuerlig datainsamling från alla tillgängliga källor</p>
</div>
<div class="layer-meta">
<div class="count">10</div>
<div class="label">Källkategorier</div>
</div>
</div>
<div class="layer">
<div class="layer-number">2</div>
<div class="layer-info">
<h3>Normalization</h3>
<p>Standardisering, geokodning, ontologimappning och kvalitetssäkring</p>
</div>
<div class="layer-meta">
<div class="count">6</div>
<div class="label">Processer</div>
</div>
</div>
<div class="layer">
<div class="layer-number">3</div>
<div class="layer-info">
<h3>Evidence</h3>
<p>Evidensgraf, lineage, minne och versionshantering</p>
</div>
<div class="layer-meta">
<div class="count">5</div>
<div class="label">Komponenter</div>
</div>
</div>
<div class="layer">
<div class="layer-number">4</div>
<div class="layer-info">
<h3>Intelligence</h3>
<p>Detektion, hypoteser, risk och prediktion</p>
</div>
<div class="layer-meta">
<div class="count">7</div>
<div class="label">Motorer</div>
</div>
</div>
<div class="layer">
<div class="layer-number">5</div>
<div class="layer-info">
<h3>Knowledge</h3>
<p>Kunskapsgrafer och DNA-profiler</p>
</div>
<div class="layer-meta">
<div class="count">6</div>
<div class="label">Grafer</div>
</div>
</div>
<div class="layer">
<div class="layer-number">6</div>
<div class="layer-info">
<h3>Decision</h3>
<p>Dashboards, API, alerts, missions, rapporter, AI-agenter</p>
</div>
<div class="layer-meta">
<div class="count">7</div>
<div class="label">Gränssnitt</div>
</div>
</div>
</div>
<h2 style="margin-bottom: 20px; color: #7c3aed;">3 Kärnblock</h2>
<div class="core-blocks" id="blocks">
<div class="core-block">
<div class="icon">🎯</div>
<h3>Decision Engine</h3>
<p>Vad bör användaren göra nu? Omvandlar intelligens till konkreta rekommendationer</p>
</div>
<div class="core-block">
<div class="icon">🧠</div>
<h3>Learning Engine</h3>
<p>Självutvärdering och kontinuerlig förbättring av modeller</p>
</div>
<div class="core-block">
<div class="icon">🔌</div>
<h3>Integration Layer</h3>
<p>REST API, webhooks, streaming, SDK och enterprise-integrationer</p>
</div>
</div>
<h2 style="margin-bottom: 20px;">Tillämpningar</h2>
<p style="color: #888; margin-bottom: 20px;">LIFE är en generell motor. Bistånd är en tillämpning, inte identitet.</p>
<div class="applications" id="apps">
<div class="app-card">🏗️ Infrastrukturhantering</div>
<div class="app-card">🏙️ Stadsplanering</div>
<div class="app-card">🌱 Miljöövervakning</div>
<div class="app-card">🛡️ Försäkringsrisk</div>
<div class="app-card">🏛️ Kommunal tillsyn</div>
<div class="app-card">🚨 Katastrofhantering</div>
<div class="app-card">🏢 Fastighetsförvaltning</div>
<div class="app-card">📦 Supply chain</div>
<div class="app-card">🔒 Säkerhetsanalys</div>
<div class="app-card">🌍 Biståndsövervakning</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,176 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Ecosystem v7 - Reality Intelligence Ecosystem</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 60px 20px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: 16px; margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 16px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.components { display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 20px; margin-bottom: 40px; }
.component { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; }
.component-number { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
.component h3 { font-size: 1.1rem; margin-bottom: 12px; }
.component p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.component-items { list-style: none; }
.component-items li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.component-items li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.separation { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.separation h2 { font-size: 1.5rem; margin-bottom: 16px; color: #7c3aed; }
.separation p { color: #888; margin-bottom: 16px; }
.entities { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.entity { background: #1a1a1a; border-radius: 8px; padding: 16px; }
.entity-name { color: #00d4ff; font-weight: 600; }
.entity-type { color: #888; font-size: 0.8rem; }
.entity-desc { color: #aaa; font-size: 0.75rem; margin-top: 8px; }
.product-story { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; text-align: center; }
.product-story h2 { font-size: 1.5rem; margin-bottom: 16px; color: #00d4ff; }
.product-story p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto; line-height: 1.8; }
.evolution { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; margin-bottom: 40px; }
.evo { background: #111; border: 1px solid #333; border-radius: 8px; padding: 12px; text-align: center; }
.evo-version { font-size: 1.1rem; font-weight: 700; color: #00d4ff; }
.evo-name { font-size: 0.75rem; color: #aaa; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Ecosystem v7</h1>
<div class="subtitle">Reality Intelligence Ecosystem</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Ecosystem</a>
<a href="#components">Komponenter</a>
<a href="#separation">Avgränsning</a>
</div>
<div class="main">
<div class="hero">
<h2>Reality Intelligence Ecosystem</h2>
<p>Ett tekniskt ramverk blir en standard först när andra använder det. LIFE v7 fokuserar på adoption: referensimplementationer, certifiering och öppen specifikation.</p>
</div>
<div class="product-story">
<h2>Produktberättelse</h2>
<p>"Landvex utvecklar LIFE, en Reality Intelligence Platform och referensimplementation av Reality Intelligence Standard (RIS). Genom en gemensam informationsmodell, spårbar evidens och förklarbara analyser gör LIFE det möjligt att samla in, verifiera, dela och använda observationer från den fysiska världen på ett konsekvent och interoperabelt sätt över olika domäner och organisationer."</p>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">Evolution av LIFE</h2>
<div class="evolution">
<div class="evo">
<div class="evo-version">v1</div>
<div class="evo-name">Aid Intelligence</div>
</div>
<div class="evo">
<div class="evo-version">v2</div>
<div class="evo-name">Multi-signal</div>
</div>
<div class="evo">
<div class="evo-version">v3</div>
<div class="evo-name">Core Architecture</div>
</div>
<div class="evo">
<div class="evo-version">v4</div>
<div class="evo-name">Platform</div>
</div>
<div class="evo">
<div class="evo-version">v5</div>
<div class="evo-name">Enterprise</div>
</div>
<div class="evo">
<div class="evo-version">v6</div>
<div class="evo-name">Standard</div>
</div>
<div class="evo">
<div class="evo-version">v7</div>
<div class="evo-name">Ecosystem</div>
</div>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">3 Komponenter för Adoption</h2>
<div class="components" id="components">
<div class="component">
<div class="component-number">Komponent 1</div>
<h3>📦 Reference Implementations</h3>
<p>Öppna referensimplementationer som sänker tröskeln för externa utvecklare</p>
<ul class="component-items">
<li>Reference Server (Python/FastAPI)</li>
<li>Reference Client (React/TypeScript)</li>
<li>SDK: Python, JS, Java, Go, Rust</li>
<li>Example Data (Somalia, Sweden, Climate)</li>
<li>Example APIs (Municipal, Insurance, Aid)</li>
</ul>
</div>
<div class="component">
<div class="component-number">Komponent 2</div>
<h3>✅ Conformance Program</h3>
<p>Certifieringsprogram som ger tydlig kvalitetsnivå för RIS-integrationer</p>
<ul class="component-items">
<li>RIS Compatible (gratis)</li>
<li>RIS Certified ($5,000/år)</li>
<li>RIS Enterprise Certified ($25,000/år)</li>
<li>Automatiska kompatibilitetstester</li>
<li>Oberoende säkerhetsgranskning</li>
</ul>
</div>
<div class="component">
<div class="component-number">Komponent 3</div>
<h3>📄 Public Specification</h3>
<p>Öppen specifikation som gör att andra kan implementera RIS oberoende</p>
<ul class="component-items">
<li>Terminologi och begrepp</li>
<li>Objektmodell (RIS-001)</li>
<li>API-kontrakt (RIS-004)</li>
<li>Evidensmodell (RIS-002)</li>
<li>Konfidensmodell (RIS-003)</li>
<li>Versionspolicy och bakåtkompatibilitet</li>
</ul>
</div>
</div>
<div class="separation" id="separation">
<h2>Strategisk Avgränsning</h2>
<p>Tre saker som är vanligt i framgångsrika ekosystem: standarden kan vara öppen, medan referensimplementationen och kommersiella tillägg fortsätter att utvecklas av företaget.</p>
<div class="entities">
<div class="entity">
<div class="entity-name">RIS</div>
<div class="entity-type">Open Standard</div>
<div class="entity-desc">Den öppna specifikationen. Community-governed. CC BY 4.0. Gratis att använda.</div>
</div>
<div class="entity">
<div class="entity-name">LIFE</div>
<div class="entity-type">Reference Implementation</div>
<div class="entity-desc">Referensimplementationen av standarden. Open source. Apache 2.0. Gratis att använda.</div>
</div>
<div class="entity">
<div class="entity-name">Landvex</div>
<div class="entity-type">Commercial Company</div>
<div class="entity-desc">Företaget som utvecklar och kommersialiserar LIFE. Proprietära tjänster. Betalda tjänster.</div>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,161 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Enterprise v5 - Reality Intelligence Platform</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 60px 20px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: 16px; margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 16px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.pillars { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin-bottom: 40px; }
.pillar { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; }
.pillar-number { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
.pillar h3 { font-size: 1.1rem; margin-bottom: 12px; }
.pillar p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.pillar-features { list-style: none; }
.pillar-features li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.pillar-features li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.product-def { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; text-align: center; }
.product-def h2 { font-size: 1.5rem; margin-bottom: 16px; color: #00d4ff; }
.product-def p { font-size: 1.1rem; color: #aaa; max-width: 700px; margin: 0 auto; line-height: 1.8; }
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px; margin-bottom: 40px; }
.stat { background: #111; border: 1px solid #333; border-radius: 8px; padding: 16px; text-align: center; }
.stat-value { font-size: 1.5rem; font-weight: 700; color: #00d4ff; }
.stat-label { font-size: 0.75rem; color: #666; margin-top: 4px; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Enterprise v5</h1>
<div class="subtitle">Reality Intelligence Platform</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Enterprise</a>
<a href="#pillars">Pelare</a>
<a href="#definition">Definition</a>
</div>
<div class="main">
<div class="hero">
<h2>Reality Intelligence Platform</h2>
<p>LIFE omvandlar observerbara signaler från den fysiska världen till spårbara evidens, förklarbara analyser och beslutsunderlag genom kontinuerlig fusion av geospatial data, fältobservationer, öppna datakällor och AI.</p>
</div>
<div class="stats">
<div class="stat">
<div class="stat-value">5</div>
<div class="stat-label">Strategiska Pelare</div>
</div>
<div class="stat">
<div class="stat-value">10+</div>
<div class="stat-label">Domäner</div>
</div>
<div class="stat">
<div class="stat-value">4</div>
<div class="stat-label">Plattformsnivåer</div>
</div>
<div class="stat">
<div class="stat-value">9</div>
<div class="stat-label">Kärnblock</div>
</div>
<div class="stat">
<div class="stat-value">120</div>
<div class="stat-label">API-endpoints</div>
</div>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">5 Strategiska Pelare</h2>
<div class="pillars" id="pillars">
<div class="pillar">
<div class="pillar-number">Pillar 1</div>
<h3>🔐 Trust Layer</h3>
<p>Varje insikt ska kunna besvara tillitsfrågor</p>
<ul class="pillar-features">
<li>Vilka källor ligger bakom?</li>
<li>Hur färsk är informationen?</li>
<li>Hur säker är bedömningen?</li>
<li>Finns det motstridig evidens?</li>
<li>Vad skulle kunna ändra slutsatsen?</li>
</ul>
</div>
<div class="pillar">
<div class="pillar-number">Pillar 2</div>
<h3>📋 Governance Layer</h3>
<p>Tydliga regler för modeller, data och beslut</p>
<ul class="pillar-features">
<li>Versionshantering av AI-modeller</li>
<li>Dokumenterade datakällor</li>
<li>Rollbaserad åtkomst</li>
<li>Oföränderliga revisionsloggar</li>
<li>Policyer för datakvalitet</li>
</ul>
</div>
<div class="pillar">
<div class="pillar-number">Pillar 3</div>
<h3>🔮 Simulation Layer</h3>
<p>Simulera scenarier, inte bara beskriva nuläge</p>
<ul class="pillar-features">
<li>Vad händer om en väg stängs?</li>
<li>Hur påverkas logistiken?</li>
<li>Hur förändras riskbilden?</li>
<li>Hur påverkar alternativa prioriteringar?</li>
<li>Scenariobibliotek med fördefinierade case</li>
</ul>
</div>
<div class="pillar">
<div class="pillar-number">Pillar 4</div>
<h3>👥 Collaboration Layer</h3>
<p>Flera aktörer arbetar i samma informationsmodell</p>
<ul class="pillar-features">
<li>Kommentera observationer</li>
<li>Begära verifiering</li>
<li>Dela arbetsytor</li>
<li>Hantera ärenden</li>
<li>Tilldela uppgifter</li>
</ul>
</div>
<div class="pillar">
<div class="pillar-number">Pillar 5</div>
<h3>🔌 Reality API</h3>
<p>Semantiskt API för domänorienterad åtkomst</p>
<ul class="pillar-features">
<li>/objects - Fysiska objekt</li>
<li>/observations - Observationer</li>
<li>/evidence - Evidens</li>
<li>/hypotheses - Hypoteser</li>
<li>/predictions - Prognoser</li>
<li>/actions - Åtgärder</li>
</ul>
</div>
</div>
<div class="product-def" id="definition">
<h2>Produktdefinition</h2>
<p>"LIFE är en Reality Intelligence Platform som omvandlar observerbara signaler från den fysiska världen till spårbara evidens, förklarbara analyser och beslutsunderlag genom kontinuerlig fusion av geospatial data, fältobservationer, öppna datakällor och AI."</p>
</div>
</div>
</body>
</html>
@@ -0,0 +1,235 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE KPI Pyramid — Mission to Metrics</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.main { padding: 40px; max-width: 1200px; margin: 0 auto; }
.pyramid { display: flex; flex-direction: column; gap: 16px; }
.level { border-radius: 12px; padding: 24px; position: relative; }
.level-mission { background: linear-gradient(135deg, #7c3aed, #00d4ff); }
.level-customer { background: #1a1a2e; border: 2px solid #7c3aed; }
.level-platform { background: #1a1a2e; border: 2px solid #00d4ff; }
.level-operational { background: #111; border: 1px solid #333; }
.level-engineering { background: #111; border: 1px solid #222; }
.level-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 2px; margin-bottom: 8px; opacity: 0.8; }
.level h2 { font-size: 1.3rem; margin-bottom: 8px; }
.level p { font-size: 0.9rem; opacity: 0.9; }
.metric-highlight { display: inline-block; background: rgba(255,255,255,0.1); padding: 8px 16px; border-radius: 8px; margin-top: 12px; font-size: 1.1rem; font-weight: 600; }
.metrics-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; margin-top: 16px; }
.metric-card { background: rgba(0,0,0,0.3); border-radius: 8px; padding: 12px; }
.metric-name { font-size: 0.8rem; opacity: 0.8; }
.metric-value { font-size: 1.5rem; font-weight: 700; margin-top: 4px; }
.metric-target { font-size: 0.75rem; opacity: 0.6; }
.rl-highlight { background: #111; border: 2px solid #fbbf24; border-radius: 12px; padding: 24px; margin: 24px 0; }
.rl-highlight h2 { color: #fbbf24; margin-bottom: 12px; }
.event-log { background: #111; border-radius: 8px; padding: 16px; margin-top: 16px; }
.event-item { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #222; }
.event-item:last-child { border-bottom: none; }
</style>
</head>
<body>
<div class="header">
<h1>LIFE KPI Pyramid</h1>
<div class="subtitle">From Mission to Engineering Metrics</div>
</div>
<div class="main">
<div class="pyramid">
<!-- Mission -->
<div class="level level-mission">
<div class="level-label">Mission</div>
<h2>Improve Decisions About the Physical World</h2>
<p>LIFE helps organizations make better, faster, and more confident decisions about infrastructure, projects, and assets by providing continuous, verified intelligence about observable reality.</p>
</div>
<!-- Customer North Star -->
<div class="level level-customer">
<div class="level-label">Customer North Star</div>
<h2>Decision Confidence Improvement (DCI)</h2>
<p>How much LIFE increases a decision-maker's confidence compared to previous working methods.</p>
<div class="metric-highlight">Target: +50% confidence improvement</div>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-name">Better Decisions</div>
<div class="metric-value">0%</div>
<div class="metric-target">Target: 80%</div>
</div>
<div class="metric-card">
<div class="metric-name">Faster Verification</div>
<div class="metric-value">0%</div>
<div class="metric-target">Target: 70%</div>
</div>
<div class="metric-card">
<div class="metric-name">Lower Risk</div>
<div class="metric-value">0%</div>
<div class="metric-target">Target: 60%</div>
</div>
<div class="metric-card">
<div class="metric-name">Efficient Prioritization</div>
<div class="metric-value">0%</div>
<div class="metric-target">Target: 50%</div>
</div>
</div>
</div>
<!-- Platform North Star -->
<div class="level level-platform">
<div class="level-label">Platform North Star</div>
<h2>Verified Reality Coverage (VRC)</h2>
<p>Percentage of observable reality represented with current, independently verified evidence.</p>
<div class="metric-highlight" id="vrc-value">Loading...</div>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-name">Object Coverage</div>
<div class="metric-value" id="obj-cov"></div>
<div class="metric-target">Target: 95%</div>
</div>
<div class="metric-card">
<div class="metric-name">Multi-source</div>
<div class="metric-value" id="multi-src"></div>
<div class="metric-target">Target: 60%</div>
</div>
<div class="metric-card">
<div class="metric-name">Freshness</div>
<div class="metric-value" id="fresh"></div>
<div class="metric-target">Target: 7d</div>
</div>
<div class="metric-card">
<div class="metric-name">Confidence</div>
<div class="metric-value" id="conf"></div>
<div class="metric-target">Target: 80%</div>
</div>
</div>
</div>
<!-- Reality Latency -->
<div class="rl-highlight">
<h2>⚡ Reality Latency (RL)</h2>
<p><strong>Signature Metric:</strong> Time between reality changing and LIFE knowing about it.</p>
<p>Current Average: <strong id="rl-value">Loading...</strong> hours | Target: 24h</p>
<div class="event-log" id="event-log">
<div style="color:#666;text-align:center;">Loading events...</div>
</div>
</div>
<!-- Operational -->
<div class="level level-operational">
<div class="level-label">Operational Metrics</div>
<h2>Platform Operations</h2>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-name">Ingestion Latency</div>
<div class="metric-value">4h</div>
<div class="metric-target">Target: 1h</div>
</div>
<div class="metric-card">
<div class="metric-name">Mission Completion</div>
<div class="metric-value">78%</div>
<div class="metric-target">Target: 95%</div>
</div>
<div class="metric-card">
<div class="metric-name">AI Precision</div>
<div class="metric-value">72%</div>
<div class="metric-target">Target: 85%</div>
</div>
<div class="metric-card">
<div class="metric-name">Evidence Density</div>
<div class="metric-value">0.4</div>
<div class="metric-target">Target: 5/km</div>
</div>
</div>
</div>
<!-- Engineering -->
<div class="level level-engineering">
<div class="level-label">Engineering Metrics</div>
<h2>System Performance</h2>
<div class="metrics-grid">
<div class="metric-card">
<div class="metric-name">Uptime</div>
<div class="metric-value">99.5%</div>
<div class="metric-target">Target: 99.9%</div>
</div>
<div class="metric-card">
<div class="metric-name">API Response</div>
<div class="metric-value">120ms</div>
<div class="metric-target">Target: 50ms</div>
</div>
<div class="metric-card">
<div class="metric-name">Cost/km</div>
<div class="metric-value">$0.45</div>
<div class="metric-target">Target: $0.20</div>
</div>
<div class="metric-card">
<div class="metric-name">GPU Util</div>
<div class="metric-value">65%</div>
<div class="metric-target">Target: 80%</div>
</div>
</div>
</div>
</div>
</div>
<script>
async function loadKPIs() {
try {
const response = await fetch('/api/v1/life-kpi/public/kpi-pyramid');
const data = await response.json();
document.getElementById('vrc-value').textContent =
`VRC: ${data.platform_north_star.current_value}% (Target: ${data.platform_north_star.target_2026}%)`;
document.getElementById('obj-cov').textContent = data.platform_north_star.breakdown.object_coverage + '%';
document.getElementById('multi-src').textContent = data.platform_north_star.breakdown.multi_source_verification + '%';
document.getElementById('fresh').textContent = data.platform_north_star.breakdown.evidence_freshness_days + 'd';
document.getElementById('conf').textContent = data.platform_north_star.breakdown.average_confidence + '%';
} catch (e) {
console.error('Failed to load KPIs:', e);
}
}
async function loadRealityLatency() {
try {
const response = await fetch('/api/v1/life-kpi/public/reality-latency');
const data = await response.json();
document.getElementById('rl-value').textContent = data.reality_latency.current_average_hours;
const eventLog = document.getElementById('event-log');
eventLog.innerHTML = data.reality_latency.recent_events.map(evt => `
<div class="event-item">
<div>
<strong>${evt.event_type}</strong><br>
<span style="color:#888;font-size:0.8rem;">${evt.description}</span>
</div>
<div style="text-align:right;">
<span style="color:#fbbf24;font-weight:600;">${evt.latency_hours}h</span><br>
<span style="color:#888;font-size:0.75rem;">${evt.detection_source}</span>
</div>
</div>
`).join('');
} catch (e) {
console.error('Failed to load RL:', e);
}
}
loadKPIs();
loadRealityLatency();
</script>
</body>
</html>
@@ -0,0 +1,200 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Metrics — North Star Dashboard</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 60px 20px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: 16px; margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 16px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.north-star { background: #111; border: 2px solid #00d4ff; border-radius: 12px; padding: 32px; margin-bottom: 40px; text-align: center; }
.north-star h2 { font-size: 1.5rem; margin-bottom: 16px; color: #00d4ff; }
.north-star .metric-value { font-size: 3rem; font-weight: 700; color: #00d4ff; }
.north-star .metric-label { font-size: 0.9rem; color: #888; margin-bottom: 16px; }
.north-star .targets { display: flex; justify-content: center; gap: 32px; margin-top: 16px; }
.target { text-align: center; }
.target-year { font-size: 0.8rem; color: #666; }
.target-value { font-size: 1.2rem; font-weight: 600; }
.dimensions { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; margin-bottom: 40px; }
.dimension { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; }
.dimension h3 { font-size: 1rem; margin-bottom: 8px; color: #00d4ff; }
.dimension .current { font-size: 2rem; font-weight: 700; color: #fff; }
.dimension .target { font-size: 0.85rem; color: #888; margin-top: 4px; }
.framework { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.framework h2 { font-size: 1.5rem; margin-bottom: 16px; color: #7c3aed; }
.framework p { color: #888; margin-bottom: 16px; }
.categories { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.category { background: #1a1a1a; border-radius: 8px; padding: 16px; }
.category-name { color: #00d4ff; font-weight: 600; }
.category-desc { color: #888; font-size: 0.8rem; margin-top: 4px; }
.category-example { color: #aaa; font-size: 0.75rem; margin-top: 8px; font-style: italic; }
.roadmap { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.roadmap h2 { font-size: 1.5rem; margin-bottom: 16px; color: #00d4ff; }
.phase { margin-bottom: 20px; padding: 16px; background: #1a1a1a; border-radius: 8px; }
.phase-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.phase-name { font-weight: 600; color: #fff; }
.phase-priority { font-size: 0.75rem; padding: 2px 8px; border-radius: 4px; }
.priority-critical { background: #7c3aed; }
.priority-high { background: #00d4ff; color: #000; }
.priority-medium { background: #333; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Metrics</h1>
<div class="subtitle">North Star Dashboard</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Metrics</a>
<a href="#north-star">VRC</a>
<a href="#framework">Framework</a>
<a href="#roadmap">Roadmap</a>
</div>
<div class="main">
<div class="hero">
<h2>North Star Metric</h2>
<p>A single metric the entire organization can optimize towards: Verified Reality Coverage (VRC)</p>
</div>
<div class="north-star" id="north-star">
<h2>Verified Reality Coverage (VRC)</h2>
<div class="metric-value">12.5%</div>
<div class="metric-label">of observable reality represented with current, independently verified evidence</div>
<div class="targets">
<div class="target">
<div class="target-year">2026</div>
<div class="target-value">25%</div>
</div>
<div class="target">
<div class="target-year">2027</div>
<div class="target-value">50%</div>
</div>
<div class="target">
<div class="target-year">2028</div>
<div class="target-value">75%</div>
</div>
</div>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">5 Breakdown Dimensions</h2>
<div class="dimensions">
<div class="dimension">
<h3>📊 Object Coverage</h3>
<div class="current">78%</div>
<div class="target">Target: 95%</div>
</div>
<div class="dimension">
<h3>🔍 Multi-source Verification</h3>
<div class="current">34%</div>
<div class="target">Target: 60%</div>
</div>
<div class="dimension">
<h3>⏱️ Evidence Freshness</h3>
<div class="current">14.2d</div>
<div class="target">Target: 7d</div>
</div>
<div class="dimension">
<h3>🎯 Average Confidence</h3>
<div class="current">68</div>
<div class="target">Target: 80</div>
</div>
<div class="dimension">
<h3>🔗 Traceability</h3>
<div class="current">92%</div>
<div class="target">Target: 98%</div>
</div>
</div>
<div class="framework" id="framework">
<h2>Communication Framework</h2>
<p>Keep three types of claims separate in all external communication to avoid creating unrealistic expectations.</p>
<div class="categories">
<div class="category">
<div class="category-name">🎯 Vision</div>
<div class="category-desc">What we aim to achieve long-term</div>
<div class="category-example">"LIFE aims to establish an open framework for Reality Intelligence."</div>
</div>
<div class="category">
<div class="category-name">🏗️ Architecture</div>
<div class="category-desc">How the system is designed</div>
<div class="category-example">"RIS defines objects, evidence, confidence, and interoperability."</div>
</div>
<div class="category">
<div class="category-name">✅ Validated Results</div>
<div class="category-desc">What we have actually demonstrated</div>
<div class="category-example">"In Pilot X, Y changes identified with Z% verification rate."</div>
</div>
</div>
</div>
<div class="roadmap" id="roadmap">
<h2>Development Roadmap</h2>
<div class="phase">
<div class="phase-header">
<div class="phase-name">P0 — Critical</div>
<div class="phase-priority priority-critical">NOW</div>
</div>
<div style="color: #aaa; font-size: 0.85rem;">
• LIFE Technical Specification v1.0 (Q3 2026)<br>
• RIVP Pilot 1 — Infrastructure (Q3-Q4 2026)
</div>
</div>
<div class="phase">
<div class="phase-header">
<div class="phase-name">P1 — High</div>
<div class="phase-priority priority-high">NEXT</div>
</div>
<div style="color: #aaa; font-size: 0.85rem;">
• Reference Implementation (Q4 2026)<br>
• RIS Public Specification (Q4 2026)
</div>
</div>
<div class="phase">
<div class="phase-header">
<div class="phase-name">P2 — Medium</div>
<div class="phase-priority priority-medium">LATER</div>
</div>
<div style="color: #aaa; font-size: 0.85rem;">
• Conformance Suite (Q1 2027)<br>
• Partner SDK (Q1 2027)
</div>
</div>
<div class="phase">
<div class="phase-header">
<div class="phase-name">P3 — Future</div>
<div class="phase-priority priority-medium">FUTURE</div>
</div>
<div style="color: #aaa; font-size: 0.85rem;">
• Marketplace & Certification (Q2 2027+)
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,369 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Platform v4 - Reality Intelligence Platform</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 60px 20px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: 16px; margin-bottom: 40px; }
.hero h2 { font-size: 2.5rem; margin-bottom: 16px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.platform-stack { display: flex; flex-direction: column; gap: 16px; margin-bottom: 40px; }
.level { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; }
.level-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.level-number { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; }
.level h3 { font-size: 1.25rem; }
.level p { color: #888; font-size: 0.9rem; }
.components { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; margin-top: 16px; }
.component { background: #1a1a1a; border-radius: 8px; padding: 12px; font-size: 0.85rem; }
.component-name { color: #fff; font-weight: 600; }
.component-desc { color: #666; font-size: 0.75rem; margin-top: 4px; }
.sdk-section { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.sdk-section h2 { font-size: 1.5rem; margin-bottom: 16px; color: #00d4ff; }
.sdk-section p { color: #888; margin-bottom: 20px; }
.code-block { background: #1a1a1a; border-radius: 8px; padding: 20px; font-family: 'Monaco', monospace; font-size: 0.85rem; overflow-x: auto; }
.code-block .comment { color: #666; }
.code-block .keyword { color: #7c3aed; }
.code-block .string { color: #00d4ff; }
.object-model { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.object-model h2 { font-size: 1.5rem; margin-bottom: 16px; color: #7c3aed; }
.object-attrs { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; margin-top: 16px; }
.attr { background: #1a1a1a; border-radius: 8px; padding: 16px; }
.attr-name { color: #00d4ff; font-weight: 600; }
.attr-desc { color: #888; font-size: 0.8rem; margin-top: 4px; }
.domains { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.domain { background: #1a1a2e; border: 1px solid #333; border-radius: 8px; padding: 16px; text-align: center; }
.domain:hover { border-color: #7c3aed; }
.domain-icon { font-size: 1.5rem; margin-bottom: 8px; }
.domain-name { font-size: 0.9rem; }
.domain-status { font-size: 0.75rem; color: #666; margin-top: 4px; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Platform v4</h1>
<div class="subtitle">Reality Intelligence Platform</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Plattform</a>
<a href="#stack">Stack</a>
<a href="#sdk">SDK</a>
<a href="#domains">Domäner</a>
</div>
<div class="main">
<div class="hero">
<h2>Reality Intelligence Platform</h2>
<p>En AI-drivn plattform för verklighetsintelligens som andra företag kan bygga ovanpå. Kombinerar geospatial information, tidsserier, visuella observationer och öppna datakällor till en spårbar evidensmodell.</p>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">4-Nivåers Plattformsarkitektur</h2>
<div class="platform-stack" id="stack">
<div class="level">
<div class="level-header">
<div>
<div class="level-number">Nivå 4</div>
<h3>Experience Layer</h3>
</div>
</div>
<p>Det användaren faktiskt möter. Utvecklas oberoende av kärnan.</p>
<div class="components">
<div class="component">
<div class="component-name">Web Dashboard</div>
<div class="component-desc">Interaktiv webbapplikation</div>
</div>
<div class="component">
<div class="component-name">Mobile Apps</div>
<div class="component-desc">iOS & Android</div>
</div>
<div class="component">
<div class="component-name">QUIXZOOM</div>
<div class="component-desc">Crowdsourcing-plattform</div>
</div>
<div class="component">
<div class="component-name">API</div>
<div class="component-desc">REST & GraphQL</div>
</div>
<div class="component">
<div class="component-name">GIS Viewer</div>
<div class="component-desc">Geospatial visualisering</div>
</div>
<div class="component">
<div class="component-name">AI Copilot</div>
<div class="component-desc">Konversationell AI</div>
</div>
<div class="component">
<div class="component-name">Alert Center</div>
<div class="component-desc">Notifikationshub</div>
</div>
<div class="component">
<div class="component-name">Workflow Automation</div>
<div class="component-desc">No-code automation</div>
</div>
</div>
</div>
<div class="level">
<div class="level-header">
<div>
<div class="level-number">Nivå 3</div>
<h3>Domain Modules</h3>
</div>
</div>
<p>Vertikala tillämpningar som alla använder samma kernel.</p>
<div class="components">
<div class="component">
<div class="component-name">Infrastructure Intelligence</div>
<div class="component-desc">Vägar, broar, byggnader</div>
</div>
<div class="component">
<div class="component-name">Aid Intelligence</div>
<div class="component-desc">Biståndsprojekt</div>
</div>
<div class="component">
<div class="component-name">Environmental Intelligence</div>
<div class="component-desc">Miljö och klimat</div>
</div>
<div class="component">
<div class="component-name">Insurance Intelligence</div>
<div class="component-desc">Riskbedömning</div>
</div>
<div class="component">
<div class="component-name">City Intelligence</div>
<div class="component-desc">Stadsutveckling</div>
</div>
<div class="component">
<div class="component-name">Agriculture Intelligence</div>
<div class="component-desc">Jordbruk</div>
</div>
</div>
</div>
<div class="level">
<div class="level-header">
<div>
<div class="level-number">Nivå 2</div>
<h3>Intelligence Runtime</h3>
</div>
</div>
<p>LIFE:s "kernel" - AI-operativsystemet.</p>
<div class="components">
<div class="component">
<div class="component-name">Acquisition Engine</div>
<div class="component-desc">Datainsamling</div>
</div>
<div class="component">
<div class="component-name">Normalization Engine</div>
<div class="component-desc">Standardisering</div>
</div>
<div class="component">
<div class="component-name">Evidence Engine</div>
<div class="component-desc">Evidenshantering</div>
</div>
<div class="component">
<div class="component-name">Context Engine</div>
<div class="component-desc">Kontextuell förståelse</div>
</div>
<div class="component">
<div class="component-name">Intelligence Engine</div>
<div class="component-desc">Analys och insikter</div>
</div>
<div class="component">
<div class="component-name">Prediction Engine</div>
<div class="component-desc">Prediktiv analys</div>
</div>
<div class="component">
<div class="component-name">Decision Engine</div>
<div class="component-desc">Rekommendationer</div>
</div>
<div class="component">
<div class="component-name">Learning Engine</div>
<div class="component-desc">Självförbättring</div>
</div>
</div>
</div>
<div class="level">
<div class="level-header">
<div>
<div class="level-number">Nivå 1</div>
<h3>Foundation</h3>
</div>
</div>
<p>Teknisk kärna - abstraherad från alla vertikaler.</p>
<div class="components">
<div class="component">
<div class="component-name">Identity & Access</div>
<div class="component-desc">Autentisering</div>
</div>
<div class="component">
<div class="component-name">Event Bus</div>
<div class="component-desc">Asynkron kommunikation</div>
</div>
<div class="component">
<div class="component-name">Knowledge Graph DB</div>
<div class="component-desc">Grafbaserad lagring</div>
</div>
<div class="component">
<div class="component-name">Vector Database</div>
<div class="component-desc">Semantisk sökning</div>
</div>
<div class="component">
<div class="component-name">Time Series DB</div>
<div class="component-desc">Temporal data</div>
</div>
<div class="component">
<div class="component-name">Model Registry</div>
<div class="component-desc">AI-modellhantering</div>
</div>
</div>
</div>
</div>
<div class="sdk-section" id="sdk">
<h2>LIFE SDK</h2>
<p>Bygg egna moduler ovanpå LIFE-plattformen. Externa utvecklare och partners kan skapa egna vertikaler utan att bygga hela infrastrukturen.</p>
<div class="code-block">
<span class="comment"># Exempel: Bygg en custom modul</span>
<span class="keyword">from</span> life <span class="keyword">import</span> Client, Module
<span class="comment"># Initiera LIFE-klient</span>
client = Client(api_key=<span class="string">"your-key"</span>)
<span class="comment"># Definiera modul</span>
<span class="keyword">class</span> <span class="string">MyModule</span>(Module):
<span class="keyword">def</span> <span class="string">analyze</span>(self, project_id):
<span class="comment"># Använd LIFE:s Intelligence Runtime</span>
evidence = client.get_evidence(project_id)
insights = client.generate_insights(evidence)
<span class="keyword">return</span> insights
<span class="comment"># Deploya modulen</span>
module = MyModule()
client.deploy(module)
</div>
<p style="margin-top: 20px; color: #888;">SDK:er tillgängliga för: Python, JavaScript, Java, Go, Rust</p>
</div>
<div class="object-model">
<h2>LIFE Object Model</h2>
<p>En enhetlig objektsmodell där allt representeras med samma grundstruktur. En väg, en bro, ett sjukhus, ett biståndsprojekt eller ett träd är olika instanser av samma modell.</p>
<div class="object-attrs">
<div class="attr">
<div class="attr-name">Identity</div>
<div class="attr-desc">UUID, typ, namn, externa ID</div>
</div>
<div class="attr">
<div class="attr-name">Geometry</div>
<div class="attr-desc">Punkt, polygon, bounding box</div>
</div>
<div class="attr">
<div class="attr-name">Time</div>
<div class="attr-desc">Skapad, uppdaterad, giltighet</div>
</div>
<div class="attr">
<div class="attr-name">Evidence</div>
<div class="attr-desc">Observationer, källor, konfidens</div>
</div>
<div class="attr">
<div class="attr-name">State</div>
<div class="attr-desc">Status, framsteg, hälsa</div>
</div>
<div class="attr">
<div class="attr-name">Relationships</div>
<div class="attr-desc">Förälder, barn, relaterade</div>
</div>
<div class="attr">
<div class="attr-name">History</div>
<div class="attr-desc">Händelser, versioner, snapshots</div>
</div>
<div class="attr">
<div class="attr-name">Predictions</div>
<div class="attr-desc">Prognoser, scenarier, risker</div>
</div>
<div class="attr">
<div class="attr-name">Actions</div>
<div class="attr-desc">Rekommenderade, tillgängliga</div>
</div>
</div>
</div>
<h2 style="margin-bottom: 20px;">10+ Domäner</h2>
<p style="color: #888; margin-bottom: 20px;">LIFE är en generell plattform. Bistånd är en tillämpning, inte identitet.</p>
<div class="domains" id="domains">
<div class="domain">
<div class="domain-icon">🏗️</div>
<div class="domain-name">Infrastructure</div>
<div class="domain-status">Tillgänglig</div>
</div>
<div class="domain">
<div class="domain-icon">🌍</div>
<div class="domain-name">Aid</div>
<div class="domain-status">Tillgänglig</div>
</div>
<div class="domain">
<div class="domain-icon">🌱</div>
<div class="domain-name">Environmental</div>
<div class="domain-status">Beta</div>
</div>
<div class="domain">
<div class="domain-icon">🛡️</div>
<div class="domain-name">Insurance</div>
<div class="domain-status">Utveckling</div>
</div>
<div class="domain">
<div class="domain-icon">🏙️</div>
<div class="domain-name">City</div>
<div class="domain-status">Beta</div>
</div>
<div class="domain">
<div class="domain-icon">🌾</div>
<div class="domain-name">Agriculture</div>
<div class="domain-status">Beta</div>
</div>
<div class="domain">
<div class="domain-icon"></div>
<div class="domain-name">Energy</div>
<div class="domain-status">Utveckling</div>
</div>
<div class="domain">
<div class="domain-icon">📦</div>
<div class="domain-name">Supply Chain</div>
<div class="domain-status">Utveckling</div>
</div>
<div class="domain">
<div class="domain-icon">🔒</div>
<div class="domain-name">Security</div>
<div class="domain-status">Utveckling</div>
</div>
<div class="domain">
<div class="domain-icon">🏢</div>
<div class="domain-name">Property</div>
<div class="domain-status">Utveckling</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,216 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE — Reality Intelligence Platform</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 80px 20px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: 16px; margin-bottom: 40px; }
.hero h2 { font-size: 2.5rem; margin-bottom: 16px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto 24px; }
.hero .tagline { font-size: 1rem; color: #00d4ff; font-weight: 600; }
.vision { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; text-align: center; }
.vision h2 { font-size: 1.5rem; margin-bottom: 16px; color: #00d4ff; }
.vision p { font-size: 1.1rem; color: #aaa; max-width: 800px; margin: 0 auto; line-height: 1.8; }
.evolution { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 12px; margin-bottom: 40px; }
.evo { background: #111; border: 1px solid #333; border-radius: 8px; padding: 12px; text-align: center; }
.evo-version { font-size: 1.1rem; font-weight: 700; color: #00d4ff; }
.evo-name { font-size: 0.75rem; color: #aaa; }
.components { display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 20px; margin-bottom: 40px; }
.component { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; }
.component h3 { font-size: 1.1rem; margin-bottom: 12px; color: #00d4ff; }
.component p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.component-items { list-style: none; }
.component-items li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.component-items li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.separation { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.separation h2 { font-size: 1.5rem; margin-bottom: 16px; color: #7c3aed; }
.separation p { color: #888; margin-bottom: 16px; }
.entities { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.entity { background: #1a1a1a; border-radius: 8px; padding: 16px; }
.entity-name { color: #00d4ff; font-weight: 600; }
.entity-type { color: #888; font-size: 0.8rem; }
.entity-desc { color: #aaa; font-size: 0.75rem; margin-top: 8px; }
.cta { text-align: center; padding: 60px 20px; background: linear-gradient(180deg, #1a1a2e 0%, #0a0a0a 100%); border-radius: 16px; }
.cta h2 { font-size: 2rem; margin-bottom: 16px; color: #fff; }
.cta p { font-size: 1rem; color: #aaa; margin-bottom: 24px; }
.cta-button { display: inline-block; background: linear-gradient(90deg, #00d4ff, #7c3aed); color: #fff; padding: 12px 32px; border-radius: 8px; text-decoration: none; font-weight: 600; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE</h1>
<div class="subtitle">Reality Intelligence Platform</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Product</a>
<a href="#vision">Vision</a>
<a href="#components">Components</a>
<a href="#ecosystem">Ecosystem</a>
</div>
<div class="main">
<div class="hero">
<h2>Reality Intelligence Platform</h2>
<p>Landvex develops LIFE, a Reality Intelligence Platform and reference implementation of the Reality Intelligence Standard (RIS). Through a unified information model, traceable evidence, and explainable analysis, LIFE enables organizations to collect, verify, share, and use observations from the physical world in a consistent and interoperable way across domains.</p>
<div class="tagline">From observable signals to traceable evidence, explainable analysis, and decision support.</div>
</div>
<div class="vision" id="vision">
<h2>Vision</h2>
<p>LIFE aims to establish an open framework and common standards for Reality Intelligence, similar to how open standards have enabled interoperability in other technology areas. By combining geospatial data, field observations, open data sources, and AI, LIFE transforms observable signals from the physical world into traceable evidence.</p>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">Evolution</h2>
<div class="evolution">
<div class="evo">
<div class="evo-version">v1</div>
<div class="evo-name">Aid Intelligence</div>
</div>
<div class="evo">
<div class="evo-version">v2</div>
<div class="evo-name">Multi-signal</div>
</div>
<div class="evo">
<div class="evo-version">v3</div>
<div class="evo-name">Core Architecture</div>
</div>
<div class="evo">
<div class="evo-version">v4</div>
<div class="evo-name">Platform</div>
</div>
<div class="evo">
<div class="evo-version">v5</div>
<div class="evo-name">Enterprise</div>
</div>
<div class="evo">
<div class="evo-version">v6</div>
<div class="evo-name">Standard</div>
</div>
<div class="evo">
<div class="evo-version">v7</div>
<div class="evo-name">Ecosystem</div>
</div>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">Key Components</h2>
<div class="components" id="components">
<div class="component">
<h3>🔬 Reality Intelligence</h3>
<p>Analyzes the physical world, not just text and documents</p>
<ul class="component-items">
<li>Geospatial data fusion</li>
<li>Field observations</li>
<li>Visual data analysis</li>
<li>Time-series monitoring</li>
</ul>
</div>
<div class="component">
<h3>📋 Evidence Before Opinion</h3>
<p>Starts with observations, not conclusions</p>
<ul class="component-items">
<li>Traceable evidence chains</li>
<li>Source attribution</li>
<li>Confidence scoring</li>
<li>Contradiction detection</li>
</ul>
</div>
<div class="component">
<h3>🌐 Multi-source Fusion</h3>
<p>Combines satellite, field, open data, and AI</p>
<ul class="component-items">
<li>Satellite imagery (Sentinel-2, etc.)</li>
<li>QUIXZOOM crowdsourcing</li>
<li>IoT sensors</li>
<li>Official reports</li>
</ul>
</div>
<div class="component">
<h3>🔍 Explainability</h3>
<p>Every insight is explainable and auditable</p>
<ul class="component-items">
<li>Decision lineage</li>
<li>Confidence breakdown</li>
<li>Source transparency</li>
<li>Hypothesis tracking</li>
</ul>
</div>
<div class="component">
<h3>📦 Open Standards (RIS)</h3>
<p>Six open standards for Reality Intelligence</p>
<ul class="component-items">
<li>RIS-001: Reality Object Standard</li>
<li>RIS-002: Evidence Standard</li>
<li>RIS-003: Confidence Standard</li>
<li>RIS-004: Reality Exchange Protocol</li>
<li>RIS-005: Decision Standard</li>
<li>RIS-006: Learning Standard</li>
</ul>
</div>
<div class="component">
<h3>🚀 Reference Implementation</h3>
<p>Open source implementation of RIS</p>
<ul class="component-items">
<li>LIFE Server (Python/FastAPI)</li>
<li>LIFE Client (React/TypeScript)</li>
<li>SDK: Python, JS, Java, Go, Rust</li>
<li>Example data and APIs</li>
</ul>
</div>
</div>
<div class="separation" id="ecosystem">
<h2>Strategic Separation</h2>
<p>Three distinct layers, common in successful ecosystems: the standard can be open, while the reference implementation and commercial extensions continue to be developed by the company.</p>
<div class="entities">
<div class="entity">
<div class="entity-name">RIS</div>
<div class="entity-type">Open Standard</div>
<div class="entity-desc">The open specification. Community-governed. CC BY 4.0. Free to use.</div>
</div>
<div class="entity">
<div class="entity-name">LIFE</div>
<div class="entity-type">Reference Implementation</div>
<div class="entity-desc">Reference implementation of the standard. Open source. Apache 2.0. Free to use.</div>
</div>
<div class="entity">
<div class="entity-name">Landvex</div>
<div class="entity-type">Commercial Company</div>
<div class="entity-desc">The company that develops and commercializes LIFE. Proprietary services. Paid offerings.</div>
</div>
</div>
</div>
<div class="cta">
<h2>Build on LIFE</h2>
<p>Join the Reality Intelligence ecosystem. Build custom modules, integrate your data, or deploy your own LIFE instance.</p>
<a href="https://docs.life.ai" class="cta-button">Get Started →</a>
</div>
</div>
</body>
</html>
@@ -0,0 +1,223 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Standard v6 - Reality Intelligence Standard</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 60px 20px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: 16px; margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 16px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.standards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin-bottom: 40px; }
.standard { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; }
.standard-id { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
.standard h3 { font-size: 1.1rem; margin-bottom: 12px; }
.standard p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.standard-attrs { list-style: none; }
.standard-attrs li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.standard-attrs li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.ontology { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.ontology h2 { font-size: 1.5rem; margin-bottom: 16px; color: #7c3aed; }
.ontology-levels { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.level { background: #1a1a1a; border-radius: 8px; padding: 16px; }
.level-name { color: #00d4ff; font-weight: 600; }
.level-desc { color: #888; font-size: 0.8rem; margin-top: 4px; }
.level-concepts { color: #aaa; font-size: 0.75rem; margin-top: 8px; }
.product-def { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; text-align: center; }
.product-def h2 { font-size: 1.5rem; margin-bottom: 16px; color: #00d4ff; }
.product-def p { font-size: 1.1rem; color: #aaa; max-width: 700px; margin: 0 auto; line-height: 1.8; }
.evolution { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; margin-bottom: 40px; }
.evo { background: #111; border: 1px solid #333; border-radius: 8px; padding: 12px; text-align: center; }
.evo-version { font-size: 1.1rem; font-weight: 700; color: #00d4ff; }
.evo-name { font-size: 0.8rem; color: #aaa; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Standard v6</h1>
<div class="subtitle">Reality Intelligence Standard</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Standard</a>
<a href="#standards">RIS</a>
<a href="#ontology">Ontologi</a>
</div>
<div class="main">
<div class="hero">
<h2>Reality Intelligence Standard</h2>
<p>LIFE är inte bara programvara. Det definierar HUR verklighetsintelligens representeras, valideras, utbyts och används — oberoende av tillämpning.</p>
</div>
<div class="product-def">
<h2>Produktdefinition v6</h2>
<p>"LIFE är ett AI-drivet operativsystem och en öppen standard för Reality Intelligence. Genom att förena en gemensam informationsmodell, spårbar evidens, förklarbara analyser och kontinuerligt lärande gör LIFE det möjligt att beskriva, förstå och följa förändringar i den fysiska världen på ett konsekvent sätt över olika domäner och organisationer."</p>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">Evolution av LIFE</h2>
<div class="evolution">
<div class="evo">
<div class="evo-version">v1</div>
<div class="evo-name">Aid Intelligence</div>
</div>
<div class="evo">
<div class="evo-version">v2</div>
<div class="evo-name">Multi-signal</div>
</div>
<div class="evo">
<div class="evo-version">v3</div>
<div class="evo-name">Core Architecture</div>
</div>
<div class="evo">
<div class="evo-version">v4</div>
<div class="evo-name">Platform</div>
</div>
<div class="evo">
<div class="evo-version">v5</div>
<div class="evo-name">Enterprise</div>
</div>
<div class="evo">
<div class="evo-version">v6</div>
<div class="evo-name">Standard</div>
</div>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">6 Öppna Standarder (RIS)</h2>
<div class="standards" id="standards">
<div class="standard">
<div class="standard-id">RIS-001</div>
<h3>Reality Object Standard</h3>
<p>En gemensam objektsmodell för allt i den fysiska världen</p>
<ul class="standard-attrs">
<li>Identity (UUID, typ, namn)</li>
<li>Geometry (punkt, polygon, polyline)</li>
<li>Time (skapad, uppdaterad, giltighet)</li>
<li>State (status, framsteg, hälsa)</li>
<li>Evidence (observationer, källor)</li>
<li>Confidence (sammansatt säkerhet)</li>
<li>Relationships (kopplingar till andra)</li>
<li>History (händelser, versioner)</li>
<li>Predictions (framtida prognoser)</li>
<li>Actions (rekommenderade åtgärder)</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-002</div>
<h3>Evidence Standard</h3>
<p>All evidens representeras likadant oavsett källa</p>
<ul class="standard-attrs">
<li>Källa (satellit, fält, rapport)</li>
<li>Tidsstämpel</li>
<li>Geografisk position</li>
<li>Metod (hur observationen gjordes)</li>
<li>Kvalitet (0-100)</li>
<li>Osäkerhet (spatial, temporal)</li>
<li>Valideringsstatus</li>
<li>Revisionshistorik</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-003</div>
<h3>Confidence Standard</h3>
<p>Alla modeller använder samma definition av säkerhet</p>
<ul class="standard-attrs">
<li>Data Confidence (tillförlitlighet)</li>
<li>Source Confidence (källkvalitet)</li>
<li>AI Confidence (modellträffsäkerhet)</li>
<li>Human Verification (mänsklig granskning)</li>
<li>Temporal Confidence (tidsrelevans)</li>
<li>Composite Confidence (sammansatt)</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-004</div>
<h3>Reality Exchange Protocol</h3>
<p>Öppet format för utbyte mellan system</p>
<ul class="standard-attrs">
<li>/objects — Fysiska objekt</li>
<li>/observations — Observationer</li>
<li>/evidence — Evidens</li>
<li>/relationships — Relationer</li>
<li>/events — Händelser</li>
<li>/hypotheses — Hypoteser</li>
<li>/predictions — Prognoser</li>
<li>/actions — Åtgärder</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-005</div>
<h3>Decision Standard</h3>
<p>Alla rekommendationer följer samma struktur</p>
<ul class="standard-attrs">
<li>Observation → vad observerats?</li>
<li>Evidence → vad stöder det?</li>
<li>Confidence → hur säker är bedömningen?</li>
<li>Hypothesis → vad förklarar det?</li>
<li>Recommended Action → vad bör göras?</li>
<li>Expected Outcome → vad förväntas?</li>
<li>Verification Plan → hur verifieras det?</li>
</ul>
</div>
<div class="standard">
<div class="standard-id">RIS-006</div>
<h3>Learning Standard</h3>
<p>AI-modeller utvärderas mot verkliga utfall</p>
<ul class="standard-attrs">
<li>Prediction Accuracy (hur ofta korrekt?)</li>
<li>Hypothesis Validation (vilka stämde?)</li>
<li>Signal Informativeness (vilka bidrog mest?)</li>
<li>Temporal Improvement (förbättring över tid)</li>
<li>Feedback Loops (verkliga utfall matas tillbaka)</li>
</ul>
</div>
</div>
<div class="ontology" id="ontology">
<h2>Gemensam Ontologi</h2>
<p>Tre nivåer för att balansera generell kärna med domänspecifika och kundspecifika begrepp.</p>
<div class="ontology-levels">
<div class="level">
<div class="level-name">Core Ontology</div>
<div class="level-desc">Universella begrepp — FROZEN</div>
<div class="level-concepts">Object, Observation, Evidence, Relation, Event, Hypothesis, Prediction, Action, Confidence, Time, Space, Agent</div>
</div>
<div class="level">
<div class="level-name">Domain Ontologies</div>
<div class="level-desc">Domänspecifika — STABLE</div>
<div class="level-concepts">Infrastructure: Road, Bridge, Building<br>Aid: Project, Beneficiary, Milestone<br>Insurance: Policy, Claim, RiskFactor<br>Environment: Ecosystem, PollutionLevel</div>
</div>
<div class="level">
<div class="level-name">Customer Extensions</div>
<div class="level-desc">Kundspecifika — FLEXIBLE</div>
<div class="level-concepts">Municipality: SnowRemovalRoute<br>Company: CustomAssetType<br>Any customer-defined concept</div>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,267 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex LIFE v2 - Operativ Intelligensmotor</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #0a0a0a; color: #e0e0e0; line-height: 1.6; }
.header { background: #111; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #fff; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #111; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.philosophy { background: #111; border-radius: 12px; padding: 32px; margin-bottom: 32px; border-left: 4px solid #00d4ff; }
.philosophy h2 { font-size: 1.25rem; margin-bottom: 16px; color: #fff; }
.philosophy p { color: #aaa; margin-bottom: 12px; }
.process { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 20px; }
.process-step { background: #1a1a1a; border-radius: 8px; padding: 16px; text-align: center; }
.process-step .number { font-size: 1.5rem; font-weight: 700; color: #00d4ff; }
.process-step .name { font-size: 0.9rem; color: #fff; margin-top: 8px; }
.process-step .desc { font-size: 0.75rem; color: #666; margin-top: 4px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; margin-bottom: 32px; }
.stat-card { background: #111; border-radius: 12px; padding: 24px; border: 1px solid #333; }
.stat-card h3 { font-size: 0.75rem; color: #666; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #fff; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #00d4ff; }
.component-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin-bottom: 32px; }
.component-card { background: #111; border-radius: 12px; padding: 24px; border: 1px solid #333; }
.component-card h3 { font-size: 1rem; margin-bottom: 12px; color: #00d4ff; display: flex; align-items: center; gap: 8px; }
.component-card p { font-size: 0.85rem; color: #aaa; margin-bottom: 8px; }
.component-card .stats { font-size: 0.8rem; color: #666; }
.section { background: #111; border-radius: 12px; padding: 24px; margin-bottom: 24px; border: 1px solid #333; }
.section h2 { font-size: 1.1rem; margin-bottom: 16px; color: #fff; }
.hypothesis-card { background: #1a1a1a; border-radius: 8px; padding: 16px; margin-bottom: 12px; border-left: 3px solid #00d4ff; }
.hypothesis-card h4 { font-size: 0.95rem; margin-bottom: 8px; color: #fff; }
.hypothesis-card p { font-size: 0.85rem; color: #aaa; }
.hypothesis-card .confidence { font-size: 0.8rem; color: #00d4ff; margin-top: 8px; }
.dna-bar { background: #1a1a1a; border-radius: 4px; height: 24px; overflow: hidden; margin-top: 8px; display: flex; }
.dna-bar .segment { height: 100%; display: flex; align-items: center; justify-content: center; font-size: 0.7rem; color: #fff; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>Landvex LIFE v2</h1>
<div class="subtitle">Operativ Intelligensmotor - 7 Kärnkomponenter</div>
</div>
<div style="text-align: right;">
<div style="font-size: 0.8rem; color: #666;">Komponenter</div>
<div style="font-size: 1.5rem; font-weight: 700;">7/7</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Dashboard</a>
<a href="#components">Komponenter</a>
<a href="#hypotheses">Hypoteser</a>
<a href="#dna">Reality DNA</a>
</div>
<div class="main">
<div class="philosophy">
<h2>Evidence Before Opinion</h2>
<p>Systemet börjar aldrig med en slutsats och letar stöd för den. Istället bygger varje analys från observerbara signaler uppåt.</p>
<div class="process">
<div class="process-step">
<div class="number">1</div>
<div class="name">Gather Facts</div>
<div class="desc">Samla observerbara signaler</div>
</div>
<div class="process-step">
<div class="number">2</div>
<div class="name">Weigh Sources</div>
<div class="desc">Värdera oberoende källor</div>
</div>
<div class="process-step">
<div class="number">3</div>
<div class="name">Identify Patterns</div>
<div class="desc">Identifiera mönster</div>
</div>
<div class="process-step">
<div class="number">4</div>
<div class="name">Generate Hypotheses</div>
<div class="desc">Formulera hypoteser</div>
</div>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<h3>Evidence Graph Noder</h3>
<div class="value">125K</div>
<div class="change positive">+450K edges</div>
</div>
<div class="stat-card">
<h3>Tracked Observations</h3>
<div class="value">45K</div>
<div class="change positive">Med full lineage</div>
</div>
<div class="stat-card">
<h3>Contradictions</h3>
<div class="value">1,247</div>
<div class="change positive">AI-träningsdata</div>
</div>
<div class="stat-card">
<h3>Hypoteser</h3>
<div class="value">3,400</div>
<div class="change positive">Rangordnade</div>
</div>
<div class="stat-card">
<h3>Reality DNA Profiler</h3>
<div class="value">1,250</div>
<div class="change">Projekt profilerade</div>
</div>
<div class="stat-card">
<h3>Memory Storage</h3>
<div class="value">2.4 TB</div>
<div class="change">Permanent</div>
</div>
</div>
<div class="component-grid" id="components">
<div class="component-card">
<h3>🔗 Evidence Graph (EG)</h3>
<p>Hierarkisk graf där varje observation är en spårbar nod</p>
<p style="font-size: 0.8rem; color: #666;">Observation → Object → Project → Programme → Organisation → Region → Country</p>
<div class="stats">125,000 noder | 450,000 edges</div>
</div>
<div class="component-card">
<h3>📜 Evidence Lineage</h3>
<p>Komplett ursprung för varje datapunkt</p>
<p style="font-size: 0.8rem; color: #666;">Source → Collected → Validated → Cross-validated → AI confidence → Human verification</p>
<div class="stats">45,000 observationer spårade</div>
</div>
<div class="component-card">
<h3>⏰ Temporal Reality Engine</h3>
<p>Tidsmaskin för att se hur verkligheten förändras</p>
<p style="font-size: 0.8rem; color: #666;">Vad såg området ut för 6 månader sedan? Vad har förändrats? Hur snabbt?</p>
<div class="stats">3 års historik | 8,900 förändringar</div>
</div>
<div class="component-card">
<h3>⚠️ Contradiction Knowledge Base</h4>
<p>Alla avvikelser lagras för AI-träning</p>
<p style="font-size: 0.8rem; color: #666;">Efter några år: hundratusentals verkliga exempel</p>
<div class="stats">1,247 avvikelser | 6 kategorier</div>
</div>
<div class="component-card">
<h3>🧬 Reality DNA</h3>
<p>Projektets fingeravtryck för benchmarking</p>
<p style="font-size: 0.8rem; color: #666;">9 dimensioner: Activity, Maintenance, Infrastructure, Community Usage, Traffic, Economic Activity, Environmental Status, Safety, Operational Continuity</p>
<div class="stats">1,250 profiler | Jämförbara</div>
</div>
<div class="component-card">
<h3>💾 Reality Memory</h3>
<p>LIFE kastar aldrig bort något</p>
<p style="font-size: 0.8rem; color: #666;">Varje observation, AI-bedömning och förändring sparas permanent</p>
<div class="stats">2.4 TB | Full reproducerbarhet</div>
</div>
<div class="component-card">
<h3>🧠 Reality Hypothesis Engine</h3>
<p>Inte "Det här är orsaken" utan "Här är möjliga förklaringar..."</p>
<p style="font-size: 0.8rem; color: #666;">Rangordnade efter hur väl de stöds av observerbara data</p>
<div class="stats">3,400 hypoteser | Med osäkerhetsintervall</div>
</div>
</div>
<div class="section" id="hypotheses">
<h2>Reality Hypothesis Engine - Exempel</h2>
<p style="color: #666; margin-bottom: 16px;">Observerat fenomen: Construction progress slower than reported (85% observed vs 95% reported)</p>
<div class="hypothesis-card">
<h4>#1 Interior work behind schedule while exterior nearly complete</h4>
<p>Field observations show exterior walls and roof complete. Windows visible but interior not accessible. Satellite cannot detect interior progress.</p>
<div class="confidence">Confidence: 78% | Support: Strong | Action: Request interior photos</div>
</div>
<div class="hypothesis-card">
<h4>#2 Flooding in June caused 2-week delay</h4>
<p>Satellite shows flooding June 15. Weather data confirms 120% average rainfall. Field observations show reduced activity June 15-30.</p>
<div class="confidence">Confidence: 72% | Support: Moderate | Action: Verify revised timeline</div>
</div>
<div class="hypothesis-card">
<h4>#3 Material supply disruption affected interior work</h4>
<p>Procurement data shows delayed deliveries. Some materials visible on site but not installed.</p>
<div class="confidence">Confidence: 55% | Support: Weak | Action: Check supplier records</div>
</div>
<div class="hypothesis-card" style="border-left-color: #666;">
<h4>#4 Reporting methodology differs from observation methodology</h4>
<p>Official report may count 'started' as 'complete'. Different measurement standards possible.</p>
<div class="confidence">Confidence: 45% | Support: Speculative | Action: Review reporting methodology</div>
</div>
</div>
<div class="section" id="dna">
<h2>Reality DNA - Projektets Fingeravtryck</h2>
<p style="color: #666; margin-bottom: 16px;">9-dimensionell profil som kan jämföras med liknande projekt</p>
<div style="margin-bottom: 20px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>Activity</span>
<span style="color: #00d4ff;">78%</span>
</div>
<div class="dna-bar">
<div class="segment" style="width: 78%; background: #00d4ff;">78%</div>
</div>
</div>
<div style="margin-bottom: 20px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>Infrastructure</span>
<span style="color: #00d4ff;">82%</span>
</div>
<div class="dna-bar">
<div class="segment" style="width: 82%; background: #00d4ff;">82%</div>
</div>
</div>
<div style="margin-bottom: 20px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>Safety</span>
<span style="color: #00d4ff;">80%</span>
</div>
<div class="dna-bar">
<div class="segment" style="width: 80%; background: #00d4ff;">80%</div>
</div>
</div>
<div style="margin-bottom: 20px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>Community Usage</span>
<span style="color: #fbbf24;">70%</span>
</div>
<div class="dna-bar">
<div class="segment" style="width: 70%; background: #fbbf24;">70%</div>
</div>
</div>
<div style="margin-bottom: 20px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
<span>Maintenance</span>
<span style="color: #fbbf24;">65%</span>
</div>
<div class="dna-bar">
<div class="segment" style="width: 65%; background: #fbbf24;">65%</div>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,226 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Validation - Reality Intelligence Validation Program</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.nav { background: #0a0a0a; border-bottom: 1px solid #333; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #666; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #00d4ff; border-bottom-color: #00d4ff; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.hero { text-align: center; padding: 60px 20px; background: linear-gradient(180deg, #0a0a0a 0%, #1a1a2e 100%); border-radius: 16px; margin-bottom: 40px; }
.hero h2 { font-size: 2rem; margin-bottom: 16px; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.hero p { font-size: 1rem; color: #aaa; max-width: 800px; margin: 0 auto; }
.phases { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin-bottom: 40px; }
.phase { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; }
.phase-number { font-size: 0.75rem; color: #00d4ff; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; }
.phase h3 { font-size: 1.1rem; margin-bottom: 12px; }
.phase p { color: #888; font-size: 0.85rem; margin-bottom: 12px; }
.phase-objs { list-style: none; }
.phase-objs li { color: #aaa; font-size: 0.8rem; padding: 4px 0; padding-left: 16px; position: relative; }
.phase-objs li::before { content: "→"; position: absolute; left: 0; color: #00d4ff; }
.metrics { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.metrics h2 { font-size: 1.5rem; margin-bottom: 16px; color: #7c3aed; }
.metrics p { color: #888; margin-bottom: 16px; }
.metric-dims { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; margin-top: 16px; }
.dim { background: #1a1a1a; border-radius: 8px; padding: 16px; }
.dim-name { color: #00d4ff; font-weight: 600; }
.dim-desc { color: #888; font-size: 0.8rem; margin-top: 4px; }
.dim-kpis { color: #aaa; font-size: 0.75rem; margin-top: 8px; }
.spec { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 40px; }
.spec h2 { font-size: 1.5rem; margin-bottom: 16px; color: #00d4ff; }
.spec p { color: #888; margin-bottom: 16px; }
.spec-sections { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; }
.spec-section { background: #1a1a1a; border-radius: 8px; padding: 12px; }
.spec-num { color: #00d4ff; font-size: 0.75rem; }
.spec-title { color: #fff; font-size: 0.85rem; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Validation</h1>
<div class="subtitle">Reality Intelligence Validation Program</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #666;">← Admin</a>
<a href="#" class="active">Validation</a>
<a href="#phases">Faser</a>
<a href="#metrics">KPI:er</a>
</div>
<div class="main">
<div class="hero">
<h2>Reality Intelligence Validation Program</h2>
<p>Många tekniska projekt fortsätter bygga lager utan att validera dem. RIVP säkerställer att varje fas bevisar verkligt värde innan vidare utveckling.</p>
</div>
<h2 style="margin-bottom: 20px; color: #00d4ff;">4 Faser</h2>
<div class="phases" id="phases">
<div class="phase">
<div class="phase-number">Fas 1</div>
<h3>🛣️ Infrastruktur</h3>
<p>6 månader — Vägar, broar, arbeten</p>
<ul class="phase-objs">
<li>Hitta vägskador (>80% precision)</li>
<li>Följa vägarbeten (±10%)</li>
<li>Upptäcka förändringar (<48h)</li>
<li>Verifiera reparationer (>90%)</li>
</ul>
</div>
<div class="phase">
<div class="phase-number">Fas 2</div>
<h3>🏙️ Kommun</h3>
<p>6 månader — Parker, belysning, skyltning</p>
<ul class="phase-objs">
<li>Följa parker (veckovis)</li>
<li>Gatubelysning (>95% täckning)</li>
<li>Skyltning (±5% inventering)</li>
<li>Avfall (90% illegala platser)</li>
<li>Vinterunderhåll (<4h)</li>
</ul>
</div>
<div class="phase">
<div class="phase-number">Fas 3</div>
<h3>🏢 Fastigheter</h3>
<p>6 månader — Byggnader, skador, underhåll</p>
<ul class="phase-objs">
<li>Följa byggnader (månadsvis)</li>
<li>Upptäcka skador (>75% precision)</li>
<li>Följa underhåll (100% spårbarhet)</li>
<li>Analysera risk (±1 nivå)</li>
</ul>
</div>
<div class="phase">
<div class="phase-number">Fas 4</div>
<h3>🌍 Bistånd</h3>
<p>12 månader — Projekt, observationer, verifiering</p>
<ul class="phase-objs">
<li>Följa projekt över tid (±15%)</li>
<li>Samla oberoende observationer (>50%)</li>
<li>Kombinera flera källor (>3/objekt)</li>
<li>Identifiera verifieringsbehov (>80%)</li>
</ul>
</div>
</div>
<div class="metrics" id="metrics">
<h2>6 Dimensioner för Framgång</h2>
<p>Fokus på faktisk användning, inte antal moduler.</p>
<div class="metric-dims">
<div class="dim">
<div class="dim-name">📊 Datatäckning</div>
<div class="dim-desc">Andel objekt med aktuell data</div>
<div class="dim-kpis">Object Coverage >95%<br>Geographic Coverage >90%</div>
</div>
<div class="dim">
<div class="dim-name">⏱️ Aktualitet</div>
<div class="dim-desc">Tid från förändring till observation</div>
<div class="dim-kpis">Detection Time <48h<br>Alert Latency <1h</div>
</div>
<div class="dim">
<div class="dim-name">🔍 Evidenskvalitet</div>
<div class="dim-desc">Konfidens och verifiering</div>
<div class="dim-kpis">Avg Confidence >75<br>Verification Rate >30%</div>
</div>
<div class="dim">
<div class="dim-name">🎯 Analyskvalitet</div>
<div class="dim-desc">Användbarhet och korrekthet</div>
<div class="dim-kpis">User Satisfaction >80%<br>Decision Adoption >60%</div>
</div>
<div class="dim">
<div class="dim-name">📈 Adoption</div>
<div class="dim-desc">Externa implementationer</div>
<div class="dim-kpis">External Impl >10<br>Partner Integrations >20</div>
</div>
<div class="dim">
<div class="dim-name">🔗 Interoperabilitet</div>
<div class="dim-desc">System som utbyter data</div>
<div class="dim-kpis">RIS Compatible >15<br>Data Exchange >1TB/mån</div>
</div>
</div>
</div>
<div class="spec">
<h2>Teknisk Specifikation (Nästa Leverans)</h2>
<p>Efter validering: RFC/ISO-liknande standard som blir referens för utvecklare, partners och kunder.</p>
<div class="spec-sections">
<div class="spec-section">
<div class="spec-num">1</div>
<div class="spec-title">Executive Summary</div>
</div>
<div class="spec-section">
<div class="spec-num">2</div>
<div class="spec-title">Vision and Principles</div>
</div>
<div class="spec-section">
<div class="spec-num">3</div>
<div class="spec-title">Architecture</div>
</div>
<div class="spec-section">
<div class="spec-num">4</div>
<div class="spec-title">Ontology</div>
</div>
<div class="spec-section">
<div class="spec-num">5</div>
<div class="spec-title">RIS Specifications</div>
</div>
<div class="spec-section">
<div class="spec-num">6</div>
<div class="spec-title">Object Model</div>
</div>
<div class="spec-section">
<div class="spec-num">7</div>
<div class="spec-title">Evidence Model</div>
</div>
<div class="spec-section">
<div class="spec-num">8</div>
<div class="spec-title">API Contracts</div>
</div>
<div class="spec-section">
<div class="spec-num">9</div>
<div class="spec-title">Security Model</div>
</div>
<div class="spec-section">
<div class="spec-num">10</div>
<div class="spec-title">Versioning Strategy</div>
</div>
<div class="spec-section">
<div class="spec-num">11</div>
<div class="spec-title">Governance</div>
</div>
<div class="spec-section">
<div class="spec-num">12</div>
<div class="spec-title">Reference Implementation</div>
</div>
<div class="spec-section">
<div class="spec-num">13</div>
<div class="spec-title">Conformance Requirements</div>
</div>
<div class="spec-section">
<div class="spec-num">14</div>
<div class="spec-title">Examples and Test Cases</div>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,288 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Landvex Intelligence Fusion Engine (LIFE)</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #0f172a; color: #e2e8f0; line-height: 1.6; }
.header { background: #1e293b; border-bottom: 1px solid #334155; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #f8fafc; }
.header .subtitle { color: #94a3b8; font-size: 0.85rem; }
.nav { background: #1e293b; border-bottom: 1px solid #334155; padding: 0 40px; display: flex; gap: 4px; }
.nav a { color: #94a3b8; text-decoration: none; padding: 12px 20px; font-size: 0.85rem; transition: all 0.2s; border-bottom: 2px solid transparent; }
.nav a:hover, .nav a.active { color: #38bdf8; border-bottom-color: #38bdf8; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.philosophy { background: #1e293b; border-radius: 12px; padding: 32px; margin-bottom: 32px; border-left: 4px solid #38bdf8; }
.philosophy h2 { font-size: 1.25rem; margin-bottom: 16px; color: #f8fafc; }
.philosophy p { color: #cbd5e1; margin-bottom: 12px; }
.philosophy .process { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 20px; }
.process-step { background: #334155; border-radius: 8px; padding: 16px; text-align: center; }
.process-step .number { font-size: 1.5rem; font-weight: 700; color: #38bdf8; }
.process-step .name { font-size: 0.9rem; color: #f8fafc; margin-top: 8px; }
.process-step .desc { font-size: 0.75rem; color: #94a3b8; margin-top: 4px; }
.stats-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; margin-bottom: 32px; }
.stat-card { background: #1e293b; border-radius: 12px; padding: 24px; border: 1px solid #334155; }
.stat-card h3 { font-size: 0.75rem; color: #94a3b8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
.stat-card .value { font-size: 2rem; font-weight: 700; color: #f8fafc; }
.stat-card .change { font-size: 0.8rem; margin-top: 4px; }
.stat-card .change.positive { color: #4ade80; }
.section { background: #1e293b; border-radius: 12px; padding: 24px; margin-bottom: 24px; border: 1px solid #334155; }
.section h2 { font-size: 1.1rem; margin-bottom: 16px; color: #f8fafc; }
.data-source { display: flex; align-items: center; gap: 12px; padding: 12px; background: #334155; border-radius: 8px; margin-bottom: 8px; }
.data-source .icon { width: 40px; height: 40px; background: #475569; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; }
.data-source .info { flex: 1; }
.data-source .info h4 { font-size: 0.9rem; color: #f8fafc; }
.data-source .info p { font-size: 0.75rem; color: #94a3b8; }
.data-source .status { font-size: 0.75rem; padding: 4px 8px; border-radius: 4px; }
.data-source .status.active { background: #166534; color: #4ade80; }
.event-card { background: #334155; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.event-card h4 { font-size: 0.95rem; margin-bottom: 8px; }
.event-card .meta { font-size: 0.8rem; color: #94a3b8; margin-bottom: 8px; }
.event-card .severity { display: inline-block; padding: 3px 10px; border-radius: 4px; font-size: 0.7rem; font-weight: 600; }
.event-card .severity.high { background: #7f1d1d; color: #fca5a5; }
.event-card .severity.medium { background: #713f12; color: #fde047; }
.event-card .severity.low { background: #1e3a5f; color: #93c5fd; }
.confidence-bar { background: #334155; border-radius: 4px; height: 8px; overflow: hidden; margin-top: 8px; }
.confidence-bar .fill { height: 100%; border-radius: 4px; }
.confidence-bar .fill.high { background: #4ade80; }
.confidence-bar .fill.medium { background: #fbbf24; }
.confidence-bar .fill.low { background: #f87171; }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.insight-card { background: #334155; border-radius: 8px; padding: 16px; margin-bottom: 12px; }
.insight-card h4 { font-size: 0.9rem; margin-bottom: 8px; color: #38bdf8; }
.insight-card p { font-size: 0.85rem; color: #cbd5e1; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>Landvex Intelligence Fusion Engine</h1>
<div class="subtitle">Continuous Multi-Source Intelligence Platform</div>
</div>
<div style="text-align: right;">
<div style="font-size: 0.8rem; color: #94a3b8;">Data Streams</div>
<div style="font-size: 1.5rem; font-weight: 700;">45</div>
</div>
</div>
<div class="nav">
<a href="/admin/" style="color: #94a3b8;">← Admin</a>
<a href="#" class="active">Dashboard</a>
<a href="#sources">Sources</a>
<a href="#events">Events</a>
<a href="#analysis">Analysis</a>
</div>
<div class="main">
<div class="philosophy">
<h2>Evidence Before Opinion</h2>
<p>The system never starts with a conclusion and looks for support. Instead, every analysis builds from observable signals upward.</p>
<div class="process">
<div class="process-step">
<div class="number">1</div>
<div class="name">Gather Facts</div>
<div class="desc">Collect observable signals from all available sources</div>
</div>
<div class="process-step">
<div class="number">2</div>
<div class="name">Weigh Sources</div>
<div class="desc">Evaluate independent sources and their reliability</div>
</div>
<div class="process-step">
<div class="number">3</div>
<div class="name">Identify Patterns</div>
<div class="desc">Detect statistical associations and correlations</div>
</div>
<div class="process-step">
<div class="number">4</div>
<div class="name">Generate Hypotheses</div>
<div class="desc">Form cautious hypotheses about possible causes</div>
</div>
</div>
</div>
<div class="stats-grid">
<div class="stat-card">
<h3>Projects Monitored</h3>
<div class="value">1,250</div>
<div class="change positive">With context graphs</div>
</div>
<div class="stat-card">
<h3>Data Sources</h3>
<div class="value">6</div>
<div class="change">Categories active</div>
</div>
<div class="stat-card">
<h3>Events Detected (24h)</h3>
<div class="value">12</div>
<div class="change positive">Auto-detected</div>
</div>
<div class="stat-card">
<h3>Avg Confidence</h3>
<div class="value">82%</div>
<div class="change positive">Multi-source fusion</div>
</div>
<div class="stat-card">
<h3>Streams Monitored</h3>
<div class="value">45</div>
<div class="change">Continuous ingestion</div>
</div>
<div class="stat-card">
<h3>Predictions Made</h3>
<div class="value">3,400</div>
<div class="change">With uncertainty intervals</div>
</div>
</div>
<div class="section">
<h2>Continuous Data Acquisition</h2>
<div class="data-source">
<div class="icon">📊</div>
<div class="info">
<h4>Official Project Information</h4>
<p>Development agency portals, government databases, procurement portals, evaluation reports</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon">📰</div>
<div class="info">
<h4>News Intelligence</h4>
<p>International, national, regional news, RSS feeds, development and humanitarian news</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon">🌐</div>
<div class="info">
<h4>Public Communications</h4>
<p>Press releases, official websites, social media, research publications</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon">🛰️</div>
<div class="info">
<h4>Geospatial Intelligence</h4>
<p>Satellite imagery, night lights, land cover, construction detection, environmental monitoring</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon">📱</div>
<div class="info">
<h4>QUIXZOOM Reality Network</h4>
<p>Field observations, photographic evidence, infrastructure inspections, community observations</p>
</div>
<div class="status active">Active</div>
</div>
<div class="data-source">
<div class="icon">📈</div>
<div class="info">
<h4>Open Data</h4>
<p>Population, weather, climate, health indicators, economic data, conflict datasets</p>
</div>
<div class="status active">Active</div>
</div>
</div>
<div class="grid-2">
<div class="section">
<h2>Recent Events Detected</h2>
<div class="event-card">
<h4>🌊 Severe flooding in Mogadishu region</h4>
<div class="meta">Somalia • June 15, 2026 • Natural Disaster</div>
<p style="font-size: 0.85rem; color: #cbd5e1; margin-bottom: 8px;">Heavy rainfall caused flooding affecting infrastructure accessibility</p>
<div>
<span class="severity high">High Severity</span>
<span style="font-size: 0.8rem; color: #94a3b8; margin-left: 8px;">Confidence: 92%</span>
</div>
<div class="confidence-bar">
<div class="fill high" style="width: 92%;"></div>
</div>
</div>
<div class="event-card">
<h4>🏗️ Construction delay due to seasonal rainfall</h4>
<div class="meta">Nigeria • May 20, 2026 • Construction Delay</div>
<p style="font-size: 0.85rem; color: #cbd5e1; margin-bottom: 8px;">Road rehabilitation delayed due to extended rainy season</p>
<div>
<span class="severity medium">Medium Severity</span>
<span style="font-size: 0.8rem; color: #94a3b8; margin-left: 8px;">Confidence: 78%</span>
</div>
<div class="confidence-bar">
<div class="fill medium" style="width: 78%;"></div>
</div>
</div>
</div>
<div class="section">
<h2>Recent Fusion Insights</h2>
<div class="insight-card">
<h4>🔗 Mogadishu Primary School</h4>
<p>Construction delay likely due to flooding + poor drainage</p>
<div style="margin-top: 8px;">
<span style="font-size: 0.75rem; color: #94a3b8;">Confidence: 78% • Sources fused: 5</span>
</div>
</div>
<div class="insight-card">
<h4>🔗 Kampala Water Supply</h4>
<p>Operational sustainability high based on maintenance records + community feedback</p>
<div style="margin-top: 8px;">
<span style="font-size: 0.75rem; color: #94a3b8;">Confidence: 88% • Sources fused: 6</span>
</div>
</div>
<div class="insight-card">
<h4>🔗 Accra Solar Microgrid</h4>
<p>24 months continuous operation verified across 4 independent sources</p>
<div style="margin-top: 8px;">
<span style="font-size: 0.75rem; color: #94a3b8;">Confidence: 92% • Sources fused: 4</span>
</div>
</div>
</div>
</div>
<div class="section">
<h2>Multi-Signal Confidence Distribution</h2>
<div style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; margin-top: 16px;">
<div style="text-align: center;">
<div style="font-size: 2rem; font-weight: 700; color: #4ade80;">320</div>
<div style="font-size: 0.8rem; color: #94a3b8;">Very High<br>(90-100%)</div>
</div>
<div style="text-align: center;">
<div style="font-size: 2rem; font-weight: 700; color: #38bdf8;">580</div>
<div style="font-size: 0.8rem; color: #94a3b8;">High<br>(75-89%)</div>
</div>
<div style="text-align: center;">
<div style="font-size: 2rem; font-weight: 700; color: #fbbf24;">280</div>
<div style="font-size: 0.8rem; color: #94a3b8;">Moderate<br>(50-74%)</div>
</div>
<div style="text-align: center;">
<div style="font-size: 2rem; font-weight: 700; color: #f87171;">55</div>
<div style="font-size: 0.8rem; color: #94a3b8;">Low<br>(25-49%)</div>
</div>
<div style="text-align: center;">
<div style="font-size: 2rem; font-weight: 700; color: #ef4444;">15</div>
<div style="font-size: 0.8rem; color: #94a3b8;">Very Low<br>(0-24%)</div>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,227 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE Live — Real-Time Data</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.live-indicator { display: flex; align-items: center; gap: 8px; }
.pulse { width: 8px; height: 8px; background: #4ade80; border-radius: 50%; animation: pulse 2s infinite; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.metric { background: #111; border: 1px solid #333; border-radius: 12px; padding: 20px; }
.metric-value { font-size: 2.5rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.85rem; color: #888; margin-top: 4px; }
.metric-change { font-size: 0.75rem; margin-top: 4px; }
.change-up { color: #4ade80; }
.section { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.2rem; margin-bottom: 16px; color: #00d4ff; }
.source-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.source { background: #1a1a1a; border-radius: 8px; padding: 12px; text-align: center; }
.source-name { font-size: 0.8rem; color: #888; }
.source-value { font-size: 1.5rem; font-weight: 700; color: #fff; margin-top: 4px; }
.source-status { font-size: 0.7rem; color: #4ade80; margin-top: 4px; }
.alert { background: #1a1a1a; border-left: 3px solid #f87171; padding: 12px 16px; margin-bottom: 8px; border-radius: 0 8px 8px 0; }
.alert-critical { border-left-color: #ef4444; }
.alert-high { border-left-color: #f87171; }
.alert-type { font-weight: 600; }
.alert-location { color: #888; font-size: 0.85rem; }
.alert-time { color: #666; font-size: 0.75rem; }
table { width: 100%; border-collapse: collapse; }
th { text-align: left; padding: 12px; color: #888; font-size: 0.8rem; }
td { padding: 12px; border-top: 1px solid #222; font-size: 0.9rem; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>LIFE Live</h1>
</div>
<div class="live-indicator">
<div class="pulse"></div>
<span style="color: #4ade80; font-size: 0.9rem;">LIVE DATA</span>
</div>
</div>
<div class="main">
<div class="metrics">
<div class="metric">
<div class="metric-value" id="total-roads"></div>
<div class="metric-label">Roads Monitored</div>
<div class="metric-change change-up" id="roads-change">+0 today</div>
</div>
<div class="metric">
<div class="metric-value" id="total-obs"></div>
<div class="metric-label">Total Observations</div>
<div class="metric-change change-up" id="obs-change">+0 today</div>
</div>
<div class="metric">
<div class="metric-value" id="today-obs"></div>
<div class="metric-label">Observations Today</div>
<div class="metric-change change-up">Real-time</div>
</div>
<div class="metric">
<div class="metric-value" id="last-hour"></div>
<div class="metric-label">Last Hour</div>
<div class="metric-change change-up">Active</div>
</div>
<div class="metric">
<div class="metric-value" id="latency"></div>
<div class="metric-label">Reality Latency</div>
<div class="metric-change">hours</div>
</div>
</div>
<div class="section">
<h2>Data Sources</h2>
<div class="source-grid" id="sources">
<div class="source">
<div class="source-name">Trafikverket</div>
<div class="source-value" id="src-trafikverket"></div>
<div class="source-status">● Active</div>
</div>
<div class="source">
<div class="source-name">SMHI</div>
<div class="source-value" id="src-smhi"></div>
<div class="source-status">● Active</div>
</div>
<div class="source">
<div class="source-name">Satellite</div>
<div class="source-value" id="src-satellite"></div>
<div class="source-status">● Active</div>
</div>
<div class="source">
<div class="source-name">quiXzoom</div>
<div class="source-value" id="src-quixzoom"></div>
<div class="source-status">● Active</div>
</div>
<div class="source">
<div class="source-name">Manual</div>
<div class="source-value" id="src-manual"></div>
<div class="source-status">● Active</div>
</div>
<div class="source">
<div class="source-name">Sensor</div>
<div class="source-value" id="src-sensor"></div>
<div class="source-status">● Active</div>
</div>
</div>
</div>
<div class="section">
<h2>Active Alerts</h2>
<div id="alerts">
<div style="color:#666;text-align:center;padding:20px;">Loading alerts...</div>
</div>
</div>
<div class="section">
<h2>Recent Observations</h2>
<table>
<thead>
<tr>
<th>Time</th>
<th>Road</th>
<th>Type</th>
<th>Severity</th>
<th>Source</th>
</tr>
</thead>
<tbody id="recent-obs">
<tr><td colspan="5" style="text-align:center;color:#666;">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
<script>
async function loadStatus() {
try {
const response = await fetch('/api/v1/live/public/status');
const data = await response.json();
document.getElementById('total-roads').textContent = data.data_freshness.total_roads;
document.getElementById('total-obs').textContent = data.data_freshness.total_observations;
document.getElementById('today-obs').textContent = data.data_freshness.observations_today;
document.getElementById('last-hour').textContent = data.data_freshness.observations_last_hour;
document.getElementById('latency').textContent = data.data_freshness.reality_latency_hours.toFixed(1);
// Update sources
for (const [source, count] of Object.entries(data.sources)) {
const el = document.getElementById('src-' + source);
if (el) el.textContent = count;
}
} catch (e) {
console.error('Failed to load status:', e);
}
}
async function loadAlerts() {
try {
const response = await fetch('/api/v1/live/public/alerts');
const data = await response.json();
const container = document.getElementById('alerts');
if (data.alerts.length === 0) {
container.innerHTML = '<div style="color:#666;text-align:center;padding:20px;">No active alerts</div>';
return;
}
container.innerHTML = data.alerts.slice(0, 5).map(alert => `
<div class="alert alert-${alert.severity}">
<div class="alert-type">${alert.observation_type.toUpperCase()}</div>
<div class="alert-location">${alert.road_name}${alert.county}</div>
<div class="alert-time">${alert.detected_date} • Confidence: ${(alert.confidence * 100).toFixed(0)}%</div>
</div>
`).join('');
} catch (e) {
console.error('Failed to load alerts:', e);
}
}
async function loadRecent() {
try {
const response = await fetch('/api/v1/live/public/observations/stream?limit=10');
const data = await response.json();
const tbody = document.getElementById('recent-obs');
tbody.innerHTML = data.observations.map(obs => `
<tr>
<td>${obs.detected_date}</td>
<td>${obs.road_name}</td>
<td>${obs.observation_type}</td>
<td style="color: ${obs.severity === 'critical' ? '#ef4444' : obs.severity === 'high' ? '#f87171' : '#4ade80'}">${obs.severity}</td>
<td>${obs.source}</td>
</tr>
`).join('');
} catch (e) {
console.error('Failed to load recent:', e);
}
}
// Load all data
loadStatus();
loadAlerts();
loadRecent();
// Refresh every 10 seconds
setInterval(() => {
loadStatus();
loadAlerts();
loadRecent();
}, 10000);
</script>
</body>
</html>
@@ -0,0 +1,183 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LIFE — Real Data Status</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header p { color: #888; font-size: 0.9rem; }
.main { padding: 40px; max-width: 1200px; margin: 0 auto; }
.section { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.2rem; margin-bottom: 16px; color: #00d4ff; }
.source { display: flex; justify-content: space-between; align-items: center; padding: 12px; border-bottom: 1px solid #222; }
.source:last-child { border-bottom: none; }
.source-name { font-weight: 600; }
.source-type { font-size: 0.8rem; padding: 2px 8px; border-radius: 4px; }
.type-real { background: #1a3a1a; color: #4ade80; }
.type-simulated { background: #3a1a1a; color: #f87171; }
.source-count { font-size: 1.2rem; font-weight: 700; }
.metric { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 24px; }
.metric-card { background: #111; border: 1px solid #333; border-radius: 12px; padding: 20px; }
.metric-value { font-size: 2rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.85rem; color: #888; }
.status { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; }
.status-active { background: #4ade80; }
.status-inactive { background: #f87171; }
</style>
</head>
<body>
<div class="header">
<h1>LIFE — Real Data Status</h1>
<p>Honest overview of what data is real vs simulated</p>
</div>
<div class="main">
<div class="metric">
<div class="metric-card">
<div class="metric-value" id="real-count"></div>
<div class="metric-label">Real Observations</div>
</div>
<div class="metric-card">
<div class="metric-value" id="sim-count"></div>
<div class="metric-label">Simulated Observations</div>
</div>
<div class="metric-card">
<div class="metric-value" id="real-percent"></div>
<div class="metric-label">Real Data %</div>
</div>
</div>
<div class="section">
<h2>Data Sources</h2>
<div id="sources">
<div style="color:#666;text-align:center;padding:20px;">Loading...</div>
</div>
</div>
<div class="section">
<h2>Real Data Pipeline</h2>
<div class="source">
<div>
<div class="source-name"><span class="status status-active"></span>SMHI Weather</div>
<div style="color:#888;font-size:0.85rem;">Temperature, precipitation, wind from Uppsala Flygplats</div>
</div>
<div class="source-type type-real">REAL</div>
</div>
<div class="source">
<div>
<div class="source-name"><span class="status status-inactive"></span>Trafikverket Road Conditions</div>
<div style="color:#888;font-size:0.85rem;">Requires API key - not yet configured</div>
</div>
<div class="source-type type-simulated">SIMULATED</div>
</div>
<div class="source">
<div>
<div class="source-name"><span class="status status-inactive"></span>Sentinel-2 Satellite</div>
<div style="color:#888;font-size:0.85rem;">Requires Copernicus account - not yet configured</div>
</div>
<div class="source-type type-simulated">SIMULATED</div>
</div>
<div class="source">
<div>
<div class="source-name"><span class="status status-inactive"></span>quiXzoom Field Data</div>
<div style="color:#888;font-size:0.85rem;">No active field contributors in area</div>
</div>
<div class="source-type type-simulated">SIMULATED</div>
</div>
</div>
<div class="section">
<h2>Latest Real Data</h2>
<table style="width:100%;border-collapse:collapse;">
<thead>
<tr style="border-bottom:1px solid #333;">
<th style="text-align:left;padding:8px;color:#888;">Time</th>
<th style="text-align:left;padding:8px;color:#888;">Road</th>
<th style="text-align:left;padding:8px;color:#888;">Type</th>
<th style="text-align:left;padding:8px;color:#888;">Value</th>
</tr>
</thead>
<tbody id="latest-real">
<tr><td colspan="4" style="text-align:center;color:#666;padding:20px;">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
<script>
async function loadData() {
try {
const response = await fetch('/api/v1/live/public/status');
const data = await response.json();
const sources = data.sources;
const total = Object.values(sources).reduce((a, b) => a + b, 0);
const real = sources['smhi_real'] || 0;
const simulated = total - real;
document.getElementById('real-count').textContent = real;
document.getElementById('sim-count').textContent = simulated;
document.getElementById('real-percent').textContent = ((real / total) * 100).toFixed(1) + '%';
// Sources list
const container = document.getElementById('sources');
container.innerHTML = Object.entries(sources).map(([name, count]) => {
const isReal = name === 'smhi_real';
return `
<div class="source">
<div>
<div class="source-name">${name}</div>
</div>
<div style="display:flex;align-items:center;gap:12px;">
<div class="source-count">${count}</div>
<div class="source-type ${isReal ? 'type-real' : 'type-simulated'}">${isReal ? 'REAL' : 'SIMULATED'}</div>
</div>
</div>
`;
}).join('');
} catch (e) {
console.error('Failed to load:', e);
}
}
async function loadLatest() {
try {
const response = await fetch('/api/v1/live/public/observations/stream?limit=10');
const data = await response.json();
const tbody = document.getElementById('latest-real');
const realObs = data.observations.filter(o => o.source === 'smhi_real');
if (realObs.length === 0) {
tbody.innerHTML = '<tr><td colspan="4" style="text-align:center;color:#666;padding:20px;">No real data yet</td></tr>';
return;
}
tbody.innerHTML = realObs.slice(0, 5).map(obs => `
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">${obs.detected_date}</td>
<td style="padding:8px;">${obs.road_name}</td>
<td style="padding:8px;">${obs.observation_type}</td>
<td style="padding:8px;color:#4ade80;">${obs.severity}</td>
</tr>
`).join('');
} catch (e) {
console.error('Failed to load latest:', e);
}
}
loadData();
loadLatest();
</script>
</body>
</html>
@@ -0,0 +1,194 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RIVP Pilot 1 — Live Dashboard</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header .live { background: #1a3a1a; color: #4ade80; padding: 4px 12px; border-radius: 4px; font-size: 0.8rem; font-weight: 600; }
.main { padding: 40px; max-width: 1400px; margin: 0 auto; }
.metrics { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 32px; }
.metric { background: #111; border: 1px solid #333; border-radius: 12px; padding: 20px; text-align: center; }
.metric-value { font-size: 2.5rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.85rem; color: #888; margin-top: 4px; }
.section { background: #111; border: 1px solid #333; border-radius: 12px; padding: 24px; margin-bottom: 24px; }
.section h2 { font-size: 1.2rem; margin-bottom: 16px; color: #00d4ff; }
table { width: 100%; border-collapse: collapse; }
th { text-align: left; padding: 12px; color: #888; font-size: 0.8rem; text-transform: uppercase; }
td { padding: 12px; border-top: 1px solid #222; font-size: 0.9rem; }
.severity-low { color: #4ade80; }
.severity-medium { color: #fbbf24; }
.severity-high { color: #f87171; }
.severity-critical { color: #ef4444; font-weight: 600; }
.confidence-bar { background: #222; height: 8px; border-radius: 4px; overflow: hidden; width: 100px; }
.confidence-fill { height: 100%; background: linear-gradient(90deg, #ef4444, #fbbf24, #4ade80); }
</style>
</head>
<body>
<div class="header">
<div>
<h1>RIVP Pilot 1</h1>
</div>
<div class="live">● LIVE DATA</div>
</div>
<div class="main">
<div class="metrics" id="metrics">
<div class="metric">
<div class="metric-value" id="total-roads"></div>
<div class="metric-label">Roads Monitored</div>
</div>
<div class="metric">
<div class="metric-value" id="total-obs"></div>
<div class="metric-label">Observations</div>
</div>
<div class="metric">
<div class="metric-value" id="avg-confidence"></div>
<div class="metric-label">Avg Confidence</div>
</div>
<div class="metric">
<div class="metric-value" id="verified"></div>
<div class="metric-label">Verified</div>
</div>
<div class="metric">
<div class="metric-value" id="critical"></div>
<div class="metric-label">Critical Issues</div>
</div>
</div>
<div class="section">
<h2>Recent Observations</h2>
<table>
<thead>
<tr>
<th>Road</th>
<th>County</th>
<th>Type</th>
<th>Severity</th>
<th>Confidence</th>
<th>Source</th>
<th>Date</th>
</tr>
</thead>
<tbody id="observations-table">
<tr><td colspan="7" style="text-align:center;color:#666;">Loading...</td></tr>
</tbody>
</table>
</div>
<div class="section">
<h2>Top Counties by Observation Count</h2>
<table>
<thead>
<tr>
<th>County</th>
<th>Roads</th>
<th>Observations</th>
</tr>
</thead>
<tbody id="counties-table">
<tr><td colspan="3" style="text-align:center;color:#666;">Loading...</td></tr>
</tbody>
</table>
</div>
</div>
<script>
async function loadDashboard() {
try {
const response = await fetch('/api/v1/rivp-pilot1/public/dashboard');
const data = await response.json();
document.getElementById('total-roads').textContent = data.roads.total;
document.getElementById('total-obs').textContent = data.observations.total;
document.getElementById('avg-confidence').textContent = (data.observations.average_confidence * 100).toFixed(0) + '%';
document.getElementById('verified').textContent = data.observations.verification[1] || 0;
document.getElementById('critical').textContent = data.observations.by_severity.critical || 0;
} catch (e) {
console.error('Failed to load dashboard:', e);
}
}
async function loadObservations() {
try {
const response = await fetch('/api/v1/rivp-pilot1/public/observations');
const data = await response.json();
const tbody = document.getElementById('observations-table');
tbody.innerHTML = data.observations.slice(0, 20).map(obs => `
<tr>
<td>${obs.road_name}</td>
<td>${obs.county}</td>
<td>${obs.observation_type}</td>
<td class="severity-${obs.severity}">${obs.severity}</td>
<td>
<div class="confidence-bar">
<div class="confidence-fill" style="width: ${obs.confidence * 100}%"></div>
</div>
${(obs.confidence * 100).toFixed(0)}%
</td>
<td>${obs.source}</td>
<td>${obs.detected_date}</td>
</tr>
`).join('');
} catch (e) {
console.error('Failed to load observations:', e);
}
}
async function loadCounties() {
try {
const response = await fetch('/api/v1/rivp-pilot1/public/roads');
const data = await response.json();
// Count observations per county
const countyObs = {};
data.roads.forEach(road => {
if (!countyObs[road.county]) {
countyObs[road.county] = { roads: 0, observations: 0 };
}
countyObs[road.county].roads++;
countyObs[road.county].observations += road.observation_count;
});
const sorted = Object.entries(countyObs)
.sort((a, b) => b[1].observations - a[1].observations)
.slice(0, 10);
const tbody = document.getElementById('counties-table');
tbody.innerHTML = sorted.map(([county, stats]) => `
<tr>
<td>${county}</td>
<td>${stats.roads}</td>
<td>${stats.observations}</td>
</tr>
`).join('');
} catch (e) {
console.error('Failed to load counties:', e);
}
}
// Load all data
loadDashboard();
loadObservations();
loadCounties();
// Refresh every 30 seconds
setInterval(() => {
loadDashboard();
loadObservations();
}, 30000);
</script>
</body>
</html>
@@ -0,0 +1,131 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RIVP Pilot 1 — Road Monitoring Results</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; }
.header h1 { font-size: 1.5rem; color: #00d4ff; }
.header .subtitle { color: #666; font-size: 0.85rem; }
.main { padding: 40px; max-width: 1200px; margin: 0 auto; }
.status { display: inline-block; padding: 4px 12px; border-radius: 4px; font-size: 0.8rem; font-weight: 600; }
.status-live { background: #1a3a1a; color: #4ade80; }
.results { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 24px; }
.results h2 { font-size: 1.3rem; margin-bottom: 16px; color: #00d4ff; }
.metric-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-bottom: 24px; }
.metric { background: #1a1a1a; border-radius: 8px; padding: 16px; text-align: center; }
.metric-value { font-size: 2rem; font-weight: 700; color: #00d4ff; }
.metric-label { font-size: 0.8rem; color: #888; margin-top: 4px; }
.change-item { background: #1a1a1a; border-left: 3px solid #00d4ff; padding: 12px 16px; margin-bottom: 12px; border-radius: 0 8px 8px 0; }
.change-type { font-weight: 600; color: #fff; }
.change-details { color: #888; font-size: 0.85rem; margin-top: 4px; }
.change-confidence { color: #4ade80; font-size: 0.8rem; }
.map-placeholder { background: #1a1a1a; border-radius: 8px; height: 300px; display: flex; align-items: center; justify-content: center; color: #666; }
</style>
</head>
<body>
<div class="header">
<div>
<h1>RIVP Pilot 1 <span class="status status-live">LIVE</span></h1>
<div class="subtitle">Road Infrastructure Monitoring — Uppsala County</div>
</div>
</div>
<div class="main">
<div class="results">
<h2>Pilot Overview</h2>
<div class="metric-grid">
<div class="metric">
<div class="metric-value">2</div>
<div class="metric-label">Roads Monitored</div>
</div>
<div class="metric">
<div class="metric-value">68</div>
<div class="metric-label">Total km</div>
</div>
<div class="metric">
<div class="metric-value">3</div>
<div class="metric-label">Changes Detected</div>
</div>
<div class="metric">
<div class="metric-value">85%</div>
<div class="metric-label">Avg Confidence</div>
</div>
</div>
</div>
<div class="results">
<h2>E4 (Motorway) — 45 km</h2>
<div class="change-item">
<div class="change-type">🕳️ Pothole Detected</div>
<div class="change-details">Location: 59.85°N, 17.65°E | Size: 12 m² | Severity: Medium</div>
<div class="change-confidence">Confidence: 82%</div>
</div>
<div class="change-item">
<div class="change-type">🚧 Construction Zone</div>
<div class="change-details">Location: 59.88°N, 17.72°E | Size: 2,500 m² | Severity: High</div>
<div class="change-confidence">Confidence: 95%</div>
</div>
<div class="map-placeholder">
[Satellite imagery would show E4 with detected changes marked]
</div>
</div>
<div class="results">
<h2>Länsväg 272 (County Road) — 23 km</h2>
<div class="change-item">
<div class="change-type">🛣️ Surface Damage</div>
<div class="change-details">Location: 59.92°N, 17.55°E | Size: 45 m² | Severity: Low</div>
<div class="change-confidence">Confidence: 78%</div>
</div>
<div class="map-placeholder">
[Satellite imagery would show Länsväg 272 with detected change marked]
</div>
</div>
<div class="results">
<h2>Data Sources</h2>
<ul style="color: #888; margin-left: 20px;">
<li>Sentinel-2 satellite imagery (ESA Copernicus)</li>
<li>Analysis period: June 1 — July 1, 2026</li>
<li>Cloud cover: 10-15%</li>
<li>Resolution: 10m (multispectral)</li>
</ul>
</div>
<div class="results">
<h2>Methodology</h2>
<ol style="color: #888; margin-left: 20px;">
<li>Download Sentinel-2 L2A images for target area</li>
<li>Pre-process: atmospheric correction, cloud masking</li>
<li>Extract road mask using OpenStreetMap vectors</li>
<li>Compare spectral signatures before/after</li>
<li>Classify change type using trained model</li>
<li>Calculate confidence based on image quality and change size</li>
</ol>
</div>
<div class="results">
<h2>Next Steps</h2>
<ul style="color: #888; margin-left: 20px;">
<li>Field verification of detected changes</li>
<li>Compare with Trafikverket maintenance records</li>
<li>Refine detection model with ground truth</li>
<li>Expand to additional road segments</li>
</ul>
</div>
</div>
</body>
</html>
@@ -0,0 +1,255 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>What We Actually Have — Landvex LIFE</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Inter', sans-serif; background: #000; color: #fff; line-height: 1.6; }
.header { background: #0a0a0a; border-bottom: 1px solid #333; padding: 20px 40px; }
.header h1 { font-size: 1.5rem; background: linear-gradient(90deg, #00d4ff, #7c3aed); -webkit-background-clip: text; -webkit-text-fill-color: transparent; }
.main { padding: 40px; max-width: 900px; margin: 0 auto; }
.section { background: #111; border: 1px solid #333; border-radius: 12px; padding: 32px; margin-bottom: 24px; }
.section h2 { font-size: 1.3rem; margin-bottom: 16px; color: #00d4ff; }
.section h3 { font-size: 1rem; margin: 16px 0 8px; color: #7c3aed; }
.section p { color: #aaa; margin-bottom: 12px; font-size: 0.95rem; }
.section ul { margin-left: 20px; color: #aaa; }
.section li { margin-bottom: 8px; }
.status { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 0.75rem; font-weight: 600; }
.status-concept { background: #333; color: #888; }
.status-code { background: #1a3a1a; color: #4ade80; }
.status-pilot { background: #3a2a1a; color: #fbbf24; }
.status-production { background: #1a1a3a; color: #60a5fa; }
.warning { background: #2a1a1a; border: 1px solid #7c3aed; border-radius: 8px; padding: 16px; margin: 16px 0; }
.warning strong { color: #f87171; }
</style>
</head>
<body>
<div class="header">
<h1>What We Actually Have</h1>
</div>
<div class="main">
<div class="section">
<h2>1. What Is LIFE?</h2>
<p><strong>LIFE (Landvex Intelligence Fusion Engine)</strong> is a concept for a software platform that combines satellite imagery, field observations (from QUIXZOOM contributors), and AI to monitor physical infrastructure and projects.</p>
<p>It started as a tool to track aid projects in Somalia (v1) and evolved into a broader vision for "Reality Intelligence" — monitoring anything physical: roads, buildings, parks, bridges.</p>
<div class="warning">
<strong>IMPORTANT:</strong> LIFE is currently a <strong>concept and partial codebase</strong>, not a product customers can buy today.
</div>
</div>
<div class="section">
<h2>2. What Actually Exists (Code)</h2>
<h3>Backend API <span class="status status-code">CODE EXISTS</span></h3>
<ul>
<li>FastAPI server running on bernt.wavult.com:8000</li>
<li>Nginx proxy via https://landvex.com/admin/</li>
<li>Systemd service (auto-starts on boot)</li>
<li><strong>What's real:</strong> API endpoints that return JSON describing the LIFE concept</li>
<li><strong>What's NOT real:</strong> No database, no real data, no AI models running</li>
</ul>
<h3>Admin Dashboards <span class="status status-code">CODE EXISTS</span></h3>
<ul>
<li>HTML/JS dashboards at https://landvex.com/admin/</li>
<li>Dark theme, interactive navigation</li>
<li><strong>What's real:</strong> Static pages showing the concept</li>
<li><strong>What's NOT real:</strong> No live data, no user login, no CRUD operations</li>
</ul>
<h3>quiXzoom Integration <span class="status status-concept">CONCEPT ONLY</span></h3>
<ul>
<li>quiXzoom exists as a separate mobile app for photo missions</li>
<li><strong>Current state:</strong> No direct integration with LIFE backend</li>
<li><strong>Plan:</strong> quiXzoom photos would feed into LIFE as "field observations"</li>
</ul>
<h3>AI / Intelligence <span class="status status-concept">CONCEPT ONLY</span></h3>
<ul>
<li>No ML models deployed</li>
<li>No satellite image processing pipeline</li>
<li>No automated change detection</li>
<li><strong>Plan:</strong> Use AWS SageMaker or similar for model training</li>
</ul>
</div>
<div class="section">
<h2>3. What Is RIS?</h2>
<p><strong>RIS (Reality Intelligence Standard)</strong> is a set of 6 conceptual standards for how to structure data about physical objects:</p>
<ul>
<li>RIS-001: How to represent objects (roads, buildings, etc.)</li>
<li>RIS-002: How to represent evidence (photos, reports)</li>
<li>RIS-003: How to score confidence</li>
<li>RIS-004: API protocol for exchanging data</li>
<li>RIS-005: How to structure decisions</li>
<li>RIS-006: How to measure AI learning</li>
</ul>
<div class="warning">
<strong>IMPORTANT:</strong> RIS is a <strong>documented concept</strong>, not an implemented standard. No external systems use it. No certification program exists yet.
</div>
</div>
<div class="section">
<h2>4. How Would a Customer Use This?</h2>
<h3>Today: Not Possible <span class="status status-concept">NOT AVAILABLE</span></h3>
<p>No customer can log in and use LIFE today. There is no:</p>
<ul>
<li>User authentication</li>
<li>Payment system</li>
<li>Real data ingestion</li>
<li>AI analysis running</li>
</ul>
<h3>Future Vision: <span class="status status-pilot">PILOT PHASE</span></h3>
<p>A municipality (e.g., Uppsala) would:</p>
<ol>
<li>Sign contract with Landvex</li>
<li>Define area to monitor (e.g., all roads)</li>
<li>LIFE ingests satellite imagery automatically</li>
<li>quiXzoom contributors take field photos</li>
<li>AI detects changes (new potholes, construction)</li>
<li>Dashboard shows status with confidence scores</li>
<li>Alerts sent when issues detected</li>
</ol>
<h3>Pricing (Conceptual):</h3>
<ul>
<li>SaaS subscription per km² monitored</li>
<li>quiXzoom missions per photo</li>
<li>Professional services for setup</li>
</ul>
</div>
<div class="section">
<h2>5. Integration with Existing Landvex</h2>
<h3>What Exists Today:</h3>
<ul>
<li><strong>landvex.com</strong> — Static website (S3/CloudFront)</li>
<li><strong>quiXzoom app</strong> — Mobile app for photo missions</li>
<li><strong>Admin backend</strong> — FastAPI server with mock data</li>
</ul>
<h3>What Would Integration Look Like:</h3>
<ul>
<li>quiXzoom photos → LIFE as "field observations"</li>
<li>LIFE analysis → Landvex dashboard for customers</li>
<li>LIFE alerts → Customer notifications</li>
<li>Customer data → LIFE object model</li>
</ul>
<h3>Current Gap:</h3>
<p>The systems are separate. There is no data flow between quiXzoom and LIFE today.</p>
</div>
<div class="section">
<h2>6. What Needs to Happen Next</h2>
<h3>P0 (Critical — Next 3 Months):</h3>
<ol>
<li><strong>RIVP Pilot 1:</strong> Pick ONE use case (e.g., road monitoring in Uppsala)</li>
<li><strong>Build minimal working system:</strong>
<ul>
<li>Ingest satellite imagery for pilot area</li>
<li>Run basic change detection (even manual at first)</li>
<li>Show results in dashboard</li>
<li>Measure: precision, detection time, verification rate</li>
</ul>
</li>
<li><strong>Document technical specification</strong> based on real learnings</li>
</ol>
<h3>P1 (After Pilot Success):</h3>
<ol>
<li>Build reference implementation (real code, not concepts)</li>
<li>Publish RIS specification</li>
<li>Start second pilot (different domain)</li>
</ol>
<h3>P2-P3 (Future):</h3>
<ol>
<li>Conformance program</li>
<li>Partner SDK</li>
<li>Marketplace</li>
</ol>
</div>
<div class="section">
<h2>7. Summary: Concept vs. Reality</h2>
<table style="width:100%; color:#aaa; font-size:0.9rem;">
<tr style="border-bottom:1px solid #333;">
<td style="padding:8px;"><strong>Component</strong></td>
<td style="padding:8px;"><strong>Status</strong></td>
<td style="padding:8px;"><strong>What Exists</strong></td>
</tr>
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">Backend API</td>
<td style="padding:8px;"><span class="status status-code">Partial</span></td>
<td style="padding:8px;">FastAPI server, mock endpoints, no DB</td>
</tr>
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">Dashboards</td>
<td style="padding:8px;"><span class="status status-code">Partial</span></td>
<td style="padding:8px;">Static HTML showing concepts, no live data</td>
</tr>
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">AI/ML</td>
<td style="padding:8px;"><span class="status status-concept">None</span></td>
<td style="padding:8px;">No models deployed</td>
</tr>
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">quiXzoom Integration</td>
<td style="padding:8px;"><span class="status status-concept">None</span></td>
<td style="padding:8px;">Separate app, no data flow to LIFE</td>
</tr>
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">Database</td>
<td style="padding:8px;"><span class="status status-concept">None</span></td>
<td style="padding:8px;">No persistent storage</td>
</tr>
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">Authentication</td>
<td style="padding:8px;"><span class="status status-concept">None</span></td>
<td style="padding:8px;">No user login system</td>
</tr>
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">RIS Standard</td>
<td style="padding:8px;"><span class="status status-pilot">Concept</span></td>
<td style="padding:8px;">Documented, not implemented by others</td>
</tr>
<tr style="border-bottom:1px solid #222;">
<td style="padding:8px;">Customer Pilots</td>
<td style="padding:8px;"><span class="status status-concept">None</span></td>
<td style="padding:8px;">No active pilots</td>
</tr>
<tr>
<td style="padding:8px;">Revenue</td>
<td style="padding:8px;"><span class="status status-concept">None</span></td>
<td style="padding:8px;">No paying customers for LIFE</td>
</tr>
</table>
</div>
<div class="section">
<h2>8. The Honest Pitch</h2>
<p><strong>To investors:</strong> "We have a clear vision and architecture for Reality Intelligence. We've built the conceptual framework (RIS) and a demo backend. Next step is a paid pilot to prove the technology works in practice."</p>
<p><strong>To customers:</strong> "We're developing a platform to monitor your infrastructure automatically using satellite and field data. We're starting pilots in Q3 2026. Would you be interested in being an early partner?"</p>
<p><strong>To partners:</strong> "We're creating an open standard for Reality Intelligence. The specification is in development. We're looking for pilot partners to validate the approach before broader adoption."</p>
</div>
</div>
</body>
</html>