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
+181 -133
View File
@@ -69,7 +69,7 @@
a { color: inherit; text-decoration: none; }
/* ── NAV ── */
/* NAV */
nav {
position: fixed; top: 0; left: 0; right: 0; z-index: 1000;
display: flex; align-items: center; justify-content: space-between;
@@ -179,7 +179,7 @@
.btn-outline:hover { background: rgba(0,0,0,0.04); transform: translateY(-1px); }
.btn-lg { padding: 14px 30px; font-size: 16px; border-radius: var(--radius-md); }
/* ── HERO ── */
/* HERO */
.hero {
min-height: 100vh;
display: flex; flex-direction: column; align-items: center; justify-content: center;
@@ -254,7 +254,7 @@
}
.stat-label { font-size: 13px; color: #6E6E73; margin-top: 4px; }
/* ── SECTION COMMON ── */
/* SECTION COMMON */
section { padding: 96px 24px; }
.container { max-width: 1140px; margin: 0 auto; }
@@ -281,7 +281,7 @@
line-height: 1.7;
}
/* ── DELIVER ── */
/* DELIVER */
.deliver-bg { background: var(--surface); }
.deliver-header {
@@ -332,7 +332,7 @@
.deliver-card p { color: #4A4A4A; font-size: 15px; color: #4A4A4A; line-height: 1.6; }
/* ── VERTICALS ── */
/* VERTICALS */
.verticals-header {
text-align: center;
margin-bottom: 60px;
@@ -369,7 +369,7 @@
.vertical-card h3 { color: #0A0A0A; font-size: 16px; font-weight: 700; color: #0A0A0A; margin-bottom: 6px; }
.vertical-card p { color: #4A4A4A; font-size: 14px; color: #4A4A4A; line-height: 1.5; }
/* ── HOW IT WORKS ── */
/* HOW IT WORKS */
.how-bg { background: var(--surface); }
.how-header { text-align: center; margin-bottom: 64px; }
@@ -377,8 +377,10 @@
.how-steps {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 0;
gap: 24px;
position: relative;
max-width: 1000px;
margin: 0 auto;
}
.how-steps::before {
@@ -394,26 +396,29 @@
.how-step:hover { transform: translateY(-3px); border-color: rgba(0,102,255,0.4); }
.how-step {
text-align: center;
padding: 0 20px;
padding: 32px 24px;
position: relative;
background: #ffffff;
border: 1px solid rgba(0,0,0,0.08);
border-radius: var(--radius-lg);
}
.step-num {
width: 56px; height: 56px;
border-radius: 50%;
width: 48px; height: 48px;
border-radius: var(--radius-full);
background: var(--blue-glow);
border: 2px solid var(--blue);
display: flex; align-items: center; justify-content: center;
font-size: 18px; font-weight: 800;
font-size: 16px; font-weight: 800;
color: var(--blue);
margin: 0 auto 24px;
margin: 0 auto 20px;
position: relative; z-index: 1;
}
.how-step h3 { font-size: 16px; font-weight: 700; color: #0A0A0A; margin-bottom: 8px; }
.how-step p { font-size: 14px; color: #4A4A4A; line-height: 1.6; }
/* ── CONTACT ── */
/* CONTACT */
.contact-wrapper {
max-width: 680px;
margin: 0 auto;
@@ -469,7 +474,7 @@
#form-message.success { background: rgba(0,200,80,0.1); border: 1px solid rgba(0,200,80,0.25); color: #4ade80; }
#form-message.error { background: rgba(255,60,60,0.1); border: 1px solid rgba(255,60,60,0.25); color: #f87171; }
/* ── FOOTER ── */
/* FOOTER */
footer {
border-top: 1px solid var(--border);
padding: 40px 40px;
@@ -504,21 +509,22 @@
.footer-social {
width: 32px; height: 32px;
border: 1px solid var(--border);
border-radius: 8px;
border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
transition: border-color 0.2s, background 0.2s;
}
.footer-social:hover { border-color: rgba(0,0,0,0.25); background: rgba(0,0,0,0.04); }
.footer-tagline { font-size: 12px; color: #6E6E73; margin-top: 4px; }
/* ── RESPONSIVE ── */
/* RESPONSIVE */
@media (max-width: 900px) {
nav { padding: 0 16px; }
.nav-links { display: none; }
.deliver-grid { grid-template-columns: 1fr; }
.verticals-grid { grid-template-columns: 1fr 1fr; }
.how-steps { grid-template-columns: 1fr 1fr; gap: 32px; }
.how-steps { grid-template-columns: 1fr 1fr; gap: 20px; }
.how-steps::before { display: none; }
.how-step { padding: 24px 20px; }
}
@media (max-width: 640px) {
@@ -533,7 +539,8 @@
.deliver-icon { overflow: hidden !important; }
.deliver-icon svg { max-width: 24px; max-height: 24px; flex-shrink: 0; }
.verticals-grid { grid-template-columns: 1fr; }
.how-steps { grid-template-columns: 1fr; }
.how-steps { grid-template-columns: 1fr; gap: 16px; }
.how-step { padding: 20px 16px; }
.form-row { grid-template-columns: 1fr; }
.contact-form { padding: 24px 20px; }
.footer-inner { flex-direction: column; text-align: center; }
@@ -562,7 +569,7 @@
.howwework-grid { grid-template-columns: 1fr !important; }
}
/* ── Global mobile fix ───────────────────────────────────────────── */
/* Global mobile fix */
@media(max-width:480px){
img, svg { max-width:100%; }
table { overflow-x:auto; display:block; }
@@ -584,9 +591,9 @@
/* Map section mobile fixes */
@media(max-width:600px){
.map-iframe{min-height:260px!important;height:52vh!important}
.map-overlay{position:static!important;background:rgba(0,0,0,.95)!important;border-radius:0 0 16px 16px;flex-direction:column;align-items:flex-start;gap:12px;padding:14px 16px!important}
.map-cta-row{width:100%;display:flex;gap:8px}
.map-cta-row a{flex:1;text-align:center}
.map-overlay{position:static!important;background:rgba(0,0,0,.95)!important;border-radius: 0 0 16px 16px;flex-direction:column!important;align-items:flex-start!important;gap:12px;padding:14px 16px!important}
.map-cta-row{width:100%!important;display:flex;gap:8px;flex-wrap:wrap}
.map-cta-row a{flex:1;text-align:center;min-width:120px}
}
/* SVG overflow fix — global */
@@ -599,7 +606,7 @@
/* AUDIT FIX m-001 safety net */
html,body{overflow-x:clip}
/* ── SOCIAL PROOF ── */
/* SOCIAL PROOF */
.social-proof {
background: #ffffff;
border-top: 1px solid rgba(0,0,0,0.06);
@@ -629,19 +636,19 @@ html,body{overflow-x:clip}
color: #6e6e73;
background: #FFFFFF;
border: 1px solid rgba(0,0,0,0.08);
border-radius: 8px;
border-radius: var(--radius-md);
padding: 8px 16px;
white-space: nowrap;
transition: border-color 0.2s, color 0.2s;
}
.sp-item:hover { border-color: rgba(0,102,255,0.22); color: #0A0A0A; }
/* ── P4 MICROINTERACTIONS ── */
/* P4 MICROINTERACTIONS */
.deliver-card, .vertical-card, .intel-card {
transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.2s ease;
}
/* ── CTA SECONDARY ── */
/* CTA SECONDARY */
.cta-secondary {
display: inline-flex; align-items: center; gap: 6px;
padding: 14px 22px;
@@ -656,7 +663,7 @@ html,body{overflow-x:clip}
}
.cta-secondary:hover { background: rgba(0,0,0,0.04); border-color: rgba(0,102,255,0.35); color: #0066FF; transform: translateY(-1px); }
/* ── FOOTER ECOSYSTEM ── */
/* FOOTER ECOSYSTEM */
.footer-ecosystem {
font-size: 12px; color: #6e6e73; margin-top: 12px; line-height: 1.5;
}
@@ -670,51 +677,98 @@ html,body{overflow-x:clip}
/* Intelligence Cards v2 */
.intel-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;margin-top:40px}
@media(max-width:768px){.intel-grid{grid-template-columns:1fr}}
.intel-card{background:#ffffff;border:1px solid rgba(0,0,0,.08);border-radius:16px;padding:28px;text-decoration:none;color:inherit;display:flex;flex-direction:column;gap:0;transition:border-color .2s,transform .2s;cursor:pointer}
.intel-card{background:#ffffff;border:1px solid rgba(0,0,0,.08);border-radius: var(--radius-lg);padding:32px;text-decoration:none;color:inherit;display:flex;flex-direction:column;gap:24px;transition:border-color .2s,transform .2s;cursor:pointer}
.intel-card:hover{border-color:rgba(0,102,255,.35);transform:translateY(-2px);box-shadow:0 8px 24px rgba(0,0,0,0.12)}
.intel-card-header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:20px}
.intel-card-header{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:0}
.intel-module{font-size:.6875rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#0066FF;margin-bottom:6px}
.intel-card h3{font-size:1.0625rem;font-weight:800;color: #0A0A0A;margin:0}
.intel-card-geo{font-size:.75rem;color:rgba(0,0,0,.75);margin-top:2px}
.intel-tag{font-size:.625rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:3px 9px;border-radius:100px;white-space:nowrap}
.intel-tag{font-size:.625rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:3px 9px;border-radius: 100px;white-space:nowrap}
.intel-tag-live{background:rgba(0,200,83,.12);color:#00C853;border:1px solid rgba(0,200,83,.2)}
.intel-tag-risk{background:rgba(255,59,48,.1);color:#FF3B30;border:1px solid rgba(255,59,48,.2)}
.intel-tag-pred{background:rgba(0,102,255,.12);color:#0066FF;border:1px solid rgba(0,102,255,.2)}
.intel-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:20px}
.intel-kpi{background:rgba(0,0,0,.03);border-radius:10px;padding:10px 12px}
.intel-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:0}
.intel-kpi{background:rgba(0,0,0,.03);border-radius: var(--radius-md);padding:10px 12px}
.intel-kpi-val{font-size:1.1875rem;font-weight:900;color: #0A0A0A;letter-spacing:-.03em;line-height:1}
.intel-kpi-delta{font-size:.6875rem;font-weight:700;margin-top:3px}
.intel-kpi-delta.up{color:#00C853}
.intel-kpi-delta.down{color:#FF3B30}
.intel-kpi-lbl{font-size:.625rem;color:rgba(0,0,0,.75);margin-top:2px;line-height:1.3}
.intel-bar-list{display:flex;flex-direction:column;gap:7px;margin-bottom:20px}
.intel-bar-list{display:flex;flex-direction:column;gap:7px;margin-bottom:0}
.intel-bar-row{display:flex;align-items:center;gap:10px}
.intel-bar-name{font-size:.75rem;color:rgba(0,0,0,.65);min-width:110px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.intel-bar-track{flex:1;height:5px;background:rgba(0,0,0,.06);border-radius:3px;overflow:hidden}
.intel-bar-fill{height:100%;border-radius:3px;background:#0066FF}
.intel-bar-track{flex:1;height:5px;background:rgba(0,0,0,.06);border-radius: var(--radius-sm);overflow:hidden}
.intel-bar-fill{height:100%;border-radius: var(--radius-sm);background:#0066FF}
.intel-bar-fill.risk{background:#FF3B30}
.intel-bar-fill.opp{background:#00C853}
.intel-bar-score{font-size:.6875rem;font-weight:700;color:rgba(0,0,0,.75);min-width:28px;text-align:right}
.intel-card-footer{display:flex;align-items:center;justify-content:space-between;padding-top:16px;border-top:1px solid rgba(0,0,0,.06);margin-top:auto}
.intel-card-footer{display:flex;align-items:center;justify-content:space-between;padding-top:16px;border-top:1px solid rgba(0,0,0,.06);margin-top:0}
.intel-obs{font-size:.6875rem;color:rgba(0,0,0,.75)}
.intel-cta{font-size:.75rem;font-weight:700;color:#0066FF;display:flex;align-items:center;gap:4px}
.intel-confidence{display:flex;align-items:center;gap:6px;font-size:.6875rem;color:rgba(0,0,0,.75)}
.intel-conf-bar{width:48px;height:4px;background:rgba(0,0,0,.08);border-radius:2px;overflow:hidden}
.intel-conf-fill{height:100%;background:#0066FF;border-radius:2px}
.intel-map-placeholder{background:linear-gradient(135deg,#0d1f3c 0%,#0a1628 50%,#0d2235 100%);border-radius:10px;height:80px;position:relative;overflow:hidden;margin-bottom:20px}
.intel-map-dot{position:absolute;width:8px;height:8px;border-radius:50%;background:#0066FF;box-shadow:0 0 0 3px rgba(0,102,255,.2)}
.intel-conf-bar{width:48px;height:4px;background:rgba(0,0,0,.08);border-radius: var(--radius-sm);overflow:hidden}
.intel-conf-fill{height:100%;background:#0066FF;border-radius: var(--radius-sm)}
.intel-map-placeholder{background:linear-gradient(135deg,#0d1f3c 0%,#0a1628 50%,#0d2235 100%);border-radius: var(--radius-md);height:80px;position:relative;overflow:hidden;margin-bottom:0}
.intel-map-dot{position:absolute;width:8px;height:8px;border-radius: var(--radius-full);background:#0066FF;box-shadow:0 0 0 3px rgba(0,102,255,.2)}
.intel-map-dot.hot{background:#00C853;box-shadow:0 0 0 3px rgba(0,200,83,.2)}
.intel-map-dot.warn{background:#FF3B30;box-shadow:0 0 0 3px rgba(255,59,48,.2)}
/* LV-ILL-02 Pipeline */
.lv-pipeline{display:flex;align-items:center;justify-content:center;gap:0;margin:32px 0 40px;overflow-x:auto;padding:0 8px}
.lv-pipeline-step{display:flex;flex-direction:column;align-items:center;gap:8px;min-width:88px}
.lv-pipeline-icon{width:52px;height:52px;border-radius:14px;background:rgba(0,102,255,.08);border:1px solid rgba(0,102,255,.18);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.lv-pipeline-icon{width:52px;height:52px;border-radius: var(--radius-lg);background:rgba(0,102,255,.08);border:1px solid rgba(0,102,255,.18);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.lv-pipeline-label{font-size:.6875rem;font-weight:700;color:rgba(0,0,0,.75);text-align:center;letter-spacing:.02em;line-height:1.3}
.lv-pipeline-connector{width:32px;height:2px;background:linear-gradient(90deg,rgba(0,102,255,.3),rgba(0,102,255,.1));flex-shrink:0;margin-top:-22px;align-self:flex-start;margin-left:0;position:relative;top:-26px}
@media(max-width:600px){.lv-pipeline{justify-content:flex-start}.lv-pipeline-connector{width:20px}}
@media(max-width:480px){.intel-grid{grid-template-columns:1fr}.intel-kpis{grid-template-columns:repeat(3,1fr)}.intel-bar-name{min-width:80px}}
@media(max-width:480px){.lv-pipeline{gap:0}.lv-pipeline-step{min-width:56px}.lv-pipeline-label{font-size:.5625rem}.lv-pipeline-icon{width:38px;height:38px;border-radius:10px}.lv-pipeline-connector{width:10px}}
@media(max-width:480px){.intel-grid{grid-template-columns:1fr}.intel-kpis{grid-template-columns:repeat(3,1fr);gap:8px}.intel-kpi{padding:8px}.intel-kpi-val{font-size:1rem}.intel-bar-row{gap:8px;flex-wrap:nowrap}.intel-bar-name{min-width:70px;font-size:.6875rem}.intel-bar-score{min-width:24px;font-size:.625rem}}
@media(max-width:480px){.lv-pipeline{gap:0}.lv-pipeline-step{min-width:56px}.lv-pipeline-label{font-size:.5625rem}.lv-pipeline-icon{width:38px;height:38px;border-radius: var(--radius-md)}.lv-pipeline-connector{width:10px}}
/* Mobile fixes for landvex.com */
@media(max-width:480px){
/* Map overlay - REMOVED to avoid conflicts with 600px breakpoint */
/* Intelligence cards */
/* Intelligence cards */
.intel-card {
padding: 16px !important;
}
.intel-card-header {
flex-direction: column !important;
gap: 8px !important;
}
.intel-card-header h3 {
font-size: 1.125rem !important;
}
.intel-kpis {
grid-template-columns: repeat(3, 1fr) !important;
gap: 8px !important;
}
.intel-kpi {
padding: 8px !important;
}
.intel-kpi-val {
font-size: 1rem !important;
}
.intel-kpi-lbl {
font-size: .5625rem !important;
}
.intel-bar-row {
gap: 8px !important;
}
.intel-bar-name {
min-width: 70px !important;
font-size: .6875rem !important;
}
.intel-bar-score {
min-width: 24px !important;
font-size: .625rem !important;
}
.intel-card-footer {
flex-direction: column !important;
gap: 8px !important;
align-items: flex-start !important;
}
}
</style>
@@ -1173,7 +1227,7 @@ html,body{overflow-x:clip}
<h2 class="section-title">From observation to intelligence.<br>Continuously.</h2>
<p class="section-sub" style="margin:0 auto;max-width:600px">RIOS is a vendor-agnostic AI operating system that transforms video observations into structured Reality Intelligence. It supports real-time field analysis today while continuously training proprietary models that gradually replace expensive third-party inference.</p>
</div>
<div class="how-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:2px;background:rgba(0,0,0,.06);border-radius:16px;overflow:hidden">
<div class="how-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:2px;background:rgba(0,0,0,.06);border-radius: var(--radius-lg);overflow:hidden">
<div style="background:#ffffff;padding:48px 44px;position:relative;border:1px solid rgba(0,0,0,0.08)">
<div style="font-size:.6875rem;font-weight:800;color:#0066FF;text-transform:uppercase;letter-spacing:.14em;margin-bottom:20px">01</div>
<h3 style="font-size:1.375rem;font-weight:800;color:#0A0A0A;letter-spacing:-.03em;margin-bottom:12px;line-height:1.2">Reality Capture</h3>
@@ -1202,10 +1256,10 @@ html,body{overflow-x:clip}
<section class="social-proof">
<p class="sp-label">Trusted by decision makers in</p>
<div class="sp-logos">
<div class="sp-item">🏛️ Municipal Government</div>
<div class="sp-item">🏗️ Infrastructure</div>
<div class="sp-item">🏢 Real Estate</div>
<div class="sp-item">🛡️ Insurance</div>
<div class="sp-item"> Municipal Government</div>
<div class="sp-item"><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> Infrastructure</div>
<div class="sp-item"><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> Real Estate</div>
<div class="sp-item"> Insurance</div>
<div class="sp-item"><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> Investment</div>
</div>
</section>
@@ -1216,8 +1270,8 @@ html,body{overflow-x:clip}
<!-- Header -->
<div style="text-align:center;margin-bottom:32px">
<div style="display:inline-flex;align-items:center;gap:8px;background:rgba(0,102,255,.08);border:1px solid rgba(0,102,255,.18);border-radius:20px;padding:5px 14px;font-size:.75rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#0052CC;margin-bottom:16px">
<span style="width:7px;height:7px;border-radius:50%;background:#0052CC;display:inline-block"></span>
<div style="display:inline-flex;align-items:center;gap:8px;background:rgba(0,102,255,.08);border:1px solid rgba(0,102,255,.18);border-radius: var(--radius-xl);padding:5px 14px;font-size:.75rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#0052CC;margin-bottom:16px">
<span style="width:7px;height:7px;border-radius: var(--radius-full);background:#0052CC;display:inline-block"></span>
Live demonstration
</div>
<h2 style="font-size:clamp(22px,4vw,36px);font-weight:800;letter-spacing:-.5px;color:#1d1d1f;margin-bottom:12px;line-height:1.15">Intelligence Map &mdash; 100+ Cities</h2>
@@ -1225,29 +1279,28 @@ html,body{overflow-x:clip}
</div>
<!-- Map frame -->
<div style="border-radius:16px;overflow:hidden;border:1px solid rgba(0,0,0,.1);box-shadow:0 8px 32px rgba(0,0,0,.10)">
<div style="border-radius: var(--radius-lg);overflow:hidden;border:1px solid rgba(0,0,0,.1);box-shadow:0 8px 32px rgba(0,0,0,.10)">
<iframe src="/intelligence-map.html" style="width:100%;height:min(68vh,560px);min-height:320px;border:none;display:block" title="Landvex Intelligence Map" loading="lazy" allow="geolocation" class="map-iframe"></iframe>
<!-- Bottom bar: sits flush under map, inside same border-radius container -->
<div class="map-overlay" style="color:#0A0A0A;background:rgba(0,0,0,.97);padding:14px 20px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;border-top:1px solid rgba(255,255,255,.07)">
<div style="display:flex;align-items:center;gap:10px;flex:1;min-width:0">
<div style="width:6px;height:6px;border-radius:50%;background:#22c55e;flex-shrink:0"></div>
<span style="font-size:.8125rem;color:#4A4A4A;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">Source First &mdash; every data point traceable to source &rsaquo; observation &rsaquo; model &rsaquo; index</span>
<div style="width:6px;height:6px;border-radius: var(--radius-full);background:#22c55e;flex-shrink:0"></div>
<span style="font-size:.8125rem;color:#4A4A4A;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">Source First</span>
</div>
<div class="map-cta-row" style="display:flex;gap:8px;flex-shrink:0">
<a href="/intelligence-map" style="background:#0066FF;color: #0A0A0A;font-size:.8125rem;font-weight:700;padding:9px 18px;border-radius:8px;text-decoration:none;white-space:nowrap">Open full map &rarr;</a>
<a href="/stockholm-intelligence" style="background:rgba(0,0,0,.07);color:rgba(0,0,0,.85);font-size:.8125rem;font-weight:600;padding:9px 18px;border-radius:8px;text-decoration:none;border:1px solid rgba(0,0,0,.12);white-space:nowrap">Stockholm deep dive</a>
<div class="map-cta-row" style="display:flex;gap:8px;flex-shrink:0;flex-wrap:wrap">
<a href="/intelligence-map" style="background:#0066FF;color: #fff;font-size:.8125rem;font-weight:700;padding:9px 18px;border-radius: var(--radius-md);text-decoration:none;white-space:nowrap">Open full map </a>
</div>
</div>
</div>
<!-- Tags -->
<div style="display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-top:20px">
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius:20px;padding:5px 13px;border:1px solid rgba(0,0,0,.07)">100+ cities</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius:20px;padding:5px 13px;border:1px solid rgba(0,0,0,.07)">Contradiction Index</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius:20px;padding:5px 13px;border:1px solid rgba(0,0,0,.07)">Infrastructure Risk</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius:20px;padding:5px 13px;border:1px solid rgba(0,0,0,.07)">Commercial Vitality</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius:20px;padding:5px 13px;border:1px solid rgba(0,0,0,.07)">City Health</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius:20px;padding:5px 13px;border:1px solid rgba(0,0,0,.07)">Source First</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius: var(--radius-xl);padding:5px 13px;border:1px solid rgba(0,0,0,.07)">100+ cities</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius: var(--radius-xl);padding:5px 13px;border:1px solid rgba(0,0,0,.07)">Contradiction Index</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius: var(--radius-xl);padding:5px 13px;border:1px solid rgba(0,0,0,.07)">Infrastructure Risk</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius: var(--radius-xl);padding:5px 13px;border:1px solid rgba(0,0,0,.07)">Commercial Vitality</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius: var(--radius-xl);padding:5px 13px;border:1px solid rgba(0,0,0,.07)">City Health</span>
<span style="font-size:.75rem;font-weight:600;background:rgba(0,0,0,.05);color:rgba(0,0,0,.4);border-radius: var(--radius-xl);padding:5px 13px;border:1px solid rgba(0,0,0,.07)">Source First</span>
</div>
</div>
@@ -1262,7 +1315,7 @@ html,body{overflow-x:clip}
<h2 class="section-title" style="color:#0A0A0A;margin-bottom:20px;line-height:1.05;text-shadow:none">We start with your decision.<br>Not with our data.</h2>
<p style="font-size:1.0625rem;color:#4A4A4A;line-height:1.7;max-width:480px">Most intelligence platforms sell you a dataset and leave the interpretation to you. Landvex works backwards — from the decision you need to make to the intelligence required to make it confidently.</p>
</div>
<div class="how-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:2px;background:rgba(0,0,0,.06);border-radius:16px;overflow:hidden">
<div class="how-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:2px;background:rgba(0,0,0,.06);border-radius: var(--radius-lg);overflow:hidden">
<div style="background:#ffffff;padding:48px 44px;position:relative;border:1px solid rgba(0,0,0,0.08)">
<div style="font-size:.6875rem;font-weight:800;color:#0066FF;text-transform:uppercase;letter-spacing:.14em;margin-bottom:20px">01</div>
<h3 style="font-size:1.375rem;font-weight:800;color:#0A0A0A;letter-spacing:-.03em;margin-bottom:12px;line-height:1.2">Define the decision</h3>
@@ -1294,7 +1347,7 @@ html,body{overflow-x:clip}
<div class="section-label">Decision intelligence</div>
<h2 class="section-title">Ten decisions. One platform.</h2>
<p class="section-sub" style="margin:0 auto;max-width:600px">Property owners, municipalities, retailers, infrastructure operators, investors. Different industries — identical need: to make better decisions about the physical world. Landvex is built for that.</p>
<div class="lv-ill-wrap" aria-hidden="true">
<div class="lv-ill-wrap" aria-hidden="true" style="margin: 40px 0;">
<svg viewBox="0 0 600 140" xmlns="http://www.w3.org/2000/svg" width="600" height="140">
<defs>
<style>@media(prefers-reduced-motion:no-preference){.pla{animation:pla 2.4s ease-in-out infinite}.plb{animation:pla 2.4s ease-in-out 1.2s infinite}}@keyframes pla{0%,100%{opacity:.65}50%{opacity:1}}</style>
@@ -1330,7 +1383,7 @@ html,body{overflow-x:clip}
</div>
<p style="text-align:center;color:var(--text-muted);font-size:0.875rem;margin:16px 0 8px;">⚠️ All intelligence examples below are illustrative sample data for demonstration purposes.</p>
<p style="text-align:center;color:var(--text-muted);font-size:0.875rem;margin:32px 0 24px;"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10 3L17 17H3L10 3Z" stroke="#f59e0b" stroke-width="2"/><path d="M10 8V12M10 14V14.5" stroke="#f59e0b" stroke-width="2" stroke-linecap="round"/></svg> All intelligence examples below are illustrative sample data for demonstration purposes.</p>
<div class="intel-grid">
@@ -1487,13 +1540,7 @@ html,body{overflow-x:clip}
<div class="intel-kpi-lbl">Identified</div>
</div>
</div>
<div class="intel-confidence">
<span>Model confidence</span>
<div class="intel-conf-bar"><div class="intel-conf-fill" style="width:87%"></div></div>
<span>87%</span>
<span style="margin-left:auto;font-size:.625rem">Commercial permits &middot; Population shifts &middot; Traffic flows</span>
</div>
<div class="intel-card-footer" style="margin-top:12px">
<div class="intel-card-footer">
<span class="intel-obs">Indicative signals &mdash; not investment advice</span>
<span class="intel-cta">View forecast <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><path d="M5 12h14M12 5l7 7-7 7"/></svg></span>
</div>
@@ -1504,36 +1551,37 @@ html,body{overflow-x:clip}
<style>
.verticals-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
align-items: stretch;
}
@media(max-width:768px){.verticals-grid{grid-template-columns:1fr 1fr}}
@media(max-width:480px){.verticals-grid{grid-template-columns:1fr}}
.vertical-card {
background: #fff;
border: 1px solid #eee;
border-radius: 12px;
padding: 24px;
border: 1px solid rgba(0,0,0,0.08);
border-radius: var(--radius-lg);
padding: 28px;
display: flex;
flex-direction: column;
gap: 8px;
gap: 12px;
text-decoration: none;
color: inherit;
transition: box-shadow 0.2s;
}
.vertical-card:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.08);
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
.vertical-card h3 {
margin: 0;
font-size: 1.1rem;
font-weight: 600;
font-size: 1.0625rem;
font-weight: 700;
}
.vertical-card p {
margin: 0;
font-size: 0.875rem;
line-height: 1.5;
color: #666;
flex-grow: 1;
color: #4A4A4A;
}
.vertical-icon {
margin-bottom: 4px;
@@ -1616,7 +1664,7 @@ html,body{overflow-x:clip}
</div>
<div class="deliver-grid">
<a class="deliver-card" href="/methodology/" style="text-decoration:none;color:inherit;cursor:pointer;display:block">
<div class="deliver-icon" style="width:48px;height:48px;min-width:48px;overflow:hidden;background:rgba(0,102,255,.12);border-radius:12px;display:flex;align-items:center;justify-content:center;margin-bottom:16px;flex-shrink:0">
<div class="deliver-icon" style="width:48px;height:48px;min-width:48px;overflow:hidden;background:rgba(0,102,255,.12);border-radius: var(--radius-md);display:flex;align-items:center;justify-content:center;margin-bottom:16px;flex-shrink:0">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#0066ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
</div>
<div class="number">20+</div>
@@ -1625,7 +1673,7 @@ html,body{overflow-x:clip}
<span style="font-size:.8rem;font-weight:700;color:#0066ff;margin-top:12px;display:block">How it works →</span>
</a>
<a class="deliver-card" href="/methodology/" style="text-decoration:none;color:inherit;cursor:pointer;display:block">
<div class="deliver-icon" style="width:48px;height:48px;min-width:48px;overflow:hidden;background:rgba(0,102,255,.12);border-radius:12px;display:flex;align-items:center;justify-content:center;margin-bottom:16px;flex-shrink:0">
<div class="deliver-icon" style="width:48px;height:48px;min-width:48px;overflow:hidden;background:rgba(0,102,255,.12);border-radius: var(--radius-md);display:flex;align-items:center;justify-content:center;margin-bottom:16px;flex-shrink:0">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#0066ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
</div>
<div class="number">2472h</div>
@@ -1634,7 +1682,7 @@ html,body{overflow-x:clip}
<span style="font-size:.8rem;font-weight:700;color:#0066ff;margin-top:12px;display:block">Methodology →</span>
</a>
<a class="deliver-card" href="/methodology/" style="text-decoration:none;color:inherit;cursor:pointer;display:block">
<div class="deliver-icon" style="width:48px;height:48px;min-width:48px;overflow:hidden;background:rgba(0,102,255,.12);border-radius:12px;display:flex;align-items:center;justify-content:center;margin-bottom:16px;flex-shrink:0">
<div class="deliver-icon" style="width:48px;height:48px;min-width:48px;overflow:hidden;background:rgba(0,102,255,.12);border-radius: var(--radius-md);display:flex;align-items:center;justify-content:center;margin-bottom:16px;flex-shrink:0">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#0066ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
</div>
<div class="number">AI</div>
@@ -1687,7 +1735,7 @@ html,body{overflow-x:clip}
</a>
<a class="vertical-card" href="/verticals/insurance/" style="border-color:rgba(0,102,255,.25);position:relative;display:block;text-decoration:none;color:inherit;cursor:pointer">
<span style="position:absolute;top:12px;right:12px;background:#0066FF;color:#0A0A0A;font-size:.6rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;padding:3px 8px;border-radius:100px">Vertical</span>
<span style="position:absolute;top:12px;right:12px;background:#0066FF;color:#0A0A0A;font-size:.6rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase;padding:3px 8px;border-radius: 100px">Vertical</span>
<div class="vertical-icon"><svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#0066ff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg></div>
<div>
<h3>Insurance</h3>
@@ -1800,13 +1848,13 @@ html,body{overflow-x:clip}
.score-table thead { display:none; }
.score-table tr { display:grid; grid-template-columns:1fr 1fr; gap:8px; padding:16px 0; border-bottom:1px solid rgba(0,0,0,.07); }
.score-table tr:last-child { border-bottom:none; }
.score-table td { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px; padding:10px 8px; background:rgba(0,0,0,.04); border-radius:10px; border-bottom:none; font-size:.75rem; }
.score-table td { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px; padding:10px 8px; background:rgba(0,0,0,.04); border-radius: var(--radius-md); border-bottom:none; font-size:.75rem; }
.score-table td:first-child { grid-column:1/-1; background:transparent; align-items:flex-start; font-size:.9375rem; padding:0 0 4px; }
.score-table td::before { content:attr(data-label); font-size:.65rem; font-weight:700; color:rgba(0,0,0,.75); text-transform:uppercase; letter-spacing:.06em; }
}
</style>
<div class="score-table-wrap">
<div style="background:rgba(255,193,7,0.08);border:1px solid rgba(255,193,7,0.3);border-radius:10px;padding:14px 18px;margin-bottom:16px;font-size:.82rem;color:rgba(0,0,0,.85);line-height:1.6">
<div style="background:rgba(255,193,7,0.08);border:1px solid rgba(255,193,7,0.3);border-radius: var(--radius-md);padding:14px 18px;margin-bottom:16px;font-size:.82rem;color:rgba(0,0,0,.85);line-height:1.6">
<strong style="color:#ffc107"><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> Format demonstration</strong> — The figures below are a simulated reference example showing report structure and output format. Live intelligence activates from August 2026 as the quiXzoom observation network launches.
</div>
<table class="score-table">
@@ -1822,62 +1870,62 @@ html,body{overflow-x:clip}
</thead>
<tbody>
<tr style="display:none">
<td data-label="">City A — District 1 <span style="font-size:.75rem;opacity:.85;font-weight:600"> sample</span></td>
<td data-label="Opp."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">84</span></td>
<td data-label="Growth"><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius:20px">78</span></td>
<td data-label="Vitality"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">91</span></td>
<td data-label="Infra"><span style="background:#fee2e2;color:#991b1b;font-weight:800;padding:4px 10px;border-radius:20px">62</span></td>
<td data-label="Invest."><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius:20px">79</span></td>
<td data-label="">City A — District 1 <span style="font-size:.75rem;opacity:.85;font-weight:600"> sample</span></td>
<td data-label="Opp."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">84</span></td>
<td data-label="Growth"><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius: 20px">78</span></td>
<td data-label="Vitality"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">91</span></td>
<td data-label="Infra"><span style="background:#fee2e2;color:#991b1b;font-weight:800;padding:4px 10px;border-radius: 20px">62</span></td>
<td data-label="Invest."><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius: 20px">79</span></td>
</tr>
<tr style="display:none">
<td data-label="">City B — Central <span style="font-size:.75rem;opacity:.85;font-weight:600"> sample</span></td>
<td data-label="Opp."><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius:20px">77</span></td>
<td data-label="Growth"><span style="background:#fee2e2;color:#991b1b;font-weight:800;padding:4px 10px;border-radius:20px">61</span></td>
<td data-label="Vitality"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">83</span></td>
<td data-label="Infra"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">88</span></td>
<td data-label="Invest."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">82</span></td>
<td data-label="">City B — Central <span style="font-size:.75rem;opacity:.85;font-weight:600"> sample</span></td>
<td data-label="Opp."><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius: 20px">77</span></td>
<td data-label="Growth"><span style="background:#fee2e2;color:#991b1b;font-weight:800;padding:4px 10px;border-radius: 20px">61</span></td>
<td data-label="Vitality"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">83</span></td>
<td data-label="Infra"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">88</span></td>
<td data-label="Invest."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">82</span></td>
</tr>
<tr>
<td data-label="">Stockholm — Norrmalm</td>
<td data-label="Opp."><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius:20px">71</span></td>
<td data-label="Growth"><span style="background:#fee2e2;color:#991b1b;font-weight:800;padding:4px 10px;border-radius:20px">58</span></td>
<td data-label="Vitality"><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius:20px">76</span></td>
<td data-label="Infra"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">92</span></td>
<td data-label="Invest."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">81</span></td>
<td data-label="Opp."><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius: 20px">71</span></td>
<td data-label="Growth"><span style="background:#fee2e2;color:#991b1b;font-weight:800;padding:4px 10px;border-radius: 20px">58</span></td>
<td data-label="Vitality"><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius: 20px">76</span></td>
<td data-label="Infra"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">92</span></td>
<td data-label="Invest."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">81</span></td>
</tr>
<tr>
<td data-label="">Milan — Porta Nuova</td>
<td data-label="Opp."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">86</span></td>
<td data-label="Growth"><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius:20px">74</span></td>
<td data-label="Vitality"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">88</span></td>
<td data-label="Infra"><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius:20px">69</span></td>
<td data-label="Invest."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius:20px">84</span></td>
<td data-label="Opp."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">86</span></td>
<td data-label="Growth"><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius: 20px">74</span></td>
<td data-label="Vitality"><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">88</span></td>
<td data-label="Infra"><span style="background:#fef9c3;color:#854d0e;font-weight:800;padding:4px 10px;border-radius: 20px">69</span></td>
<td data-label="Invest."><span style="background:#dcfce7;color:#166534;font-weight:800;padding:4px 10px;border-radius: 20px">84</span></td>
</tr>
</tbody>
</table>
<p style="font-size:.8rem;color:#515154;margin-top:12px;text-align:center;line-height:1.5">Intelligence outputs are advisory analytical signals — not investment advice, financial promotion, or statements of fact about named locations. <a href="/methodology/" style="color:#0066FF;text-decoration:underline">Methodology →</a></p>
</div>
<div style="margin-top:48px;background:#0066FF;border-radius:16px;padding:40px 48px;display:flex;align-items:center;gap:48px;flex-wrap:wrap">
<div style="margin-top:48px;background:#0066FF;border-radius: var(--radius-lg);padding:40px 48px;display:flex;align-items:center;gap:48px;flex-wrap:wrap">
<div style="flex:1;min-width:260px">
<h3 style="color: #0A0A0A;font-size:1.25rem;font-weight:800;margin-bottom:8px">Four layers. One answer.</h3>
<p style="color:rgba(0,0,0,0.85);line-height:1.65;font-size:.9375rem">quiXzoom observes. AMOS analyses. Landvex delivers the answer. Every engagement starts with one question: <em style="color: #0A0A0A;font-style:normal">what decision are you trying to make?</em></p>
<!-- quiXzoom → Landvex → You pipeline -->
<div style="display:flex;align-items:center;gap:0;margin-top:24px;flex-wrap:wrap">
<div style="display:flex;flex-direction:column;align-items:center;gap:6px;min-width:100px;padding:0 8px">
<div style="width:44px;height:44px;border-radius:12px;background:rgba(0,0,0,0.15);border:1px solid rgba(0,0,0,0.25);display:flex;align-items:center;justify-content:center;font-size:20px">🔭</div>
<div style="width:44px;height:44px;border-radius: var(--radius-md);background:rgba(0,0,0,0.15);border:1px solid rgba(0,0,0,0.25);display:flex;align-items:center;justify-content:center;font-size:20px"></div>
<div style="font-size:11px;font-weight:800;color: #0A0A0A;letter-spacing:.04em">quiXzoom</div>
<div style="font-size:10px;color:rgba(0,0,0,0.75);text-align:center;line-height:1.4">Observes reality on the ground</div>
</div>
<div style="font-size:18px;color:rgba(0,0,0,0.5);margin:0 4px;padding-bottom:22px">&rarr;</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:6px;min-width:100px;padding:0 8px">
<div style="width:44px;height:44px;border-radius:12px;background:rgba(0,0,0,0.15);border:1px solid rgba(0,0,0,0.25);display:flex;align-items:center;justify-content:center;font-size:20px"></div>
<div style="width:44px;height:44px;border-radius: var(--radius-md);background:rgba(0,0,0,0.15);border:1px solid rgba(0,0,0,0.25);display:flex;align-items:center;justify-content:center;font-size:20px"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 2L5 9H8L7 14L11 7H8L9 2Z" fill="#f59e0b"/></svg></div>
<div style="font-size:11px;font-weight:800;color: #0A0A0A;letter-spacing:.04em">Landvex</div>
<div style="font-size:10px;color:rgba(0,0,0,0.75);text-align:center;line-height:1.4">Analyses &amp; detects contradictions</div>
</div>
<div style="font-size:18px;color:rgba(0,0,0,0.5);margin:0 4px;padding-bottom:22px">&rarr;</div>
<div style="display:flex;flex-direction:column;align-items:center;gap:6px;min-width:100px;padding:0 8px">
<div style="width:44px;height:44px;border-radius:12px;background:rgba(0,0,0,0.15);border:1px solid rgba(0,0,0,0.25);display:flex;align-items:center;justify-content:center;font-size:20px"><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>
<div style="width:44px;height:44px;border-radius: var(--radius-md);background:rgba(0,0,0,0.15);border:1px solid rgba(0,0,0,0.25);display:flex;align-items:center;justify-content:center;font-size:20px"><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>
<div style="font-size:11px;font-weight:800;color: #0A0A0A;letter-spacing:.04em">You decide</div>
<div style="font-size:10px;color:rgba(0,0,0,0.75);text-align:center;line-height:1.4">Act on what&rsquo;s actually happening</div>
</div>
@@ -1896,42 +1944,42 @@ html,body{overflow-x:clip}
<div class="section-label" style="color:#0066FF">Advanced intelligence</div>
<h2 class="section-title">Most systems confirm what you already believe.<br>Landvex tells you when you're wrong.</h2>
<p class="section-sub" style="color:#515154;margin:0 auto;max-width:600px">The most valuable intelligence is not confirmation — it's contradiction. Landvex actively searches for conflicts between official narratives and observed reality, so you can correct course before it costs you.</p>
<p style="color:rgba(0,0,0,.9);font-size:.8rem;margin-top:8px;max-width:500px;margin-left:auto;margin-right:auto;background:rgba(255,149,0,.08);border:1px solid rgba(255,149,0,.25);border-radius:8px;padding:8px 12px"> All contradiction analysis shown is representative data based on real observed patterns. Live intelligence from August 2026. Reports about specific named locations are based on observed field data and explicitly labelled as analytical intelligence — not statements of fact.</p>
<p style="color:rgba(0,0,0,.9);font-size:.8rem;margin-top:8px;max-width:500px;margin-left:auto;margin-right:auto;background:rgba(255,149,0,.08);border:1px solid rgba(255,149,0,.25);border-radius: var(--radius-md);padding:8px 12px"> All contradiction analysis shown is representative data based on real observed patterns. Live intelligence from August 2026. Reports about specific named locations are based on observed field data and explicitly labelled as analytical intelligence — not statements of fact.</p>
</div>
<div style="background:#ffffff;border:1px solid rgba(0,0,0,.08);border-radius:16px;padding:36px 40px;margin-bottom:32px">
<div style="background:#ffffff;border:1px solid rgba(0,0,0,.08);border-radius: var(--radius-lg);padding:36px 40px;margin-bottom:32px">
<div style="display:flex;align-items:flex-start;gap:16px;margin-bottom:24px">
<span style="display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;background:rgba(220,38,38,.08);border-radius:8px"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#f87171" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg></span>
<span style="display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;background:rgba(220,38,38,.08);border-radius: 8px"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#f87171" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg></span>
<div>
<div style="background:#cc2222;color: #0A0A0A;font-size:.65rem;font-weight:800;text-transform:uppercase;letter-spacing:.1em;padding:3px 8px;border-radius:4px;display:inline-block;margin-bottom:8px">Representative data — based on real observed patterns</div><div style="color:#cc2222;font-weight:800;font-size:.9375rem;margin-bottom:4px">Narrative Conflict Detected — City B (sample)</div>
<div style="background:#cc2222;color: #0A0A0A;font-size:.65rem;font-weight:800;text-transform:uppercase;letter-spacing:.1em;padding:3px 8px;border-radius: var(--radius-sm);display:inline-block;margin-bottom:8px">Representative data — based on real observed patterns</div><div style="color:#cc2222;font-weight:800;font-size:.9375rem;margin-bottom:4px">Narrative Conflict Detected — City B (sample)</div>
<div style="color:#515154;font-size:.875rem;line-height:1.6">Official growth indicators are positive. Observed commercial activity is declining. 7 contradicting signals vs 3 supporting signals.</div>
</div>
</div>
<div class="contradiction-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:16px">
<div style="background:rgba(34,197,94,.15);border:1px solid rgba(34,197,94,.3);border-radius:10px;padding:16px">
<div style="background:rgba(34,197,94,.15);border:1px solid rgba(34,197,94,.3);border-radius: var(--radius-md);padding:16px">
<div style="color:#0d5c1d;font-size:.75rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;margin-bottom:10px">Official narrative</div>
<ul style="list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:6px">
<li style="color:#1d1d1f;font-size:.875rem"> GDP growth +3.2%</li>
<li style="color:#1d1d1f;font-size:.875rem"> Construction permits up</li>
<li style="color:#1d1d1f;font-size:.875rem"> Property prices rising</li>
<li style="color:#1d1d1f;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> GDP growth +3.2%</li>
<li style="color:#1d1d1f;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> Construction permits up</li>
<li style="color:#1d1d1f;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> Property prices rising</li>
</ul>
</div>
<div style="background:rgba(239,68,68,.15);border:1px solid rgba(239,68,68,.3);border-radius:10px;padding:16px">
<div style="background:rgba(239,68,68,.15);border:1px solid rgba(239,68,68,.3);border-radius: var(--radius-md);padding:16px">
<div style="color:#7f1d1d;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:#1d1d1f;font-size:.875rem"> Vacancies +18% this quarter</li>
<li style="color:#1d1d1f;font-size:.875rem"> Foot traffic down 12%</li>
<li style="color:#1d1d1f;font-size:.875rem"> 23 closures, 8 openings</li>
<li style="color:#1d1d1f;font-size:.875rem"> Maintenance deferred on 4 blocks</li>
<li style="color:#1d1d1f;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> Vacancies +18% this quarter</li>
<li style="color:#1d1d1f;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> Foot traffic down 12%</li>
<li style="color:#1d1d1f;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> 23 closures, 8 openings</li>
<li style="color:#1d1d1f;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> Maintenance deferred on 4 blocks</li>
</ul>
</div>
</div>
<div style="margin-top:20px;padding-top:20px;border-top:1px solid rgba(0,0,0,.1);display:flex;justify-content:space-between;align-items:center">
<span style="color:#515154;font-size:.8125rem">Confidence in official narrative <em style="font-size:.75rem;opacity:.85;font-weight:600"> sample</em></span>
<span style="color:#cc2222;font-weight:800;font-size:1.125rem">34% <span style="font-size:.75rem;font-weight:600;opacity:.85"> representative</span></span>
<span style="color:#515154;font-size:.8125rem">Confidence in official narrative <em style="font-size:.75rem;opacity:.85;font-weight:600"> sample</em></span>
<span style="color:#cc2222;font-weight:800;font-size:1.125rem">34% <span style="font-size:.75rem;font-weight:600;opacity:.85"> representative</span></span>
</div>
</div>
<div class="howwework-grid" style="display:grid;grid-template-columns:repeat(3,1fr);gap:2px;background:rgba(0,0,0,.05);border-radius:12px;overflow:hidden;margin-top:32px">
<div class="howwework-grid" style="display:grid;grid-template-columns:repeat(3,1fr);gap:2px;background:rgba(0,0,0,.05);border-radius: var(--radius-md);overflow:hidden;margin-top:32px">
<div style="background:#ffffff;padding:28px 32px;display:flex;flex-direction:column;gap:12px">
<div style="font-size:.6875rem;font-weight:800;color:#0066FF;text-transform:uppercase;letter-spacing:.12em">Intelligence</div>
<div style="color:#1d1d1f;font-weight:800;font-size:1rem;letter-spacing:-.02em;line-height:1.25">Show me what I'm missing</div>
@@ -1993,7 +2041,7 @@ html,body{overflow-x:clip}
<h2 class="section-title">Contribution Mode.<br>Train intelligence by confirming reality.</h2>
<p class="section-sub" style="margin:0 auto;max-width:600px">Instead of asking "What is this?", AI asks: "I think there's damage here, but I'm only 62% sure. Can you confirm?" Every validation permanently improves the platform.</p>
</div>
<div class="how-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:2px;background:rgba(0,0,0,.06);border-radius:16px;overflow:hidden">
<div class="how-grid" style="display:grid;grid-template-columns:1fr 1fr;gap:2px;background:rgba(0,0,0,.06);border-radius: var(--radius-lg);overflow:hidden">
<div style="background:#f5f5f7;padding:48px 44px;position:relative;border:1px solid rgba(0,0,0,0.08)">
<div style="font-size:.6875rem;font-weight:800;color:#0066FF;text-transform:uppercase;letter-spacing:.14em;margin-bottom:20px">Micro Validation</div>
<h3 style="font-size:1.375rem;font-weight:800;color:#0A0A0A;letter-spacing:-.03em;margin-bottom:12px;line-height:1.2">2-second confirmations</h3>
@@ -2378,7 +2426,7 @@ html,body{overflow-x:clip}
});
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 {