thermograph/templates/base.html.j2
Emi Griffith 90bded90b7 Give climate/city/record pages full header parity + working °F/°C (#124)
The server-rendered SEO pages shared base.html.j2's nav but carried no JS, so
they lacked the °F/°C toggle and account/bell, and their temperatures were baked
as dual-unit strings that couldn't respond to a toggle.

- Load units.js + account.js + climate.js on base.html.j2, so every SEO page gets
  the same header as the interactive pages (nav + °F/°C toggle + account + bell).
- Emit each temperature as <span class="temp" data-temp-f> (default °F text, real
  for crawlers/no-JS); climate.js rewrites them to the active unit on load and on
  toggle. Tint classes stay pinned to absolute °F. Drops the inline "(NN°C)".
- Make account.js base-aware: derive the app base from import.meta.url so its
  api/v2 fetches and the alerts links resolve from deep /climate/{slug} URLs
  instead of 404ing. Equivalent on the depth-1 interactive pages.
- Default the unit from the browser locale for first-time visitors (no stored
  pref): en-US → °F, everyone else → °C. A stored choice always wins.
2026-07-16 17:48:30 +00:00

69 lines
3.4 KiB
Django/Jinja

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{% block title %}Thermograph{% endblock %}</title>
<meta name="description" content="{% block description %}{% endblock %}" />
<meta name="theme-color" content="#f0803c" />
<link rel="canonical" href="{{ base_url }}{% block canonical_path %}/{% endblock %}" />
<meta property="og:type" content="{% block og_type %}website{% endblock %}" />
<meta property="og:site_name" content="Thermograph" />
<meta property="og:title" content="{{ self.title() }}" />
<meta property="og:description" content="{{ self.description() }}" />
<meta property="og:url" content="{{ base_url }}{{ self.canonical_path() }}" />
<meta property="og:image" content="{{ base_url }}/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="{{ base }}/logo.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="{{ base }}/logo.png" />
<link rel="manifest" href="{{ base }}/manifest.webmanifest" />
<link rel="stylesheet" href="{{ base }}/style.css" />
{% block jsonld %}{% endblock %}
</head>
<body>
<header>
<div class="brand">
<a class="logo" href="{{ base }}/" aria-label="Thermograph home"><svg viewBox="116 116 280 280" width="28" height="28" aria-hidden="true"><rect x="116" y="116" width="134" height="134" rx="20" fill="currentColor"/><rect x="262" y="262" width="134" height="134" rx="20" fill="currentColor"/></svg></a>
<div>
<h1 class="site-name"><a href="{{ base }}/">Thermograph</a></h1>
<p class="tag">How unusual is the weather? Graded against ~45 years of local climate history.</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="{{ base }}/">Weekly</a>
<a href="{{ base }}/calendar">Calendar</a>
<a href="{{ base }}/day">Day Detail</a>
<a href="{{ base }}/compare">Compare</a>
<a href="{{ base }}/climate"{% if section == 'climate' %} class="active"{% endif %}>Climate</a>
</nav>
</div>
</details>
</div>
</header>
<main class="content">
{% block content %}{% endblock %}
</main>
<footer class="site-footer">
<nav aria-label="Footer">
<a href="{{ base }}/climate">City climates</a>
<a href="{{ base }}/glossary">Weather glossary</a>
<a href="{{ base }}/about">About &amp; methodology</a>
<a href="{{ base }}/">Open the tool</a>
</nav>
<p class="muted">Thermograph grades weather by its percentile against ~45 years of local
climate history. Climate data via Open-Meteo (ERA5 reanalysis).</p>
</footer>
<!-- Header parity with the interactive pages: the °F/°C toggle, account + bell,
and the client-side temperature converter. All self-contained modules. -->
<script type="module" src="{{ base }}/units.js"></script>
<script type="module" src="{{ base }}/account.js"></script>
<script type="module" src="{{ base }}/climate.js"></script>
</body>
</html>