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
+11 -11
View File
@@ -17,17 +17,17 @@
.hero { background: #fff; padding: 80px 24px; text-align: center; }
.hero h1 { font-size: 48px; font-weight: 700; margin-bottom: 16px; }
.hero p { font-size: 20px; color: #86868b; max-width: 600px; margin: 0 auto 32px; }
.btn { display: inline-block; padding: 14px 28px; border-radius: 8px; font-size: 16px; font-weight: 500; text-decoration: none; transition: all 0.2s; }
.btn { display: inline-block; padding: 14px 28px; border-radius: var(--radius-md); font-size: 16px; font-weight: 500; text-decoration: none; transition: all 0.2s; }
.btn-primary { background: #0071e3; color: #fff; }
.btn-primary:hover { background: #0077ed; }
.features { padding: 64px 24px; max-width: 1200px; margin: 0 auto; }
.features-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 32px; margin-top: 48px; }
.feature { background: #fff; padding: 32px; border-radius: 16px; }
.feature { background: #fff; padding: 32px; border-radius: var(--radius-lg); }
.feature h3 { font-size: 20px; font-weight: 600; margin-bottom: 12px; }
.feature p { color: #86868b; }
.countries { padding: 64px 24px; background: #fff; }
.countries-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; max-width: 1200px; margin: 32px auto 0; }
.country { padding: 20px; border: 1px solid #d2d2d7; border-radius: 12px; text-align: center; }
.country { padding: 20px; border: 1px solid #d2d2d7; border-radius: var(--radius-md); text-align: center; }
.country a { color: #0071e3; text-decoration: none; font-weight: 500; }
.footer { background: #1d1d1f; color: #fff; padding: 40px 24px; text-align: center; }
@media (max-width: 640px) {
@@ -67,11 +67,11 @@
<p>Deploy inspection missions to qualified Zoomers near your infrastructure assets.</p>
</div>
<div class="feature">
<h3>📸 Visual Evidence</h3>
<h3> Visual Evidence</h3>
<p>Receive geolocated, timestamped imagery with AI-extracted structural features.</p>
</div>
<div class="feature">
<h3>🔍 Defect Detection</h3>
<h3><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="7" cy="7" r="5" stroke="#666" stroke-width="2"/><path d="M11 11L14 14" stroke="#666" stroke-width="2" stroke-linecap="round"/></svg> Defect Detection</h3>
<p>Automatic identification of cracks, corrosion, deformation, and wear patterns.</p>
</div>
<div class="feature">
@@ -83,7 +83,7 @@
<p>Real-time notifications when critical defects are detected or conditions worsen.</p>
</div>
<div class="feature">
<h3>📈 Predictive Analytics</h3>
<h3><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> Predictive Analytics</h3>
<p>Forecast degradation timelines and optimize maintenance scheduling.</p>
</div>
</div>
@@ -92,11 +92,11 @@
<section class="countries">
<h2 style="text-align: center; font-size: 32px;">Available In</h2>
<div class="countries-grid">
<div class="country"><a href="/bridge-inspection/sweden/">🇸🇪 Sweden</a></div>
<div class="country"><a href="/bridge-inspection/germany/">🇩🇪 Germany</a></div>
<div class="country"><a href="/bridge-inspection/france/">🇫🇷 France</a></div>
<div class="country"><a href="/bridge-inspection/uk/">🇬🇧 United Kingdom</a></div>
<div class="country"><a href="/bridge-inspection/netherlands/">🇳🇱 Netherlands</a></div>
<div class="country"><a href="/bridge-inspection/sweden/"><span class="flag-se">SE</span> Sweden</a></div>
<div class="country"><a href="/bridge-inspection/germany/"> Germany</a></div>
<div class="country"><a href="/bridge-inspection/france/"> France</a></div>
<div class="country"><a href="/bridge-inspection/uk/"> United Kingdom</a></div>
<div class="country"><a href="/bridge-inspection/netherlands/"> Netherlands</a></div>
</div>
</section>
@@ -18,7 +18,7 @@
.content h2 { font-size: 24px; margin-bottom: 16px; }
.content p { color: #86868b; margin-bottom: 16px; }
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin: 32px 0; }
.stat { background: #fff; padding: 24px; border-radius: 12px; text-align: center; }
.stat { background: #fff; padding: 24px; border-radius: var(--radius-md); text-align: center; }
.stat-value { font-size: 32px; font-weight: 700; color: #0071e3; }
.stat-label { font-size: 14px; color: #86868b; margin-top: 8px; }
.footer { background: #1d1d1f; color: #fff; padding: 40px 24px; text-align: center; margin-top: 48px; }
@@ -37,7 +37,7 @@
</header>
<section class="hero">
<h1>🇸🇪 Bridge Inspection Sweden</h1>
<h1><span class="flag-se">SE</span> Bridge Inspection Sweden</h1>
<p>Comprehensive bridge assessment services across Sweden using AI and crowdsourced field data.</p>
</section>