Mobile hamburger nav; crisp SVG logo; month travel-note callout (#117)
- Collapse the view navigation into a hamburger menu on phones. The nav is wrapped in a <details> (pure CSS, no JS — so it works on the crawlable SEO pages too): transparent (display:contents) on desktop so the tabs render inline, a dropdown behind a hamburger under 640px. The °F/°C toggle, bell and account stay in the header bar; units.js/account.js now anchor their injected controls on the wrapper. - Replace the header logo: the ▚ glyph was a rotated Unicode char that fonts rendered inconsistently (warped). Use a crisp inline SVG of the two accent squares (currentColor) across all headers. - Month pages: turn the plain "Visiting <city> in <month>?" line into a bordered callout with a CTA button, matching the city page's travel box. Verified in Firefox and Chromium at desktop and 390px, light and dark: desktop nav inline, mobile hamburger opens the dropdown, logo crisp, travel note styled.
This commit is contained in:
parent
59bc40da5c
commit
4f6716283b
9 changed files with 81 additions and 27 deletions
|
|
@ -259,8 +259,8 @@ function ensureAcctEl() {
|
|||
if (!acctEl) {
|
||||
acctEl = document.createElement("div");
|
||||
acctEl.className = "acct";
|
||||
const nav = brand.querySelector(".view-nav");
|
||||
brand.insertBefore(acctEl, nav); // top-right, just left of the view tabs
|
||||
const anchor = brand.querySelector(".nav-menu") || brand.querySelector(".view-nav");
|
||||
brand.insertBefore(acctEl, anchor); // top-right, just left of the nav menu
|
||||
}
|
||||
return acctEl;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,16 +29,19 @@
|
|||
<body>
|
||||
<header class="compact">
|
||||
<div class="brand">
|
||||
<span class="logo">▚</span>
|
||||
<span class="logo"><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></span>
|
||||
<div>
|
||||
<h1>Thermograph · Calendar</h1>
|
||||
</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>
|
||||
<nav class="view-nav" aria-label="Views">
|
||||
<a href="./" data-view="map">Weekly</a>
|
||||
<a href="calendar" data-view="calendar" class="active">Calendar</a>
|
||||
<a href="day" data-view="day">Day</a>
|
||||
<a href="compare" data-view="compare">Compare</a>
|
||||
</nav>
|
||||
</details>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,17 +29,20 @@
|
|||
<body>
|
||||
<header>
|
||||
<div class="brand">
|
||||
<span class="logo">▚</span>
|
||||
<span class="logo"><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></span>
|
||||
<div>
|
||||
<h1>Thermograph · Compare</h1>
|
||||
<p class="tag">Which place best hits your comfort temperature over a date range</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>
|
||||
<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>
|
||||
</details>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,17 +29,20 @@
|
|||
<body>
|
||||
<header>
|
||||
<div class="brand">
|
||||
<span class="logo">▚</span>
|
||||
<span class="logo"><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></span>
|
||||
<div>
|
||||
<h1>Thermograph · Day</h1>
|
||||
<p class="tag">Every percentile boundary for one day vs its typical climate</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>
|
||||
<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" class="active">Day</a>
|
||||
<a href="compare" data-view="compare">Compare</a>
|
||||
</nav>
|
||||
</details>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,17 +32,20 @@
|
|||
<body>
|
||||
<header>
|
||||
<div class="brand">
|
||||
<span class="logo">▚</span>
|
||||
<span class="logo"><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></span>
|
||||
<div>
|
||||
<h1>Thermograph</h1>
|
||||
<p class="tag">Grading today's weather 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>
|
||||
<nav class="view-nav" aria-label="Views">
|
||||
<a href="./" data-view="map" class="active">Weekly</a>
|
||||
<a href="calendar" data-view="calendar">Calendar</a>
|
||||
<a href="day" data-view="day">Day</a>
|
||||
<a href="compare" data-view="compare">Compare</a>
|
||||
</nav>
|
||||
</details>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
|
|
@ -28,17 +28,20 @@
|
|||
<body>
|
||||
<header>
|
||||
<div class="brand">
|
||||
<span class="logo">▚</span>
|
||||
<span class="logo"><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></span>
|
||||
<div>
|
||||
<h1>Thermograph · Guide</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>
|
||||
<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">Compare</a>
|
||||
</nav>
|
||||
</details>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
|
|
@ -67,17 +67,18 @@ header {
|
|||
instead of bumping the toggle onto its own line. */
|
||||
.brand > div:not(.unit-toggle):not(.acct) { flex: 1 1 0; min-width: 0; }
|
||||
.logo {
|
||||
font-size: 30px;
|
||||
color: var(--accent);
|
||||
transform: rotate(90deg);
|
||||
display: inline-block;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.logo svg { width: 28px; height: 28px; display: block; }
|
||||
h1 { margin: 0; font-size: 22px; letter-spacing: -0.02em; }
|
||||
.tag { margin: 2px 0 0; color: var(--muted); font-size: 13px; }
|
||||
/* Compact header (e.g. Calendar): no tagline, roughly half the height.
|
||||
Only the vertical padding is trimmed so the responsive side padding stands. */
|
||||
header.compact { padding-top: 9px; padding-bottom: 9px; }
|
||||
header.compact .logo { font-size: 22px; }
|
||||
header.compact .logo svg { width: 22px; height: 22px; }
|
||||
header.compact h1 { font-size: 18px; }
|
||||
|
||||
main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
|
||||
|
|
@ -490,6 +491,19 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
|
|||
.view-nav a:hover { color: var(--text); }
|
||||
.view-nav a.active { background: var(--accent); color: #fff; }
|
||||
|
||||
/* Hamburger wrapper. On desktop it's transparent (display:contents) so the nav
|
||||
renders inline as pills and the hamburger summary is hidden; on phones (the
|
||||
640px block) it becomes a dropdown while the F/C toggle, bell and account stay
|
||||
in the header bar. */
|
||||
.nav-menu { display: contents; }
|
||||
/* A closed <details> hides its non-summary content; force the nav visible on
|
||||
desktop (the 640px block re-hides it behind the hamburger on phones). */
|
||||
.nav-menu > .view-nav { display: inline-flex; }
|
||||
.nav-menu::details-content { display: contents; }
|
||||
.nav-toggle { display: none; list-style: none; cursor: pointer; }
|
||||
.nav-toggle::-webkit-details-marker { display: none; }
|
||||
.nav-toggle svg { display: block; }
|
||||
|
||||
/* --- calendar subpage --- */
|
||||
.metric-toggle {
|
||||
display: flex; flex-wrap: wrap; border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
|
||||
|
|
@ -1296,14 +1310,27 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
|
|||
h1 { font-size: 19px; }
|
||||
.tag { font-size: 12px; }
|
||||
|
||||
/* Let the header wrap so the view switcher drops to its own full-width row
|
||||
(and stays a comfortable touch target) instead of crowding the title. */
|
||||
/* Let the header wrap if the control cluster runs out of room. */
|
||||
.brand { flex-wrap: wrap; }
|
||||
/* Full-width bar; each tab is an equal, fully-tappable third. The unit toggle
|
||||
stays on the title row (pushed to the top-right); the tabs wrap below it. */
|
||||
.view-nav { margin-left: 0; width: 100%; }
|
||||
.unit-toggle + .view-nav { margin-left: 0; }
|
||||
.view-nav a { min-height: 44px; padding: 8px 12px; }
|
||||
/* The view navigation collapses into a hamburger dropdown; the F/C toggle, bell
|
||||
and account stay in the header bar beside it. */
|
||||
/* A real box again (not display:contents) so it's the positioning context for
|
||||
the absolute dropdown and holds the hamburger. */
|
||||
.nav-menu { display: inline-flex; position: relative; align-self: center; }
|
||||
.nav-toggle {
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 44px; height: 40px; border: 1px solid var(--border); border-radius: 10px;
|
||||
background: var(--surface-2); color: var(--text);
|
||||
}
|
||||
.nav-menu[open] .nav-toggle { border-color: var(--accent); color: var(--accent); }
|
||||
.view-nav {
|
||||
position: absolute; right: 0; top: calc(100% + 8px); z-index: 60; margin: 0;
|
||||
flex-direction: column; align-items: stretch; width: max-content; min-width: 176px;
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, .35);
|
||||
}
|
||||
.nav-menu:not([open]) .view-nav { display: none; }
|
||||
.view-nav a { min-height: 44px; padding: 10px 14px; justify-content: flex-start; }
|
||||
.view-nav a + a::before { display: none; }
|
||||
/* Collapse the account entry to an icon-only button so it doesn't crush the
|
||||
title/tagline on narrow screens (it still opens the modal / menu). */
|
||||
.acct-btn span { display: none; }
|
||||
|
|
@ -1572,6 +1599,15 @@ td.rec-date { color: var(--muted); font-size: 13px; }
|
|||
.city-event p { margin: 0; }
|
||||
.city-travel { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px 18px; margin: 28px 0; }
|
||||
.city-travel h2 { margin-top: 4px; }
|
||||
/* Month page: the "visiting in <month>?" prompt as a compact callout — text on
|
||||
the left, a CTA button on the right (stacks on narrow screens). */
|
||||
.travel-note {
|
||||
display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
|
||||
background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
|
||||
padding: 14px 18px; margin: 22px 0;
|
||||
}
|
||||
.travel-note p { margin: 0; flex: 1 1 240px; }
|
||||
.travel-note .cta { flex-shrink: 0; margin-top: 0; }
|
||||
.travel-note { font-size: 15px; }
|
||||
|
||||
/* Hub / directory of cities */
|
||||
|
|
|
|||
|
|
@ -26,17 +26,20 @@
|
|||
<body>
|
||||
<header>
|
||||
<div class="brand">
|
||||
<span class="logo">▚</span>
|
||||
<span class="logo"><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></span>
|
||||
<div>
|
||||
<h1>Thermograph · Alerts</h1>
|
||||
<p class="tag">Get notified when a city's weather passes the percentile you set</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>
|
||||
<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">Compare</a>
|
||||
</nav>
|
||||
</details>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ function syncUnitToggle(wrap) {
|
|||
const b = e.target.closest("button[data-unit]");
|
||||
if (b) setUnit(b.dataset.unit);
|
||||
});
|
||||
const nav = brand.querySelector(".view-nav");
|
||||
brand.insertBefore(wrap, nav); // sits just left of the view tabs (top-right)
|
||||
const anchor = brand.querySelector(".nav-menu") || brand.querySelector(".view-nav");
|
||||
brand.insertBefore(wrap, anchor); // sits just left of the nav (top-right)
|
||||
syncUnitToggle(wrap);
|
||||
})();
|
||||
|
|
|
|||
Loading…
Reference in a new issue