thermograph/static/compare.html

111 lines
5 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" />
<title>Thermograph — compare comfort</title>
<meta name="description" content="Pick any point on Earth and see how its recent weather stacks up against ~45 years of local climate history — graded days, calendars, forecasts, and side-by-side comparisons." />
<meta name="theme-color" content="#f0803c" />
<!-- Link previews (Discord, Slack, iMessage…). The server fills the og:url /
og:image origins in from this request's scheme://host + base path —
crawlers need absolute URLs and don't run JS. -->
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Thermograph" />
<meta property="og:title" content="Thermograph — compare comfort" />
<meta property="og:description" content="Pick any point on Earth and see how its recent weather stacks up against ~45 years of local climate history — graded days, calendars, forecasts, and side-by-side comparisons." />
<meta property="og:url" content="__ORIGIN__/compare" />
<meta property="og:image" content="__ORIGIN__/logo.png" />
<meta property="og:image:width" content="512" />
<meta property="og:image:height" content="512" />
<meta property="og:image:alt" content="Thermograph logo" />
<meta name="twitter:card" content="summary" />
<link rel="icon" href="logo.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="logo.png" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header>
<div class="brand">
<span class="logo"></span>
<div>
<h1>Thermograph · Compare</h1>
<p class="tag">Which place best hits your comfort temperature over a date range</p>
</div>
<nav class="view-nav" aria-label="Views">
<a href="./" data-view="map">Weekly</a>
<a href="calendar" data-view="calendar">Calendar</a>
<a href="day" data-view="day">Day</a>
<a href="compare" data-view="compare" class="active">Compare</a>
</nav>
</div>
</header>
<main>
<!-- Locations to line up against each other. -->
<section class="controls">
<div class="cmp-locs">
<span class="cal-filter-label">Locations</span>
<ul id="cmp-loc-list" class="cmp-loc-list"></ul>
<div class="cmp-loc-actions">
<button type="button" id="cmp-add" class="find-btn"></button>
<button type="button" id="cmp-refresh" class="cmp-refresh-btn" hidden>Refresh comparison ↻</button>
</div>
</div>
</section>
<!-- The comfort target, what temperature to judge by, the tolerance band, and
the date range. Comfort/band/basis recompute instantly (no refetch); only
the date range or the location set trigger a data load. -->
<div id="cmp-params" class="cmp-params" hidden>
<div class="cmp-param cmp-comfort">
<label for="cmp-comfort">Comfort temperature <b id="cmp-comfort-val"></b></label>
<input id="cmp-comfort" type="range" min="30" max="100" step="1" />
</div>
<div class="cmp-param cmp-band">
<label for="cmp-tol">Comfort band <b id="cmp-tol-val"></b></label>
<input id="cmp-tol" type="range" min="0" max="15" step="1" />
<span class="hint">A day "hits comfort" when it lands within this many degrees.</span>
</div>
<div class="cmp-param cmp-basis-block">
<span class="cal-filter-label">Judge each day by its</span>
<div class="metric-toggle" id="cmp-basis" role="group" aria-label="Temperature to compare">
<button type="button" data-basis="tmax" class="active">High</button>
<button type="button" data-basis="mean">Mean</button>
<button type="button" data-basis="tmin">Low</button>
<button type="button" data-basis="feels">Feels</button>
</div>
</div>
<div class="cmp-param cmp-range cal-range" id="cmp-range">
<div class="cal-range-head">
<span class="cal-filter-label">Date range</span>
<span class="hint">any span; longer loads take a moment</span>
</div>
<label>From <input id="cmp-start" type="month" /></label>
<label>To <input id="cmp-end" type="month" /></label>
<span class="hint">Editing the range arms Refresh — tap it to reload.</span>
</div>
</div>
<div id="cmp-head" class="cal-head" hidden></div>
<div class="placeholder" id="cmp-placeholder">
<p>Add two or more places to see which one best matches your comfort temperature
across a date range — the share of days that land in your comfort band, how
often it runs colder or warmer, and by how much.</p>
</div>
<div id="cmp-results" class="cmp-results"></div>
</main>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="nav.js"></script>
Extract shared.js: one home for tier colors, scales, formatters, helpers (#47) The page scripts each re-declared the shared presentation layer — the tier color table existed in four places (app.js, calendar.js, day.js, style.css) and the scale label tables in three (plus legend.html's own drifting copy), alongside per-page copies of the dryness ramp, formatters, ord, todayISO, esc, the weather icons/summary, month helpers and the 2-year range chunker. ~240 duplicated lines deleted (net -236 with the new module included). - frontend/shared.js (IIFE, extends window.Thermograph): tier colors read from style.css's :root custom properties at load — the CSS is now the single source of truth; the JS map exists only because inline-SVG work (chart + PNG export) needs literal values, with hex fallbacks for a missing stylesheet. Plus SCALE_TEMP/SCALE_RAIN, drynessColor, fmt*, ord, todayISO, esc, placeLabel, month/chunk date helpers, clickOpensPicker, and the weatherType summary (dsr-aware; the day page just omits dsr). - nav.js: wrapped in an IIFE — its ~15 top-level functions were globals in the shared classic-script scope, and a leaked locHash collided with page destructuring (caught by the browser smoke, not by node --check). locHash is now exported and used by all 8 former hand-built hash sites. - mappicker.js: initFindButton/setFindLabel replace the Find-button block each page rebuilt. - legend.html renders its scales from the shared tables, so the guide can no longer drift from what the app shows. Verified: node --check on all JS; 108 backend tests; headless-Chromium smoke over all five pages against live data — no console/page errors, legend rows 9/9, weekly 7 cards + colored chart/key/table + metric toggle, calendar grid + key + metric switch, day 7 ladders + weather icon, compare seeded rank card.
2026-07-11 20:21:48 +00:00
<script src="shared.js"></script>
<script src="mappicker.js"></script>
<script src="compare.js"></script>
</body>
</html>