Files
boc/quixzoom-landing-fixed/zoomer-start.html
T

584 lines
18 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>Become a Zoomer — quiXzoom</title>
<link rel="stylesheet" >
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: var(--font-text, -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif);
background: var(--bg-primary, #000);
color: var(--label-primary, #fff);
min-height: 100dvh;
padding-top: env(safe-area-inset-top, 44px);
padding-bottom: env(safe-area-inset-bottom, 34px);
-webkit-font-smoothing: antialiased;
}
/* Nav Bar */
.nav-bar {
position: sticky;
top: 0;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
height: 44px;
padding: 0 16px;
background: rgba(242,242,247,0.82);
backdrop-filter: saturate(180%) blur(20px);
-webkit-backdrop-filter: saturate(180%) blur(20px);
border-bottom: 0.5px solid rgba(255,255,255,0.12);
}
.nav-bar .nav-logo {
font-family: var(--font-display, -apple-system, BlinkMacSystemFont, "SF Pro Display", sans-serif);
font-size: 17px;
font-weight: 600;
letter-spacing: -0.41px;
background: linear-gradient(135deg, #007AFF 0%, #5856D6 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Hero */
.hero {
padding: 48px 20px 32px;
text-align: center;
}
.hero-badge {
display: inline-block;
background: rgba(0,122,255,0.15);
border: 0.5px solid rgba(0,122,255,0.4);
color: #007AFF;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
padding: 5px 14px;
border-radius: var(--radius-xl);
margin-bottom: 20px;
}
.hero h1 {
font-family: var(--font-display, -apple-system, BlinkMacSystemFont, "SF Pro Display", sans-serif);
font-size: 34px;
font-weight: 700;
line-height: 1.12;
letter-spacing: -0.8px;
margin-bottom: 16px;
}
.hero h1 .accent {
background: linear-gradient(135deg, #007AFF 0%, #5856D6 50%, #AF52DE 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero p {
font-size: 17px;
line-height: 1.5;
color: rgba(60,60,67,0.7);
max-width: 340px;
margin: 0 auto 28px;
}
/* Earnings Banner */
.earnings-card {
margin: 0 20px 32px;
background: linear-gradient(135deg, rgba(52,199,89,0.15) 0%, rgba(0,122,255,0.10) 100%);
border: 0.5px solid rgba(52,199,89,0.3);
border-radius: var(--radius-lg);
padding: 20px;
text-align: center;
}
.earnings-card .amount {
font-family: var(--font-display, -apple-system, "SF Pro Display", sans-serif);
font-size: 42px;
font-weight: 700;
letter-spacing: -1px;
color: #34C759;
}
.earnings-card .amount-label {
font-size: 13px;
color: rgba(255,255,255,0.75);
margin-top: 4px;
}
/* 3-Step How It Works */
.section-title {
font-family: var(--font-display, -apple-system, "SF Pro Display", sans-serif);
font-size: 22px;
font-weight: 700;
letter-spacing: -0.4px;
padding: 0 20px;
margin-bottom: 16px;
}
.steps {
padding: 0 20px;
display: flex;
flex-direction: column;
gap: 12px;
margin-bottom: 36px;
}
.step-card {
display: flex;
align-items: flex-start;
gap: 16px;
background: rgba(255,255,255,0.06);
border: 0.5px solid rgba(255,255,255,0.1);
border-radius: var(--radius-lg);
padding: 18px 16px;
transition: background 0.2s;
}
.step-card:active {
background: rgba(255,255,255,0.1);
}
.step-icon {
width: 44px;
height: 44px;
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
flex-shrink: 0;
}
.step-icon.blue { background: rgba(0,122,255,0.18); }
.step-icon.green { background: rgba(52,199,89,0.18); }
.step-icon.purple { background: rgba(88,86,214,0.18); }
.step-content .step-num {
font-size: 12px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: rgba(255,255,255,0.75);
margin-bottom: 4px;
}
.step-content .step-title {
font-size: 17px;
font-weight: 600;
letter-spacing: -0.3px;
margin-bottom: 4px;
}
.step-content .step-desc {
font-size: 15px;
color: rgba(255,255,255,0.75);
line-height: 1.4;
}
/* Live Missions */
.missions-section {
margin-bottom: 36px;
}
.missions-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
margin-bottom: 12px;
}
.live-dot {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
color: rgba(60,60,67,0.5);
}
.live-dot::before {
content: '';
width: 8px;
height: 8px;
border-radius: var(--radius-full);
background: #34C759;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.5; transform: scale(0.85); }
}
.missions-scroll {
display: flex;
gap: 12px;
overflow-x: auto;
padding: 0 20px 4px;
scrollbar-width: none;
-webkit-overflow-scrolling: touch;
}
.missions-scroll::-webkit-scrollbar { display: none; }
.mission-card {
flex: 0 0 260px;
background: rgba(255,255,255,0.07);
border: 0.5px solid rgba(255,255,255,0.1);
border-radius: var(--radius-lg);
padding: 16px;
}
.mission-type-badge {
display: inline-flex;
align-items: center;
gap: 5px;
font-size: 12px;
font-weight: 600;
padding: 3px 10px;
border-radius: var(--radius-md);
margin-bottom: 10px;
}
.mission-type-badge.facade { background: rgba(88,86,214,0.2); color: #5856D6; }
.mission-type-badge.roof { background: rgba(255,149,0,0.2); color: #FF9500; }
.mission-type-badge.road { background: rgba(90,200,250,0.2); color: #5AC8FA; }
.mission-type-badge.water { background: rgba(255,45,85,0.2); color: #FF2D55; }
.mission-card h3 {
font-size: 15px;
font-weight: 600;
letter-spacing: -0.2px;
margin-bottom: 6px;
line-height: 1.3;
}
.mission-card .mission-meta {
font-size: 13px;
color: rgba(60,60,67,0.5);
margin-bottom: 12px;
}
.mission-reward {
font-size: 22px;
font-weight: 700;
color: #34C759;
letter-spacing: -0.4px;
}
.mission-reward span {
font-size: 14px;
font-weight: 500;
color: rgba(52,199,89,0.7);
}
/* CTA Buttons */
.cta-section {
padding: 0 20px;
margin-bottom: 40px;
}
.btn-primary {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 56px;
background: #007AFF;
color: #fff;
border: none;
border-radius: var(--radius-lg);
font-family: var(--font-text, -apple-system, sans-serif);
font-size: 17px;
font-weight: 600;
letter-spacing: -0.2px;
cursor: pointer;
text-decoration: none;
transition: opacity 0.15s;
margin-bottom: 12px;
}
.btn-primary:active { opacity: 0.8; }
.btn-secondary {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 50px;
background: rgba(255,255,255,0.08);
color: rgba(255,255,255,0.85);
border: 0.5px solid rgba(255,255,255,0.15);
border-radius: var(--radius-lg);
font-size: 16px;
font-weight: 500;
cursor: pointer;
text-decoration: none;
transition: background 0.15s;
}
.btn-secondary:active { background: rgba(255,255,255,0.14); }
/* Stats Strip */
.stats-strip {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1px;
background: rgba(255,255,255,0.08);
border-radius: var(--radius-lg);
margin: 0 20px 36px;
overflow: hidden;
border: 0.5px solid rgba(255,255,255,0.1);
}
.stat {
background: rgba(255,255,255,0.04);
padding: 16px 12px;
text-align: center;
}
.stat-value {
font-family: var(--font-display, -apple-system, "SF Pro Display", sans-serif);
font-size: 22px;
font-weight: 700;
letter-spacing: -0.4px;
margin-bottom: 4px;
}
.stat-label {
font-size: 12px;
color: rgba(255,255,255,0.75);
}
/* FAQ / Trust */
.trust-section {
padding: 0 20px;
margin-bottom: 48px;
}
.trust-item {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 0;
border-bottom: 0.5px solid rgba(255,255,255,0.08);
font-size: 15px;
color: rgba(255,255,255,0.75);
}
.trust-item:last-child { border-bottom: none; }
.trust-icon {
width: 32px;
height: 32px;
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
flex-shrink: 0;
background: rgba(52,199,89,0.15);
}
/* Loading state for missions */
.missions-loading {
padding: 0 20px;
color: rgba(255,255,255,0.75);
font-size: 15px;
}
@media (max-width: 640px) {
.hero h1 { font-size: 2rem !important; }
.hero p { font-size: 1rem !important; }
.card { padding: 1.5rem !important; }
.grid { grid-template-columns: 1fr !important; }
.btn { padding: 0.75rem 1.5rem !important; font-size: 1rem !important; }
}
</style>
<style id="wcag-contrast-enforcement">
/* AAMOS GLOBAL CONTRAST ENFORCEMENT — WCAG AA (4.5:1 minimum) */
/* Regel: Ingen text under 70% opacity. Aldrig. */
body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
/* Fix common low-contrast patterns */
[style*="rgba(60,60,67,0.4)"] { color: rgba(60,60,67,0.65) !important; }
[style*="rgba(60,60,67,0.3)"] { color: rgba(60,60,67,0.65) !important; }
[style*="rgba(255,255,255,0.4)"] { color: rgba(255,255,255,0.72) !important; }
[style*="rgba(255,255,255,0.3)"] { color: rgba(255,255,255,0.72) !important; }
[style*="opacity: 0.4"] { opacity: 0.72 !important; }
[style*="opacity: 0.3"] { opacity: 0.72 !important; }
@media (max-width: 640px) {
.hero h1 { font-size: 2rem !important; }
.hero p { font-size: 1rem !important; }
.card { padding: 1.5rem !important; }
.grid { grid-template-columns: 1fr !important; }
.btn { padding: 0.75rem 1.5rem !important; font-size: 1rem !important; }
}
</style>
<script src="i18n.js"></script>
<meta property="og:type" content="website">
<meta property="og:title" content="Become a Zoomer — quiXzoom">
<meta property="og:description" content="quiXzoom — Earn per Mission. No Platform Fee.">
<meta property="og:url" content="https://www.quixzoom.com/zoomer-start.html">
<meta property="og:image" content="https://www.quixzoom.com/images/app-screenshot.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="quiXzoom — start earning as a Zoomer today">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="https://www.quixzoom.com/images/app-screenshot.jpg">
<meta name="twitter:title" content="Become a Zoomer — quiXzoom">
</head>
<body>
<!-- Nav Bar -->
<div class="nav-bar">
<span class="nav-logo">quiXzoom</span>
</div>
<!-- Hero -->
<section class="hero">
<div class="hero-badge"> Launching August 2026</div>
<h1>Earn money on<br><span class="accent">what you see around you</span></h1>
<p>Take photo missions near you. Get paid fast. No boss, no invoicing.</p>
</section>
<!-- Earnings Banner -->
<div class="earnings-card">
<div class="amount">900 4 500 kr</div>
<div class="amount-label">per mission · paid out within 48h</div>
</div>
<!-- Stats -->
<div class="stats-strip">
<div class="stat">
<div class="stat-value" id="stat-missions">4</div>
<div class="stat-label">Open missions</div>
</div>
<div class="stat">
<div class="stat-value">48h</div>
<div class="stat-label">Payout time</div>
</div>
<div class="stat">
<div class="stat-value">2 100</div>
<div class="stat-label">Avg per mission</div>
</div>
</div>
<!-- How It Works -->
<p class="section-title">How it works</p>
<div class="steps">
<div class="step-card">
<div class="step-icon blue"><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></div>
<div class="step-content">
<div class="step-num">Step 1</div>
<div class="step-title">Find missions near you</div>
<div class="step-desc">Open the map and find missions in your area — facade scans, roof photos, road inspections.</div>
</div>
</div>
<div class="step-card">
<div class="step-icon green"></div>
<div class="step-content">
<div class="step-num">Step 2</div>
<div class="step-title">Complete the mission</div>
<div class="step-desc">Head over, take the photos as briefed. Upload directly from the app. Usually 1545 min.</div>
</div>
</div>
<div class="step-card">
<div class="step-icon purple"></div>
<div class="step-content">
<div class="step-num">Step 3</div>
<div class="step-title">Get paid</div>
<div class="step-desc">When the mission is approved, your payment is released immediately. No middlemen.</div>
</div>
</div>
</div>
<!-- Live Missions -->
<div class="missions-section">
<div class="missions-header">
<p class="section-title" style="padding:0;margin:0">Live missions</p>
<div class="live-dot">Live</div>
</div>
<div class="missions-scroll" id="missions-container">
<div class="mission-card" style="opacity:0.5;text-align:center;padding:24px">
<div style="font-size:24px;margin-bottom:8px"></div>
<div style="font-size:14px;color:#aaa">Loading missions near you...</div>
</div>
</div>
</div>
<!-- Trust signals -->
<div class="trust-section">
<p class="section-title" style="padding:0;margin-bottom:12px">Always included</p>
<div class="trust-item">
<div class="trust-icon"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="9" stroke="#22c55e" stroke-width="2"/><path d="M6 10L9 13L14 7" stroke="#22c55e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
Clear brief — you know exactly what to do
</div>
<div class="trust-item">
<div class="trust-icon"></div>
Secure payout via Stripe Connect
</div>
<div class="trust-item">
<div class="trust-icon"></div>
No special gear — a smartphone is enough
</div>
<div class="trust-item">
<div class="trust-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 2L5 9H8L7 14L11 7H8L9 2Z" fill="#f59e0b"/></svg></div>
Approval and payment within 48 hours
</div>
<div class="trust-item">
<div class="trust-icon"></div>
Choose which missions you take
</div>
</div>
<!-- CTA -->
<div class="cta-section">
<a href="/join" class="btn-primary">
Register as a Zoomer →
</a>
<a href="/map" class="btn-secondary">
View missions on map
</a>
</div>
<script>
const API_BASE = 'https://api.quixzoom.com/api/qz';
function missionEmoji(t){
if(/elledn|kabel|transfor/i.test(t)) return '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 2L5 9H8L7 14L11 7H8L9 2Z" fill="#f59e0b"/></svg>';
if(/vag|potthal|trottoar/i.test(t)) return '';
if(/kanal|bro/i.test(t)) return '';
if(/gatuliv|neon/i.test(t)) return '';
return '';
}
function renderMissions(missions){
const c=document.getElementById('missions-container');
if(!missions.length){c.innerHTML='<div style="text-align:center;padding:24px;color:#aaa;font-size:14px"> No missions near you right now</div>';return;}
c.innerHTML=missions.slice(0,6).map(m=>{
const d=m.distance_meters<1000?Math.round(m.distance_meters)+'m':(m.distance_meters/1000).toFixed(1)+'km';
return '<div class="mission-card" onclick="location.href=\''/zoomer-onboarding-flow\'" style="cursor:pointer">'
+'<div class="mission-type-badge road">'+missionEmoji(m.title)+' '+(m.area_name||'Mission')+'</div>'
+'<h3>'+m.title+'</h3>'
+'<div class="mission-meta"> '+d+' away · '+(m.required_photos||1)+' photo</div>'
+'<div class="mission-reward">'+m.reward_credits+' cr<span> on approval</span></div>'
+'</div>';
}).join('');
const el=document.getElementById('stat-missions');
if(el&&missions.length>0) el.textContent=missions.length+'+';
}
function load(lat,lng){
const url=lat?`${API_BASE}/missions?lat=${lat}&lng=${lng}&radius=15&limit=20`:`${API_BASE}/missions?lat=59.33&lng=18.07&radius=15&limit=20`;
fetch(url).then(r=>r.json()).then(d=>renderMissions(d.missions||[])).catch(()=>{});
}
if(navigator.geolocation){navigator.geolocation.getCurrentPosition(p=>load(p.coords.latitude,p.coords.longitude),()=>load(null,null),{timeout:5000});}
else load(null,null);
</script>
</body>
</html>