Aperture / frontend /index.html
KSvend
refactor: rename "indicators" to "EO products" throughout
df6bf75
Raw
History Blame Contribute Delete
20.7 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MERLx Aperture</title>
<!-- MERLx Design System -->
<link rel="stylesheet" href="/static/css/merlx.css" />
<!-- MapLibre GL JS 4.1.2 -->
<link rel="stylesheet" href="https://unpkg.com/maplibre-gl@4.1.2/dist/maplibre-gl.css" />
<script src="https://unpkg.com/maplibre-gl@4.1.2/dist/maplibre-gl.js"></script>
<style>
/* Page-level overrides not covered by component styles */
body { margin: 0; overflow: hidden; height: 100vh; }
/* All pages hidden by default; active class shows them */
.page { display: none; }
.page.active { display: flex; }
/* Landing fills full viewport */
#page-landing {
height: 100vh;
align-items: center;
justify-content: center;
background-color: var(--shell);
}
#page-login {
height: 100vh;
align-items: center;
justify-content: center;
background-color: var(--shell);
}
/* Define Area: map + sidebar split */
#page-define-area {
height: 100vh;
overflow: hidden;
}
/* Products: full column */
#page-products {
height: 100vh;
flex-direction: column;
overflow: hidden;
}
/* Confirm: centered card */
#page-confirm {
height: 100vh;
align-items: center;
justify-content: center;
background-color: var(--shell);
overflow-y: auto;
padding: var(--space-12);
}
/* Status: centered card */
#page-status {
height: 100vh;
align-items: center;
justify-content: center;
background-color: var(--shell);
overflow-y: auto;
padding: var(--space-12);
}
#page-history {
height: 100vh;
flex-direction: column;
overflow: hidden;
}
/* Results: full-height split */
#page-results {
height: 100vh;
flex-direction: column;
overflow: hidden;
}
</style>
</head>
<body>
<!-- ═══════════════════════════════════════════════════════════
PAGE 1 β€” LANDING
═══════════════════════════════════════════════════════════ -->
<div id="page-landing" class="page">
<div class="landing-hero">
<!-- Logo -->
<div class="landing-logo">
MERL<span style="color: var(--iris)">x</span>
</div>
<!-- Subtitle -->
<div class="landing-subtitle" style="font-family: 'DM Serif Display', serif; font-style: italic; font-size: var(--text-lg); color: var(--ink-muted); margin-top: var(--space-3);">
Aperture
</div>
<!-- Headline -->
<h1 class="landing-headline">
AI-enhanced satellite analysis for humanitarian programme teams.
</h1>
<!-- Sub-copy -->
<p class="landing-sub">
Select your area, choose your EO products, get evidence-grade
satellite analysis delivered β€” using free, open data.
</p>
<!-- CTA -->
<button id="cta-start" class="btn btn-primary btn-lg">
Start a new analysis
</button>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
PAGE β€” LOGIN
═══════════════════════════════════════════════════════════ -->
<div id="page-login" class="page">
<div class="login-card">
<!-- Logo -->
<div class="login-logo">
MERL<span style="color: var(--iris)">x</span>
</div>
<div style="font-family: 'DM Serif Display', serif; font-style: italic; font-size: var(--text-lg); color: var(--ink-muted); margin-bottom: var(--space-10); text-align: center;">
Aperture
</div>
<!-- State 1: Email entry -->
<div id="login-email-step">
<h2 class="login-heading">Sign in to continue</h2>
<div class="form-group" style="margin-bottom: var(--space-8);">
<label class="label" for="login-email">Email address</label>
<input id="login-email" class="input" type="email" placeholder="you@organisation.org" />
</div>
<button id="login-send-btn" class="btn btn-primary" style="width:100%;">
Send magic link
</button>
<p class="login-helper">In demo mode, the code will appear automatically.</p>
</div>
<!-- State 2: Token entry -->
<div id="login-token-step" style="display:none;">
<h2 class="login-heading" id="login-token-heading">Check your email</h2>
<div class="form-group" style="margin-bottom: var(--space-8);">
<label class="label" for="login-token">Verification code</label>
<input id="login-token" class="input" type="text" placeholder="Paste your code" />
</div>
<button id="login-verify-btn" class="btn btn-primary" style="width:100%;">
Verify
</button>
<a href="#" id="login-back-link" class="login-back-link">Use a different email</a>
</div>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
PAGE 2 β€” DEFINE AREA
═══════════════════════════════════════════════════════════ -->
<div id="page-define-area" class="page">
<!-- Sidebar -->
<aside class="map-sidebar">
<div class="map-sidebar-header">
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom: var(--space-5);">
<span class="logo">MERL<span class="x">x</span></span>
<!-- Steps -->
<div class="steps">
<span class="step-dot" data-step-page="define-area"></span>
<span class="step-connector"></span>
<span class="step-dot" data-step-page="products"></span>
<span class="step-connector"></span>
<span class="step-dot" data-step-page="confirm"></span>
</div>
</div>
<h2 style="font-size: var(--text-base); font-weight: 600; color: var(--ink);">Define your area</h2>
<p style="font-size: var(--text-xs); color: var(--ink-muted); margin-top: var(--space-2);">Click the map or search to place your area of interest.</p>
</div>
<div class="map-sidebar-body">
<!-- Area name -->
<div class="form-group">
<label class="label" for="area-name">Area name</label>
<input id="area-name" class="input" type="text" placeholder="e.g. Turkana County" />
</div>
<!-- Geocoder -->
<div class="form-group">
<label class="label" for="geocoder-input">Search location</label>
<input id="geocoder-input" class="input" type="text" placeholder="Type and press Enter…" />
</div>
<!-- AOI size -->
<div class="form-group">
<label class="label">AOI size</label>
<div class="size-toggles">
<button class="size-toggle-btn" data-km2="100" type="button">100 kmΒ²</button>
<button class="size-toggle-btn" data-km2="250" type="button">250 kmΒ²</button>
<button class="size-toggle-btn active" data-km2="500" type="button">500 kmΒ²</button>
</div>
<div id="aoi-area-display" class="aoi-area-display" style="display:none;"></div>
</div>
<!-- AOI Advisor -->
<div id="aoi-advisor" class="aoi-advisor" style="display:none;">
<div id="aoi-advisor-loading" class="aoi-advisor-loading">Analyzing region…</div>
<div id="aoi-advisor-content" style="display:none;">
<div class="aoi-advisor-heading">Region Insight</div>
<p id="advisor-context" class="aoi-advisor-text"></p>
<p id="advisor-dates" class="aoi-advisor-meta"></p>
<p id="advisor-reasoning" class="aoi-advisor-text" style="font-style: italic;"></p>
<div id="advisor-priorities" class="aoi-advisor-priorities"></div>
</div>
</div>
<hr class="divider" />
<!-- Date range -->
<div class="form-group">
<label class="label">Analysis period</label>
<div class="date-row">
<div>
<label class="label" for="date-start" style="font-size: var(--text-xxs);">Start</label>
<input id="date-start" class="input" type="date" />
</div>
<div>
<label class="label" for="date-end" style="font-size: var(--text-xxs);">End</label>
<input id="date-end" class="input" type="date" />
</div>
</div>
</div>
<!-- Analysis season -->
<div class="form-group">
<label class="label">Analysis season</label>
<p style="font-size: var(--text-xxs); color: var(--ink-muted); margin-bottom: var(--space-3);">
Select the months relevant to your analysis. For year-round monitoring, leave as Jan–Dec.
</p>
<div class="date-row">
<div>
<label class="label" for="season-start" style="font-size: var(--text-xxs);">Start month</label>
<select id="season-start" class="input">
<option value="1" selected>January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
</div>
<div>
<label class="label" for="season-end" style="font-size: var(--text-xxs);">End month</label>
<select id="season-end" class="input">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12" selected>December</option>
</select>
</div>
</div>
<p id="season-wrap-hint" style="font-size: var(--text-xxs); color: var(--iris); margin-top: var(--space-2); display: none;">
↻ Season crosses year boundary
</p>
</div>
</div><!-- /sidebar-body -->
<div class="map-sidebar-footer">
<button id="aoi-continue-btn" class="btn btn-primary" style="width:100%;" disabled>
Continue to EO products
</button>
</div>
</aside>
<!-- Map -->
<div class="map-container">
<div id="map"></div>
</div>
</div><!-- /page-define-area -->
<!-- ═══════════════════════════════════════════════════════════
PAGE 3 β€” SELECT EO PRODUCTS
═══════════════════════════════════════════════════════════ -->
<div id="page-products" class="page">
<!-- Top bar -->
<div class="indicators-topbar">
<div style="display:flex; align-items:center; gap: var(--space-10);">
<span class="logo">MERL<span class="x">x</span></span>
<!-- Steps -->
<div class="steps">
<span class="step-dot" data-step-page="define-area"></span>
<span class="step-connector"></span>
<span class="step-dot" data-step-page="products"></span>
<span class="step-connector"></span>
<span class="step-dot" data-step-page="confirm"></span>
</div>
</div>
<div style="display:flex; align-items:center; gap: var(--space-5);">
<a href="#" class="topbar-link nav-my-analyses">My analyses</a>
<a href="#" class="topbar-link nav-signout">Sign out</a>
<button id="products-back-btn" class="btn btn-secondary">Back</button>
</div>
</div>
<!-- Page heading -->
<div style="padding: var(--space-8) var(--space-12) 0; flex-shrink:0; background-color: var(--surface); border-bottom: 1px solid var(--border-light);">
<h1 style="font-size: var(--text-xl); font-weight: 600; margin-bottom: var(--space-2);">Select EO Products</h1>
<p style="font-size: var(--text-xs); color: var(--ink-muted); margin-bottom: var(--space-8);">
Select the satellite-derived EO products to include in your analysis.
</p>
</div>
<!-- Products grid (scrolls) -->
<div id="products-grid" class="indicators-grid"></div>
<!-- Sticky summary bar -->
<div class="indicators-summary-bar">
<span id="products-summary-text" class="summary-text">
Select at least one EO product to continue.
</span>
<button id="products-continue-btn" class="btn btn-primary" disabled>
Continue
</button>
</div>
</div><!-- /page-products -->
<!-- ═══════════════════════════════════════════════════════════
PAGE 4 β€” CONFIRM
═══════════════════════════════════════════════════════════ -->
<div id="page-confirm" class="page">
<div class="confirm-card">
<!-- Steps -->
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom: var(--space-10);">
<span class="logo" style="font-size: var(--text-base);">MERL<span class="x">x</span></span>
<div class="steps">
<span class="step-dot" data-step-page="define-area"></span>
<span class="step-connector"></span>
<span class="step-dot" data-step-page="products"></span>
<span class="step-connector"></span>
<span class="step-dot" data-step-page="confirm"></span>
</div>
</div>
<h1 class="confirm-title">Confirm your analysis</h1>
<!-- Summary -->
<div class="confirm-summary">
<div class="confirm-row">
<span class="confirm-row-label">Area</span>
<span id="confirm-area-name" class="confirm-row-value">β€”</span>
</div>
<div class="confirm-row">
<span class="confirm-row-label">Period</span>
<span class="confirm-row-value">
<span id="confirm-period-start">β€”</span>
<span style="color: var(--ink-faint); margin: 0 4px;">to</span>
<span id="confirm-period-end">β€”</span>
</span>
</div>
<div class="confirm-row">
<span class="confirm-row-label">Season</span>
<span id="confirm-season" class="confirm-row-value">January – December</span>
</div>
<div class="confirm-row">
<span class="confirm-row-label">EO Products</span>
<span id="confirm-indicators" class="confirm-row-value">0</span>
</div>
</div>
<!-- Email -->
<div class="form-group" style="margin-bottom: var(--space-10);">
<label class="label" for="confirm-email">Notify me at</label>
<input id="confirm-email" class="input" type="email" placeholder="you@organisation.org" />
</div>
<!-- Actions -->
<div style="display:flex; gap: var(--space-5);">
<button id="confirm-back-btn" class="btn btn-secondary">Back</button>
<button id="confirm-submit-btn" class="btn btn-primary" style="flex:1;">Submit analysis</button>
</div>
</div>
</div><!-- /page-confirm -->
<!-- ═══════════════════════════════════════════════════════════
PAGE 5 β€” STATUS
═══════════════════════════════════════════════════════════ -->
<div id="page-status" class="page">
<div class="status-card">
<div class="status-header">
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom: var(--space-8);">
<span class="logo" style="font-size: var(--text-base);">MERL<span class="x">x</span></span>
<span id="status-job-id" class="font-data text-xxs text-muted"></span>
</div>
<h1 class="status-title">Analysis in progress</h1>
<p class="status-subtitle">Your EO products are being processed. This page updates automatically.</p>
</div>
<div id="status-list" class="status-list">
<!-- Populated by app.js -->
</div>
</div>
</div><!-- /page-status -->
<!-- ═══════════════════════════════════════════════════════════
PAGE β€” HISTORY
═══════════════════════════════════════════════════════════ -->
<div id="page-history" class="page">
<!-- Top bar -->
<div class="history-topbar">
<span class="logo">MERL<span class="x">x</span></span>
<h2 style="font-size: var(--text-base); font-weight: 600; color: var(--ink);">My Analyses</h2>
<div style="display:flex; align-items:center; gap: var(--space-5);">
<button id="history-new-btn" class="btn btn-primary">New analysis</button>
<a href="#" id="history-signout" class="topbar-link">Sign out</a>
</div>
</div>
<!-- Job list -->
<div id="history-list" class="history-list">
<!-- Populated by app.js -->
</div>
<!-- Empty state -->
<div id="history-empty" class="history-empty" style="display:none;">
<p>No analyses yet. Start your first one.</p>
<button id="history-empty-cta" class="btn btn-primary" style="margin-top: var(--space-8);">
New analysis
</button>
</div>
</div>
<!-- ═══════════════════════════════════════════════════════════
PAGE 6 β€” RESULTS DASHBOARD
═══════════════════════════════════════════════════════════ -->
<div id="page-results" class="page">
<!-- Top bar -->
<div class="results-topbar">
<span class="logo">MERL<span class="x">x</span></span>
<h2 style="font-size: var(--text-base); font-weight: 600; color: var(--ink);">Results Dashboard</h2>
<div style="display:flex; align-items:center; gap: var(--space-5);">
<a href="#" class="topbar-link nav-my-analyses">My analyses</a>
<a href="#" class="topbar-link nav-signout">Sign out</a>
<button
class="btn btn-secondary"
id="results-new-btn"
style="font-size: var(--text-xs);"
>
New analysis
</button>
</div>
</div>
<!-- Body: map + panel -->
<div class="results-body">
<!-- Map (65%) -->
<div class="results-map">
<div id="results-map"></div>
</div>
<!-- Panel (35%) -->
<aside class="results-panel">
<div id="results-panel-body" class="results-panel-body">
<!-- Populated by results.js -->
</div>
<div id="results-panel-footer" class="results-panel-footer">
<!-- Download links β€” populated by results.js -->
</div>
</aside>
</div>
</div><!-- /page-results -->
<!-- ═══════════════════════════════════════════════════════════
Application entry point
═══════════════════════════════════════════════════════════ -->
<script type="module" src="/static/js/app.js"></script>
</body>
</html>