Files
boc/landvex-site/landvex-admin.html
T

1303 lines
49 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="sv">
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<title>LandveX Admin — Infrastrukturportal</title>
<link rel="stylesheet" >
<style>
/*
LANDVEX ADMIN PORTAL — iOS Native
Wavult Group · 2026
*/
* { box-sizing: border-box; margin: 0; padding: 0; -webkit-font-smoothing: antialiased; }
body {
font-family: var(--font-text);
background: var(--background-secondary);
color: var(--label-primary);
min-height: 100vh;
}
/* NAVIGATION BAR */
.nav-bar {
position: sticky;
top: 0;
z-index: 100;
height: 44px;
background: var(--glass-bg);
backdrop-filter: var(--glass-blur);
-webkit-backdrop-filter: var(--glass-blur);
border-bottom: 0.5px solid var(--separator);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
safe-area-inset-top: env(safe-area-inset-top);
}
.nav-title {
font-family: var(--font-display);
font-size: 17px;
font-weight: 600;
letter-spacing: -0.4px;
color: var(--label-primary);
}
.nav-logo {
display: flex;
align-items: center;
gap: 8px;
}
.nav-logo .logo-icon {
width: 28px;
height: 28px;
background: linear-gradient(135deg, #007AFF 0%, #0055CC 100%);
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: white;
font-weight: 700;
letter-spacing: -0.5px;
}
.badge-admin {
font-size: 11px;
font-weight: 600;
padding: 3px 8px;
background: rgba(255, 149, 0, 0.15);
color: var(--ios-orange);
border-radius: var(--radius-xl);
letter-spacing: 0.3px;
}
/* CONTENT */
.content {
padding: 0 16px 120px;
max-width: 1100px;
margin: 0 auto;
}
/* SECTION HEADER */
.section-header {
padding: 20px 0 8px;
font-family: var(--font-display);
font-size: 20px;
font-weight: 700;
letter-spacing: -0.4px;
color: var(--label-primary);
}
.section-header-large {
padding: 28px 0 4px;
font-family: var(--font-display);
font-size: 28px;
font-weight: 700;
letter-spacing: -0.5px;
}
.section-sub {
font-size: 15px;
color: var(--label-secondary);
padding-bottom: 12px;
}
/* METRICS GRID */
.metrics-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 12px;
margin-bottom: 8px;
}
.metric-card {
background: var(--background-primary);
border-radius: var(--radius-lg);
padding: 16px;
border: 0.5px solid var(--separator);
}
.metric-value {
font-family: var(--font-display);
font-size: 32px;
font-weight: 700;
letter-spacing: -1px;
line-height: 1;
margin-bottom: 4px;
}
.metric-label {
font-size: 13px;
color: var(--label-secondary);
font-weight: 500;
}
.metric-trend {
font-size: 12px;
font-weight: 600;
margin-top: 6px;
}
.trend-up { color: var(--ios-green); }
.trend-down { color: var(--ios-red); }
.trend-flat { color: var(--label-tertiary); }
.metric-blue .metric-value { color: var(--ios-blue); }
.metric-green .metric-value { color: var(--ios-green); }
.metric-orange .metric-value { color: var(--ios-orange); }
.metric-red .metric-value { color: var(--ios-red); }
/* TABLE */
.table-card {
background: var(--background-primary);
border-radius: var(--radius-lg);
border: 0.5px solid var(--separator);
overflow: hidden;
margin-bottom: 12px;
}
.table-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px 16px;
border-bottom: 0.5px solid var(--separator);
}
.table-title {
font-size: 17px;
font-weight: 600;
letter-spacing: -0.3px;
}
.table-action {
font-size: 15px;
color: var(--ios-blue);
font-weight: 500;
cursor: pointer;
background: none;
border: none;
padding: 0;
}
.table-scroll {
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
thead th {
text-align: left;
padding: 8px 16px;
font-size: 12px;
font-weight: 600;
color: var(--label-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
background: var(--background-secondary);
border-bottom: 0.5px solid var(--separator);
}
tbody tr {
border-bottom: 0.5px solid var(--separator);
transition: background 0.15s;
cursor: pointer;
}
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--fill-quaternary); }
tbody td {
padding: 12px 16px;
vertical-align: middle;
}
.td-name {
font-weight: 600;
letter-spacing: -0.2px;
}
.td-sub {
font-size: 12px;
color: var(--label-secondary);
margin-top: 2px;
}
/* STATUS BADGES */
.status-badge {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
font-weight: 600;
padding: 4px 10px;
border-radius: var(--radius-xl);
}
.status-ok {
background: rgba(52, 199, 89, 0.15);
color: var(--ios-green);
}
.status-warn {
background: rgba(255, 149, 0, 0.15);
color: var(--ios-orange);
}
.status-critical {
background: rgba(255, 59, 48, 0.15);
color: var(--ios-red);
}
.status-pending {
background: rgba(142, 142, 147, 0.15);
color: var(--ios-gray);
}
.status-dot {
width: 6px;
height: 6px;
border-radius: var(--radius-full);
background: currentColor;
}
/* RISK SCORE */
.risk-bar-wrap {
display: flex;
align-items: center;
gap: 8px;
}
.risk-bar {
flex: 1;
height: 4px;
background: var(--fill-tertiary);
border-radius: var(--radius-sm);
overflow: hidden;
min-width: 60px;
}
.risk-fill {
height: 100%;
border-radius: var(--radius-sm);
transition: width 0.3s;
}
.risk-low .risk-fill { background: var(--ios-green); }
.risk-medium .risk-fill { background: var(--ios-orange); }
.risk-high .risk-fill { background: var(--ios-red); }
.risk-label {
font-size: 12px;
font-weight: 600;
min-width: 28px;
text-align: right;
}
/* MAP PLACEHOLDER */
.map-card {
background: var(--background-primary);
border-radius: var(--radius-lg);
border: 0.5px solid var(--separator);
overflow: hidden;
margin-bottom: 12px;
}
.map-container {
height: 320px;
background: #E8EDF2;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
@media (prefers-color-scheme: dark) {
.map-container { background: #1C2328; }
}
.map-overlay {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 8px;
color: var(--label-secondary);
}
.map-grid {
position: absolute;
inset: 0;
opacity: 0.3;
background-image:
linear-gradient(rgba(0,122,255,0.3) 1px, transparent 1px),
linear-gradient(90deg, rgba(0,122,255,0.3) 1px, transparent 1px);
background-size: 40px 40px;
}
.map-pin {
position: absolute;
width: 28px;
height: 28px;
border-radius: var(--radius-full) 50% 50% 0;
transform: rotate(-45deg);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
transition: transform 0.2s;
}
.map-pin:hover { transform: rotate(-45deg) scale(1.2); }
.map-pin-ok { background: var(--ios-green); }
.map-pin-warn { background: var(--ios-orange); }
.map-pin-critical { background: var(--ios-red); }
.map-pin-inner {
transform: rotate(45deg);
font-size: 11px;
color: white;
}
.map-legend {
position: absolute;
bottom: 12px;
right: 12px;
background: var(--glass-bg);
backdrop-filter: var(--glass-blur);
-webkit-backdrop-filter: var(--glass-blur);
border-radius: var(--radius-md);
padding: 8px 12px;
border: 0.5px solid var(--separator);
display: flex;
gap: 12px;
}
.legend-item {
display: flex;
align-items: center;
gap: 5px;
font-size: 11px;
color: var(--label-secondary);
}
.legend-dot {
width: 8px;
height: 8px;
border-radius: var(--radius-full);
}
/* FAB BUTTON */
.fab {
position: fixed;
bottom: calc(24px + env(safe-area-inset-bottom));
right: 20px;
z-index: 200;
background: var(--ios-blue);
color: white;
border: none;
border-radius: 28px;
height: 56px;
padding: 0 20px;
font-size: 15px;
font-weight: 600;
font-family: var(--font-text);
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
box-shadow: 0 4px 20px rgba(0, 122, 255, 0.4);
transition: transform 0.15s, box-shadow 0.15s;
}
.fab:hover {
transform: translateY(-2px);
box-shadow: 0 8px 28px rgba(0, 122, 255, 0.5);
}
.fab:active {
transform: translateY(0) scale(0.97);
box-shadow: 0 2px 12px rgba(0, 122, 255, 0.35);
}
/* INSPECTION CELLS */
.inspection-list {
background: var(--background-primary);
border-radius: var(--radius-lg);
border: 0.5px solid var(--separator);
overflow: hidden;
}
.inspection-item {
display: flex;
align-items: center;
padding: 14px 16px;
border-bottom: 0.5px solid var(--separator);
gap: 12px;
cursor: pointer;
transition: background 0.15s;
}
.inspection-item:last-child { border-bottom: none; }
.inspection-item:hover { background: var(--fill-quaternary); }
.inspection-icon {
width: 40px;
height: 40px;
border-radius: var(--radius-md);
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
flex-shrink: 0;
}
.inspection-body { flex: 1; min-width: 0; }
.inspection-title {
font-size: 15px;
font-weight: 600;
letter-spacing: -0.2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.inspection-meta {
font-size: 13px;
color: var(--label-secondary);
margin-top: 2px;
}
.inspection-chevron {
font-size: 17px;
color: var(--label-tertiary);
flex-shrink: 0;
}
/* MODAL */
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(242,242,247,0.4);
backdrop-filter: blur(4px);
z-index: 300;
display: flex;
align-items: flex-end;
justify-content: center;
opacity: 0;
pointer-events: none;
transition: opacity 0.25s;
}
.modal-overlay.open {
opacity: 1;
pointer-events: all;
}
.modal-sheet {
background: var(--background-primary);
border-radius: var(--radius-xl) 20px 0 0;
width: 100%;
max-width: 640px;
padding: 8px 0 env(safe-area-inset-bottom);
transform: translateY(100%);
transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
}
.modal-overlay.open .modal-sheet {
transform: translateY(0);
}
.modal-handle {
width: 36px;
height: 4px;
background: var(--fill-primary);
border-radius: var(--radius-sm);
margin: 8px auto 16px;
}
.modal-title {
font-size: 20px;
font-weight: 700;
letter-spacing: -0.4px;
padding: 0 20px 16px;
border-bottom: 0.5px solid var(--separator);
}
.form-group {
padding: 16px 20px;
border-bottom: 0.5px solid var(--separator);
}
.form-label {
font-size: 13px;
font-weight: 600;
color: var(--label-secondary);
margin-bottom: 6px;
}
.form-input {
width: 100%;
padding: 10px 12px;
background: var(--background-secondary);
border: 0.5px solid var(--separator);
border-radius: var(--radius-md);
font-size: 15px;
font-family: var(--font-text);
color: var(--label-primary);
outline: none;
transition: border-color 0.2s;
}
.form-input:focus {
border-color: var(--ios-blue);
}
.form-select {
width: 100%;
padding: 10px 12px;
background: var(--background-secondary);
border: 0.5px solid var(--separator);
border-radius: var(--radius-md);
font-size: 15px;
font-family: var(--font-text);
color: var(--label-primary);
outline: none;
appearance: none;
cursor: pointer;
}
.modal-actions {
padding: 16px 20px;
display: flex;
gap: 10px;
}
.btn-primary {
flex: 1;
height: 50px;
background: var(--ios-blue);
color: white;
border: none;
border-radius: var(--radius-lg);
font-size: 17px;
font-weight: 600;
font-family: var(--font-text);
cursor: pointer;
transition: opacity 0.15s;
}
.btn-primary:active { opacity: 0.7; }
.btn-secondary {
flex: 1;
height: 50px;
background: var(--fill-secondary);
color: var(--label-primary);
border: none;
border-radius: var(--radius-lg);
font-size: 17px;
font-weight: 600;
font-family: var(--font-text);
cursor: pointer;
transition: opacity 0.15s;
}
.btn-secondary:active { opacity: 0.7; }
/* TAB BAR */
.tab-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: calc(49px + env(safe-area-inset-bottom));
padding-bottom: env(safe-area-inset-bottom);
background: var(--glass-bg);
backdrop-filter: var(--glass-blur);
-webkit-backdrop-filter: var(--glass-blur);
border-top: 0.5px solid var(--separator);
display: flex;
align-items: flex-start;
justify-content: space-around;
padding-top: 8px;
z-index: 90;
}
.tab-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
cursor: pointer;
flex: 1;
padding: 0 8px;
opacity: 0.6;
transition: opacity 0.15s;
}
.tab-item.active { opacity: 1; }
.tab-icon { font-size: 22px; }
.tab-label { font-size: 10px; font-weight: 500; }
.tab-item.active .tab-label { color: var(--ios-blue); }
.tab-item.active .tab-icon { filter: none; }
/* DARK MODE */
@media (prefers-color-scheme: dark) {
.map-container { background: #1A1E23; }
}
/* RESPONSIVE */
@media (min-width: 768px) {
.metrics-grid { grid-template-columns: repeat(4, 1fr); }
.content { padding: 0 24px 80px; }
}
@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(0,0,0,0.4)"] { color: rgba(0,0,0,0.72) !important; }
[style*="rgba(0,0,0,0.3)"] { color: rgba(0,0,0,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>
</head>
<body>
<!-- NAV BAR -->
<nav class="nav-bar">
<div class="nav-logo">
<div class="logo-icon">LX</div>
<span class="nav-title">LandveX Admin</span>
</div>
<div style="display:flex;align-items:center;gap:8px;">
<span class="badge-admin">ADMIN</span>
<div style="width:32px;height:32px;border-radius: var(--radius-full);background:linear-gradient(135deg,#007AFF,#0055CC);display:flex;align-items:center;justify-content:center;color:white;font-size:14px;font-weight:700;">A</div>
</div>
</nav>
<!-- MAIN CONTENT -->
<main class="content">
<!-- HEADER -->
<div class="section-header-large">Infrastrukturportal</div>
<div class="section-sub">LandveX · Administration · 18 maj 2026</div>
<!-- METRICS -->
<div class="section-header">Systemöversikt</div>
<div class="metrics-grid">
<div class="metric-card metric-blue">
<div class="metric-value">247</div>
<div class="metric-label">Registrerade objekt</div>
<div class="metric-trend trend-up">↑ 12 denna vecka</div>
</div>
<div class="metric-card metric-green">
<div class="metric-value">189</div>
<div class="metric-label">OK-status</div>
<div class="metric-trend trend-up">↑ 76%</div>
</div>
<div class="metric-card metric-orange">
<div class="metric-value">41</div>
<div class="metric-label">Kräver åtgärd</div>
<div class="metric-trend trend-flat">↔ Stabil</div>
</div>
<div class="metric-card metric-red">
<div class="metric-value">17</div>
<div class="metric-label">Kritiska</div>
<div class="metric-trend trend-down">↑ 3 sedan igår</div>
</div>
</div>
<!-- MAP -->
<div class="section-header">Live Operationell Karta</div>
<!-- LIVE MAP WITH ZOOMER POSITIONS -->
<div class="map-card" style="margin-bottom:12px;">
<div class="table-header">
<span class="table-title"> Realtids zoomers + objekt</span>
<button class="table-action" onclick="cycleZoomerPos()">↻ Uppdatera</button>
</div>
<div class="map-container" id="map" style="position:relative;min-height:260px;">
<div class="map-grid"></div>
<!-- Object pins -->
<div class="map-pin map-pin-ok" style="left:22%;top:30%;" title="Gamla Stan Bron · OK"><div class="map-pin-inner"><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></div></div>
<div class="map-pin map-pin-warn" style="left:45%;top:45%;" title="E4 Avsnitt 12 · Varning"><div class="map-pin-inner">!</div></div>
<div class="map-pin map-pin-critical" style="left:68%;top:25%;" title="E4 Älvsjö · Kritisk"><div class="map-pin-inner"></div></div>
<div class="map-pin map-pin-ok" style="left:35%;top:65%;" title="Arlanda Terminal 5 · OK"><div class="map-pin-inner"><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></div></div>
<div class="map-pin map-pin-warn" style="left:80%;top:55%;" title="Öresundsbron · Varning"><div class="map-pin-inner">!</div></div>
<div class="map-pin map-pin-ok" style="left:55%;top:72%;" title="Göta Älvbron · OK"><div class="map-pin-inner"><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></div></div>
<!-- Live zoomer pins -->
<div id="zoomer-lx01" style="position:absolute;left:48%;top:42%;z-index:10;transition:all 2s ease;">
<div style="background:var(--ios-blue);color: #1d1d1f;border-radius: var(--radius-full);width:28px;height:28px;display:flex;align-items:center;justify-content:center;font-size:14px;box-shadow:0 2px 8px rgba(0,122,255,0.5);animation:zoomer-pulse 2s infinite;"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg></div>
<div style="font-size:9px;font-weight:700;color:var(--ios-blue);text-align:center;margin-top:2px;background:rgba(0,0,0,0.9);border-radius: var(--radius-sm);padding:1px 4px;">LX-01</div>
</div>
<div id="zoomer-lx02" style="position:absolute;left:24%;top:27%;z-index:10;transition:all 2s ease;">
<div style="background:var(--ios-green);color: #1d1d1f;border-radius: var(--radius-full);width:28px;height:28px;display:flex;align-items:center;justify-content:center;font-size:14px;box-shadow:0 2px 8px rgba(52,199,89,0.5);"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg></div>
<div style="font-size:9px;font-weight:700;color:var(--ios-green);text-align:center;margin-top:2px;background:rgba(0,0,0,0.9);border-radius: var(--radius-sm);padding:1px 4px;">LX-02</div>
</div>
<div id="zoomer-lx03" style="position:absolute;left:72%;top:58%;z-index:10;transition:all 2s ease;">
<div style="background:var(--ios-orange);color: #1d1d1f;border-radius: var(--radius-full);width:28px;height:28px;display:flex;align-items:center;justify-content:center;font-size:14px;box-shadow:0 2px 8px rgba(255,149,0,0.5);"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg></div>
<div style="font-size:9px;font-weight:700;color:var(--ios-orange);text-align:center;margin-top:2px;background:rgba(0,0,0,0.9);border-radius: var(--radius-sm);padding:1px 4px;">LX-03 <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>
<!-- Live indicator -->
<div style="position:absolute;top:10px;left:10px;z-index:11;display:flex;align-items:center;gap:5px;background:rgba(0,0,0,0.9);border-radius: var(--radius-xl);padding:4px 10px;font-size:11px;font-weight:600;color:var(--ios-green);">
<div style="width:6px;height:6px;border-radius: var(--radius-full);background:var(--ios-green);animation:zoomer-pulse 2s infinite;"></div>
LIVE
</div>
<div class="map-legend">
<div class="legend-item"><div class="legend-dot" style="background:var(--ios-green)"></div>OK (189)</div>
<div class="legend-item"><div class="legend-dot" style="background:var(--ios-orange)"></div>Varning (41)</div>
<div class="legend-item"><div class="legend-dot" style="background:var(--ios-red)"></div>Kritisk (17)</div>
<div class="legend-item"><div class="legend-dot" style="background:var(--ios-blue)"></div><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg> Zoomer (3)</div>
</div>
</div>
</div>
<!-- UPPDRAGSSTATUS -->
<div class="section-header">Uppdragsstatus</div>
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:12px;">
<div class="metric-card metric-green">
<div class="metric-value">14</div>
<div class="metric-label">Pågående</div>
<div class="metric-trend trend-up"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg> Aktiva uppdrag</div>
</div>
<div class="metric-card metric-blue">
<div class="metric-value">218</div>
<div class="metric-label">Klart idag</div>
<div class="metric-trend trend-up">↑ 23% vs plan</div>
</div>
<div class="metric-card metric-orange">
<div class="metric-value">3</div>
<div class="metric-label">Avvikelse</div>
<div class="metric-trend trend-down">↓ Kräver åtgärd</div>
</div>
</div>
<!-- ACTIVE MISSIONS TABLE -->
<div class="table-card" style="margin-bottom:12px;">
<div class="table-header">
<span class="table-title"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 2L5 9H8L7 14L11 7H8L9 2Z" fill="#f59e0b"/></svg> Pågående uppdrag</span>
<button class="table-action" onclick="openDispatch()">Snabb-dispatch →</button>
</div>
<div class="table-scroll">
<table>
<thead><tr>
<th>Zoomer</th><th>Objekt</th><th>Status</th><th>Progress</th><th>ETA</th><th>Åtgärd</th>
</tr></thead>
<tbody>
<tr>
<td><span style="font-weight:600;color:var(--ios-blue);"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg> LX-01</span></td>
<td>E4 Avsnitt 12</td>
<td><span style="background:rgba(52,199,89,0.12);color:var(--ios-green);font-size:11px;font-weight:700;padding:3px 8px;border-radius: var(--radius-xl);">PÅGÅR</span></td>
<td>
<div style="width:80px;height:5px;background:var(--fill-tertiary);border-radius: var(--radius-sm);overflow:hidden;">
<div style="width:72%;height:100%;background:var(--ios-blue);border-radius: var(--radius-sm);"></div>
</div>
<div style="font-size:10px;color:var(--label-tertiary);margin-top:2px;">72%</div>
</td>
<td style="font-size:13px;">14 min</td>
<td><button style="font-size:12px;color:var(--ios-blue);background:none;border:none;cursor:pointer;padding:4px 0;">Följ live</button></td>
</tr>
<tr>
<td><span style="font-weight:600;color:var(--ios-green);"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg> LX-02</span></td>
<td>Gamla Stan Bron</td>
<td><span style="background:rgba(52,199,89,0.12);color:var(--ios-green);font-size:11px;font-weight:700;padding:3px 8px;border-radius: var(--radius-xl);">PÅGÅR</span></td>
<td>
<div style="width:80px;height:5px;background:var(--fill-tertiary);border-radius: var(--radius-sm);overflow:hidden;">
<div style="width:35%;height:100%;background:var(--ios-green);border-radius: var(--radius-sm);"></div>
</div>
<div style="font-size:10px;color:var(--label-tertiary);margin-top:2px;">35%</div>
</td>
<td style="font-size:13px;">38 min</td>
<td><button style="font-size:12px;color:var(--ios-blue);background:none;border:none;cursor:pointer;padding:4px 0;">Följ live</button></td>
</tr>
<tr>
<td><span style="font-weight:600;color:var(--ios-orange);"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg> LX-03</span></td>
<td>Öresundsbron S3</td>
<td><span style="background:rgba(255,149,0,0.12);color:var(--ios-orange);font-size:11px;font-weight:700;padding:3px 8px;border-radius: var(--radius-xl);">AVVIKELSE</span></td>
<td>
<div style="width:80px;height:5px;background:var(--fill-tertiary);border-radius: var(--radius-sm);overflow:hidden;">
<div style="width:58%;height:100%;background:var(--ios-orange);border-radius: var(--radius-sm);"></div>
</div>
<div style="font-size:10px;color:var(--label-tertiary);margin-top:2px;">58%</div>
</td>
<td style="font-size:13px;">Försenad</td>
<td><button style="font-size:12px;color:var(--ios-red);background:none;border:none;cursor:pointer;font-weight:600;padding:4px 0;" onclick="openDispatch()">Dispatch ny</button></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- KOSTNADSEFFEKTIVITET -->
<div class="section-header">Kostnadseffektivitet</div>
<div style="display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin-bottom:12px;">
<div class="metric-card metric-green">
<div class="metric-value">1 240</div>
<div class="metric-label">Pris/inspektion (SEK)</div>
<div class="metric-trend trend-up">↓ 62% vs marknad</div>
</div>
<div class="metric-card metric-blue">
<div class="metric-value">3 280</div>
<div class="metric-label">Marknadspris (SEK)</div>
<div class="metric-trend flat">→ Traditionell inspektion</div>
</div>
<div class="metric-card metric-green">
<div class="metric-value">218</div>
<div class="metric-label">Insp. idag</div>
<div class="metric-trend trend-up">Rekord <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#0066FF" stroke-width="2"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg></div>
</div>
<div class="metric-card metric-orange">
<div class="metric-value">270k</div>
<div class="metric-label">Besparing idag (SEK)</div>
<div class="metric-trend trend-up">↑ vs traditionellt</div>
</div>
</div>
<!-- PIPELINE -->
<div class="section-header">Inkommande beställningar</div>
<div class="table-card" style="margin-bottom:12px;">
<div class="table-header">
<span class="table-title">Pipeline · 7 väntande</span>
<button class="table-action">Hantera alla →</button>
</div>
<div class="table-scroll">
<table>
<thead><tr>
<th>Kund</th><th>Objekt</th><th>Typ</th><th>Prio</th><th>Mottagen</th><th>Åtgärd</th>
</tr></thead>
<tbody>
<tr>
<td style="font-weight:600;">Trafikverket</td><td>E4 Älvsjö · Kritisk</td><td>Fullständig</td>
<td><span style="background:rgba(255,59,48,0.12);color:var(--ios-red);font-size:11px;font-weight:700;padding:2px 7px;border-radius: var(--radius-xl);">KRITISK</span></td>
<td style="font-size:12px;color:var(--label-tertiary);">09:12</td>
<td><button style="font-size:12px;color: #1d1d1f;background:var(--ios-red);border:none;border-radius: var(--radius-md);padding:4px 12px;cursor:pointer;font-weight:600;" onclick="openDispatch()">Dispatch nu</button></td>
</tr>
<tr>
<td style="font-weight:600;">Region Stockholm</td><td>Gamla Stan Bro</td><td>Ytinspektion</td>
<td><span style="background:rgba(255,149,0,0.12);color:var(--ios-orange);font-size:11px;font-weight:700;padding:2px 7px;border-radius: var(--radius-xl);">HÖG</span></td>
<td style="font-size:12px;color:var(--label-tertiary);">08:45</td>
<td><button style="font-size:12px;color: #1d1d1f;background:var(--ios-orange);border:none;border-radius: var(--radius-md);padding:4px 12px;cursor:pointer;font-weight:600;" onclick="openDispatch()">Dispatch</button></td>
</tr>
<tr>
<td style="font-weight:600;">NCC Sverige</td><td>Rv 40 Borås</td><td>Strukturkontroll</td>
<td><span style="background:rgba(0,122,255,0.10);color:var(--ios-blue);font-size:11px;font-weight:700;padding:2px 7px;border-radius: var(--radius-xl);">NORMAL</span></td>
<td style="font-size:12px;color:var(--label-tertiary);">Igår</td>
<td><button style="font-size:12px;color:var(--ios-blue);background:none;border:1px solid var(--ios-blue);border-radius: var(--radius-md);padding:4px 12px;cursor:pointer;font-weight:600;">Schemalägg</button></td>
</tr>
<tr>
<td style="font-weight:600;">Ellevio AB</td><td>Kraftledning N32</td><td>Optisk scanning</td>
<td><span style="background:rgba(0,122,255,0.10);color:var(--ios-blue);font-size:11px;font-weight:700;padding:2px 7px;border-radius: var(--radius-xl);">NORMAL</span></td>
<td style="font-size:12px;color:var(--label-tertiary);">Igår</td>
<td><button style="font-size:12px;color:var(--ios-blue);background:none;border:1px solid var(--ios-blue);border-radius: var(--radius-md);padding:4px 12px;cursor:pointer;font-weight:600;">Schemalägg</button></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- KARTVY (original) -->
<div class="section-header" style="display:none;">Kartvy (Legacy)</div>
<!-- OBJECTS TABLE -->
<div class="section-header">Registrerade objekt</div>
<div class="table-card">
<div class="table-header">
<span class="table-title">Fastigheter & Infrastruktur</span>
<button class="table-action" onclick="openModal()">+ Nytt objekt</button>
</div>
<div class="table-scroll">
<table>
<thead>
<tr>
<th>Objekt</th>
<th>Typ</th>
<th>Status</th>
<th>Risk</th>
<th>Senaste inspektion</th>
<th>Nästa inspektion</th>
</tr>
</thead>
<tbody>
<tr onclick="alert('Öppnar objektdetaljer: E4 Norrtull')">
<td><div class="td-name">E4 Norrtull Avsnitt 12</div><div class="td-sub">REF-001 · Stockholm</div></td>
<td> Väg</td>
<td><span class="status-badge status-warn"><span class="status-dot"></span>Kräver åtgärd</span></td>
<td>
<div class="risk-bar-wrap risk-medium">
<div class="risk-bar"><div class="risk-fill" style="width:58%"></div></div>
<span class="risk-label">58</span>
</div>
</td>
<td>2026-05-10</td>
<td>2026-05-25</td>
</tr>
<tr onclick="alert('Öppnar objektdetaljer: Gamla Stan')">
<td><div class="td-name">Gamla Stan Bro</div><div class="td-sub">REF-002 · Stockholm</div></td>
<td> Bro</td>
<td><span class="status-badge status-ok"><span class="status-dot"></span>OK</span></td>
<td>
<div class="risk-bar-wrap risk-low">
<div class="risk-bar"><div class="risk-fill" style="width:22%"></div></div>
<span class="risk-label">22</span>
</div>
</td>
<td>2026-05-14</td>
<td>2026-08-14</td>
</tr>
<tr onclick="alert('Öppnar objektdetaljer: Kungliga Slottet')">
<td><div class="td-name">Kungliga Slottet Tak</div><div class="td-sub">REF-003 · Stockholm</div></td>
<td> Byggnad</td>
<td><span class="status-badge status-critical"><span class="status-dot"></span>Kritisk</span></td>
<td>
<div class="risk-bar-wrap risk-high">
<div class="risk-bar"><div class="risk-fill" style="width:87%"></div></div>
<span class="risk-label">87</span>
</div>
</td>
<td>2026-05-01</td>
<td> Omedelbart</td>
</tr>
<tr onclick="alert('Öppnar objektdetaljer: Arlanda Terminal 5')">
<td><div class="td-name">Arlanda Terminal 5</div><div class="td-sub">REF-004 · Sigtuna</div></td>
<td> Byggnad</td>
<td><span class="status-badge status-ok"><span class="status-dot"></span>OK</span></td>
<td>
<div class="risk-bar-wrap risk-low">
<div class="risk-bar"><div class="risk-fill" style="width:15%"></div></div>
<span class="risk-label">15</span>
</div>
</td>
<td>2026-05-16</td>
<td>2026-11-16</td>
</tr>
<tr onclick="alert('Öppnar objektdetaljer: Öresundsbron')">
<td><div class="td-name">Öresundsbron Sektion 3</div><div class="td-sub">REF-005 · Malmö</div></td>
<td> Bro</td>
<td><span class="status-badge status-warn"><span class="status-dot"></span>Kräver åtgärd</span></td>
<td>
<div class="risk-bar-wrap risk-medium">
<div class="risk-bar"><div class="risk-fill" style="width:63%"></div></div>
<span class="risk-label">63</span>
</div>
</td>
<td>2026-04-28</td>
<td>2026-05-20</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- INSPECTIONS -->
<div class="section-header">Senaste inspektioner</div>
<div class="inspection-list">
<div class="inspection-item">
<div class="inspection-icon" style="background:rgba(52,199,89,0.15)"><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>
<div class="inspection-body">
<div class="inspection-title">E4 Norrtull — Ytinspektion</div>
<div class="inspection-meta">Anna Lindqvist · 2026-05-10 · <span style="color:var(--ios-green)">Godkänd</span></div>
</div>
<div class="inspection-chevron"></div>
</div>
<div class="inspection-item">
<div class="inspection-icon" style="background:rgba(255,149,0,0.15)"></div>
<div class="inspection-body">
<div class="inspection-title">Öresundsbron — Strukturkontroll</div>
<div class="inspection-meta">Marcus Holm · 2026-04-28 · <span style="color:var(--ios-orange)">Åtgärder krävs</span></div>
</div>
<div class="inspection-chevron"></div>
</div>
<div class="inspection-item">
<div class="inspection-icon" style="background:rgba(255,59,48,0.15)"></div>
<div class="inspection-body">
<div class="inspection-title">Kungliga Slottet — Takinspektion</div>
<div class="inspection-meta">Sofia Berg · 2026-05-01 · <span style="color:var(--ios-red)">Kritisk rapport</span></div>
</div>
<div class="inspection-chevron"></div>
</div>
<div class="inspection-item">
<div class="inspection-icon" style="background:rgba(0,122,255,0.15)"></div>
<div class="inspection-body">
<div class="inspection-title">Arlanda T5 — Fasadinspektion</div>
<div class="inspection-meta">Erik Svensson · 2026-05-16 · <span style="color:var(--ios-green)">Godkänd</span></div>
</div>
<div class="inspection-chevron"></div>
</div>
</div>
<!-- STATUS REPORTS -->
<div class="section-header">Statusrapporter</div>
<div class="table-card">
<div class="table-scroll">
<table>
<thead>
<tr>
<th>Rapport</th>
<th>Period</th>
<th>Objekt</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td><div class="td-name">Månatlig Statusrapport</div><div class="td-sub">Automatisk</div></td>
<td>Maj 2026</td>
<td>247 objekt</td>
<td><span class="status-badge status-ok"><span class="status-dot"></span>Klar</span></td>
<td><button class="table-action">Ladda ned</button></td>
</tr>
<tr>
<td><div class="td-name">Kritiska avvikelser</div><div class="td-sub">Automatisk · Alert</div></td>
<td>2026-05-17</td>
<td>3 objekt</td>
<td><span class="status-badge status-critical"><span class="status-dot"></span>Åtgärda</span></td>
<td><button class="table-action">Visa</button></td>
</tr>
<tr>
<td><div class="td-name">Kvartal Q1 2026</div><div class="td-sub">Manuell</div></td>
<td>JanMar 2026</td>
<td>231 objekt</td>
<td><span class="status-badge status-ok"><span class="status-dot"></span>Klar</span></td>
<td><button class="table-action">Ladda ned</button></td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<!-- FAB -->
<button class="fab" onclick="openModal()">
<span>+</span>
<span>Ny inspektion</span>
</button>
<!-- MODAL: Ny inspektion -->
<div class="modal-overlay" id="modal" onclick="closeModal(event)">
<div class="modal-sheet" onclick="event.stopPropagation()">
<div class="modal-handle"></div>
<div class="modal-title">Skapa ny inspektion</div>
<div class="form-group">
<div class="form-label">Objekt</div>
<select class="form-select">
<option>E4 Norrtull Avsnitt 12</option>
<option>Gamla Stan Bro</option>
<option>Kungliga Slottet Tak</option>
<option>Arlanda Terminal 5</option>
<option>Öresundsbron Sektion 3</option>
</select>
</div>
<div class="form-group">
<div class="form-label">Inspektionstyp</div>
<select class="form-select">
<option>Ytinspektion</option>
<option>Strukturkontroll</option>
<option>Fasadinspektion</option>
<option>Takinspektion</option>
<option>Fullständig inspektion</option>
</select>
</div>
<div class="form-group">
<div class="form-label">Ansvarig inspektion</div>
<input class="form-input" type="text" placeholder="Sök inspektör...">
</div>
<div class="form-group">
<div class="form-label">Datum</div>
<input class="form-input" type="date" value="2026-05-20">
</div>
<div class="modal-actions">
<button class="btn-secondary" onclick="closeModal()">Avbryt</button>
<button class="btn-primary" onclick="submitInspection()">Skapa inspektion</button>
</div>
</div>
</div>
<!-- TAB BAR -->
<nav class="tab-bar">
<div class="tab-item active">
<div class="tab-icon"></div>
<div class="tab-label">Översikt</div>
</div>
<div class="tab-item" onclick="window.location.href='landvex-admin.html#objects'">
<div class="tab-icon"><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>
<div class="tab-label">Objekt</div>
</div>
<div class="tab-item" onclick="window.location.href='landvex-admin.html#inspections'">
<div class="tab-icon"><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="tab-label">Inspektioner</div>
</div>
<div class="tab-item">
<div class="tab-icon"><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>
<div class="tab-label">Rapporter</div>
</div>
<div class="tab-item">
<div class="tab-icon"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="3" stroke="#666" stroke-width="1.5"/><path d="M8 2V4M8 12V14M2 8H4M12 8H14M4.3 4.3L5.7 5.7M10.3 10.3L11.7 11.7M4.3 11.7L5.7 10.3M10.3 5.7L11.7 4.3" stroke="#666" stroke-width="1.5" stroke-linecap="round"/></svg></div>
<div class="tab-label">Inställningar</div>
</div>
</nav>
<style>
@keyframes zoomer-pulse {
0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(0,122,255,0.4); }
50% { transform: scale(1.05); box-shadow: 0 0 0 6px rgba(0,122,255,0); }
}
@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>
<!-- DISPATCH MODAL -->
<div id="dispatch-modal" style="position:fixed;inset:0;background: rgba(242,242,247,0.5);display:flex;align-items:flex-end;z-index:1001;opacity:0;pointer-events:none;transition:opacity 0.25s;">
<div style="background:var(--background-primary);border-radius: var(--radius-xl) 20px 0 0;padding:20px 20px 40px;width:100%;max-height:80vh;overflow-y:auto;transform:translateY(100%);transition:transform 0.35s cubic-bezier(0.34,1.56,0.64,1);" id="dispatch-sheet">
<div style="width:36px;height:4px;background:var(--fill-secondary);border-radius: var(--radius-sm);margin:0 auto 16px;"></div>
<div style="font-family:var(--font-display);font-size:22px;font-weight:700;letter-spacing:-0.4px;margin-bottom:16px;"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M9 2L5 9H8L7 14L11 7H8L9 2Z" fill="#f59e0b"/></svg> Snabb-dispatch</div>
<div style="background:var(--background-secondary);border-radius: var(--radius-md);padding:14px;margin-bottom:12px;">
<div style="font-size:13px;font-weight:600;color:var(--label-secondary);text-transform:uppercase;letter-spacing:0.4px;margin-bottom:10px;">Närmaste lediga zoomer</div>
<div style="display:flex;align-items:center;gap:12px;padding:10px;background:rgba(52,199,89,0.08);border-radius: var(--radius-md);border:0.5px solid rgba(52,199,89,0.3);margin-bottom:8px;">
<span style="font-size:24px;"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg></span>
<div style="flex:1;">
<div style="font-size:16px;font-weight:600;">LX-04 · Stockholm N</div>
<div style="font-size:12px;color:var(--label-secondary);">4.2 km bort · Laddad 100% · HD + Multispektral</div>
</div>
<button onclick="confirmDispatch('LX-04')" style="background:var(--ios-green);color: #1d1d1f;border:none;border-radius: var(--radius-md);padding:8px 14px;font-size:14px;font-weight:600;cursor:pointer;">Skicka</button>
</div>
<div style="display:flex;align-items:center;gap:12px;padding:10px;background:var(--fill-quaternary);border-radius: var(--radius-md);margin-bottom:8px;">
<span style="font-size:24px;"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2V6M4 4H12" stroke="#666" stroke-width="1.5" stroke-linecap="round"/><path d="M2 8H6L8 6L10 8H14" stroke="#666" stroke-width="1.5" stroke-linejoin="round"/><path d="M6 8V12H10V8" stroke="#666" stroke-width="1.5"/></svg></span>
<div style="flex:1;">
<div style="font-size:16px;font-weight:600;">LX-07 · Nacka</div>
<div style="font-size:12px;color:var(--label-secondary);">8.7 km bort · Laddad 87% · HD</div>
</div>
<button onclick="confirmDispatch('LX-07')" style="background:var(--ios-blue);color: #1d1d1f;border:none;border-radius: var(--radius-md);padding:8px 14px;font-size:14px;font-weight:600;cursor:pointer;">Skicka</button>
</div>
</div>
<div id="dispatch-success" style="display:none;text-align:center;padding:16px;background:rgba(52,199,89,0.1);border-radius: var(--radius-lg);color:var(--ios-green);font-size:16px;font-weight:600;"><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> Dispatch bekräftad! Zoomer anländer inom 12 min.</div>
<button onclick="closeDispatch()" style="width:100%;padding:14px;background:var(--fill-tertiary);color:var(--label-primary);border:none;border-radius: var(--radius-lg);font-size:17px;font-weight:600;cursor:pointer;margin-top:8px;">Stäng</button>
</div>
</div>
<script>
function openModal() {
document.getElementById('modal').classList.add('open');
}
function closeModal(e) {
if (!e || e.target === document.getElementById('modal')) {
document.getElementById('modal').classList.remove('open');
}
}
function submitInspection() {
document.getElementById('modal').classList.remove('open');
// Toast feedback
const toast = document.createElement('div');
toast.style.cssText = 'position:fixed;bottom:80px;left:50%;transform:translateX(-50%);background:var(--ios-green);color:white;padding:12px 20px;border-radius: var(--radius-xl);font-size:15px;font-weight:600;z-index:500;box-shadow:0 4px 16px rgba(52,199,89,0.4);';
toast.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> Inspektion skapad';
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 2500);
}
// Tab switching
document.querySelectorAll('.tab-item').forEach((tab, i) => {
tab.addEventListener('click', () => {
document.querySelectorAll('.tab-item').forEach(t => t.classList.remove('active'));
tab.classList.add('active');
});
});
// Dispatch modal
function openDispatch() {
const m = document.getElementById('dispatch-modal');
const s = document.getElementById('dispatch-sheet');
document.getElementById('dispatch-success').style.display = 'none';
m.style.opacity = '1';
m.style.pointerEvents = 'all';
setTimeout(() => s.style.transform = 'translateY(0)', 10);
}
function closeDispatch() {
const m = document.getElementById('dispatch-modal');
const s = document.getElementById('dispatch-sheet');
s.style.transform = 'translateY(100%)';
setTimeout(() => { m.style.opacity = '0'; m.style.pointerEvents = 'none'; }, 300);
}
function confirmDispatch(zoomerId) {
setTimeout(() => {
document.getElementById('dispatch-success').style.display = 'block';
}, 800);
}
document.getElementById('dispatch-modal').addEventListener('click', (e) => {
if (e.target === document.getElementById('dispatch-modal')) closeDispatch();
});
// Zoomer live position animation
function cycleZoomerPos() {
const z1 = document.getElementById('zoomer-lx01');
const z2 = document.getElementById('zoomer-lx02');
const z3 = document.getElementById('zoomer-lx03');
if (z1) z1.style.left = (44 + Math.random() * 8) + '%';
if (z1) z1.style.top = (38 + Math.random() * 8) + '%';
if (z2) z2.style.left = (20 + Math.random() * 8) + '%';
if (z2) z2.style.top = (25 + Math.random() * 8) + '%';
if (z3) z3.style.left = (68 + Math.random() * 8) + '%';
if (z3) z3.style.top = (52 + Math.random() * 8) + '%';
}
// Auto-animate zoomers every 5s
setInterval(cycleZoomerPos, 5000);
</script>
</body>
</html>