Replace em-dashes in user-facing copy across the server-rendered pages, static frontend views, and the strings the app injects at runtime, using colons, commas, parentheses or full stops as the context wants. Data placeholder glyphs (a lone "—" for a missing reading) are left alone, since a hyphen there reads as a minus sign in temperature columns. Also tighten the high-visibility surfaces (home hero and meta, about, privacy, city and records ledes, glossary blurbs) toward a plainer, more direct voice while keeping every factual claim intact. Claude-Session: https://claude.ai/code/session_01XXxmNFy9cZ6Gh8Y9thZn62
120 lines
11 KiB
HTML
120 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Thermograph: reading the grades</title>
|
|
<meta name="description" content="How Thermograph grades weather: percentiles of a location's own ±7-day seasonal history, the scale from Below Normal to Near Record, and what every metric means." />
|
|
<meta name="theme-color" content="#f0803c" />
|
|
<!-- iOS/Android home-screen install: run standalone (no browser chrome) when
|
|
added to the Home Screen. On iOS 16.4+ this is what unlocks Web Push. -->
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
|
<meta name="apple-mobile-web-app-title" content="Thermograph" />
|
|
<!-- 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: reading the grades" />
|
|
<meta property="og:description" content="How Thermograph grades weather: percentiles of a location's own ±7-day seasonal history, the scale from Below Normal to Near Record, and what every metric means." />
|
|
<meta property="og:url" content="__ORIGIN__/legend" />
|
|
<meta property="og:image" content="__ORIGIN__/logo.png?v=3" />
|
|
<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="canonical" href="__ORIGIN__/legend" />
|
|
<link rel="icon" href="favicon.svg?v=3" type="image/svg+xml" />
|
|
<link rel="icon" href="favicon-48.png?v=3" type="image/png" sizes="48x48" />
|
|
<link rel="icon" href="favicon-32.png?v=3" type="image/png" sizes="32x32" />
|
|
<link rel="icon" href="favicon-16.png?v=3" type="image/png" sizes="16x16" />
|
|
<link rel="apple-touch-icon" href="apple-touch-icon.png?v=3" />
|
|
<link rel="manifest" href="manifest.webmanifest" />
|
|
<link rel="stylesheet" href="style.css" />
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<div class="brand">
|
|
<div>
|
|
<h1><a href="./"><span class="logo"><svg viewBox="0 0 512 512" width="28" height="28" aria-hidden="true"><rect x="32" y="32" width="448" height="448" rx="96" fill="#10141B" stroke="#FFFFFF" stroke-opacity="0.08" stroke-width="4"/><rect x="115" y="403" width="42" height="42" rx="10" fill="#111924"/><rect x="163" y="403" width="42" height="42" rx="10" fill="#111924"/><rect x="211" y="403" width="42" height="42" rx="10" fill="#111924"/><rect x="259" y="403" width="42" height="42" rx="10" fill="#111924"/><rect x="307" y="403" width="42" height="42" rx="10" fill="#111924"/><rect x="355" y="403" width="42" height="42" rx="10" fill="#111924"/><rect x="403" y="403" width="42" height="42" rx="10" fill="#111924"/><rect x="163" y="355" width="42" height="42" rx="10" fill="#131C25"/><rect x="211" y="355" width="42" height="42" rx="10" fill="#131C25"/><rect x="259" y="355" width="42" height="42" rx="10" fill="#131C25"/><rect x="307" y="355" width="42" height="42" rx="10" fill="#131C25"/><rect x="355" y="355" width="42" height="42" rx="10" fill="#131C25"/><rect x="403" y="355" width="42" height="42" rx="10" fill="#131C25"/><rect x="67" y="307" width="42" height="42" rx="10" fill="#181F27"/><rect x="163" y="307" width="42" height="42" rx="10" fill="#181F27"/><rect x="211" y="307" width="42" height="42" rx="10" fill="#181F27"/><rect x="259" y="307" width="42" height="42" rx="10" fill="#181F27"/><rect x="307" y="307" width="42" height="42" rx="10" fill="#181F27"/><rect x="355" y="307" width="42" height="42" rx="10" fill="#181F27"/><rect x="403" y="307" width="42" height="42" rx="10" fill="#181F27"/><rect x="67" y="259" width="42" height="42" rx="10" fill="#131C1F"/><rect x="211" y="259" width="42" height="42" rx="10" fill="#131C1F"/><rect x="403" y="259" width="42" height="42" rx="10" fill="#131C1F"/><rect x="67" y="211" width="42" height="42" rx="10" fill="#1E1E22"/><rect x="115" y="211" width="42" height="42" rx="10" fill="#1E1E22"/><rect x="211" y="211" width="42" height="42" rx="10" fill="#1E1E22"/><rect x="307" y="211" width="42" height="42" rx="10" fill="#1E1E22"/><rect x="67" y="163" width="42" height="42" rx="10" fill="#1D1C1E"/><rect x="115" y="163" width="42" height="42" rx="10" fill="#1D1C1E"/><rect x="307" y="163" width="42" height="42" rx="10" fill="#1D1C1E"/><rect x="355" y="163" width="42" height="42" rx="10" fill="#1D1C1E"/><rect x="67" y="115" width="42" height="42" rx="10" fill="#1C191E"/><rect x="115" y="115" width="42" height="42" rx="10" fill="#1C191E"/><rect x="163" y="115" width="42" height="42" rx="10" fill="#1C191E"/><rect x="211" y="115" width="42" height="42" rx="10" fill="#1C191E"/><rect x="259" y="115" width="42" height="42" rx="10" fill="#1C191E"/><rect x="307" y="115" width="42" height="42" rx="10" fill="#1C191E"/><rect x="355" y="115" width="42" height="42" rx="10" fill="#1C191E"/><rect x="67" y="67" width="42" height="42" rx="10" fill="#18141B"/><rect x="115" y="67" width="42" height="42" rx="10" fill="#18141B"/><rect x="163" y="67" width="42" height="42" rx="10" fill="#18141B"/><rect x="211" y="67" width="42" height="42" rx="10" fill="#18141B"/><rect x="259" y="67" width="42" height="42" rx="10" fill="#18141B"/><rect x="307" y="67" width="42" height="42" rx="10" fill="#18141B"/><rect x="355" y="67" width="42" height="42" rx="10" fill="#18141B"/><rect x="67" y="403" width="42" height="42" rx="10" fill="#2166ac"/><rect x="67" y="355" width="42" height="42" rx="10" fill="#4393c3"/><rect x="115" y="355" width="42" height="42" rx="10" fill="#4393c3"/><rect x="115" y="307" width="42" height="42" rx="10" fill="#92c5de"/><rect x="115" y="259" width="42" height="42" rx="10" fill="#4a9d5b"/><rect x="163" y="259" width="42" height="42" rx="10" fill="#4a9d5b"/><rect x="163" y="211" width="42" height="42" rx="10" fill="#f6c18a"/><rect x="163" y="163" width="42" height="42" rx="10" fill="#ef9351"/><rect x="211" y="163" width="42" height="42" rx="10" fill="#ef9351"/><rect x="259" y="163" width="42" height="42" rx="10" fill="#ef9351"/><rect x="259" y="211" width="42" height="42" rx="10" fill="#f6c18a"/><rect x="259" y="259" width="42" height="42" rx="10" fill="#4a9d5b"/><rect x="307" y="259" width="42" height="42" rx="10" fill="#4a9d5b"/><rect x="355" y="259" width="42" height="42" rx="10" fill="#4a9d5b"/><rect x="355" y="211" width="42" height="42" rx="10" fill="#f6c18a"/><rect x="403" y="211" width="42" height="42" rx="10" fill="#f6c18a"/><rect x="403" y="163" width="42" height="42" rx="10" fill="#ef9351"/><rect x="403" y="115" width="42" height="42" rx="10" fill="#dd6b52"/><rect x="403" y="67" width="42" height="42" rx="10" fill="#8f0e20"/></svg></span>Thermograph</a></h1>
|
|
<p class="tag">What the metrics and percentile grades mean</p>
|
|
</div>
|
|
<details class="nav-menu">
|
|
<summary class="nav-toggle" aria-label="Menu"><svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M4 7h16M4 12h16M4 17h16"/></svg></summary>
|
|
<div class="nav-panel">
|
|
<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 Detail</a>
|
|
<a href="compare" data-view="compare">Compare</a>
|
|
<a href="score" data-view="score">Score</a>
|
|
<a href="climate">Climate</a>
|
|
<a href="alerts">Alerts</a>
|
|
</nav>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="guide">
|
|
<section class="guide-block">
|
|
<h2>How the grades work</h2>
|
|
<p>Every grade is <b>relative to this place's own climate history</b>, not an absolute
|
|
temperature. For each day Thermograph builds a ±7-day seasonal distribution from
|
|
decades of local records, then reports the <b>percentile</b> where the day falls in it.</p>
|
|
<p>So a 60° day can be “Above Normal” in one place or season and
|
|
“Below Normal” in another. That's why the categories read
|
|
“Above/Below Normal”, “High/Low”, and “Near Record”,
|
|
never “hot” or “cold”.</p>
|
|
</section>
|
|
|
|
<section class="guide-block">
|
|
<h2>Grade scale: percentile of the local ±7-day history</h2>
|
|
<div class="guide-scale" id="temp-scale"></div>
|
|
</section>
|
|
|
|
<section class="guide-block">
|
|
<h2>Rain intensity: percentile among rain days</h2>
|
|
<p class="muted">Precipitation is graded only across days that actually saw rain, so
|
|
“Heavy” means heavy <i>for a rainy day here</i>. Dry days are colored by
|
|
their dry streak instead (below).</p>
|
|
<div class="guide-scale" id="rain-scale"></div>
|
|
</section>
|
|
|
|
<section class="guide-block">
|
|
<h2>The metrics</h2>
|
|
<dl class="guide-metrics">
|
|
<dt>High / Low</dt><dd>The day's highest and lowest air temperature (<span data-unit-label="temp">°F</span>).</dd>
|
|
<dt>Feels</dt><dd>Apparent temperature: what the air actually felt like once humidity
|
|
and wind are factored in, taking whichever apparent extreme (heat-index high or
|
|
wind-chill low) sits further from a temperate baseline, graded against its own history.</dd>
|
|
<dt>Humid</dt><dd>Absolute humidity: grams of water vapor per cubic meter of air (g/m³).</dd>
|
|
<dt>Wind</dt><dd>Average sustained wind speed (<span data-unit-label="wind">mph</span>).</dd>
|
|
<dt>Gust</dt><dd>Peak wind gust for the day (<span data-unit-label="wind">mph</span>).</dd>
|
|
<dt>Precip</dt><dd>Total precipitation (<span data-unit-label="precip">inches</span>), graded by intensity among rain days.</dd>
|
|
<dt>Dry streak</dt><dd>Consecutive days since the last measurable rain; the color deepens
|
|
the longer it's been dry, and resets to blue on a rain day.</dd>
|
|
</dl>
|
|
</section>
|
|
|
|
<p class="guide-back"><a href="./">← Back to Thermograph</a></p>
|
|
</main>
|
|
|
|
<script type="module">
|
|
import "./nav.js"; // header view-links follow the last location
|
|
import "./units.js"; // the °F/°C toggle
|
|
import "./account.js"; // header sign-in entry + notification bell
|
|
// The scale rows come from the shared tier tables, so this guide can't
|
|
// drift from what the app actually shows.
|
|
import { SCALE_TEMP, SCALE_RAIN } from "./shared.js";
|
|
const row = ({ c, label, range }) =>
|
|
`<div class="guide-seg"><span class="guide-sw" style="background:var(--${c})"></span>` +
|
|
`<span class="guide-lbl">${label}</span><span class="guide-rng">${range}</span></div>`;
|
|
document.getElementById("temp-scale").innerHTML = SCALE_TEMP.map(row).join("");
|
|
document.getElementById("rain-scale").innerHTML = SCALE_RAIN.map(row).join("");
|
|
</script>
|
|
<script type="module" src="ios-install.js"></script>
|
|
</body>
|
|
</html>
|