feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏗️</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Infrastructure condition</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Physical state of roads, utilities, public infrastructure and built environment across the area.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏪</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Commercial vitality</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Density and health of commercial activity — openings, closures, vacancy rates and foot traffic patterns.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🌳</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Public space quality</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Condition of parks, squares, pedestrian zones and shared public environments.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🔧</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Maintenance trajectory</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Rate of observable maintenance activity vs observed deterioration — leading indicator of future condition.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">📈</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Change velocity</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Speed and direction of visible change across the area — construction, renovation, closures, openings.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Municipal resource allocation</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Urban planning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Investment screening</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Municipal resource allocation</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Urban planning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Investment screening</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Score 0100 + trend direction + key signals</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#4ade80;font-size:.875rem;font-weight:700">↑ Improving</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:72%;background:#4ade80;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:72%;background:#4ade80;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">The City Health Index compares official urban condition reports and maintenance schedules against observed field data. When official assessments rate an area as well-maintained but field observations show deferred maintenance, rising vacancies, or deteriorating public spaces — the engine flags a narrative conflict.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/neighbourhood-quality-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🏘️</div>
<a href="/intelligence/neighbourhood-quality-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Neighbourhood Quality Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/infrastructure-risk-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<a href="/intelligence/infrastructure-risk-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Infrastructure Risk Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/development-forecast/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🔮</div>
<a href="/intelligence/development-forecast/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Development Forecast</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🆕</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">New business openings</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Rate of new commercial openings in the area — by category, size and observed activity level.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏚️</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Vacancy rates</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observable storefront and commercial vacancy — current level and directional trend over time.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">👥</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Foot traffic signals</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Pedestrian density and movement patterns observed in the field across different times and zones.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏢</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1" stroke="#666" stroke-width="1.5"/><path d="M6 5H7M6 8H7M6 11H7M9 5H10M9 8H10M9 11H10" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Competitor presence</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Category density, anchor tenants, brand presence and competitive clustering by district.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🔨</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Renovation activity</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Volume of active fitouts, renovations and commercial improvements — a leading signal of investment intent.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Retail site selection</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Franchise expansion</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Property acquisition</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Retail site selection</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Franchise expansion</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Property acquisition</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Opportunity score + gap map + competitor density</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#4ade80;font-size:.875rem;font-weight:700">↑ Strong growth</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:81%;background:#4ade80;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:81%;background:#4ade80;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">The Commercial Opportunity Index cross-references property registers, planning applications and official business statistics against observed commercial activity on the ground. A location listed as commercially active but observed with rising vacancies and declining foot traffic triggers a contradiction alert — often weeks before it surfaces in official data.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/urban-growth-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🌱</div>
<a href="/intelligence/urban-growth-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Urban Growth Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/investment-attractiveness-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">💎</div>
<a href="/intelligence/investment-attractiveness-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Investment Attractiveness Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/growth-velocity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🚀</div>
<a href="/intelligence/growth-velocity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2L10 8L14 9L8 14L6 8L2 7L8 2Z" fill="#666"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Growth Velocity Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏗️</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Construction activity</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Volume and intensity of active construction, scaffolding, site preparation and demolition observed in the field.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">📄</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Permit signals</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observable evidence of planning permissions — site hoardings, notices, contractor presence and groundworks.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏪</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Commercial openings</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">New business formations and commercial fitouts as a leading indicator of investment confidence.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">💰</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Capital flows</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Indirect signals of capital allocation — scaffolding, premium renovations, branded development sites.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🚶</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Population movement</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observable demographic shifts — new residents, changing consumer mix, service infrastructure evolution.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Real estate development</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Investment allocation</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Urban planning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Real estate development</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Investment allocation</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Urban planning</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Development score + cycle stage + investment confidence</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#4ade80;font-size:.875rem;font-weight:700">↑ Cycle accelerating</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:67%;background:#fbbf24;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:67%;background:#fbbf24;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">Development Forecast detects when official planning data diverges from observed ground activity. A district listed as "under development" in permits with no observable site activity, or conversely, rapid development activity ahead of formal permissions — both trigger narrative conflicts that change the forecast score.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/urban-growth-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🌱</div>
<a href="/intelligence/urban-growth-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Urban Growth Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/investment-attractiveness-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">💎</div>
<a href="/intelligence/investment-attractiveness-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Investment Attractiveness Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">📈</div>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Commercial Opportunity Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏪</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Change rate (commercial)</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Speed of commercial turnover — openings, closures, category shifts and brand mix changes.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏗️</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Change rate (physical)</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Rate of physical transformation — construction, demolition, renovation and public realm works.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#0066FF" stroke-width="2"><path d="M18 20V10"/><path d="M12 20V4"/><path d="M6 20v-6"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Trend acceleration</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Whether the rate of change is itself accelerating or decelerating — a second-order velocity signal.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">📉</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Volatility score</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Consistency of change direction — high volatility means rapid oscillation between positive and negative signals.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🚀</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2L10 8L14 9L8 14L6 8L2 7L8 2Z" fill="#666"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Momentum indicators</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Leading signals that suggest the current change rate will continue — or is about to reverse.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Timing investment decisions</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Early market entry</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Risk-adjusted expansion</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Timing investment decisions</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Early market entry</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Risk-adjusted expansion</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Velocity score + acceleration signal + volatility rating</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#4ade80;font-size:.875rem;font-weight:700">↑ Accelerating</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:83%;background:#4ade80;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:83%;background:#4ade80;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">Growth Velocity Index detects when official economic release cycles lag observable reality. GDP and business register data typically reflects conditions 618 months in the past. When field velocity indicators diverge sharply from the most recent official statistics, the contradiction engine quantifies the gap and adjusts the forward-looking velocity forecast.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/urban-growth-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🌱</div>
<a href="/intelligence/urban-growth-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Urban Growth Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/investment-attractiveness-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">💎</div>
<a href="/intelligence/investment-attractiveness-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Investment Attractiveness Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">📈</div>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Commercial Opportunity Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">📉</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Observed deterioration rate</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Speed of visible degradation across roads, bridges, utilities and public infrastructure assets.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🔧</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Maintenance gap</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Delta between required maintenance frequency and observed maintenance activity in the field.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">📋</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1" stroke="#666" stroke-width="1.5"/><path d="M6 5H10M6 8H10M6 11H8" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Official vs observed delta</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Divergence between official condition ratings and field observations — the key contradiction signal.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Age-adjusted risk</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Deterioration rate adjusted for asset age and original condition — identifies assets aging faster than expected.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">💥</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Failure probability</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Composite probability score of near-term infrastructure failure based on all observed signals.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Maintenance prioritization</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Capex planning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Insurance underwriting</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Maintenance prioritization</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Capex planning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Insurance underwriting</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Risk score + failure probability + priority ranking</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#f87171;font-size:.875rem;font-weight:700">↓ Risk increasing</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:44%;background:#f87171;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:44%;background:#f87171;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">Infrastructure Risk Index is built on contradiction detection. It systematically compares official maintenance records, inspection reports and asset condition databases against observed reality. When a bridge or road corridor is rated "good" in official systems but field observations show accelerating deterioration — the contradiction score rises, triggering priority review.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/city-health-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🏙️</div>
<a href="/intelligence/city-health-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">City Health Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/risk-resilience-profile/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🛡️</div>
<a href="/intelligence/risk-resilience-profile/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Risk & Resilience Profile</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/development-forecast/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🔮</div>
<a href="/intelligence/development-forecast/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Development Forecast</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">💡</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Opportunity score</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Composite signal of commercial opportunity, underserved demand and competitive positioning.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#0066FF" stroke-width="2"><path d="M18 20V10"/><path d="M12 20V4"/><path d="M6 20v-6"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Risk-adjusted return potential</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Expected return potential weighted against observed risk signals and contradiction indicators.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">📈</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Growth trajectory</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Direction and velocity of area growth — observed leading indicators of future value creation.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V4M8 12V14M2 8H4M12 8H14" stroke="#f59e0b" stroke-width="1.5" stroke-linecap="round"/><circle cx="8" cy="8" r="2" fill="#f59e0b"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Quality of physical environment</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Condition, upkeep and observable quality of the built environment — a proxy for long-term value retention.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">⚔️</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Competitive intensity</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observed competitive activity — existing investment presence and new entrant signals in the area.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Capital allocation</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Site selection</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Portfolio construction</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Capital allocation</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Site selection</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Portfolio construction</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Attractiveness score + risk-adjusted rank + comparable benchmark</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#4ade80;font-size:.875rem;font-weight:700">↑ Improving</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:76%;background:#4ade80;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:76%;background:#4ade80;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">Investment Attractiveness Index combines all contradiction signals from across the index family into a single composite score. When multiple indexes show divergence between official data and observed reality, the investment risk-adjustment factor rises — reducing the attractiveness score to reflect information uncertainty in the official record.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">📈</div>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Commercial Opportunity Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/growth-velocity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🚀</div>
<a href="/intelligence/growth-velocity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2L10 8L14 9L8 14L6 8L2 7L8 2Z" fill="#666"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Growth Velocity Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/risk-resilience-profile/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🛡️</div>
<a href="/intelligence/risk-resilience-profile/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Risk & Resilience Profile</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏠</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Physical condition score</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observable condition of buildings, streetscapes, public spaces and shared infrastructure.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 2L5 9H8L7 14L11 7H8L9 2Z" fill="#f59e0b"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Activity level</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Density and vibrancy of observable activity — pedestrians, commercial activity, events, services.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#00C853" stroke-width="3"><path d="M20 6L9 17l-5-5"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Maintenance quality</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Evidence of active upkeep — street cleaning, repairs, landscaping, graffiti removal and general care.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🔒</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Safety signals</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observable environmental safety indicators — lighting quality, surveillance, footfall density and activation.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🔄</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 8C2 11.3 4.7 14 8 14C10.5 14 12.7 12.5 13.7 10.3" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M14 8C14 4.7 11.3 2 8 2C5.5 2 3.3 3.5 2.3 5.7" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M13.5 7.5L14 10L11.5 9.5" stroke="#666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M2.5 8.5L2 6L4.5 6.5" stroke="#666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Change direction</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Whether the area is improving or declining — trajectory from field observations over time.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Residential development</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Retail positioning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Public space investment</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Residential development</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Retail positioning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Public space investment</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Quality score + experience rating + trajectory signal</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#fbbf24;font-size:.875rem;font-weight:700">→ Stable</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:69%;background:#fbbf24;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:69%;background:#fbbf24;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">Neighbourhood Quality Index flags when resident satisfaction surveys, official quality-of-life indexes or planning documents describe an area differently from what field observations record. High survey satisfaction scores in areas with observed maintenance decline often precede a quality drop — the index detects this divergence early.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/city-health-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🏙️</div>
<a href="/intelligence/city-health-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">City Health Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">📈</div>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Commercial Opportunity Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/risk-resilience-profile/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🛡️</div>
<a href="/intelligence/risk-resilience-profile/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Risk & Resilience Profile</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Physical exposure score</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Composite score of observable physical risk factors — drainage, elevation, construction quality, age.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🌊</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Flood/weather risk signals</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observed drainage capacity, flood markers, historical damage evidence and climate exposure indicators.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏗️</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 14H14M4 14V8L8 4L12 8V14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 14V10H10V14" stroke="#666" stroke-width="1.5"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Infrastructure vulnerability</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Condition and resilience of critical infrastructure serving the area — power, water, roads, communications.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🤝</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Social resilience indicators</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observable signals of community capacity and social infrastructure — services, connectivity, density.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🔄</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 8C2 11.3 4.7 14 8 14C10.5 14 12.7 12.5 13.7 10.3" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M14 8C14 4.7 11.3 2 8 2C5.5 2 3.3 3.5 2.3 5.7" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M13.5 7.5L14 10L11.5 9.5" stroke="#666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M2.5 8.5L2 6L4.5 6.5" stroke="#666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Recovery capacity</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Speed of observable recovery from prior disruption events — maintenance responsiveness and institutional capacity.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Insurance underwriting</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Portfolio stress testing</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Resilience planning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Insurance underwriting</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Portfolio stress testing</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Resilience planning</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Risk score + exposure map + resilience rating</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#fbbf24;font-size:.875rem;font-weight:700">→ Stable risk</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:38%;background:#f87171;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:38%;background:#f87171;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">Risk & Resilience Profile detects contradictions between official risk assessments and observed physical conditions. When flood zone maps say low risk but field observations show inadequate drainage, ageing embankments and deferred maintenance — the contradiction engine raises the actual risk score above the official rating.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/infrastructure-risk-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<a href="/intelligence/infrastructure-risk-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Infrastructure Risk Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/city-health-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🏙️</div>
<a href="/intelligence/city-health-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">City Health Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/neighbourhood-quality-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🏘️</div>
<a href="/intelligence/neighbourhood-quality-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Neighbourhood Quality Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }
@@ -167,7 +167,7 @@
.footer-links a { font-size: 14px; color: var(--text-muted); transition: color 0.2s; }
.footer-links a:hover { color: #1d1d1f; }
.footer-social {
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: 8px;
width: 32px; height: 32px; border: 1px solid var(--border); border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
@@ -187,7 +187,7 @@
[style*="grid-template-columns:repeat(auto-fit,minmax(260px"] { grid-template-columns: 1fr !important; }
}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius:8px;line-height:1.6;max-width:800px}
.lv-disclaimer{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:24px;padding:12px 16px;background:rgba(0,0,0,.04);border-radius: var(--radius-md);line-height:1.6;max-width:800px}
.lv-disclaimer a{color:rgba(0,0,0,.65);text-decoration:underline}
.lv-disclaimer--light{color:#888;background:#f5f5f5}
.lv-disclaimer--light a{color:#555}
@@ -263,32 +263,32 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:20px">
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">📈</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Commercial expansion rate</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Speed of new commercial openings relative to closures — net growth rate of the commercial ecosystem.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏠</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Residential activity</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observable indicators of residential growth — new builds, renovations, moving activity, service infrastructure.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🏥</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Service density growth</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Expansion of service infrastructure — cafés, gyms, medical, childcare — that follows population growth.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">🔌</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Infrastructure investment</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">New utilities, roads, transit stops and public infrastructure as a signal of long-term growth commitment.</p>
</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px">👥</div>
<div style="background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:24px 28px;cursor:pointer" onclick="location.href='#contact'" role="button" tabindex="0">
<div style="font-size:1.5rem;margin-bottom:10px"></div>
<h3 style="font-size:1rem;font-weight:700;color:#0a0a0a;margin-bottom:6px">Demographic signals</h3>
<p style="font-size:.875rem;color:#6b7280;line-height:1.6">Observable shifts in the demographic mix of an area — a leading indicator of future commercial and property demand.</p>
</div>
@@ -303,9 +303,9 @@
<div class="section-label">Use cases</div>
<h2 class="section-title section-title-light" style="margin-bottom:24px">Who uses this index.</h2>
<div style="display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-bottom:40px">
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Early-stage investment</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Retail pre-positioning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius:100px">Infrastructure planning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Early-stage investment</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Retail pre-positioning</span>
<span style="background:#e0eaff;color:#0052cc;font-size:.8125rem;font-weight:600;padding:6px 14px;border-radius: 100px">Infrastructure planning</span>
</div>
</div>
</div>
@@ -318,7 +318,7 @@
<div class="section-label">Sample output</div>
<h2 class="section-title" style="margin-bottom:8px">What you receive.</h2>
<p style="color:var(--text-dim);margin-bottom:48px">Growth velocity score + district ranking + 12-month trajectory</p>
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius:16px;padding:36px 40px;text-align:left">
<div style="background:var(--surface-2);border:1px solid var(--border);border-radius: var(--radius-lg);padding:36px 40px;text-align:left">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
<span style="color:var(--text-dim);font-size:.875rem;font-weight:600">Sample location · Placeholder score</span>
<span style="color:#4ade80;font-size:.875rem;font-weight:700">↑ High velocity</span>
@@ -328,8 +328,8 @@
<span style="font-size:1.5rem;color:var(--text-dim)">/100</span>
</div>
<div style="background:#f3f4f6;border-radius:8px;height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:78%;background:#4ade80;border-radius:8px;transition:width 1s ease"></div>
<div style="background:#f3f4f6;border-radius: var(--radius-md);height:12px;width:100%;margin:12px 0 8px;overflow:hidden">
<div style="height:100%;width:78%;background:#4ade80;border-radius: var(--radius-md);transition:width 1s ease"></div>
</div>
<div style="display:flex;justify-content:space-between;font-size:.75rem;color:var(--text-dim)">
@@ -352,29 +352,29 @@
<h2 class="section-title">How this index detects narrative conflicts.</h2>
<p style="color:rgba(255,255,255,.75);max-width:600px;margin:0 auto;line-height:1.7">Urban Growth Index flags when official population and economic statistics show growth in areas where observed activity is stagnant — or vice versa. Emerging districts frequently grow faster than statistics reflect. When field observations show rapid commercial expansion ahead of official economic data, the index raises the score and flags the statistical gap.</p>
</div>
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius:16px;padding:32px 36px">
<div style="background:rgba(0,0,0,.05);border:1px solid rgba(0,0,0,.1);border-radius: var(--radius-lg);padding:32px 36px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="font-size:1.5rem">🚩</span>
<span style="font-size:1.5rem"></span>
<div>
<div style="color:#f87171;font-weight:800;font-size:.9375rem;margin-bottom:4px">Contradiction Engine — How it works</div>
<div style="color:rgba(255,255,255,.75);font-size:.875rem;line-height:1.6">Field observations are continuously cross-referenced against official records, registers, and published statistics. Divergence above threshold triggers a conflict flag.</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.1);border:1px solid rgba(34,197,94,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#86efac;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official record</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Register data</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Published condition ratings</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Official statistics</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Register data</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.2);border-radius: var(--radius-md);padding:16px">
<div style="color:#fca5a5;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Observed reality</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"> Contradiction flags</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Field observations</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Real-time signals</li>
<li style="color:rgba(255,255,255,.7);font-size:.875rem"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 4L12 12M12 4L4 12" stroke="#ef4444" stroke-width="2" stroke-linecap="round"/></svg> Contradiction flags</li>
</ul>
</div>
</div>
@@ -392,20 +392,20 @@
</div>
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));gap:20px;max-width:900px;margin:0 auto">
<a href="/intelligence/growth-velocity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">🚀</div>
<a href="/intelligence/growth-velocity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2L10 8L14 9L8 14L6 8L2 7L8 2Z" fill="#666"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Growth Velocity Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">📈</div>
<a href="/intelligence/commercial-opportunity-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 12L6 8L9 11L14 5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M10 5H14V9" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Commercial Opportunity Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
<a href="/intelligence/investment-attractiveness-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius:12px;padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px">💎</div>
<a href="/intelligence/investment-attractiveness-index/" style="display:block;background:#f8f9ff;border:1px solid #e5e7eb;border-radius: var(--radius-md);padding:20px 24px;text-decoration:none;color:inherit;transition:border-color .2s,transform .15s" onmouseover="this.style.borderColor='#0066ff';this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='#e5e7eb';this.style.transform='none'">
<div style="font-size:1.25rem;margin-bottom:8px"></div>
<div style="font-weight:700;color:#0a0a0a;font-size:.9375rem;margin-bottom:4px">Investment Attractiveness Index</div>
<div style="color:#0066ff;font-size:.8125rem;font-weight:700">View index →</div>
</a>
@@ -503,7 +503,7 @@
});
if (res.ok || res.status === 201) {
msgEl.className = 'success';
msgEl.textContent = " Request received. We'll be in touch within one business day.";
msgEl.textContent = "<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8L6.5 11.5L13 4.5" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg> Request received. We'll be in touch within one business day.";
msgEl.style.display = 'block';
this.reset();
} else { throw new Error('Server error ' + res.status); }