{{/*
  Ported from templates/base.html.j2 (Jinja, trim_blocks + lstrip_blocks +
  keep_trailing_newline=False). The Jinja layout used {% extends %}/{% block %};
  in a single html/template parse set a per-page {{define "title"}} would
  collide across the 10 pages, so the layout is instead split into sequential
  chunks that every page template stitches together in order:

    base_head_start        doctype .. the manifest <link>. title/description/
                           canonical/og:* are data-driven (.PageTitle,
                           .PageDescription, .CanonicalPath) — the og:title /
                           og:url duplication Jinja did via self.title() falls
                           out for free.
    [page head_extra]      inline in the page file (home: leaflet css)
    base_head_end          the style.css <link>
    [page jsonld]          inline in the page file (city/records/glossary_term/home)
    base_body_start        </head> .. <body> header + nav .. <main ...>
    [page content]
    base_body_end          </main> .. footer
    [page body_scripts]    base_scripts_default, or the page's own (home)
    base_tail              digest/ios-install scripts, </body></html>

  Whitespace mirrors the Jinja env's exact output byte-for-byte (golden-diff
  contract): control tags on their own line vanished entirely under
  trim_blocks/lstrip_blocks, so here the equivalent actions are glued to the
  start of the following content line; keep_trailing_newline=False means the
  document ends at </html> with no final newline (see base_tail).

  HTML comments that must SURVIVE into the output go through the `comment`
  FuncMap helper, because html/template strips literal <!-- --> comments.

  Data contract (all pages): .Base .AssetBase .AssetBaseURL .BaseURL
  .UnitDefault .Section .BrandTag ("h1"; home passes "p") .MainClass
  ("content"; home passes "") .PageTitle .PageDescription .CanonicalPath
  .Fmt (unit-bound formatter: Temp/TempBare/TempClass) and, on pages that have
  one, .Breadcrumb []contentapi.Crumb.
*/}}
{{define "base_head_start" -}}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  {{head_verify}}
  <title>{{.PageTitle}}</title>
  <meta name="description" content="{{.PageDescription}}" />
  <meta name="theme-color" content="#f0803c" />
  {{comment `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 rel="canonical" href="{{.BaseURL}}{{.CanonicalPath}}" />
  <meta property="og:type" content="website" />
  <meta property="og:site_name" content="Thermograph" />
  <meta property="og:title" content="{{.PageTitle}}" />
  <meta property="og:description" content="{{.PageDescription}}" />
  <meta property="og:url" content="{{.BaseURL}}{{.CanonicalPath}}" />
  <meta property="og:image" content="{{.AssetBaseURL}}/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="icon" href="{{.AssetBase}}/favicon.svg?v=3" type="image/svg+xml" />
  <link rel="icon" href="{{.AssetBase}}/favicon-48.png?v=3" type="image/png" sizes="48x48" />
  <link rel="icon" href="{{.AssetBase}}/favicon-32.png?v=3" type="image/png" sizes="32x32" />
  <link rel="icon" href="{{.AssetBase}}/favicon-16.png?v=3" type="image/png" sizes="16x16" />
  <link rel="apple-touch-icon" href="{{.AssetBase}}/apple-touch-icon.png?v=3" />
  <link rel="manifest" href="{{.AssetBase}}/manifest.webmanifest" />
{{end}}
{{define "base_head_end" -}}
  <link rel="stylesheet" href="{{.AssetBase}}/style.css" />
{{end}}
{{/* The brand lockup (logo svg + wordmark) shared by both brand-tag variants
     below. */}}
{{define "brand_link"}}<a href="{{.Base}}/"><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>{{end}}
{{define "base_body_start" -}}
</head>
<body{{if .UnitDefault}} data-unit-default="{{.UnitDefault}}"{{end}}>
  <header>
    <div class="brand">
      <div>{{/* The brand is the page's h1 everywhere EXCEPT the homepage, where the
           hero headline owns the sole h1 and the brand degrades to a <p>. The
           .brand h1, .brand .site-name selector pair in style.css keeps the
           lockup looking identical either way. (The Jinja original wrote
           <{{ brand_tag|default('h1') }} …>; html/template forbids actions in
           tag names, hence two literal branches around one shared lockup.) */}}
        {{if eq .BrandTag "p"}}<p class="site-name">{{template "brand_link" .}}</p>{{else}}<h1 class="site-name">{{template "brand_link" .}}</h1>{{end}}
        <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">{{/* data-view marks the links nav.js rewrites to carry the current
           location hash, so moving between views keeps the place you picked.
           Climate and Alerts deliberately opt out (they aren't cell-scoped).
           Inert on the SEO pages, which never load nav.js. */}}
        <nav class="view-nav" aria-label="Views">
        <a href="{{.Base}}/" data-view="map"{{if eq .Section "home"}} class="active"{{end}}>Weekly</a>
        <a href="{{.AssetBase}}/calendar" data-view="calendar">Calendar</a>
        <a href="{{.AssetBase}}/day" data-view="day">Day Detail</a>
        <a href="{{.AssetBase}}/compare" data-view="compare">Compare</a>
        <a href="{{.AssetBase}}/score" data-view="score"{{if eq .Section "score"}} class="active"{{end}}>Score</a>
        <a href="{{.Base}}/climate"{{if eq .Section "climate"}} class="active"{{end}}>Climate</a>
        <a href="{{.AssetBase}}/alerts">Alerts</a>
      </nav>
        </div>
      </details>
    </div>
  </header>

  <main{{if .MainClass}} class="{{.MainClass}}"{{end}}>
{{end}}
{{define "base_body_end" -}}
  </main>

  <footer class="site-footer">{{/* The compact digest signup is the site-wide footer pattern, not a
       homepage-only surface: every page is a possible entry point.
       Hidden for now; restore by uncommenting the form block below
       (kept verbatim from the Jinja original — {{ asset_base }} becomes
       {{.AssetBase}} when it comes back):

    <form class="digest-form digest-compact" method="post" action="{{ asset_base }}/digest"
          data-digest aria-labelledby="footer-digest-label">
      <label id="footer-digest-label" for="footer-digest-email">Your city's weather, graded — monthly</label>
      <div class="digest-row">
        <input id="footer-digest-email" name="email" type="email" required
               autocomplete="email" placeholder="you@example.com" />
        <button type="submit">Get the digest</button>
      </div>
      <p class="digest-note muted">No spam, no sharing your address, unsubscribe anytime.</p>
      <p class="digest-status" role="status" aria-live="polite" hidden></p>
    </form>
    */}}
    <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}}/privacy">Privacy</a>
      <a href="{{.Base}}/">Open the tool</a>
    </nav>
    <p class="muted">Free. No ads. No tracking. No account needed. Built by one person in the open.</p>
    <p class="muted">Thermograph grades weather by its percentile against ~45 years of local
       climate history. Data: ERA5 via Open-Meteo &middot; NASA POWER &middot; MET Norway.</p>
    <p class="muted">Made by <a href="https://emigriffith.dev">emigriffith.dev</a>
       <a href="mailto:emerytgriffith@gmail.com" aria-label="Email" title="emerytgriffith@gmail.com">@</a></p>
  </footer>
{{end}}
{{define "base_scripts_default" -}}
  {{comment `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="{{.AssetBase}}/units.js"></script>
  <script type="module" src="{{.AssetBase}}/account.js"></script>
  <script type="module" src="{{.AssetBase}}/climate.js"></script>
{{end}}
{{define "base_tail" -}}
  <script type="module" src="{{.AssetBase}}/digest.js"></script>
  <script type="module" src="{{.AssetBase}}/ios-install.js"></script>
</body>
</html>{{end}}
{{/* Shared breadcrumb nav (each Jinja page repeated this line verbatim; the
     output is identical, so it is factored here). The separator is emitted
     BEFORE every non-first crumb — same byte stream as Jinja's
     `{% if not loop.last %}` after-each-but-last. Crumb.Href is *string
     (terminal crumb: null). */}}
{{define "breadcrumb" -}}
<nav class="breadcrumb" aria-label="Breadcrumb">
{{range $i, $c := .Breadcrumb}}{{if $i}} <span class="sep">›</span> {{end}}{{if $c.Href}}<a href="{{$c.Href}}">{{$c.Name}}</a>{{else}}<span>{{$c.Name}}</span>{{end}}{{end -}}
</nav>
{{end}}